diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index c676c15524..b182ed57c0 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -955,6 +955,7 @@ WOLFSSL_WC_SLHDSA_RECURSIVE WOLFSSL_WC_XMSS_NO_SHA256 WOLFSSL_WC_XMSS_NO_SHAKE256 WOLFSSL_WICED_PSEUDO_UNIX_EPOCH_TIME +WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE WOLFSSL_X509_STORE_CERTS WOLFSSL_X509_TRUSTED_CERTIFICATE_CALLBACK WOLFSSL_XFREE_NO_NULLNESS_CHECK diff --git a/src/x509_str.c b/src/x509_str.c index 294a5a2eb2..068842a9c1 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -705,14 +705,18 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) /* We found our issuer in the non-trusted cert list, add it * to the CM and verify the current cert against it */ - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - /* OpenSSL doesn't allow the cert as CA if it is not CA:TRUE for - * intermediate certs. + #ifndef WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE + /* RFC 5280 6.1.3(k): a non-self-issued intermediate must have + * basicConstraints CA:TRUE to be used as a signing authority. + * Reject CA:FALSE intermediates here; the verify_cb (if any) + * may override. Define WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE + * to restore the legacy permissive behavior. */ if (!issuer->isCa) { /* error depth is current depth + 1 */ SetupStoreCtxError_ex(ctx, X509_V_ERR_INVALID_CA, (ctx->chain) ? (int)(ctx->chain->num + 1) : 1); + #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) if (ctx->store->verify_cb) { ret = ctx->store->verify_cb(0, ctx); if (ret != WOLFSSL_SUCCESS) { @@ -720,7 +724,9 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) goto exit; } } - else { + else + #endif + { ret = WOLFSSL_FAILURE; goto exit; } diff --git a/tests/api/test_ossl_x509_str.c b/tests/api/test_ossl_x509_str.c index b0756f8bbb..30612156c7 100644 --- a/tests/api/test_ossl_x509_str.c +++ b/tests/api/test_ossl_x509_str.c @@ -1144,7 +1144,8 @@ int test_X509_STORE_untrusted(void) return EXPECT_RESULT(); } -#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) +#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE) static int last_errcode; static int last_errdepth; @@ -1165,7 +1166,8 @@ static int X509Callback(int ok, X509_STORE_CTX *ctx) int test_X509_STORE_InvalidCa(void) { EXPECT_DECLS; -#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) +#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE) const char* filename = "./certs/intermediate/ca_false_intermediate/" "test_int_not_cacert.pem"; const char* srvfile = "./certs/intermediate/ca_false_intermediate/" @@ -1221,7 +1223,8 @@ int test_X509_STORE_InvalidCa(void) int test_X509_STORE_InvalidCa_NoCallback(void) { EXPECT_DECLS; -#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE) const char* filename = "./certs/intermediate/ca_false_intermediate/" "test_int_not_cacert.pem"; const char* srvfile = "./certs/intermediate/ca_false_intermediate/"