]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add a test for accessing an X509_STORE from multiple threads
authorMatt Caswell <matt@openssl.org>
Tue, 19 Aug 2025 07:38:07 +0000 (08:38 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 4 Sep 2025 12:26:02 +0000 (13:26 +0100)
Check we don't have any threading issues when accessing an X509_STORE
simultaneously

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28385)

test/recipes/90-test_threads_data/store/.gitignore [new file with mode: 0644]
test/recipes/90-test_threads_data/store/8489a545.0 [new file with mode: 0644]
test/threadstest.c

diff --git a/test/recipes/90-test_threads_data/store/.gitignore b/test/recipes/90-test_threads_data/store/.gitignore
new file mode 100644 (file)
index 0000000..9127784
--- /dev/null
@@ -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 (file)
index 0000000..7fd65df
--- /dev/null
@@ -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-----
index 046a9eb80239a6f7c8ed73e65792c6ab3d1089fd..c3ab0745fb5cf6b2f0d98bad6103fe2b792daa2f 100644 (file)
@@ -30,6 +30,7 @@
 
 static int do_fips = 0;
 static char *privkey;
+static char *storedir;
 static char *config_file = NULL;
 static int multidefault_run = 0;
 static const char *default_provider[] = { "default", NULL };
@@ -582,7 +583,6 @@ static int test_multi_default(void)
 {
     thread_t thread1, thread2;
     int testresult = 0;
-    OSSL_PROVIDER *prov = NULL;
 
     /* Avoid running this test twice */
     if (multidefault_run) {
@@ -593,9 +593,6 @@ static int test_multi_default(void)
 
     multi_success = 1;
     multi_libctx = NULL;
-    prov = OSSL_PROVIDER_load(multi_libctx, "default");
-    if (!TEST_ptr(prov))
-        goto err;
 
     if (!TEST_true(run_thread(&thread1, thread_multi_simple_fetch))
             || !TEST_true(run_thread(&thread2, thread_multi_simple_fetch)))
@@ -611,7 +608,6 @@ static int test_multi_default(void)
     testresult = 1;
 
  err:
-    OSSL_PROVIDER_unload(prov);
     return testresult;
 }
 
@@ -663,6 +659,62 @@ static int test_lib_ctx_load_config(void)
                            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_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,
@@ -709,20 +761,24 @@ int setup_tests(void)
     if (!TEST_ptr(privkey))
         return 0;
 
+    storedir = test_mk_file_path(datadir, "store");
+
     /* Keep first to validate auto creation of default library context */
     ADD_TEST(test_multi_default);
-
     ADD_TEST(test_lock);
     ADD_TEST(test_once);
     ADD_TEST(test_thread_local);
     ADD_TEST(test_atomic);
     ADD_TEST(test_multi_load);
+
     ADD_ALL_TESTS(test_multi, 6);
     ADD_TEST(test_lib_ctx_load_config);
+    ADD_TEST(test_x509_store);
     return 1;
 }
 
 void cleanup_tests(void)
 {
     OPENSSL_free(privkey);
+    OPENSSL_free(storedir);
 }