Copy the RSA public key onto the CA Signer in static-memory builds

ParseCert() guarded its RSA public-key copy with !WOLFSSL_NO_MALLOC,
while StoreKey() guards the equivalent copy for every non-RSA key with
!WC_ASN_NO_HEAP. Those are not the same condition: WC_ASN_NO_HEAP is
auto-defined only when WOLFSSL_NO_MALLOC and NO_WOLFSSL_MEMORY are set
without XMALLOC_USER or WOLFSSL_STATIC_MEMORY, so a static-memory build
defines WOLFSSL_NO_MALLOC yet still has a working allocator.

In such a build the copy was skipped, cert->pubKeyStored stayed 0, and
FillSigner() therefore never populated signer->publicKey/pubKeySize.
ParseCertRelative() then passed a NULL key and a zero key size to
ConfirmSignature(), which rejects them with BAD_FUNC_ARG before its
WOLFSSL_ENTER. The effect was that no certificate issued by an RSA CA
could be verified against it - wolfSSL_CertManagerVerifyBuffer() and TLS
peer validation alike - while ECC, Ed25519, Ed448 and ML-DSA CAs worked,
because those keys travel through StoreKey().

Use WC_ASN_NO_HEAP in all three guards, including the one on the ptr
declaration. FreeDecodedCert() and FreeSigner() already key off
pubKeyStored, so ownership and freeing are unchanged.

Point the MC/DC white-box guard for this block at WC_ASN_NO_HEAP too. It
still keyed off WOLFSSL_NO_MALLOC, so in a static-memory build the copy is
now compiled and executed while the section covering it fell back to its
stub, and the coverage claim was inaccurate for the one configuration this
fixes.
pull/11432/head
Tobias Frauenschläger 2026-09-14 20:05:47 +02:00
parent 5b9f1793d0
commit da9540d320
2 changed files with 10 additions and 7 deletions

View File

@ -2745,7 +2745,7 @@ static void wb_decode_cert_req_version(void) { WB_NOTE("WOLFSSL_CERT_REQ off; sk
* Section 26: ParseCert() RSA public key store [:23263-:23267]
* (best-effort -- see file-header RESIDUAL note for operands 2/3).
* ------------------------------------------------------------------------- */
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
#if (!defined(WC_ASN_NO_HEAP) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
defined(WOLFSSL_DYN_CERT)
static void wb_parse_cert_rsa_pubkey(void)
{
@ -2769,7 +2769,7 @@ static void wb_parse_cert_rsa_pubkey(void)
FreeDecodedCert(&cert);
}
#else
static void wb_parse_cert_rsa_pubkey(void) { WB_NOTE("WOLFSSL_NO_MALLOC build; ParseCert copy-out skipped"); }
static void wb_parse_cert_rsa_pubkey(void) { WB_NOTE("WC_ASN_NO_HEAP build; ParseCert copy-out skipped"); }
#endif
/* ------------------------------------------------------------------------- *

View File

@ -24206,7 +24206,7 @@ static int DecodeCertReq(DecodedCert* cert, int* criticalExt)
int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
{
int ret;
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
#if (!defined(WC_ASN_NO_HEAP) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
defined(WOLFSSL_DYN_CERT)
char* ptr;
#endif
@ -24215,9 +24215,9 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
if (ret < 0)
return ret;
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
#if (!defined(WC_ASN_NO_HEAP) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
defined(WOLFSSL_DYN_CERT)
/* cert->subjectCN not stored as copy of WOLFSSL_NO_MALLOC defined */
/* cert->subjectCN not stored as a copy when there is no allocator */
if (cert->subjectCNLen > 0) {
ptr = (char*)XMALLOC((size_t)cert->subjectCNLen + 1, cert->heap,
DYNAMIC_TYPE_SUBJECT_CN);
@ -24230,9 +24230,12 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
}
#endif
#if (!defined(WOLFSSL_NO_MALLOC) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
/* WC_ASN_NO_HEAP, not WOLFSSL_NO_MALLOC: a static-memory build defines the
* latter but still has an allocator, and StoreKey() copies the non-RSA keys
* on the same condition. Skipping the copy here leaves Signer.publicKey NULL,
* so every chain verify under an RSA CA fails BAD_FUNC_ARG. */
#if (!defined(WC_ASN_NO_HEAP) && !defined(NO_WOLFSSL_CM_VERIFY)) || \
defined(WOLFSSL_DYN_CERT)
/* cert->publicKey not stored as copy if WOLFSSL_NO_MALLOC defined */
if ((cert->keyOID == RSAk
#ifdef WC_RSA_PSS
|| cert->keyOID == RSAPSSk