@@ -3685,6 +3685,105 @@ int test_wc_DecodeExtKeyUsage_ssh_oid_collision(void)
36853685 return EXPECT_RESULT ();
36863686}
36873687
3688+ #if !defined(NO_ASN ) && !defined(NO_RSA ) && !defined(NO_CERTS ) && \
3689+ defined(WOLFSSL_CERT_GEN ) && defined(WOLFSSL_CERT_EXT ) && \
3690+ defined(WOLFSSL_EKU_OID ) && !defined(NO_SHA256 ) && \
3691+ defined(USE_CERT_BUFFERS_2048 ) && !defined(NO_ASN_TIME ) && \
3692+ !defined(WC_NO_RNG ) && !defined(NO_ASN_CRYPT )
3693+ #define TEST_EKU_OID_SUM_COLLISION
3694+ #endif
3695+
3696+ /* A KeyPurposeId whose wc_oid_sum() collides with id-kp-serverAuth must not
3697+ * authorize server authentication, while the real OID still does. */
3698+ int test_wc_DecodeExtKeyUsage_oidSumCollision (void )
3699+ {
3700+ EXPECT_DECLS ;
3701+ #ifdef TEST_EKU_OID_SUM_COLLISION
3702+ static const struct {
3703+ const char * oid ; /* custom EKU OID, NULL to use a named purpose */
3704+ const char * name ; /* named purpose, used when oid is NULL */
3705+ byte expected ;
3706+ } ekuCases [] = {
3707+ /* id-kp-serverAuth. */
3708+ { NULL , "serverAuth" , EXTKEYUSE_SERVER_AUTH },
3709+ #ifdef WOLFSSL_OLD_OID_SUM
3710+ /* 1.5.6.1.5.5.3.1, the same byte sum (71) as id-kp-serverAuth. */
3711+ { "1.5.6.1.5.5.3.1" , NULL , 0 },
3712+ #else
3713+ /* 1.19.6.1.5.21.7.3.1, the same XOR-shift sum (0x0402012e) as
3714+ * id-kp-serverAuth. */
3715+ { "1.19.6.1.5.21.7.3.1" , NULL , 0 },
3716+ #endif
3717+ };
3718+ WC_RNG rng ;
3719+ RsaKey key ;
3720+ byte * der = NULL ;
3721+ word32 idx = 0 ;
3722+ int rngInit = 0 ;
3723+ int keyInit = 0 ;
3724+ size_t c ;
3725+
3726+ XMEMSET (& rng , 0 , sizeof (rng ));
3727+ XMEMSET (& key , 0 , sizeof (key ));
3728+
3729+ ExpectIntEQ (wc_InitRng (& rng ), 0 );
3730+ if (EXPECT_SUCCESS ()) rngInit = 1 ;
3731+
3732+ ExpectNotNull (der = (byte * )XMALLOC (FOURK_BUF , HEAP_HINT ,
3733+ DYNAMIC_TYPE_TMP_BUFFER ));
3734+
3735+ ExpectIntEQ (wc_InitRsaKey_ex (& key , HEAP_HINT , testDevId ), 0 );
3736+ if (EXPECT_SUCCESS ()) keyInit = 1 ;
3737+ ExpectIntEQ (wc_RsaPrivateKeyDecode (server_key_der_2048 , & idx , & key ,
3738+ sizeof_server_key_der_2048 ), 0 );
3739+
3740+ for (c = 0 ; c < XELEM_CNT (ekuCases ); c ++ ) {
3741+ Cert cert ;
3742+ DecodedCert dCert ;
3743+ int dCertInit = 0 ;
3744+ int derSz = 0 ;
3745+
3746+ if (!EXPECT_SUCCESS ()) break ;
3747+
3748+ XMEMSET (& cert , 0 , sizeof (cert ));
3749+ ExpectIntEQ (wc_InitCert (& cert ), 0 );
3750+ if (EXPECT_SUCCESS ()) {
3751+ cert .sigType = CTC_SHA256wRSA ;
3752+ cert .isCA = 0 ;
3753+ XSTRNCPY (cert .subject .country , "US" , CTC_NAME_SIZE );
3754+ XSTRNCPY (cert .subject .org , "wolfSSL" , CTC_NAME_SIZE );
3755+ XSTRNCPY (cert .subject .commonName , "extKeyUsage" , CTC_NAME_SIZE );
3756+ }
3757+ if (ekuCases [c ].oid != NULL ) {
3758+ ExpectIntEQ (wc_SetExtKeyUsageOID (& cert , ekuCases [c ].oid ,
3759+ (word32 )XSTRLEN (ekuCases [c ].oid ), 0 , HEAP_HINT ), 0 );
3760+ }
3761+ else {
3762+ ExpectIntEQ (wc_SetExtKeyUsage (& cert , ekuCases [c ].name ), 0 );
3763+ }
3764+ ExpectIntGT (derSz = wc_MakeSelfCert (& cert , der , FOURK_BUF , & key , & rng ),
3765+ 0 );
3766+
3767+ if (EXPECT_SUCCESS () && (der != NULL )) {
3768+ wc_InitDecodedCert (& dCert , der , (word32 )derSz , HEAP_HINT );
3769+ dCertInit = 1 ;
3770+ ExpectIntEQ (wc_ParseCert (& dCert , CERT_TYPE , NO_VERIFY , NULL ), 0 );
3771+ /* The extension must be seen in both cases - an unrecognized
3772+ * KeyPurposeId is skipped, not an error - but only the real OID
3773+ * may authorize a purpose. */
3774+ ExpectIntNE (dCert .extExtKeyUsageSet , 0 );
3775+ ExpectIntEQ (dCert .extExtKeyUsage , ekuCases [c ].expected );
3776+ }
3777+ if (dCertInit ) wc_FreeDecodedCert (& dCert );
3778+ }
3779+
3780+ if (keyInit ) wc_FreeRsaKey (& key );
3781+ if (rngInit ) wc_FreeRng (& rng );
3782+ XFREE (der , HEAP_HINT , DYNAMIC_TYPE_TMP_BUFFER );
3783+ #endif /* TEST_EKU_OID_SUM_COLLISION */
3784+ return EXPECT_RESULT ();
3785+ }
3786+
36883787int test_wc_SignCert_buffer_bounds (void )
36893788{
36903789 EXPECT_DECLS ;
0 commit comments