From f9063c406b5057428a76009c9206c355dd12f891 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 14 Aug 2025 12:14:55 +0200 Subject: [PATCH] Enables dynamic TLS cert loading with OCSP Exposes dynamic TLS certificate loading and OCSP stapling to allow applications to load certs lazily. The server no longer needs to load the CA to staple OCSP responses. Adds a certificate setup callback (WOLFSSL_CERT_SETUP_CB) Adds an OCSP status callback to load OCSP responses directly Adds `wc_NewOCSP`, `wc_FreeOCSP`, and `wc_CheckCertOcspResponse` Don't call verify twice on the same error Send correct alert on status response error --- .github/workflows/os-check.yml | 2 + IDE/GCC-ARM/Header/user_settings.h | 2 +- IDE/SimplicityStudio/user_settings.h | 2 +- IDE/WICED-STUDIO/user_settings.h | 2 +- IDE/WINCE/user_settings.h | 2 +- .../macOS-C++/Intel/user_settings.h | 2 +- IDE/XCODE-FIPSv2/macOS-C++/M1/user_settings.h | 2 +- IDE/XCODE-FIPSv2/user_settings.h | 2 +- IDE/XCODE-FIPSv5/user_settings.h | 2 +- IDE/XCODE-FIPSv6/user_settings.h | 2 +- configure.ac | 10 + doc/dox_comments/header_files/ocsp.h | 49 ++ doc/dox_comments/header_files/ssl.h | 230 +++++++++ examples/configs/user_settings_template.h | 2 +- src/internal.c | 237 +++++---- src/ocsp.c | 59 ++- src/ssl.c | 194 ++++---- src/ssl_load.c | 4 - src/tls.c | 137 +----- src/tls13.c | 84 +++- src/x509_str.c | 3 - tests/api.c | 120 +++-- tests/api/create_ocsp_test_blobs.py | 55 ++- tests/api/test_ocsp.c | 366 ++++++++++++++ tests/api/test_ocsp.h | 1 + tests/api/test_ocsp_test_blobs.h | 459 ++++++++++++++++++ wolfcrypt/src/asn.c | 9 +- wolfcrypt/src/wc_port.c | 2 +- wolfssl/internal.h | 23 +- wolfssl/ocsp.h | 8 + wolfssl/openssl/ssl.h | 8 +- wolfssl/ssl.h | 81 ++-- wolfssl/wolfcrypt/settings.h | 5 +- wolfssl/wolfcrypt/types.h | 2 +- wolfssl/wolfcrypt/wc_port.h | 4 +- 35 files changed, 1768 insertions(+), 404 deletions(-) create mode 100644 doc/dox_comments/header_files/ocsp.h diff --git a/.github/workflows/os-check.yml b/.github/workflows/os-check.yml index 81f071ccf..07b8272c2 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 2265ddb8b..d6b495432 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 ff6961bd7..d9f1031e3 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 0ba1d034e..2eec72ac0 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 bba21fcb0..8c1fa7329 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 82efed9db..7c95a574a 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 756eb5389..7669708c6 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 f67eb48b9..2e83871db 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 19edc9526..f475a3189 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 208f34e07..16166f1f2 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 802abaca5..e81eb771f 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 000000000..cd7966b84 --- /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 e6901921d..ee851963f 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 6a0af9b1d..c88cbc820 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 1834fdee4..153a746fb 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 f12166209..ed255aa91 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 78cb42a17..af639cc91 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 fac44a2e2..3ca77d7a7 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 18bdffb72..5759e344d 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 76a6b3977..c97ebffde 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 f10281397..28c428ed3 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 c22d02456..252e16182 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)); - func_cb_client.ctx_ready = certSetupCb; - func_cb_client.ssl_ready = certClearCb; - func_cb_server.ctx_ready = certSetupCb; - func_cb_server.ssl_ready = certClearCb; + printf("\tTesting with %s...\n", test_params[i].desc); - ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, - &func_cb_server, NULL), TEST_SUCCESS); + 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); + } #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 24847bf69..b615acbcf 100644 --- a/tests/api/create_ocsp_test_blobs.py +++ b/tests/api/create_ocsp_test_blobs.py @@ -9,7 +9,7 @@ from pyasn1.codec.der.decoder import decode 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 @@ if __name__ == '__main__': '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 997b99b12..bd529a800 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 67d30e78a..267809f5a 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 d0801afef..48f80caf6 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 ae5bab5b0..4258f7eda 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 0b328408b..0d0a78226 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 0faf0bdc4..a2798c8ae 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 a887299d1..3882ad83b 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 582f9b754..5b251c0c4 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 8f370ee1a..8c0c0d1d8 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 153e301a0..0c064623b 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 e4be257ae..8bf86bda7 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 bad52a989..6cdf8c656 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