ocsp: don't error out if we can't verify our certificate

We can omit either the CeritificateStatus message or the appropriate extension when we can not provide the OCSP staple that the peer is asking for. Let peer decide if it requires stapling and error out if we don't send it.
This commit is contained in:
Juliusz Sosinowicz
2023-12-08 17:38:26 +01:00
parent 1aed438a21
commit 51ba745214
4 changed files with 135 additions and 23 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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),