From 6940aa6d96d3a9fc492fb06b8a7acf1a22e0e690 Mon Sep 17 00:00:00 2001 From: Mattia Moffa Date: Fri, 7 Aug 2026 22:11:44 +0200 Subject: [PATCH] Keep out CAs from cert manager if allowed only by callback When an application's verify callback overrides ASN_NO_SIGNER_E or ASN_SELF_SIGNED_E on a cert, DoVerifyCallback() clears ret. ProcessPeerCerts() then reads ret==0 as proof that the CA is valid and calls AddCA() to add it to the WOLFSSL_CTX certificate manager. Instead, the callback allowing a CA is meant to be a one-time exception. This fix records the real certificate verification result and skips AddCA() if the callback is what cleared a trust error. Other types of errors don't prevent AddCA() because in those cases the cert is still trusted. All of this is only relevant when WOLFSSL_ALT_CERT_CHAINS is not enabled, because the alt cert chains logic sets skipAddCA on an unverified cert before even doing the callback logic. --- src/internal.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/internal.c b/src/internal.c index f5400c2088..d0a332b944 100644 --- a/src/internal.c +++ b/src/internal.c @@ -17999,6 +17999,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* WOLFSSL_TRUST_PEER_CERT */ ) { int skipAddCA = 0; + int preCbRet; /* select last certificate */ args->certIdx = args->count - 1; @@ -18261,7 +18262,13 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) */ /* Do verify callback */ + preCbRet = ret; ret = DoVerifyCallback(SSL_CM(ssl), ssl, ret, args); + if (ret == 0 && + (preCbRet == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E) || + preCbRet == WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E))) { + skipAddCA = 1; + } if (ssl->options.verifyNone && (ret == WC_NO_ERR_TRACE(CRL_MISSING) || ret == WC_NO_ERR_TRACE(CRL_CERT_REVOKED) ||