diff --git a/scripts/ocsp-stapling.test b/scripts/ocsp-stapling.test index cdc03f569..c14fbf0e7 100755 --- a/scripts/ocsp-stapling.test +++ b/scripts/ocsp-stapling.test @@ -243,16 +243,18 @@ else OPENSSL_RESULT=$? echo "$OPENSSL_OUTPUT" fgrep -q 'self signed certificate in certificate chain' <<< "$OPENSSL_OUTPUT" - FGREP_RESULT=$? - if [ $OPENSSL_RESULT -eq 0 -a $FGREP_RESULT -ne 0 ]; then + FGREP1_RESULT=$? + fgrep -q 'self-signed certificate in certificate chain' <<< "$OPENSSL_OUTPUT" + FGREP2_RESULT=$? + if [ $OPENSSL_RESULT -eq 0 -a $FGREP1_RESULT -ne 0 -a $FGREP2_RESULT -ne 0 ]; then printf '%s\n' "Expected verification error from s_client is missing." remove_single_rF "$ready_file" exit 1 fi remove_single_rF "$ready_file" wait $wolf_pid - if [ $? -ne 1 ]; then - printf '%s\n' "wolfSSL server unexpected fail value" + if [ $? -ne 0 ]; then + printf '%s\n' "wolfSSL server unexpected fail" exit 1 fi fi diff --git a/src/internal.c b/src/internal.c index fec764be5..23aab852e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -15972,43 +15972,44 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E); return OUT_OF_ORDER_E; } +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) if (ssl->msgsReceived.got_certificate_status == 0) { + int csrRet = 0; #ifdef HAVE_CERTIFICATE_STATUS_REQUEST - if (ssl->status_request) { - int ret; - + if (csrRet == 0 && ssl->status_request) { WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange"); - if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0) - return ret; + csrRet = TLSX_CSR_ForceRequest(ssl); } #endif #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 - if (ssl->status_request_v2) { - int ret; - + if (csrRet == 0 && ssl->status_request_v2) { WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange"); - if ((ret = TLSX_CSR2_ForceRequest(ssl)) != 0) - return ret; + csrRet = TLSX_CSR2_ForceRequest(ssl); } #endif -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ - defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (csrRet != 0) { + /* Error out if OCSP lookups are enabled and failed or if + * the user requires stapling. */ + if (SSL_CM(ssl)->ocspEnabled || SSL_CM(ssl)->ocspMustStaple) + return csrRet; + } /* Check that a status request extension was seen as the * CertificateStatus wasn't when an OCSP staple is required. */ if ( - #ifdef HAVE_CERTIFICATE_STATUS_REQUEST +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST !ssl->status_request && - #endif - #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +#endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 !ssl->status_request_v2 && - #endif +#endif SSL_CM(ssl)->ocspMustStaple) { WOLFSSL_ERROR_VERBOSE(OCSP_CERT_UNKNOWN); return OCSP_CERT_UNKNOWN; } - #endif } +#endif break; #endif @@ -23298,8 +23299,12 @@ int SendCertificateStatus(WOLFSSL* ssl) if (ret == 0 && response.buffer) { ret = BuildCertificateStatus(ssl, status_type, &response, 1); - } + + /* Let's not error out the connection if we can't verify our cert */ + if (ret == ASN_SELF_SIGNED_E || ret == ASN_NO_SIGNER_E) + ret = 0; + if (response.buffer) { XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); response.buffer = NULL; @@ -23428,6 +23433,10 @@ int SendCertificateStatus(WOLFSSL* ssl) } } + /* Let's not error out the connection if we can't verify our cert */ + if (ret == ASN_SELF_SIGNED_E || ret == ASN_NO_SIGNER_E) + ret = 0; + break; } #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ diff --git a/src/tls.c b/src/tls.c index 919aa9332..48d76dfa2 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3307,9 +3307,13 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, InitDecodedCert(cert, ssl->buffers.certificate->buffer, ssl->buffers.certificate->length, ssl->heap); ret = ParseCert(cert, CERT_TYPE, 1, SSL_CM(ssl)); - if (ret != 0 ) { + 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 == ASN_SELF_SIGNED_E || ret == ASN_NO_SIGNER_E) + ret = 0; return ret; } ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap); diff --git a/tests/api.c b/tests/api.c index 939924444..ccf1069b3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -68693,6 +68693,102 @@ static int test_dtls13_early_data(void) return EXPECT_RESULT(); } +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST +static int test_self_signed_stapling_client_v1_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1); + ExpectIntEQ(wolfSSL_CTX_UseOCSPStapling(ctx, WOLFSSL_CSR_OCSP, + WOLFSSL_CSR_OCSP_USE_NONCE), 1); + return EXPECT_RESULT(); +} +#endif + +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 +static int test_self_signed_stapling_client_v2_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1); + ExpectIntEQ(wolfSSL_CTX_UseOCSPStaplingV2(ctx, WOLFSSL_CSR2_OCSP, + WOLFSSL_CSR2_OCSP_USE_NONCE), 1); + return EXPECT_RESULT(); +} + +static int test_self_signed_stapling_client_v2_multi_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1); + ExpectIntEQ(wolfSSL_CTX_UseOCSPStaplingV2(ctx, WOLFSSL_CSR2_OCSP_MULTI, + 0), 1); + return EXPECT_RESULT(); +} +#endif + +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) +static int test_self_signed_stapling_server_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1); + return EXPECT_RESULT(); +} +#endif + +static int test_self_signed_stapling(void) +{ + EXPECT_DECLS; +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + test_ssl_cbf client_cbf; + test_ssl_cbf server_cbf; + size_t i; + struct { + method_provider client_meth; + method_provider server_meth; + ctx_cb client_ctx; + const char* tls_version; + } params[] = { +#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST) + { wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, + test_self_signed_stapling_client_v1_ctx_ready, "TLSv1_3 v1" }, +#endif +#ifndef WOLFSSL_NO_TLS12 +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, + test_self_signed_stapling_client_v1_ctx_ready, "TLSv1_2 v1" }, +#endif +#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, + test_self_signed_stapling_client_v2_ctx_ready, "TLSv1_2 v2" }, + { wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, + test_self_signed_stapling_client_v2_multi_ctx_ready, + "TLSv1_2 v2 multi" }, +#endif +#endif + }; + + for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) { + XMEMSET(&client_cbf, 0, sizeof(client_cbf)); + XMEMSET(&server_cbf, 0, sizeof(server_cbf)); + + printf("\nTesting self-signed cert with status request: %s\n", + params[i].tls_version); + + client_cbf.method = params[i].client_meth; + client_cbf.ctx_ready = params[i].client_ctx; + + server_cbf.method = params[i].server_meth; + server_cbf.certPemFile = "certs/ca-cert.pem"; + server_cbf.keyPemFile = "certs/ca-key.pem"; + server_cbf.ctx_ready = test_self_signed_stapling_server_ctx_ready; + + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf, + &server_cbf, NULL), TEST_SUCCESS); + } +#endif + return EXPECT_RESULT(); +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -69886,6 +69982,7 @@ TEST_CASE testCases[] = { /* OCSP Stapling */ TEST_DECL(test_wolfSSL_UseOCSPStapling), TEST_DECL(test_wolfSSL_UseOCSPStaplingV2), + TEST_DECL(test_self_signed_stapling), /* Multicast */ TEST_DECL(test_wolfSSL_mcast),