diff --git a/.github/workflows/os-check.yml b/.github/workflows/os-check.yml index 81f071ccf31..07b8272c238 100644 --- a/.github/workflows/os-check.yml +++ b/.github/workflows/os-check.yml @@ -61,6 +61,8 @@ jobs: '--enable-all CPPFLAGS=-DWOLFSSL_DEBUG_CERTS ', '--enable-all CFLAGS="-DWOLFSSL_CHECK_MEM_ZERO"', '--enable-coding=no', + '--enable-dtls --enable-dtls13 --enable-ocspstapling --enable-ocspstapling2 + --enable-cert-setup-cb --enable-sessioncerts', ] name: make check if: github.repository_owner == 'wolfssl' diff --git a/IDE/GCC-ARM/Header/user_settings.h b/IDE/GCC-ARM/Header/user_settings.h index 2265ddb8b5b..d6b495432f0 100644 --- a/IDE/GCC-ARM/Header/user_settings.h +++ b/IDE/GCC-ARM/Header/user_settings.h @@ -521,7 +521,7 @@ extern unsigned int my_rng_seed_gen(void); #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/SimplicityStudio/user_settings.h b/IDE/SimplicityStudio/user_settings.h index ff6961bd779..d9f1031e382 100644 --- a/IDE/SimplicityStudio/user_settings.h +++ b/IDE/SimplicityStudio/user_settings.h @@ -438,7 +438,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/WICED-STUDIO/user_settings.h b/IDE/WICED-STUDIO/user_settings.h index 0ba1d034e0b..2eec72ac034 100644 --- a/IDE/WICED-STUDIO/user_settings.h +++ b/IDE/WICED-STUDIO/user_settings.h @@ -515,7 +515,7 @@ extern unsigned int my_rng_seed_gen(void); #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/WINCE/user_settings.h b/IDE/WINCE/user_settings.h index bba21fcb043..8c1fa7329c3 100644 --- a/IDE/WINCE/user_settings.h +++ b/IDE/WINCE/user_settings.h @@ -646,7 +646,7 @@ C149F3285397DFBD0C6720E14818475C3A50B10880EF9619463173A6D5ED15E7 #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/XCODE-FIPSv2/macOS-C++/Intel/user_settings.h b/IDE/XCODE-FIPSv2/macOS-C++/Intel/user_settings.h index 82efed9db7f..7c95a574a16 100644 --- a/IDE/XCODE-FIPSv2/macOS-C++/Intel/user_settings.h +++ b/IDE/XCODE-FIPSv2/macOS-C++/Intel/user_settings.h @@ -512,7 +512,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/XCODE-FIPSv2/macOS-C++/M1/user_settings.h b/IDE/XCODE-FIPSv2/macOS-C++/M1/user_settings.h index 756eb5389b4..7669708c6ce 100644 --- a/IDE/XCODE-FIPSv2/macOS-C++/M1/user_settings.h +++ b/IDE/XCODE-FIPSv2/macOS-C++/M1/user_settings.h @@ -523,7 +523,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/XCODE-FIPSv2/user_settings.h b/IDE/XCODE-FIPSv2/user_settings.h index f67eb48b966..2e83871dbdc 100644 --- a/IDE/XCODE-FIPSv2/user_settings.h +++ b/IDE/XCODE-FIPSv2/user_settings.h @@ -524,7 +524,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/XCODE-FIPSv5/user_settings.h b/IDE/XCODE-FIPSv5/user_settings.h index 19edc9526dc..f475a3189b7 100644 --- a/IDE/XCODE-FIPSv5/user_settings.h +++ b/IDE/XCODE-FIPSv5/user_settings.h @@ -605,7 +605,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/IDE/XCODE-FIPSv6/user_settings.h b/IDE/XCODE-FIPSv6/user_settings.h index 208f34e07c1..16166f1f282 100644 --- a/IDE/XCODE-FIPSv6/user_settings.h +++ b/IDE/XCODE-FIPSv6/user_settings.h @@ -665,7 +665,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/configure.ac b/configure.ac index 802abaca521..e81eb771f96 100644 --- a/configure.ac +++ b/configure.ac @@ -9857,6 +9857,13 @@ AC_ARG_ENABLE([rpk], [ ENABLED_RPK=no ] ) +# Allows dynamically loading the certificate +AC_ARG_ENABLE([cert-setup-cb], + [AS_HELP_STRING([--enable-cert-setup-cb],[Enable support for dynamically loading TLS certificates (default: disabled)])], + [ ENABLED_CERT_SETUP_CB=$enableval ], + [ ENABLED_CERT_SETUP_CB=no ] + ) + # check if should run the trusted peer certs test # (for now checking both C_FLAGS and C_EXTRA_FLAGS) AS_CASE(["$CFLAGS $CPPFLAGS"],[*'WOLFSSL_TRUST_PEER_CERT'*],[ENABLED_TRUSTED_PEER_CERT=yes]) @@ -10278,6 +10285,9 @@ AS_IF([test "x$ENABLED_DUAL_ALG_CERTS" = "xyes"], AS_IF([test "x$ENABLED_RPK" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DHAVE_RPK"]) +AS_IF([test "x$ENABLED_CERT_SETUP_CB" = "xyes"], + [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_SETUP_CB"]) + AS_IF([test "x$ENABLED_ALTNAMES" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALT_NAMES"]) diff --git a/doc/dox_comments/header_files/ocsp.h b/doc/dox_comments/header_files/ocsp.h new file mode 100644 index 00000000000..cd7966b84d3 --- /dev/null +++ b/doc/dox_comments/header_files/ocsp.h @@ -0,0 +1,49 @@ +/*! + \ingroup OCSP + + \brief Allocates and initialises an OCSP context. + + This function allocates and initialises a WOLFSSL_OCSP structure for use + with OCSP operations. + + \param cm Pointer to the certificate manager. + + \return Pointer to allocated WOLFSSL_OCSP on success + \return NULL on failure + + \sa wc_FreeOCSP +*/ +WOLFSSL_OCSP* wc_NewOCSP(WOLFSSL_CERT_MANAGER* cm); + +/*! + \ingroup OCSP + + \brief Frees resources associated with an OCSP context. + + This function releases any resources associated with a WOLFSSL_OCSP structure. + + \param ocsp Pointer to the WOLFSSL_OCSP structure to free. + + \return void + + \sa wc_NewOCSP +*/ +void wc_FreeOCSP(WOLFSSL_OCSP* ocsp); + +/*! + \ingroup OCSP + + \brief Checks the OCSP response for a given certificate. + + This function verifies an OCSP response for a specific certificate. + + \param ocsp Pointer to the WOLFSSL_OCSP structure. + \param cert Pointer to the decoded certificate. + \param response Pointer to the OCSP response buffer. + \param responseSz Size of the OCSP response buffer. + \param heap Optional heap pointer. + + \return 0 on success + \return <0 on failure +*/ +int wc_CheckCertOcspResponse(WOLFSSL_OCSP *ocsp, DecodedCert *cert, byte *response, int responseSz, void* heap); diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index e6901921d05..ee851963f47 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -5410,6 +5410,236 @@ int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v); */ long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg); +/*! + \ingroup CertsKeys + + \brief Sets a callback to select the client certificate and private key. + + This function allows the application to register a callback that will be invoked + when a client certificate is requested during the handshake. The callback can + select and provide the certificate and key to use. + + \param ctx The WOLFSSL_CTX object. + \param cb The callback function to select the client certificate and key. + + \return void + + _Example_ + \code + int my_client_cert_cb(WOLFSSL *ssl, WOLFSSL_X509 **x509, WOLFSSL_EVP_PKEY **pkey) { ... } + wolfSSL_CTX_set_client_cert_cb(ctx, my_client_cert_cb); + \endcode + + \sa wolfSSL_CTX_set_cert_cb +*/ +void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb); + +/*! + \ingroup CertsKeys + + \brief Sets a generic certificate setup callback. + + This function allows the application to register a callback that will be invoked + during certificate setup. The callback can perform custom certificate selection + or loading logic. + + \param ctx The WOLFSSL_CTX object. + \param cb The callback function for certificate setup. + \param arg User argument to pass to the callback. + + \return void + + _Example_ + \code + int my_cert_setup_cb(WOLFSSL* ssl, void* arg) { ... } + wolfSSL_CTX_set_cert_cb(ctx, my_cert_setup_cb, NULL); + \endcode + + \sa wolfSSL_CTX_set_client_cert_cb +*/ +void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, CertSetupCallback cb, void *arg); + +/*! + \ingroup OCSP + + \brief Sets the callback to be used for handling OCSP status requests (OCSP stapling). + + This function allows the application to register a callback that will be invoked + when an OCSP status request is received during the TLS handshake. The callback + can provide an OCSP response to be stapled to the handshake. This API is only + useful on the server side. + + \param ctx The WOLFSSL_CTX object. + \param cb The callback function to handle OCSP status requests. + + \return SSL_SUCCESS on success, SSL_FAILURE otherwise. + + _Example_ + \code + int my_ocsp_status_cb(WOLFSSL* ssl, void* arg) { ... } + wolfSSL_CTX_set_tlsext_status_cb(ctx, my_ocsp_status_cb); + \endcode + + \sa wolfSSL_CTX_get_tlsext_status_cb + \sa wolfSSL_CTX_set_tlsext_status_arg +*/ +int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb); + +/*! + \ingroup OCSP + + \brief Gets the currently set OCSP status callback for the context. + + \param ctx The WOLFSSL_CTX object. + \param cb Pointer to receive the callback function. + + \return SSL_SUCCESS on success, SSL_FAILURE otherwise. + + \sa wolfSSL_CTX_set_tlsext_status_cb +*/ +int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb); + +/*! + \ingroup OCSP + + \brief Sets the argument to be passed to the OCSP status callback. + + \param ctx The WOLFSSL_CTX object. + \param arg The user argument to pass to the callback. + + \return SSL_SUCCESS on success, SSL_FAILURE otherwise. + + \sa wolfSSL_CTX_set_tlsext_status_cb +*/ +long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg); + +/*! + \ingroup OCSP + + \brief Gets the OCSP response that will be sent (stapled) to the peer. + + \param ssl The WOLFSSL session. + \param resp Pointer to receive the response buffer. + + \return Length of the response, or negative value on error. + + \sa wolfSSL_set_tlsext_status_ocsp_resp +*/ +long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char **resp); + +/*! + \ingroup OCSP + + \brief Sets the OCSP response to be sent (stapled) to the peer. + + The buffer in resp becomes owned by wolfSSL and will be freed by + wolfSSL. The application must not free the buffer after calling this + function. + + \param ssl The WOLFSSL session. + \param resp Pointer to the response buffer. + \param len Length of the response buffer. + + \return SSL_SUCCESS on success, SSL_FAILURE otherwise. + + \sa wolfSSL_get_tlsext_status_ocsp_resp +*/ +long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char *resp, int len); + +/*! + \ingroup OCSP + + \brief Sets multiple OCSP responses for TLS multi-certificate chains. + + The buffer in resp becomes owned by wolfSSL and will be freed by + wolfSSL. The application must not free the buffer after calling this + function. + + \param ssl The WOLFSSL session. + \param resp Pointer to the response buffer. + \param len Length of the response buffer. + \param idx Index of the certificate chain. + + \return SSL_SUCCESS on success, SSL_FAILURE otherwise. +*/ +int wolfSSL_set_tlsext_status_ocsp_resp_multi(WOLFSSL* ssl, unsigned char *resp, int len, word32 idx); + +/*! + \ingroup OCSP + + \brief Sets a callback to verify the OCSP status response. + + It is recommended to enable SESSION_CERTS in order to have access to the + peer's certificate chain during OCSP verification. + + \param ctx The WOLFSSL_CTX object. + \param cb The callback function. + \param cbArg User argument to pass to the callback. + + \return void + + _Example_ + \code + void my_ocsp_verify_cb(WOLFSSL* ssl, int err, byte* resp, word32 respSz, word32 idx, void* arg) + { + (void)arg; + if (err == 0 && staple && stapleSz > 0) { + printf("Client: OCSP staple received, size=%u\n", stapleSz); + return 0; + } + // Manual OCSP staple verification if err != 0 + if (err != 0 && staple && stapleSz > 0) { + WOLFSSL_CERT_MANAGER* cm = NULL; + DecodedCert cert; + byte certInit = 0; + WOLFSSL_OCSP* ocsp = NULL; + WOLFSSL_X509_CHAIN* peerCerts; + int i; + + cm = wolfSSL_CertManagerNew(); + if (cm == NULL) + goto cleanup; + if (wolfSSL_CertManagerLoadCA(cm, CA_CERT, NULL) != WOLFSSL_SUCCESS) + goto cleanup; + + peerCerts = wolfSSL_get_peer_chain(ssl); + if (peerCerts == NULL || wolfSSL_get_chain_count(peerCerts) <= (int)idx) + goto cleanup; + + for (i = idx + 1; i < wolfSSL_get_chain_count(peerCerts); i++) { + if (wolfSSL_CertManagerLoadCABuffer(cm, wolfSSL_get_chain_cert(peerCerts, i), + wolfSSL_get_chain_length(peerCerts, i), WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) + goto cleanup; + } + + wc_InitDecodedCert(&cert, wolfSSL_get_chain_cert(peerCerts, idx), wolfSSL_get_chain_length(peerCerts, idx), NULL); + certInit = 1; + if (wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm) != 0) + goto cleanup; + if ((ocsp = wc_NewOCSP(cm)) == NULL) + goto cleanup; + if (wc_CheckCertOcspResponse(ocsp, &cert, staple, stapleSz, NULL) != 0) + goto cleanup; + + printf("Client: Manual OCSP staple verification succeeded for idx=%u\n", idx); + err = 0; + cleanup: + wc_FreeOCSP(ocsp); + if (certInit) + wc_FreeDecodedCert(&cert); + wolfSSL_CertManagerFree(cm); + if (err == 0) + return 0; + printf("Client: Manual OCSP staple verification failed for idx=%u\n", idx); + } + printf("Client: OCSP staple verify error=%d\n", err); + return err; + } + wolfSSL_CTX_set_ocsp_status_verify_cb(ctx, my_ocsp_verify_cb, NULL); + \endcode +*/ +void wolfSSL_CTX_set_ocsp_status_verify_cb(WOLFSSL_CTX* ctx, ocspVerifyStatusCb cb, void* cbArg); + /*! \ingroup Setup diff --git a/examples/configs/user_settings_template.h b/examples/configs/user_settings_template.h index 6a0af9b1d4b..c88cbc8203b 100644 --- a/examples/configs/user_settings_template.h +++ b/examples/configs/user_settings_template.h @@ -455,7 +455,7 @@ extern "C" { #define USE_WOLF_STRTOK #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) diff --git a/src/internal.c b/src/internal.c index 1834fdee45a..153a746fbcb 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6734,13 +6734,21 @@ int InitSSL_Suites(WOLFSSL* ssl) !havePSK && !haveAnon && !haveMcast && !haveCertSetupCb) { /* server certificate must be loaded */ - if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer) { + if ((!ssl->buffers.certificate || !ssl->buffers.certificate->buffer) +#ifdef WOLFSSL_CERT_SETUP_CB + && ssl->ctx->certSetupCb == NULL +#endif + ) { WOLFSSL_MSG("Server missing certificate"); WOLFSSL_ERROR_VERBOSE(NO_PRIVATE_KEY); return NO_PRIVATE_KEY; } - if (!ssl->buffers.key || !ssl->buffers.key->buffer) { + if ((!ssl->buffers.key || !ssl->buffers.key->buffer) +#ifdef WOLFSSL_CERT_SETUP_CB + && ssl->ctx->certSetupCb == NULL +#endif + ) { /* allow no private key if using existing key */ #ifdef WOLF_PRIVATE_KEY_ID if (ssl->devId != INVALID_DEVID @@ -7050,9 +7058,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->buffers.certificate = ctx->certificate; ssl->buffers.certChain = ctx->certChain; #endif -#ifdef WOLFSSL_TLS13 ssl->buffers.certChainCnt = ctx->certChainCnt; -#endif #ifndef WOLFSSL_BLIND_PRIVATE_KEY #ifdef WOLFSSL_COPY_KEY if (ctx->privateKey != NULL) { @@ -8716,11 +8722,12 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA XFREE(ssl->param, ssl->heap, DYNAMIC_TYPE_OPENSSL); #endif -#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) - if (ssl->ocspResp) { - XFREE(ssl->ocspResp, NULL, 0); - ssl->ocspResp = NULL; - ssl->ocspRespSz = 0; +#if defined(HAVE_OCSP) + { + size_t i; + for (i = 0; i < XELEM_CNT(ssl->ocspCsrResp); i++) + XFREE(ssl->ocspCsrResp[i].buffer, NULL, 0); + XMEMSET(ssl->ocspCsrResp, 0, sizeof(ssl->ocspCsrResp)); } #endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) @@ -9055,11 +9062,12 @@ void FreeHandshakeResources(WOLFSSL* ssl) * !WOLFSSL_POST_HANDSHAKE_AUTH */ #endif /* HAVE_TLS_EXTENSIONS && !NO_TLS */ -#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) - if (ssl->ocspResp != NULL) { - XFREE(ssl->ocspResp, NULL, 0); - ssl->ocspResp = NULL; - ssl->ocspRespSz = 0; +#if defined(HAVE_OCSP) + { + size_t i; + for (i = 0; i < XELEM_CNT(ssl->ocspCsrResp); i++) + XFREE(ssl->ocspCsrResp[i].buffer, NULL, 0); + XMEMSET(ssl->ocspCsrResp, 0, sizeof(ssl->ocspCsrResp)); } #endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ @@ -13917,6 +13925,29 @@ int CopyDecodedAcertToX509(WOLFSSL_X509_ACERT* x509, DecodedAcert* dAcert) #if (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) && !defined(WOLFSSL_NO_TLS12) +static int CsrDoStatusVerifyCb(WOLFSSL* ssl, byte* input, word32 inputSz, word32 idx, + int ret) +{ + if (ssl->ctx->ocspStatusVerifyCb != NULL) { + int verRet; + WOLFSSL_MSG("Calling OCSP status verify callback"); + verRet = ssl->ctx->ocspStatusVerifyCb(ssl, ret, + input, inputSz, idx, ssl->ctx->ocspStatusVerifyCbArg); + if (verRet > 0) { + WOLFSSL_MSG("\tInvalid OCSP status verify callback return"); + ret = BAD_CERTIFICATE_STATUS_ERROR; + } + else { + if (ret == 0 && verRet < 0) + WOLFSSL_MSG("\tforcing error"); + else if (ret < 0 && verRet == 0) + WOLFSSL_MSG("\toverriding error"); + ret = verRet; + } + } + return ret; +} + static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 status_length, int idx) { @@ -13969,9 +14000,6 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx, return BUFFER_ERROR; } while(0); - if (request == NULL) - return BAD_CERTIFICATE_STATUS_ERROR; /* not expected */ - #ifdef WOLFSSL_SMALL_STACK status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap, DYNAMIC_TYPE_OCSP_STATUS); @@ -13996,22 +14024,34 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* InitOcspResponse sets single and status to response struct. */ - InitOcspResponse(response, single, status, input +*inOutIdx, status_length, ssl->heap); + InitOcspResponse(response, single, status, input +*inOutIdx, status_length, + ssl->heap); - if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0, 0) != 0) + /* Extract producedDate */ + if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 1, 1) != 0) ret = BAD_CERTIFICATE_STATUS_ERROR; - else if (CompareOcspReqResp(request, response) != 0) - ret = BAD_CERTIFICATE_STATUS_ERROR; - else if (response->responseStatus != OCSP_SUCCESSFUL) - ret = BAD_CERTIFICATE_STATUS_ERROR; - else if (response->single->status->status == CERT_REVOKED) - ret = OCSP_CERT_REVOKED; - else if (response->single->status->status != CERT_GOOD) - ret = BAD_CERTIFICATE_STATUS_ERROR; - - else { - XMEMCPY(ssl->ocspProducedDate, response->producedDate, sizeof ssl->ocspProducedDate); + if (ret == 0) { + XMEMCPY(ssl->ocspProducedDate, response->producedDate, + sizeof(ssl->ocspProducedDate)); ssl->ocspProducedDateFormat = response->producedDateFormat; + + /* Reset response */ + FreeOcspResponse(response); + InitOcspResponse(response, single, status, input + *inOutIdx, + status_length, ssl->heap); + + if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0, 0) != 0) + ret = BAD_CERTIFICATE_STATUS_ERROR; + else if (CompareOcspReqResp(request, response) != 0) + ret = BAD_CERTIFICATE_STATUS_ERROR; + else if (response->responseStatus != OCSP_SUCCESSFUL) + ret = BAD_CERTIFICATE_STATUS_ERROR; + else if (response->single->status->status == CERT_REVOKED) + ret = OCSP_CERT_REVOKED; + else if (response->single->status->status != CERT_GOOD) + ret = BAD_CERTIFICATE_STATUS_ERROR; + + ret = CsrDoStatusVerifyCb(ssl, input + *inOutIdx, status_length, idx, ret); } *inOutIdx += status_length; @@ -15663,14 +15703,23 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif } - if (ret == 0) { #ifdef HAVE_OCSP + if (ret == 0 || + /* Don't enter when args->dCert is potentially in + * a bad state. */ + (ret != WC_NO_ERR_TRACE(ASN_PARSE_E) && + ret != WC_NO_ERR_TRACE(BUFFER_E) && + ret != WC_NO_ERR_TRACE(MEMORY_E) && + ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))) { + /* If we are processing OCSP staples then always + * initialize the corresponding request. */ + int ocspRet = 0; #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 addToPendingCAs = 0; if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->status_request_v2 && TLSX_CSR2_IsMulti(ssl->extensions)) { - ret = TLSX_CSR2_InitRequests(ssl->extensions, + ocspRet = TLSX_CSR2_InitRequests(ssl->extensions, args->dCert, 0, ssl->heap); addToPendingCAs = 1; } @@ -15684,12 +15733,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, * Server. Server side will check client * certificates by traditional OCSP if enabled */ - ret = TLSX_CSR_InitRequest_ex(ssl->extensions, + ocspRet = TLSX_CSR_InitRequest_ex(ssl->extensions, args->dCert, ssl->heap, args->certIdx); } else #endif - if (SSL_CM(ssl)->ocspEnabled && + if (ret == 0 && SSL_CM(ssl)->ocspEnabled && SSL_CM(ssl)->ocspCheckAll) { WOLFSSL_MSG("Doing Non Leaf OCSP check"); ret = CheckCertOCSP_ex(SSL_CM(ssl)->ocsp, @@ -15705,8 +15754,15 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("\tOCSP Lookup not ok"); } } + if (ocspRet != 0) { + ret = ocspRet; + WOLFSSL_ERROR_VERBOSE(ret); + goto exit_ppc; + } + } #endif /* HAVE_OCSP */ + if (ret == 0) { #ifdef HAVE_CRL if (SSL_CM(ssl)->crlEnabled && SSL_CM(ssl)->crlCheckAll) { @@ -16015,6 +16071,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) goto exit_ppc; #endif + if (ret == 0) { WOLFSSL_MSG("Verified Peer's cert"); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) @@ -16106,19 +16163,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } #endif - if (ssl->verifyCallback) { - WOLFSSL_MSG( - "\tCallback override available, will continue"); - /* check if fatal error */ - args->fatal = (args->verifyErr) ? (word16)(1) - : (word16)(0); - if (args->fatal) - DoCertFatalAlert(ssl, ret); - } + /* Do verify callback. */ + args->leafVerifyErr = ret = + DoVerifyCallback(SSL_CM(ssl), ssl, ret, args); + #if defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) /* Disregard failure to verify peer cert, as we will verify * the whole chain with the native API later */ - else if (ssl->ctx->doAppleNativeCertValidationFlag) { + if (ssl->ctx->doAppleNativeCertValidationFlag) { WOLFSSL_MSG("\tApple native CA validation override" " available, will continue"); /* check if fatal error */ @@ -16126,9 +16178,10 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (args->fatal) DoCertFatalAlert(ssl, ret); } + else #endif/*defined(__APPLE__)&& defined(WOLFSSL_SYS_CA_CERTS)*/ - else { - WOLFSSL_MSG("\tNo callback override available, fatal"); + if (ret != 0) { + WOLFSSL_MSG("\tfatal cert error"); args->fatal = 1; DoCertFatalAlert(ssl, ret); } @@ -16910,8 +16963,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } #endif /* defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) */ - /* Do verify callback */ - ret = DoVerifyCallback(SSL_CM(ssl), ssl, ret, args); + /* Do leaf verify callback when it wasn't called yet */ + if (ret == 0 || ret != args->leafVerifyErr) + ret = DoVerifyCallback(SSL_CM(ssl), ssl, ret, args); if (ssl->options.verifyNone && (ret == WC_NO_ERR_TRACE(CRL_MISSING) || @@ -17141,15 +17195,16 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, else if (CompareOcspReqResp(request, response) != 0) { ret = BAD_CERTIFICATE_STATUS_ERROR; } - else { - if (idx == 0) /* server cert must be OK */ - endCertificateOK = 1; - } } /* only frees 'single' if single->isDynamic is set */ FreeOcspResponse(response); + ret = CsrDoStatusVerifyCb(ssl, input + *inOutIdx, status_length, + idx, ret); + if (ret == 0 && idx == 0) /* server cert must be OK */ + endCertificateOK = 1; + *inOutIdx += status_length; list_length -= status_length; } @@ -24348,10 +24403,9 @@ int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request, InitDecodedCert(cert, certData, length, ssl->heap); /* TODO: Setup async support here */ - ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, SSL_CM(ssl), NULL); - if (ret != 0) { + ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, SSL_CM(ssl), NULL); + if (ret != 0) WOLFSSL_MSG("ParseCert failed"); - } if (ret == 0) ret = InitOcspRequest(request, cert, 0, ssl->heap); if (ret == 0) { @@ -25104,51 +25158,55 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, } #endif -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ - (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_HAPROXY)) -static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl) +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) +static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl, byte status_type) { WOLFSSL_OCSP *ocsp; - void *ioCtx = NULL; - buffer response; - int ret; + int ret = 0; - if (ssl == NULL) { + if (ssl == NULL) return BAD_FUNC_ARG; - } + if (status_type != WOLFSSL_CSR2_OCSP && + status_type != WOLFSSL_CSR2_OCSP_MULTI) + return 0; ocsp = SSL_CM(ssl)->ocsp_stapling; if (ocsp == NULL || ocsp->statusCb == NULL) return BAD_FUNC_ARG; - ioCtx = (ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; - XMEMSET(&response, 0, sizeof(response)); WOLFSSL_MSG("Calling ocsp->statusCb"); - ret = ocsp->statusCb(ssl, ioCtx); + ret = ocsp->statusCb(ssl, ocsp->statusCbArg); switch (ret) { - case SSL_TLSEXT_ERR_OK: - if (ssl->ocspResp == NULL || ssl->ocspRespSz == 0) { - ret = 0; - break; + case WOLFSSL_OCSP_STATUS_CB_OK: { + byte cnt = 1; +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (status_type == WOLFSSL_CSR2_OCSP_MULTI) { + /* Find last response set */ + for (cnt = XELEM_CNT(ssl->ocspCsrResp); + cnt > 0 && ssl->ocspCsrResp[cnt-1].buffer == NULL; + cnt--); + cnt = MIN(cnt, ssl->buffers.certChainCnt + 1); } - response.buffer = ssl->ocspResp; - response.length = ssl->ocspRespSz; - ret = BuildCertificateStatus(ssl, WOLFSSL_CSR_OCSP, &response, 1); +#endif + ret = BuildCertificateStatus(ssl, status_type, ssl->ocspCsrResp, + cnt); break; - case SSL_TLSEXT_ERR_NOACK: + } + case WOLFSSL_OCSP_STATUS_CB_NOACK: /* No OCSP response to send */ ret = 0; break; - case SSL_TLSEXT_ERR_ALERT_FATAL: + case WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL: /* fall through */ default: ret = WOLFSSL_FATAL_ERROR; break; } + return ret; } -#endif /* HAVE_CERTIFICATE_STATUS_REQUEST && (defined(OPENSSL_ALL) || - defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST || + * HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ #endif /* NO_WOLFSSL_SERVER */ @@ -25174,13 +25232,11 @@ int SendCertificateStatus(WOLFSSL* ssl) status_type = status_type ? status_type : ssl->status_request_v2; #endif -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ - (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_HAPROXY)) +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) if (SSL_CM(ssl)->ocsp_stapling != NULL && SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { - if (ssl->status_request == WOLFSSL_CSR_OCSP) - return BuildCertificateStatusWithStatusCB(ssl); + return BuildCertificateStatusWithStatusCB(ssl, status_type); } #endif @@ -25270,14 +25326,14 @@ int SendCertificateStatus(WOLFSSL* ssl) return MEMORY_E; } - /* use certChain if available, otherwise use peer certificate */ + /* use certChain if available, otherwise use certificate */ chain = ssl->buffers.certChain; if (chain == NULL) { chain = ssl->buffers.certificate; } if (chain && chain->buffer) { - while (idx + OPAQUE24_LEN < chain->length) { + while (ret == 0 && idx + OPAQUE24_LEN < chain->length) { c24to32(chain->buffer + idx, &der.length); idx += OPAQUE24_LEN; @@ -25290,7 +25346,7 @@ int SendCertificateStatus(WOLFSSL* ssl) der.length, &ctxOwnsRequest); if (ret == 0) { request->ssl = ssl; - ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling, + ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling, request, &responses[i + 1], ssl->heap); /* Suppressing, not critical */ @@ -31693,7 +31749,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, word16 len; word32 begin = *inOutIdx; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ - defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) + defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ + defined(WOLFSSL_CERT_SETUP_CB) int ret; #endif #ifdef OPENSSL_EXTRA @@ -31839,6 +31896,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, len -= (word16)(OPAQUE16_LEN) + dnSz; } + #ifdef WOLFSSL_CERT_SETUP_CB #ifdef OPENSSL_EXTRA /* call client cert callback if no cert has been loaded */ if ((ssl->ctx->CBClientCert != NULL) && @@ -31860,6 +31918,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, return WOLFSSL_ERROR_WANT_X509_LOOKUP; } } + #endif if ((ret = CertSetupCbWrapper(ssl)) != 0) return ret; #endif @@ -35332,6 +35391,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return handshake_failure; case WC_NO_ERR_TRACE(VERSION_ERROR): return wolfssl_alert_protocol_version; + case WC_NO_ERR_TRACE(BAD_CERTIFICATE_STATUS_ERROR): + return bad_certificate_status_response; default: return invalid_alert; } @@ -38536,7 +38597,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #endif -#ifdef OPENSSL_EXTRA +#ifdef WOLFSSL_CERT_SETUP_CB /* Give user last chance to provide a cert for cipher selection */ if (ret == 0 && ssl->ctx->certSetupCb != NULL) ret = CertSetupCbWrapper(ssl); diff --git a/src/ocsp.c b/src/ocsp.c index f12166209dd..ed255aa9148 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -44,6 +44,63 @@ #include #endif +/* Allocates and initializes a WOLFSSL_OCSP object. Returns pointer on success, NULL on failure. */ +WOLFSSL_OCSP* wc_NewOCSP(WOLFSSL_CERT_MANAGER* cm) +{ + WOLFSSL_OCSP* ocsp = NULL; + ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm ? cm->heap : NULL, DYNAMIC_TYPE_OCSP); + if (ocsp == NULL) + return NULL; + if (InitOCSP(ocsp, cm) != 0) { + XFREE(ocsp, cm ? cm->heap : NULL, DYNAMIC_TYPE_OCSP); + return NULL; + } + return ocsp; +} + +/* Frees a WOLFSSL_OCSP object allocated by wc_NewOCSP. */ +void wc_FreeOCSP(WOLFSSL_OCSP* ocsp) +{ + if (ocsp) { + FreeOCSP(ocsp, 1); + } +} + +int wc_CheckCertOcspResponse(WOLFSSL_OCSP *ocsp, DecodedCert *cert, + byte *response, int responseSz, void* heap) +{ + int ret = WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E); + +#ifdef WOLFSSL_SMALL_STACK + OcspRequest* ocspRequest; +#else + OcspRequest ocspRequest[1]; +#endif + + +#ifdef WOLFSSL_SMALL_STACK + ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (ocspRequest == NULL) { + WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); + return MEMORY_E; + } +#endif + + if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce, + ocsp->cm->heap) == 0) { + ret = CheckOcspResponse(ocsp, response, responseSz, NULL, NULL, NULL, + ocspRequest, heap); + FreeOcspRequest(ocspRequest); + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + WOLFSSL_LEAVE("CheckCertOCSP", ret); + return ret; +} int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm) { @@ -375,7 +432,7 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz, ocspResponse->single->status->next = status->next; XMEMCPY(status, ocspResponse->single->status, sizeof(CertStatus)); } - else { + else if (entry != NULL) { /* Save new certificate entry */ status = (CertStatus*)XMALLOC(sizeof(CertStatus), ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS); diff --git a/src/ssl.c b/src/ssl.c index 78cb42a179f..af639cc9150 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10839,7 +10839,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #ifndef NO_CERTS /* in case used set_accept_state after init */ if (!havePSK && !haveAnon && !haveMcast) { - #ifdef OPENSSL_EXTRA + #ifdef WOLFSSL_CERT_SETUP_CB if (ssl->ctx->certSetupCb != NULL) { WOLFSSL_MSG("CertSetupCb set. server cert and " "key not checked"); @@ -12274,7 +12274,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } #endif /* WOLFSSL_NO_CA_NAMES */ -#ifdef OPENSSL_EXTRA +#ifdef WOLFSSL_CERT_SETUP_CB +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) /* registers client cert callback, called during handshake if server requests client auth but user has not loaded client cert/key */ void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb) @@ -12285,6 +12286,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ctx->CBClientCert = cb; } } +#endif void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, CertSetupCallback cb, void *arg) @@ -12487,7 +12489,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } return ret; } -#endif /* OPENSSL_EXTRA */ +#endif /* WOLFSSL_CERT_SETUP_CB */ #ifndef WOLFSSL_NO_CA_NAMES WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list( @@ -17886,30 +17888,6 @@ void wolfSSL_ERR_load_SSL_strings(void) } #endif -#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) -long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp) -{ - if (s == NULL || resp == NULL) - return 0; - - *resp = s->ocspResp; - return s->ocspRespSz; -} - -long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, - int len) -{ - if (s == NULL) - return WOLFSSL_FAILURE; - - XFREE(s->ocspResp, NULL, 0); - s->ocspResp = resp; - s->ocspRespSz = len; - - return WOLFSSL_SUCCESS; -} -#endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ - #ifdef HAVE_MAX_FRAGMENT #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS) /** @@ -18118,20 +18096,6 @@ long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx) } #endif -#ifndef NO_CERTS - -long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg) -{ - if (ctx == NULL || ctx->cm == NULL) { - return WOLFSSL_FAILURE; - } - - ctx->cm->ocspIOCtx = arg; - return WOLFSSL_SUCCESS; -} - -#endif /* !NO_CERTS */ - int wolfSSL_get_read_ahead(const WOLFSSL* ssl) { if (ssl == NULL) { @@ -23022,8 +22986,8 @@ long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx, /* Not an OpenSSL API. */ int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response) { - *response = ssl->ocspResp; - return ssl->ocspRespSz; + *response = ssl->ocspCsrResp[0].buffer; + return ssl->ocspCsrResp[0].length; } /* Not an OpenSSL API. */ @@ -23086,6 +23050,109 @@ int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) { } #endif +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) +int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb) +{ + if (ctx == NULL || ctx->cm == NULL || cb == NULL) + return WOLFSSL_FAILURE; + +#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + if (ctx->cm->ocsp_stapling == NULL) + return WOLFSSL_FAILURE; + + *cb = ctx->cm->ocsp_stapling->statusCb; +#else + (void)cb; + *cb = NULL; +#endif + + return WOLFSSL_SUCCESS; + +} + +int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb) +{ + if (ctx == NULL || ctx->cm == NULL) + return WOLFSSL_FAILURE; + +#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + /* Ensure stapling is on for callback to be used. */ + wolfSSL_CTX_EnableOCSPStapling(ctx); + + if (ctx->cm->ocsp_stapling == NULL) + return WOLFSSL_FAILURE; + + ctx->cm->ocsp_stapling->statusCb = cb; +#else + (void)cb; +#endif + + return WOLFSSL_SUCCESS; +} + +long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg) +{ + if (ctx == NULL || ctx->cm == NULL) + return WOLFSSL_FAILURE; + +#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + /* Ensure stapling is on for callback to be used. */ + wolfSSL_CTX_EnableOCSPStapling(ctx); + + if (ctx->cm->ocsp_stapling == NULL) + return WOLFSSL_FAILURE; + + ctx->cm->ocsp_stapling->statusCbArg = arg; +#else + (void)arg; +#endif + + return WOLFSSL_SUCCESS; +} + +long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char **resp) +{ + if (ssl == NULL || resp == NULL) + return 0; + + *resp = ssl->ocspCsrResp[0].buffer; + return (long)ssl->ocspCsrResp[0].length; +} + +long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char *resp, + int len) +{ + return wolfSSL_set_tlsext_status_ocsp_resp_multi(ssl, resp, len, 0); +} + +int wolfSSL_set_tlsext_status_ocsp_resp_multi(WOLFSSL* ssl, unsigned char *resp, + int len, word32 idx) +{ + if (ssl == NULL || idx >= XELEM_CNT(ssl->ocspCsrResp) || len < 0) + return WOLFSSL_FAILURE; + if (!((resp == NULL) ^ (len > 0))) + return WOLFSSL_FAILURE; + + XFREE(ssl->ocspCsrResp[idx].buffer, NULL, 0); + ssl->ocspCsrResp[idx].buffer = resp; + ssl->ocspCsrResp[idx].length = (word32)len; + + return WOLFSSL_SUCCESS; +} + +void wolfSSL_CTX_set_ocsp_status_verify_cb(WOLFSSL_CTX* ctx, + ocspVerifyStatusCb cb, void* cbArg) +{ + if (ctx != NULL) { + ctx->ocspStatusVerifyCb = cb; + ctx->ocspStatusVerifyCbArg = cbArg; + } +} +#endif #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) @@ -23152,47 +23219,6 @@ int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, return WOLFSSL_SUCCESS; } -int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb) -{ - if (ctx == NULL || ctx->cm == NULL || cb == NULL) - return WOLFSSL_FAILURE; - -#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ - || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) - if (ctx->cm->ocsp_stapling == NULL) - return WOLFSSL_FAILURE; - - *cb = ctx->cm->ocsp_stapling->statusCb; -#else - (void)cb; - *cb = NULL; -#endif - - return WOLFSSL_SUCCESS; - -} - -int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb) -{ - if (ctx == NULL || ctx->cm == NULL) - return WOLFSSL_FAILURE; - -#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ - || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) - /* Ensure stapling is on for callback to be used. */ - wolfSSL_CTX_EnableOCSPStapling(ctx); - - if (ctx->cm->ocsp_stapling == NULL) - return WOLFSSL_FAILURE; - - ctx->cm->ocsp_stapling->statusCb = cb; -#else - (void)cb; -#endif - - return WOLFSSL_SUCCESS; -} - int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx, WOLF_STACK_OF(WOLFSSL_X509) **sk) { diff --git a/src/ssl_load.c b/src/ssl_load.c index fac44a2e249..3ca77d7a748 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -249,10 +249,8 @@ static int ProcessUserChainRetain(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ret = AllocCopyDer(&ssl->buffers.certChain, chainBuffer, len, type, heap); ssl->buffers.weOwnCertChain = (ret == 0); - #ifdef WOLFSSL_TLS13 /* Update count of certificates in chain. */ ssl->buffers.certChainCnt = cnt; - #endif } /* Store in SSL context object if available. */ else if (ctx != NULL) { @@ -260,10 +258,8 @@ static int ProcessUserChainRetain(WOLFSSL_CTX* ctx, WOLFSSL* ssl, FreeDer(&ctx->certChain); /* Allocate and copy the buffer into SSL context object. */ ret = AllocCopyDer(&ctx->certChain, chainBuffer, len, type, heap); - #ifdef WOLFSSL_TLS13 /* Update count of certificates in chain. */ ctx->certChainCnt = cnt; - #endif } return ret; diff --git a/src/tls.c b/src/tls.c index 18bdffb72b8..5759e344d90 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3244,14 +3244,11 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest, #endif #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) { -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL && SSL_CM(csr->ssl)->ocsp_stapling != NULL && - SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL && - idx == 0) { - return OPAQUE8_LEN + OPAQUE24_LEN + csr->ssl->ocspRespSz; + SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL) { + return OPAQUE8_LEN + OPAQUE24_LEN + csr->ssl->ocspCsrResp[idx].length; } -#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ return (word16)(OPAQUE8_LEN + OPAQUE24_LEN + csr->responses[idx].length); } @@ -3261,11 +3258,9 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest, return size; } -#if (defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)) && \ -(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) -static int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl) +#if (defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)) +int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl) { - void *ioCtx = NULL; WOLFSSL_OCSP *ocsp; int ret; @@ -3274,23 +3269,27 @@ static int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl) ocsp = SSL_CM(ssl)->ocsp_stapling; if (ocsp == NULL || ocsp->statusCb == NULL) return BAD_FUNC_ARG; - ioCtx = (ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; - ret = ocsp->statusCb(ssl, ioCtx); + ret = ocsp->statusCb(ssl, ocsp->statusCbArg); switch (ret) { - case SSL_TLSEXT_ERR_OK: - if (ssl->ocspRespSz > 0) { - /* ack the extension, status cb provided the response in - * ssl->ocspResp */ - TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); - ssl->status_request = WOLFSSL_CSR_OCSP; + case WOLFSSL_OCSP_STATUS_CB_OK: { + size_t i; + for (i = 0; i < XELEM_CNT(ssl->ocspCsrResp); i++) { + if (ssl->ocspCsrResp[i].length > 0) { + /* ack the extension, status cb provided the response in + * ssl->ocspCsrResp */ + TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); + ssl->status_request = WOLFSSL_CSR_OCSP; + break; + } } ret = 0; break; - case SSL_TLSEXT_ERR_NOACK: + } + case WOLFSSL_OCSP_STATUS_CB_NOACK: /* suppressing as not critical */ ret = 0; break; - case SSL_TLSEXT_ERR_ALERT_FATAL: + case WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL: default: ret = WOLFSSL_FATAL_ERROR; break; @@ -3299,7 +3298,7 @@ static int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl) } static int TLSX_CSR_WriteWithStatusCB(CertificateStatusRequest* csr, - byte* output) + byte* output, int idx) { WOLFSSL *ssl = csr->ssl; WOLFSSL_OCSP *ocsp; @@ -3312,8 +3311,8 @@ static int TLSX_CSR_WriteWithStatusCB(CertificateStatusRequest* csr, ocsp = SSL_CM(ssl)->ocsp_stapling; if (ocsp == NULL || ocsp->statusCb == NULL) return BAD_FUNC_ARG; - response = ssl->ocspResp; - respSz = ssl->ocspRespSz; + response = ssl->ocspCsrResp[idx].buffer; + respSz = ssl->ocspCsrResp[idx].length; if (response == NULL || respSz == 0) return BAD_FUNC_ARG; output[offset++] = WOLFSSL_CSR_OCSP; @@ -3322,8 +3321,7 @@ static int TLSX_CSR_WriteWithStatusCB(CertificateStatusRequest* csr, XMEMCPY(output + offset, response, respSz); return offset + respSz; } -#endif /* (TLS13 && !NO_WOLFSLL_SERVER) && (OPENSSL_ALL || WOLFSSL_NGINX || -WOLFSSL_HAPROXY) */ +#endif /* (TLS13 && !NO_WOLFSLL_SERVER) */ static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) { @@ -3377,14 +3375,11 @@ int TLSX_CSR_Write_ex(CertificateStatusRequest* csr, byte* output, #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) { word16 offset = 0; -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL && SSL_CM(csr->ssl)->ocsp_stapling != NULL && - SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL && - idx == 0) { - return TLSX_CSR_WriteWithStatusCB(csr, output); + SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL) { + return TLSX_CSR_WriteWithStatusCB(csr, output, idx); } -#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ output[offset++] = csr->status_type; c32to24(csr->responses[idx].length, output + offset); offset += OPAQUE24_LEN; @@ -3413,7 +3408,7 @@ static int TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output, * ssl SSL/TLS object. * returns 0 on success, otherwise failure. */ -static int ProcessChainOCSPRequest(WOLFSSL* ssl) +int ProcessChainOCSPRequest(WOLFSSL* ssl) { DecodedCert* cert; OcspRequest* request; @@ -3496,9 +3491,6 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, #if !defined(NO_WOLFSSL_SERVER) byte status_type; word16 size = 0; -#if defined(WOLFSSL_TLS13) - DecodedCert* cert; -#endif #endif #if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER) \ @@ -3658,76 +3650,7 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (ret != WOLFSSL_SUCCESS) return ret == 0 ? -1 : ret; /* throw error */ - #if defined(WOLFSSL_TLS13) - if (ssl->options.tls1_3) { -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) - if (ssl != NULL && SSL_CM(ssl) != NULL && - SSL_CM(ssl)->ocsp_stapling != NULL && - SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { - return TLSX_CSR_SetResponseWithStatusCB(ssl); -} -#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ - if (ssl->buffers.certificate == NULL) { - WOLFSSL_MSG("Certificate buffer not set!"); - return BUFFER_ERROR; - } - cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap, - DYNAMIC_TYPE_DCERT); - if (cert == NULL) { - return MEMORY_E; - } - InitDecodedCert(cert, ssl->buffers.certificate->buffer, - ssl->buffers.certificate->length, ssl->heap); - ret = ParseCert(cert, CERT_TYPE, 1, SSL_CM(ssl)); - if (ret != 0) { - FreeDecodedCert(cert); - XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); - /* Let's not error out the connection if we can't verify our - * cert */ - if (ret == WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E) || - ret == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E)) - ret = 0; - return ret; - } - ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap); - if (ret != 0 ) { - FreeDecodedCert(cert); - XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); - return ret; - } - FreeDecodedCert(cert); - XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); - extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); - csr = extension ? - (CertificateStatusRequest*)extension->data : NULL; - if (csr == NULL) - return MEMORY_ERROR; - - request = &csr->request.ocsp[0]; - ret = CreateOcspResponse(ssl, &request, &csr->responses[0]); - if (request != &csr->request.ocsp[0] && - ssl->buffers.weOwnCert) { - /* request will be allocated in CreateOcspResponse() */ - FreeOcspRequest(request); - XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); - } - if (ret != 0) - return ret; - - if (csr->responses[0].buffer) - TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); - #if defined(WOLFSSL_TLS_OCSP_MULTI) - /* process OCSP request in certificate chain */ - if ((ret = ProcessChainOCSPRequest(ssl)) != 0) { - WOLFSSL_MSG("Process Cert Chain OCSP request failed"); - WOLFSSL_ERROR_VERBOSE(ret); - return ret; - } - #endif - } - else - #endif - TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); + TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); ssl->status_request = status_type; #endif } @@ -4163,14 +4086,6 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length, continue; } -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) - /* OpenSSL status CB supports only CERTIFICATE STATUS REQ V1 */ - if (ssl != NULL && SSL_CM(ssl) != NULL && - SSL_CM(ssl)->ocsp_stapling != NULL && - SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { - return 0; - } -#endif /* if using status_request and already sending it, remove it * and prefer to use the v2 version */ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST diff --git a/src/tls13.c b/src/tls13.c index 76a6b397763..c97ebffdef4 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5780,6 +5780,11 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, if (ssl->toInfoOn) AddLateName("CertificateRequest", &ssl->timeoutInfo); #endif +#ifdef WOLFSSL_CERT_SETUP_CB + if ((ret = CertSetupCbWrapper(ssl)) != 0) + return ret; +#endif + if (OPAQUE8_LEN > size) return BUFFER_ERROR; @@ -7186,7 +7191,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case TLS_ASYNC_DO: { -#ifdef OPENSSL_EXTRA +#ifdef WOLFSSL_CERT_SETUP_CB if ((ret = CertSetupCbWrapper(ssl)) != 0) goto exit_dch; #endif @@ -8692,6 +8697,77 @@ static word32 AddCertExt(WOLFSSL* ssl, byte* cert, word32 len, word16 extSz, return i; } +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && !defined(NO_WOLFSSL_SERVER) +static int SetupOcspResp(WOLFSSL* ssl) +{ + DecodedCert* cert = NULL; + CertificateStatusRequest* csr = NULL; + TLSX* extension = NULL; + int ret = 0; + OcspRequest* request = NULL; + + extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); + if (extension == NULL) + return 0; /* peer didn't signal ocsp support */ + csr = extension ? + (CertificateStatusRequest*)extension->data : NULL; + if (csr == NULL) + return MEMORY_ERROR; + + if (SSL_CM(ssl) != NULL && + SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + return TLSX_CSR_SetResponseWithStatusCB(ssl); + } + + if (ssl->buffers.certificate == NULL) { + WOLFSSL_MSG("Certificate buffer not set!"); + return BUFFER_ERROR; + } + cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap, + DYNAMIC_TYPE_DCERT); + if (cert == NULL) { + return MEMORY_E; + } + InitDecodedCert(cert, ssl->buffers.certificate->buffer, + ssl->buffers.certificate->length, ssl->heap); + ret = ParseCert(cert, CERT_TYPE, NO_VERIFY, SSL_CM(ssl)); + if (ret != 0) { + FreeDecodedCert(cert); + XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); + return ret; + } + ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap); + FreeDecodedCert(cert); + XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); + if (ret != 0 ) + return ret; + + request = &csr->request.ocsp[0]; + ret = CreateOcspResponse(ssl, &request, &csr->responses[0]); + if (request != &csr->request.ocsp[0] && + ssl->buffers.weOwnCert) { + /* request will be allocated in CreateOcspResponse() */ + FreeOcspRequest(request); + XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); + } + if (ret != 0) + return ret; + + if (csr->responses[0].buffer) + extension->resp = 1; +#if defined(WOLFSSL_TLS_OCSP_MULTI) + /* process OCSP request in certificate chain */ + if ((ret = ProcessChainOCSPRequest(ssl)) != 0) { + WOLFSSL_MSG("Process Cert Chain OCSP request failed"); + WOLFSSL_ERROR_VERBOSE(ret); + return ret; + } +#endif + return ret; +} +#endif + /* handle generation TLS v1.3 certificate (11) */ /* Send the certificate for this end and any CAs that help with validation. * This message is always encrypted in TLS v1.3. @@ -8736,7 +8812,7 @@ static int SendTls13Certificate(WOLFSSL* ssl) } #endif -#ifdef OPENSSL_EXTRA +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_SETUP_CB) /* call client cert callback if no cert has been loaded */ if ((ssl->ctx->CBClientCert != NULL) && (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer)) { @@ -8779,6 +8855,10 @@ static int SendTls13Certificate(WOLFSSL* ssl) * is populated with the server response. We would be sending the server * its own stapling data. */ if (ssl->options.side == WOLFSSL_SERVER_END) { + ret = SetupOcspResp(ssl); + if (ret != 0) + return ret; + ret = WriteCSRToBuffer(ssl, &ssl->buffers.certExts[0], &extSz[0], 1 /* +1 for leaf */ + ssl->buffers.certChainCnt); if (ret < 0) diff --git a/src/x509_str.c b/src/x509_str.c index f10281397bf..28c428ed365 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -687,8 +687,6 @@ void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx) #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(WOLFSSL_EXTRA) int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx) { WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error"); @@ -704,7 +702,6 @@ void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx) return ctx->error_depth; return WOLFSSL_FATAL_ERROR; } -#endif #ifdef OPENSSL_EXTRA void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx, diff --git a/tests/api.c b/tests/api.c index c22d02456e2..252e161820c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -7525,12 +7525,12 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) #ifdef WOLFSSL_ENCRYPTED_KEYS wolfSSL_CTX_set_default_passwd_cb(ctx->c_ctx, PasswordCallBack); #endif - if (ctx->c_cb.caPemFile != NULL) - ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx, - ctx->c_cb.caPemFile, 0), WOLFSSL_SUCCESS); - else + if (ctx->c_cb.caPemFile == NULL) ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx, caCertFile, 0), WOLFSSL_SUCCESS); + else if (*ctx->c_cb.caPemFile != '\0') + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx, + ctx->c_cb.caPemFile, 0), WOLFSSL_SUCCESS); if (ctx->c_cb.certPemFile != NULL) { clientCertFile = ctx->c_cb.certPemFile; } @@ -7541,10 +7541,14 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) if (!c_sharedCtx) #endif { - ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->c_ctx, - clientCertFile), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, clientKeyFile, - CERT_FILETYPE), WOLFSSL_SUCCESS); + if (*clientCertFile != '\0') { + ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->c_ctx, + clientCertFile), WOLFSSL_SUCCESS); + } + if (*clientKeyFile != '\0') { + ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, clientKeyFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + } } #ifdef HAVE_CRL if (ctx->c_cb.crlPemFile != NULL) { @@ -7600,12 +7604,12 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) wolfSSL_SetIOSend(ctx->s_ctx, test_ssl_memio_write_cb); wolfSSL_CTX_set_verify(ctx->s_ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); - if (ctx->s_cb.caPemFile != NULL) - ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx, - ctx->s_cb.caPemFile, 0), WOLFSSL_SUCCESS); - else + if (ctx->s_cb.caPemFile == NULL) ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx, cliCertFile, 0), WOLFSSL_SUCCESS); + else if (*ctx->s_cb.caPemFile != '\0') + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx, + ctx->s_cb.caPemFile, 0), WOLFSSL_SUCCESS); #ifdef WOLFSSL_ENCRYPTED_KEYS wolfSSL_CTX_set_default_passwd_cb(ctx->s_ctx, PasswordCallBack); #endif @@ -7616,8 +7620,10 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) if (!s_sharedCtx) #endif { - ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->s_ctx, - serverCertFile), WOLFSSL_SUCCESS); + if (*serverCertFile != '\0') { + ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->s_ctx, + serverCertFile), WOLFSSL_SUCCESS); + } } if (ctx->s_cb.keyPemFile != NULL) { serverKeyFile = ctx->s_cb.keyPemFile; @@ -7626,8 +7632,10 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) if (!s_sharedCtx) #endif { - ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, serverKeyFile, - CERT_FILETYPE), WOLFSSL_SUCCESS); + if (*serverKeyFile != '\0') { + ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, serverKeyFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + } } if (ctx->s_ciphers != NULL) { ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx->s_ctx, ctx->s_ciphers), @@ -7644,17 +7652,18 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) ExpectNotNull(ctx->c_ssl = wolfSSL_new(ctx->c_ctx)); wolfSSL_SetIOWriteCtx(ctx->c_ssl, ctx); wolfSSL_SetIOReadCtx(ctx->c_ssl, ctx); - if (0 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) - || c_sharedCtx -#endif - ) - { - ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl, - clientCertFile), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, clientKeyFile, - CERT_FILETYPE), WOLFSSL_SUCCESS); + if (c_sharedCtx) { + if (*clientCertFile != '\0') { + ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl, + clientCertFile), WOLFSSL_SUCCESS); + } + if (*clientKeyFile != '\0') { + ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, clientKeyFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + } } +#endif if (ctx->c_cb.ssl_ready != NULL) { ExpectIntEQ(ctx->c_cb.ssl_ready(ctx->c_ssl), TEST_SUCCESS); } @@ -7665,17 +7674,18 @@ int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) ExpectNotNull(ctx->s_ssl = wolfSSL_new(ctx->s_ctx)); wolfSSL_SetIOWriteCtx(ctx->s_ssl, ctx); wolfSSL_SetIOReadCtx(ctx->s_ssl, ctx); - if (0 #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) - || s_sharedCtx -#endif - ) - { - ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl, - serverCertFile), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, serverKeyFile, - CERT_FILETYPE), WOLFSSL_SUCCESS); + if (s_sharedCtx) { + if (*serverCertFile != '\0') { + ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl, + serverCertFile), WOLFSSL_SUCCESS); + } + if (*serverKeyFile != '\0') { + ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, serverKeyFile, + CERT_FILETYPE), WOLFSSL_SUCCESS); + } } +#endif #if !defined(NO_FILESYSTEM) && !defined(NO_DH) wolfSSL_SetTmpDH_file(ctx->s_ssl, dhParamFile, CERT_FILETYPE); #elif !defined(NO_DH) @@ -27534,17 +27544,42 @@ static int test_wolfSSL_cert_cb(void) #if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) test_ssl_cbf func_cb_client; test_ssl_cbf func_cb_server; + size_t i; + struct { + method_provider client_meth; + method_provider server_meth; + const char* desc; + } test_params[] = { +#ifdef WOLFSSL_TLS13 + {wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3"}, +#endif +#ifndef WOLFSSL_NO_TLS12 + {wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2"}, +#endif +#ifndef NO_OLD_TLS + {wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLS 1.1"}, +#ifdef WOLFSSL_ALLOW_TLSV10 + {wolfTLSv1_client_method, wolfTLSv1_server_method, "TLS 1.0"}, +#endif +#endif + }; - XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); - XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + for (i = 0; i < XELEM_CNT(test_params) && !EXPECT_FAIL(); i++) { + XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); + XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + + printf("\tTesting with %s...\n", test_params[i].desc); - func_cb_client.ctx_ready = certSetupCb; - func_cb_client.ssl_ready = certClearCb; - func_cb_server.ctx_ready = certSetupCb; - func_cb_server.ssl_ready = certClearCb; + func_cb_client.method = test_params[i].client_meth; + func_cb_server.method = test_params[i].server_meth; + func_cb_client.ctx_ready = certSetupCb; + func_cb_client.ssl_ready = certClearCb; + func_cb_server.ctx_ready = certSetupCb; + func_cb_server.ssl_ready = certClearCb; - ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, - &func_cb_server, NULL), TEST_SUCCESS); + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, + &func_cb_server, NULL), TEST_SUCCESS); + } #endif return EXPECT_RESULT(); } @@ -51378,6 +51413,7 @@ TEST_DECL(test_wc_RsaPSS_DigitalSignVerify), TEST_DECL(test_ocsp_basic_verify), TEST_DECL(test_ocsp_response_parsing), TEST_DECL(test_ocsp_certid_enc_dec), + TEST_DECL(test_ocsp_tls_cert_cb), TEST_DECL(test_tls12_unexpected_ccs), TEST_DECL(test_tls13_unexpected_ccs), TEST_DECL(test_tls12_curve_intersection), diff --git a/tests/api/create_ocsp_test_blobs.py b/tests/api/create_ocsp_test_blobs.py index 24847bf69fe..b615acbcf69 100644 --- a/tests/api/create_ocsp_test_blobs.py +++ b/tests/api/create_ocsp_test_blobs.py @@ -9,7 +9,7 @@ from pyasn1.type import univ, tag, useful, namedtype from base64 import b64decode from hashlib import sha1, sha256 -from datetime import datetime +from datetime import datetime, timedelta from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography import x509 @@ -124,7 +124,7 @@ def cert_status(value: int) -> rfc6960.CertStatus: revoked = rfc6960.RevokedInfo().subtype(implicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatSimple, 1)) revoked['revocationTime'] = useful.GeneralizedTime().fromDateTime( - datetime.now()) + datetime.now() - timedelta(days=1)) cs['revoked'] = revoked return cs @@ -136,7 +136,7 @@ def single_response(issuer_cert_path: str, serial: int, sr = rfc6960.SingleResponse().clone() sr.setComponentByName('certID', cid) sr['certStatus'] = cs - sr['thisUpdate'] = useful.GeneralizedTime().fromDateTime(datetime.now()) + sr['thisUpdate'] = useful.GeneralizedTime().fromDateTime(datetime.now() - timedelta(days=1)) return sr def response_data(rid: rfc6960.ResponderID | None, @@ -146,7 +146,7 @@ def response_data(rid: rfc6960.ResponderID | None, tag.tagClassContext, tag.tagFormatSimple, 0)) if rid: rd['responderID'] = rid - rd['producedAt'] = useful.GeneralizedTime().fromDateTime(datetime.now()) + rd['producedAt'] = useful.GeneralizedTime().fromDateTime(datetime.now() - timedelta(days=1)) rs = univ.SequenceOf(componentType=rfc6960.SingleResponse()) rs.extend(responses) rd['responses'] = rs @@ -233,7 +233,7 @@ def single_response_from_cert(cert_path: str, sr = rfc6960.SingleResponse().clone() sr.setComponentByName('certID', cid) sr['certStatus'] = cs - sr['thisUpdate'] = useful.GeneralizedTime().fromDateTime(datetime.now()) + sr['thisUpdate'] = useful.GeneralizedTime().fromDateTime(datetime.now() - timedelta(days=1)) return sr RESPONSE_STATUS_GOOD = 0 @@ -399,6 +399,51 @@ def create_bad_response(rd: dict) -> bytes: 'responder_key': WOLFSSL_OCSP_CERT_PATH + 'root-ca-key.pem', 'name': 'resp_bad_embedded_cert' }, + { + 'response_status': 0, + 'signature_algorithm': signature_algorithm(), + 'certs_path': [WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-cert.pem'], + 'responder_by_name': True, + 'responses': [ + { + 'issuer_cert': WOLFSSL_OCSP_CERT_PATH + 'intermediate1-ca-cert.pem', + 'serial': 0x05, + 'status': CERT_GOOD + } + ], + 'responder_key': WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-key.pem', + 'name': 'resp_server1_cert' + }, + { + 'response_status': 0, + 'signature_algorithm': signature_algorithm(), + 'certs_path': [WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-cert.pem'], + 'responder_by_name': True, + 'responses': [ + { + 'issuer_cert': WOLFSSL_OCSP_CERT_PATH + 'root-ca-cert.pem', + 'serial': 0x01, + 'status': CERT_GOOD + } + ], + 'responder_key': WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-key.pem', + 'name': 'resp_intermediate1_cert' + }, + { + 'response_status': 0, + 'signature_algorithm': signature_algorithm(), + 'certs_path': [WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-cert.pem'], + 'responder_by_name': True, + 'responses': [ + { + 'issuer_cert': WOLFSSL_OCSP_CERT_PATH + 'root-ca-cert.pem', + 'serial': 0x63, + 'status': CERT_GOOD + } + ], + 'responder_key': WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-key.pem', + 'name': 'resp_root_ca_cert' + }, ] with open('./tests/api/test_ocsp_test_blobs.h', 'w') as f: diff --git a/tests/api/test_ocsp.c b/tests/api/test_ocsp.c index 997b99b1221..bd529a80065 100644 --- a/tests/api/test_ocsp.c +++ b/tests/api/test_ocsp.c @@ -658,3 +658,369 @@ int test_ocsp_certid_enc_dec(void) return TEST_SKIPPED; } #endif + +#if defined(HAVE_OCSP) && defined(WOLFSSL_CERT_SETUP_CB) && \ + defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_RSA) && \ + (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) && \ + defined(SESSION_CERTS) + +static struct { + size_t chainLen; + byte failStaple:2; +} test_ocsp_tls_cert_cb_opts; +/* --- certificate-selection callback ----------------------------------- */ +static int test_ocsp_tls_cert_cb_cert_cb(WOLFSSL* ssl, void* arg) +{ + (void)arg; + switch (test_ocsp_tls_cert_cb_opts.chainLen) { + case 1: + if (wolfSSL_use_certificate_file(ssl, + "./certs/ocsp/server1-cert.pem", WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + return 0; + break; + case 2: { + /* We need to limit the buffer to only the leaf and int certs */ + byte* buf = NULL; + size_t bufLen = 0; + byte* lastCert = NULL; + byte loaded = 0; + + if (wc_FileLoad("./certs/ocsp/server1-cert.pem", &buf, &bufLen, + NULL) != 0) + return 0; + /* Find the last cert */ + lastCert = (byte*)XSTRNSTR((char*)buf, + "-----BEGIN CERTIFICATE-----", (unsigned int)bufLen); + if (lastCert != NULL) { + lastCert = (byte*)XSTRNSTR((char*)lastCert + 1, + "-----BEGIN CERTIFICATE-----", + (unsigned int)(bufLen - (lastCert - buf))); + } + if (lastCert != NULL) { + lastCert = (byte*)XSTRNSTR((char*)lastCert + 1, + "-----BEGIN CERTIFICATE-----", + (unsigned int)(bufLen - (lastCert - buf))); + } + if (lastCert != NULL) { + if (wolfSSL_use_certificate_chain_buffer(ssl, buf, lastCert - buf) + == WOLFSSL_SUCCESS) + loaded = 1; + } + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!loaded) + return 0; + break; + } + case 3: + if (wolfSSL_use_certificate_chain_file(ssl, + "./certs/ocsp/server1-cert.pem") + != WOLFSSL_SUCCESS) + return 0; + break; + } + if (wolfSSL_use_PrivateKey_file(ssl, + "./certs/ocsp/server1-key.pem", WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + return 0; + return 1; /* success */ +} + +static int test_ocsp_tls_cert_cb_status_cb(WOLFSSL* ssl, void* ioCtx) +{ + byte* leaf_resp = NULL; + byte* int_resp = NULL; + byte* root_resp = NULL; + int ret = WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL; + (void)ioCtx; + leaf_resp = (byte*)XMALLOC(sizeof(resp_server1_cert), NULL, 0); + int_resp = (byte*)XMALLOC(sizeof(resp_intermediate1_cert), NULL, 0); + root_resp = (byte*)XMALLOC(sizeof(resp_root_ca_cert), NULL, 0); + if (leaf_resp != NULL && int_resp != NULL && root_resp != NULL) { + XMEMCPY(leaf_resp, resp_server1_cert, sizeof(resp_server1_cert)); + XMEMCPY(int_resp, resp_intermediate1_cert, sizeof(resp_intermediate1_cert)); + XMEMCPY(root_resp, resp_root_ca_cert, sizeof(resp_root_ca_cert)); + /* 320 is inside the signature so flipping bits should cause errors */ + switch (test_ocsp_tls_cert_cb_opts.failStaple) { + case 1: + leaf_resp[320] = ~leaf_resp[320]; + break; + case 2: + int_resp[320] = ~int_resp[320]; + break; + case 3: + root_resp[320] = ~root_resp[320]; + break; + } + if (wolfSSL_set_tlsext_status_ocsp_resp_multi(ssl, leaf_resp, + sizeof(resp_server1_cert), 0) == WOLFSSL_SUCCESS) + leaf_resp = NULL; + if (wolfSSL_set_tlsext_status_ocsp_resp_multi(ssl, int_resp, + sizeof(resp_intermediate1_cert), 1) == WOLFSSL_SUCCESS) + int_resp = NULL; + if (wolfSSL_set_tlsext_status_ocsp_resp_multi(ssl, root_resp, + sizeof(resp_root_ca_cert), 2) == WOLFSSL_SUCCESS) + root_resp = NULL; + /* If all responses loaded then return OK */ + if (leaf_resp == NULL && int_resp == NULL && root_resp == NULL) + ret = WOLFSSL_OCSP_STATUS_CB_OK; + } + XFREE(leaf_resp, NULL, 0); + XFREE(int_resp, NULL, 0); + XFREE(root_resp, NULL, 0); + return ret; +} + +static int test_ocsp_tls_cert_cb_verify_cb(int preverify, + WOLFSSL_X509_STORE_CTX* store) +{ + int ret = 1; + int err = wolfSSL_X509_STORE_CTX_get_error(store); + int idx = wolfSSL_X509_STORE_CTX_get_error_depth(store); + + if (err == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E) || + err == WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E) +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ + defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED) + || err == WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + || err == WOLFSSL_X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT +#endif + ) { + WOLFSSL_BUFFER_INFO* bInfo = &store->certs[idx]; + WOLFSSL_CERT_MANAGER* cm = NULL; + DecodedCert cert; + byte certInit = 0; + + ret = 1; + cm = wolfSSL_CertManagerNew(); + if (cm == NULL) + ret = 0; + if (ret == 1 && + wolfSSL_CertManagerLoadCA(cm, "./certs/ocsp/root-ca-cert.pem", NULL) + != WOLFSSL_SUCCESS) + ret = 0; + /* If verifying leaf cert then we need to load the intermediate CA */ + if (ret == 1 && idx == 0 && + wolfSSL_CertManagerLoadCA(cm, "./certs/ocsp/intermediate1-ca-cert.pem", NULL) + != WOLFSSL_SUCCESS) + ret = 0; + + /* Verify cert with CA */ + if (ret == 1) { + wc_InitDecodedCert(&cert, bInfo->buffer, bInfo->length, NULL); + certInit = 1; + } + if (ret == 1 && wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm) != 0) + ret = 0; + + if (certInit) + wc_FreeDecodedCert(&cert); + wolfSSL_CertManagerFree(cm); + } + (void)preverify; + return ret; +} + +static int test_ocsp_tls_cert_cb_ocsp_verify_cb(WOLFSSL* ssl, int err, + byte* staple, word32 stapleSz, word32 idx, void* arg) +{ + (void)ssl; + (void)arg; + if (err != 0) { + WOLFSSL_CERT_MANAGER* cm = NULL; + DecodedCert cert; + byte certInit = 0; + WOLFSSL_OCSP* ocsp = NULL; + WOLFSSL_X509_CHAIN* peerCerts; + + cm = wolfSSL_CertManagerNew(); + if (cm == NULL) + goto cleanup; + if (wolfSSL_CertManagerLoadCA(cm, "./certs/ocsp/root-ca-cert.pem", NULL) + != WOLFSSL_SUCCESS) + goto cleanup; + /* If verifying leaf cert then we need to load the intermediate CA */ + if (idx == 0 && wolfSSL_CertManagerLoadCA(cm, + "./certs/ocsp/intermediate1-ca-cert.pem", NULL) + != WOLFSSL_SUCCESS) + goto cleanup; + + peerCerts = wolfSSL_get_peer_chain(ssl); + if (peerCerts == NULL || wolfSSL_get_chain_count(peerCerts) <= (int)idx) + goto cleanup; + + /* Verify cert with CA */ + wc_InitDecodedCert(&cert, wolfSSL_get_chain_cert(peerCerts, idx), + wolfSSL_get_chain_length(peerCerts, idx), NULL); + certInit = 1; + if (wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm) != 0) + goto cleanup; + if ((ocsp = wc_NewOCSP(cm)) == NULL) + goto cleanup; + if (wc_CheckCertOcspResponse(ocsp, &cert, staple, stapleSz, NULL) != 0) + goto cleanup; + + err = 0; +cleanup: + wc_FreeOCSP(ocsp); + if (certInit) + wc_FreeDecodedCert(&cert); + wolfSSL_CertManagerFree(cm); + } + return err; +} + +static int test_ocsp_tls_cert_cb_ctx_ready(WOLFSSL_CTX* ctx) +{ + /* server: dynamic cert */ + wolfSSL_CTX_set_cert_cb(ctx, test_ocsp_tls_cert_cb_cert_cb, NULL); + return TEST_SUCCESS; +} + +/* --- very small OCSP-status callback ---------------------------------- */ +/* no status callback path - context struct not needed */ + +/* --- the actual test case --------------------------------------------- */ +int test_ocsp_tls_cert_cb(void) +{ + EXPECT_DECLS; + size_t i, j, chainLen; + struct { + method_provider client_meth; + method_provider server_meth; + const char* tls_version; + byte useV2:1; + byte useV2multi:1; + byte maxFail:2; + } params[] = { +#if !defined(WOLFSSL_NO_TLS12) + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2", 0, 0, 1 }, + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2", 1, 0, 1 }, + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2", 1, 1, 1 }, + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2", 0, 0, 1 }, + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2", 1, 0, 1 }, + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2", 1, 1, 3 }, +#ifdef WOLFSSL_DTLS + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2", 0, 0, 1 }, + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2", 1, 0, 1 }, + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2", 1, 1, 1 }, + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2", 0, 0, 1 }, + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2", 1, 0, 1 }, + { wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2", 1, 1, 3 }, +#endif +#endif +#ifdef WOLFSSL_TLS13 + { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3", 0, 0, 3 }, + { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3", 0, 0, 1 }, +#ifdef WOLFSSL_DTLS13 + { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3", 0, 0, 3 }, + { wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3", 0, 0, 1 }, +#endif +#endif + }; + + for (i = 0; i < XELEM_CNT(params) && !EXPECT_FAIL(); i++) { + printf("\nTesting %s\n", params[i].tls_version); + for (chainLen = 1; chainLen <= 3 && !EXPECT_FAIL(); chainLen++) { + printf("\tWith chain length %zu\n", chainLen); + /* 0 - all staples valid + * 1-3 - break the corresponding staple */ + for (j = 0; j <= params[i].maxFail && j <= chainLen && !EXPECT_FAIL(); j++) { + struct test_ssl_memio_ctx test_ctx; + byte skip = 0; + + test_ocsp_tls_cert_cb_opts.failStaple = j; + printf("\t%s (%zu)", j ? "with failing staple" : "correct staple", j); + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + test_ctx.c_cb.caPemFile = ""; + /* Do NOT preload any cert/key into the server context: leave empty strings + so that ctx setup code skips loading them entirely and the only cert + comes from the per-connection callback below. */ + test_ctx.s_cb.certPemFile = ""; /* nothing pre-loaded */ + test_ctx.s_cb.keyPemFile = ""; + + test_ctx.c_cb.method = params[i].client_meth; + test_ctx.s_cb.method = params[i].server_meth; + + test_ocsp_tls_cert_cb_opts.chainLen = chainLen; + + test_ctx.s_cb.ctx_ready = test_ocsp_tls_cert_cb_ctx_ready; + + ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS); + + /* Unload the certificate that test helpers may have put into the server + SSL object - we want the server to *not* have any certificate at the + moment it parses ClientHello so that the early OCSP code path fails. */ + ExpectIntEQ(wolfSSL_UnloadCertsKeys(test_ctx.s_ssl), WOLFSSL_SUCCESS); + + /* turn on OCSP stapling on the server side */ + ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(test_ctx.s_ctx), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_set_tlsext_status_cb(test_ctx.s_ctx, + test_ocsp_tls_cert_cb_status_cb), WOLFSSL_SUCCESS); + + /* client: request stapling */ + wolfSSL_set_verify(test_ctx.c_ssl, WOLFSSL_VERIFY_DEFAULT, + test_ocsp_tls_cert_cb_verify_cb); + wolfSSL_CTX_set_ocsp_status_verify_cb(test_ctx.c_ctx, + test_ocsp_tls_cert_cb_ocsp_verify_cb, NULL); + + /* Set the ssl object as the cert callback context as there is + * no way to get ssl from the store without OPENSSL_EXTRA */ + wolfSSL_SetCertCbCtx(test_ctx.c_ssl, test_ctx.c_ssl); + ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(test_ctx.c_ctx), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_EnableOCSPMustStaple(test_ctx.c_ctx), WOLFSSL_SUCCESS); + if (params[i].useV2) { + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + printf("\twith V2 %s\n", params[i].useV2multi ? "multi" : "single"); + ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(test_ctx.c_ssl, + params[i].useV2multi ? + WOLFSSL_CSR2_OCSP_MULTI : WOLFSSL_CSR2_OCSP, + WOLFSSL_CSR2_OCSP_USE_NONCE), + WOLFSSL_SUCCESS); + #else + skip = 1; + #endif + } + else { + #ifdef HAVE_CERTIFICATE_STATUS_REQUEST + printf("\twith V1\n"); + ExpectIntEQ(wolfSSL_UseOCSPStapling(test_ctx.c_ssl, + WOLFSSL_CSR_OCSP, 0), + WOLFSSL_SUCCESS); + #else + skip = 1; + #endif + } + + if (!skip) { + ExpectIntEQ(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), + j == 0 ? TEST_SUCCESS : TEST_FAIL); + if (j != 0) { + WOLFSSL_ALERT_HISTORY h; + XMEMSET(&h, 0, sizeof(h)); + ExpectIntEQ(wolfSSL_get_alert_history(test_ctx.s_ssl, &h), + WOLFSSL_SUCCESS); + ExpectIntEQ(h.last_rx.level, alert_fatal); + ExpectIntEQ(h.last_rx.code, bad_certificate_status_response); + } + } + else { + printf("\tskipping test case\n"); + } + + test_ssl_memio_cleanup(&test_ctx); + } + } + } + + return EXPECT_RESULT(); +} + +#else /* feature guards */ +int test_ocsp_tls_cert_cb(void) +{ + return TEST_SKIPPED; +} +#endif diff --git a/tests/api/test_ocsp.h b/tests/api/test_ocsp.h index 67d30e78a36..267809f5ad9 100644 --- a/tests/api/test_ocsp.h +++ b/tests/api/test_ocsp.h @@ -26,5 +26,6 @@ int test_ocsp_certid_enc_dec(void); int test_ocsp_status_callback(void); int test_ocsp_basic_verify(void); int test_ocsp_response_parsing(void); +int test_ocsp_tls_cert_cb(void); #endif /* WOLFSSL_TEST_OCSP_H */ diff --git a/tests/api/test_ocsp_test_blobs.h b/tests/api/test_ocsp_test_blobs.h index d0801afefd6..48f80caf6bc 100644 --- a/tests/api/test_ocsp_test_blobs.h +++ b/tests/api/test_ocsp_test_blobs.h @@ -641,6 +641,465 @@ unsigned char resp_bad_embedded_cert[] = { 0x05, 0x0f, 0x43, 0x7c, 0x21, 0xb6, }; +unsigned char resp_server1_cert[] = { + 0x30, 0x82, 0x07, 0x04, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x06, 0xfd, 0x30, + 0x82, 0x06, 0xf9, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x01, 0x04, 0x82, 0x06, 0xea, 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, + 0x01, 0x06, 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, 0x35, 0x30, 0x39, 0x31, 0x34, 0x31, 0x37, 0x33, 0x38, + 0x35, 0x38, 0x5a, 0x30, 0x4f, 0x30, 0x4d, 0x30, 0x38, 0x30, 0x07, 0x06, + 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 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, + 0x35, 0x30, 0x39, 0x31, 0x34, 0x31, 0x37, 0x33, 0x38, 0x35, 0x38, 0x5a, + 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaa, 0x0e, 0x68, 0x4c, 0x62, 0x97, + 0x79, 0x78, 0xad, 0x0e, 0xe7, 0x5b, 0x9e, 0x78, 0xca, 0xf7, 0x8c, 0x15, + 0x48, 0x22, 0x7f, 0x34, 0xf3, 0x4e, 0x4e, 0xfc, 0x9a, 0x9c, 0x69, 0xc8, + 0xc1, 0x1c, 0xfc, 0xbc, 0xc4, 0x3a, 0xc3, 0x70, 0xd8, 0x7a, 0xf1, 0x45, + 0x02, 0x75, 0x69, 0x51, 0x17, 0x07, 0x14, 0x02, 0xb1, 0xbe, 0x2e, 0x3c, + 0x2f, 0x60, 0x45, 0xc9, 0x91, 0x27, 0x80, 0x8f, 0x25, 0x49, 0xbc, 0x06, + 0x0b, 0x7e, 0xab, 0xf6, 0xb7, 0xd1, 0xcf, 0x07, 0x7b, 0x3d, 0x85, 0x35, + 0xd0, 0x3d, 0xbf, 0x10, 0x59, 0x0c, 0xbc, 0x84, 0xab, 0x4a, 0x0d, 0xd0, + 0x38, 0xcd, 0x8b, 0x18, 0xbd, 0x56, 0x13, 0x54, 0xd9, 0x8f, 0x8d, 0x81, + 0x53, 0x5a, 0x67, 0x0a, 0xa5, 0x00, 0xaa, 0x28, 0x8d, 0xee, 0x98, 0xe0, + 0x13, 0xbe, 0x86, 0xfc, 0x5b, 0xcb, 0x79, 0x6a, 0x9a, 0xf4, 0x83, 0xa1, + 0xa6, 0x4a, 0x25, 0x8f, 0x09, 0xc4, 0xa0, 0xb4, 0xf8, 0x17, 0x5f, 0x63, + 0xde, 0xc6, 0x40, 0xa2, 0xf4, 0x77, 0x52, 0x7e, 0xa1, 0xc4, 0x9d, 0x49, + 0x3e, 0x5e, 0x92, 0x46, 0xc0, 0x91, 0x95, 0x11, 0x19, 0xa3, 0x97, 0xa4, + 0xc2, 0x74, 0x60, 0x5b, 0xb9, 0x6d, 0x1a, 0x49, 0x1f, 0x4d, 0x59, 0xa8, + 0x20, 0x7d, 0x2e, 0xa7, 0x57, 0x62, 0x37, 0x16, 0xfb, 0x6e, 0x58, 0x9d, + 0xbc, 0xb0, 0xb7, 0x4d, 0xab, 0x3e, 0x10, 0xee, 0x81, 0x52, 0x52, 0x3f, + 0x97, 0xb7, 0x0f, 0xc6, 0x3f, 0x96, 0x7e, 0x2b, 0x48, 0xae, 0x06, 0xc1, + 0x21, 0xcc, 0xaa, 0x7f, 0x60, 0x83, 0xda, 0x6d, 0xa8, 0x17, 0xad, 0xfe, + 0x16, 0xe6, 0xbd, 0x58, 0xea, 0x4e, 0x16, 0x08, 0xc8, 0x54, 0x0a, 0xba, + 0xad, 0x83, 0xd1, 0x19, 0x36, 0x49, 0x61, 0xc6, 0x8a, 0x06, 0x3a, 0x9c, + 0x0c, 0xf1, 0x86, 0x99, 0x24, 0xdf, 0xe4, 0x2d, 0xca, 0xcf, 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, 0x34, 0x31, 0x32, 0x31, 0x38, 0x32, 0x31, 0x32, + 0x35, 0x33, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x39, 0x31, 0x34, + 0x32, 0x31, 0x32, 0x35, 0x33, 0x31, 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, 0x4d, 0xa2, 0xd8, 0x55, + 0xe0, 0x2b, 0xf4, 0xad, 0x65, 0xe2, 0x92, 0x35, 0xcb, 0x60, 0xa0, 0xa2, + 0x6b, 0xa6, 0x88, 0xc1, 0x86, 0x58, 0x57, 0x37, 0xbd, 0x2e, 0x28, 0x6e, + 0x1c, 0x56, 0x2a, 0x35, 0xde, 0xff, 0x3e, 0x8e, 0x3d, 0x47, 0x21, 0x1a, + 0xe9, 0xd3, 0xc6, 0xb4, 0xe2, 0xcb, 0x3e, 0xc6, 0xaf, 0x9b, 0xef, 0x23, + 0x88, 0x56, 0x95, 0x73, 0x2e, 0xb3, 0xed, 0xc5, 0x11, 0x4b, 0x69, 0xf7, + 0x13, 0x3a, 0x05, 0xe1, 0xaf, 0xba, 0xc9, 0x59, 0xfd, 0xe2, 0xa0, 0x81, + 0xa0, 0x4c, 0x0c, 0x2c, 0xcb, 0x57, 0xad, 0x96, 0x3a, 0x8c, 0x32, 0xa6, + 0x4a, 0xf8, 0x72, 0xb8, 0xec, 0xb3, 0x26, 0x69, 0xd6, 0x6a, 0x4c, 0x4c, + 0x78, 0x18, 0x3c, 0xca, 0x19, 0xf1, 0xb5, 0x8e, 0x23, 0x81, 0x5b, 0x27, + 0x90, 0xe0, 0x5c, 0x2b, 0x17, 0x4d, 0x78, 0x99, 0x6b, 0x25, 0xbd, 0x2f, + 0xae, 0x1b, 0xaa, 0xce, 0x84, 0xb9, 0x44, 0x21, 0x46, 0xc0, 0x34, 0x6b, + 0x5b, 0xb9, 0x1b, 0xca, 0x5c, 0x60, 0xf1, 0xef, 0xe6, 0x66, 0xbc, 0x84, + 0x63, 0x56, 0x50, 0x7d, 0xbb, 0x2c, 0x2f, 0x7b, 0x47, 0xb4, 0xfd, 0x58, + 0x77, 0x87, 0xee, 0x27, 0x20, 0x96, 0x72, 0x8e, 0x4c, 0x7e, 0x4f, 0x93, + 0xeb, 0x5f, 0x8f, 0x9c, 0x1e, 0x59, 0x7a, 0x96, 0xaa, 0x53, 0x77, 0x22, + 0x41, 0xd8, 0xd3, 0xf9, 0x89, 0x8f, 0xe8, 0x9d, 0x65, 0xbd, 0x0c, 0x71, + 0x3c, 0xbb, 0xa3, 0x07, 0xbf, 0xfb, 0xa8, 0xd1, 0x18, 0x0a, 0xb4, 0xc4, + 0xf7, 0x83, 0xb3, 0x86, 0x2b, 0xf0, 0x5b, 0x05, 0x28, 0xc1, 0x01, 0x31, + 0x73, 0x5c, 0x2b, 0xbd, 0x60, 0x97, 0xa3, 0x36, 0x82, 0x96, 0xd7, 0x83, + 0xdf, 0x75, 0xee, 0x29, 0x42, 0x97, 0x86, 0x41, 0x55, 0xb9, 0x70, 0x87, + 0xd5, 0x02, 0x85, 0x13, 0x41, 0xf8, 0x25, 0x05, 0xab, 0x6a, 0xaa, 0x57, +}; + +unsigned char resp_intermediate1_cert[] = { + 0x30, 0x82, 0x07, 0x04, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x06, 0xfd, 0x30, + 0x82, 0x06, 0xf9, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x01, 0x04, 0x82, 0x06, 0xea, 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, + 0x01, 0x06, 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, 0x35, 0x30, 0x39, 0x31, 0x34, 0x31, 0x37, 0x33, 0x38, + 0x35, 0x38, 0x5a, 0x30, 0x4f, 0x30, 0x4d, 0x30, 0x38, 0x30, 0x07, 0x06, + 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x44, 0xa8, 0xdb, 0xd1, + 0xbc, 0x97, 0x0a, 0x83, 0x3b, 0x5b, 0x31, 0x9a, 0x4c, 0xb8, 0xd2, 0x52, + 0x37, 0x15, 0x8a, 0x88, 0x04, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f, 0x82, + 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, 0xb0, 0x04, 0x82, 0x3a, 0x7e, 0x72, + 0x15, 0x21, 0x02, 0x01, 0x01, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, + 0x35, 0x30, 0x39, 0x31, 0x34, 0x31, 0x37, 0x33, 0x38, 0x35, 0x38, 0x5a, + 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0x9e, 0xdb, 0x13, 0x95, 0xd4, + 0x9b, 0x3b, 0x93, 0xb3, 0x03, 0x44, 0x6e, 0xd3, 0xa6, 0x27, 0xc6, 0x7e, + 0x6e, 0x69, 0x2d, 0x1d, 0x9d, 0xa3, 0xbe, 0x1f, 0x95, 0xa1, 0xb0, 0xbe, + 0x09, 0xbc, 0xa8, 0xf6, 0xba, 0xcc, 0xfb, 0xb9, 0x76, 0x54, 0x21, 0xcd, + 0x26, 0x95, 0xa3, 0xb7, 0xee, 0xcf, 0xe1, 0x38, 0x4b, 0xb8, 0x4c, 0x84, + 0x00, 0xc4, 0x92, 0x28, 0x15, 0x2b, 0x54, 0x0e, 0x95, 0x43, 0xb0, 0x0c, + 0x15, 0x79, 0x07, 0x58, 0x12, 0x4a, 0x6b, 0xcf, 0x9d, 0x22, 0x91, 0x5c, + 0x37, 0x87, 0x25, 0xfd, 0x7c, 0x75, 0xc4, 0x31, 0x77, 0xe2, 0x4e, 0x1a, + 0x2c, 0xa1, 0x57, 0x17, 0x72, 0x9e, 0xf6, 0x13, 0xb7, 0x4e, 0xe1, 0x90, + 0xe4, 0xdb, 0x01, 0x43, 0xb5, 0xdc, 0xd7, 0x30, 0x16, 0x1e, 0x0f, 0xb0, + 0xef, 0x1f, 0xbf, 0x90, 0xa8, 0x0a, 0x8f, 0x0c, 0x7b, 0x36, 0x62, 0x09, + 0xe1, 0xcc, 0x11, 0x6d, 0xbe, 0x3f, 0x28, 0x3c, 0x3e, 0x11, 0x8e, 0x10, + 0x24, 0x73, 0x4e, 0x86, 0xdc, 0x1d, 0x50, 0xce, 0xf8, 0xb8, 0xd7, 0x12, + 0x72, 0xda, 0x32, 0x58, 0xd0, 0xc3, 0xe9, 0x56, 0x2c, 0xeb, 0x3a, 0xfc, + 0xa1, 0x2f, 0x34, 0x82, 0x83, 0xb8, 0x51, 0x2d, 0x60, 0x38, 0x35, 0x7f, + 0xe3, 0x06, 0x78, 0x79, 0x78, 0x5d, 0x12, 0x4b, 0x82, 0x8b, 0x6e, 0xf9, + 0xfd, 0x49, 0xf0, 0xd8, 0x2d, 0x82, 0x84, 0x27, 0x19, 0x72, 0x50, 0x36, + 0x0f, 0x63, 0x74, 0xea, 0x21, 0xcb, 0xa7, 0xdc, 0xc3, 0x8e, 0x67, 0x80, + 0x52, 0xda, 0x0f, 0x1a, 0x99, 0xdc, 0x02, 0x8f, 0x1d, 0xfc, 0xa1, 0xe9, + 0xc6, 0xda, 0x5c, 0xf2, 0x99, 0x4d, 0x0e, 0xfc, 0x36, 0xde, 0x7e, 0x82, + 0x1e, 0x3d, 0x1c, 0x37, 0xe6, 0x2b, 0x1e, 0x3b, 0xe0, 0x42, 0x0e, 0x43, + 0x57, 0xfe, 0x7c, 0xdc, 0x69, 0x83, 0xf7, 0xba, 0xe4, 0xf9, 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, 0x34, 0x31, 0x32, 0x31, 0x38, 0x32, 0x31, 0x32, + 0x35, 0x33, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x39, 0x31, 0x34, + 0x32, 0x31, 0x32, 0x35, 0x33, 0x31, 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, 0x4d, 0xa2, 0xd8, 0x55, + 0xe0, 0x2b, 0xf4, 0xad, 0x65, 0xe2, 0x92, 0x35, 0xcb, 0x60, 0xa0, 0xa2, + 0x6b, 0xa6, 0x88, 0xc1, 0x86, 0x58, 0x57, 0x37, 0xbd, 0x2e, 0x28, 0x6e, + 0x1c, 0x56, 0x2a, 0x35, 0xde, 0xff, 0x3e, 0x8e, 0x3d, 0x47, 0x21, 0x1a, + 0xe9, 0xd3, 0xc6, 0xb4, 0xe2, 0xcb, 0x3e, 0xc6, 0xaf, 0x9b, 0xef, 0x23, + 0x88, 0x56, 0x95, 0x73, 0x2e, 0xb3, 0xed, 0xc5, 0x11, 0x4b, 0x69, 0xf7, + 0x13, 0x3a, 0x05, 0xe1, 0xaf, 0xba, 0xc9, 0x59, 0xfd, 0xe2, 0xa0, 0x81, + 0xa0, 0x4c, 0x0c, 0x2c, 0xcb, 0x57, 0xad, 0x96, 0x3a, 0x8c, 0x32, 0xa6, + 0x4a, 0xf8, 0x72, 0xb8, 0xec, 0xb3, 0x26, 0x69, 0xd6, 0x6a, 0x4c, 0x4c, + 0x78, 0x18, 0x3c, 0xca, 0x19, 0xf1, 0xb5, 0x8e, 0x23, 0x81, 0x5b, 0x27, + 0x90, 0xe0, 0x5c, 0x2b, 0x17, 0x4d, 0x78, 0x99, 0x6b, 0x25, 0xbd, 0x2f, + 0xae, 0x1b, 0xaa, 0xce, 0x84, 0xb9, 0x44, 0x21, 0x46, 0xc0, 0x34, 0x6b, + 0x5b, 0xb9, 0x1b, 0xca, 0x5c, 0x60, 0xf1, 0xef, 0xe6, 0x66, 0xbc, 0x84, + 0x63, 0x56, 0x50, 0x7d, 0xbb, 0x2c, 0x2f, 0x7b, 0x47, 0xb4, 0xfd, 0x58, + 0x77, 0x87, 0xee, 0x27, 0x20, 0x96, 0x72, 0x8e, 0x4c, 0x7e, 0x4f, 0x93, + 0xeb, 0x5f, 0x8f, 0x9c, 0x1e, 0x59, 0x7a, 0x96, 0xaa, 0x53, 0x77, 0x22, + 0x41, 0xd8, 0xd3, 0xf9, 0x89, 0x8f, 0xe8, 0x9d, 0x65, 0xbd, 0x0c, 0x71, + 0x3c, 0xbb, 0xa3, 0x07, 0xbf, 0xfb, 0xa8, 0xd1, 0x18, 0x0a, 0xb4, 0xc4, + 0xf7, 0x83, 0xb3, 0x86, 0x2b, 0xf0, 0x5b, 0x05, 0x28, 0xc1, 0x01, 0x31, + 0x73, 0x5c, 0x2b, 0xbd, 0x60, 0x97, 0xa3, 0x36, 0x82, 0x96, 0xd7, 0x83, + 0xdf, 0x75, 0xee, 0x29, 0x42, 0x97, 0x86, 0x41, 0x55, 0xb9, 0x70, 0x87, + 0xd5, 0x02, 0x85, 0x13, 0x41, 0xf8, 0x25, 0x05, 0xab, 0x6a, 0xaa, 0x57, +}; + +unsigned char resp_root_ca_cert[] = { + 0x30, 0x82, 0x07, 0x04, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x06, 0xfd, 0x30, + 0x82, 0x06, 0xf9, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x01, 0x04, 0x82, 0x06, 0xea, 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, + 0x01, 0x06, 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, 0x35, 0x30, 0x39, 0x31, 0x34, 0x31, 0x37, 0x33, 0x38, + 0x35, 0x38, 0x5a, 0x30, 0x4f, 0x30, 0x4d, 0x30, 0x38, 0x30, 0x07, 0x06, + 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x44, 0xa8, 0xdb, 0xd1, + 0xbc, 0x97, 0x0a, 0x83, 0x3b, 0x5b, 0x31, 0x9a, 0x4c, 0xb8, 0xd2, 0x52, + 0x37, 0x15, 0x8a, 0x88, 0x04, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f, 0x82, + 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, 0xb0, 0x04, 0x82, 0x3a, 0x7e, 0x72, + 0x15, 0x21, 0x02, 0x01, 0x63, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, + 0x35, 0x30, 0x39, 0x31, 0x34, 0x31, 0x37, 0x33, 0x38, 0x35, 0x38, 0x5a, + 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, 0x02, 0x30, 0x91, 0x94, 0x36, 0x21, + 0x17, 0xbf, 0x7a, 0x6c, 0x8d, 0x8e, 0xa3, 0x9e, 0x43, 0x75, 0x99, 0x7d, + 0x56, 0xee, 0x5b, 0x5b, 0xee, 0xc1, 0x1b, 0x57, 0xd4, 0x61, 0xda, 0xa8, + 0xc4, 0x89, 0x72, 0x49, 0xf2, 0xad, 0x75, 0x95, 0xa1, 0x2b, 0xa5, 0x20, + 0xda, 0x98, 0xce, 0x98, 0xe4, 0x8f, 0x38, 0xaf, 0x02, 0x13, 0x73, 0x2c, + 0xa3, 0xc5, 0xda, 0x17, 0x0f, 0x2d, 0x37, 0xb2, 0xce, 0x78, 0x42, 0xb0, + 0x72, 0x20, 0x90, 0xef, 0xd2, 0x20, 0xf5, 0xb0, 0x40, 0x11, 0xa3, 0x22, + 0x66, 0x2b, 0x93, 0xe0, 0x50, 0x25, 0x4c, 0x9a, 0x98, 0x20, 0xd3, 0xef, + 0xba, 0x3a, 0x4f, 0xb4, 0x87, 0xc0, 0xfc, 0xfc, 0xc4, 0x72, 0x1e, 0xfe, + 0x1f, 0x92, 0x79, 0xaf, 0x39, 0x79, 0x68, 0x47, 0x99, 0x79, 0x91, 0x67, + 0x47, 0xe8, 0x57, 0xdb, 0x86, 0xd7, 0x29, 0x38, 0xc1, 0x25, 0x3e, 0x68, + 0xda, 0x4d, 0xf0, 0x38, 0x68, 0x73, 0x51, 0x8f, 0x3e, 0xf9, 0x67, 0x78, + 0xba, 0xf2, 0xff, 0x47, 0x83, 0x18, 0x93, 0x82, 0x32, 0x9d, 0x4c, 0x34, + 0x8f, 0x72, 0x42, 0x8a, 0x20, 0xb2, 0x67, 0xac, 0xaa, 0xe2, 0xbd, 0x5b, + 0x1f, 0xdb, 0xe8, 0xc0, 0x21, 0xc9, 0x62, 0xf0, 0x59, 0x8e, 0xd5, 0x02, + 0xfd, 0xe2, 0x5f, 0x27, 0xe3, 0x10, 0x79, 0xed, 0x66, 0x9d, 0xcf, 0x9a, + 0xca, 0x2d, 0x92, 0xbf, 0x25, 0xba, 0xb5, 0xda, 0x81, 0x71, 0x41, 0x3d, + 0x4c, 0x4f, 0x37, 0x72, 0x59, 0xb1, 0xae, 0x2b, 0x6d, 0x77, 0xda, 0x1c, + 0x06, 0xb6, 0xa5, 0x67, 0x4e, 0x67, 0x8a, 0xb9, 0x75, 0x3b, 0x41, 0x55, + 0x66, 0x41, 0x8b, 0x07, 0xde, 0xa4, 0xa7, 0xd9, 0x97, 0x06, 0x43, 0xec, + 0x65, 0xe6, 0xfd, 0x7a, 0xc3, 0xb3, 0x19, 0x14, 0x2f, 0xe6, 0x98, 0x89, + 0xf7, 0x40, 0xd7, 0x56, 0xdb, 0xf2, 0x5a, 0x88, 0x27, 0xeb, 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, 0x34, 0x31, 0x32, 0x31, 0x38, 0x32, 0x31, 0x32, + 0x35, 0x33, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x39, 0x31, 0x34, + 0x32, 0x31, 0x32, 0x35, 0x33, 0x31, 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, 0x4d, 0xa2, 0xd8, 0x55, + 0xe0, 0x2b, 0xf4, 0xad, 0x65, 0xe2, 0x92, 0x35, 0xcb, 0x60, 0xa0, 0xa2, + 0x6b, 0xa6, 0x88, 0xc1, 0x86, 0x58, 0x57, 0x37, 0xbd, 0x2e, 0x28, 0x6e, + 0x1c, 0x56, 0x2a, 0x35, 0xde, 0xff, 0x3e, 0x8e, 0x3d, 0x47, 0x21, 0x1a, + 0xe9, 0xd3, 0xc6, 0xb4, 0xe2, 0xcb, 0x3e, 0xc6, 0xaf, 0x9b, 0xef, 0x23, + 0x88, 0x56, 0x95, 0x73, 0x2e, 0xb3, 0xed, 0xc5, 0x11, 0x4b, 0x69, 0xf7, + 0x13, 0x3a, 0x05, 0xe1, 0xaf, 0xba, 0xc9, 0x59, 0xfd, 0xe2, 0xa0, 0x81, + 0xa0, 0x4c, 0x0c, 0x2c, 0xcb, 0x57, 0xad, 0x96, 0x3a, 0x8c, 0x32, 0xa6, + 0x4a, 0xf8, 0x72, 0xb8, 0xec, 0xb3, 0x26, 0x69, 0xd6, 0x6a, 0x4c, 0x4c, + 0x78, 0x18, 0x3c, 0xca, 0x19, 0xf1, 0xb5, 0x8e, 0x23, 0x81, 0x5b, 0x27, + 0x90, 0xe0, 0x5c, 0x2b, 0x17, 0x4d, 0x78, 0x99, 0x6b, 0x25, 0xbd, 0x2f, + 0xae, 0x1b, 0xaa, 0xce, 0x84, 0xb9, 0x44, 0x21, 0x46, 0xc0, 0x34, 0x6b, + 0x5b, 0xb9, 0x1b, 0xca, 0x5c, 0x60, 0xf1, 0xef, 0xe6, 0x66, 0xbc, 0x84, + 0x63, 0x56, 0x50, 0x7d, 0xbb, 0x2c, 0x2f, 0x7b, 0x47, 0xb4, 0xfd, 0x58, + 0x77, 0x87, 0xee, 0x27, 0x20, 0x96, 0x72, 0x8e, 0x4c, 0x7e, 0x4f, 0x93, + 0xeb, 0x5f, 0x8f, 0x9c, 0x1e, 0x59, 0x7a, 0x96, 0xaa, 0x53, 0x77, 0x22, + 0x41, 0xd8, 0xd3, 0xf9, 0x89, 0x8f, 0xe8, 0x9d, 0x65, 0xbd, 0x0c, 0x71, + 0x3c, 0xbb, 0xa3, 0x07, 0xbf, 0xfb, 0xa8, 0xd1, 0x18, 0x0a, 0xb4, 0xc4, + 0xf7, 0x83, 0xb3, 0x86, 0x2b, 0xf0, 0x5b, 0x05, 0x28, 0xc1, 0x01, 0x31, + 0x73, 0x5c, 0x2b, 0xbd, 0x60, 0x97, 0xa3, 0x36, 0x82, 0x96, 0xd7, 0x83, + 0xdf, 0x75, 0xee, 0x29, 0x42, 0x97, 0x86, 0x41, 0x55, 0xb9, 0x70, 0x87, + 0xd5, 0x02, 0x85, 0x13, 0x41, 0xf8, 0x25, 0x05, 0xab, 0x6a, 0xaa, 0x57, +}; + unsigned char ocsp_responder_cert_pem[] = { 0x30, 0x82, 0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ae5bab5b018..4258f7edaeb 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -25926,13 +25926,17 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, } #ifdef HAVE_OCSP - if (verify != NO_VERIFY && type != CA_TYPE && + if (type != CA_TYPE && type != TRUSTED_PEER_TYPE) { + /* Need the CA's public key hash for OCSP */ if (cert->ca) { - /* Need the CA's public key hash for OCSP */ XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash, KEYID_SIZE); } + else if (cert->selfSigned) { + XMEMCPY(cert->issuerKeyHash, cert->subjectKeyHash, + KEYID_SIZE); + } } #endif /* HAVE_OCSP */ } @@ -39504,7 +39508,6 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, ret = 0; } } - else #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */ if (!noVerifySignature && !sigValid) { Signer* ca; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 0b328408baa..0d0a78226d0 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -3970,7 +3970,7 @@ time_t stm32_hal_time(time_t *t1) #if (!defined(WOLFSSL_LEANPSK) && !defined(STRING_USER)) || \ defined(USE_WOLF_STRNSTR) -char* mystrnstr(const char* s1, const char* s2, unsigned int n) +char* wolfSSL_strnstr(const char* s1, const char* s2, unsigned int n) { unsigned int s2_len = (unsigned int)XSTRLEN(s2); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0faf0bdc42c..a2798c8ae1d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2446,10 +2446,8 @@ struct WOLFSSL_OCSP { OcspEntry* ocspList; /* OCSP response list */ wolfSSL_Mutex ocspLock; /* OCSP list lock */ int error; -#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \ - defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) int(*statusCb)(WOLFSSL*, void*); -#endif + void* statusCbArg; }; #endif @@ -2686,6 +2684,7 @@ typedef struct ProcPeerCertArgs { int count; int certIdx; int lastErr; + int leafVerifyErr; #ifdef WOLFSSL_TLS13 byte ctxSz; #endif @@ -3288,6 +3287,9 @@ WOLFSSL_LOCAL int TLSX_CSR_Write_ex(CertificateStatusRequest* csr, byte* output, byte isRequest, int idx); WOLFSSL_LOCAL void* TLSX_CSR_GetRequest_ex(TLSX* extensions, int idx); +WOLFSSL_LOCAL int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl); +WOLFSSL_LOCAL int ProcessChainOCSPRequest(WOLFSSL* ssl); + #endif #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) @@ -3747,6 +3749,7 @@ struct WOLFSSL_CTX { #ifndef NO_CERTS DerBuffer* certificate; DerBuffer* certChain; + int certChainCnt; /* chain after self, in DER, with leading size for each cert */ #ifndef WOLFSSL_NO_CA_NAMES WOLF_STACK_OF(WOLFSSL_X509_NAME)* client_ca_names; @@ -3754,12 +3757,13 @@ struct WOLFSSL_CTX { #endif #ifdef OPENSSL_EXTRA WOLF_STACK_OF(WOLFSSL_X509)* x509Chain; + #endif +#ifdef WOLFSSL_CERT_SETUP_CB +#ifdef OPENSSL_EXTRA client_cert_cb CBClientCert; /* client certificate callback */ +#endif CertSetupCallback certSetupCb; void* certSetupCbArg; - #endif -#ifdef WOLFSSL_TLS13 - int certChainCnt; #endif DerBuffer* privateKey; #ifdef WOLFSSL_BLIND_PRIVATE_KEY @@ -4014,6 +4018,8 @@ struct WOLFSSL_CTX { #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) OcspRequest* certOcspRequest; + ocspVerifyStatusCb ocspStatusVerifyCb; + void* ocspStatusVerifyCbArg; #endif #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) OcspRequest* chainOcspRequest[MAX_CHAIN_DEPTH]; @@ -4820,8 +4826,8 @@ typedef struct Buffers { #endif DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ -#ifdef WOLFSSL_TLS13 int certChainCnt; +#ifdef WOLFSSL_TLS13 DerBuffer* certExts[MAX_CERT_EXTENSIONS]; #endif #endif @@ -6110,9 +6116,8 @@ struct WOLFSSL { void* ocspIOCtx; byte ocspProducedDate[MAX_DATE_SZ]; int ocspProducedDateFormat; + buffer ocspCsrResp[1 + MAX_CHAIN_DEPTH]; #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) - byte* ocspResp; - int ocspRespSz; char* url; #endif #if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST) diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h index a887299d12e..3882ad83b3d 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -77,6 +77,14 @@ WOLFSSL_LOCAL int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int resp WOLFSSL_LOCAL int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp); +/* Allocates and initializes a WOLFSSL_OCSP object */ +WOLFSSL_API WOLFSSL_OCSP* wc_NewOCSP(WOLFSSL_CERT_MANAGER* cm); +/* Frees a WOLFSSL_OCSP object allocated by wc_NewOCSP */ +WOLFSSL_API void wc_FreeOCSP(WOLFSSL_OCSP* ocsp); +WOLFSSL_API int wc_CheckCertOcspResponse(WOLFSSL_OCSP *ocsp, DecodedCert *cert, + byte *response, int responseSz, void* heap); + + #ifdef OPENSSL_EXTRA WOLFSSL_API int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs, WOLFSSL_OCSP_CERTID *id, int *status, int *reason, diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 582f9b75457..5b251c0c41d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1405,6 +1405,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define SSL_CTX_get_tlsext_ticket_keys wolfSSL_CTX_get_tlsext_ticket_keys #define SSL_CTX_set_tlsext_ticket_keys wolfSSL_CTX_set_tlsext_ticket_keys #define SSL_CTX_get_tlsext_status_cb wolfSSL_CTX_get_tlsext_status_cb +#define SSL_CTX_set_tlsext_status_arg wolfSSL_CTX_set_tlsext_status_arg #define SSL_CTX_set_tlsext_status_cb wolfSSL_CTX_set_tlsext_status_cb #define SSL_CTX_set_num_tickets wolfSSL_CTX_set_num_tickets #define SSL_CTX_get_num_tickets wolfSSL_CTX_get_num_tickets @@ -1581,9 +1582,9 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define SSL3_AL_FATAL 2 #define SSL_TLSEXT_ERR_OK 0 -#define SSL_TLSEXT_ERR_ALERT_WARNING warning_return -#define SSL_TLSEXT_ERR_ALERT_FATAL fatal_return -#define SSL_TLSEXT_ERR_NOACK noack_return +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 #define TLSEXT_NAMETYPE_host_name WOLFSSL_SNI_HOST_NAME #define SSL_set_tlsext_host_name wolfSSL_set_tlsext_host_name @@ -1720,7 +1721,6 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define SSL_in_connect_init wolfSSL_SSL_in_connect_init #define SSL_get0_session wolfSSL_SSL_get0_session #define SSL_CTX_set_tlsext_ticket_key_cb wolfSSL_CTX_set_tlsext_ticket_key_cb -#define SSL_CTX_set_tlsext_status_cb wolfSSL_CTX_set_tlsext_status_cb #define SSL_CTX_get_extra_chain_certs wolfSSL_CTX_get_extra_chain_certs #define SSL_CTX_get0_chain_certs wolfSSL_CTX_get0_chain_certs #define SSL_get0_chain_certs wolfSSL_get0_chain_certs diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 8f370ee1a53..8c0c0d1d8de 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1840,13 +1840,36 @@ WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long e); WOLFSSL_API const char* wolfSSL_ERR_func_error_string(unsigned long e); WOLFSSL_API const char* wolfSSL_ERR_lib_error_string(unsigned long e); -/* -------- EXTRAS BEGIN -------- */ -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ - defined(WOLFSSL_EXTRA) WOLFSSL_API int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx); WOLFSSL_API int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx); +/* -------- EXTRAS BEGIN -------- */ + +#ifdef WOLFSSL_CERT_SETUP_CB +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) +typedef int (*client_cert_cb)(WOLFSSL *ssl, WOLFSSL_X509 **x509, + WOLFSSL_EVP_PKEY **pkey); +WOLFSSL_API void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb); #endif +typedef int (*CertSetupCallback)(WOLFSSL* ssl, void*); +WOLFSSL_API void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, + CertSetupCallback cb, void *arg); +WOLFSSL_API int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, + const byte** suites, word16* suiteSz, + const byte** hashSigAlgo, word16* hashSigAlgoSz); +typedef struct WOLFSSL_CIPHERSUITE_INFO { + WC_BITFIELD rsaAuth:1; + WC_BITFIELD eccAuth:1; + WC_BITFIELD eccStatic:1; + WC_BITFIELD psk:1; +} WOLFSSL_CIPHERSUITE_INFO; +WOLFSSL_API WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, + byte second); +WOLFSSL_API int wolfSSL_get_sigalg_info(byte first, + byte second, int* hashAlgo, int* sigAlgo); +WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl); +#endif /* WOLFSSL_CERT_SETUP_CB */ + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) WOLFSSL_API void wolfSSL_ERR_print_errors(WOLFSSL_BIO *bio); @@ -2438,28 +2461,6 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_get0_peer_CA_list( const WOLFSSL *ssl); #endif /* !WOLFSSL_NO_CA_NAMES */ -typedef int (*client_cert_cb)(WOLFSSL *ssl, WOLFSSL_X509 **x509, - WOLFSSL_EVP_PKEY **pkey); -WOLFSSL_API void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb); - -typedef int (*CertSetupCallback)(WOLFSSL* ssl, void*); -WOLFSSL_API void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, - CertSetupCallback cb, void *arg); -WOLFSSL_API int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, - const byte** suites, word16* suiteSz, - const byte** hashSigAlgo, word16* hashSigAlgoSz); -typedef struct WOLFSSL_CIPHERSUITE_INFO { - WC_BITFIELD rsaAuth:1; - WC_BITFIELD eccAuth:1; - WC_BITFIELD eccStatic:1; - WC_BITFIELD psk:1; -} WOLFSSL_CIPHERSUITE_INFO; -WOLFSSL_API WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, - byte second); -WOLFSSL_API int wolfSSL_get_sigalg_info(byte first, - byte second, int* hashAlgo, int* sigAlgo); -WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl); - WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( WOLFSSL_X509_STORE_CTX* ctx, int idx); WOLFSSL_API int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, @@ -2543,7 +2544,6 @@ WOLFSSL_API int wolfSSL_get_read_ahead(const WOLFSSL* ssl); WOLFSSL_API int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v); WOLFSSL_API int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v); -WOLFSSL_API long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg); WOLFSSL_API long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg( WOLFSSL_CTX* ctx, void* arg); WOLFSSL_API int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509); @@ -2564,8 +2564,6 @@ WOLFSSL_API long wolfSSL_get_tlsext_status_type(WOLFSSL *s); WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg); WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg); WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg); -WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp); -WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len); WOLFSSL_API int wolfSSL_set_tlsext_max_fragment_length (WOLFSSL *s, unsigned char mode); WOLFSSL_API int wolfSSL_CTX_set_tlsext_max_fragment_length @@ -5659,6 +5657,27 @@ WOLFSSL_API long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx); WOLFSSL_API long wolfSSL_get_timeout(WOLFSSL* ssl); #endif +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) +#define WOLFSSL_OCSP_STATUS_CB_OK 0 +#define WOLFSSL_OCSP_STATUS_CB_ALERT_WARNING 1 +#define WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL 2 +#define WOLFSSL_OCSP_STATUS_CB_NOACK 3 +typedef int(*tlsextStatusCb)(WOLFSSL* ssl, void*); +WOLFSSL_API int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb); +WOLFSSL_API int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb); +WOLFSSL_API long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg); +WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char **resp); +WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *ssl, unsigned char *resp, int len); +WOLFSSL_API int wolfSSL_set_tlsext_status_ocsp_resp_multi(WOLFSSL* ssl, unsigned char *resp, + int len, word32 idx); +typedef int(*ocspVerifyStatusCb)(WOLFSSL* ssl, int err, byte* resp, word32 respSz, + word32 idx, void* arg); +/* This callback is only useful when SESSION_CERTS is enabled */ +WOLFSSL_API void wolfSSL_CTX_set_ocsp_status_verify_cb(WOLFSSL_CTX* ctx, + ocspVerifyStatusCb cb, void* cbArg); +#endif + #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \ || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) WOLFSSL_API WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl); @@ -5700,14 +5719,10 @@ typedef int (*ticketCompatCb)(WOLFSSL *ssl, unsigned char *name, unsigned char * WOLFSSL_API int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX* ctx, ticketCompatCb cb); #endif -#if defined(HAVE_OCSP) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLFSSL_API int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain); -typedef int(*tlsextStatusCb)(WOLFSSL* ssl, void*); -WOLFSSL_API int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb); -WOLFSSL_API int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb); - WOLFSSL_API int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx, WOLF_STACK_OF(WOLFSSL_X509) **sk); WOLFSSL_API int wolfSSL_get0_chain_certs(WOLFSSL *ssl, diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 153e301a075..0c064623b15 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1356,7 +1356,7 @@ #define XSTRLEN(s1) uStrlen((s1)) #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) #define XSTRSTR(s1,s2) strstr((s1),(s2)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) @@ -3858,6 +3858,9 @@ extern void uITRON4_free(void *p) ; #undef WOLFSSL_SESSION_ID_CTX #define WOLFSSL_SESSION_ID_CTX + + #undef WOLFSSL_CERT_SETUP_CB + #define WOLFSSL_CERT_SETUP_CB #endif /* OPENSSL_EXTRA */ #ifdef OPENSSL_EXTRA_X509_SMALL diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index e4be257aef1..8bf86bda786 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -802,7 +802,7 @@ enum { /* strstr, strncmp, strcmp, and strncat only used by wolfSSL proper, * not required for wolfCrypt only */ #define XSTRSTR(s1,s2) strstr((s1),(s2)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + #define XSTRNSTR(s1,s2,n) wolfSSL_strnstr((s1),(s2),(n)) #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) #define XSTRCMP(s1,s2) strcmp((s1),(s2)) #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index bad52a98937..6cdf8c656bb 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1182,7 +1182,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); #define XCLEARERR(fp) WC_DO_NOTHING #endif - WOLFSSL_LOCAL int wc_FileLoad(const char* fname, unsigned char** buf, + WOLFSSL_API int wc_FileLoad(const char* fname, unsigned char** buf, size_t* bufLen, void* heap); #if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_NUCLEUS) && \ @@ -1603,7 +1603,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); #if (!defined(WOLFSSL_LEANPSK) && !defined(STRING_USER)) || \ defined(USE_WOLF_STRNSTR) - char* mystrnstr(const char* s1, const char* s2, unsigned int n); + WOLFSSL_TEST_VIS char* wolfSSL_strnstr(const char* s1, const char* s2, unsigned int n); #endif #ifndef FILE_BUFFER_SIZE