@@ -2540,3 +2540,90 @@ int test_various_pathlen_chains(void)
25402540#endif
25412541 return EXPECT_RESULT ();
25422542}
2543+
2544+ /* Verify that certificates signed with MD5 (md5WithRSAEncryption) are
2545+ * rejected during chain verification. MD5 must not be acceptable as a
2546+ * certificate signature hash, even when MD5 is compiled in (e.g. for TLS
2547+ * 1.0 PRF or HMAC uses). Trust anchors are exempt from this check because
2548+ * ParseCertRelative skips ConfirmSignature for CA_TYPE. */
2549+ int test_wolfSSL_CertManagerRejectMD5Cert (void )
2550+ {
2551+ EXPECT_DECLS ;
2552+ #if !defined(NO_CERTS ) && !defined(NO_RSA ) && !defined(NO_MD5 ) && \
2553+ !defined(WOLFSSL_ALLOW_MD5_CERT_SIGS ) && defined(WOLFSSL_CERT_GEN ) && \
2554+ !defined(NO_WOLFSSL_CM_VERIFY ) && !defined(NO_ASN_CRYPT ) && \
2555+ !defined(USE_CERT_BUFFERS_1024 )
2556+ WOLFSSL_CERT_MANAGER * cm = NULL ;
2557+ RsaKey caKey ;
2558+ WC_RNG rng ;
2559+ Cert leaf ;
2560+ byte * der = NULL ;
2561+ int derSz = 0 ;
2562+ word32 idx = 0 ;
2563+ int caKeyInit = 0 ;
2564+ int rngInit = 0 ;
2565+
2566+ XMEMSET (& caKey , 0 , sizeof (caKey ));
2567+ XMEMSET (& rng , 0 , sizeof (rng ));
2568+
2569+ ExpectIntEQ (wc_InitRng (& rng ), 0 );
2570+ if (EXPECT_SUCCESS ()) rngInit = 1 ;
2571+
2572+ ExpectIntEQ (wc_InitRsaKey_ex (& caKey , HEAP_HINT , testDevId ), 0 );
2573+ if (EXPECT_SUCCESS ()) caKeyInit = 1 ;
2574+ ExpectIntEQ (wc_RsaPrivateKeyDecode (ca_key_der_2048 , & idx , & caKey ,
2575+ sizeof_ca_key_der_2048 ), 0 );
2576+
2577+ ExpectNotNull (der = (byte * )XMALLOC (FOURK_BUF , HEAP_HINT ,
2578+ DYNAMIC_TYPE_TMP_BUFFER ));
2579+ if (der == NULL ) {
2580+ goto cleanup ;
2581+ }
2582+
2583+ /* Build a leaf certificate whose issuer is the built-in 2048-bit
2584+ * wolfSSL test CA and sign it with MD5+RSA using the matching CA
2585+ * private key. */
2586+ ExpectIntEQ (wc_InitCert (& leaf ), 0 );
2587+ leaf .sigType = CTC_MD5wRSA ;
2588+ leaf .isCA = 0 ;
2589+ XSTRNCPY (leaf .subject .country , "US" , CTC_NAME_SIZE );
2590+ XSTRNCPY (leaf .subject .state , "MT" , CTC_NAME_SIZE );
2591+ XSTRNCPY (leaf .subject .locality , "Bozeman" , CTC_NAME_SIZE );
2592+ XSTRNCPY (leaf .subject .org , "wolfSSL" , CTC_NAME_SIZE );
2593+ XSTRNCPY (leaf .subject .unit , "Test" , CTC_NAME_SIZE );
2594+ XSTRNCPY (leaf .subject .commonName , "md5-leaf" , CTC_NAME_SIZE );
2595+ XSTRNCPY (leaf .subject .email , "info@wolfssl.com" , CTC_NAME_SIZE );
2596+
2597+ ExpectIntEQ (wc_SetIssuerBuffer (& leaf , ca_cert_der_2048 ,
2598+ sizeof_ca_cert_der_2048 ), 0 );
2599+
2600+ /* wc_MakeCert needs an RSA public key for the subject; reuse caKey
2601+ * for simplicity (we only care about signature-side verification). */
2602+ ExpectIntGT ((derSz = wc_MakeCert (& leaf , der , FOURK_BUF , & caKey , NULL ,
2603+ & rng )), 0 );
2604+ ExpectIntGT ((derSz = wc_SignCert (leaf .bodySz , leaf .sigType , der ,
2605+ FOURK_BUF , & caKey , NULL , & rng )), 0 );
2606+
2607+ /* Load the SHA-256 signed CA cert as a trust anchor and attempt
2608+ * to verify the MD5-signed leaf: it must be rejected because
2609+ * HashForSignature() now returns HASH_TYPE_E for MD5 in verify mode,
2610+ * and wolfSSL_CertManagerVerifyBuffer() returns that error. */
2611+ ExpectNotNull (cm = wolfSSL_CertManagerNew ());
2612+ if (cm != NULL ) {
2613+ ExpectIntEQ (wolfSSL_CertManagerLoadCABuffer (cm , ca_cert_der_2048 ,
2614+ sizeof_ca_cert_der_2048 , WOLFSSL_FILETYPE_ASN1 ),
2615+ WOLFSSL_SUCCESS );
2616+
2617+ ExpectIntEQ (wolfSSL_CertManagerVerifyBuffer (cm , der , derSz ,
2618+ WOLFSSL_FILETYPE_ASN1 ),
2619+ WC_NO_ERR_TRACE (HASH_TYPE_E ));
2620+ }
2621+
2622+ cleanup :
2623+ wolfSSL_CertManagerFree (cm );
2624+ XFREE (der , HEAP_HINT , DYNAMIC_TYPE_TMP_BUFFER );
2625+ if (caKeyInit ) wc_FreeRsaKey (& caKey );
2626+ if (rngInit ) wc_FreeRng (& rng );
2627+ #endif
2628+ return EXPECT_RESULT ();
2629+ }
0 commit comments