From 5e4ae820ed450772d2311c3bda219dc55904ba47 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Tue, 22 Oct 2024 15:10:18 -0700 Subject: [PATCH] Restore proper error code handling for self signed CA in non-trusted intermediates --- src/x509_str.c | 20 ++++++++++++++++++++ tests/api.c | 8 ++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/x509_str.c b/src/x509_str.c index f85d023b18..44e104ba6b 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -305,6 +305,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) int depth = 0; WOLFSSL_X509 *issuer = NULL; WOLFSSL_X509 *orig = NULL; + WOLFSSL_X509 *tmp = NULL; WOLF_STACK_OF(WOLFSSL_X509)* certs = NULL; WOLFSSL_ENTER("wolfSSL_X509_verify_cert"); @@ -355,6 +356,25 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) /* Try to find an untrusted issuer first */ ret = X509StoreGetIssuerEx(&issuer, certs, ctx->current_cert); + if (issuer != NULL && + wolfSSL_X509_NAME_cmp(&issuer->issuer, &issuer->subject) == 0) { + ret = WOLFSSL_FAILURE; + /* Self signed allowed if in set trusted stack, otherwise + * ignore it and fall back to see if its in CM */ + if ((certs == ctx->setTrustedSk) && + (wolfSSL_sk_X509_num(certs) > numInterAdd)) { + for (i = wolfSSL_sk_X509_num(certs) - 1; + i > (numInterAdd > 0 ? numInterAdd - 1 : 0); + i++) { + tmp = wolfSSL_sk_X509_value(certs, i); + if (wolfSSL_X509_NAME_cmp( + &issuer->subject, &tmp->subject) == 0) { + ret = WOLFSSL_SUCCESS; + break; + } + } + } + } if (ret == WOLFSSL_SUCCESS) { if (ctx->current_cert == issuer) { wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert); diff --git a/tests/api.c b/tests/api.c index dbacd64ed9..bcd24ad3c8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -60407,10 +60407,14 @@ static int test_X509_STORE_untrusted(void) /* Succeeds because path to loaded CA is available. */ ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted2, 1, 0, 1), TEST_SUCCESS); - /* Root CA in untrusted chain is OK */ + /* Root CA in untrusted chain is OK so long as CA has been loaded + * properly */ ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 1, 0, 1), TEST_SUCCESS); - ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 1, 0, 0), + /* Still needs properly loaded CA, while including it in untrusted + * list is not an error, it also doesnt count for verify */ + ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted3, 0, + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, 0), TEST_SUCCESS); /* Succeeds because path to loaded CA is available. */ ExpectIntEQ(test_X509_STORE_untrusted_certs(untrusted4, 1, 0, 1),