@@ -1974,3 +1974,119 @@ int test_X509_STORE_No_SSL_CTX(void)
19741974#endif
19751975 return EXPECT_RESULT ();
19761976}
1977+
1978+ /* Test that SSL_CTX_set_cert_store propagates certificates (including
1979+ * non-self-signed intermediates) into the CertManager, and that certs
1980+ * added to the store after set_cert_store also reach the CertManager.
1981+ * Regression test for ZD 19760 / GitHub PR #8708.
1982+ */
1983+ int test_wolfSSL_CTX_set_cert_store (void )
1984+ {
1985+ EXPECT_DECLS ;
1986+ #if defined(OPENSSL_EXTRA ) && !defined(NO_RSA ) && !defined(NO_FILESYSTEM ) && \
1987+ !defined(NO_WOLFSSL_CLIENT ) && !defined(NO_TLS )
1988+ SSL_CTX * ctx = NULL ;
1989+ X509_STORE * store = NULL ;
1990+ X509 * rootCa = NULL ;
1991+ X509 * intCa = NULL ;
1992+ X509 * int2Ca = NULL ;
1993+ X509_STORE_CTX * storeCtx = NULL ;
1994+ X509 * svrCert = NULL ;
1995+
1996+ const char caCert [] = "./certs/ca-cert.pem" ;
1997+ const char intCaCert [] = "./certs/intermediate/ca-int-cert.pem" ;
1998+ const char int2CaCert [] = "./certs/intermediate/ca-int2-cert.pem" ;
1999+ const char svrIntCert [] = "./certs/intermediate/server-int-cert.pem" ;
2000+
2001+ /* --- Part 1: Add certs to store BEFORE set_cert_store ---
2002+ * Non-self-signed intermediates should be pushed into the CertManager
2003+ * when set_cert_store is called. */
2004+ ExpectNotNull (store = X509_STORE_new ());
2005+ ExpectNotNull (rootCa = wolfSSL_X509_load_certificate_file (caCert ,
2006+ SSL_FILETYPE_PEM ));
2007+ ExpectNotNull (intCa = wolfSSL_X509_load_certificate_file (intCaCert ,
2008+ SSL_FILETYPE_PEM ));
2009+ ExpectNotNull (int2Ca = wolfSSL_X509_load_certificate_file (int2CaCert ,
2010+ SSL_FILETYPE_PEM ));
2011+
2012+ ExpectIntEQ (X509_STORE_add_cert (store , rootCa ), SSL_SUCCESS );
2013+ ExpectIntEQ (X509_STORE_add_cert (store , intCa ), SSL_SUCCESS );
2014+ ExpectIntEQ (X509_STORE_add_cert (store , int2Ca ), SSL_SUCCESS );
2015+
2016+ ExpectNotNull (ctx = SSL_CTX_new (TLS_client_method ()));
2017+
2018+ /* This should push intermediates from store->certs into the CM */
2019+ SSL_CTX_set_cert_store (ctx , store );
2020+
2021+ /* After set_cert_store, store->certs and store->trusted should be NULLed
2022+ * to signal CTX ownership */
2023+ if (EXPECT_SUCCESS ()) {
2024+ ExpectNull (store -> certs );
2025+ ExpectNull (store -> trusted );
2026+ }
2027+
2028+ /* Verify using CertManagerVerify - this only checks the CM, not the
2029+ * store's certs stack, so it proves the intermediates were pushed */
2030+ ExpectIntEQ (wolfSSL_CertManagerVerify (wolfSSL_CTX_GetCertManager (ctx ),
2031+ svrIntCert , SSL_FILETYPE_PEM ), WOLFSSL_SUCCESS );
2032+
2033+ /* Also verify using X509_verify_cert for completeness */
2034+ ExpectNotNull (svrCert = wolfSSL_X509_load_certificate_file (svrIntCert ,
2035+ SSL_FILETYPE_PEM ));
2036+ ExpectNotNull (storeCtx = X509_STORE_CTX_new ());
2037+ if (EXPECT_SUCCESS ()) {
2038+ ExpectIntEQ (X509_STORE_CTX_init (storeCtx ,
2039+ SSL_CTX_get_cert_store (ctx ), svrCert , NULL ), SSL_SUCCESS );
2040+ ExpectIntEQ (X509_verify_cert (storeCtx ), SSL_SUCCESS );
2041+ }
2042+
2043+ X509_STORE_CTX_free (storeCtx );
2044+ storeCtx = NULL ;
2045+ X509_free (svrCert );
2046+ svrCert = NULL ;
2047+ SSL_CTX_free (ctx );
2048+ ctx = NULL ;
2049+ /* store is freed by SSL_CTX_free */
2050+ store = NULL ;
2051+
2052+ X509_free (rootCa );
2053+ rootCa = NULL ;
2054+ X509_free (intCa );
2055+ intCa = NULL ;
2056+ X509_free (int2Ca );
2057+ int2Ca = NULL ;
2058+
2059+ /* --- Part 2: Add certs to store AFTER set_cert_store ---
2060+ * When store->certs is NULL (CTX-owned), X509_STORE_add_cert should
2061+ * route non-self-signed certs directly to the CertManager. */
2062+ ExpectNotNull (store = X509_STORE_new ());
2063+ ExpectNotNull (ctx = SSL_CTX_new (TLS_client_method ()));
2064+
2065+ /* Attach empty store first */
2066+ SSL_CTX_set_cert_store (ctx , store );
2067+
2068+ /* Now add certs after ownership transfer */
2069+ ExpectNotNull (rootCa = wolfSSL_X509_load_certificate_file (caCert ,
2070+ SSL_FILETYPE_PEM ));
2071+ ExpectNotNull (intCa = wolfSSL_X509_load_certificate_file (intCaCert ,
2072+ SSL_FILETYPE_PEM ));
2073+ ExpectNotNull (int2Ca = wolfSSL_X509_load_certificate_file (int2CaCert ,
2074+ SSL_FILETYPE_PEM ));
2075+
2076+ ExpectIntEQ (X509_STORE_add_cert (store , rootCa ), SSL_SUCCESS );
2077+ ExpectIntEQ (X509_STORE_add_cert (store , intCa ), SSL_SUCCESS );
2078+ ExpectIntEQ (X509_STORE_add_cert (store , int2Ca ), SSL_SUCCESS );
2079+
2080+ /* Verify that certs added after set_cert_store are in the CM */
2081+ ExpectIntEQ (wolfSSL_CertManagerVerify (wolfSSL_CTX_GetCertManager (ctx ),
2082+ svrIntCert , SSL_FILETYPE_PEM ), WOLFSSL_SUCCESS );
2083+
2084+ SSL_CTX_free (ctx );
2085+ /* store freed by SSL_CTX_free */
2086+ X509_free (rootCa );
2087+ X509_free (intCa );
2088+ X509_free (int2Ca );
2089+ #endif
2090+ return EXPECT_RESULT ();
2091+ }
2092+
0 commit comments