-
Notifications
You must be signed in to change notification settings - Fork 917
Description
Contact Details
Version
5.8.4
Description
Configure flags:
./configure flags: --disable-shared --enable-static --prefix=/ '--bindir=${prefix}/bin' '--sbindir=${prefix}/bin' '--libdir=${prefix}/lib' '--includedir=${prefix}/include' '--oldincludedir=${prefix}/include' --disable-examples --disable-crypttests --enable-harden --enable-debug=yes --enable-opensslall=yes --enable-opensslextra=yes --enable-sslv3=no --enable-alpn=no --enable-des3=no --enable-tls13=yes --enable-certgen=no --enable-dsa=no --enable-ripemd=no --enable-sessioncerts=no --enable-sni=no --enable-testcert=no --enable-shared=no --enable-static=yes --enable-asio --enable-altcertchains --enable-sys-ca-certs CC=/opt/homebrew/opt/llvm@20/bin/clang 'CFLAGS= -fPIC -g -mmacosx-version-min=15.0 -DWOLFSSL_APPLE_NATIVE_CERT_VALIDATION -framework CoreFoundation -framework Security' 'LDFLAGS= -mmacosx-version-min=15.0' CPPFLAGS=
Hey,
When the support for System Certificate Store is enabled on Apple platforms, and the validation of the peer cert chain against the CAs loaded into wolfSSL fails, wolfSSL wants to validate it against the system certificates using Apple's native trust APIs:
#if defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS)
/* If we can't validate the peer cert chain against the CAs loaded
* into wolfSSL, try to validate against the system certificates
* using Apple's native trust APIs */
if ((ret == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E)) &&
(ssl->ctx->doAppleNativeCertValidationFlag)) {
if (DoAppleNativeCertValidation(ssl, args->certs,
args->totalCerts)) {
WOLFSSL_MSG("Apple native cert chain validation SUCCESS");
ret = 0;
}
else {
WOLFSSL_MSG("Apple native cert chain validation FAIL");
}
}
#endif /* defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) */
/* Do leaf verify callback when it wasn't called yet */
if (ret == 0 || ret != args->leafVerifyErr)
ret = DoVerifyCallback(SSL_CM(ssl), ssl, ret, args);
To make it happen, the ret must be equal to ASN_NO_SIGNER_E. However, the value will never be equal to ASN_NO_SIGNER_E if the verify callback is set and returns true because it will be overwritten here:
/* Do verify callback. */
args->leafVerifyErr = ret =
DoVerifyCallback(SSL_CM(ssl), ssl, ret, args);
#if defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS)
/* Disregard failure to verify peer cert, as we will verify
* the whole chain with the native API later */
if (ssl->ctx->doAppleNativeCertValidationFlag) {
WOLFSSL_MSG("\tApple native CA validation override"
" available, will continue");
/* check if fatal error */
args->fatal = (args->verifyErr) ? 1 : 0;
if (args->fatal)
DoCertFatalAlert(ssl, ret);
}
and the native cert validation will never be called.
The value of ret may be retained only if the verify callback fails, but then args->verifyErr is set and we end up here:
args->fatal = (args->verifyErr) ? 1 : 0;
if (args->fatal)
DoCertFatalAlert(ssl, ret);
The ret can also be retained if the verify callback is not set at all.
Is it intended behaviour? It was introduced within this #9144.
I believe it can be fixed like this:
/* Do verify callback. */
args->leafVerifyErr = ret =
DoVerifyCallback(SSL_CM(ssl), ssl, ret, args);
#if defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS)
/* Disregard failure to verify peer cert, as we will verify
* the whole chain with the native API later */
if (ssl->ctx->doAppleNativeCertValidationFlag) {
WOLFSSL_MSG("\tApple native CA validation override"
" available, will continue");
/* check if fatal error */
if (ret != 0 && ret != WC_NO_ERR_TRACE(ASN_NO_SIGNER_E)) {
args->fatal = (args->verifyErr) ? 1 : 0;
if (args->fatal)
DoCertFatalAlert(ssl, ret);
}
}
Reproduction steps
No response