From 3af87f6f93ac373e4882246fdea21e9150db04df Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 7 Jul 2023 08:54:22 +1000 Subject: [PATCH] Moved CertManager APIs into own file Split out certificate manager APIs into ssl_certman.c. ssl.c includes ssl_certman.c Better test coverage. Minor fixes. wolfSSL_X509_chain_up_ref calls XFREE with name->heap but name may be NULL. Check for NULL first. --- .gitignore | 1 + .../components/wolfssl/CMakeLists.txt | 1 + src/include.am | 1 + src/ssl.c | 1549 +---------- src/ssl_certman.c | 2355 +++++++++++++++++ src/ssl_misc.c | 13 +- src/x509.c | 4 +- tests/api.c | 1288 ++++++--- wolfcrypt/src/asn.c | 2 +- wolfssl/internal.h | 2 +- wolfssl/ssl.h | 65 +- 11 files changed, 3290 insertions(+), 1991 deletions(-) create mode 100644 src/ssl_certman.c diff --git a/.gitignore b/.gitignore index 84fdff138e..5ec7039b79 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ testsuite/testsuite.test tests/unit.test tests/bio_write_test.txt tests/test-log-dump-to-file.txt +tests/cert_cache.tmp test-write-dhparams.pem testsuite/*.der testsuite/*.pem diff --git a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt index eff3591838..fa366e10cd 100644 --- a/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt +++ b/IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/CMakeLists.txt @@ -192,6 +192,7 @@ set(COMPONENT_SRCEXCLUDE "${WOLFSSL_ROOT}/src/pk.c" "${WOLFSSL_ROOT}/src/ssl_asn1.c" # included by ssl.c "${WOLFSSL_ROOT}/src/ssl_bn.c" # included by ssl.c + "${WOLFSSL_ROOT}/src/ssl_certman.c" # included by ssl.c "${WOLFSSL_ROOT}/src/ssl_misc.c" # included by ssl.c "${WOLFSSL_ROOT}/src/x509.c" "${WOLFSSL_ROOT}/src/x509_str.c" diff --git a/src/include.am b/src/include.am index 174be84831..050b253a2e 100644 --- a/src/include.am +++ b/src/include.am @@ -21,6 +21,7 @@ EXTRA_DIST += src/conf.c EXTRA_DIST += src/pk.c EXTRA_DIST += src/ssl_asn1.c EXTRA_DIST += src/ssl_bn.c +EXTRA_DIST += src/ssl_certman.c EXTRA_DIST += src/ssl_misc.c EXTRA_DIST += src/x509.c EXTRA_DIST += src/x509_str.c diff --git a/src/ssl.c b/src/ssl.c index c9720e96b4..50e00b44c5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -208,6 +208,11 @@ #define WOLFSSL_EVP_INCLUDED #include "wolfcrypt/src/evp.c" +#ifndef WOLFCRYPT_ONLY +#define WOLFSSL_SSL_CERTMAN_INCLUDED +#include "src/ssl_certman.c" +#endif + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ !defined(WOLFCRYPT_ONLY) /* Convert shortname to NID. @@ -5038,7 +5043,6 @@ int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq) #endif /* ATOMIC_USER */ #ifndef NO_CERTS - WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx) { WOLFSSL_CERT_MANAGER* cm = NULL; @@ -5046,298 +5050,6 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx) cm = ctx->cm; return cm; } - -WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap) -{ - WOLFSSL_CERT_MANAGER* cm; - - WOLFSSL_ENTER("wolfSSL_CertManagerNew"); - - cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap, - DYNAMIC_TYPE_CERT_MANAGER); - if (cm) { - int ret; - - XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER)); - - if (wc_InitMutex(&cm->caLock) != 0) { - WOLFSSL_MSG("Bad mutex init"); - wolfSSL_CertManagerFree(cm); - return NULL; - } - - wolfSSL_RefInit(&cm->ref, &ret); - #ifdef WOLFSSL_REFCNT_ERROR_RETURN - if (ret != 0) { - WOLFSSL_MSG("Bad mutex init"); - wolfSSL_CertManagerFree(cm); - return NULL; - } - #else - (void)ret; - #endif - - #ifdef WOLFSSL_TRUST_PEER_CERT - if (wc_InitMutex(&cm->tpLock) != 0) { - WOLFSSL_MSG("Bad mutex init"); - wolfSSL_CertManagerFree(cm); - return NULL; - } - #endif - - /* set default minimum key size allowed */ - #ifndef NO_RSA - cm->minRsaKeySz = MIN_RSAKEY_SZ; - #endif - #ifdef HAVE_ECC - cm->minEccKeySz = MIN_ECCKEY_SZ; - #endif - #ifdef HAVE_PQC - #ifdef HAVE_FALCON - cm->minFalconKeySz = MIN_FALCONKEY_SZ; - #endif /* HAVE_FALCON */ - #ifdef HAVE_DILITHIUM - cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ; - #endif /* HAVE_DILITHIUM */ - #endif /* HAVE_PQC */ - - cm->heap = heap; - } - - return cm; -} - - -WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void) -{ - return wolfSSL_CertManagerNew_ex(NULL); -} - - -void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerFree"); - - if (cm) { - int doFree = 0; - int ret; - - wolfSSL_RefDec(&cm->ref, &doFree, &ret); - #ifdef WOLFSSL_REFCNT_ERROR_RETURN - if (ret != 0) { - WOLFSSL_MSG("Couldn't lock cm mutex"); - } - #else - (void)ret; - #endif - if (doFree) { - #ifdef HAVE_CRL - if (cm->crl) - FreeCRL(cm->crl, 1); - #endif - #ifdef HAVE_OCSP - if (cm->ocsp) - FreeOCSP(cm->ocsp, 1); - XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); - #if !defined(NO_WOLFSSL_SERVER) && \ - (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ - defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) - if (cm->ocsp_stapling) - FreeOCSP(cm->ocsp_stapling, 1); - #endif - #endif - FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); - wc_FreeMutex(&cm->caLock); - - #ifdef WOLFSSL_TRUST_PEER_CERT - FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); - wc_FreeMutex(&cm->tpLock); - #endif - wolfSSL_RefFree(&cm->ref); - XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); - } - } - -} - -int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm) -{ - if (cm) { - int ret; - - wolfSSL_RefInc(&cm->ref, &ret); - #ifdef WOLFSSL_REFCNT_ERROR_RETURN - if (ret != 0) { - WOLFSSL_MSG("Failed to lock cm mutex"); - return WOLFSSL_FAILURE; - } - #else - (void)ret; - #endif - - return WOLFSSL_SUCCESS; - } - - return WOLFSSL_FAILURE; -} - -#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) -#if defined(WOLFSSL_SIGNER_DER_CERT) -/****************************************************************************** -* wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a -* certificate manager (CM). -* -* RETURNS: -* returns stack of X509 certs on success, otherwise returns a NULL. -*/ -WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_STACK* sk = NULL; - int numCerts = 0; - DerBuffer** certBuffers = NULL; - const byte* derBuffer = NULL; - Signer* signers = NULL; - word32 row = 0; - WOLFSSL_X509* x509 = NULL; - int i = 0; - int ret = 0; - - if (cm == NULL) - return NULL; - - sk = wolfSSL_sk_X509_new_null(); - if (sk == NULL) - goto error; - - if (wc_LockMutex(&cm->caLock) != 0) - goto error; - - /* Iterate once to get the number of certs, for memory allocation - purposes. */ - for (row = 0; row < CA_TABLE_SIZE; row++) { - signers = cm->caTable[row]; - while (signers && signers->derCert && signers->derCert->buffer) { - ++numCerts; - signers = signers->next; - } - } - - if (numCerts == 0) { - wc_UnLockMutex(&cm->caLock); - goto error; - } - - certBuffers = (DerBuffer**)XMALLOC(sizeof(DerBuffer*) * numCerts, cm->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (certBuffers == NULL) { - wc_UnLockMutex(&cm->caLock); - goto error; - } - XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * numCerts); - - /* Copy the certs locally so that we can release the caLock. If the lock is - held when wolfSSL_d2i_X509 is called, GetCA will also try to get the - lock, leading to deadlock. */ - for (row = 0; row < CA_TABLE_SIZE; row++) { - signers = cm->caTable[row]; - while (signers && signers->derCert && signers->derCert->buffer) { - ret = AllocDer(&certBuffers[i], signers->derCert->length, CA_TYPE, - cm->heap); - if (ret < 0) { - wc_UnLockMutex(&cm->caLock); - goto error; - } - - XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer, - signers->derCert->length); - certBuffers[i]->length = signers->derCert->length; - - ++i; - signers = signers->next; - } - } - - wc_UnLockMutex(&cm->caLock); - - for (i = 0; i < numCerts; ++i) { - derBuffer = certBuffers[i]->buffer; - wolfSSL_d2i_X509(&x509, &derBuffer, certBuffers[i]->length); - if (x509 == NULL) - goto error; - - if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) { - wolfSSL_X509_free(x509); - goto error; - } - } - - for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) { - FreeDer(&certBuffers[i]); - } - - XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - - return sk; - -error: - if (sk) - wolfSSL_sk_X509_pop_free(sk, NULL); - - if (certBuffers != NULL) { - for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) { - FreeDer(&certBuffers[i]); - } - } - - if (certBuffers) - XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - - return NULL; -} - -#endif /* WOLFSSL_SIGNER_DER_CERT */ -#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */ - -/* Unload the CA signer list */ -int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs"); - - if (cm == NULL) - return BAD_FUNC_ARG; - - if (wc_LockMutex(&cm->caLock) != 0) - return BAD_MUTEX_E; - - FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); - - wc_UnLockMutex(&cm->caLock); - - - return WOLFSSL_SUCCESS; -} - - -#ifdef WOLFSSL_TRUST_PEER_CERT -int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers"); - - if (cm == NULL) - return BAD_FUNC_ARG; - - if (wc_LockMutex(&cm->tpLock) != 0) - return BAD_MUTEX_E; - - FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); - - wc_UnLockMutex(&cm->tpLock); - - - return WOLFSSL_SUCCESS; -} -#endif /* WOLFSSL_TRUST_PEER_CERT */ - #endif /* NO_CERTS */ #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) \ @@ -7425,20 +7137,18 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, else { /* ASN1 (DER) */ int length = (int)sz; - if (format == WOLFSSL_FILETYPE_ASN1) { - /* get length of der (read sequence or octet string) */ - word32 inOutIdx = 0; - if (GetSequence(buff, &inOutIdx, &length, (word32)sz) >= 0) { - length += inOutIdx; /* include leading sequence */ - } - /* get length using octet string (allowed for private key types) */ - else if (type == PRIVATEKEY_TYPE && + word32 inOutIdx = 0; + /* get length of der (read sequence or octet string) */ + if (GetSequence(buff, &inOutIdx, &length, (word32)sz) >= 0) { + length += inOutIdx; /* include leading sequence */ + } + /* get length using octet string (allowed for private key types) */ + else if (type == PRIVATEKEY_TYPE && GetOctetString(buff, &inOutIdx, &length, (word32)sz) >= 0) { - length += inOutIdx; /* include leading oct string */ - } - else { - ret = ASN_PARSE_E; - } + length += inOutIdx; /* include leading oct string */ + } + else { + ret = ASN_PARSE_E; } info->consumed = length; @@ -8184,117 +7894,8 @@ static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } -static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void) -{ - #ifndef NO_WOLFSSL_CLIENT - #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) - return wolfSSLv3_client_method(); - #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10) - return wolfTLSv1_client_method(); - #elif !defined(NO_OLD_TLS) - return wolfTLSv1_1_client_method(); - #elif !defined(WOLFSSL_NO_TLS12) - return wolfTLSv1_2_client_method(); - #elif defined(WOLFSSL_TLS13) - return wolfTLSv1_3_client_method(); - #else - return NULL; - #endif - #elif !defined(NO_WOLFSSL_SERVER) - #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) - return wolfSSLv3_server_method(); - #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10) - return wolfTLSv1_server_method(); - #elif !defined(NO_OLD_TLS) - return wolfTLSv1_1_server_method(); - #elif !defined(WOLFSSL_NO_TLS12) - return wolfTLSv1_2_server_method(); - #elif defined(WOLFSSL_TLS13) - return wolfTLSv1_3_server_method(); - #else - return NULL; - #endif - #else - return NULL; - #endif -} - - -int wolfSSL_CertManagerLoadCABuffer_ex(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* in, long sz, - int format, int userChain, word32 flags) -{ - int ret = WOLFSSL_FATAL_ERROR; - WOLFSSL_CTX* tmp; - - WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer_ex"); - - if (cm == NULL) { - WOLFSSL_MSG("No CertManager error"); - return ret; - } - tmp = wolfSSL_CTX_new(cm_pick_method()); - - if (tmp == NULL) { - WOLFSSL_MSG("CTX new failed"); - return ret; - } - - /* for tmp use */ - wolfSSL_CertManagerFree(tmp->cm); - tmp->cm = cm; - - ret = wolfSSL_CTX_load_verify_buffer_ex(tmp, in, sz, format, - userChain, flags); - - /* don't loose our good one */ - tmp->cm = NULL; - wolfSSL_CTX_free(tmp); - - return ret; -} - -/* like load verify locations, 1 for success, < 0 for error */ -int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* in, long sz, - int format) -{ - return wolfSSL_CertManagerLoadCABuffer_ex(cm, in, sz, format, 0, - WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS); -} - #ifdef HAVE_CRL -int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* buff, long sz, int type) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer"); - if (cm == NULL) - return BAD_FUNC_ARG; - - if (cm->crl == NULL) { - if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) != - WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Enable CRL failed"); - return WOLFSSL_FATAL_ERROR; - } - } - - return BufferLoadCRL(cm->crl, buff, sz, type, VERIFY); -} - -int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL"); - if (cm == NULL) - return BAD_FUNC_ARG; - if (cm->crl != NULL){ - FreeCRL(cm->crl, 1); - cm->crl = NULL; - } - return WOLFSSL_SUCCESS; -} - int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz, int type) { @@ -8319,457 +7920,16 @@ int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff, return wolfSSL_CertManagerLoadCRLBuffer(SSL_CM(ssl), buff, sz, type); } - #endif /* HAVE_CRL */ -/* turn on CRL if off and compiled in, set options */ -int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options) +#ifdef HAVE_OCSP +int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options) { - int ret = WOLFSSL_SUCCESS; - - WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL"); - if (cm == NULL) - return BAD_FUNC_ARG; -#if defined(OPENSSL_COMPATIBLE_DEFAULTS) - if (options == 0) { - - /* Turn off doing Leaf CRL check */ - cm->crlEnabled = 0; - /* Turn off all checks */ - cm->crlCheckAll = 0; - return ret; - } -#else - (void)options; -#endif - - #ifdef HAVE_CRL - if (cm->crl == NULL) { - cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap, - DYNAMIC_TYPE_CRL); - if (cm->crl == NULL) - return MEMORY_E; - - if (InitCRL(cm->crl, cm) != 0) { - WOLFSSL_MSG("Init CRL failed"); - FreeCRL(cm->crl, 1); - cm->crl = NULL; - return WOLFSSL_FAILURE; - } - - #if defined(HAVE_CRL_IO) && defined(USE_WOLFSSL_IO) - cm->crl->crlIOCb = EmbedCrlLookup; - #endif - } -#if defined(OPENSSL_COMPATIBLE_DEFAULTS) - if ((options & WOLFSSL_CRL_CHECKALL) || - (options & WOLFSSL_CRL_CHECK)) -#endif - { - cm->crlEnabled = 1; - if (options & WOLFSSL_CRL_CHECKALL) - cm->crlCheckAll = 1; - } - #else - ret = NOT_COMPILED_IN; - #endif - - return ret; -} - - -int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL"); - if (cm == NULL) - return BAD_FUNC_ARG; - - cm->crlEnabled = 0; - - return WOLFSSL_SUCCESS; -} - -#ifndef NO_WOLFSSL_CM_VERIFY -void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify"); - if (cm == NULL) - return; - - cm->verifyCallback = vc; -} -#endif /* NO_WOLFSSL_CM_VERIFY */ - -#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) -/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */ -int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff, - long sz, int format, int err_val) -{ - int ret = 0; - DerBuffer* der = NULL; -#ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert; -#else - DecodedCert cert[1]; -#endif - - WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer"); - -#ifdef WOLFSSL_SMALL_STACK - cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, - DYNAMIC_TYPE_DCERT); - if (cert == NULL) - return MEMORY_E; -#endif - - if (format == WOLFSSL_FILETYPE_PEM) { -#ifdef WOLFSSL_PEM_TO_DER - ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL); - if (ret != 0) { - FreeDer(&der); - #ifdef WOLFSSL_SMALL_STACK - XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); - #endif - return ret; - } - InitDecodedCert(cert, der->buffer, der->length, cm->heap); -#else - ret = NOT_COMPILED_IN; -#endif - } - else { - InitDecodedCert(cert, buff, (word32)sz, cm->heap); - } - - if (ret == 0) - ret = ParseCertRelative(cert, CERT_TYPE, 1, cm); - -#ifdef HAVE_CRL - if (ret == 0 && cm->crlEnabled) - ret = CheckCertCRL(cm->crl, cert); -#endif - -#ifndef NO_WOLFSSL_CM_VERIFY - /* if verify callback has been set */ - if (cm->verifyCallback) { - buffer certBuf; - #ifdef WOLFSSL_SMALL_STACK - ProcPeerCertArgs* args; - args = (ProcPeerCertArgs*)XMALLOC( - sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (args == NULL) { - XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); - return MEMORY_E; - } - #else - ProcPeerCertArgs args[1]; - #endif - - certBuf.buffer = (byte*)buff; - certBuf.length = (unsigned int)sz; - XMEMSET(args, 0, sizeof(ProcPeerCertArgs)); - - args->totalCerts = 1; - args->certs = &certBuf; - args->dCert = cert; - args->dCertInit = 1; - - if (err_val != 0) { - ret = err_val; - } - ret = DoVerifyCallback(cm, NULL, ret, args); - #ifdef WOLFSSL_SMALL_STACK - XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - #endif - } -#else - (void)err_val; -#endif - - FreeDecodedCert(cert); - FreeDer(&der); -#ifdef WOLFSSL_SMALL_STACK - XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); -#endif - - return ret == 0 ? WOLFSSL_SUCCESS : ret; -} - -/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */ -int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff, - long sz, int format) -{ - return CM_VerifyBuffer_ex(cm, buff, sz, format, 0); -} -#endif /* !NO_WOLFSSL_CLIENT || !WOLFSSL_NO_CLIENT_AUTH */ - -/* turn on OCSP if off and compiled in, set options */ -int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options) -{ - int ret = WOLFSSL_SUCCESS; - - (void)options; - - WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP"); - if (cm == NULL) - return BAD_FUNC_ARG; - - #ifdef HAVE_OCSP - if (cm->ocsp == NULL) { - cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap, - DYNAMIC_TYPE_OCSP); - if (cm->ocsp == NULL) - return MEMORY_E; - - if (InitOCSP(cm->ocsp, cm) != 0) { - WOLFSSL_MSG("Init OCSP failed"); - FreeOCSP(cm->ocsp, 1); - cm->ocsp = NULL; - return WOLFSSL_FAILURE; - } - } - cm->ocspEnabled = 1; - if (options & WOLFSSL_OCSP_URL_OVERRIDE) - cm->ocspUseOverrideURL = 1; - if (options & WOLFSSL_OCSP_NO_NONCE) - cm->ocspSendNonce = 0; - else - cm->ocspSendNonce = 1; - if (options & WOLFSSL_OCSP_CHECKALL) - cm->ocspCheckAll = 1; - #ifndef WOLFSSL_USER_IO - cm->ocspIOCb = EmbedOcspLookup; - cm->ocspRespFreeCb = EmbedOcspRespFree; - cm->ocspIOCtx = cm->heap; - #endif /* WOLFSSL_USER_IO */ - #else - ret = NOT_COMPILED_IN; - #endif - - return ret; -} - - -int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP"); - if (cm == NULL) - return BAD_FUNC_ARG; - - cm->ocspEnabled = 0; - - return WOLFSSL_SUCCESS; -} - -/* turn on OCSP Stapling if off and compiled in, set options */ -int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm) -{ - int ret = WOLFSSL_SUCCESS; - - WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling"); - - if (cm == NULL) - return BAD_FUNC_ARG; - -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ - || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - #ifndef NO_WOLFSSL_SERVER - if (cm->ocsp_stapling == NULL) { - cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), - cm->heap, DYNAMIC_TYPE_OCSP); - if (cm->ocsp_stapling == NULL) - return MEMORY_E; - - if (InitOCSP(cm->ocsp_stapling, cm) != 0) { - WOLFSSL_MSG("Init OCSP failed"); - FreeOCSP(cm->ocsp_stapling, 1); - cm->ocsp_stapling = NULL; - return WOLFSSL_FAILURE; - } - } - - #ifndef WOLFSSL_USER_IO - cm->ocspIOCb = EmbedOcspLookup; - cm->ocspRespFreeCb = EmbedOcspRespFree; - cm->ocspIOCtx = cm->heap; - #endif /* WOLFSSL_USER_IO */ - #endif /* NO_WOLFSSL_SERVER */ - cm->ocspStaplingEnabled = 1; -#else - ret = NOT_COMPILED_IN; -#endif - - return ret; -} - -int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm) -{ - int ret = WOLFSSL_SUCCESS; - - WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling"); - - if (cm == NULL) - return BAD_FUNC_ARG; - -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ - || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - cm->ocspStaplingEnabled = 0; -#else - ret = NOT_COMPILED_IN; -#endif - return ret; -} - -/* require OCSP stapling response */ -int wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm) -{ - int ret; - - WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPMustStaple"); - - if (cm == NULL) - return BAD_FUNC_ARG; - -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ - || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - #ifndef NO_WOLFSSL_CLIENT - cm->ocspMustStaple = 1; - #endif - ret = WOLFSSL_SUCCESS; -#else - ret = NOT_COMPILED_IN; -#endif - - return ret; -} - -int wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm) -{ - int ret; - - WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPMustStaple"); - - if (cm == NULL) - return BAD_FUNC_ARG; - -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ - || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - #ifndef NO_WOLFSSL_CLIENT - cm->ocspMustStaple = 0; - #endif - ret = WOLFSSL_SUCCESS; -#else - ret = NOT_COMPILED_IN; -#endif - return ret; -} - -#ifdef HAVE_OCSP -/* check CRL if enabled, WOLFSSL_SUCCESS */ -int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz) -{ - int ret; -#ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; -#else - DecodedCert cert[1]; -#endif - - WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP"); - - if (cm == NULL) - return BAD_FUNC_ARG; - - if (cm->ocspEnabled == 0) - return WOLFSSL_SUCCESS; - -#ifdef WOLFSSL_SMALL_STACK - cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, DYNAMIC_TYPE_DCERT); - if (cert == NULL) - return MEMORY_E; -#endif - - InitDecodedCert(cert, der, sz, NULL); - - if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) { - WOLFSSL_MSG("ParseCert failed"); - } - else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) { - WOLFSSL_MSG("CheckCertOCSP failed"); - } - - FreeDecodedCert(cert); -#ifdef WOLFSSL_SMALL_STACK - XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); -#endif - - return ret == 0 ? WOLFSSL_SUCCESS : ret; -} - -int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm, - byte *response, int responseSz, buffer *responseBuffer, - CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest) -{ - int ret; - - WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSPResponse"); - if (cm == NULL || response == NULL) - return BAD_FUNC_ARG; - if (cm->ocspEnabled == 0) - return WOLFSSL_SUCCESS; - - ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, status, - entry, ocspRequest, NULL); - - return ret == 0 ? WOLFSSL_SUCCESS : ret; -} - -int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm, - const char* url) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL"); - if (cm == NULL) - return BAD_FUNC_ARG; - - XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); - if (url != NULL) { - int urlSz = (int)XSTRLEN(url) + 1; - cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL); - if (cm->ocspOverrideURL != NULL) { - XMEMCPY(cm->ocspOverrideURL, url, urlSz); - } - else - return MEMORY_E; - } - else - cm->ocspOverrideURL = NULL; - - return WOLFSSL_SUCCESS; -} - - -int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm, - CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb"); - if (cm == NULL) - return BAD_FUNC_ARG; - - cm->ocspIOCb = ioCb; - cm->ocspRespFreeCb = respFreeCb; - cm->ocspIOCtx = ioCbCtx; - - return WOLFSSL_SUCCESS; -} - - -int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options) -{ - WOLFSSL_ENTER("wolfSSL_EnableOCSP"); - SSL_CM_WARNING(ssl); - if (ssl) - return wolfSSL_CertManagerEnableOCSP(SSL_CM(ssl), options); - else + WOLFSSL_ENTER("wolfSSL_EnableOCSP"); + SSL_CM_WARNING(ssl); + if (ssl) + return wolfSSL_CertManagerEnableOCSP(SSL_CM(ssl), options); + else return BAD_FUNC_ARG; } @@ -9404,210 +8564,9 @@ int wolfSSL_trust_peer_cert(WOLFSSL* ssl, const char* file, int type) } #endif /* WOLFSSL_TRUST_PEER_CERT */ - -#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) -/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */ -int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname, - int format) -{ - int ret = WOLFSSL_FATAL_ERROR; -#ifdef WOLFSSL_SMALL_STACK - byte staticBuffer[1]; /* force heap usage */ -#else - byte staticBuffer[FILE_BUFFER_SIZE]; -#endif - byte* myBuffer = staticBuffer; - int dynamic = 0; - long sz = 0; - XFILE file = XFOPEN(fname, "rb"); - - WOLFSSL_ENTER("wolfSSL_CertManagerVerify"); - - if (file == XBADFILE) return WOLFSSL_BAD_FILE; - if(XFSEEK(file, 0, XSEEK_END) != 0) { - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - sz = XFTELL(file); - if(XFSEEK(file, 0, XSEEK_SET) != 0) { - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - - if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) { - WOLFSSL_MSG("CertManagerVerify file size error"); - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - - if (sz > (long)sizeof(staticBuffer)) { - WOLFSSL_MSG("Getting dynamic buffer"); - myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE); - if (myBuffer == NULL) { - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - dynamic = 1; - } - - if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz) - ret = WOLFSSL_BAD_FILE; - else - ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format); - - XFCLOSE(file); - if (dynamic) - XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE); - - return ret; -} -#endif - -/* like load verify locations, 1 for success, < 0 for error */ -int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file, - const char* path) -{ - int ret = WOLFSSL_FATAL_ERROR; - WOLFSSL_CTX* tmp; - - WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA"); - - if (cm == NULL) { - WOLFSSL_MSG("No CertManager error"); - return ret; - } - tmp = wolfSSL_CTX_new(cm_pick_method()); - - if (tmp == NULL) { - WOLFSSL_MSG("CTX new failed"); - return ret; - } - - /* Some configurations like OPENSSL_COMPATIBLE_DEFAULTS may turn off - * verification by default. Let's restore our desired defaults. */ - wolfSSL_CTX_set_verify(tmp, WOLFSSL_VERIFY_DEFAULT, NULL); - - /* for tmp use */ - wolfSSL_CertManagerFree(tmp->cm); - tmp->cm = cm; - - ret = wolfSSL_CTX_load_verify_locations(tmp, file, path); - - /* don't lose our good one */ - tmp->cm = NULL; - wolfSSL_CTX_free(tmp); - - return ret; -} - - -#endif /* NO_FILESYSTEM */ - -#ifdef HAVE_CRL - -/* check CRL if enabled, WOLFSSL_SUCCESS */ -int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz) -{ - int ret = 0; -#ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; -#else - DecodedCert cert[1]; -#endif - - WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL"); - - if (cm == NULL) - return BAD_FUNC_ARG; - - if (cm->crlEnabled == 0) - return WOLFSSL_SUCCESS; - -#ifdef WOLFSSL_SMALL_STACK - cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT); - if (cert == NULL) - return MEMORY_E; -#endif - - InitDecodedCert(cert, der, sz, NULL); - - if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) { - WOLFSSL_MSG("ParseCert failed"); - } - else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) { - WOLFSSL_MSG("CheckCertCRL failed"); - } - - FreeDecodedCert(cert); -#ifdef WOLFSSL_SMALL_STACK - XFREE(cert, NULL, DYNAMIC_TYPE_DCERT); -#endif - - return ret == 0 ? WOLFSSL_SUCCESS : ret; -} - - -int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb"); - if (cm == NULL) - return BAD_FUNC_ARG; - - cm->cbMissingCRL = cb; - - return WOLFSSL_SUCCESS; -} - -#ifdef HAVE_CRL_IO -int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb) -{ - if (cm == NULL) - return BAD_FUNC_ARG; - - cm->crl->crlIOCb = cb; - - return WOLFSSL_SUCCESS; -} -#endif - -#ifndef NO_FILESYSTEM -int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path, - int type, int monitor) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL"); - if (cm == NULL) - return BAD_FUNC_ARG; - - if (cm->crl == NULL) { - if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Enable CRL failed"); - return WOLFSSL_FATAL_ERROR; - } - } - - return LoadCRL(cm->crl, path, type, monitor); -} - -int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, const char* file, - int type) -{ - WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLFile"); - if (cm == NULL || file == NULL) - return BAD_FUNC_ARG; - - if (cm->crl == NULL) { - if (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Enable CRL failed"); - return WOLFSSL_FATAL_ERROR; - } - } - - return ProcessFile(NULL, file, type, CRL_TYPE, NULL, 0, cm->crl, - VERIFY); -} -#endif +#endif /* NO_FILESYSTEM */ + +#ifdef HAVE_CRL int wolfSSL_EnableCRL(WOLFSSL* ssl, int options) { @@ -12274,462 +11233,6 @@ long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx) #endif /* NO_SESSION_CACHE */ - -#if !defined(NO_CERTS) -#if defined(PERSIST_CERT_CACHE) - - -#define WOLFSSL_CACHE_CERT_VERSION 1 - -typedef struct { - int version; /* cache cert layout version id */ - int rows; /* hash table rows, CA_TABLE_SIZE */ - int columns[CA_TABLE_SIZE]; /* columns per row on list */ - int signerSz; /* sizeof Signer object */ -} CertCacheHeader; - -/* current cert persistence layout is: - - 1) CertCacheHeader - 2) caTable - - update WOLFSSL_CERT_CACHE_VERSION if change layout for the following - PERSIST_CERT_CACHE functions -*/ - - -/* Return memory needed to persist this signer, have lock */ -static WC_INLINE int GetSignerMemory(Signer* signer) -{ - int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) - + sizeof(signer->nameLen) + sizeof(signer->subjectNameHash); - -#if !defined(NO_SKID) - sz += (int)sizeof(signer->subjectKeyIdHash); -#endif - - /* add dynamic bytes needed */ - sz += signer->pubKeySize; - sz += signer->nameLen; - - return sz; -} - - -/* Return memory needed to persist this row, have lock */ -static WC_INLINE int GetCertCacheRowMemory(Signer* row) -{ - int sz = 0; - - while (row) { - sz += GetSignerMemory(row); - row = row->next; - } - - return sz; -} - - -/* get the size of persist cert cache, have lock */ -static WC_INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm) -{ - int sz; - int i; - - sz = sizeof(CertCacheHeader); - - for (i = 0; i < CA_TABLE_SIZE; i++) - sz += GetCertCacheRowMemory(cm->caTable[i]); - - return sz; -} - - -/* Store cert cache header columns with number of items per list, have lock */ -static WC_INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns) -{ - int i; - Signer* row; - - for (i = 0; i < CA_TABLE_SIZE; i++) { - int count = 0; - row = cm->caTable[i]; - - while (row) { - ++count; - row = row->next; - } - columns[i] = count; - } -} - - -/* Restore whole cert row from memory, have lock, return bytes consumed, - < 0 on error, have lock */ -static WC_INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, - int row, int listSz, const byte* end) -{ - int idx = 0; - - if (listSz < 0) { - WOLFSSL_MSG("Row header corrupted, negative value"); - return PARSE_ERROR; - } - - while (listSz) { - Signer* signer; - byte* publicKey; - byte* start = current + idx; /* for end checks on this signer */ - int minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) + - sizeof(signer->nameLen) + sizeof(signer->subjectNameHash); - #ifndef NO_SKID - minSz += (int)sizeof(signer->subjectKeyIdHash); - #endif - - if (start + minSz > end) { - WOLFSSL_MSG("Would overread restore buffer"); - return BUFFER_E; - } - signer = MakeSigner(cm->heap); - if (signer == NULL) - return MEMORY_E; - - /* pubKeySize */ - XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize)); - idx += (int)sizeof(signer->pubKeySize); - - /* keyOID */ - XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID)); - idx += (int)sizeof(signer->keyOID); - - /* publicKey */ - if (start + minSz + signer->pubKeySize > end) { - WOLFSSL_MSG("Would overread restore buffer"); - FreeSigner(signer, cm->heap); - return BUFFER_E; - } - publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap, - DYNAMIC_TYPE_KEY); - if (publicKey == NULL) { - FreeSigner(signer, cm->heap); - return MEMORY_E; - } - - XMEMCPY(publicKey, current + idx, signer->pubKeySize); - signer->publicKey = publicKey; - idx += signer->pubKeySize; - - /* nameLen */ - XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen)); - idx += (int)sizeof(signer->nameLen); - - /* name */ - if (start + minSz + signer->pubKeySize + signer->nameLen > end) { - WOLFSSL_MSG("Would overread restore buffer"); - FreeSigner(signer, cm->heap); - return BUFFER_E; - } - signer->name = (char*)XMALLOC(signer->nameLen, cm->heap, - DYNAMIC_TYPE_SUBJECT_CN); - if (signer->name == NULL) { - FreeSigner(signer, cm->heap); - return MEMORY_E; - } - - XMEMCPY(signer->name, current + idx, signer->nameLen); - idx += signer->nameLen; - - /* subjectNameHash */ - XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE); - idx += SIGNER_DIGEST_SIZE; - - #ifndef NO_SKID - /* subjectKeyIdHash */ - XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE); - idx += SIGNER_DIGEST_SIZE; - #endif - - signer->next = cm->caTable[row]; - cm->caTable[row] = signer; - - --listSz; - } - - return idx; -} - - -/* Store whole cert row into memory, have lock, return bytes added */ -static WC_INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row) -{ - int added = 0; - Signer* list = cm->caTable[row]; - - while (list) { - XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize)); - added += (int)sizeof(list->pubKeySize); - - XMEMCPY(current + added, &list->keyOID, sizeof(list->keyOID)); - added += (int)sizeof(list->keyOID); - - XMEMCPY(current + added, list->publicKey, list->pubKeySize); - added += list->pubKeySize; - - XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen)); - added += (int)sizeof(list->nameLen); - - XMEMCPY(current + added, list->name, list->nameLen); - added += list->nameLen; - - XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE); - added += SIGNER_DIGEST_SIZE; - - #ifndef NO_SKID - XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE); - added += SIGNER_DIGEST_SIZE; - #endif - - list = list->next; - } - - return added; -} - - -/* Persist cert cache to memory, have lock */ -static WC_INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, - void* mem, int sz) -{ - int realSz; - int ret = WOLFSSL_SUCCESS; - int i; - - WOLFSSL_ENTER("DoMemSaveCertCache"); - - realSz = GetCertCacheMemSize(cm); - if (realSz > sz) { - WOLFSSL_MSG("Mem output buffer too small"); - ret = BUFFER_E; - } - else { - byte* current; - CertCacheHeader hdr; - - hdr.version = WOLFSSL_CACHE_CERT_VERSION; - hdr.rows = CA_TABLE_SIZE; - SetCertHeaderColumns(cm, hdr.columns); - hdr.signerSz = (int)sizeof(Signer); - - XMEMCPY(mem, &hdr, sizeof(CertCacheHeader)); - current = (byte*)mem + sizeof(CertCacheHeader); - - for (i = 0; i < CA_TABLE_SIZE; ++i) - current += StoreCertRow(cm, current, i); - } - - return ret; -} - - -#if !defined(NO_FILESYSTEM) - -/* Persist cert cache to file */ -int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname) -{ - XFILE file; - int rc = WOLFSSL_SUCCESS; - int memSz; - byte* mem; - - WOLFSSL_ENTER("CM_SaveCertCache"); - - file = XFOPEN(fname, "w+b"); - if (file == XBADFILE) { - WOLFSSL_MSG("Couldn't open cert cache save file"); - return WOLFSSL_BAD_FILE; - } - - if (wc_LockMutex(&cm->caLock) != 0) { - WOLFSSL_MSG("wc_LockMutex on caLock failed"); - XFCLOSE(file); - return BAD_MUTEX_E; - } - - memSz = GetCertCacheMemSize(cm); - mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (mem == NULL) { - WOLFSSL_MSG("Alloc for tmp buffer failed"); - rc = MEMORY_E; - } else { - rc = DoMemSaveCertCache(cm, mem, memSz); - if (rc == WOLFSSL_SUCCESS) { - int ret = (int)XFWRITE(mem, memSz, 1, file); - if (ret != 1) { - WOLFSSL_MSG("Cert cache file write failed"); - rc = FWRITE_ERROR; - } - } - XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - } - - wc_UnLockMutex(&cm->caLock); - XFCLOSE(file); - - return rc; -} - - -/* Restore cert cache from file */ -int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname) -{ - XFILE file; - int rc = WOLFSSL_SUCCESS; - int ret; - int memSz; - byte* mem; - - WOLFSSL_ENTER("CM_RestoreCertCache"); - - file = XFOPEN(fname, "rb"); - if (file == XBADFILE) { - WOLFSSL_MSG("Couldn't open cert cache save file"); - return WOLFSSL_BAD_FILE; - } - - if(XFSEEK(file, 0, XSEEK_END) != 0) { - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - memSz = (int)XFTELL(file); - if(XFSEEK(file, 0, XSEEK_SET) != 0) { - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - - if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz <= 0) { - WOLFSSL_MSG("CM_RestoreCertCache file size error"); - XFCLOSE(file); - return WOLFSSL_BAD_FILE; - } - - mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (mem == NULL) { - WOLFSSL_MSG("Alloc for tmp buffer failed"); - XFCLOSE(file); - return MEMORY_E; - } - - ret = (int)XFREAD(mem, memSz, 1, file); - if (ret != 1) { - WOLFSSL_MSG("Cert file read error"); - rc = FREAD_ERROR; - } else { - rc = CM_MemRestoreCertCache(cm, mem, memSz); - if (rc != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Mem restore cert cache failed"); - } - } - - XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFCLOSE(file); - - return rc; -} - -#endif /* NO_FILESYSTEM */ - - -/* Persist cert cache to memory */ -int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used) -{ - int ret = WOLFSSL_SUCCESS; - - WOLFSSL_ENTER("CM_MemSaveCertCache"); - - if (wc_LockMutex(&cm->caLock) != 0) { - WOLFSSL_MSG("wc_LockMutex on caLock failed"); - return BAD_MUTEX_E; - } - - ret = DoMemSaveCertCache(cm, mem, sz); - if (ret == WOLFSSL_SUCCESS) - *used = GetCertCacheMemSize(cm); - - wc_UnLockMutex(&cm->caLock); - - return ret; -} - - -/* Restore cert cache from memory */ -int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz) -{ - int ret = WOLFSSL_SUCCESS; - int i; - CertCacheHeader* hdr = (CertCacheHeader*)mem; - byte* current = (byte*)mem + sizeof(CertCacheHeader); - byte* end = (byte*)mem + sz; /* don't go over */ - - WOLFSSL_ENTER("CM_MemRestoreCertCache"); - - if (current > end) { - WOLFSSL_MSG("Cert Cache Memory buffer too small"); - return BUFFER_E; - } - - if (hdr->version != WOLFSSL_CACHE_CERT_VERSION || - hdr->rows != CA_TABLE_SIZE || - hdr->signerSz != (int)sizeof(Signer)) { - - WOLFSSL_MSG("Cert Cache Memory header mismatch"); - return CACHE_MATCH_ERROR; - } - - if (wc_LockMutex(&cm->caLock) != 0) { - WOLFSSL_MSG("wc_LockMutex on caLock failed"); - return BAD_MUTEX_E; - } - - FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); - - for (i = 0; i < CA_TABLE_SIZE; ++i) { - int added = RestoreCertRow(cm, current, i, hdr->columns[i], end); - if (added < 0) { - WOLFSSL_MSG("RestoreCertRow error"); - ret = added; - break; - } - current += added; - } - - wc_UnLockMutex(&cm->caLock); - - return ret; -} - - -/* get how big the the cert cache save buffer needs to be */ -int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm) -{ - int sz; - - WOLFSSL_ENTER("CM_GetCertCacheMemSize"); - - if (wc_LockMutex(&cm->caLock) != 0) { - WOLFSSL_MSG("wc_LockMutex on caLock failed"); - return BAD_MUTEX_E; - } - - sz = GetCertCacheMemSize(cm); - - wc_UnLockMutex(&cm->caLock); - - return sz; -} - -#endif /* PERSIST_CERT_CACHE */ -#endif /* NO_CERTS */ - #ifdef OPENSSL_EXTRA /* diff --git a/src/ssl_certman.c b/src/ssl_certman.c new file mode 100644 index 0000000000..03322cc782 --- /dev/null +++ b/src/ssl_certman.c @@ -0,0 +1,2355 @@ +/* ssl_certman.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + + #include + +#if !defined(WOLFSSL_SSL_CERTMAN_INCLUDED) + #ifndef WOLFSSL_IGNORE_FILE_WARN + #warning ssl_certman.c does not need to be compiled separately from ssl.c + #endif +#else + +#ifndef NO_CERTS + +/* Pick an available TLS method. + * + * Used when creating temporary WOLFSSL_CTX. + * + * @return A TLS method on success. + * @return NULL when no TLS method built into wolfSSL. + */ +static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void) +{ + #ifndef NO_WOLFSSL_CLIENT + #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) + return wolfSSLv3_client_method(); + #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10) + return wolfTLSv1_client_method(); + #elif !defined(NO_OLD_TLS) + return wolfTLSv1_1_client_method(); + #elif !defined(WOLFSSL_NO_TLS12) + return wolfTLSv1_2_client_method(); + #elif defined(WOLFSSL_TLS13) + return wolfTLSv1_3_client_method(); + #else + return NULL; + #endif + #elif !defined(NO_WOLFSSL_SERVER) + #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) + return wolfSSLv3_server_method(); + #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10) + return wolfTLSv1_server_method(); + #elif !defined(NO_OLD_TLS) + return wolfTLSv1_1_server_method(); + #elif !defined(WOLFSSL_NO_TLS12) + return wolfTLSv1_2_server_method(); + #elif defined(WOLFSSL_TLS13) + return wolfTLSv1_3_server_method(); + #else + return NULL; + #endif + #else + return NULL; + #endif +} + +/* Create a new certificate manager with a heap hint. + * + * @param [in] heap Heap hint. + * @return Certificate manager object on success. + * @return NULL on failure. + */ +WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap) +{ + int err = 0; + WOLFSSL_CERT_MANAGER* cm; + + WOLFSSL_ENTER("wolfSSL_CertManagerNew"); + + /* Allocate memory for certificate manager. */ + cm = (WOLFSSL_CERT_MANAGER*)XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap, + DYNAMIC_TYPE_CERT_MANAGER); + if (cm == NULL) { + err = 1; + } + if (!err) { + /* Reset all fields. */ + XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER)); + + /* Create a mutex for use when modify table of stored CAs. */ + if (wc_InitMutex(&cm->caLock) != 0) { + WOLFSSL_MSG("Bad mutex init"); + err = 1; + } + } + if (!err) { + /* Initialize reference count. */ + wolfSSL_RefInit(&cm->ref, &err); + #ifdef WOLFSSL_REFCNT_ERROR_RETURN + if (err != 0) { + WOLFSSL_MSG("Bad reference count init"); + } + #endif + } +#ifdef WOLFSSL_TRUST_PEER_CERT + /* Create a mutex for use when modify table of trusted peers. */ + if ((!err) && (wc_InitMutex(&cm->tpLock) != 0)) { + WOLFSSL_MSG("Bad mutex init"); + err = 1; + } +#endif + if (!err) { + /* Set default minimum key sizes allowed. */ + #ifndef NO_RSA + cm->minRsaKeySz = MIN_RSAKEY_SZ; + #endif + #ifdef HAVE_ECC + cm->minEccKeySz = MIN_ECCKEY_SZ; + #endif + #ifdef HAVE_PQC + #ifdef HAVE_FALCON + cm->minFalconKeySz = MIN_FALCONKEY_SZ; + #endif /* HAVE_FALCON */ + #ifdef HAVE_DILITHIUM + cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ; + #endif /* HAVE_DILITHIUM */ + #endif /* HAVE_PQC */ + + /* Set heap hint to use in certificate manager operations. */ + cm->heap = heap; + } + + /* Dispose of certificate manager on error. */ + if (err && (cm != NULL)) { + wolfSSL_CertManagerFree(cm); + cm = NULL; + } + return cm; +} + +/* Create a new certificate manager. + * + * @return Certificate manager object on success. + * @return NULL on failure. + */ +WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void) +{ + /* No heap hint. */ + return wolfSSL_CertManagerNew_ex(NULL); +} + +/* Dispose of certificate manager. + * + * @param [in, out] cm Certificate manager. + */ +void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) +{ + WOLFSSL_ENTER("wolfSSL_CertManagerFree"); + + /* Validate parameter. */ + if (cm != NULL) { + int doFree = 0; + int ret; + + /* Decrement reference count and check if value is 0. */ + wolfSSL_RefDec(&cm->ref, &doFree, &ret); + #ifdef WOLFSSL_REFCNT_ERROR_RETURN + if (ret != 0) { + WOLFSSL_MSG("Couldn't lock cm mutex"); + } + #else + (void)ret; + #endif + if (doFree) { + #ifdef HAVE_CRL + /* Dispose of CRL handler. */ + if (cm->crl != NULL) { + /* Dispose of CRL object - indicating dynamicly allocated. */ + FreeCRL(cm->crl, 1); + } + #endif + + #ifdef HAVE_OCSP + /* Dispose of OCSP handler. */ + if (cm->ocsp != NULL) { + FreeOCSP(cm->ocsp, 1); + } + /* Dispose of URL. */ + XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); + #if !defined(NO_WOLFSSL_SERVER) && \ + (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + /* Dispose of OCSP stapling handler. */ + if (cm->ocsp_stapling) { + FreeOCSP(cm->ocsp_stapling, 1); + } + #endif + #endif /* HAVE_OCSP */ + + /* Dispose of CA table and mutex. */ + FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); + wc_FreeMutex(&cm->caLock); + + #ifdef WOLFSSL_TRUST_PEER_CERT + /* Dispose of trusted peer table and mutex. */ + FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); + wc_FreeMutex(&cm->tpLock); + #endif + + /* Dispose of reference count. */ + wolfSSL_RefFree(&cm->ref); + /* Dispose of certificate manager memory. */ + XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); + } + } +} + +/* Increase reference count on certificate manager. + * + * @param [in, out] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return 0 when cm is NULL or locking mutex fails. + */ +int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + /* Validate parameter. */ + if (cm == NULL) { + ret = 0; + } + if (ret == WOLFSSL_SUCCESS) { + int err; + + /* Increment reference. */ + wolfSSL_RefInc(&cm->ref, &err); + #ifdef WOLFSSL_REFCNT_ERROR_RETURN + if (err) { + WOLFSSL_MSG("Failed to lock cm mutex"); + ret = 0; + } + #else + (void)err; + #endif + } + + return ret; +} + +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) +#if defined(WOLFSSL_SIGNER_DER_CERT) +static WC_INLINE int wolfssl_cm_get_certs_der(WOLFSSL_CERT_MANAGER* cm, + DerBuffer*** buffers, int* cnt) +{ + int err = 0; + Signer* signers = NULL; + DerBuffer** certBuffers = NULL; + int i = 0; + word32 row = 0; + int numCerts = 0; + + /* Iterate once to get the number of certs, for memory allocation + * purposes. */ + for (row = 0; row < CA_TABLE_SIZE; row++) { + /* Get signer information of CAs in a row. */ + signers = cm->caTable[row]; + /* Count each signer in row that has a DER certificate buffer. */ + while ((signers != NULL) && (signers->derCert != NULL) && + (signers->derCert->buffer != NULL)) { + ++numCerts; + signers = signers->next; + } + } + /* Check we found certificates. */ + if (numCerts == 0) { + err = 1; + } + + if (!err) { + /* Allocate memory for pointers to each DER buffer. */ + certBuffers = (DerBuffer**)XMALLOC(sizeof(DerBuffer*) * numCerts, + cm->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (certBuffers == NULL) { + err = 1; + } + } + if (!err) { + /* Reset pointers. */ + XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * numCerts); + } + + /* Copy the certs locally so that we can release the caLock. If the lock + * is held when wolfSSL_d2i_X509 is called, GetCA will also try to get + * the lock, leading to deadlock. */ + for (row = 0; (!err) && (row < CA_TABLE_SIZE); row++) { + /* Get signer information of CAs in a row. */ + signers = cm->caTable[row]; + /* Copy each DER certificate buffer of signers in a row. */ + while ((signers != NULL) && (signers->derCert != NULL) && + (signers->derCert->buffer != NULL)) { + /* Allocate memory to hold DER certificate buffer. */ + int ret = AllocDer(&certBuffers[i], signers->derCert->length, + CA_TYPE, cm->heap); + if (ret < 0) { + err = 1; + break; + } + + /* Copy buffer into array element. */ + XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer, + signers->derCert->length); + certBuffers[i]->length = signers->derCert->length; + + /* Store in next index. */ + ++i; + /* Move on to next signer in row. */ + signers = signers->next; + } + } + + *buffers = certBuffers; + *cnt = numCerts; + return err; +} + +/* Retrieve stack of X509 certificates in a certificate manager (CM). + * + * @param [in] cm Certificate manager. + * + * @return Stack of X509 certs on success + * @return NULL on failure. + */ +WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) +{ + WOLFSSL_STACK* sk = NULL; + int numCerts = 0; + DerBuffer** certBuffers = NULL; + int i = 0; + int err = 0; + + WOLFSSL_ENTER("wolfSSL_CertManagerGetCerts"); + + /* Validate parameter. */ + if (cm == NULL) { + err = 1; + } + if (!err) { + /* Create an empty certificate stack to return. */ + sk = wolfSSL_sk_X509_new_null(); + if (sk == NULL) { + err = 1; + } + } + /* Lock CA table. */ + if ((!err) && (wc_LockMutex(&cm->caLock) != 0)) { + err = 1; + } + if (!err) { + err = wolfssl_cm_get_certs_der(cm, &certBuffers, &numCerts); + /* Release CA lock. */ + wc_UnLockMutex(&cm->caLock); + } + + /* Put each DER certificate buffer into a stack of WOLFSSL_X509 */ + for (i = 0; (!err) && (i < numCerts); ++i) { + const byte* derBuffer = NULL; + WOLFSSL_X509* x509 = NULL; + + /* Get pointer to DER encoding of certificate. */ + derBuffer = certBuffers[i]->buffer; + /* Decode certificate. */ + wolfSSL_d2i_X509(&x509, &derBuffer, certBuffers[i]->length); + if (x509 == NULL) { + err = 1; + } + + /* Decode certificate. */ + if ((!err) && (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)) { + wolfSSL_X509_free(x509); + err = 1; + } + } + + if (certBuffers != NULL) { + /* Dispose of temporary cert storage (for access outside of lock). */ + for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) { + FreeDer(&certBuffers[i]); + } + XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* Dispose of stack of certificates on error. */ + if (err && (sk != NULL)) { + wolfSSL_sk_X509_pop_free(sk, NULL); + sk = NULL; + } + return sk; +} + +#endif /* WOLFSSL_SIGNER_DER_CERT */ +#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */ + +/* Unload the CA signer table. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + * @return BAD_MUTEX_E when locking fails. + */ +int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + /* Lock CA table. */ + if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) { + ret = BAD_MUTEX_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Dispose of CA table. */ + FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); + + /* Unlock CA table. */ + wc_UnLockMutex(&cm->caLock); + } + + return ret; +} + + +#ifdef WOLFSSL_TRUST_PEER_CERT +/* Unload the trusted peers table. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + * @return BAD_MUTEX_E when locking fails. + */ +int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + /* Lock trusted peers table. */ + if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->tpLock) != 0)) { + ret = BAD_MUTEX_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Dispose of trusted peers table. */ + FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); + + /* Unlock trusted peers table. */ + wc_UnLockMutex(&cm->tpLock); + } + + return ret; +} +#endif /* WOLFSSL_TRUST_PEER_CERT */ + +/* Load certificate/s from buffer with flags. + * + * @param [in] cm Certificate manager. + * @param [in] buff Buffer holding encoding of certificate. + * @param [in] sz Length in bytes of data in buffer. + * @param [in] format Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @param [in] userChain Indicates buffer holds chain of certificates. + * @param [in] flags Flags to modify behaviour of loading. Valid flags: + * WOLFSSL_LOAD_FLAG_IGNORE_ERR, + * WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY, + * WOLFSSL_LOAD_FLAG_PEM_CA_ONLY, + * WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR, and + * WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE. + * @return WOLFSSL_SUCCESS on success. + * @return WOLFSSL_FATAL_ERROR when cm is NULL or failed create WOLFSSL_CTX. + * @return Other values on loading failure. + */ +int wolfSSL_CertManagerLoadCABuffer_ex(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* buff, long sz, int format, int userChain, word32 flags) +{ + int ret = WOLFSSL_SUCCESS; + WOLFSSL_CTX* tmp = NULL; + + WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer_ex"); + + /* Validate parameters. */ + if (cm == NULL) { + WOLFSSL_MSG("No CertManager error"); + ret = WOLFSSL_FATAL_ERROR; + } + /* Allocate a temporary WOLFSSL_CTX to load with. */ + if ((ret == WOLFSSL_SUCCESS) && ((tmp = wolfSSL_CTX_new(cm_pick_method())) + == NULL)) { + WOLFSSL_MSG("CTX new failed"); + ret = WOLFSSL_FATAL_ERROR; + } + if (ret == WOLFSSL_SUCCESS) { + /* Replace certificate manager with one to load certificate/s into. */ + wolfSSL_CertManagerFree(tmp->cm); + tmp->cm = cm; + + /* Load certificate buffer. */ + ret = wolfSSL_CTX_load_verify_buffer_ex(tmp, buff, sz, format, + userChain, flags); + + /* Clear certificate manager in WOLFSSL_CTX so it won't be freed. */ + tmp->cm = NULL; + } + + /* Dispose of temporary WOLFSSL_CTX. */ + wolfSSL_CTX_free(tmp); + return ret; +} + +/* Load certificate/s from buffer into table. + * + * Uses default load verification flags and is not a user chain. + * + * @param [in] cm Certificate manager. + * @param [in] buff Buffer holding encoding of certificate. + * @param [in] sz Length in bytes of data in buffer. + * @param [in] format Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @return WOLFSSL_SUCCESS on success. + * @return WOLFSSL_FATAL_ERROR when cm is NULL or failed create WOLFSSL_CTX. + * @return Other values on loading failure. + */ +int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* buff, long sz, int format) +{ + return wolfSSL_CertManagerLoadCABuffer_ex(cm, buff, sz, format, 0, + WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS); +} + +#ifndef NO_WOLFSSL_CM_VERIFY +/* Set the verification callback into certificate manager. + * + * @param [in] cm Certificate manager. + * @param [in] vc Verification callback. + */ +void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc) +{ + WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify"); + if (cm != NULL) { + cm->verifyCallback = vc; + } +} +#endif /* NO_WOLFSSL_CM_VERIFY */ + +#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) +/* Verify the certificate. + * + * Uses the verification callback if available. + * + * @param [in] cm Certificate manager. + * @param [in] buff Buffer holding encoded certificate. + * @param [in] sz Size in bytes of data in buffer. + * @param [in] format Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @param [in] prev_err Previous error. Passed to callback. + * @return WOLFSSL_SUCCESS on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return NOT_COMPILED_IN when converting from PEM to DER is not a feature of + * the wolfSSL build. + */ +int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const unsigned char* buff, + long sz, int format, int prev_err) +{ + int ret = 0; + int fatal = 0; + DerBuffer* der = NULL; +#ifdef WOLFSSL_SMALL_STACK + DecodedCert* cert = NULL; +#else + DecodedCert cert[1]; +#endif + + WOLFSSL_ENTER("CM_VerifyBuffer_ex"); + + (void)prev_err; + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate memory for decoded certificate. */ + cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, + DYNAMIC_TYPE_DCERT); + if (cert == NULL) { + ret = MEMORY_E; + fatal = 1; + } + if (ret == 0) +#endif + { + /* Reset fields of decoded certifcate. */ + XMEMSET(cert, 0, sizeof(DecodedCert)); + + if (format == WOLFSSL_FILETYPE_PEM) { + #ifndef WOLFSSL_PEM_TO_DER + ret = NOT_COMPILED_IN; + fatal = 1; + #else + /* Convert to DER from PEM. */ + ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL); + if (ret != 0) { + fatal = 1; + } + else { + /* Replace buffer pointer and size with DER buffer. */ + buff = der->buffer; + sz = (long)der->length; + } + #endif + } + } + if (ret == 0) { + /* Create a decoded certificate with DER buffer. */ + InitDecodedCert(cert, buff, (word32)sz, cm->heap); + + /* Parse DER into decoded certificate fields and verify signature + * against a known CA. */ + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, cm); + } + +#ifdef HAVE_CRL + if ((ret == 0) && cm->crlEnabled) { + /* Check for a CRL for the CA and check validity of certificate. */ + ret = CheckCertCRL(cm->crl, cert); + } +#endif + + (void)fatal; + +#ifndef NO_WOLFSSL_CM_VERIFY + /* Use callback to perform verification too if available. */ + if ((!fatal) && cm->verifyCallback) { + #ifdef WOLFSSL_SMALL_STACK + ProcPeerCertArgs* args; + #else + ProcPeerCertArgs args[1]; + #endif + buffer certBuf; + + #ifdef WOLFSSL_SMALL_STACK + /* Allocate memory for object to hold arguements for callback. */ + args = (ProcPeerCertArgs*)XMALLOC(sizeof(ProcPeerCertArgs), cm->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (args == NULL) { + ret = MEMORY_E; + fatal = 1; + } + if (!fatal) + #endif + { + XMEMSET(args, 0, sizeof(ProcPeerCertArgs)); + + /* DER encoding. */ + certBuf.buffer = (byte*)buff; + certBuf.length = (unsigned int)sz; + + /* One certificate available. */ + args->totalCerts = 1; + args->certs = &certBuf; + args->dCert = cert; + args->dCertInit = 1; + + /* Replace value in ret with an error value passed in. */ + if (prev_err != 0) { + ret = prev_err; + } + /* Use callback to verify certificate. */ + ret = DoVerifyCallback(cm, NULL, ret, args); + } + #ifdef WOLFSSL_SMALL_STACK + /* Dispose of allocated callback args. */ + XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + } +#endif + + /* Dispose of allocated memory. */ + FreeDecodedCert(cert); + FreeDer(&der); +#ifdef WOLFSSL_SMALL_STACK + XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); +#endif + + /* Convert the ret value to a return value. */ + return (ret == 0) ? WOLFSSL_SUCCESS : ret; +} + +/* Verify the certificate. + * + * Uses the verification callback if available. + * + * @param [in] cm Certificate manager. + * @param [in] buff Buffer holding encoded certificate. + * @param [in] sz Size in bytes of data in buffer. + * @param [in] format Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @param [in] prev_err Previous error. Passed to callback. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm or buff is NULL ot sz is negativei or zero. + * @return WOLFSSL_BAD_FILETYPE when format is invalid. + * @return MEMORY_E when dynamic memory allocation fails. + * @return NOT_COMPILED_IN when converting from PEM to DER is not a feature of + * the wolfSSL build. + */ +int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* buff, long sz, int format) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer"); + + /* Validate parameters. */ + if ((cm == NULL) || (buff == NULL) || (sz <= 0)) { + ret = BAD_FUNC_ARG; + } + else if ((format != WOLFSSL_FILETYPE_ASN1) && + (format != WOLFSSL_FILETYPE_PEM)) { + ret = WOLFSSL_BAD_FILETYPE; + } + else { + /* No previous error. */ + ret = CM_VerifyBuffer_ex(cm, buff, sz, format, 0); + } + + return ret; +} +#endif /* !NO_WOLFSSL_CLIENT || !WOLFSSL_NO_CLIENT_AUTH */ + +#ifndef NO_FILESYSTEM + +#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) +/* Verify the certificate loaded from a file. + * + * Uses the verification callback if available. + * + * @param [in] cm Certificate manager. + * @param [in] format Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @param [in] prev_err Previous error. Passed to callback. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm or buff is NULL ot sz is negative. + * @return WOLFSSL_BAD_FILETYPE when format is invalid. + * @return WOLFSSL_BAD_FILE when reading the certificate file fails. + * @return MEMORY_E when dynamic memory allocation fails. + * @return NOT_COMPILED_IN when converting from PEM to DER is not a feature of + * the wolfSSL build. + */ +int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname, + int format) +{ + int ret = WOLFSSL_SUCCESS; +#ifndef WOLFSSL_SMALL_STACK + byte staticBuffer[FILE_BUFFER_SIZE]; +#endif + byte* buff; + long sz = 0; + XFILE file = XBADFILE; + + WOLFSSL_ENTER("wolfSSL_CertManagerVerify"); + +#ifndef WOLFSSL_SMALL_STACK + buff = staticBuffer; +#endif + + /* Validate parameters. cm and format validated in: + * wolfSSL_CertManagerVerifyBuffer */ + if ((cm == NULL) || (fname == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* Open the file containing a certificate. */ + if ((ret == WOLFSSL_SUCCESS) && + ((file = XFOPEN(fname, "rb")) == XBADFILE)) { + ret = WOLFSSL_BAD_FILE; + } + /* Get the length of the file. */ + if (ret == WOLFSSL_SUCCESS) { + ret = wolfssl_file_len(file, &sz); + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + } + } + /* Allocate dynamic memory for file contents if no static buffer or too + * small. */ +#ifndef WOLFSSL_SMALL_STACK + if ((ret == WOLFSSL_SUCCESS) && (sz > (long)sizeof(staticBuffer))) +#endif + { + WOLFSSL_MSG("Getting dynamic buffer"); + buff = (byte*)XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE); + if (buff == NULL) { + ret = WOLFSSL_BAD_FILE; + } + } + /* Read all the file into buffer. */ + if ((ret == WOLFSSL_SUCCESS) && ((size_t)XFREAD(buff, 1, sz, file) != + (size_t)sz)) { + ret = WOLFSSL_BAD_FILE; + } + /* Close file if opened. */ + if (file != XBADFILE) { + XFCLOSE(file); + } + if (ret == WOLFSSL_SUCCESS) { + /* Verify the certificate read. */ + ret = wolfSSL_CertManagerVerifyBuffer(cm, buff, sz, format); + } + + /* Dispose of buffer if it was allocated. */ +#ifndef WOLFSSL_SMALL_STACK + if (buff != staticBuffer) +#endif + { + XFREE(buff, cm->heap, DYNAMIC_TYPE_FILE); + } + return ret; +} +#endif + +/* Load the CA file and/or certificate files in a path. + * + * @param [in] cm Certificate manager. + * @param [in] file Name of CA file. + * @param [in] path Path to a directory containing certificates. + * @return WOLFSSL_SUCCESS on success. + * @return WOLFSSL_FATAL_ERROR when cm is NULL or unalbe to create WOLFSSL_CTX. + * @return Otherwise failure. + */ +int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file, + const char* path) +{ + int ret = WOLFSSL_SUCCESS; + WOLFSSL_CTX* tmp = NULL; + + WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA"); + + /* Validate parameters. file and path validated in: + * wolfSSL_CTX_load_verify_locations*/ + if (cm == NULL) { + WOLFSSL_MSG("No CertManager error"); + ret = WOLFSSL_FATAL_ERROR; + } + /* Create temporary WOLFSSL_CTX. */ + if ((ret == WOLFSSL_SUCCESS) && ((tmp = wolfSSL_CTX_new(cm_pick_method())) + == NULL)) { + WOLFSSL_MSG("CTX new failed"); + ret = WOLFSSL_FATAL_ERROR; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Replace certificate manager with one to load certificate/s into. */ + wolfSSL_CertManagerFree(tmp->cm); + tmp->cm = cm; + + ret = wolfSSL_CTX_load_verify_locations(tmp, file, path); + + /* Clear certificate manager in WOLFSSL_CTX so it won't be freed. */ + tmp->cm = NULL; + } + + /* Dispose of temporary WOLFSSL_CTX. */ + wolfSSL_CTX_free(tmp); + return ret; +} + +#endif /* NO_FILESYSTEM */ + +#if defined(PERSIST_CERT_CACHE) + +/* Version of layout of cache of CA certificates. */ +#define WOLFSSL_CACHE_CERT_VERSION 1 + +/* CA certificates cache information. */ +typedef struct { + /* Cache certficate layout version id. */ + int version; + /* Number of hash table rows. Maximum of CA_TABLE_SIZE. */ + int rows; + /* Number of colums per row. */ + int columns[CA_TABLE_SIZE]; + /* Size of Signer object. */ + int signerSz; +} CertCacheHeader; + +/* current cert persistence layout is: + + 1) CertCacheHeader + 2) caTable + + update WOLFSSL_CERT_CACHE_VERSION if change layout for the following + PERSIST_CERT_CACHE functions +*/ + + +/* Return number of bytes of memory needed to persist this signer. + * + * Assumes we have locked CA table. + * + * @param [in] Signer Signer entry in CA table. + * @return Number of bytes. + */ +static WC_INLINE int cm_get_signer_memory(Signer* signer) +{ + int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) + + sizeof(signer->nameLen) + sizeof(signer->subjectNameHash); + +#if !defined(NO_SKID) + sz += (int)sizeof(signer->subjectKeyIdHash); +#endif + + /* Add dynamic bytes needed. */ + sz += signer->pubKeySize; + sz += signer->nameLen; + + return sz; +} + + +/* Return number of bytes of memory needed to persist this row. + * + * Assumes we have locked CA table. + * + * @param [in] row A row of signers from the CA table. + * @return Number of bytes. + */ +static WC_INLINE int cm_get_cert_cache_row_memory(Signer* row) +{ + int sz = 0; + + /* Each signer in row. */ + while (row != NULL) { + /* Add in size of this signer. */ + sz += cm_get_signer_memory(row); + row = row->next; + } + + return sz; +} + + +/* Return the number of bytes of memory to persist cert cache. + * + * Assumes we have locked CA table. + * + * @param [in] cm Certificate manager. + * @return Number of bytes. + */ +static WC_INLINE int cm_get_cert_cache_mem_size(WOLFSSL_CERT_MANAGER* cm) +{ + int sz; + int i; + + sz = sizeof(CertCacheHeader); + + /* Each row in table. */ + for (i = 0; i < CA_TABLE_SIZE; i++) { + /* Add in size of this row. */ + sz += cm_get_cert_cache_row_memory(cm->caTable[i]); + } + + return sz; +} + + +/* Get count of colums for each row. + * + * Assumes we have locked CA table. + * + * @param [in] cm Certificate manager. + * @param [in] columns Array of row counts. + */ +static WC_INLINE void cm_set_cert_header_Columns(WOLFSSL_CERT_MANAGER* cm, + int* columns) +{ + int i; + Signer* row; + + /* Each row in table. */ + for (i = 0; i < CA_TABLE_SIZE; i++) { + int count = 0; + + /* Get row from table. */ + row = cm->caTable[i]; + /* Each entry in row. */ + while (row != NULL) { + /* Update count. */ + ++count; + row = row->next; + } + /* Store row count. */ + columns[i] = count; + } +} + + +/* Restore whole cert row from memory, + * + * Assumes we have locked CA table. + * + * @param [in] cm Certificate manager. + * @param [in] current Buffer containing rows. + * @param [in] row Row number being restored. + * @param [in] listSz Number of entries in row. + * @param [in] end End of data in buffer. + * @return Number of bytes consumed on success. + * @return PARSE_ERROR when listSz is less than zero. + * @return BUFFER_E when buffer is too small. + * @return MEMORY_E when dynamic memory allocation fails. + * @return Negative value on error. + */ +static WC_INLINE int cm_restore_cert_row(WOLFSSL_CERT_MANAGER* cm, + byte* current, int row, int listSz, const byte* end) +{ + int ret = 0; + int idx = 0; + + /* Validate parameters. */ + if (listSz < 0) { + WOLFSSL_MSG("Row header corrupted, negative value"); + ret = PARSE_ERROR; + } + + /* Process all entries. */ + while ((ret == 0) && (listSz > 0)) { + Signer* signer = NULL; + byte* publicKey; + byte* start = current + idx; /* for end checks on this signer */ + int minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) + + sizeof(signer->nameLen) + sizeof(signer->subjectNameHash); + #ifndef NO_SKID + minSz += (int)sizeof(signer->subjectKeyIdHash); + #endif + + /* Check minimal size of bytes available. */ + if (start + minSz > end) { + WOLFSSL_MSG("Would overread restore buffer"); + ret = BUFFER_E; + } + /* Make a new signer. */ + if ((ret == 0) && ((signer = MakeSigner(cm->heap)) == NULL)) { + ret = MEMORY_E; + } + + if (ret == 0) { + /* Copy in public key size. */ + XMEMCPY(&signer->pubKeySize, current + idx, + sizeof(signer->pubKeySize)); + idx += (int)sizeof(signer->pubKeySize); + + /* Copy in public key OID. */ + XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID)); + idx += (int)sizeof(signer->keyOID); + + /* Check bytes available for public key. */ + if (start + minSz + signer->pubKeySize > end) { + WOLFSSL_MSG("Would overread restore buffer"); + ret = BUFFER_E; + } + } + if (ret == 0) { + /* Allocate memory for public key to be stored in. */ + publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap, + DYNAMIC_TYPE_KEY); + if (publicKey == NULL) { + ret = MEMORY_E; + } + } + + if (ret == 0) { + /* Copy in public key. */ + XMEMCPY(publicKey, current + idx, signer->pubKeySize); + signer->publicKey = publicKey; + idx += signer->pubKeySize; + + /* Copy in certificate name length. */ + XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen)); + idx += (int)sizeof(signer->nameLen); + + /* Check bytes available for certificate name. */ + if (start + minSz + signer->pubKeySize + signer->nameLen > end) { + WOLFSSL_MSG("Would overread restore buffer"); + ret = BUFFER_E; + } + } + if (ret == 0) { + /* Allocate memory for public key to be stored in. */ + signer->name = (char*)XMALLOC(signer->nameLen, cm->heap, + DYNAMIC_TYPE_SUBJECT_CN); + if (signer->name == NULL) { + ret = MEMORY_E; + } + } + + if (ret == 0) { + /* Copy in certificate name. */ + XMEMCPY(signer->name, current + idx, signer->nameLen); + idx += signer->nameLen; + + /* Copy in hash of subject name. */ + XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE); + idx += SIGNER_DIGEST_SIZE; + + #ifndef NO_SKID + /* Copy in hash of subject key. */ + XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE); + idx += SIGNER_DIGEST_SIZE; + #endif + + /* Make next Signer the head of the row. */ + signer->next = cm->caTable[row]; + /* Add Signer to start of row. */ + cm->caTable[row] = signer; + + /* Done one more Signer. */ + --listSz; + } + + if ((ret != 0) && (signer != NULL)) { + /* Dispose of allocated signer. */ + FreeSigner(signer, cm->heap); + } + } + + if (ret == 0) { + /* Return the number of bytes used on success. */ + ret = idx; + } + return ret; +} + + +/* Store whole CA certificate row into memory. + * + * Assumes we have locked CA table. + * + * @param [in] cm Certificate manager. + * @param [in] current Buffer to write to. + * @param [in] row Row number being stored. + * @return Number of bytes added. + */ +static WC_INLINE int cm_store_cert_row(WOLFSSL_CERT_MANAGER* cm, byte* current, + int row) +{ + int added = 0; + Signer* list; + + /* Get the row - a linked list. */ + list = cm->caTable[row]; + /* Each certificate in row. */ + while (list != NULL) { + /* Public key size. */ + XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize)); + added += (int)sizeof(list->pubKeySize); + + /* Public key OID. */ + XMEMCPY(current + added, &list->keyOID, sizeof(list->keyOID)); + added += (int)sizeof(list->keyOID); + + /* Public key. */ + XMEMCPY(current + added, list->publicKey, list->pubKeySize); + added += list->pubKeySize; + + /* Certificate name length. */ + XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen)); + added += (int)sizeof(list->nameLen); + + /* Certificate name. */ + XMEMCPY(current + added, list->name, list->nameLen); + added += list->nameLen; + + /* Hash of subject name. */ + XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE); + added += SIGNER_DIGEST_SIZE; + + #ifndef NO_SKID + /* Hash of public key. */ + XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE); + added += SIGNER_DIGEST_SIZE; + #endif + + /* Next certificate in row. */ + list = list->next; + } + + return added; +} + + +/* Persist CA certificate cache to memory. + * + * Assumes we have locked CA table. + * + * @param [in] cm Certificate manager. + * @param [in] mem Memory to persist into. + * @param [in] sz Size in bytes of memory. + * @return WOLFSSL_SUCCESS on success. + * @return BUFFER_E when memory is too small. + */ +static WC_INLINE int cm_do_mem_save_cert_cache(WOLFSSL_CERT_MANAGER* cm, + void* mem, int sz) +{ + int ret = WOLFSSL_SUCCESS; + int realSz; + int i; + + WOLFSSL_ENTER("cm_do_mem_save_cert_cache"); + + /* Calculate amount of memory required to store CA certificate table. */ + realSz = cm_get_cert_cache_mem_size(cm); + if (realSz > sz) { + WOLFSSL_MSG("Mem output buffer too small"); + ret = BUFFER_E; + } + if (ret == WOLFSSL_SUCCESS) { + byte* current; + CertCacheHeader hdr; + + /* Create header for storage. */ + hdr.version = WOLFSSL_CACHE_CERT_VERSION; + hdr.rows = CA_TABLE_SIZE; + cm_set_cert_header_Columns(cm, hdr.columns); + hdr.signerSz = (int)sizeof(Signer); + + /* Copy header into memory. */ + XMEMCPY(mem, &hdr, sizeof(CertCacheHeader)); + current = (byte*)mem + sizeof(CertCacheHeader); + + /* Each row of table. */ + for (i = 0; i < CA_TABLE_SIZE; ++i) { + /* Append row to memory. */ + current += cm_store_cert_row(cm, current, i); + } + } + + return ret; +} + + +#if !defined(NO_FILESYSTEM) + +/* Persist CA certificate cache to file. + * + * Locks CA table. + * + * @param [in] cm Certificate manager. + * @param [in] fname File name to write to. + * @return WOLFSSL_SUCCESS on success. + * @return WOLFSSL_BAD_FILE when opening file fails. + * @return BAD_MUTEX_E when locking fails. + * @return MEMORY_E when dynamic memory allocation fails. + * @return FWRITE_ERROR when writing to file fails. + */ +int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname) +{ + XFILE file; + int ret = WOLFSSL_SUCCESS; + int memSz; + byte* mem; + + WOLFSSL_ENTER("CM_SaveCertCache"); + + /* Open file for writing. */ + file = XFOPEN(fname, "w+b"); + if (file == XBADFILE) { + WOLFSSL_MSG("Couldn't open cert cache save file"); + ret = WOLFSSL_BAD_FILE; + } + + /* Lock CA table. */ + if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) { + WOLFSSL_MSG("wc_LockMutex on caLock failed"); + ret = BAD_MUTEX_E; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Calculate size of memory required to store CA table. */ + memSz = cm_get_cert_cache_mem_size(cm); + /* Allocate memory to hold CA table. */ + mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (mem == NULL) { + WOLFSSL_MSG("Alloc for tmp buffer failed"); + ret = MEMORY_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Store CA table in memory. */ + ret = cm_do_mem_save_cert_cache(cm, mem, memSz); + } + if (ret == WOLFSSL_SUCCESS) { + /* Write memory to file. */ + int sz = (int)XFWRITE(mem, memSz, 1, file); + if (sz != 1) { + WOLFSSL_MSG("Cert cache file write failed"); + ret = FWRITE_ERROR; + } + XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* Unlock CA table. */ + wc_UnLockMutex(&cm->caLock); + } + + /* Close file. */ + if (file != XBADFILE) { + XFCLOSE(file); + } + return ret; +} + + +/* Restore CA certificate cache from file. + * + * @param [in] cm Certificate manager. + * @param [in] fname File name to write to. + * @return WOLFSSL_SUCCESS on success. + * @return WOLFSSL_BAD_FILE when opening or using file fails. + * @return MEMORY_E when dynamic memory allocation fails. + * @return FREAD_ERROR when reading from file fails. + */ +int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname) +{ + XFILE file; + int ret = WOLFSSL_SUCCESS; + int memSz = 0; + byte* mem = NULL; + + WOLFSSL_ENTER("CM_RestoreCertCache"); + + /* Open file for reading. */ + file = XFOPEN(fname, "rb"); + if (file == XBADFILE) { + WOLFSSL_MSG("Couldn't open cert cache save file"); + ret = WOLFSSL_BAD_FILE; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Read file into allocated memory. */ + ret = wolfssl_read_file(file, (char**)&mem, &memSz); + if (ret == 0) { + ret = WOLFSSL_SUCCESS; + } + } + if (ret == WOLFSSL_SUCCESS) { + /* Create the CA certificate table from memory. */ + ret = CM_MemRestoreCertCache(cm, mem, memSz); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Mem restore cert cache failed"); + } + } + + /* Dispose of dynamic memory read into. */ + XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); + /* Close file. */ + if (file != XBADFILE) { + XFCLOSE(file); + } + return ret; +} + +#endif /* NO_FILESYSTEM */ + + +/* Persist CA certificate cache to memory. + * + * Locks CA table. + * + * @param [in] cm Certificate manager. + * @param [in] mem Memory to persist into. + * @param [in] sz Size in bytes of memory. + * @param [out] used Number of bytes used when persisting cache. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_MUTEX_E when locking fails. + * @return BUFFER_E when memory is too small. + */ +int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("CM_MemSaveCertCache"); + + /* Lock CA table. */ + if (wc_LockMutex(&cm->caLock) != 0) { + WOLFSSL_MSG("wc_LockMutex on caLock failed"); + ret = BAD_MUTEX_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Save CA table into memory. */ + ret = cm_do_mem_save_cert_cache(cm, mem, sz); + if (ret == WOLFSSL_SUCCESS) { + /* Get the number of bytes used. */ + *used = cm_get_cert_cache_mem_size(cm); + } + + /* Unlock CA table. */ + wc_UnLockMutex(&cm->caLock); + } + + return ret; +} + + +/* Restore CA certificate table from memory, + * + * Locks CA table. + * + * @param [in] cm Certificate manager. + * @param [in] mem Buffer containing rows. + * @param [in] sz Size in bytes of data in buffer. + * @return WOLFSSL_SUCCESS on success. + * @return BUFFER_E when buffer is too small. + * @return BAD_MUTEX_E when locking fails. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz) +{ + int ret = WOLFSSL_SUCCESS; + int i; + CertCacheHeader* hdr = (CertCacheHeader*)mem; + byte* current = (byte*)mem + sizeof(CertCacheHeader); + byte* end = (byte*)mem + sz; /* don't go over */ + + WOLFSSL_ENTER("CM_MemRestoreCertCache"); + + /* Check memory available is bigger than cache header. */ + if (current > end) { + WOLFSSL_MSG("Cert Cache Memory buffer too small"); + ret = BUFFER_E; + } + + /* Validate the cache header. */ + if ((ret == WOLFSSL_SUCCESS) && + ((hdr->version != WOLFSSL_CACHE_CERT_VERSION) || + (hdr->rows != CA_TABLE_SIZE) || + (hdr->signerSz != (int)sizeof(Signer)))) { + WOLFSSL_MSG("Cert Cache Memory header mismatch"); + ret = CACHE_MATCH_ERROR; + } + + /* Lock CA table. */ + if ((ret == WOLFSSL_SUCCESS) && (wc_LockMutex(&cm->caLock) != 0)) { + WOLFSSL_MSG("wc_LockMutex on caLock failed"); + ret = BAD_MUTEX_E; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Dispose of current CA certificate table. */ + FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); + + /* Each row. */ + for (i = 0; i < CA_TABLE_SIZE; ++i) { + /* Restore a row from memory. */ + int added = cm_restore_cert_row(cm, current, i, hdr->columns[i], + end); + /* Bail on error. */ + if (added < 0) { + WOLFSSL_MSG("cm_restore_cert_row error"); + ret = added; + break; + } + /* Update pointer to data of next row. */ + current += added; + } + + /* Unlock CA table. */ + wc_UnLockMutex(&cm->caLock); + } + + return ret; +} + + +/* Calculate size of CA certificate cache when persisted to memory. + * + * Locks CA table. + * + * @param [in] cm Certificate manager. + * @return Number of bytes on success. + * @return BAD_MUTEX_E when locking fails. + */ +int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm) +{ + int ret; + + WOLFSSL_ENTER("CM_GetCertCacheMemSize"); + + /* Lock CA table. */ + if (wc_LockMutex(&cm->caLock) != 0) { + WOLFSSL_MSG("wc_LockMutex on caLock failed"); + ret = BAD_MUTEX_E; + } + else { + /* Calculate memory size. */ + ret = cm_get_cert_cache_mem_size(cm); + + /* Unlock CA table. */ + wc_UnLockMutex(&cm->caLock); + } + + return ret; +} + +#endif /* PERSIST_CERT_CACHE */ + +/******************************************************************************* + * CRL handling + ******************************************************************************/ + +/* Enables/disables the use of CRLs when validating certificates. + * + * @param [in] cm Certificate manager. + * @param [in] options Options for using CRLs. Valid flags: + * WOLFSSL_CRL_CHECKALL, WOLFSSL_CRL_CHECK. + * @return WOLFSSL_SUCCESS on success. + * @return WOLFSSL_FAILURE when initializing the CRL object fails. + * @return BAD_FUNC_ARG when cm is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + * @return NOT_COMPILED_IN when the CRL feature is disabled. + */ +int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL"); + + (void)options; + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + +#if defined(OPENSSL_COMPATIBLE_DEFAULTS) + /* If disabling then don't worry about whether CRL feature is enabled. */ + if ((ret == WOLFSSL_SUCCESS) && (options == 0)) { + /* Disable leaf CRL check. */ + cm->crlEnabled = 0; + /* Disable all CRL checks. */ + cm->crlCheckAll = 0; + } + else +#endif + if (ret == WOLFSSL_SUCCESS) { +#ifndef HAVE_CRL + /* CRL feature not enabled. */ + ret = NOT_COMPILED_IN; +#else + /* Create CRL object if not present. */ + if (cm->crl == NULL) { + /* Allocate memory for CRL object. */ + cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap, + DYNAMIC_TYPE_CRL); + if (cm->crl == NULL) { + ret = MEMORY_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Reset fields of CRL object. */ + XMEMSET(cm->crl, 0, sizeof(WOLFSSL_CRL)); + /* Initialize CRL object. */ + if (InitCRL(cm->crl, cm) != 0) { + WOLFSSL_MSG("Init CRL failed"); + /* Dispose of CRL object - indicating dynamicly allocated. + */ + FreeCRL(cm->crl, 1); + cm->crl = NULL; + ret = WOLFSSL_FAILURE; + } + } + } + + if (ret == WOLFSSL_SUCCESS) { + #if defined(HAVE_CRL_IO) && defined(USE_WOLFSSL_IO) + /* Use built-in callback to lookup CRL from URL. */ + cm->crl->crlIOCb = EmbedCrlLookup; + #endif + #if defined(OPENSSL_COMPATIBLE_DEFAULTS) + if ((options & WOLFSSL_CRL_CHECKALL) || + (options & WOLFSSL_CRL_CHECK)) + #endif + { + /* Enable leaf CRL check. */ + cm->crlEnabled = 1; + if (options & WOLFSSL_CRL_CHECKALL) { + /* Enable all CRL check. */ + cm->crlCheckAll = 1; + } + } + } +#endif + } + + return ret; +} + + +/* Disables the CRL checks. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { + /* Disable CRL checking. */ + cm->crlEnabled = 0; + } + + return ret; +} + +#ifdef HAVE_CRL + +/* Load CRL for use. + * + * @param [in] cm Certificate manager. + * @param [in] buff Buffer holding CRL. + * @param [in] sz Size in bytes of CRL in buffer. + * @param [in] type Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm or buff is NULL or sz is negative or zero. + * @return WOLFSSL_FATAL_ERROR when creating CRL object fails. + */ +int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* buff, long sz, int type) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer"); + + /* Validate parameters. */ + if ((cm == NULL) || (buff == NULL) || (sz <= 0)) { + ret = BAD_FUNC_ARG; + } + + /* Create a CRL object if not available and enable CRL checking. */ + if ((ret == WOLFSSL_SUCCESS) && (cm->crl == NULL) && + (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) != + WOLFSSL_SUCCESS)) { + WOLFSSL_MSG("Enable CRL failed"); + ret = WOLFSSL_FATAL_ERROR; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Load CRL into CRL object of the certificate manager. */ + ret = BufferLoadCRL(cm->crl, buff, sz, type, VERIFY); + } + + return ret; +} + +/* Free the CRL object of the certificate manager. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + /* Check whether CRL object exists. */ + if ((ret == WOLFSSL_SUCCESS) && (cm->crl != NULL)) { + /* Dispose of CRL object - indicating dynamicly allocated. */ + FreeCRL(cm->crl, 1); + cm->crl = NULL; + } + + return ret; +} + +/* Check DER encoded certificate against CRLs if checking enabled. + * + * @param [in] cm Certificate manager. + * @param [in] der DER encode certificate. + * @param [in] sz Size in bytes of DER encode certificate. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm or der is NULL or sz is negative or zero. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* der, int sz) +{ + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + DecodedCert* cert = NULL; +#else + DecodedCert cert[1]; +#endif + + WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL"); + + /* Validate parameters. */ + if ((cm == NULL) || (der == NULL) || (sz <= 0)) { + ret = BAD_FUNC_ARG; + } + + /* Check if CRL checking enabled. */ + if ((ret == 0) && cm->crlEnabled) { + #ifdef WOLFSSL_SMALL_STACK + /* Allocate memory for decoded certificate. */ + cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_DCERT); + if (cert == NULL) + ret = MEMORY_E; + if (ret == 0) + #endif + { + /* Initialize decoded certificate with buffer. */ + InitDecodedCert(cert, der, sz, NULL); + + /* Parse certificate and perform CRL checks. */ + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm); + if (ret != 0) { + WOLFSSL_MSG("ParseCert failed"); + } + /* Do CRL checks with decoded certificate. */ + else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) { + WOLFSSL_MSG("CheckCertCRL failed"); + } + + /* Dispose of dynamically allocated memory. */ + FreeDecodedCert(cert); + #ifdef WOLFSSL_SMALL_STACK + XFREE(cert, NULL, DYNAMIC_TYPE_DCERT); + #endif + } + } + + return (ret == 0) ? WOLFSSL_SUCCESS : ret; +} + +/* Set the missing CRL callback. + * + * @param [in] cm Certificate manager. + * @param [in] cb Missing CRL callback. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb"); + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { + /* Store callback. */ + cm->cbMissingCRL = cb; + } + + return ret; +} + +#ifdef HAVE_CRL_IO +/* Set the CRL I/O callback. + * + * @param [in] cm Certificate manager. + * @param [in] cb CRL I/O callback. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb) +{ + int ret = WOLFSSL_SUCCESS; + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if ((ret == WOLFSSL_SUCCESS) && (cm->crl != NULL)) { + /* Store callback. */ + cm->crl->crlIOCb = cb; + } + + return ret; +} +#endif + +#ifndef NO_FILESYSTEM +/* Load CRL/s from path with the option of monitoring for changes. + * + * @param [in] cm Certificate manager. + * @param [in] path Path to a directory containing CRLs. + * @param [in] type Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @param [in] monitor Whether to monitor path for changes to files. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FNUC_ARG when cm or path is NULL. + * @return WOLFSSL_FATAL_ERROR when enabling CRLs fails. + */ +int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path, + int type, int monitor) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL"); + + /* Validate parameters. */ + if ((cm == NULL) || (path == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* Create a CRL object if not available. */ + if ((ret == WOLFSSL_SUCCESS) && (cm->crl == NULL) && + (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) != + WOLFSSL_SUCCESS)) { + WOLFSSL_MSG("Enable CRL failed"); + ret = WOLFSSL_FATAL_ERROR; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Load CRLs from path into CRL object of ceritifcate manager. */ + ret = LoadCRL(cm->crl, path, type, monitor); + } + + return ret; +} + +/* Load CRL from file. + * + * @param [in] cm Certificate manager. + * @param [in] file Path to a directory containing CRLs. + * @param [in] type Format of encoding. Valid values: + * WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FNUC_ARG when cm or file is NULL. + * @return WOLFSSL_FATAL_ERROR when enabling CRLs fails. + */ +int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, const char* file, + int type) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLFile"); + + /* Validate parameters. */ + if ((cm == NULL) || (file == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* Create a CRL object if not available. */ + if ((ret == WOLFSSL_SUCCESS) && (cm->crl == NULL) && + (wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK) != + WOLFSSL_SUCCESS)) { + WOLFSSL_MSG("Enable CRL failed"); + ret = WOLFSSL_FATAL_ERROR; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Load CRL file into CRL object of ceritifcate manager. */ + ret = ProcessFile(NULL, file, type, CRL_TYPE, NULL, 0, cm->crl, VERIFY); + } + + return ret; +} +#endif /* !NO_FILESYSTEM */ + +#endif /* HAVE_CRL */ + +/******************************************************************************* + * OCSP handling + ******************************************************************************/ + +/* Enables OCSP when validating certificates and sets options. + * + * @param [in] cm Certificate manager. + * @param [in] options Options for using OCSP. Valid flags: + * WOLFSSL_OCSP_URL_OVERRIDE, WOLFSSL_OCSP_NO_NONCE, + * WOLFSSL_OCSP_CHECKALL. + * @return WOLFSSL_SUCCESS on success. + * @return 0 when initializing the OCSP object fails. + * @return BAD_FUNC_ARG when cm is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + * @return NOT_COMPILED_IN when the OCSP feature is disabled. + */ +int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options) +{ + int ret = WOLFSSL_SUCCESS; + + (void)options; + + WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP"); + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + +#ifndef HAVE_OCSP + if (ret == WOLFSSL_SUCCESS) { + /* OCSP feature not enabled. */ + ret = NOT_COMPILED_IN; + } +#else + if (ret == WOLFSSL_SUCCESS) { + /* Check wheter OCSP object is available. */ + if (cm->ocsp == NULL) { + /* Allocate memory for OCSP object. */ + cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap, + DYNAMIC_TYPE_OCSP); + if (cm->ocsp == NULL) { + ret = MEMORY_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Reset the fields of the OCSP object. */ + XMEMSET(cm->ocsp, 0, sizeof(WOLFSSL_OCSP)); + /* Initialize the OCSP object. */ + if (InitOCSP(cm->ocsp, cm) != 0) { + WOLFSSL_MSG("Init OCSP failed"); + /* Dispose of OCSP object - indicating dynamicly allocated. + */ + FreeOCSP(cm->ocsp, 1); + cm->ocsp = NULL; + ret = 0; + } + } + } + } + if (ret == WOLFSSL_SUCCESS) { + /* Enable OCSP checking. */ + cm->ocspEnabled = 1; + /* Enable URL override if requested. */ + if (options & WOLFSSL_OCSP_URL_OVERRIDE) { + cm->ocspUseOverrideURL = 1; + } + /* Set nonce option for creating OCSP requests. */ + cm->ocspSendNonce = (options & WOLFSSL_OCSP_NO_NONCE) != 0; + /* Set all OCSP checks on if requested. */ + if (options & WOLFSSL_OCSP_CHECKALL) { + cm->ocspCheckAll = 1; + } + #ifndef WOLFSSL_USER_IO + /* Set built-in OCSP lookup. */ + cm->ocspIOCb = EmbedOcspLookup; + cm->ocspRespFreeCb = EmbedOcspRespFree; + cm->ocspIOCtx = cm->heap; + #endif /* WOLFSSL_USER_IO */ + } +#endif /* HAVE_OCSP */ + + return ret; +} + +/* Disables the OCSP checks. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { + /* Disable use of OCSP with certificate validation. */ + cm->ocspEnabled = 0; + } + + return ret; +} + +/* Enables OCSP stapling with certificates in manager. + * + * @param [in] cm Certificate manager. + * @param [in] options Options for using OCSP. Valid flags: + * WOLFSSL_OCSP_URL_OVERRIDE, WOLFSSL_OCSP_NO_NONCE, + * WOLFSSL_OCSP_CHECKALL. + * @return WOLFSSL_SUCCESS on success. + * @return 0 when initializing the OCSP stapling object fails. + * @return BAD_FUNC_ARG when cm is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + * @return NOT_COMPILED_IN when the OCSP stapling feature is disabled. + */ +int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling"); + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + +#if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ + !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (ret == WOLFSSL_SUCCESS) { + /* OCSP stapling feature not enabled. */ + ret = NOT_COMPILED_IN; + } +#else +#ifndef NO_WOLFSSL_SERVER + if (ret == WOLFSSL_SUCCESS) { + /* Check wheter OCSP object is available. */ + if (cm->ocsp_stapling == NULL) { + /* Allocate memory for OCSP stapling object. */ + cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), + cm->heap, DYNAMIC_TYPE_OCSP); + if (cm->ocsp_stapling == NULL) { + ret = MEMORY_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Reset the fields of the OCSP object. */ + XMEMSET(cm->ocsp_stapling, 0, sizeof(WOLFSSL_OCSP)); + /* Initialize the OCSP stapling object. */ + if (InitOCSP(cm->ocsp_stapling, cm) != 0) { + WOLFSSL_MSG("Init OCSP failed"); + /* Dispose of OCSP stapling object - indicating dynamicly + * allocated. */ + FreeOCSP(cm->ocsp_stapling, 1); + cm->ocsp_stapling = NULL; + ret = 0; + } + } + } + } +#ifndef WOLFSSL_USER_IO + if (ret == WOLFSSL_SUCCESS) { + /* Set built-in OCSP lookup. */ + cm->ocspIOCb = EmbedOcspLookup; + cm->ocspRespFreeCb = EmbedOcspRespFree; + cm->ocspIOCtx = cm->heap; + } +#endif /* WOLFSSL_USER_IO */ +#endif /* NO_WOLFSSL_SERVER */ + if (ret == WOLFSSL_SUCCESS) { + /* Enable OCSP stapling. */ + cm->ocspStaplingEnabled = 1; + } +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST || + * HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ + + return ret; +} + +/* Disables OCSP Stapling. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + /* Disable use of OCSP Stapling. */ + cm->ocspStaplingEnabled = 0; + #else + /* OCSP stapling feature not enabled. */ + ret = NOT_COMPILED_IN; + #endif + } + + return ret; +} + +/* Enable the must use OCSP Stapling option. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPMustStaple"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + #ifndef NO_WOLFSSL_CLIENT + /* Enable must use OCSP Stapling option. */ + cm->ocspMustStaple = 1; + #endif +#else + /* OCSP stapling feature not enabled. */ + ret = NOT_COMPILED_IN; +#endif + } + + return ret; +} + +/* Disable the must use OCSP Stapling option. + * + * @param [in] cm Certificate manager. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPMustStaple"); + + /* Validate parameter. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == WOLFSSL_SUCCESS) { +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + #ifndef NO_WOLFSSL_CLIENT + /* Disable must use OCSP Stapling option. */ + cm->ocspMustStaple = 0; + #endif +#else + /* OCSP stapling feature not enabled. */ + ret = NOT_COMPILED_IN; +#endif + } + + return ret; +} + +#ifdef HAVE_OCSP +/* Check DER encoded certificate against with OCSP if checking enabled. + * + * @param [in] cm Certificate manager. + * @param [in] der DER encode certificate. + * @param [in] sz Size in bytes of DER encode certificate. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm or der is NULL or sz is negative or 0. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, + const unsigned char* der, int sz) +{ + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + DecodedCert* cert = NULL; +#else + DecodedCert cert[1]; +#endif + + WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP"); + + /* Validate parameters. */ + if ((cm == NULL) || (der == NULL) || (sz <= 0)) { + ret = BAD_FUNC_ARG; + } + + /* Check if OCSP checking enabled. */ + if ((ret == 0) && cm->ocspEnabled) { + #ifdef WOLFSSL_SMALL_STACK + /* Allocate memory for decoded certificate. */ + cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, + DYNAMIC_TYPE_DCERT); + if (cert == NULL) { + ret = MEMORY_E; + } + if (ret == 0) + #endif + { + /* Initialize decoded certificate with buffer. */ + InitDecodedCert(cert, der, sz, NULL); + + /* Parse certificate and perform CRL checks. */ + ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm); + if (ret != 0) { + WOLFSSL_MSG("ParseCert failed"); + } + /* Do OCSP checks with decoded certificate. */ + else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) { + WOLFSSL_MSG("CheckCertOCSP failed"); + } + + /* Dispose of dynamically allocated memory. */ + FreeDecodedCert(cert); + #ifdef WOLFSSL_SMALL_STACK + XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT); + #endif + } + } + + return (ret == 0) ? WOLFSSL_SUCCESS : ret; +} + +/* Check OCSP response. + * + * @param [in] cm Certificate manager. + * @param [in] response Buffer holding OCSP response. + * @param [in] responseSz Size in bytes of OCSP response. + * @param [in] responseBuffer Buffer to copy response into. + * @param [in] status Place to store certificate status. + * @param [in] entry Place to store OCSP entry. + * @param [in] ocspRequest OCSP request to match with response. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm or response is NULL. + */ +int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm, + byte *response, int responseSz, buffer *responseBuffer, + CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest) +{ + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSPResponse"); + + /* Validate parameters. */ + if ((cm == NULL) || (response == NULL)) { + ret = BAD_FUNC_ARG; + } + if ((ret == 0) && cm->ocspEnabled) { + /* Check OCSP response with OCSP object from certificate manager. */ + ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, + status, entry, ocspRequest, NULL); + } + + return (ret == 0) ? WOLFSSL_SUCCESS : ret; +} + +/* Set the OCSP override URL. + * + * @param [in] cm Certificate manager. + * @param [in] url URL to get an OCSP response from. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + * @return MEMORY_E when dynamic memory allocation fails. + */ +int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm, + const char* url) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL"); + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == WOLFSSL_SUCCESS) { + /* Dispose of old URL. */ + XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); + if (url != NULL) { + /* Calculate size of URL string. Include terminator character. */ + int urlSz = (int)XSTRLEN(url) + 1; + /* Allocate memory for URL to be copied into. */ + cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, + DYNAMIC_TYPE_URL); + if (cm->ocspOverrideURL == NULL) { + ret = MEMORY_E; + } + if (ret == WOLFSSL_SUCCESS) { + /* Copy URL into certificate manager. */ + XMEMCPY(cm->ocspOverrideURL, url, urlSz); + } + } + else { + /* No URL to set so make it NULL. */ + cm->ocspOverrideURL = NULL; + } + } + + return ret; +} + +/* Set the OCSP I/O callback, OCSP response free callback and related data. + * + * @param [in] cm Certificate manager. + * @param [in] ioCb OCSP callback. + * @param [in] respFreeCb Callback to free OCSP response buffer. + * @param [in] ioCbCtx Context daa to pass to OCSP callbacks. + * @return WOLFSSL_SUCCESS on success. + * @return BAD_FUNC_ARG when cm is NULL. + */ +int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm, CbOCSPIO ioCb, + CbOCSPRespFree respFreeCb, void* ioCbCtx) +{ + int ret = WOLFSSL_SUCCESS; + + WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb"); + + /* Validate parameters. */ + if (cm == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == WOLFSSL_SUCCESS) { + /* Set callbacks and data into certificate manager. */ + cm->ocspIOCb = ioCb; + cm->ocspRespFreeCb = respFreeCb; + cm->ocspIOCtx = ioCbCtx; + } + + return ret; +} + +#endif /* HAVE_OCSP */ + +#endif /* NO_CERTS */ + +#endif /* !WOLFSSL_SSL_CERTMAN_INCLUDED */ diff --git a/src/ssl_misc.c b/src/ssl_misc.c index af0b99bac1..9bc42ddd9b 100644 --- a/src/ssl_misc.c +++ b/src/ssl_misc.c @@ -203,8 +203,12 @@ static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** data, int* dataSz, return ret; } #endif /* !NO_BIO */ +#endif /* OPENSSL_EXTRA && !WOLFCRYPT_ONLY */ -#if !defined(NO_FILESYSTEM) +#if (defined(OPENSSL_EXTRA) || defined(PERSIST_CERT_CACHE) || \ + (!defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \ + !defined(WOLFSSL_NO_CLIENT_AUTH)))) && !defined(WOLFCRYPT_ONLY) && \ + !defined(NO_FILESYSTEM) /* Read all the data from a file. * * @param [in] fp File pointer to read with. @@ -253,7 +257,10 @@ static int wolfssl_file_len(XFILE fp, long* fileSz) return ret; } +#endif +#if (defined(OPENSSL_EXTRA) || defined(PERSIST_CERT_CACHE)) && \ + !defined(WOLFCRYPT_ONLY) && !defined(NO_FILESYSTEM) /* Read all the data from a file. * * @param [in] fp File pointer to read with. @@ -290,7 +297,7 @@ static int wolfssl_read_file(XFILE fp, char** data, int* dataSz) XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; } -#endif /* !NO_FILESYSTEM */ -#endif /* OPENSSL_EXTRA && !WOLFCRYPT_ONLY */ +#endif /* (OPENSSL_EXTRA || PERSIST_CERT_CACHE) && !WOLFCRYPT_ONLY && + * !NO_FILESYSTEM */ #endif /* !WOLFSSL_SSL_MISC_INCLUDED */ diff --git a/src/x509.c b/src/x509.c index c4b7d1c4b7..63ff45b1d8 100644 --- a/src/x509.c +++ b/src/x509.c @@ -9477,7 +9477,9 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref( { WOLFSSL_ENTER("wolfSSL_X509_NAME_free"); FreeX509Name(name); - XFREE(name, name->heap, DYNAMIC_TYPE_X509); + if (name != NULL) { + XFREE(name, name->heap, DYNAMIC_TYPE_X509); + } } diff --git a/tests/api.c b/tests/api.c index 9e9155186d..3f2b78900f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1389,7 +1389,6 @@ static int test_wolfSSL_CTX_trust_peer_cert(void) return EXPECT_RESULT(); } - static int test_wolfSSL_CTX_load_verify_locations(void) { EXPECT_DECLS; @@ -1398,7 +1397,15 @@ static int test_wolfSSL_CTX_load_verify_locations(void) #ifndef NO_RSA WOLFSSL_CERT_MANAGER* cm = NULL; #ifdef PERSIST_CERT_CACHE - int cacheSz; + int cacheSz = 0; + unsigned char* cache = NULL; + int used = 0; +#ifndef NO_FILESYSTEM + const char* cacheFile = "./tests/cert_cache.tmp"; +#endif + int i; + int t; + int* p; #endif #endif #if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS) @@ -1439,6 +1446,98 @@ static int test_wolfSSL_CTX_load_verify_locations(void) #ifdef PERSIST_CERT_CACHE /* Get cert cache size */ ExpectIntGT(cacheSz = wolfSSL_CTX_get_cert_cache_memsize(ctx), 0); + + ExpectNotNull(cache = XMALLOC(cacheSz, NULL, DYNAMIC_TYPE_TMP_BUFFER)); + + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, -1, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, NULL, -1, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, cache, -1, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, cacheSz, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, -1, &used), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, cache, cacheSz, &used), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, NULL, cacheSz, &used), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, -1, &used), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz - 10, &used), + BUFFER_E); + ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz, &used), 1); + ExpectIntEQ(cacheSz, used); + + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, NULL, -1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, NULL, -1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, cache, -1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, NULL, cacheSz), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, cache, cacheSz), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, NULL, cacheSz), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, -1), + BAD_FUNC_ARG); + /* Smaller than header. */ + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, 1), BUFFER_E); + for (i = 1; i < cacheSz; i++) { + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz - i), + BUFFER_E); + } + if (EXPECT_SUCCESS()) { + /* Modify header for bad results! */ + p = (int*)cache; + /* version */ + t = p[0]; p[0] = 0xff; + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), + CACHE_MATCH_ERROR); + p[0] = t; p++; + /* rows */ + t = p[0]; p[0] = 0xff; + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), + CACHE_MATCH_ERROR); + p[0] = t; p++; + /* colums[0] */ + t = p[0]; p[0] = -1; + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), + PARSE_ERROR); + p[0] = t; p += CA_TABLE_SIZE; + /* signerSz*/ + t = p[0]; p[0] = 0xff; + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), + CACHE_MATCH_ERROR); + p[0] = t; + } + + ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), 1); + ExpectIntEQ(cacheSz = wolfSSL_CTX_get_cert_cache_memsize(ctx), used); + +#ifndef NO_FILESYSTEM + ExpectIntEQ(wolfSSL_CTX_save_cert_cache(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_save_cert_cache(ctx, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_save_cert_cache(NULL, cacheFile), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_save_cert_cache(ctx, cacheFile), 1); + + ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(NULL, cacheFile), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, "no-file"), + WOLFSSL_BAD_FILE); + ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, cacheFile), 1); + /* File contents is not a cache. */ + ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, "./certs/ca-cert.pem"), + CACHE_MATCH_ERROR); +#endif + + XFREE(cache, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif /* Test unloading CA's */ ExpectIntEQ(wolfSSL_CTX_UnloadCAs(ctx), WOLFSSL_SUCCESS); @@ -1575,7 +1674,8 @@ static int test_wolfSSL_CTX_load_system_CA_certs(void) } #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) -static int test_cm_load_ca_buffer(const byte* cert_buf, size_t cert_sz, int file_type) +static int test_cm_load_ca_buffer(const byte* cert_buf, size_t cert_sz, + int file_type) { int ret; WOLFSSL_CERT_MANAGER* cm; @@ -1712,374 +1812,171 @@ static int test_cm_load_ca_file_ex(const char* ca_cert_file, word32 flags) #endif /* !NO_FILESYSTEM && !NO_CERTS */ -static int test_wolfSSL_CertManagerCheckOCSPResponse(void) +static int test_wolfSSL_CertManagerAPI(void) { EXPECT_DECLS; -#if defined(HAVE_OCSP) && !defined(NO_RSA) -/* Need one of these for wolfSSL_OCSP_REQUEST_new. */ -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_APACHE_HTTPD) || \ - defined(HAVE_LIGHTY) +#ifndef NO_CERTS WOLFSSL_CERT_MANAGER* cm = NULL; - /* Raw OCSP response bytes captured using the following setup: - * - Run responder with - * openssl ocsp -port 9999 -ndays 9999 - * -index certs/ocsp/index-intermediate1-ca-issued-certs.txt - * -rsigner certs/ocsp/ocsp-responder-cert.pem - * -rkey certs/ocsp/ocsp-responder-key.pem - * -CA certs/ocsp/intermediate1-ca-cert.pem - * - Run client with - * openssl ocsp -host 127.0.0.1:9999 -respout resp.out - * -issuer certs/ocsp/intermediate1-ca-cert.pem - * -cert certs/ocsp/server1-cert.pem - * -CAfile certs/ocsp/root-ca-cert.pem -noverify - * - Copy raw response from Wireshark. - */ - byte response[] = { - 0x30, 0x82, 0x07, 0x40, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x07, 0x39, 0x30, 0x82, 0x07, 0x35, 0x06, - 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01, 0x04, 0x82, 0x07, 0x26, 0x30, 0x82, - 0x07, 0x22, 0x30, 0x82, 0x01, 0x40, 0xa1, 0x81, 0xa1, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, - 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, 0x50, 0x20, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, - 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, - 0x30, 0x35, 0x30, 0x33, 0x32, 0x31, 0x34, 0x37, 0x31, 0x30, 0x5a, 0x30, 0x64, 0x30, 0x62, 0x30, - 0x3a, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x71, 0x4d, - 0x82, 0x23, 0x40, 0x59, 0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18, - 0xda, 0x04, 0x04, 0x14, 0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, 0xd7, 0x9d, 0x4c, 0xe2, - 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e, 0x02, 0x01, 0x05, 0x80, 0x00, 0x18, 0x0f, 0x32, - 0x30, 0x32, 0x31, 0x30, 0x35, 0x30, 0x33, 0x32, 0x31, 0x34, 0x37, 0x31, 0x30, 0x5a, 0xa0, 0x11, - 0x18, 0x0f, 0x32, 0x30, 0x34, 0x38, 0x30, 0x39, 0x31, 0x37, 0x32, 0x31, 0x34, 0x37, 0x31, 0x30, - 0x5a, 0xa1, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, - 0x01, 0x02, 0x04, 0x12, 0x04, 0x10, 0x38, 0x31, 0x60, 0x99, 0xc8, 0x05, 0x09, 0x68, 0x1c, 0x33, - 0x49, 0xea, 0x45, 0x26, 0x2f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4d, 0x58, 0xcc, 0x69, 0x42, 0xe2, - 0x9e, 0x64, 0xf6, 0x57, 0xce, 0xcb, 0x5f, 0x14, 0xaf, 0x08, 0x6c, 0xc1, 0x52, 0x7a, 0x40, 0x0a, - 0xfd, 0xb6, 0xce, 0xbb, 0x40, 0xf4, 0xb9, 0xa5, 0x88, 0xc7, 0xf3, 0x42, 0x9f, 0xa9, 0x94, 0xbe, - 0x6e, 0x7e, 0x09, 0x30, 0x9d, 0x0e, 0x10, 0x6f, 0x9c, 0xd9, 0x4c, 0x71, 0x81, 0x41, 0x64, 0x95, - 0xf5, 0x85, 0x77, 0x94, 0x81, 0x61, 0x88, 0xc8, 0x0b, 0x50, 0xbb, 0x37, 0xc8, 0x86, 0x76, 0xd8, - 0xa2, 0xed, 0x66, 0x34, 0xfb, 0xe4, 0xe7, 0x09, 0x8c, 0xf5, 0xb5, 0x85, 0xd0, 0x4b, 0xb5, 0xe6, - 0x23, 0x62, 0xc3, 0xd0, 0xef, 0xf7, 0x42, 0x89, 0x02, 0x80, 0x64, 0xc9, 0xed, 0xdd, 0x7c, 0x8f, - 0x0d, 0xe7, 0x43, 0x9b, 0x88, 0x1f, 0xb0, 0xfd, 0x24, 0x01, 0xc7, 0x55, 0xc3, 0x73, 0x12, 0x84, - 0x09, 0x7c, 0x57, 0xa8, 0x5d, 0xab, 0x75, 0x29, 0x5c, 0x36, 0x97, 0x64, 0x40, 0x0b, 0x55, 0x34, - 0x0a, 0x5d, 0xb1, 0x1b, 0x61, 0x1b, 0xdc, 0xe5, 0x89, 0xdd, 0x92, 0x62, 0x57, 0xa7, 0x52, 0xb4, - 0x38, 0x9a, 0x48, 0xc8, 0x3a, 0x14, 0xde, 0x69, 0x42, 0xe9, 0x37, 0xa4, 0xe7, 0x2d, 0x00, 0xa7, - 0x0b, 0x29, 0x18, 0xd5, 0xce, 0xd9, 0x0d, 0xdd, 0xfe, 0xae, 0x86, 0xb3, 0x32, 0x1c, 0xc9, 0x33, - 0xb0, 0x2b, 0xb7, 0x3c, 0x0d, 0x43, 0xd8, 0x6c, 0xf2, 0xb7, 0xcd, 0x7b, 0xd5, 0x7d, 0xf0, 0xde, - 0x34, 0x9f, 0x6d, 0x83, 0xb9, 0xd5, 0xed, 0xe3, 0xda, 0x96, 0x40, 0x9e, 0xd6, 0xa6, 0xfd, 0x70, - 0x80, 0x70, 0x87, 0x61, 0x0f, 0xc5, 0x9f, 0x75, 0xfe, 0x11, 0x78, 0x34, 0xc9, 0x42, 0x16, 0x73, - 0x46, 0x7b, 0x05, 0x53, 0x28, 0x43, 0xbe, 0xee, 0x88, 0x67, 0x1d, 0xcc, 0x74, 0xa7, 0xb6, 0x58, - 0x7b, 0x29, 0x68, 0x40, 0xcf, 0xce, 0x7b, 0x19, 0x33, 0x68, 0xa0, 0x82, 0x04, 0xc6, 0x30, 0x82, - 0x04, 0xc2, 0x30, 0x82, 0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, - 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, - 0x00, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, - 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, - 0x53, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, - 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, - 0x31, 0x30, 0x32, 0x31, 0x30, 0x31, 0x39, 0x34, 0x39, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x33, - 0x31, 0x31, 0x30, 0x37, 0x31, 0x39, 0x34, 0x39, 0x35, 0x34, 0x5a, 0x30, 0x81, 0x9e, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, - 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, - 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x0c, 0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, - 0x50, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f, 0x30, 0x1d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, - 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb8, 0xba, 0x23, - 0xb4, 0xf6, 0xc3, 0x7b, 0x14, 0xc3, 0xa4, 0xf5, 0x1d, 0x61, 0xa1, 0xf5, 0x1e, 0x63, 0xb9, 0x85, - 0x23, 0x34, 0x50, 0x6d, 0xf8, 0x7c, 0xa2, 0x8a, 0x04, 0x8b, 0xd5, 0x75, 0x5c, 0x2d, 0xf7, 0x63, - 0x88, 0xd1, 0x07, 0x7a, 0xea, 0x0b, 0x45, 0x35, 0x2b, 0xeb, 0x1f, 0xb1, 0x22, 0xb4, 0x94, 0x41, - 0x38, 0xe2, 0x9d, 0x74, 0xd6, 0x8b, 0x30, 0x22, 0x10, 0x51, 0xc5, 0xdb, 0xca, 0x3f, 0x46, 0x2b, - 0xfe, 0xe5, 0x5a, 0x3f, 0x41, 0x74, 0x67, 0x75, 0x95, 0xa9, 0x94, 0xd5, 0xc3, 0xee, 0x42, 0xf8, - 0x8d, 0xeb, 0x92, 0x95, 0xe1, 0xd9, 0x65, 0xb7, 0x43, 0xc4, 0x18, 0xde, 0x16, 0x80, 0x90, 0xce, - 0x24, 0x35, 0x21, 0xc4, 0x55, 0xac, 0x5a, 0x51, 0xe0, 0x2e, 0x2d, 0xb3, 0x0a, 0x5a, 0x4f, 0x4a, - 0x73, 0x31, 0x50, 0xee, 0x4a, 0x16, 0xbd, 0x39, 0x8b, 0xad, 0x05, 0x48, 0x87, 0xb1, 0x99, 0xe2, - 0x10, 0xa7, 0x06, 0x72, 0x67, 0xca, 0x5c, 0xd1, 0x97, 0xbd, 0xc8, 0xf1, 0x76, 0xf8, 0xe0, 0x4a, - 0xec, 0xbc, 0x93, 0xf4, 0x66, 0x4c, 0x28, 0x71, 0xd1, 0xd8, 0x66, 0x03, 0xb4, 0x90, 0x30, 0xbb, - 0x17, 0xb0, 0xfe, 0x97, 0xf5, 0x1e, 0xe8, 0xc7, 0x5d, 0x9b, 0x8b, 0x11, 0x19, 0x12, 0x3c, 0xab, - 0x82, 0x71, 0x78, 0xff, 0xae, 0x3f, 0x32, 0xb2, 0x08, 0x71, 0xb2, 0x1b, 0x8c, 0x27, 0xac, 0x11, - 0xb8, 0xd8, 0x43, 0x49, 0xcf, 0xb0, 0x70, 0xb1, 0xf0, 0x8c, 0xae, 0xda, 0x24, 0x87, 0x17, 0x3b, - 0xd8, 0x04, 0x65, 0x6c, 0x00, 0x76, 0x50, 0xef, 0x15, 0x08, 0xd7, 0xb4, 0x73, 0x68, 0x26, 0x14, - 0x87, 0x95, 0xc3, 0x5f, 0x6e, 0x61, 0xb8, 0x87, 0x84, 0xfa, 0x80, 0x1a, 0x0a, 0x8b, 0x98, 0xf3, - 0xe3, 0xff, 0x4e, 0x44, 0x1c, 0x65, 0x74, 0x7c, 0x71, 0x54, 0x65, 0xe5, 0x39, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x32, 0x67, 0xe1, 0xb1, 0x79, 0xd2, 0x81, 0xfc, 0x9f, 0x23, 0x0c, 0x70, 0x40, 0x50, 0xb5, 0x46, - 0x56, 0xb8, 0x30, 0x36, 0x30, 0x81, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xbc, 0x30, - 0x81, 0xb9, 0x80, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f, 0x82, 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, - 0xb0, 0x04, 0x82, 0x3a, 0x7e, 0x72, 0x15, 0x21, 0xa1, 0x81, 0x9d, 0xa4, 0x81, 0x9a, 0x30, 0x81, - 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, - 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, - 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, - 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, - 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, - 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, - 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x63, 0x30, 0x13, 0x06, 0x03, 0x55, - 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x07, 0xca, 0xa6, 0xa1, 0x9f, 0xbf, 0xaf, 0x92, 0x41, 0x35, 0x66, 0x51, - 0xac, 0xbc, 0x2c, 0xec, 0xe7, 0x8d, 0x65, 0x7e, 0xe9, 0x40, 0xfe, 0x5a, 0xab, 0x8a, 0x1d, 0x3d, - 0x13, 0xdb, 0xb4, 0x43, 0x2c, 0x9a, 0x36, 0x98, 0x21, 0xa5, 0xe8, 0xca, 0xa9, 0x4d, 0xfc, 0xe3, - 0xf7, 0x45, 0x88, 0xcd, 0x33, 0xbf, 0x8a, 0x62, 0x10, 0x2f, 0xb2, 0xb7, 0x04, 0xef, 0x26, 0x43, - 0x51, 0x1d, 0x43, 0x62, 0x7d, 0x1e, 0x50, 0xc8, 0xd5, 0x98, 0x94, 0x71, 0x8f, 0x3b, 0x23, 0x26, - 0xf1, 0x71, 0x8e, 0x1e, 0x3d, 0x3f, 0x21, 0xfd, 0xb7, 0x2d, 0x65, 0xe4, 0x07, 0x65, 0xac, 0x3c, - 0xfc, 0xc0, 0x47, 0xa9, 0x32, 0xf6, 0xda, 0x26, 0x93, 0x10, 0xb2, 0xd1, 0x6d, 0xc8, 0x81, 0x31, - 0x7c, 0xb0, 0x6b, 0xc5, 0x22, 0x8d, 0xb3, 0xfa, 0xbe, 0x82, 0xea, 0x41, 0x42, 0xc4, 0xc0, 0xef, - 0xe3, 0x84, 0x0f, 0x6f, 0x9a, 0x03, 0x63, 0xb3, 0x30, 0xe0, 0x31, 0x81, 0x2a, 0x16, 0xb3, 0x47, - 0xd9, 0x5b, 0x38, 0x93, 0x07, 0xd0, 0x6e, 0x79, 0x52, 0x2c, 0xe5, 0x50, 0x84, 0x79, 0x10, 0xe7, - 0xf6, 0x31, 0x7a, 0x3e, 0x48, 0xa2, 0x38, 0x21, 0x90, 0x7a, 0xf2, 0x5f, 0x48, 0xa4, 0x46, 0x93, - 0x87, 0xdd, 0x5c, 0x83, 0x64, 0xea, 0xb5, 0x99, 0xa2, 0xe9, 0x01, 0x40, 0xfe, 0xf0, 0x48, 0x66, - 0x4f, 0x96, 0xf7, 0x83, 0x52, 0xf8, 0x6d, 0xf8, 0x5f, 0xed, 0x0c, 0xbb, 0xbe, 0xd0, 0x69, 0x10, - 0x4b, 0x99, 0x8f, 0xf8, 0x61, 0x53, 0x9d, 0x12, 0xca, 0x86, 0xaa, 0xb1, 0x80, 0xb4, 0xa6, 0xc1, - 0xcb, 0xb7, 0x48, 0xf7, 0x9f, 0x55, 0xb4, 0x6e, 0xab, 0xd3, 0xa1, 0xaa, 0x4b, 0xa7, 0x21, 0x6e, - 0x16, 0x7f, 0xad, 0xbb, 0xea, 0x0f, 0x41, 0x80, 0x9b, 0x7f, 0xd6, 0x46, 0xa2, 0xc0, 0x61, 0x72, - 0x59, 0x59, 0xa0, 0x07 - }; - OcspEntry entry[1]; - CertStatus status[1]; - OcspRequest* request = NULL; - - byte serial[] = {0x05}; - byte issuerHash[] = {0x71, 0x4d, 0x82, 0x23, 0x40, 0x59, 0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18, 0xda, 0x04}; - byte issuerKeyHash[] = {0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, 0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e}; - - - XMEMSET(entry, 0, sizeof(OcspEntry)); - XMEMSET(status, 0, sizeof(CertStatus)); - - ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new()); - ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL, - DYNAMIC_TYPE_OCSP_REQUEST)); - - if ((request != NULL) && (request->serial != NULL)) { - request->serialSz = sizeof(serial); - XMEMCPY(request->serial, serial, sizeof(serial)); - XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash)); - XMEMCPY(request->issuerKeyHash, issuerKeyHash, sizeof(issuerKeyHash)); - } + unsigned char c; ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); - ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, - "./certs/ocsp/intermediate1-ca-cert.pem", NULL), WOLFSSL_SUCCESS); - - /* Response should be valid. */ - ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, response, - sizeof(response), NULL, status, entry, request), WOLFSSL_SUCCESS); - /* Flip a byte in the request serial number, response should be invalid - * now. */ - if ((request != NULL) && (request->serial != NULL)) - request->serial[0] ^= request->serial[0]; - ExpectIntNE(wolfSSL_CertManagerCheckOCSPResponse(cm, response, - sizeof(response), NULL, status, entry, request), WOLFSSL_SUCCESS); - - - wolfSSL_OCSP_REQUEST_free(request); - wolfSSL_CertManagerFree(cm); - -#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || - * WOLFSSL_APACHE_HTTPD || HAVE_LIGHTY */ -#endif /* HAVE_OCSP */ - return EXPECT_RESULT(); -} - -static int test_wolfSSL_CheckOCSPResponse(void) -{ - EXPECT_DECLS; -#if defined(HAVE_OCSP) && !defined(NO_RSA) && defined(OPENSSL_ALL) - const char* responseFile = "./certs/ocsp/test-response.der"; - const char* responseMultiFile = "./certs/ocsp/test-multi-response.der"; - const char* responseNoInternFile = - "./certs/ocsp/test-response-nointern.der"; - const char* caFile = "./certs/ocsp/root-ca-cert.pem"; - OcspResponse* res = NULL; - byte data[4096]; - const unsigned char* pt; - int dataSz = 0; /* initialize to mitigate spurious maybe-uninitialized from - * gcc sanitizer with --enable-heapmath. - */ - XFILE f = XBADFILE; - WOLFSSL_OCSP_BASICRESP* bs = NULL; - WOLFSSL_X509_STORE* st = NULL; - WOLFSSL_X509* issuer = NULL; - - - ExpectTrue((f = XFOPEN(responseFile, "rb")) != XBADFILE); - ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); - if (f != XBADFILE) { - XFCLOSE(f); - f = XBADFILE; - } - - pt = data; - ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz)); - ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile, - SSL_FILETYPE_PEM)); - ExpectNotNull(st = wolfSSL_X509_STORE_new()); - ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS); - ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res)); - ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), WOLFSSL_SUCCESS); - wolfSSL_OCSP_BASICRESP_free(bs); - bs = NULL; - wolfSSL_OCSP_RESPONSE_free(res); - res = NULL; - wolfSSL_X509_STORE_free(st); - st = NULL; - wolfSSL_X509_free(issuer); - issuer = NULL; - - /* check loading a response with optional certs */ - ExpectTrue((f = XFOPEN(responseNoInternFile, "rb")) != XBADFILE); - ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); - if (f != XBADFILE) - XFCLOSE(f); - f = XBADFILE; - - pt = data; - ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz)); - wolfSSL_OCSP_RESPONSE_free(res); - res = NULL; + wolfSSL_CertManagerFree(NULL); + ExpectIntEQ(wolfSSL_CertManager_up_ref(NULL), 0); + ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(NULL), BAD_FUNC_ARG); +#ifdef WOLFSSL_TRUST_PEER_CERT + ExpectIntEQ(wolfSSL_CertManagerUnload_trust_peers(NULL), BAD_FUNC_ARG); +#endif + + ExpectIntEQ(wolfSSL_CertManagerLoadCABuffer_ex(NULL, &c, 1, + WOLFSSL_FILETYPE_ASN1, 0, 0), WOLFSSL_FATAL_ERROR); + +#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, NULL, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, NULL, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, &c, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, NULL, 1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(NULL, &c, 1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, NULL, 1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, &c, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, &c, 1, -1), + WOLFSSL_BAD_FILETYPE); +#endif - /* check loading a response with multiple certs */ +#if !defined(NO_FILESYSTEM) { - WOLFSSL_CERT_MANAGER* cm = NULL; - OcspEntry *entry = NULL; - CertStatus* status = NULL; - OcspRequest* request = NULL; + const char* ca_cert = "./certs/ca-cert.pem"; + const char* ca_cert_der = "./certs/ca-cert.der"; + const char* ca_path = "./certs"; - byte serial1[] = {0x01}; - byte serial[] = {0x02}; - - byte issuerHash[] = { - 0x44, 0xA8, 0xDB, 0xD1, 0xBC, 0x97, 0x0A, 0x83, - 0x3B, 0x5B, 0x31, 0x9A, 0x4C, 0xB8, 0xD2, 0x52, - 0x37, 0x15, 0x8A, 0x88 - }; - byte issuerKeyHash[] = { - 0x73, 0xB0, 0x1C, 0xA4, 0x2F, 0x82, 0xCB, 0xCF, - 0x47, 0xA5, 0x38, 0xD7, 0xB0, 0x04, 0x82, 0x3A, - 0x7E, 0x72, 0x15, 0x21 - }; - - ExpectNotNull(entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL, - DYNAMIC_TYPE_OPENSSL)); - - ExpectNotNull(status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, - DYNAMIC_TYPE_OPENSSL)); + #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) + ExpectIntEQ(wolfSSL_CertManagerVerify(NULL, NULL, -1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, NULL, WOLFSSL_FILETYPE_ASN1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerify(NULL, ca_cert, + WOLFSSL_FILETYPE_PEM), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, ca_cert, -1), + WOLFSSL_BAD_FILETYPE); + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, "no-file", + WOLFSSL_FILETYPE_ASN1), WOLFSSL_BAD_FILE); + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, ca_cert_der, + WOLFSSL_FILETYPE_PEM), ASN_NO_PEM_HEADER); + #endif - if (entry != NULL) - XMEMSET(entry, 0, sizeof(OcspEntry)); - if (status != NULL) - XMEMSET(status, 0, sizeof(CertStatus)); + ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, NULL, NULL), + WOLFSSL_FATAL_ERROR); + ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, ca_cert, NULL), + WOLFSSL_FATAL_ERROR); + ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, NULL, ca_path), + WOLFSSL_FATAL_ERROR); + ExpectIntEQ(wolfSSL_CertManagerLoadCA(NULL, ca_cert, ca_path), + WOLFSSL_FATAL_ERROR); + } +#endif - ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new()); - ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL, - DYNAMIC_TYPE_OCSP_REQUEST)); +#ifdef OPENSSL_COMPATIBLE_DEFAULTS + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, 0), 1); +#elif !defined(HAVE_CRL) + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, 0), NOT_COMPILED_IN); +#endif - if (request != NULL && request->serial != NULL) { - request->serialSz = sizeof(serial); - XMEMCPY(request->serial, serial, sizeof(serial)); - XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash)); - XMEMCPY(request->issuerKeyHash, issuerKeyHash, - sizeof(issuerKeyHash)); - } + ExpectIntEQ(wolfSSL_CertManagerDisableCRL(NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerDisableCRL(cm), 1); +#ifdef HAVE_CRL + /* Test APIs when CRL is disabled. */ +#ifdef HAVE_CRL_IO + ExpectIntEQ(wolfSSL_CertManagerSetCRL_IOCb(cm, NULL), 1); +#endif + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048, + sizeof_server_cert_der_2048), 1); + ExpectIntEQ(wolfSSL_CertManagerFreeCRL(cm), 1); +#endif - ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); - ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caFile, NULL), - WOLFSSL_SUCCESS); + /* OCSP */ + ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSP(NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSPStapling(NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPMustStaple(NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSPMustStaple(NULL), BAD_FUNC_ARG); +#if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ + !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + ExpectIntEQ(wolfSSL_CertManagerDisableOCSPStapling(cm), NOT_COMPILED_IN); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPMustStaple(cm), NOT_COMPILED_IN); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSPMustStaple(cm), NOT_COMPILED_IN); +#endif - ExpectTrue((f = XFOPEN(responseMultiFile, "rb")) != XBADFILE); - ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); - if (f != XBADFILE) - XFCLOSE(f); - f = XBADFILE; +#ifdef HAVE_OCSP + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, NULL, -1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, NULL, -1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, &c, -1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(NULL, &c, 1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, &c, -1), BAD_FUNC_ARG); - ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, - dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, - dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS); - ExpectNotNull(entry->status); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(NULL, NULL, 0, + NULL, NULL, NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, NULL, 1, + NULL, NULL, NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(NULL, &c, 1, + NULL, NULL, NULL, NULL), BAD_FUNC_ARG); - if (request != NULL && request->serial != NULL) - XMEMCPY(request->serial, serial1, sizeof(serial1)); - ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, - dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(NULL, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(NULL, ""), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(cm, NULL), 1); - /* store both status's in the entry to check that "next" is not - * overwritten */ - if (EXPECT_SUCCESS() && status != NULL && entry != NULL) { - status->next = entry->status; - entry->status = status; - } + ExpectIntEQ(wolfSSL_CertManagerSetOCSP_Cb(NULL, NULL, NULL, NULL), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerSetOCSP_Cb(cm, NULL, NULL, NULL), 1); - if (request != NULL && request->serial != NULL) - XMEMCPY(request->serial, serial, sizeof(serial)); - ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, - dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS); - ExpectNotNull(entry->status->next); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSP(cm), 1); + /* Test APIs when OCSP is disabled. */ + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, &c, 1, + NULL, NULL, NULL, NULL), 1); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, &c, 1), 1); - /* compare the status found */ - ExpectIntEQ(status->serialSz, entry->status->serialSz); - ExpectIntEQ(XMEMCMP(status->serial, entry->status->serial, - status->serialSz), 0); +#endif - if (status != NULL && entry != NULL && entry->status != status) { - XFREE(status, NULL, DYNAMIC_TYPE_OPENSSL); - } - wolfSSL_OCSP_CERTID_free(entry); - wolfSSL_OCSP_REQUEST_free(request); - wolfSSL_CertManagerFree(cm); - } + ExpectIntEQ(wolfSSL_CertManager_up_ref(cm), 1); + wolfSSL_CertManagerFree(cm); + wolfSSL_CertManagerFree(cm); + cm = NULL; -#if defined(WC_RSA_PSS) - { - const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der"; + ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); - /* check loading a response with RSA-PSS signature */ - ExpectTrue((f = XFOPEN(responsePssFile, "rb")) != XBADFILE); - ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); - if (f != XBADFILE) - XFCLOSE(f); +#ifdef HAVE_OCSP + ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, WOLFSSL_OCSP_URL_OVERRIDE | + WOLFSSL_OCSP_CHECKALL), 1); +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(cm), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(cm), 1); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSPStapling(cm), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPStapling(cm), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSPMustStaple(cm), 1); + ExpectIntEQ(wolfSSL_CertManagerDisableOCSPMustStaple(cm), 1); +#endif - pt = data; - ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz)); + ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(cm, ""), 1); + ExpectIntEQ(wolfSSL_CertManagerSetOCSPOverrideURL(cm, ""), 1); +#endif - /* try to verify the response */ - ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile, - SSL_FILETYPE_PEM)); - ExpectNotNull(st = wolfSSL_X509_STORE_new()); - ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS); - ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res)); - ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), - WOLFSSL_SUCCESS); - wolfSSL_OCSP_BASICRESP_free(bs); - wolfSSL_OCSP_RESPONSE_free(res); - wolfSSL_X509_STORE_free(st); - wolfSSL_X509_free(issuer); - } +#ifdef WOLFSSL_TRUST_PEER_CERT + ExpectIntEQ(wolfSSL_CertManagerUnload_trust_peers(cm), 1); +#endif + wolfSSL_CertManagerFree(cm); #endif -#endif /* HAVE_OCSP */ return EXPECT_RESULT(); } @@ -2091,7 +1988,7 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem"; int ret; - ret = test_cm_load_ca_file(ca_cert); + ExpectIntLE(ret = test_cm_load_ca_file(ca_cert), 1); #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR); #elif defined(NO_RSA) @@ -2100,7 +1997,7 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) ExpectIntEQ(ret, WOLFSSL_SUCCESS); #endif - ret = test_cm_load_ca_file(ca_expired_cert); + ExpectIntLE(ret = test_cm_load_ca_file(ca_expired_cert), 1); #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR); #elif defined(NO_RSA) @@ -2112,7 +2009,6 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) ExpectIntEQ(ret, WOLFSSL_SUCCESS); #endif #endif - return EXPECT_RESULT(); } @@ -2124,7 +2020,8 @@ static int test_wolfSSL_CertManagerLoadCABuffer_ex(void) const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem"; int ret; - ret = test_cm_load_ca_file_ex(ca_cert, WOLFSSL_LOAD_FLAG_NONE); + ExpectIntLE(ret = test_cm_load_ca_file_ex(ca_cert, WOLFSSL_LOAD_FLAG_NONE), + 1); #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR); #elif defined(NO_RSA) @@ -2133,8 +2030,8 @@ static int test_wolfSSL_CertManagerLoadCABuffer_ex(void) ExpectIntEQ(ret, WOLFSSL_SUCCESS); #endif - ret = test_cm_load_ca_file_ex(ca_expired_cert, - WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY); + ExpectIntLE(ret = test_cm_load_ca_file_ex(ca_expired_cert, + WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), 1); #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) ExpectIntEQ(ret, WOLFSSL_FATAL_ERROR); #elif defined(NO_RSA) @@ -2175,6 +2072,7 @@ static int test_wolfSSL_CertManagerGetCerts(void) fclose(file1); } + ExpectNull(sk = wolfSSL_CertManagerGetCerts(NULL)); ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); ExpectNull(sk = wolfSSL_CertManagerGetCerts(cm)); @@ -2223,36 +2121,38 @@ static int test_wolfSSL_CertManagerSetVerify(void) #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) && \ (!defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)) - int ret = 0; WOLFSSL_CERT_MANAGER* cm = NULL; int tmp = myVerifyAction; const char* ca_cert = "./certs/ca-cert.pem"; const char* expiredCert = "./certs/test/expired/expired-cert.pem"; + wolfSSL_CertManagerSetVerify(NULL, NULL); + wolfSSL_CertManagerSetVerify(NULL, myVerify); + ExpectNotNull(cm = wolfSSL_CertManagerNew()); wolfSSL_CertManagerSetVerify(cm, myVerify); - #if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) - ExpectIntEQ(ret = wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL), -1); - #else - ExpectIntEQ(ret = wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL), +#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) + ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL), -1); +#else + ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL), WOLFSSL_SUCCESS); - #endif +#endif /* Use the test CB that always accepts certs */ myVerifyAction = VERIFY_OVERRIDE_ERROR; - ExpectIntEQ(ret = wolfSSL_CertManagerVerify(cm, expiredCert, + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, expiredCert, WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); #ifdef WOLFSSL_ALWAYS_VERIFY_CB { - const char* verifyCert = "./certs/server-cert.pem"; + const char* verifyCert = "./certs/server-cert.der"; /* Use the test CB that always fails certs */ myVerifyAction = VERIFY_FORCE_FAIL; - ExpectIntEQ(ret = wolfSSL_CertManagerVerify(cm, verifyCert, - WOLFSSL_FILETYPE_PEM), VERIFY_CERT_ERROR); + ExpectIntEQ(wolfSSL_CertManagerVerify(cm, verifyCert, + WOLFSSL_FILETYPE_ASN1), VERIFY_CERT_ERROR); } #endif @@ -3112,6 +3012,556 @@ static int test_wolfSSL_CertManagerNameConstraint5(void) return EXPECT_RESULT(); } +static int test_wolfSSL_CertManagerCRL(void) +{ + EXPECT_DECLS; +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \ + !defined(NO_RSA) + const char* ca_cert = "./certs/ca-cert.pem"; + const char* crl1 = "./certs/crl/crl.pem"; + const char* crl2 = "./certs/crl/crl2.pem"; + const unsigned char crl_buff[] = { + 0x30, 0x82, 0x02, 0x04, 0x30, 0x81, 0xed, 0x02, + 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, + 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, + 0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, + 0x53, 0x61, 0x77, 0x74, 0x6f, 0x6f, 0x74, 0x68, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x0a, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, + 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, + 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31, + 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, + 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, + 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, + 0x17, 0x0d, 0x32, 0x32, 0x31, 0x32, 0x31, 0x36, + 0x32, 0x31, 0x31, 0x37, 0x35, 0x30, 0x5a, 0x17, + 0x0d, 0x32, 0x35, 0x30, 0x39, 0x31, 0x31, 0x32, + 0x31, 0x31, 0x37, 0x35, 0x30, 0x5a, 0x30, 0x14, + 0x30, 0x12, 0x02, 0x01, 0x02, 0x17, 0x0d, 0x32, + 0x32, 0x31, 0x32, 0x31, 0x36, 0x32, 0x31, 0x31, + 0x37, 0x35, 0x30, 0x5a, 0xa0, 0x0e, 0x30, 0x0c, + 0x30, 0x0a, 0x06, 0x03, 0x55, 0x1d, 0x14, 0x04, + 0x03, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x39, 0x44, 0xff, 0x39, 0xf4, 0x04, 0x45, 0x79, + 0x7e, 0x73, 0xe2, 0x42, 0x48, 0xdb, 0x85, 0x66, + 0xfd, 0x99, 0x76, 0x94, 0x7c, 0xb5, 0x79, 0x5d, + 0x15, 0x71, 0x36, 0xa9, 0x87, 0xf0, 0x73, 0x05, + 0x50, 0x08, 0x6b, 0x1c, 0x6e, 0xde, 0x96, 0x45, + 0x31, 0xc3, 0xc0, 0xba, 0xba, 0xf5, 0x08, 0x1d, + 0x05, 0x4a, 0x52, 0x39, 0xe9, 0x03, 0xef, 0x59, + 0xc8, 0x1d, 0x4a, 0xf2, 0x86, 0x05, 0x99, 0x7b, + 0x4b, 0x74, 0xf6, 0xd3, 0x75, 0x8d, 0xb2, 0x57, + 0xba, 0xac, 0xa7, 0x11, 0x14, 0xd6, 0x6c, 0x71, + 0xc4, 0x4c, 0x1c, 0x68, 0xbc, 0x49, 0x78, 0xf0, + 0xc9, 0x52, 0x8a, 0xe7, 0x8b, 0x54, 0xe6, 0x20, + 0x58, 0x20, 0x60, 0x66, 0xf5, 0x14, 0xd8, 0xcb, + 0xff, 0xe0, 0xa0, 0x45, 0xbc, 0xb4, 0x81, 0xad, + 0x1d, 0xbc, 0xcf, 0xf8, 0x8e, 0xa8, 0x87, 0x24, + 0x55, 0x99, 0xd9, 0xce, 0x47, 0xf7, 0x5b, 0x4a, + 0x33, 0x6d, 0xdb, 0xbf, 0x93, 0x64, 0x1a, 0xa6, + 0x46, 0x5f, 0x27, 0xdc, 0xd8, 0xd4, 0xf9, 0xc2, + 0x42, 0x2a, 0x7e, 0xb2, 0x7c, 0xdd, 0x98, 0x77, + 0xf5, 0x88, 0x7d, 0x15, 0x25, 0x08, 0xbc, 0xe0, + 0xd0, 0x8d, 0xf4, 0xc3, 0xc3, 0x04, 0x41, 0xa4, + 0xd1, 0xb1, 0x39, 0x4a, 0x6b, 0x2c, 0xb5, 0x2e, + 0x9a, 0x65, 0x43, 0x0d, 0x0e, 0x73, 0xf4, 0x06, + 0xe1, 0xb3, 0x49, 0x34, 0x94, 0xb0, 0xb7, 0xff, + 0xc0, 0x27, 0xc1, 0xb5, 0xea, 0x06, 0xf7, 0x71, + 0x71, 0x97, 0xbb, 0xbc, 0xc7, 0x1a, 0x9f, 0xeb, + 0xf6, 0x3d, 0xa5, 0x7b, 0x55, 0xa7, 0xbf, 0xdd, + 0xd7, 0xee, 0x97, 0xb8, 0x9d, 0xdc, 0xcd, 0xe3, + 0x06, 0xdb, 0x9a, 0x2c, 0x60, 0xbf, 0x70, 0x84, + 0xfa, 0x6b, 0x8d, 0x70, 0x7d, 0xde, 0xe8, 0xb7, + 0xab, 0xb0, 0x38, 0x68, 0x6c, 0xc0, 0xb1, 0xe1, + 0xba, 0x45, 0xe0, 0xd7, 0x12, 0x3d, 0x71, 0x5b + }; + + WOLFSSL_CERT_MANAGER* cm = NULL; + + ExpectNotNull(cm = wolfSSL_CertManagerNew()); + + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(NULL, 0), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECK), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, + WOLFSSL_CRL_CHECK | WOLFSSL_CRL_CHECKALL), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, 16), 1); + ExpectIntEQ(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL), 1); + + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, NULL, -1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, NULL, -1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, server_cert_der_2048, -1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(NULL, server_cert_der_2048, 1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, NULL, 1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048, -1), + BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048, + sizeof_server_cert_der_2048), ASN_NO_SIGNER_E); + + ExpectIntEQ(wolfSSL_CertManagerSetCRL_Cb(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerSetCRL_Cb(cm, NULL), 1); +#ifdef HAVE_CRL_IO + ExpectIntEQ(wolfSSL_CertManagerSetCRL_IOCb(NULL, NULL), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerSetCRL_IOCb(cm, NULL), 1); +#endif + +#ifndef NO_FILESYSTEM + ExpectIntEQ(wolfSSL_CertManagerLoadCRL(NULL, NULL, WOLFSSL_FILETYPE_ASN1, + 0), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRL(cm, NULL, WOLFSSL_FILETYPE_ASN1, + 0), BAD_FUNC_ARG); + /* -1 seen as !WOLFSSL_FILETYPE_PEM */ + ExpectIntEQ(wolfSSL_CertManagerLoadCRL(cm, "./certs/crl", -1, 0), 1); + + ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(NULL, NULL, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, NULL, WOLFSSL_FILETYPE_ASN1), + BAD_FUNC_ARG); + /* -1 seen as !WOLFSSL_FILETYPE_PEM */ + ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, "./certs/crl/crl.pem", -1), + ASN_PARSE_E); +#endif + + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, NULL, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, NULL, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, crl_buff, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, NULL, 1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(NULL, crl_buff, 1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, NULL, 1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_buff, -1, + WOLFSSL_FILETYPE_ASN1), BAD_FUNC_ARG); + + ExpectIntEQ(wolfSSL_CertManagerFreeCRL(NULL), BAD_FUNC_ARG); + DoExpectIntEQ(wolfSSL_CertManagerFreeCRL(cm), 1); + + ExpectIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL)); + ExpectIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CertManagerLoadCRL(cm, crl1, WOLFSSL_FILETYPE_PEM, 0)); + ExpectIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CertManagerLoadCRL(cm, crl2, WOLFSSL_FILETYPE_PEM, 0)); + wolfSSL_CertManagerFreeCRL(cm); + + ExpectIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CertManagerLoadCRL(cm, crl1, WOLFSSL_FILETYPE_PEM, 0)); + ExpectIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL)); + ExpectIntEQ(wolfSSL_CertManagerCheckCRL(cm, server_cert_der_2048, + sizeof_server_cert_der_2048), CRL_MISSING); + ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, server_cert_der_2048, + sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1), CRL_MISSING); + + ExpectIntEQ(wolfSSL_CertManagerLoadCRLBuffer(cm, crl_buff, sizeof(crl_buff), + WOLFSSL_FILETYPE_ASN1), 1); + + wolfSSL_CertManagerFree(cm); +#endif + + return EXPECT_RESULT(); +} + +static int test_wolfSSL_CertManagerCheckOCSPResponse(void) +{ + EXPECT_DECLS; +#if defined(HAVE_OCSP) && !defined(NO_RSA) +/* Need one of these for wolfSSL_OCSP_REQUEST_new. */ +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_APACHE_HTTPD) || \ + defined(HAVE_LIGHTY) + WOLFSSL_CERT_MANAGER* cm = NULL; + /* Raw OCSP response bytes captured using the following setup: + * - Run responder with + * openssl ocsp -port 9999 -ndays 9999 + * -index certs/ocsp/index-intermediate1-ca-issued-certs.txt + * -rsigner certs/ocsp/ocsp-responder-cert.pem + * -rkey certs/ocsp/ocsp-responder-key.pem + * -CA certs/ocsp/intermediate1-ca-cert.pem + * - Run client with + * openssl ocsp -host 127.0.0.1:9999 -respout resp.out + * -issuer certs/ocsp/intermediate1-ca-cert.pem + * -cert certs/ocsp/server1-cert.pem + * -CAfile certs/ocsp/root-ca-cert.pem -noverify + * - Copy raw response from Wireshark. + */ + byte response[] = { + 0x30, 0x82, 0x07, 0x40, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x07, 0x39, 0x30, 0x82, 0x07, 0x35, 0x06, + 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01, 0x04, 0x82, 0x07, 0x26, 0x30, 0x82, + 0x07, 0x22, 0x30, 0x82, 0x01, 0x40, 0xa1, 0x81, 0xa1, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, + 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, 0x50, 0x20, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, + 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, + 0x30, 0x35, 0x30, 0x33, 0x32, 0x31, 0x34, 0x37, 0x31, 0x30, 0x5a, 0x30, 0x64, 0x30, 0x62, 0x30, + 0x3a, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x71, 0x4d, + 0x82, 0x23, 0x40, 0x59, 0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18, + 0xda, 0x04, 0x04, 0x14, 0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, 0xd7, 0x9d, 0x4c, 0xe2, + 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e, 0x02, 0x01, 0x05, 0x80, 0x00, 0x18, 0x0f, 0x32, + 0x30, 0x32, 0x31, 0x30, 0x35, 0x30, 0x33, 0x32, 0x31, 0x34, 0x37, 0x31, 0x30, 0x5a, 0xa0, 0x11, + 0x18, 0x0f, 0x32, 0x30, 0x34, 0x38, 0x30, 0x39, 0x31, 0x37, 0x32, 0x31, 0x34, 0x37, 0x31, 0x30, + 0x5a, 0xa1, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x02, 0x04, 0x12, 0x04, 0x10, 0x38, 0x31, 0x60, 0x99, 0xc8, 0x05, 0x09, 0x68, 0x1c, 0x33, + 0x49, 0xea, 0x45, 0x26, 0x2f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4d, 0x58, 0xcc, 0x69, 0x42, 0xe2, + 0x9e, 0x64, 0xf6, 0x57, 0xce, 0xcb, 0x5f, 0x14, 0xaf, 0x08, 0x6c, 0xc1, 0x52, 0x7a, 0x40, 0x0a, + 0xfd, 0xb6, 0xce, 0xbb, 0x40, 0xf4, 0xb9, 0xa5, 0x88, 0xc7, 0xf3, 0x42, 0x9f, 0xa9, 0x94, 0xbe, + 0x6e, 0x7e, 0x09, 0x30, 0x9d, 0x0e, 0x10, 0x6f, 0x9c, 0xd9, 0x4c, 0x71, 0x81, 0x41, 0x64, 0x95, + 0xf5, 0x85, 0x77, 0x94, 0x81, 0x61, 0x88, 0xc8, 0x0b, 0x50, 0xbb, 0x37, 0xc8, 0x86, 0x76, 0xd8, + 0xa2, 0xed, 0x66, 0x34, 0xfb, 0xe4, 0xe7, 0x09, 0x8c, 0xf5, 0xb5, 0x85, 0xd0, 0x4b, 0xb5, 0xe6, + 0x23, 0x62, 0xc3, 0xd0, 0xef, 0xf7, 0x42, 0x89, 0x02, 0x80, 0x64, 0xc9, 0xed, 0xdd, 0x7c, 0x8f, + 0x0d, 0xe7, 0x43, 0x9b, 0x88, 0x1f, 0xb0, 0xfd, 0x24, 0x01, 0xc7, 0x55, 0xc3, 0x73, 0x12, 0x84, + 0x09, 0x7c, 0x57, 0xa8, 0x5d, 0xab, 0x75, 0x29, 0x5c, 0x36, 0x97, 0x64, 0x40, 0x0b, 0x55, 0x34, + 0x0a, 0x5d, 0xb1, 0x1b, 0x61, 0x1b, 0xdc, 0xe5, 0x89, 0xdd, 0x92, 0x62, 0x57, 0xa7, 0x52, 0xb4, + 0x38, 0x9a, 0x48, 0xc8, 0x3a, 0x14, 0xde, 0x69, 0x42, 0xe9, 0x37, 0xa4, 0xe7, 0x2d, 0x00, 0xa7, + 0x0b, 0x29, 0x18, 0xd5, 0xce, 0xd9, 0x0d, 0xdd, 0xfe, 0xae, 0x86, 0xb3, 0x32, 0x1c, 0xc9, 0x33, + 0xb0, 0x2b, 0xb7, 0x3c, 0x0d, 0x43, 0xd8, 0x6c, 0xf2, 0xb7, 0xcd, 0x7b, 0xd5, 0x7d, 0xf0, 0xde, + 0x34, 0x9f, 0x6d, 0x83, 0xb9, 0xd5, 0xed, 0xe3, 0xda, 0x96, 0x40, 0x9e, 0xd6, 0xa6, 0xfd, 0x70, + 0x80, 0x70, 0x87, 0x61, 0x0f, 0xc5, 0x9f, 0x75, 0xfe, 0x11, 0x78, 0x34, 0xc9, 0x42, 0x16, 0x73, + 0x46, 0x7b, 0x05, 0x53, 0x28, 0x43, 0xbe, 0xee, 0x88, 0x67, 0x1d, 0xcc, 0x74, 0xa7, 0xb6, 0x58, + 0x7b, 0x29, 0x68, 0x40, 0xcf, 0xce, 0x7b, 0x19, 0x33, 0x68, 0xa0, 0x82, 0x04, 0xc6, 0x30, 0x82, + 0x04, 0xc2, 0x30, 0x82, 0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, + 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, + 0x53, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, + 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, + 0x31, 0x30, 0x32, 0x31, 0x30, 0x31, 0x39, 0x34, 0x39, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x33, + 0x31, 0x31, 0x30, 0x37, 0x31, 0x39, 0x34, 0x39, 0x35, 0x34, 0x5a, 0x30, 0x81, 0x9e, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, + 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, + 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, + 0x50, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, + 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb8, 0xba, 0x23, + 0xb4, 0xf6, 0xc3, 0x7b, 0x14, 0xc3, 0xa4, 0xf5, 0x1d, 0x61, 0xa1, 0xf5, 0x1e, 0x63, 0xb9, 0x85, + 0x23, 0x34, 0x50, 0x6d, 0xf8, 0x7c, 0xa2, 0x8a, 0x04, 0x8b, 0xd5, 0x75, 0x5c, 0x2d, 0xf7, 0x63, + 0x88, 0xd1, 0x07, 0x7a, 0xea, 0x0b, 0x45, 0x35, 0x2b, 0xeb, 0x1f, 0xb1, 0x22, 0xb4, 0x94, 0x41, + 0x38, 0xe2, 0x9d, 0x74, 0xd6, 0x8b, 0x30, 0x22, 0x10, 0x51, 0xc5, 0xdb, 0xca, 0x3f, 0x46, 0x2b, + 0xfe, 0xe5, 0x5a, 0x3f, 0x41, 0x74, 0x67, 0x75, 0x95, 0xa9, 0x94, 0xd5, 0xc3, 0xee, 0x42, 0xf8, + 0x8d, 0xeb, 0x92, 0x95, 0xe1, 0xd9, 0x65, 0xb7, 0x43, 0xc4, 0x18, 0xde, 0x16, 0x80, 0x90, 0xce, + 0x24, 0x35, 0x21, 0xc4, 0x55, 0xac, 0x5a, 0x51, 0xe0, 0x2e, 0x2d, 0xb3, 0x0a, 0x5a, 0x4f, 0x4a, + 0x73, 0x31, 0x50, 0xee, 0x4a, 0x16, 0xbd, 0x39, 0x8b, 0xad, 0x05, 0x48, 0x87, 0xb1, 0x99, 0xe2, + 0x10, 0xa7, 0x06, 0x72, 0x67, 0xca, 0x5c, 0xd1, 0x97, 0xbd, 0xc8, 0xf1, 0x76, 0xf8, 0xe0, 0x4a, + 0xec, 0xbc, 0x93, 0xf4, 0x66, 0x4c, 0x28, 0x71, 0xd1, 0xd8, 0x66, 0x03, 0xb4, 0x90, 0x30, 0xbb, + 0x17, 0xb0, 0xfe, 0x97, 0xf5, 0x1e, 0xe8, 0xc7, 0x5d, 0x9b, 0x8b, 0x11, 0x19, 0x12, 0x3c, 0xab, + 0x82, 0x71, 0x78, 0xff, 0xae, 0x3f, 0x32, 0xb2, 0x08, 0x71, 0xb2, 0x1b, 0x8c, 0x27, 0xac, 0x11, + 0xb8, 0xd8, 0x43, 0x49, 0xcf, 0xb0, 0x70, 0xb1, 0xf0, 0x8c, 0xae, 0xda, 0x24, 0x87, 0x17, 0x3b, + 0xd8, 0x04, 0x65, 0x6c, 0x00, 0x76, 0x50, 0xef, 0x15, 0x08, 0xd7, 0xb4, 0x73, 0x68, 0x26, 0x14, + 0x87, 0x95, 0xc3, 0x5f, 0x6e, 0x61, 0xb8, 0x87, 0x84, 0xfa, 0x80, 0x1a, 0x0a, 0x8b, 0x98, 0xf3, + 0xe3, 0xff, 0x4e, 0x44, 0x1c, 0x65, 0x74, 0x7c, 0x71, 0x54, 0x65, 0xe5, 0x39, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x32, 0x67, 0xe1, 0xb1, 0x79, 0xd2, 0x81, 0xfc, 0x9f, 0x23, 0x0c, 0x70, 0x40, 0x50, 0xb5, 0x46, + 0x56, 0xb8, 0x30, 0x36, 0x30, 0x81, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xbc, 0x30, + 0x81, 0xb9, 0x80, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f, 0x82, 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, + 0xb0, 0x04, 0x82, 0x3a, 0x7e, 0x72, 0x15, 0x21, 0xa1, 0x81, 0x9d, 0xa4, 0x81, 0x9a, 0x30, 0x81, + 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, + 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, + 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, + 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, + 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, + 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x63, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x07, 0xca, 0xa6, 0xa1, 0x9f, 0xbf, 0xaf, 0x92, 0x41, 0x35, 0x66, 0x51, + 0xac, 0xbc, 0x2c, 0xec, 0xe7, 0x8d, 0x65, 0x7e, 0xe9, 0x40, 0xfe, 0x5a, 0xab, 0x8a, 0x1d, 0x3d, + 0x13, 0xdb, 0xb4, 0x43, 0x2c, 0x9a, 0x36, 0x98, 0x21, 0xa5, 0xe8, 0xca, 0xa9, 0x4d, 0xfc, 0xe3, + 0xf7, 0x45, 0x88, 0xcd, 0x33, 0xbf, 0x8a, 0x62, 0x10, 0x2f, 0xb2, 0xb7, 0x04, 0xef, 0x26, 0x43, + 0x51, 0x1d, 0x43, 0x62, 0x7d, 0x1e, 0x50, 0xc8, 0xd5, 0x98, 0x94, 0x71, 0x8f, 0x3b, 0x23, 0x26, + 0xf1, 0x71, 0x8e, 0x1e, 0x3d, 0x3f, 0x21, 0xfd, 0xb7, 0x2d, 0x65, 0xe4, 0x07, 0x65, 0xac, 0x3c, + 0xfc, 0xc0, 0x47, 0xa9, 0x32, 0xf6, 0xda, 0x26, 0x93, 0x10, 0xb2, 0xd1, 0x6d, 0xc8, 0x81, 0x31, + 0x7c, 0xb0, 0x6b, 0xc5, 0x22, 0x8d, 0xb3, 0xfa, 0xbe, 0x82, 0xea, 0x41, 0x42, 0xc4, 0xc0, 0xef, + 0xe3, 0x84, 0x0f, 0x6f, 0x9a, 0x03, 0x63, 0xb3, 0x30, 0xe0, 0x31, 0x81, 0x2a, 0x16, 0xb3, 0x47, + 0xd9, 0x5b, 0x38, 0x93, 0x07, 0xd0, 0x6e, 0x79, 0x52, 0x2c, 0xe5, 0x50, 0x84, 0x79, 0x10, 0xe7, + 0xf6, 0x31, 0x7a, 0x3e, 0x48, 0xa2, 0x38, 0x21, 0x90, 0x7a, 0xf2, 0x5f, 0x48, 0xa4, 0x46, 0x93, + 0x87, 0xdd, 0x5c, 0x83, 0x64, 0xea, 0xb5, 0x99, 0xa2, 0xe9, 0x01, 0x40, 0xfe, 0xf0, 0x48, 0x66, + 0x4f, 0x96, 0xf7, 0x83, 0x52, 0xf8, 0x6d, 0xf8, 0x5f, 0xed, 0x0c, 0xbb, 0xbe, 0xd0, 0x69, 0x10, + 0x4b, 0x99, 0x8f, 0xf8, 0x61, 0x53, 0x9d, 0x12, 0xca, 0x86, 0xaa, 0xb1, 0x80, 0xb4, 0xa6, 0xc1, + 0xcb, 0xb7, 0x48, 0xf7, 0x9f, 0x55, 0xb4, 0x6e, 0xab, 0xd3, 0xa1, 0xaa, 0x4b, 0xa7, 0x21, 0x6e, + 0x16, 0x7f, 0xad, 0xbb, 0xea, 0x0f, 0x41, 0x80, 0x9b, 0x7f, 0xd6, 0x46, 0xa2, 0xc0, 0x61, 0x72, + 0x59, 0x59, 0xa0, 0x07 + }; + OcspEntry entry[1]; + CertStatus status[1]; + OcspRequest* request = NULL; +#ifndef NO_FILESYSTEM + const char* ca_cert = "./certs/ca-cert.pem"; +#endif + + byte serial[] = {0x05}; + byte issuerHash[] = {0x71, 0x4d, 0x82, 0x23, 0x40, 0x59, 0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18, 0xda, 0x04}; + byte issuerKeyHash[] = {0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, 0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e}; + + + XMEMSET(entry, 0, sizeof(OcspEntry)); + XMEMSET(status, 0, sizeof(CertStatus)); + + ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new()); + ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL, + DYNAMIC_TYPE_OCSP_REQUEST)); + + if ((request != NULL) && (request->serial != NULL)) { + request->serialSz = sizeof(serial); + XMEMCPY(request->serial, serial, sizeof(serial)); + XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash)); + XMEMCPY(request->issuerKeyHash, issuerKeyHash, sizeof(issuerKeyHash)); + } + + ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, + "./certs/ocsp/intermediate1-ca-cert.pem", NULL), WOLFSSL_SUCCESS); + + /* Response should be valid. */ + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, response, + sizeof(response), NULL, status, entry, request), WOLFSSL_SUCCESS); + + /* Flip a byte in the request serial number, response should be invalid + * now. */ + if ((request != NULL) && (request->serial != NULL)) + request->serial[0] ^= request->serial[0]; + ExpectIntNE(wolfSSL_CertManagerCheckOCSPResponse(cm, response, + sizeof(response), NULL, status, entry, request), WOLFSSL_SUCCESS); + +#ifndef NO_FILESYSTEM + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, server_cert_der_2048, + sizeof(server_cert_der_2048)), ASN_NO_SIGNER_E); + ExpectIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL)); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSP(cm, server_cert_der_2048, + sizeof(server_cert_der_2048)), 1); +#endif + + wolfSSL_OCSP_REQUEST_free(request); + wolfSSL_CertManagerFree(cm); +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || + * WOLFSSL_APACHE_HTTPD || HAVE_LIGHTY */ +#endif /* HAVE_OCSP */ + return EXPECT_RESULT(); +} + +static int test_wolfSSL_CheckOCSPResponse(void) +{ + EXPECT_DECLS; +#if defined(HAVE_OCSP) && !defined(NO_RSA) && defined(OPENSSL_ALL) + const char* responseFile = "./certs/ocsp/test-response.der"; + const char* responseMultiFile = "./certs/ocsp/test-multi-response.der"; + const char* responseNoInternFile = + "./certs/ocsp/test-response-nointern.der"; + const char* caFile = "./certs/ocsp/root-ca-cert.pem"; + OcspResponse* res = NULL; + byte data[4096]; + const unsigned char* pt; + int dataSz = 0; /* initialize to mitigate spurious maybe-uninitialized from + * gcc sanitizer with --enable-heapmath. + */ + XFILE f = XBADFILE; + WOLFSSL_OCSP_BASICRESP* bs = NULL; + WOLFSSL_X509_STORE* st = NULL; + WOLFSSL_X509* issuer = NULL; + + + ExpectTrue((f = XFOPEN(responseFile, "rb")) != XBADFILE); + ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); + if (f != XBADFILE) { + XFCLOSE(f); + f = XBADFILE; + } + + pt = data; + ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz)); + ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile, + SSL_FILETYPE_PEM)); + ExpectNotNull(st = wolfSSL_X509_STORE_new()); + ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS); + ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res)); + ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), WOLFSSL_SUCCESS); + wolfSSL_OCSP_BASICRESP_free(bs); + bs = NULL; + wolfSSL_OCSP_RESPONSE_free(res); + res = NULL; + wolfSSL_X509_STORE_free(st); + st = NULL; + wolfSSL_X509_free(issuer); + issuer = NULL; + + /* check loading a response with optional certs */ + ExpectTrue((f = XFOPEN(responseNoInternFile, "rb")) != XBADFILE); + ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); + if (f != XBADFILE) + XFCLOSE(f); + f = XBADFILE; + + pt = data; + ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz)); + wolfSSL_OCSP_RESPONSE_free(res); + res = NULL; + + /* check loading a response with multiple certs */ + { + WOLFSSL_CERT_MANAGER* cm = NULL; + OcspEntry *entry = NULL; + CertStatus* status = NULL; + OcspRequest* request = NULL; + + byte serial1[] = {0x01}; + byte serial[] = {0x02}; + + byte issuerHash[] = { + 0x44, 0xA8, 0xDB, 0xD1, 0xBC, 0x97, 0x0A, 0x83, + 0x3B, 0x5B, 0x31, 0x9A, 0x4C, 0xB8, 0xD2, 0x52, + 0x37, 0x15, 0x8A, 0x88 + }; + byte issuerKeyHash[] = { + 0x73, 0xB0, 0x1C, 0xA4, 0x2F, 0x82, 0xCB, 0xCF, + 0x47, 0xA5, 0x38, 0xD7, 0xB0, 0x04, 0x82, 0x3A, + 0x7E, 0x72, 0x15, 0x21 + }; + + ExpectNotNull(entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL, + DYNAMIC_TYPE_OPENSSL)); + + ExpectNotNull(status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, + DYNAMIC_TYPE_OPENSSL)); + + if (entry != NULL) + XMEMSET(entry, 0, sizeof(OcspEntry)); + if (status != NULL) + XMEMSET(status, 0, sizeof(CertStatus)); + + ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new()); + ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL, + DYNAMIC_TYPE_OCSP_REQUEST)); + + if (request != NULL && request->serial != NULL) { + request->serialSz = sizeof(serial); + XMEMCPY(request->serial, serial, sizeof(serial)); + XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash)); + XMEMCPY(request->issuerKeyHash, issuerKeyHash, + sizeof(issuerKeyHash)); + } + + ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); + ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caFile, NULL), + WOLFSSL_SUCCESS); + + ExpectTrue((f = XFOPEN(responseMultiFile, "rb")) != XBADFILE); + ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); + if (f != XBADFILE) + XFCLOSE(f); + f = XBADFILE; + + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, + dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, + dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS); + ExpectNotNull(entry->status); + + if (request != NULL && request->serial != NULL) + XMEMCPY(request->serial, serial1, sizeof(serial1)); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, + dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS); + + /* store both status's in the entry to check that "next" is not + * overwritten */ + if (EXPECT_SUCCESS() && status != NULL && entry != NULL) { + status->next = entry->status; + entry->status = status; + } + + if (request != NULL && request->serial != NULL) + XMEMCPY(request->serial, serial, sizeof(serial)); + ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data, + dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS); + ExpectNotNull(entry->status->next); + + /* compare the status found */ + ExpectIntEQ(status->serialSz, entry->status->serialSz); + ExpectIntEQ(XMEMCMP(status->serial, entry->status->serial, + status->serialSz), 0); + + if (status != NULL && entry != NULL && entry->status != status) { + XFREE(status, NULL, DYNAMIC_TYPE_OPENSSL); + } + wolfSSL_OCSP_CERTID_free(entry); + wolfSSL_OCSP_REQUEST_free(request); + wolfSSL_CertManagerFree(cm); + } + +#if defined(WC_RSA_PSS) + { + const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der"; + + /* check loading a response with RSA-PSS signature */ + ExpectTrue((f = XFOPEN(responsePssFile, "rb")) != XBADFILE); + ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0); + if (f != XBADFILE) + XFCLOSE(f); + + pt = data; + ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz)); + + /* try to verify the response */ + ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile, + SSL_FILETYPE_PEM)); + ExpectNotNull(st = wolfSSL_X509_STORE_new()); + ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS); + ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res)); + ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), + WOLFSSL_SUCCESS); + wolfSSL_OCSP_BASICRESP_free(bs); + wolfSSL_OCSP_RESPONSE_free(res); + wolfSSL_X509_STORE_free(st); + wolfSSL_X509_free(issuer); + } +#endif +#endif /* HAVE_OCSP */ + return EXPECT_RESULT(); +} + static int test_wolfSSL_FPKI(void) { EXPECT_DECLS; @@ -3232,36 +3682,6 @@ static int test_wolfSSL_CertRsaPss(void) return EXPECT_RESULT(); } -static int test_wolfSSL_CertManagerCRL(void) -{ - EXPECT_DECLS; -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \ - !defined(NO_RSA) - const char* ca_cert = "./certs/ca-cert.pem"; - const char* crl1 = "./certs/crl/crl.pem"; - const char* crl2 = "./certs/crl/crl2.pem"; - - WOLFSSL_CERT_MANAGER* cm = NULL; - - ExpectNotNull(cm = wolfSSL_CertManagerNew()); - ExpectIntEQ(WOLFSSL_SUCCESS, - wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL)); - ExpectIntEQ(WOLFSSL_SUCCESS, - wolfSSL_CertManagerLoadCRL(cm, crl1, WOLFSSL_FILETYPE_PEM, 0)); - ExpectIntEQ(WOLFSSL_SUCCESS, - wolfSSL_CertManagerLoadCRL(cm, crl2, WOLFSSL_FILETYPE_PEM, 0)); - wolfSSL_CertManagerFreeCRL(cm); - - ExpectIntEQ(WOLFSSL_SUCCESS, - wolfSSL_CertManagerLoadCRL(cm, crl1, WOLFSSL_FILETYPE_PEM, 0)); - ExpectIntEQ(WOLFSSL_SUCCESS, - wolfSSL_CertManagerLoadCA(cm, ca_cert, NULL)); - wolfSSL_CertManagerFree(cm); -#endif - - return EXPECT_RESULT(); -} - static int test_wolfSSL_CTX_load_verify_locations_ex(void) { EXPECT_DECLS; @@ -9456,61 +9876,61 @@ static int test_wolfSSL_UseSNI_connection(void) #endif /* success case at ctx */ - printf("\n\tsuccess case at ctx\n"); + fprintf(stderr, "\n\tsuccess case at ctx\n"); client_cb.ctx_ready = use_SNI_at_ctx; client_cb.ssl_ready = NULL; client_cb.on_result = NULL; server_cb.ctx_ready = use_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_real_matching; test_wolfSSL_client_server(&client_cb, &server_cb); /* success case at ssl */ - printf("\tsuccess case at ssl\n"); + fprintf(stderr, "\tsuccess case at ssl\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_SNI_at_ssl; client_cb.on_result = verify_SNI_real_matching; server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_SNI_real_matching; test_wolfSSL_client_server(&client_cb, &server_cb); /* default mismatch behavior */ - printf("\tdefault mismatch behavior\n"); + fprintf(stderr, "\tdefault mismatch behavior\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = verify_FATAL_ERROR_on_client; server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_UNKNOWN_SNI_on_server; test_wolfSSL_client_server(&client_cb, &server_cb); /* continue on mismatch */ - printf("\tcontinue on mismatch\n"); + fprintf(stderr, "\tcontinue on mismatch\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL; server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_WITH_CONTINUE_at_ssl; server_cb.on_result = verify_SNI_no_matching; test_wolfSSL_client_server(&client_cb, &server_cb); /* fake answer on mismatch */ - printf("\tfake answer on mismatch\n"); + fprintf(stderr, "\tfake answer on mismatch\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL; server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_WITH_FAKE_ANSWER_at_ssl; server_cb.on_result = verify_SNI_fake_matching; test_wolfSSL_client_server(&client_cb, &server_cb); /* sni abort - success */ - printf("\tsni abort - success\n"); + fprintf(stderr, "\tsni abort - success\n"); client_cb.ctx_ready = use_SNI_at_ctx; client_cb.ssl_ready = NULL; client_cb.on_result = NULL; server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_real_matching; test_wolfSSL_client_server(&client_cb, &server_cb); /* sni abort - abort when absent (ctx) */ - printf("\tsni abort - abort when absent (ctx)\n"); + fprintf(stderr, "\tsni abort - abort when absent (ctx)\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = verify_FATAL_ERROR_on_client; server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_ABSENT_on_server; test_wolfSSL_client_server(&client_cb, &server_cb); /* sni abort - abort when absent (ssl) */ - printf("\tsni abort - abort when absent (ssl)\n"); + fprintf(stderr, "\tsni abort - abort when absent (ssl)\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = verify_FATAL_ERROR_on_client; server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_MANDATORY_SNI_at_ssl; server_cb.on_result = verify_SNI_ABSENT_on_server; test_wolfSSL_client_server(&client_cb, &server_cb); /* sni abort - success when overwritten */ - printf("\tsni abort - success when overwritten\n"); + fprintf(stderr, "\tsni abort - success when overwritten\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = NULL; server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_SNI_no_matching; test_wolfSSL_client_server(&client_cb, &server_cb); /* sni abort - success when allowing mismatches */ - printf("\tsni abort - success when allowing mismatches\n"); + fprintf(stderr, "\tsni abort - success when allowing mismatches\n"); client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL; server_cb.ctx_ready = use_PSEUDO_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_fake_matching; test_wolfSSL_client_server(&client_cb, &server_cb); @@ -34074,12 +34494,12 @@ static THREAD_RETURN WOLFSSL_THREAD server_task_ech(void* args) if (ret != WOLFSSL_SUCCESS) { char buff[WOLFSSL_MAX_ERROR_SZ]; - printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buff)); + fprintf(stderr, "error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buff)); } else { if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) { input[idx] = 0; - printf("Client message: %s\n", input); + fprintf(stderr, "Client message: %s\n", input); } AssertIntEQ(privateNameLen, wolfSSL_write(ssl, privateName, @@ -61592,11 +62012,11 @@ static int test_harden_no_secure_renegotiation(void) static int test_override_alt_cert_chain_cert_cb(int preverify, WOLFSSL_X509_STORE_CTX* store) { - printf("preverify: %d\n", preverify); - printf("store->error: %d\n", store->error); - printf("error reason: %s\n", wolfSSL_ERR_reason_error_string(store->error)); + fprintf(stderr, "preverify: %d\n", preverify); + fprintf(stderr, "store->error: %d\n", store->error); + fprintf(stderr, "error reason: %s\n", wolfSSL_ERR_reason_error_string(store->error)); if (store->error == OCSP_INVALID_STATUS) { - printf("Overriding OCSP error\n"); + fprintf(stderr, "Overriding OCSP error\n"); return 1; } #ifndef WOLFSSL_ALT_CERT_CHAINS @@ -61607,7 +62027,7 @@ static int test_override_alt_cert_chain_cert_cb(int preverify, || store->error == WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY #endif ) && store->error_depth == store->totalCerts - 1) { - printf("Overriding no signer error only for root cert\n"); + fprintf(stderr, "Overriding no signer error only for root cert\n"); return 1; } #endif @@ -61683,7 +62103,7 @@ static int test_override_alt_cert_chain(void) XMEMSET(&client_cbs, 0, sizeof(client_cbs)); XMEMSET(&server_cbs, 0, sizeof(server_cbs)); - printf("test config: %d\n", (int)i); + fprintf(stderr, "test config: %d\n", (int)i); client_cbs.ctx_ready = params[i].client_ctx_cb; server_cbs.ctx_ready = params[i].server_ctx_cb; @@ -61822,13 +62242,13 @@ static int test_short_session_id(void) #endif }; - printf("\n"); + fprintf(stderr, "\n"); for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) { XMEMSET(&client_cbf, 0, sizeof(client_cbf)); XMEMSET(&server_cbf, 0, sizeof(server_cbf)); - printf("\tTesting short ID with %s\n", params[i].tls_version); + fprintf(stderr, "\tTesting short ID with %s\n", params[i].tls_version); client_cbf.ssl_ready = test_short_session_id_ssl_ready; client_cbf.method = params[i].client_meth; @@ -62490,6 +62910,8 @@ TEST_CASE testCases[] = { */ TEST_DECL(test_wolfCrypt_Cleanup), + TEST_DECL(test_wolfSSL_Init), + /********************************* * OpenSSL compatibility API tests *********************************/ @@ -63031,11 +63453,33 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_FIPS_mode), TEST_DECL(test_openssl_FIPS_drbg), + /********************************* + * CertManager API tests + *********************************/ + + TEST_DECL(test_wolfSSL_CertManagerAPI), + TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer), + TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer_ex), + TEST_DECL(test_wolfSSL_CertManagerGetCerts), + TEST_DECL(test_wolfSSL_CertManagerSetVerify), + TEST_DECL(test_wolfSSL_CertManagerNameConstraint), + TEST_DECL(test_wolfSSL_CertManagerNameConstraint2), + TEST_DECL(test_wolfSSL_CertManagerNameConstraint3), + TEST_DECL(test_wolfSSL_CertManagerNameConstraint4), + TEST_DECL(test_wolfSSL_CertManagerNameConstraint5), + TEST_DECL(test_wolfSSL_CertManagerCRL), + TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse), + TEST_DECL(test_wolfSSL_CheckOCSPResponse), +#if !defined(NO_RSA) && !defined(NO_SHA) && !defined(NO_FILESYSTEM) && \ + !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \ + !defined(WOLFSSL_NO_CLIENT_AUTH)) + TEST_DECL(test_various_pathlen_chains), +#endif + /********************************* * SSL/TLS API tests *********************************/ - TEST_DECL(test_wolfSSL_Init), TEST_DECL(test_wolfSSL_Method_Allocators), #ifndef NO_WOLFSSL_SERVER TEST_DECL(test_wolfSSL_CTX_new), @@ -63113,24 +63557,6 @@ TEST_CASE testCases[] = { /* Large number of memory allocations. */ TEST_DECL(test_wolfSSL_CTX_load_system_CA_certs), - TEST_DECL(test_wolfSSL_CertManagerCheckOCSPResponse), - TEST_DECL(test_wolfSSL_CheckOCSPResponse), - TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer), - TEST_DECL(test_wolfSSL_CertManagerLoadCABuffer_ex), - TEST_DECL(test_wolfSSL_CertManagerGetCerts), - TEST_DECL(test_wolfSSL_CertManagerSetVerify), - TEST_DECL(test_wolfSSL_CertManagerNameConstraint), - TEST_DECL(test_wolfSSL_CertManagerNameConstraint2), - TEST_DECL(test_wolfSSL_CertManagerNameConstraint3), - TEST_DECL(test_wolfSSL_CertManagerNameConstraint4), - TEST_DECL(test_wolfSSL_CertManagerNameConstraint5), - TEST_DECL(test_wolfSSL_CertManagerCRL), -#if !defined(NO_RSA) && !defined(NO_SHA) && !defined(NO_FILESYSTEM) && \ - !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \ - !defined(WOLFSSL_NO_CLIENT_AUTH)) - TEST_DECL(test_various_pathlen_chains), -#endif - TEST_DECL(test_wolfSSL_CertRsaPss), TEST_DECL(test_wolfSSL_CTX_load_verify_locations_ex), TEST_DECL(test_wolfSSL_CTX_load_verify_buffer_ex), diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 469ac2c3bf..30424cf72f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -21584,7 +21584,7 @@ static int GetAKIHash(const byte* input, word32 maxIdx, int sigOID, ret = GetHashId( dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.data, dataASN[AUTHKEYIDASN_IDX_KEYID].data.ref.length, - hash, sigOID); + hash, HashIdAlg(sigOID)); } break; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index b4e630ad5a..16529d03bd 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2603,7 +2603,7 @@ WOLFSSL_LOCAL int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz); WOLFSSL_LOCAL int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm); WOLFSSL_LOCAL int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff, - long sz, int format, int err_val); + long sz, int format, int prev_err); #ifndef NO_CERTS diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b562d4b853..90f35b0f0e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3548,70 +3548,73 @@ WOLFSSL_API void wolfSSL_CTX_SetPerformTlsRecordProcessingCb(WOLFSSL_CTX* ctx, WOLFSSL_API void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm); - WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* f, - const char* d); + WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, + const char* f, const char* d); WOLFSSL_API int wolfSSL_CertManagerLoadCABuffer_ex(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* in, long sz, int format, int userChain, - word32 flags); + const unsigned char* buff, long sz, int format, int userChain, + word32 flags); WOLFSSL_API int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* in, long sz, int format); + const unsigned char* buff, long sz, int format); WOLFSSL_API int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm); #ifdef WOLFSSL_TRUST_PEER_CERT - WOLFSSL_API int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_API int wolfSSL_CertManagerUnload_trust_peers( + WOLFSSL_CERT_MANAGER* cm); #endif - WOLFSSL_API int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* f, - int format); + WOLFSSL_API int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, + const char* f, int format); WOLFSSL_API int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* buff, long sz, int format); + const unsigned char* buff, long sz, int format); WOLFSSL_API int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, - unsigned char* der, int sz); + const unsigned char* der, int sz); WOLFSSL_API int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, - int options); + int options); WOLFSSL_API int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, - VerifyCallback vc); + VerifyCallback vc); WOLFSSL_API int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, - const char* path, int type, int monitor); + const char* path, int type, int monitor); WOLFSSL_API int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, - const char* file, int type); + const char* file, int type); WOLFSSL_API int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm, - const unsigned char* buff, long sz, int type); + const unsigned char* buff, long sz, int type); WOLFSSL_API int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, - CbMissingCRL cb); + CbMissingCRL cb); WOLFSSL_API int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm); #ifdef HAVE_CRL_IO WOLFSSL_API int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, - CbCrlIO cb); + CbCrlIO cb); #endif #if defined(HAVE_OCSP) - WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER* cm, - byte *response, int responseSz, WOLFSSL_BUFFER_INFO *responseBuffer, - CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest); + WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse( + WOLFSSL_CERT_MANAGER* cm, unsigned char *response, int responseSz, + WOLFSSL_BUFFER_INFO *responseBuffer, CertStatus *status, + OcspEntry *entry, OcspRequest *ocspRequest); #endif WOLFSSL_API int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, - unsigned char* der, int sz); + const unsigned char* der, int sz); WOLFSSL_API int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, - int options); + int options); WOLFSSL_API int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm); - WOLFSSL_API int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm, - const char* url); + WOLFSSL_API int wolfSSL_CertManagerSetOCSPOverrideURL( + WOLFSSL_CERT_MANAGER* cm, const char* url); WOLFSSL_API int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm, - CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx); + CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx); WOLFSSL_API int wolfSSL_CertManagerEnableOCSPStapling( - WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API int wolfSSL_CertManagerDisableOCSPStapling( - WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API int wolfSSL_CertManagerEnableOCSPMustStaple( - WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API int wolfSSL_CertManagerDisableOCSPMustStaple( - WOLFSSL_CERT_MANAGER* cm); + WOLFSSL_CERT_MANAGER* cm); #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SIGNER_DER_CERT) && \ !defined(NO_FILESYSTEM) -WOLFSSL_API WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_CertManagerGetCerts( + WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( - WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name); + WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name); #endif /* OPENSSL_EXTRA && WOLFSSL_SIGNER_DER_CERT && !NO_FILESYSTEM */ WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options); WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl);