@@ -71,6 +71,108 @@ int test_wolfSSL_X509_check_private_key(void)
7171 return EXPECT_RESULT ();
7272}
7373
74+ /* EVP_PKCS82PKEY() must populate pkey.ptr/pkey_sz for ML-DSA so
75+ * X509_check_private_key() (wc_CheckPrivateKey) can redecode the DER, and
76+ * d2i_PKCS8_PKEY() must keep the full PKCS#8 wrapper for ML-DSA level recovery
77+ * from the AlgorithmIdentifier. */
78+ int test_wolfSSL_X509_check_private_key_mldsa (void )
79+ {
80+ EXPECT_DECLS ;
81+ #if defined(OPENSSL_EXTRA ) && !defined(NO_FILESYSTEM ) && \
82+ !defined(NO_BIO ) && !defined(NO_CHECK_PRIVATE_KEY ) && \
83+ defined(HAVE_DILITHIUM ) && !defined(WOLFSSL_DILITHIUM_NO_SIGN ) && \
84+ !defined(WOLFSSL_DILITHIUM_NO_VERIFY ) && \
85+ (defined(OPENSSL_ALL ) || defined(WOLFSSL_WPAS_SMALL )) && \
86+ (!defined(WOLFSSL_NO_ML_DSA_44 ) || !defined(WOLFSSL_NO_ML_DSA_65 ) || \
87+ !defined(WOLFSSL_NO_ML_DSA_87 ))
88+ static const struct {
89+ const char * keyPath ;
90+ const char * certPath ;
91+ const char * mismatchCertPath ; /* NULL if no other level available */
92+ } cases [] = {
93+ #if !defined (WOLFSSL_NO_ML_DSA_44 )
94+ { "./certs/mldsa/mldsa44-key.pem" ,
95+ "./certs/mldsa/mldsa44-cert.der" ,
96+ #if !defined (WOLFSSL_NO_ML_DSA_65 )
97+ "./certs/mldsa/mldsa65-cert.der"
98+ #elif !defined (WOLFSSL_NO_ML_DSA_87 )
99+ "./certs/mldsa/mldsa87-cert.der"
100+ #else
101+ NULL
102+ #endif
103+ },
104+ #endif
105+ #if !defined (WOLFSSL_NO_ML_DSA_65 )
106+ { "./certs/mldsa/mldsa65-key.pem" ,
107+ "./certs/mldsa/mldsa65-cert.der" ,
108+ #if !defined (WOLFSSL_NO_ML_DSA_87 )
109+ "./certs/mldsa/mldsa87-cert.der"
110+ #elif !defined (WOLFSSL_NO_ML_DSA_44 )
111+ "./certs/mldsa/mldsa44-cert.der"
112+ #else
113+ NULL
114+ #endif
115+ },
116+ #endif
117+ #if !defined (WOLFSSL_NO_ML_DSA_87 )
118+ { "./certs/mldsa/mldsa87-key.pem" ,
119+ "./certs/mldsa/mldsa87-cert.der" ,
120+ #if !defined (WOLFSSL_NO_ML_DSA_44 )
121+ "./certs/mldsa/mldsa44-cert.der"
122+ #elif !defined (WOLFSSL_NO_ML_DSA_65 )
123+ "./certs/mldsa/mldsa65-cert.der"
124+ #else
125+ NULL
126+ #endif
127+ },
128+ #endif
129+ };
130+ size_t i ;
131+
132+ for (i = 0 ; i < sizeof (cases ) / sizeof (cases [0 ]); i ++ ) {
133+ PKCS8_PRIV_KEY_INFO * pt = NULL ;
134+ EVP_PKEY * pkey = NULL ;
135+ X509 * x509 = NULL ;
136+ X509 * mismatchX509 = NULL ;
137+ BIO * bio = NULL ;
138+ byte * buf = NULL ;
139+ size_t sz = 0 ;
140+
141+ ExpectIntEQ (load_file (cases [i ].keyPath , & buf , & sz ), 0 );
142+
143+ ExpectNotNull (bio = BIO_new_mem_buf ((void * )buf , (int )sz ));
144+ ExpectNotNull (pt = d2i_PKCS8_PRIV_KEY_INFO_bio (bio , NULL ));
145+
146+ ExpectNotNull (pkey = EVP_PKCS82PKEY (pt ));
147+ if (pkey != NULL ) {
148+ ExpectIntEQ (EVP_PKEY_id (pkey ), EVP_PKEY_DILITHIUM );
149+ /* pkey.ptr must hold the DER so that X509_check_private_key() to
150+ * wc_CheckPrivateKey() can re-decode it. */
151+ ExpectNotNull (pkey -> pkey .ptr );
152+ ExpectIntGT (pkey -> pkey_sz , 0 );
153+ }
154+
155+ ExpectNotNull (x509 = X509_load_certificate_file (
156+ cases [i ].certPath , SSL_FILETYPE_ASN1 ));
157+ ExpectIntEQ (X509_check_private_key (x509 , pkey ), 1 );
158+
159+ if (cases [i ].mismatchCertPath != NULL ) {
160+ ExpectNotNull (mismatchX509 = X509_load_certificate_file (
161+ cases [i ].mismatchCertPath , SSL_FILETYPE_ASN1 ));
162+ ExpectIntEQ (X509_check_private_key (mismatchX509 , pkey ), 0 );
163+ }
164+
165+ X509_free (mismatchX509 );
166+ X509_free (x509 );
167+ EVP_PKEY_free (pkey );
168+ PKCS8_PRIV_KEY_INFO_free (pt );
169+ BIO_free (bio );
170+ XFREE (buf , NULL , DYNAMIC_TYPE_TMP_BUFFER );
171+ }
172+ #endif
173+ return EXPECT_RESULT ();
174+ }
175+
74176int test_wolfSSL_X509_verify (void )
75177{
76178 EXPECT_DECLS ;
0 commit comments