@@ -244,6 +244,104 @@ int test_x509_GetCAByAKID(void)
244244 return EXPECT_RESULT ();
245245}
246246
247+ /* Regression test: wolfSSL_X509_verify_cert() must honour the hostname set via
248+ * X509_VERIFY_PARAM_set1_host(). Before the fix the hostname was stored in
249+ * ctx->param->hostName but never consulted, so any chain-valid certificate
250+ * would pass regardless of hostname mismatch (RFC 6125 sec. 6.4.1 violation).
251+ *
252+ * Uses existing PEM fixtures:
253+ * svrCertFile - CN=www.wolfssl.com, SAN DNS=example.com, SAN IP=127.0.0.1
254+ * caCertFile - CA that signed svrCertFile
255+ */
256+ int test_x509_verify_cert_hostname_check (void )
257+ {
258+ EXPECT_DECLS ;
259+ #if defined(OPENSSL_EXTRA ) && !defined(NO_FILESYSTEM ) && !defined(NO_RSA )
260+ WOLFSSL_X509_STORE * store = NULL ;
261+ WOLFSSL_X509_STORE_CTX * ctx = NULL ;
262+ WOLFSSL_X509 * ca = NULL ;
263+ WOLFSSL_X509 * leaf = NULL ;
264+ WOLFSSL_X509_VERIFY_PARAM * param = NULL ;
265+
266+ ExpectNotNull (store = wolfSSL_X509_STORE_new ());
267+ ExpectNotNull (ca = wolfSSL_X509_load_certificate_file (caCertFile ,
268+ SSL_FILETYPE_PEM ));
269+ ExpectIntEQ (wolfSSL_X509_STORE_add_cert (store , ca ), WOLFSSL_SUCCESS );
270+
271+ ExpectNotNull (leaf = wolfSSL_X509_load_certificate_file (svrCertFile ,
272+ SSL_FILETYPE_PEM ));
273+
274+ /* Case 1: no hostname constraint - must succeed. */
275+ ExpectNotNull (ctx = wolfSSL_X509_STORE_CTX_new ());
276+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_init (ctx , store , leaf , NULL ),
277+ WOLFSSL_SUCCESS );
278+ ExpectIntEQ (wolfSSL_X509_verify_cert (ctx ), WOLFSSL_SUCCESS );
279+ wolfSSL_X509_STORE_CTX_free (ctx );
280+ ctx = NULL ;
281+
282+ /* Case 2: hostname matches a SAN DNS entry - must succeed. */
283+ ExpectNotNull (ctx = wolfSSL_X509_STORE_CTX_new ());
284+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_init (ctx , store , leaf , NULL ),
285+ WOLFSSL_SUCCESS );
286+ param = wolfSSL_X509_STORE_CTX_get0_param (ctx );
287+ ExpectNotNull (param );
288+ ExpectIntEQ (wolfSSL_X509_VERIFY_PARAM_set1_host (param , "example.com" ,
289+ XSTRLEN ("example.com" )), WOLFSSL_SUCCESS );
290+ ExpectIntEQ (wolfSSL_X509_verify_cert (ctx ), WOLFSSL_SUCCESS );
291+ wolfSSL_X509_STORE_CTX_free (ctx );
292+ ctx = NULL ;
293+
294+ /* Case 3: hostname does not match - must FAIL with the right error code. */
295+ ExpectNotNull (ctx = wolfSSL_X509_STORE_CTX_new ());
296+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_init (ctx , store , leaf , NULL ),
297+ WOLFSSL_SUCCESS );
298+ param = wolfSSL_X509_STORE_CTX_get0_param (ctx );
299+ ExpectNotNull (param );
300+ ExpectIntEQ (wolfSSL_X509_VERIFY_PARAM_set1_host (param , "wrong.com" ,
301+ XSTRLEN ("wrong.com" )), WOLFSSL_SUCCESS );
302+ ExpectIntNE (wolfSSL_X509_verify_cert (ctx ), WOLFSSL_SUCCESS );
303+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_get_error (ctx ),
304+ X509_V_ERR_HOSTNAME_MISMATCH );
305+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_get_error_depth (ctx ), 0 );
306+ wolfSSL_X509_STORE_CTX_free (ctx );
307+ ctx = NULL ;
308+
309+ #ifdef WOLFSSL_IP_ALT_NAME
310+ /* Case 4: IP matches a SAN IP entry - must succeed. */
311+ ExpectNotNull (ctx = wolfSSL_X509_STORE_CTX_new ());
312+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_init (ctx , store , leaf , NULL ),
313+ WOLFSSL_SUCCESS );
314+ param = wolfSSL_X509_STORE_CTX_get0_param (ctx );
315+ ExpectNotNull (param );
316+ ExpectIntEQ (wolfSSL_X509_VERIFY_PARAM_set1_ip_asc (param , "127.0.0.1" ),
317+ WOLFSSL_SUCCESS );
318+ ExpectIntEQ (wolfSSL_X509_verify_cert (ctx ), WOLFSSL_SUCCESS );
319+ wolfSSL_X509_STORE_CTX_free (ctx );
320+ ctx = NULL ;
321+
322+ /* Case 5: IP does not match - must FAIL with the right error code. */
323+ ExpectNotNull (ctx = wolfSSL_X509_STORE_CTX_new ());
324+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_init (ctx , store , leaf , NULL ),
325+ WOLFSSL_SUCCESS );
326+ param = wolfSSL_X509_STORE_CTX_get0_param (ctx );
327+ ExpectNotNull (param );
328+ ExpectIntEQ (wolfSSL_X509_VERIFY_PARAM_set1_ip_asc (param , "192.168.1.1" ),
329+ WOLFSSL_SUCCESS );
330+ ExpectIntNE (wolfSSL_X509_verify_cert (ctx ), WOLFSSL_SUCCESS );
331+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_get_error (ctx ),
332+ X509_V_ERR_IP_ADDRESS_MISMATCH );
333+ ExpectIntEQ (wolfSSL_X509_STORE_CTX_get_error_depth (ctx ), 0 );
334+ wolfSSL_X509_STORE_CTX_free (ctx );
335+ ctx = NULL ;
336+ #endif /* WOLFSSL_IP_ALT_NAME */
337+
338+ wolfSSL_X509_free (leaf );
339+ wolfSSL_X509_free (ca );
340+ wolfSSL_X509_STORE_free (store );
341+ #endif /* OPENSSL_EXTRA && !NO_FILESYSTEM && !NO_RSA */
342+ return EXPECT_RESULT ();
343+ }
344+
247345int test_x509_set_serialNumber (void )
248346{
249347#if defined(OPENSSL_EXTRA ) || defined(OPENSSL_EXTRA_X509_SMALL )
0 commit comments