mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 19:54:40 +02:00
Apple native cert validation: add WOLFSSL_TEST_APPLE_CERT_VALIDATION feature macro that forces system CA certs on and makes all CA certs added to CM via xxx_load_verify_xxx APIs to instead be loaded as system trust anchors when used for TLS cert verification
This commit is contained in:
195
src/internal.c
195
src/internal.c
@@ -2915,6 +2915,12 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
|
|||||||
ctx->x509Chain = NULL;
|
ctx->x509Chain = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
if (ctx->testTrustedCAs != NULL) {
|
||||||
|
CFRelease(ctx->testTrustedCAs);
|
||||||
|
ctx->testTrustedCAs = NULL;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
#endif /* !NO_CERTS */
|
#endif /* !NO_CERTS */
|
||||||
|
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
@@ -42777,6 +42783,79 @@ cleanup:
|
|||||||
return secCert;
|
return secCert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int DisplaySecTrustError(CFErrorRef error, SecTrustRef trust)
|
||||||
|
{
|
||||||
|
CFStringRef desc;
|
||||||
|
CFStringRef domain;
|
||||||
|
SecTrustResultType trustResult;
|
||||||
|
CFDictionaryRef info;
|
||||||
|
|
||||||
|
/* Description */
|
||||||
|
desc = CFErrorCopyDescription(error);
|
||||||
|
if (desc) {
|
||||||
|
char buffer[256];
|
||||||
|
if (CFStringGetCString(desc, buffer, sizeof(buffer),
|
||||||
|
kCFStringEncodingUTF8)) {
|
||||||
|
WOLFSSL_MSG_EX("SecTrustEvaluateWithError Error description: %s\n",
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
CFRelease(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Domain */
|
||||||
|
domain = CFErrorGetDomain(error);
|
||||||
|
if (domain) {
|
||||||
|
char domainStr[128];
|
||||||
|
if (CFStringGetCString(domain, domainStr, sizeof(domainStr),
|
||||||
|
kCFStringEncodingUTF8)) {
|
||||||
|
WOLFSSL_MSG_EX("SecTrustEvaluateWithError Domain: %s\n", domainStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get additional trust result info */
|
||||||
|
if (SecTrustGetTrustResult(trust, &trustResult) == errSecSuccess) {
|
||||||
|
WOLFSSL_MSG_EX("SecTrustResultType: %d\n", trustResult);
|
||||||
|
/* Optional: decode the enum */
|
||||||
|
switch (trustResult) {
|
||||||
|
case kSecTrustResultInvalid:
|
||||||
|
WOLFSSL_MSG("TrustResult: Invalid\n");
|
||||||
|
break;
|
||||||
|
case kSecTrustResultProceed:
|
||||||
|
WOLFSSL_MSG("TrustResult: Proceed\n");
|
||||||
|
break;
|
||||||
|
case kSecTrustResultDeny:
|
||||||
|
WOLFSSL_MSG("TrustResult: Deny\n");
|
||||||
|
break;
|
||||||
|
case kSecTrustResultUnspecified:
|
||||||
|
WOLFSSL_MSG("TrustResult: Unspecified (implicitly trusted)\n");
|
||||||
|
break;
|
||||||
|
case kSecTrustResultRecoverableTrustFailure:
|
||||||
|
WOLFSSL_MSG("TrustResult: Recoverable trust failure\n");
|
||||||
|
break;
|
||||||
|
case kSecTrustResultFatalTrustFailure:
|
||||||
|
WOLFSSL_MSG("TrustResult: Fatal trust failure\n");
|
||||||
|
break;
|
||||||
|
case kSecTrustResultOtherError:
|
||||||
|
WOLFSSL_MSG("TrustResult: Other error\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("TrustResult: Unknown\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WOLFSSL_MSG("SecTrustGetTrustResult failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
info = CFErrorCopyUserInfo(error);
|
||||||
|
if (info) {
|
||||||
|
printf("Trust error info dump:\n");
|
||||||
|
CFShow(info);
|
||||||
|
CFRelease(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validates a chain of certificates using the Apple system trust APIs
|
* Validates a chain of certificates using the Apple system trust APIs
|
||||||
@@ -42793,13 +42872,13 @@ cleanup:
|
|||||||
* wolfSSL's built-in certificate validation mechanisms anymore. We instead
|
* wolfSSL's built-in certificate validation mechanisms anymore. We instead
|
||||||
* must call into the Security Framework APIs to authenticate peer certificates
|
* must call into the Security Framework APIs to authenticate peer certificates
|
||||||
*/
|
*/
|
||||||
static int DoAppleNativeCertValidation(WOLFSSL* ssl,
|
static int DoAppleNativeCertValidation(WOLFSSL* ssl,
|
||||||
const WOLFSSL_BUFFER_INFO* certs,
|
const WOLFSSL_BUFFER_INFO* certs,
|
||||||
int totalCerts)
|
int totalCerts)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
CFMutableArrayRef certArray = NULL;
|
CFMutableArrayRef certArray = NULL;
|
||||||
SecCertificateRef secCert = NULL;
|
SecCertificateRef secCert = NULL;
|
||||||
SecTrustRef trust = NULL;
|
SecTrustRef trust = NULL;
|
||||||
@@ -42808,8 +42887,7 @@ static int DoAppleNativeCertValidation(WOLFSSL* ssl,
|
|||||||
|
|
||||||
WOLFSSL_ENTER("DoAppleNativeCertValidation");
|
WOLFSSL_ENTER("DoAppleNativeCertValidation");
|
||||||
|
|
||||||
certArray = CFArrayCreateMutable(kCFAllocatorDefault,
|
certArray = CFArrayCreateMutable(kCFAllocatorDefault, totalCerts,
|
||||||
totalCerts,
|
|
||||||
&kCFTypeArrayCallBacks);
|
&kCFTypeArrayCallBacks);
|
||||||
if (!certArray) {
|
if (!certArray) {
|
||||||
WOLFSSL_MSG("Error: can't allocate CFArray for certificates");
|
WOLFSSL_MSG("Error: can't allocate CFArray for certificates");
|
||||||
@@ -42818,8 +42896,8 @@ static int DoAppleNativeCertValidation(WOLFSSL* ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < totalCerts; i++) {
|
for (i = 0; i < totalCerts; i++) {
|
||||||
secCert = ConvertToSecCertificateRef(certs[i].buffer,
|
secCert =
|
||||||
(int)certs[i].length);
|
ConvertToSecCertificateRef(certs[i].buffer, (int)certs[i].length);
|
||||||
if (!secCert) {
|
if (!secCert) {
|
||||||
WOLFSSL_MSG("Error: can't convert DER cert to SecCertificateRef");
|
WOLFSSL_MSG("Error: can't convert DER cert to SecCertificateRef");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -42833,35 +42911,74 @@ static int DoAppleNativeCertValidation(WOLFSSL* ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create trust object for SecCertifiate Ref */
|
/* Create trust object for SecCertifiate Ref */
|
||||||
if (ssl->buffers.domainName.buffer &&
|
if (ssl->buffers.domainName.buffer && ssl->buffers.domainName.length > 0) {
|
||||||
ssl->buffers.domainName.length > 0) {
|
|
||||||
/* Create policy with specified value to require host name match */
|
/* Create policy with specified value to require host name match */
|
||||||
hostname = CFStringCreateWithCString(kCFAllocatorDefault,
|
hostname = CFStringCreateWithCString(
|
||||||
(const char*)ssl->buffers.domainName.buffer,
|
kCFAllocatorDefault, (const char*)ssl->buffers.domainName.buffer,
|
||||||
kCFStringEncodingUTF8);
|
kCFStringEncodingUTF8);
|
||||||
}
|
}
|
||||||
if (hostname != NULL) {
|
if (hostname != NULL) {
|
||||||
policy = SecPolicyCreateSSL(true, hostname);
|
policy = SecPolicyCreateSSL(true, hostname);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
policy = SecPolicyCreateSSL(true, NULL);
|
policy = SecPolicyCreateSSL(true, NULL);
|
||||||
}
|
}
|
||||||
status = SecTrustCreateWithCertificates(certArray, policy, &trust);
|
status = SecTrustCreateWithCertificates(certArray, policy, &trust);
|
||||||
if (status != errSecSuccess) {
|
if (status != errSecSuccess) {
|
||||||
WOLFSSL_MSG_EX("Error creating trust object, "
|
WOLFSSL_MSG_EX("Error creating trust object, "
|
||||||
"SecTrustCreateWithCertificates returned %d",status);
|
"SecTrustCreateWithCertificates returned %d",
|
||||||
|
status);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION)
|
||||||
|
/* TEST ONLY CODE:
|
||||||
|
* Set accumulated list of trusted CA certificates as trust anchors */
|
||||||
|
if (ssl->ctx->testTrustedCAs != NULL) {
|
||||||
|
status = SecTrustSetAnchorCertificates(trust, ssl->ctx->testTrustedCAs);
|
||||||
|
if (status != errSecSuccess) {
|
||||||
|
WOLFSSL_MSG_EX("Error setting anchor certificates: %d", status);
|
||||||
|
ret = 0;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Evaluate the certificate's authenticity */
|
/* Evaluate the certificate's authenticity */
|
||||||
if (SecTrustEvaluateWithError(trust, NULL) == 1) {
|
WOLFSSL_MSG("Performing Apple native cert validation via "
|
||||||
WOLFSSL_MSG("Cert chain is trusted");
|
"SecTrustEvaluateWithError");
|
||||||
ret = 1;
|
CFErrorRef error = NULL;
|
||||||
|
ret = SecTrustEvaluateWithError(trust, &error);
|
||||||
|
if (ret != 1) {
|
||||||
|
if (error) {
|
||||||
|
CFIndex code;
|
||||||
|
code = CFErrorGetCode(error);
|
||||||
|
WOLFSSL_MSG_EX("SecTrustEvaluateWithError failed with code: %ld\n",
|
||||||
|
code);
|
||||||
|
DisplaySecTrustError(error, trust);
|
||||||
|
|
||||||
|
#if WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
/* TEST ONLY CODE:
|
||||||
|
* wolfSSL API tests use a cert with a validity period that is too
|
||||||
|
* long for the Apple system trust APIs
|
||||||
|
* (See: https://support.apple.com/en-us/103769)
|
||||||
|
* therefore we should skip over this particular error */
|
||||||
|
if (code == errSecCertificateValidityPeriodTooLong) {
|
||||||
|
WOLFSSL_MSG("Skipping certificate validity period error");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CFRelease(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WOLFSSL_MSG(
|
||||||
|
"SecTrustEvaluateWithError failed with unknown error.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("Cert chain trust evaluation failed"
|
WOLFSSL_MSG("SecTrustEvaluateWithError succeeded");
|
||||||
"SecTrustEvaluateWithError returned 0");
|
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
@@ -42883,6 +43000,38 @@ cleanup:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION)
|
||||||
|
int wolfSSL_TestAppleNativeCertValidation_AppendCA(WOLFSSL_CTX* ctx,
|
||||||
|
const byte* derCert,
|
||||||
|
int derLen)
|
||||||
|
{
|
||||||
|
SecCertificateRef certRef;
|
||||||
|
|
||||||
|
if (derCert == NULL || derLen == 0) {
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the base array for trust anchors if it doesn't exist */
|
||||||
|
if (ctx->testTrustedCAs == NULL) {
|
||||||
|
ctx->testTrustedCAs =
|
||||||
|
CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||||
|
if (!ctx->testTrustedCAs) {
|
||||||
|
return WOLFSSL_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
certRef = ConvertToSecCertificateRef(derCert, derLen);
|
||||||
|
if (!certRef) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFArrayAppendValue(ctx->testTrustedCAs, certRef);
|
||||||
|
CFRelease(certRef);
|
||||||
|
return WOLFSSL_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
|
|
||||||
#endif /* defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) */
|
#endif /* defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) */
|
||||||
|
|
||||||
#undef ERROR_OUT
|
#undef ERROR_OUT
|
||||||
|
@@ -42,9 +42,14 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(HAVE_SECURITY_SECTRUSTSETTINGS_H)
|
#if defined(__APPLE__)
|
||||||
|
#if defined(HAVE_SECURITY_SECTRUSTSETTINGS_H)
|
||||||
#include <Security/SecTrustSettings.h>
|
#include <Security/SecTrustSettings.h>
|
||||||
#endif
|
#endif /* HAVE_SECURITY_SECTRUSTSETTINGS_H */
|
||||||
|
#if WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
#endif /* WOLFSSL_SYS_CA_CERTS */
|
#endif /* WOLFSSL_SYS_CA_CERTS */
|
||||||
|
|
||||||
@@ -2153,8 +2158,40 @@ static int ProcessBufferCertHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
|
|||||||
|
|
||||||
/* CA certificate to verify with. */
|
/* CA certificate to verify with. */
|
||||||
if (type == CA_TYPE) {
|
if (type == CA_TYPE) {
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
word32 derLen;
|
||||||
|
byte* derBuf;
|
||||||
|
if (ctx->doAppleNativeCertValidationFlag == 1) {
|
||||||
|
derLen = der->length;
|
||||||
|
derBuf = (byte*)XMALLOC(derLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (derBuf == NULL) {
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
XMEMCPY(derBuf, der->buffer, derLen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(void)derLen;
|
||||||
|
(void)derBuf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* verify CA unless user set to no verify */
|
/* verify CA unless user set to no verify */
|
||||||
ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
|
ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
if (ret == 1 && ctx->doAppleNativeCertValidationFlag == 1) {
|
||||||
|
WOLFSSL_MSG("Appending CA to cert list for native cert validation test");
|
||||||
|
ret = wolfSSL_TestAppleNativeCertValidation_AppendCA(ctx, derBuf, (int)derLen);
|
||||||
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
|
WOLFSSL_MSG("Clearing CA table for native cert validation test");
|
||||||
|
/* Clear the CA table so we can ensure they won't be used for
|
||||||
|
* verification */
|
||||||
|
ret = wolfSSL_CertManagerUnloadCAs(ctx->cm);
|
||||||
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
}
|
||||||
|
#endif /* !WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
@@ -2978,6 +3015,12 @@ int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
|
|||||||
ret = NOT_COMPILED_IN;
|
ret = NOT_COMPILED_IN;
|
||||||
(void)flags;
|
(void)flags;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
if (ret == 1) {
|
||||||
|
wolfSSL_CTX_load_system_CA_certs(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -3422,6 +3465,12 @@ int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
|
|||||||
GET_VERIFY_SETTING_CTX(ctx));
|
GET_VERIFY_SETTING_CTX(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
if (ret == 1) {
|
||||||
|
wolfSSL_CTX_load_system_CA_certs(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Return 1 on success or 0 on failure. */
|
/* Return 1 on success or 0 on failure. */
|
||||||
return WS_RC(ret);
|
return WS_RC(ret);
|
||||||
}
|
}
|
||||||
@@ -3950,6 +3999,12 @@ int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX* ctx, const unsigned char* in,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
if (ret == 1) {
|
||||||
|
wolfSSL_CTX_load_system_CA_certs(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
WOLFSSL_LEAVE("wolfSSL_CTX_load_verify_buffer_ex", ret);
|
WOLFSSL_LEAVE("wolfSSL_CTX_load_verify_buffer_ex", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -300,6 +300,10 @@
|
|||||||
#include <wolfssl/sniffer.h>
|
#include <wolfssl/sniffer.h>
|
||||||
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -4242,6 +4246,10 @@ struct WOLFSSL_CTX {
|
|||||||
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
|
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
|
||||||
int secLevel; /* The security level of system-wide crypto policy. */
|
int secLevel; /* The security level of system-wide crypto policy. */
|
||||||
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
|
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
CFMutableArrayRef testTrustedCAs;
|
||||||
|
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
};
|
};
|
||||||
|
|
||||||
WOLFSSL_LOCAL
|
WOLFSSL_LOCAL
|
||||||
@@ -4278,6 +4286,13 @@ int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
|
||||||
|
WOLFSSL_API
|
||||||
|
int wolfSSL_TestAppleNativeCertValidation_AppendCA(WOLFSSL_CTX* ctx,
|
||||||
|
const byte* derCert,
|
||||||
|
int derLen);
|
||||||
|
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
|
||||||
|
|
||||||
/* All cipher suite related info
|
/* All cipher suite related info
|
||||||
* Keep as a constant size (no ifdefs) for session export */
|
* Keep as a constant size (no ifdefs) for session export */
|
||||||
typedef struct CipherSpecs {
|
typedef struct CipherSpecs {
|
||||||
|
Reference in New Issue
Block a user