From: Matt Caswell Date: Tue, 19 Aug 2025 07:38:07 +0000 (+0100) Subject: Add a test for accessing an X509_STORE from multiple threads X-Git-Tag: openssl-3.2.6~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b18c28cafbbd82b23decb15b546ff8a4017dae5;p=thirdparty%2Fopenssl.git Add a test for accessing an X509_STORE from multiple threads Check we don't have any threading issues when accessing an X509_STORE simultaneously Reviewed-by: Saša Nedvědický Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/28198) (cherry picked from commit 994774b4ca61cf7ecf42750a7d374dd2865f1ce3) --- diff --git a/test/recipes/90-test_threads_data/store/.gitignore b/test/recipes/90-test_threads_data/store/.gitignore new file mode 100644 index 00000000000..91277842865 --- /dev/null +++ b/test/recipes/90-test_threads_data/store/.gitignore @@ -0,0 +1,3 @@ +#The top level .gitignore ignores certificate files with the .0 extension +#But we actually want them in this directory, so we override the top level rule +!*.0 diff --git a/test/recipes/90-test_threads_data/store/8489a545.0 b/test/recipes/90-test_threads_data/store/8489a545.0 new file mode 100644 index 00000000000..7fd65dfe924 --- /dev/null +++ b/test/recipes/90-test_threads_data/store/8489a545.0 @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAf6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTIwMTIxMjIwMTEzN1oYDzIxMjAxMjEzMjAxMTM3WjASMRAwDgYDVQQD +DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8 +oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS +feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN +wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g +MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u +aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff +tWgiQ35mJCOvxQIDAQABo3UwczAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3o1IwHwYDVR0jBBgwFoAUjvUl +rx6ba4Q9fICayVOcTXL3o1IwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcN +AQELBQADggEBABWUjaqtkdRDhVAJZTxkJVgohjRrBwp86Y0JZWdCDua/sErmEaGu +nQVxWWFWIgu6sb8tyQo3/7dBIQl3Rpij9bsgKhToO1OzoG3Oi3d0+zRDHfY6xNrj +TUE00FeLHGNWsgZSIvu99DrGApT/+uPdWfJgMu5szillqW+4hcCUPLjG9ekVNt1s +KhdEklo6PrP6eMbm6s22EIVUxqGE6xxAmrvyhlY1zJH9BJ23Ps+xabjG6OeMRZzT +0F/fU7XIFieSO7rqUcjgo1eYc3ghsDxNUJ6TPBgv5z4SPnstoOBj59rjpJ7Qkpyd +L17VfEadezat37Cpeha7vGDduCsyMfN4kiw= +-----END CERTIFICATE----- diff --git a/test/threadstest.c b/test/threadstest.c index 2ea9cca7964..ab2aea39432 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -40,6 +40,7 @@ static int do_fips = 0; static char *privkey; +static char *storedir; static char *config_file = NULL; static int multidefault_run = 0; @@ -681,7 +682,7 @@ static int test_multi_default(void) multidefault_run = 1; return thread_run_test(&thread_multi_simple_fetch, - 2, &thread_multi_simple_fetch, 0, default_provider); + 2, &thread_multi_simple_fetch, 0, NULL); } static int test_multi_load(void) @@ -854,6 +855,62 @@ static int test_pem_read(void) &test_pem_read_one, 1, default_provider); } +static X509_STORE *store = NULL; + +static void test_x509_store_by_subject(void) +{ + X509_STORE_CTX *ctx; + X509_OBJECT *obj = NULL; + X509_NAME *name = NULL; + int success = 0; + + ctx = X509_STORE_CTX_new(); + if (!TEST_ptr(ctx)) + goto err; + + if (!TEST_true(X509_STORE_CTX_init(ctx, store, NULL, NULL))) + goto err; + + name = X509_NAME_new(); + if (!TEST_ptr(name)) + goto err; + if (!TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (unsigned char *)"Root CA", + -1, -1, 0))) + goto err; + obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name); + if (!TEST_ptr(obj)) + goto err; + + success = 1; + err: + X509_OBJECT_free(obj); + X509_STORE_CTX_free(ctx); + X509_NAME_free(name); + if (!success) + multi_set_success(0); +} + +/* Test accessing an X509_STORE from multiple threads */ +static int test_x509_store(void) +{ + int ret = 0; + + store = X509_STORE_new(); + if (!TEST_ptr(store)) + return 0; + if (!TEST_true(X509_STORE_load_store(store, storedir))) + goto err; + + ret = thread_run_test(&test_x509_store_by_subject, MAXIMUM_THREADS, + &test_x509_store_by_subject, 0, NULL); + + err: + X509_STORE_free(store); + store = NULL; + return ret; +} + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, @@ -900,6 +957,10 @@ int setup_tests(void) if (!TEST_ptr(privkey)) return 0; + storedir = test_mk_file_path(datadir, "store"); + if (!TEST_ptr(storedir)) + return 0; + if (!TEST_ptr(global_lock = CRYPTO_THREAD_lock_new())) return 0; @@ -932,12 +993,14 @@ int setup_tests(void) ADD_TEST(test_bio_dgram_pair); #endif ADD_TEST(test_pem_read); + ADD_TEST(test_x509_store); return 1; } void cleanup_tests(void) { OPENSSL_free(privkey); + OPENSSL_free(storedir); #ifdef TSAN_REQUIRES_LOCKING CRYPTO_THREAD_lock_free(tsan_lock); #endif