1 /*
2 * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 /*
11 * The test_multi_downgrade_shared_pkey function tests the thread safety of a
12 * deprecated function.
13 */
14 #ifndef OPENSSL_NO_DEPRECATED_3_0
15 #define OPENSSL_SUPPRESS_DEPRECATED
16 #endif
17
18 #if defined(_WIN32)
19 #include <windows.h>
20 #endif
21
22 #include <string.h>
23 #include <openssl/crypto.h>
24 #include <openssl/rsa.h>
25 #include <openssl/aes.h>
26 #include <openssl/err.h>
27 #include <openssl/rand.h>
28 #include <openssl/pem.h>
29 #include <openssl/evp.h>
30 #include "internal/tsan_assist.h"
31 #include "internal/nelem.h"
32 #include "internal/time.h"
33 #include "internal/rcu.h"
34 #include "testutil.h"
35 #include "threadstest.h"
36
37 #ifdef __SANITIZE_THREAD__
38 #include <sanitizer/tsan_interface.h>
39 #define TSAN_ACQUIRE(s) __tsan_acquire(s)
40 #else
41 #define TSAN_ACQUIRE(s)
42 #endif
43
44 /* Limit the maximum number of threads */
45 #define MAXIMUM_THREADS 10
46
47 /* Limit the maximum number of providers loaded into a library context */
48 #define MAXIMUM_PROVIDERS 4
49
50 static int do_fips = 0;
51 static char *privkey;
52 static char *storedir;
53 static char *config_file = NULL;
54 static int multidefault_run = 0;
55
56 static const char *default_provider[] = { "default", NULL };
57 static const char *fips_provider[] = { "fips", NULL };
58 static const char *fips_and_default_providers[] = { "default", "fips", NULL };
59
60 static CRYPTO_RWLOCK *global_lock;
61
62 #ifdef TSAN_REQUIRES_LOCKING
63 static CRYPTO_RWLOCK *tsan_lock;
64 #endif
65
66 /* Grab a globally unique integer value, return 0 on failure */
get_new_uid(void)67 static int get_new_uid(void)
68 {
69 /*
70 * Start with a nice large number to avoid potential conflicts when
71 * we generate a new OID.
72 */
73 static TSAN_QUALIFIER int current_uid = 1 << (sizeof(int) * 8 - 2);
74 #ifdef TSAN_REQUIRES_LOCKING
75 int r;
76
77 if (!TEST_true(CRYPTO_THREAD_write_lock(tsan_lock)))
78 return 0;
79 r = ++current_uid;
80 if (!TEST_true(CRYPTO_THREAD_unlock(tsan_lock)))
81 return 0;
82 return r;
83
84 #else
85 return tsan_counter(¤t_uid);
86 #endif
87 }
88
test_lock(void)89 static int test_lock(void)
90 {
91 CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
92 int res;
93
94 if (!TEST_ptr(lock))
95 return 0;
96
97 res = TEST_true(CRYPTO_THREAD_read_lock(lock))
98 && TEST_true(CRYPTO_THREAD_unlock(lock))
99 && TEST_true(CRYPTO_THREAD_write_lock(lock))
100 && TEST_true(CRYPTO_THREAD_unlock(lock));
101
102 CRYPTO_THREAD_lock_free(lock);
103
104 return res;
105 }
106
107 #if defined(OPENSSL_THREADS)
108 static int contention = 0;
109 static int rwwriter1_done = 0;
110 static int rwwriter2_done = 0;
111 static int rwreader1_iterations = 0;
112 static int rwreader2_iterations = 0;
113 static int rwwriter1_iterations = 0;
114 static int rwwriter2_iterations = 0;
115 static int *rwwriter_ptr = NULL;
116 static int rw_torture_result = 1;
117 static CRYPTO_RWLOCK *rwtorturelock = NULL;
118 static CRYPTO_RWLOCK *atomiclock = NULL;
119
rwwriter_fn(int id,int * iterations)120 static void rwwriter_fn(int id, int *iterations)
121 {
122 int count;
123 int *old, *new;
124 OSSL_TIME t1, t2;
125 t1 = ossl_time_now();
126
127 for (count = 0;; count++) {
128 new = CRYPTO_zalloc(sizeof(int), NULL, 0);
129 if (contention == 0)
130 OSSL_sleep(1000);
131 if (!CRYPTO_THREAD_write_lock(rwtorturelock))
132 abort();
133 if (rwwriter_ptr != NULL) {
134 *new = *rwwriter_ptr + 1;
135 } else {
136 *new = 0;
137 }
138 old = rwwriter_ptr;
139 rwwriter_ptr = new;
140 if (!CRYPTO_THREAD_unlock(rwtorturelock))
141 abort();
142 if (old != NULL)
143 CRYPTO_free(old, __FILE__, __LINE__);
144 t2 = ossl_time_now();
145 if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= 4)
146 break;
147 }
148 *iterations = count;
149 return;
150 }
151
rwwriter1_fn(void)152 static void rwwriter1_fn(void)
153 {
154 int local;
155
156 TEST_info("Starting writer1");
157 rwwriter_fn(1, &rwwriter1_iterations);
158 CRYPTO_atomic_add(&rwwriter1_done, 1, &local, atomiclock);
159 }
160
rwwriter2_fn(void)161 static void rwwriter2_fn(void)
162 {
163 int local;
164
165 TEST_info("Starting writer 2");
166 rwwriter_fn(2, &rwwriter2_iterations);
167 CRYPTO_atomic_add(&rwwriter2_done, 1, &local, atomiclock);
168 }
169
rwreader_fn(int * iterations)170 static void rwreader_fn(int *iterations)
171 {
172 unsigned int count = 0;
173
174 int old = 0;
175 int lw1 = 0;
176 int lw2 = 0;
177
178 if (CRYPTO_THREAD_read_lock(rwtorturelock) == 0)
179 abort();
180
181 while (lw1 != 1 || lw2 != 1) {
182 CRYPTO_atomic_add(&rwwriter1_done, 0, &lw1, atomiclock);
183 CRYPTO_atomic_add(&rwwriter2_done, 0, &lw2, atomiclock);
184
185 count++;
186 if (rwwriter_ptr != NULL) {
187 if (old > *rwwriter_ptr) {
188 TEST_info("rwwriter pointer went backwards! %d : %d\n",
189 old, *rwwriter_ptr);
190 rw_torture_result = 0;
191 }
192 old = *rwwriter_ptr;
193 }
194 if (CRYPTO_THREAD_unlock(rwtorturelock) == 0)
195 abort();
196 if (rw_torture_result == 0) {
197 *iterations = count;
198 return;
199 }
200 if (CRYPTO_THREAD_read_lock(rwtorturelock) == 0)
201 abort();
202 }
203 *iterations = count;
204 if (CRYPTO_THREAD_unlock(rwtorturelock) == 0)
205 abort();
206 }
207
rwreader1_fn(void)208 static void rwreader1_fn(void)
209 {
210 TEST_info("Starting reader 1");
211 rwreader_fn(&rwreader1_iterations);
212 }
213
rwreader2_fn(void)214 static void rwreader2_fn(void)
215 {
216 TEST_info("Starting reader 2");
217 rwreader_fn(&rwreader2_iterations);
218 }
219
220 static thread_t rwwriter1;
221 static thread_t rwwriter2;
222 static thread_t rwreader1;
223 static thread_t rwreader2;
224
_torture_rw(void)225 static int _torture_rw(void)
226 {
227 double tottime = 0;
228 int ret = 0;
229 double avr, avw;
230 OSSL_TIME t1, t2;
231 struct timeval dtime;
232
233 rwtorturelock = CRYPTO_THREAD_lock_new();
234 atomiclock = CRYPTO_THREAD_lock_new();
235 if (!TEST_ptr(rwtorturelock) || !TEST_ptr(atomiclock))
236 goto out;
237
238 rwwriter1_iterations = 0;
239 rwwriter2_iterations = 0;
240 rwreader1_iterations = 0;
241 rwreader2_iterations = 0;
242 rwwriter1_done = 0;
243 rwwriter2_done = 0;
244 rw_torture_result = 1;
245
246 memset(&rwwriter1, 0, sizeof(thread_t));
247 memset(&rwwriter2, 0, sizeof(thread_t));
248 memset(&rwreader1, 0, sizeof(thread_t));
249 memset(&rwreader2, 0, sizeof(thread_t));
250
251 TEST_info("Staring rw torture");
252 t1 = ossl_time_now();
253 if (!TEST_true(run_thread(&rwreader1, rwreader1_fn))
254 || !TEST_true(run_thread(&rwreader2, rwreader2_fn))
255 || !TEST_true(run_thread(&rwwriter1, rwwriter1_fn))
256 || !TEST_true(run_thread(&rwwriter2, rwwriter2_fn))
257 || !TEST_true(wait_for_thread(rwwriter1))
258 || !TEST_true(wait_for_thread(rwwriter2))
259 || !TEST_true(wait_for_thread(rwreader1))
260 || !TEST_true(wait_for_thread(rwreader2)))
261 goto out;
262
263 t2 = ossl_time_now();
264 dtime = ossl_time_to_timeval(ossl_time_subtract(t2, t1));
265 tottime = dtime.tv_sec + (dtime.tv_usec / 1e6);
266 TEST_info("rw_torture_result is %d\n", rw_torture_result);
267 TEST_info("performed %d reads and %d writes over 2 read and 2 write threads in %e seconds",
268 rwreader1_iterations + rwreader2_iterations,
269 rwwriter1_iterations + rwwriter2_iterations, tottime);
270 if ((rwreader1_iterations + rwreader2_iterations == 0)
271 || (rwwriter1_iterations + rwwriter2_iterations == 0)) {
272 TEST_info("Threads did not iterate\n");
273 goto out;
274 }
275 avr = tottime / (rwreader1_iterations + rwreader2_iterations);
276 avw = (tottime / (rwwriter1_iterations + rwwriter2_iterations));
277 TEST_info("Average read time %e/read", avr);
278 TEST_info("Averate write time %e/write", avw);
279
280 if (TEST_int_eq(rw_torture_result, 1))
281 ret = 1;
282 out:
283 CRYPTO_THREAD_lock_free(rwtorturelock);
284 CRYPTO_THREAD_lock_free(atomiclock);
285 rwtorturelock = NULL;
286 return ret;
287 }
288
torture_rw_low(void)289 static int torture_rw_low(void)
290 {
291 contention = 0;
292 return _torture_rw();
293 }
294
torture_rw_high(void)295 static int torture_rw_high(void)
296 {
297 contention = 1;
298 return _torture_rw();
299 }
300
301 static CRYPTO_RCU_LOCK *rcu_lock = NULL;
302
303 static int writer1_done = 0;
304 static int writer2_done = 0;
305 static int reader1_iterations = 0;
306 static int reader2_iterations = 0;
307 static int writer1_iterations = 0;
308 static int writer2_iterations = 0;
309 static uint64_t *writer_ptr = NULL;
310 static uint64_t global_ctr = 0;
311 static int rcu_torture_result = 1;
free_old_rcu_data(void * data)312 static void free_old_rcu_data(void *data)
313 {
314 CRYPTO_free(data, NULL, 0);
315 }
316
writer_fn(int id,int * iterations)317 static void writer_fn(int id, int *iterations)
318 {
319 int count;
320 OSSL_TIME t1, t2;
321 uint64_t *old, *new;
322 CRYPTO_RCU_CB_ITEM *cbi = NULL;
323
324 t1 = ossl_time_now();
325
326 for (count = 0;; count++) {
327 new = CRYPTO_malloc(sizeof(uint64_t), NULL, 0);
328 *new = (uint64_t)0xBAD;
329
330 if (contention == 0) {
331 cbi = ossl_rcu_cb_item_new();
332 OPENSSL_assert(cbi != NULL);
333 }
334
335 if (contention == 0)
336 OSSL_sleep(1000);
337 ossl_rcu_write_lock(rcu_lock);
338 old = ossl_rcu_deref(&writer_ptr);
339 TSAN_ACQUIRE(&writer_ptr);
340 *new = global_ctr++;
341 ossl_rcu_assign_ptr(&writer_ptr, &new);
342 if (contention == 0)
343 ossl_rcu_call(rcu_lock, cbi, free_old_rcu_data, old);
344 ossl_rcu_write_unlock(rcu_lock);
345 if (contention != 0) {
346 ossl_synchronize_rcu(rcu_lock);
347 CRYPTO_free(old, NULL, 0);
348 }
349 t2 = ossl_time_now();
350 if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= 4)
351 break;
352 }
353 *iterations = count;
354 return;
355 }
356
writer1_fn(void)357 static void writer1_fn(void)
358 {
359 int local;
360
361 TEST_info("Starting writer1");
362 writer_fn(1, &writer1_iterations);
363 CRYPTO_atomic_add(&writer1_done, 1, &local, atomiclock);
364 }
365
writer2_fn(void)366 static void writer2_fn(void)
367 {
368 int local;
369
370 TEST_info("Starting writer2");
371 writer_fn(2, &writer2_iterations);
372 CRYPTO_atomic_add(&writer2_done, 1, &local, atomiclock);
373 }
374
reader_fn(int * iterations)375 static void reader_fn(int *iterations)
376 {
377 unsigned int count = 0;
378 uint64_t *valp;
379 uint64_t val;
380 uint64_t oldval = 0;
381 int lw1 = 0;
382 int lw2 = 0;
383
384 while (lw1 != 1 || lw2 != 1) {
385 CRYPTO_atomic_add(&writer1_done, 0, &lw1, atomiclock);
386 CRYPTO_atomic_add(&writer2_done, 0, &lw2, atomiclock);
387 count++;
388 ossl_rcu_read_lock(rcu_lock);
389 valp = ossl_rcu_deref(&writer_ptr);
390 val = (valp == NULL) ? 0 : *valp;
391
392 if (oldval > val) {
393 TEST_info("rcu torture value went backwards! %llu : %llu", (unsigned long long)oldval, (unsigned long long)val);
394 if (valp == NULL)
395 TEST_info("ossl_rcu_deref did return NULL!");
396 rcu_torture_result = 0;
397 }
398 oldval = val; /* just try to deref the pointer */
399 ossl_rcu_read_unlock(rcu_lock);
400 if (rcu_torture_result == 0) {
401 *iterations = count;
402 return;
403 }
404 }
405 *iterations = count;
406 }
407
reader1_fn(void)408 static void reader1_fn(void)
409 {
410 TEST_info("Starting reader 1");
411 reader_fn(&reader1_iterations);
412 }
413
reader2_fn(void)414 static void reader2_fn(void)
415 {
416 TEST_info("Starting reader 2");
417 reader_fn(&reader2_iterations);
418 }
419
420 static thread_t writer1;
421 static thread_t writer2;
422 static thread_t reader1;
423 static thread_t reader2;
424
_torture_rcu(void)425 static int _torture_rcu(void)
426 {
427 OSSL_TIME t1, t2;
428 struct timeval dtime;
429 double tottime;
430 double avr, avw;
431 int rc = 0;
432
433 atomiclock = CRYPTO_THREAD_lock_new();
434 if (!TEST_ptr(atomiclock))
435 goto out;
436
437 memset(&writer1, 0, sizeof(thread_t));
438 memset(&writer2, 0, sizeof(thread_t));
439 memset(&reader1, 0, sizeof(thread_t));
440 memset(&reader2, 0, sizeof(thread_t));
441
442 writer1_iterations = 0;
443 writer2_iterations = 0;
444 reader1_iterations = 0;
445 reader2_iterations = 0;
446 writer1_done = 0;
447 writer2_done = 0;
448 rcu_torture_result = 1;
449
450 rcu_lock = ossl_rcu_lock_new(contention == 2 ? 4 : 1, NULL);
451 if (rcu_lock == NULL)
452 goto out;
453
454 TEST_info("Staring rcu torture");
455 t1 = ossl_time_now();
456 if (!TEST_true(run_thread(&reader1, reader1_fn))
457 || !TEST_true(run_thread(&reader2, reader2_fn))
458 || !TEST_true(run_thread(&writer1, writer1_fn))
459 || !TEST_true(run_thread(&writer2, writer2_fn))
460 || !TEST_true(wait_for_thread(writer1))
461 || !TEST_true(wait_for_thread(writer2))
462 || !TEST_true(wait_for_thread(reader1))
463 || !TEST_true(wait_for_thread(reader2)))
464 goto out;
465
466 t2 = ossl_time_now();
467 dtime = ossl_time_to_timeval(ossl_time_subtract(t2, t1));
468 tottime = dtime.tv_sec + (dtime.tv_usec / 1e6);
469 TEST_info("rcu_torture_result is %d\n", rcu_torture_result);
470 TEST_info("performed %d reads and %d writes over 2 read and 2 write threads in %e seconds",
471 reader1_iterations + reader2_iterations,
472 writer1_iterations + writer2_iterations, tottime);
473 if ((reader1_iterations + reader2_iterations == 0)
474 || (writer1_iterations + writer2_iterations == 0)) {
475 TEST_info("Threads did not iterate\n");
476 goto out;
477 }
478 avr = tottime / (reader1_iterations + reader2_iterations);
479 avw = tottime / (writer1_iterations + writer2_iterations);
480 TEST_info("Average read time %e/read", avr);
481 TEST_info("Average write time %e/write", avw);
482
483 if (!TEST_int_eq(rcu_torture_result, 1))
484 goto out;
485
486 rc = 1;
487 out:
488 ossl_rcu_lock_free(rcu_lock);
489 CRYPTO_THREAD_lock_free(atomiclock);
490 if (!TEST_int_eq(rcu_torture_result, 1))
491 return 0;
492
493 return rc;
494 }
495
torture_rcu_low(void)496 static int torture_rcu_low(void)
497 {
498 contention = 0;
499 return _torture_rcu();
500 }
501
torture_rcu_high(void)502 static int torture_rcu_high(void)
503 {
504 contention = 1;
505 return _torture_rcu();
506 }
507
torture_rcu_high2(void)508 static int torture_rcu_high2(void)
509 {
510 contention = 2;
511 return _torture_rcu();
512 }
513 #endif
514
515 static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
516 static unsigned once_run_count = 0;
517
once_do_run(void)518 static void once_do_run(void)
519 {
520 once_run_count++;
521 }
522
once_run_thread_cb(void)523 static void once_run_thread_cb(void)
524 {
525 CRYPTO_THREAD_run_once(&once_run, once_do_run);
526 }
527
test_once(void)528 static int test_once(void)
529 {
530 thread_t thread;
531
532 if (!TEST_true(run_thread(&thread, once_run_thread_cb))
533 || !TEST_true(wait_for_thread(thread))
534 || !CRYPTO_THREAD_run_once(&once_run, once_do_run)
535 || !TEST_int_eq(once_run_count, 1))
536 return 0;
537 return 1;
538 }
539
540 static CRYPTO_THREAD_LOCAL thread_local_key;
541 static unsigned destructor_run_count = 0;
542 static int thread_local_thread_cb_ok = 0;
543
thread_local_destructor(void * arg)544 static void thread_local_destructor(void *arg)
545 {
546 unsigned *count;
547
548 if (arg == NULL)
549 return;
550
551 count = arg;
552
553 (*count)++;
554 }
555
thread_local_thread_cb(void)556 static void thread_local_thread_cb(void)
557 {
558 void *ptr;
559
560 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
561 if (!TEST_ptr_null(ptr)
562 || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key,
563 &destructor_run_count)))
564 return;
565
566 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
567 if (!TEST_ptr_eq(ptr, &destructor_run_count))
568 return;
569
570 thread_local_thread_cb_ok = 1;
571 }
572
test_thread_local(void)573 static int test_thread_local(void)
574 {
575 thread_t thread;
576 void *ptr = NULL;
577
578 if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
579 thread_local_destructor)))
580 return 0;
581
582 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
583 if (!TEST_ptr_null(ptr)
584 || !TEST_true(run_thread(&thread, thread_local_thread_cb))
585 || !TEST_true(wait_for_thread(thread))
586 || !TEST_int_eq(thread_local_thread_cb_ok, 1))
587 return 0;
588
589 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
590
591 ptr = CRYPTO_THREAD_get_local(&thread_local_key);
592 if (!TEST_ptr_null(ptr))
593 return 0;
594
595 #if !defined(OPENSSL_SYS_WINDOWS)
596 if (!TEST_int_eq(destructor_run_count, 1))
597 return 0;
598 #endif
599 #endif
600
601 if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
602 return 0;
603 return 1;
604 }
605
606 /*
607 * Basic test to ensure that we can repeatedly create and
608 * destroy local keys without leaking anything
609 */
test_thread_local_multi_key(void)610 static int test_thread_local_multi_key(void)
611 {
612 int dummy;
613 int i;
614
615 for (i = 0; i < 1000; i++) {
616 if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
617 thread_local_destructor)))
618 return 0;
619
620 if (!TEST_true(CRYPTO_THREAD_set_local(&thread_local_key, &dummy)))
621 return 0;
622
623 if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
624 return 0;
625 }
626 return 1;
627 }
628
test_atomic(void)629 static int test_atomic(void)
630 {
631 int val = 0, ret = 0, testresult = 0;
632 uint64_t val64 = 1, ret64 = 0;
633 CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
634
635 if (!TEST_ptr(lock))
636 return 0;
637
638 if (CRYPTO_atomic_add(&val, 1, &ret, NULL)) {
639 /* This succeeds therefore we're on a platform with lockless atomics */
640 if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
641 goto err;
642 } else {
643 /* This failed therefore we're on a platform without lockless atomics */
644 if (!TEST_int_eq(val, 0) || !TEST_int_eq(val, ret))
645 goto err;
646 }
647 val = 0;
648 ret = 0;
649
650 if (!TEST_true(CRYPTO_atomic_add(&val, 1, &ret, lock)))
651 goto err;
652 if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
653 goto err;
654
655 if (CRYPTO_atomic_or(&val64, 2, &ret64, NULL)) {
656 /* This succeeds therefore we're on a platform with lockless atomics */
657 if (!TEST_uint_eq((unsigned int)val64, 3)
658 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
659 goto err;
660 } else {
661 /* This failed therefore we're on a platform without lockless atomics */
662 if (!TEST_uint_eq((unsigned int)val64, 1)
663 || !TEST_int_eq((unsigned int)ret64, 0))
664 goto err;
665 }
666 val64 = 1;
667 ret64 = 0;
668
669 if (!TEST_true(CRYPTO_atomic_or(&val64, 2, &ret64, lock)))
670 goto err;
671
672 if (!TEST_uint_eq((unsigned int)val64, 3)
673 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
674 goto err;
675
676 ret64 = 0;
677 if (CRYPTO_atomic_load(&val64, &ret64, NULL)) {
678 /* This succeeds therefore we're on a platform with lockless atomics */
679 if (!TEST_uint_eq((unsigned int)val64, 3)
680 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
681 goto err;
682 } else {
683 /* This failed therefore we're on a platform without lockless atomics */
684 if (!TEST_uint_eq((unsigned int)val64, 3)
685 || !TEST_int_eq((unsigned int)ret64, 0))
686 goto err;
687 }
688
689 ret64 = 0;
690 if (!TEST_true(CRYPTO_atomic_load(&val64, &ret64, lock)))
691 goto err;
692
693 if (!TEST_uint_eq((unsigned int)val64, 3)
694 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
695 goto err;
696
697 ret64 = 0;
698
699 if (CRYPTO_atomic_and(&val64, 5, &ret64, NULL)) {
700 /* This succeeds therefore we're on a platform with lockless atomics */
701 if (!TEST_uint_eq((unsigned int)val64, 1)
702 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
703 goto err;
704 } else {
705 /* This failed therefore we're on a platform without lockless atomics */
706 if (!TEST_uint_eq((unsigned int)val64, 3)
707 || !TEST_int_eq((unsigned int)ret64, 0))
708 goto err;
709 }
710 val64 = 3;
711 ret64 = 0;
712
713 if (!TEST_true(CRYPTO_atomic_and(&val64, 5, &ret64, lock)))
714 goto err;
715
716 if (!TEST_uint_eq((unsigned int)val64, 1)
717 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
718 goto err;
719
720 ret64 = 0;
721
722 if (CRYPTO_atomic_add64(&val64, 2, &ret64, NULL)) {
723 /* This succeeds therefore we're on a platform with lockless atomics */
724 if (!TEST_uint_eq((unsigned int)val64, 3)
725 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
726 goto err;
727 } else {
728 /* This failed therefore we're on a platform without lockless atomics */
729 if (!TEST_uint_eq((unsigned int)val64, 1)
730 || !TEST_int_eq((unsigned int)ret64, 0))
731 goto err;
732 }
733 val64 = 1;
734 ret64 = 0;
735
736 if (!TEST_true(CRYPTO_atomic_add64(&val64, 2, &ret64, lock)))
737 goto err;
738
739 if (!TEST_uint_eq((unsigned int)val64, 3)
740 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
741 goto err;
742
743 testresult = 1;
744 err:
745 CRYPTO_THREAD_lock_free(lock);
746 return testresult;
747 }
748
749 static OSSL_LIB_CTX *multi_libctx = NULL;
750 static int multi_success;
751 static OSSL_PROVIDER *multi_provider[MAXIMUM_PROVIDERS + 1];
752 static size_t multi_num_threads;
753 static thread_t multi_threads[MAXIMUM_THREADS];
754
multi_intialise(void)755 static void multi_intialise(void)
756 {
757 multi_success = 1;
758 multi_libctx = NULL;
759 multi_num_threads = 0;
760 memset(multi_threads, 0, sizeof(multi_threads));
761 memset(multi_provider, 0, sizeof(multi_provider));
762 }
763
multi_set_success(int ok)764 static void multi_set_success(int ok)
765 {
766 if (CRYPTO_THREAD_write_lock(global_lock) == 0) {
767 /* not synchronized, but better than not reporting failure */
768 multi_success = ok;
769 return;
770 }
771
772 multi_success = ok;
773
774 CRYPTO_THREAD_unlock(global_lock);
775 }
776
thead_teardown_libctx(void)777 static void thead_teardown_libctx(void)
778 {
779 OSSL_PROVIDER **p;
780
781 for (p = multi_provider; *p != NULL; p++)
782 OSSL_PROVIDER_unload(*p);
783 OSSL_LIB_CTX_free(multi_libctx);
784 multi_intialise();
785 }
786
thread_setup_libctx(int libctx,const char * providers[])787 static int thread_setup_libctx(int libctx, const char *providers[])
788 {
789 size_t n;
790
791 if (libctx && !TEST_true(test_get_libctx(&multi_libctx, NULL, config_file, NULL, NULL)))
792 return 0;
793
794 if (providers != NULL)
795 for (n = 0; providers[n] != NULL; n++)
796 if (!TEST_size_t_lt(n, MAXIMUM_PROVIDERS)
797 || !TEST_ptr(multi_provider[n] = OSSL_PROVIDER_load(multi_libctx,
798 providers[n]))) {
799 thead_teardown_libctx();
800 return 0;
801 }
802 return 1;
803 }
804
teardown_threads(void)805 static int teardown_threads(void)
806 {
807 size_t i;
808
809 for (i = 0; i < multi_num_threads; i++)
810 if (!TEST_true(wait_for_thread(multi_threads[i])))
811 return 0;
812 return 1;
813 }
814
start_threads(size_t n,void (* thread_func)(void))815 static int start_threads(size_t n, void (*thread_func)(void))
816 {
817 size_t i;
818
819 if (!TEST_size_t_le(multi_num_threads + n, MAXIMUM_THREADS))
820 return 0;
821
822 for (i = 0; i < n; i++)
823 if (!TEST_true(run_thread(multi_threads + multi_num_threads++, thread_func)))
824 return 0;
825 return 1;
826 }
827
828 /* Template multi-threaded test function */
thread_run_test(void (* main_func)(void),size_t num_threads,void (* thread_func)(void),int libctx,const char * providers[])829 static int thread_run_test(void (*main_func)(void),
830 size_t num_threads, void (*thread_func)(void),
831 int libctx, const char *providers[])
832 {
833 int testresult = 0;
834
835 multi_intialise();
836 if (!thread_setup_libctx(libctx, providers)
837 || !start_threads(num_threads, thread_func))
838 goto err;
839
840 if (main_func != NULL)
841 main_func();
842
843 if (!teardown_threads()
844 || !TEST_true(multi_success))
845 goto err;
846 testresult = 1;
847 err:
848 thead_teardown_libctx();
849 return testresult;
850 }
851
thread_general_worker(void)852 static void thread_general_worker(void)
853 {
854 EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
855 EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
856 EVP_CIPHER_CTX *cipherctx = EVP_CIPHER_CTX_new();
857 EVP_CIPHER *ciph = EVP_CIPHER_fetch(multi_libctx, "AES-128-CBC", NULL);
858 const char *message = "Hello World";
859 size_t messlen = strlen(message);
860 /* Should be big enough for encryption output too */
861 unsigned char out[EVP_MAX_MD_SIZE];
862 const unsigned char key[AES_BLOCK_SIZE] = {
863 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
864 0x0c, 0x0d, 0x0e, 0x0f
865 };
866 const unsigned char iv[AES_BLOCK_SIZE] = {
867 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
868 0x0c, 0x0d, 0x0e, 0x0f
869 };
870 unsigned int mdoutl;
871 int ciphoutl;
872 EVP_PKEY *pkey = NULL;
873 int testresult = 0;
874 int i, isfips;
875
876 isfips = OSSL_PROVIDER_available(multi_libctx, "fips");
877
878 if (!TEST_ptr(mdctx)
879 || !TEST_ptr(md)
880 || !TEST_ptr(cipherctx)
881 || !TEST_ptr(ciph))
882 goto err;
883
884 /* Do some work */
885 for (i = 0; i < 5; i++) {
886 if (!TEST_true(EVP_DigestInit_ex(mdctx, md, NULL))
887 || !TEST_true(EVP_DigestUpdate(mdctx, message, messlen))
888 || !TEST_true(EVP_DigestFinal(mdctx, out, &mdoutl)))
889 goto err;
890 }
891 for (i = 0; i < 5; i++) {
892 if (!TEST_true(EVP_EncryptInit_ex(cipherctx, ciph, NULL, key, iv))
893 || !TEST_true(EVP_EncryptUpdate(cipherctx, out, &ciphoutl,
894 (unsigned char *)message,
895 messlen))
896 || !TEST_true(EVP_EncryptFinal(cipherctx, out, &ciphoutl)))
897 goto err;
898 }
899
900 /*
901 * We want the test to run quickly - not securely.
902 * Therefore we use an insecure bit length where we can (512).
903 * In the FIPS module though we must use a longer length.
904 */
905 pkey = EVP_PKEY_Q_keygen(multi_libctx, NULL, "RSA", (size_t)(isfips ? 2048 : 512));
906 if (!TEST_ptr(pkey))
907 goto err;
908
909 testresult = 1;
910 err:
911 EVP_MD_CTX_free(mdctx);
912 EVP_MD_free(md);
913 EVP_CIPHER_CTX_free(cipherctx);
914 EVP_CIPHER_free(ciph);
915 EVP_PKEY_free(pkey);
916 if (!testresult)
917 multi_set_success(0);
918 }
919
thread_multi_simple_fetch(void)920 static void thread_multi_simple_fetch(void)
921 {
922 EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
923
924 if (md != NULL)
925 EVP_MD_free(md);
926 else
927 multi_set_success(0);
928 }
929
930 static EVP_PKEY *shared_evp_pkey = NULL;
931
thread_shared_evp_pkey(void)932 static void thread_shared_evp_pkey(void)
933 {
934 char *msg = "Hello World";
935 unsigned char ctbuf[256];
936 unsigned char ptbuf[256];
937 size_t ptlen, ctlen = sizeof(ctbuf);
938 EVP_PKEY_CTX *ctx = NULL;
939 int success = 0;
940 int i;
941
942 for (i = 0; i < 1 + do_fips; i++) {
943 if (i > 0)
944 EVP_PKEY_CTX_free(ctx);
945 ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey,
946 i == 0 ? "provider=default"
947 : "provider=fips");
948 if (!TEST_ptr(ctx))
949 goto err;
950
951 if (!TEST_int_ge(EVP_PKEY_encrypt_init(ctx), 0)
952 || !TEST_int_ge(EVP_PKEY_encrypt(ctx, ctbuf, &ctlen,
953 (unsigned char *)msg, strlen(msg)),
954 0))
955 goto err;
956
957 EVP_PKEY_CTX_free(ctx);
958 ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey, NULL);
959
960 if (!TEST_ptr(ctx))
961 goto err;
962
963 ptlen = sizeof(ptbuf);
964 if (!TEST_int_ge(EVP_PKEY_decrypt_init(ctx), 0)
965 || !TEST_int_gt(EVP_PKEY_decrypt(ctx, ptbuf, &ptlen, ctbuf, ctlen),
966 0)
967 || !TEST_mem_eq(msg, strlen(msg), ptbuf, ptlen))
968 goto err;
969 }
970
971 success = 1;
972
973 err:
974 EVP_PKEY_CTX_free(ctx);
975 if (!success)
976 multi_set_success(0);
977 }
978
thread_provider_load_unload(void)979 static void thread_provider_load_unload(void)
980 {
981 OSSL_PROVIDER *deflt = OSSL_PROVIDER_load(multi_libctx, "default");
982
983 if (!TEST_ptr(deflt)
984 || !TEST_true(OSSL_PROVIDER_available(multi_libctx, "default")))
985 multi_set_success(0);
986
987 OSSL_PROVIDER_unload(deflt);
988 }
989
test_multi_general_worker_default_provider(void)990 static int test_multi_general_worker_default_provider(void)
991 {
992 return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
993 1, default_provider);
994 }
995
test_multi_general_worker_fips_provider(void)996 static int test_multi_general_worker_fips_provider(void)
997 {
998 if (!do_fips)
999 return TEST_skip("FIPS not supported");
1000 return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
1001 1, fips_provider);
1002 }
1003
test_multi_fetch_worker(void)1004 static int test_multi_fetch_worker(void)
1005 {
1006 return thread_run_test(&thread_multi_simple_fetch,
1007 2, &thread_multi_simple_fetch, 1, default_provider);
1008 }
1009
test_multi_shared_pkey_common(void (* worker)(void))1010 static int test_multi_shared_pkey_common(void (*worker)(void))
1011 {
1012 int testresult = 0;
1013
1014 multi_intialise();
1015 if (!thread_setup_libctx(1, do_fips ? fips_and_default_providers : default_provider)
1016 || !TEST_ptr(shared_evp_pkey = load_pkey_pem(privkey, multi_libctx))
1017 || !start_threads(1, &thread_shared_evp_pkey)
1018 || !start_threads(1, worker))
1019 goto err;
1020
1021 thread_shared_evp_pkey();
1022
1023 if (!teardown_threads()
1024 || !TEST_true(multi_success))
1025 goto err;
1026 testresult = 1;
1027 err:
1028 EVP_PKEY_free(shared_evp_pkey);
1029 thead_teardown_libctx();
1030 return testresult;
1031 }
1032
1033 #ifndef OPENSSL_NO_DEPRECATED_3_0
thread_downgrade_shared_evp_pkey(void)1034 static void thread_downgrade_shared_evp_pkey(void)
1035 {
1036 /*
1037 * This test is only relevant for deprecated functions that perform
1038 * downgrading
1039 */
1040 if (EVP_PKEY_get0_RSA(shared_evp_pkey) == NULL)
1041 multi_set_success(0);
1042 }
1043
test_multi_downgrade_shared_pkey(void)1044 static int test_multi_downgrade_shared_pkey(void)
1045 {
1046 return test_multi_shared_pkey_common(&thread_downgrade_shared_evp_pkey);
1047 }
1048 #endif
1049
test_multi_shared_pkey(void)1050 static int test_multi_shared_pkey(void)
1051 {
1052 return test_multi_shared_pkey_common(&thread_shared_evp_pkey);
1053 }
1054
thread_release_shared_pkey(void)1055 static void thread_release_shared_pkey(void)
1056 {
1057 OSSL_sleep(0);
1058 EVP_PKEY_free(shared_evp_pkey);
1059 }
1060
test_multi_shared_pkey_release(void)1061 static int test_multi_shared_pkey_release(void)
1062 {
1063 int testresult = 0;
1064 size_t i = 1;
1065
1066 multi_intialise();
1067 shared_evp_pkey = NULL;
1068 if (!thread_setup_libctx(1, do_fips ? fips_and_default_providers : default_provider)
1069 || !TEST_ptr(shared_evp_pkey = load_pkey_pem(privkey, multi_libctx)))
1070 goto err;
1071 for (; i < 10; ++i) {
1072 if (!TEST_true(EVP_PKEY_up_ref(shared_evp_pkey)))
1073 goto err;
1074 }
1075
1076 if (!start_threads(10, &thread_release_shared_pkey))
1077 goto err;
1078 i = 0;
1079
1080 if (!teardown_threads()
1081 || !TEST_true(multi_success))
1082 goto err;
1083 testresult = 1;
1084 err:
1085 while (i > 0) {
1086 EVP_PKEY_free(shared_evp_pkey);
1087 --i;
1088 }
1089 thead_teardown_libctx();
1090 return testresult;
1091 }
1092
test_multi_load_unload_provider(void)1093 static int test_multi_load_unload_provider(void)
1094 {
1095 EVP_MD *sha256 = NULL;
1096 OSSL_PROVIDER *prov = NULL;
1097 int testresult = 0;
1098
1099 multi_intialise();
1100 if (!thread_setup_libctx(1, NULL)
1101 || !TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, "default"))
1102 || !TEST_ptr(sha256 = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL))
1103 || !TEST_true(OSSL_PROVIDER_unload(prov)))
1104 goto err;
1105 prov = NULL;
1106
1107 if (!start_threads(2, &thread_provider_load_unload))
1108 goto err;
1109
1110 thread_provider_load_unload();
1111
1112 if (!teardown_threads()
1113 || !TEST_true(multi_success))
1114 goto err;
1115 testresult = 1;
1116 err:
1117 OSSL_PROVIDER_unload(prov);
1118 EVP_MD_free(sha256);
1119 thead_teardown_libctx();
1120 return testresult;
1121 }
1122
1123 static char *multi_load_provider = "legacy";
1124 /*
1125 * This test attempts to load several providers at the same time, and if
1126 * run with a thread sanitizer, should crash if the core provider code
1127 * doesn't synchronize well enough.
1128 */
test_multi_load_worker(void)1129 static void test_multi_load_worker(void)
1130 {
1131 OSSL_PROVIDER *prov;
1132
1133 if (!TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, multi_load_provider))
1134 || !TEST_true(OSSL_PROVIDER_unload(prov)))
1135 multi_set_success(0);
1136 }
1137
test_multi_default(void)1138 static int test_multi_default(void)
1139 {
1140 /* Avoid running this test twice */
1141 if (multidefault_run) {
1142 TEST_skip("multi default test already run");
1143 return 1;
1144 }
1145 multidefault_run = 1;
1146
1147 return thread_run_test(&thread_multi_simple_fetch,
1148 2, &thread_multi_simple_fetch, 0, NULL);
1149 }
1150
test_multi_load(void)1151 static int test_multi_load(void)
1152 {
1153 int res = 1;
1154 OSSL_PROVIDER *prov;
1155
1156 /* The multidefault test must run prior to this test */
1157 if (!multidefault_run) {
1158 TEST_info("Running multi default test first");
1159 res = test_multi_default();
1160 }
1161
1162 /*
1163 * We use the legacy provider in test_multi_load_worker because it uses a
1164 * child libctx that might hit more codepaths that might be sensitive to
1165 * threading issues. But in a no-legacy build that won't be loadable so
1166 * we use the default provider instead.
1167 */
1168 prov = OSSL_PROVIDER_load(NULL, "legacy");
1169 if (prov == NULL) {
1170 TEST_info("Cannot load legacy provider - assuming this is a no-legacy build");
1171 multi_load_provider = "default";
1172 }
1173 OSSL_PROVIDER_unload(prov);
1174
1175 return thread_run_test(NULL, MAXIMUM_THREADS, &test_multi_load_worker, 0,
1176 NULL)
1177 && res;
1178 }
1179
test_obj_create_one(void)1180 static void test_obj_create_one(void)
1181 {
1182 char tids[12], oid[40], sn[30], ln[30];
1183 int id = get_new_uid();
1184
1185 BIO_snprintf(tids, sizeof(tids), "%d", id);
1186 BIO_snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids);
1187 BIO_snprintf(sn, sizeof(sn), "short-name-%s", tids);
1188 BIO_snprintf(ln, sizeof(ln), "long-name-%s", tids);
1189 if (!TEST_int_ne(id, 0)
1190 || !TEST_true(id = OBJ_create(oid, sn, ln))
1191 || !TEST_true(OBJ_add_sigid(id, NID_sha3_256, NID_rsa)))
1192 multi_set_success(0);
1193 }
1194
test_obj_add(void)1195 static int test_obj_add(void)
1196 {
1197 return thread_run_test(&test_obj_create_one,
1198 MAXIMUM_THREADS, &test_obj_create_one,
1199 1, default_provider);
1200 }
1201
1202 #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
1203 static BIO *multi_bio1, *multi_bio2;
1204
test_bio_dgram_pair_worker(void)1205 static void test_bio_dgram_pair_worker(void)
1206 {
1207 ossl_unused int r;
1208 int ok = 0;
1209 uint8_t ch = 0;
1210 uint8_t scratch[64];
1211 BIO_MSG msg = { 0 };
1212 size_t num_processed = 0;
1213
1214 if (!TEST_int_eq(RAND_bytes_ex(multi_libctx, &ch, 1, 64), 1))
1215 goto err;
1216
1217 msg.data = scratch;
1218 msg.data_len = sizeof(scratch);
1219
1220 /*
1221 * We do not test for failure here as recvmmsg may fail if no sendmmsg
1222 * has been called yet. The purpose of this code is to exercise tsan.
1223 */
1224 if (ch & 2)
1225 r = BIO_sendmmsg(ch & 1 ? multi_bio2 : multi_bio1, &msg,
1226 sizeof(BIO_MSG), 1, 0, &num_processed);
1227 else
1228 r = BIO_recvmmsg(ch & 1 ? multi_bio2 : multi_bio1, &msg,
1229 sizeof(BIO_MSG), 1, 0, &num_processed);
1230
1231 ok = 1;
1232 err:
1233 if (ok == 0)
1234 multi_set_success(0);
1235 }
1236
test_bio_dgram_pair(void)1237 static int test_bio_dgram_pair(void)
1238 {
1239 int r;
1240 BIO *bio1 = NULL, *bio2 = NULL;
1241
1242 r = BIO_new_bio_dgram_pair(&bio1, 0, &bio2, 0);
1243 if (!TEST_int_eq(r, 1))
1244 goto err;
1245
1246 multi_bio1 = bio1;
1247 multi_bio2 = bio2;
1248
1249 r = thread_run_test(&test_bio_dgram_pair_worker,
1250 MAXIMUM_THREADS, &test_bio_dgram_pair_worker,
1251 1, default_provider);
1252
1253 err:
1254 BIO_free(bio1);
1255 BIO_free(bio2);
1256 return r;
1257 }
1258 #endif
1259
1260 static const char *pemdataraw[] = {
1261 "-----BEGIN RSA PRIVATE KEY-----\n",
1262 "MIIBOgIBAAJBAMFcGsaxxdgiuuGmCkVImy4h99CqT7jwY3pexPGcnUFtR2Fh36Bp\n",
1263 "oncwtkZ4cAgtvd4Qs8PkxUdp6p/DlUmObdkCAwEAAQJAUR44xX6zB3eaeyvTRzms\n",
1264 "kHADrPCmPWnr8dxsNwiDGHzrMKLN+i/HAam+97HxIKVWNDH2ba9Mf1SA8xu9dcHZ\n",
1265 "AQIhAOHPCLxbtQFVxlnhSyxYeb7O323c3QulPNn3bhOipElpAiEA2zZpBE8ZXVnL\n",
1266 "74QjG4zINlDfH+EOEtjJJ3RtaYDugvECIBtsQDxXytChsRgDQ1TcXdStXPcDppie\n",
1267 "dZhm8yhRTTBZAiAZjE/U9rsIDC0ebxIAZfn3iplWh84yGB3pgUI3J5WkoQIhAInE\n",
1268 "HTUY5WRj5riZtkyGnbm3DvF+1eMtO2lYV+OuLcfE\n",
1269 "-----END RSA PRIVATE KEY-----\n",
1270 NULL
1271 };
1272
test_pem_read_one(void)1273 static void test_pem_read_one(void)
1274 {
1275 EVP_PKEY *key = NULL;
1276 BIO *pem = NULL;
1277 char *pemdata;
1278 size_t len;
1279
1280 pemdata = glue_strings(pemdataraw, &len);
1281 if (pemdata == NULL) {
1282 multi_set_success(0);
1283 goto err;
1284 }
1285
1286 pem = BIO_new_mem_buf(pemdata, len);
1287 if (pem == NULL) {
1288 multi_set_success(0);
1289 goto err;
1290 }
1291
1292 key = PEM_read_bio_PrivateKey(pem, NULL, NULL, NULL);
1293 if (key == NULL)
1294 multi_set_success(0);
1295
1296 err:
1297 EVP_PKEY_free(key);
1298 BIO_free(pem);
1299 OPENSSL_free(pemdata);
1300 }
1301
1302 /* Test reading PEM files in multiple threads */
test_pem_read(void)1303 static int test_pem_read(void)
1304 {
1305 return thread_run_test(&test_pem_read_one, MAXIMUM_THREADS,
1306 &test_pem_read_one, 1, default_provider);
1307 }
1308
1309 static X509_STORE *store = NULL;
1310
test_x509_store_by_subject(void)1311 static void test_x509_store_by_subject(void)
1312 {
1313 X509_STORE_CTX *ctx;
1314 X509_OBJECT *obj = NULL;
1315 X509_NAME *name = NULL;
1316 int success = 0;
1317
1318 ctx = X509_STORE_CTX_new();
1319 if (!TEST_ptr(ctx))
1320 goto err;
1321
1322 if (!TEST_true(X509_STORE_CTX_init(ctx, store, NULL, NULL)))
1323 goto err;
1324
1325 name = X509_NAME_new();
1326 if (!TEST_ptr(name))
1327 goto err;
1328 if (!TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1329 (unsigned char *)"Root CA",
1330 -1, -1, 0)))
1331 goto err;
1332 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name);
1333 if (!TEST_ptr(obj))
1334 goto err;
1335
1336 success = 1;
1337 err:
1338 X509_OBJECT_free(obj);
1339 X509_STORE_CTX_free(ctx);
1340 X509_NAME_free(name);
1341 if (!success)
1342 multi_set_success(0);
1343 }
1344
1345 /* Test accessing an X509_STORE from multiple threads */
test_x509_store(void)1346 static int test_x509_store(void)
1347 {
1348 int ret = 0;
1349
1350 store = X509_STORE_new();
1351 if (!TEST_ptr(store))
1352 return 0;
1353 if (!TEST_true(X509_STORE_load_store(store, storedir)))
1354 goto err;
1355
1356 ret = thread_run_test(&test_x509_store_by_subject, MAXIMUM_THREADS,
1357 &test_x509_store_by_subject, 0, NULL);
1358
1359 err:
1360 X509_STORE_free(store);
1361 store = NULL;
1362 return ret;
1363 }
1364
1365 typedef enum OPTION_choice {
1366 OPT_ERR = -1,
1367 OPT_EOF = 0,
1368 OPT_FIPS,
1369 OPT_CONFIG_FILE,
1370 OPT_TEST_ENUM
1371 } OPTION_CHOICE;
1372
test_get_options(void)1373 const OPTIONS *test_get_options(void)
1374 {
1375 static const OPTIONS options[] = {
1376 OPT_TEST_OPTIONS_DEFAULT_USAGE,
1377 { "fips", OPT_FIPS, '-', "Test the FIPS provider" },
1378 { "config", OPT_CONFIG_FILE, '<',
1379 "The configuration file to use for the libctx" },
1380 { NULL }
1381 };
1382 return options;
1383 }
1384
setup_tests(void)1385 int setup_tests(void)
1386 {
1387 OPTION_CHOICE o;
1388 char *datadir;
1389
1390 while ((o = opt_next()) != OPT_EOF) {
1391 switch (o) {
1392 case OPT_FIPS:
1393 do_fips = 1;
1394 break;
1395 case OPT_CONFIG_FILE:
1396 config_file = opt_arg();
1397 break;
1398 case OPT_TEST_CASES:
1399 break;
1400 default:
1401 return 0;
1402 }
1403 }
1404
1405 if (!TEST_ptr(datadir = test_get_argument(0)))
1406 return 0;
1407
1408 privkey = test_mk_file_path(datadir, "rsakey.pem");
1409 if (!TEST_ptr(privkey))
1410 return 0;
1411
1412 storedir = test_mk_file_path(datadir, "store");
1413 if (!TEST_ptr(storedir))
1414 return 0;
1415
1416 if (!TEST_ptr(global_lock = CRYPTO_THREAD_lock_new()))
1417 return 0;
1418
1419 #ifdef TSAN_REQUIRES_LOCKING
1420 if (!TEST_ptr(tsan_lock = CRYPTO_THREAD_lock_new()))
1421 return 0;
1422 #endif
1423
1424 /* Keep first to validate auto creation of default library context */
1425 ADD_TEST(test_multi_default);
1426
1427 ADD_TEST(test_lock);
1428 #if defined(OPENSSL_THREADS)
1429 ADD_TEST(torture_rw_low);
1430 ADD_TEST(torture_rw_high);
1431 ADD_TEST(torture_rcu_low);
1432 ADD_TEST(torture_rcu_high);
1433 ADD_TEST(torture_rcu_high2);
1434 #endif
1435 ADD_TEST(test_once);
1436 ADD_TEST(test_thread_local);
1437 ADD_TEST(test_thread_local_multi_key);
1438 ADD_TEST(test_atomic);
1439 ADD_TEST(test_multi_load);
1440 ADD_TEST(test_multi_general_worker_default_provider);
1441 ADD_TEST(test_multi_general_worker_fips_provider);
1442 ADD_TEST(test_multi_fetch_worker);
1443 ADD_TEST(test_multi_shared_pkey);
1444 #ifndef OPENSSL_NO_DEPRECATED_3_0
1445 ADD_TEST(test_multi_downgrade_shared_pkey);
1446 #endif
1447 ADD_TEST(test_multi_shared_pkey_release);
1448 ADD_TEST(test_multi_load_unload_provider);
1449 ADD_TEST(test_obj_add);
1450 #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
1451 ADD_TEST(test_bio_dgram_pair);
1452 #endif
1453 ADD_TEST(test_pem_read);
1454 ADD_TEST(test_x509_store);
1455 return 1;
1456 }
1457
cleanup_tests(void)1458 void cleanup_tests(void)
1459 {
1460 OPENSSL_free(privkey);
1461 OPENSSL_free(storedir);
1462 #ifdef TSAN_REQUIRES_LOCKING
1463 CRYPTO_THREAD_lock_free(tsan_lock);
1464 #endif
1465 CRYPTO_THREAD_lock_free(global_lock);
1466 }
1467