Fix printing of PROXY_CERT_INFO_EXTENSION to not assume NUL terminated strings
[openssl.git] / test / threadstest.c
1 /*
2  * Copyright 2016-2021 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 /* test_multi below tests the thread safety of a deprecated function */
11 #define OPENSSL_SUPPRESS_DEPRECATED
12
13 #if defined(_WIN32)
14 # include <windows.h>
15 #endif
16
17 #include <string.h>
18 #include <openssl/crypto.h>
19 #include <openssl/rsa.h>
20 #include <openssl/aes.h>
21 #include <openssl/rsa.h>
22 #include "testutil.h"
23 #include "threadstest.h"
24
25 static int do_fips = 0;
26 static char *privkey;
27 static char *config_file = NULL;
28 static int multidefault_run = 0;
29
30 static int test_lock(void)
31 {
32     CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
33     int res;
34
35     res = TEST_true(CRYPTO_THREAD_read_lock(lock))
36           && TEST_true(CRYPTO_THREAD_unlock(lock));
37
38     CRYPTO_THREAD_lock_free(lock);
39
40     return res;
41 }
42
43 static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
44 static unsigned once_run_count = 0;
45
46 static void once_do_run(void)
47 {
48     once_run_count++;
49 }
50
51 static void once_run_thread_cb(void)
52 {
53     CRYPTO_THREAD_run_once(&once_run, once_do_run);
54 }
55
56 static int test_once(void)
57 {
58     thread_t thread;
59
60     if (!TEST_true(run_thread(&thread, once_run_thread_cb))
61         || !TEST_true(wait_for_thread(thread))
62         || !CRYPTO_THREAD_run_once(&once_run, once_do_run)
63         || !TEST_int_eq(once_run_count, 1))
64         return 0;
65     return 1;
66 }
67
68 static CRYPTO_THREAD_LOCAL thread_local_key;
69 static unsigned destructor_run_count = 0;
70 static int thread_local_thread_cb_ok = 0;
71
72 static void thread_local_destructor(void *arg)
73 {
74     unsigned *count;
75
76     if (arg == NULL)
77         return;
78
79     count = arg;
80
81     (*count)++;
82 }
83
84 static void thread_local_thread_cb(void)
85 {
86     void *ptr;
87
88     ptr = CRYPTO_THREAD_get_local(&thread_local_key);
89     if (!TEST_ptr_null(ptr)
90         || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key,
91                                               &destructor_run_count)))
92         return;
93
94     ptr = CRYPTO_THREAD_get_local(&thread_local_key);
95     if (!TEST_ptr_eq(ptr, &destructor_run_count))
96         return;
97
98     thread_local_thread_cb_ok = 1;
99 }
100
101 static int test_thread_local(void)
102 {
103     thread_t thread;
104     void *ptr = NULL;
105
106     if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
107                                             thread_local_destructor)))
108         return 0;
109
110     ptr = CRYPTO_THREAD_get_local(&thread_local_key);
111     if (!TEST_ptr_null(ptr)
112         || !TEST_true(run_thread(&thread, thread_local_thread_cb))
113         || !TEST_true(wait_for_thread(thread))
114         || !TEST_int_eq(thread_local_thread_cb_ok, 1))
115         return 0;
116
117 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
118
119     ptr = CRYPTO_THREAD_get_local(&thread_local_key);
120     if (!TEST_ptr_null(ptr))
121         return 0;
122
123 # if !defined(OPENSSL_SYS_WINDOWS)
124     if (!TEST_int_eq(destructor_run_count, 1))
125         return 0;
126 # endif
127 #endif
128
129     if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
130         return 0;
131     return 1;
132 }
133
134 static int test_atomic(void)
135 {
136     int val = 0, ret = 0, testresult = 0;
137     uint64_t val64 = 1, ret64 = 0;
138     CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
139
140     if (!TEST_ptr(lock))
141         return 0;
142
143     if (CRYPTO_atomic_add(&val, 1, &ret, NULL)) {
144         /* This succeeds therefore we're on a platform with lockless atomics */
145         if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
146             goto err;
147     } else {
148         /* This failed therefore we're on a platform without lockless atomics */
149         if (!TEST_int_eq(val, 0) || !TEST_int_eq(val, ret))
150             goto err;
151     }
152     val = 0;
153     ret = 0;
154
155     if (!TEST_true(CRYPTO_atomic_add(&val, 1, &ret, lock)))
156         goto err;
157     if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
158         goto err;
159
160     if (CRYPTO_atomic_or(&val64, 2, &ret64, NULL)) {
161         /* This succeeds therefore we're on a platform with lockless atomics */
162         if (!TEST_uint_eq((unsigned int)val64, 3)
163                 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
164             goto err;
165     } else {
166         /* This failed therefore we're on a platform without lockless atomics */
167         if (!TEST_uint_eq((unsigned int)val64, 1)
168                 || !TEST_int_eq((unsigned int)ret64, 0))
169             goto err;
170     }
171     val64 = 1;
172     ret64 = 0;
173
174     if (!TEST_true(CRYPTO_atomic_or(&val64, 2, &ret64, lock)))
175         goto err;
176
177     if (!TEST_uint_eq((unsigned int)val64, 3)
178             || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
179         goto err;
180
181     ret64 = 0;
182     if (CRYPTO_atomic_load(&val64, &ret64, NULL)) {
183         /* This succeeds therefore we're on a platform with lockless atomics */
184         if (!TEST_uint_eq((unsigned int)val64, 3)
185                 || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
186             goto err;
187     } else {
188         /* This failed therefore we're on a platform without lockless atomics */
189         if (!TEST_uint_eq((unsigned int)val64, 3)
190                 || !TEST_int_eq((unsigned int)ret64, 0))
191             goto err;
192     }
193
194     ret64 = 0;
195     if (!TEST_true(CRYPTO_atomic_load(&val64, &ret64, lock)))
196         goto err;
197
198     if (!TEST_uint_eq((unsigned int)val64, 3)
199             || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
200         goto err;
201
202     testresult = 1;
203  err:
204     CRYPTO_THREAD_lock_free(lock);
205     return testresult;
206 }
207
208 static OSSL_LIB_CTX *multi_libctx = NULL;
209 static int multi_success;
210
211 static void thread_general_worker(void)
212 {
213     EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
214     EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
215     EVP_CIPHER_CTX *cipherctx = EVP_CIPHER_CTX_new();
216     EVP_CIPHER *ciph = EVP_CIPHER_fetch(multi_libctx, "AES-128-CBC", NULL);
217     const char *message = "Hello World";
218     size_t messlen = strlen(message);
219     /* Should be big enough for encryption output too */
220     unsigned char out[EVP_MAX_MD_SIZE];
221     const unsigned char key[AES_BLOCK_SIZE] = {
222         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
223         0x0c, 0x0d, 0x0e, 0x0f
224     };
225     const unsigned char iv[AES_BLOCK_SIZE] = {
226         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
227         0x0c, 0x0d, 0x0e, 0x0f
228     };
229     unsigned int mdoutl;
230     int ciphoutl;
231     EVP_PKEY *pkey = NULL;
232     int testresult = 0;
233     int i, isfips;
234
235     isfips = OSSL_PROVIDER_available(multi_libctx, "fips");
236
237     if (!TEST_ptr(mdctx)
238             || !TEST_ptr(md)
239             || !TEST_ptr(cipherctx)
240             || !TEST_ptr(ciph))
241         goto err;
242
243     /* Do some work */
244     for (i = 0; i < 5; i++) {
245         if (!TEST_true(EVP_DigestInit_ex(mdctx, md, NULL))
246                 || !TEST_true(EVP_DigestUpdate(mdctx, message, messlen))
247                 || !TEST_true(EVP_DigestFinal(mdctx, out, &mdoutl)))
248             goto err;
249     }
250     for (i = 0; i < 5; i++) {
251         if (!TEST_true(EVP_EncryptInit_ex(cipherctx, ciph, NULL, key, iv))
252                 || !TEST_true(EVP_EncryptUpdate(cipherctx, out, &ciphoutl,
253                                                 (unsigned char *)message,
254                                                 messlen))
255                 || !TEST_true(EVP_EncryptFinal(cipherctx, out, &ciphoutl)))
256             goto err;
257     }
258
259     /*
260      * We want the test to run quickly - not securely.
261      * Therefore we use an insecure bit length where we can (512).
262      * In the FIPS module though we must use a longer length.
263      */
264     pkey = EVP_PKEY_Q_keygen(multi_libctx, NULL, "RSA", isfips ? 2048 : 512);
265     if (!TEST_ptr(pkey))
266         goto err;
267
268     testresult = 1;
269  err:
270     EVP_MD_CTX_free(mdctx);
271     EVP_MD_free(md);
272     EVP_CIPHER_CTX_free(cipherctx);
273     EVP_CIPHER_free(ciph);
274     EVP_PKEY_free(pkey);
275     if (!testresult)
276         multi_success = 0;
277 }
278
279 static void thread_multi_simple_fetch(void)
280 {
281     EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
282
283     if (md != NULL)
284         EVP_MD_free(md);
285     else
286         multi_success = 0;
287 }
288
289 static EVP_PKEY *shared_evp_pkey = NULL;
290
291 static void thread_shared_evp_pkey(void)
292 {
293     char *msg = "Hello World";
294     unsigned char ctbuf[256];
295     unsigned char ptbuf[256];
296     size_t ptlen = sizeof(ptbuf), ctlen = sizeof(ctbuf);
297     EVP_PKEY_CTX *ctx = NULL;
298     int success = 0;
299     int i;
300
301     for (i = 0; i < 1 + do_fips; i++) {
302         if (i > 0)
303             EVP_PKEY_CTX_free(ctx);
304         ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey,
305                                          i == 0 ? "provider=default"
306                                                 : "provider=fips");
307         if (!TEST_ptr(ctx))
308             goto err;
309
310         if (!TEST_int_ge(EVP_PKEY_encrypt_init(ctx), 0)
311                 || !TEST_int_ge(EVP_PKEY_encrypt(ctx, ctbuf, &ctlen,
312                                                 (unsigned char *)msg, strlen(msg)),
313                                                 0))
314             goto err;
315
316         EVP_PKEY_CTX_free(ctx);
317         ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey, NULL);
318
319         if (!TEST_ptr(ctx))
320             goto err;
321
322         if (!TEST_int_ge(EVP_PKEY_decrypt_init(ctx), 0)
323                 || !TEST_int_ge(EVP_PKEY_decrypt(ctx, ptbuf, &ptlen, ctbuf, ctlen),
324                                                 0)
325                 || !TEST_mem_eq(msg, strlen(msg), ptbuf, ptlen))
326             goto err;
327     }
328
329     success = 1;
330
331  err:
332     EVP_PKEY_CTX_free(ctx);
333     if (!success)
334         multi_success = 0;
335 }
336
337 static void thread_downgrade_shared_evp_pkey(void)
338 {
339 #ifndef OPENSSL_NO_DEPRECATED_3_0
340     /*
341      * This test is only relevant for deprecated functions that perform
342      * downgrading
343      */
344     if (EVP_PKEY_get0_RSA(shared_evp_pkey) == NULL)
345         multi_success = 0;
346 #else
347     /* Shouldn't ever get here */
348     multi_success = 0;
349 #endif
350 }
351
352 static void thread_provider_load_unload(void)
353 {
354     OSSL_PROVIDER *deflt = OSSL_PROVIDER_load(multi_libctx, "default");
355
356     if (!TEST_ptr(deflt)
357             || !TEST_true(OSSL_PROVIDER_available(multi_libctx, "default")))
358         multi_success = 0;
359
360     OSSL_PROVIDER_unload(deflt);
361 }
362
363 /*
364  * Do work in multiple worker threads at the same time.
365  * Test 0: General worker, using the default provider
366  * Test 1: General worker, using the fips provider
367  * Test 2: Simple fetch worker
368  * Test 3: Worker downgrading a shared EVP_PKEY
369  * Test 4: Worker using a shared EVP_PKEY
370  * Test 5: Worker loading and unloading a provider
371  */
372 static int test_multi(int idx)
373 {
374     thread_t thread1, thread2;
375     int testresult = 0;
376     OSSL_PROVIDER *prov = NULL, *prov2 = NULL;
377     void (*worker)(void) = NULL;
378     void (*worker2)(void) = NULL;
379     EVP_MD *sha256 = NULL;
380
381     if (idx == 1 && !do_fips)
382         return TEST_skip("FIPS not supported");
383
384 #ifdef OPENSSL_NO_DEPRECATED_3_0
385     if (idx == 3)
386         return TEST_skip("Skipping tests for deprected functions");
387 #endif
388
389     multi_success = 1;
390     if (!TEST_true(test_get_libctx(&multi_libctx, NULL, config_file,
391                                    NULL, NULL)))
392         return 0;
393
394     prov = OSSL_PROVIDER_load(multi_libctx, (idx == 1) ? "fips" : "default");
395     if (!TEST_ptr(prov))
396         goto err;
397
398     switch (idx) {
399     case 0:
400     case 1:
401         worker = thread_general_worker;
402         break;
403     case 2:
404         worker = thread_multi_simple_fetch;
405         break;
406     case 3:
407         worker2 = thread_downgrade_shared_evp_pkey;
408         /* fall through */
409     case 4:
410         /*
411          * If available we have both the default and fips providers for this
412          * test
413          */
414         if (do_fips
415                 && !TEST_ptr(prov2 = OSSL_PROVIDER_load(multi_libctx, "fips")))
416             goto err;
417         if (!TEST_ptr(shared_evp_pkey = load_pkey_pem(privkey, multi_libctx)))
418             goto err;
419         worker = thread_shared_evp_pkey;
420         break;
421     case 5:
422         /*
423          * We ensure we get an md from the default provider, and then unload the
424          * provider. This ensures the provider remains around but in a
425          * deactivated state.
426          */
427         sha256 = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
428         OSSL_PROVIDER_unload(prov);
429         prov = NULL;
430         worker = thread_provider_load_unload;
431         break;
432     default:
433         TEST_error("Invalid test index");
434         goto err;
435     }
436     if (worker2 == NULL)
437         worker2 = worker;
438
439     if (!TEST_true(run_thread(&thread1, worker))
440             || !TEST_true(run_thread(&thread2, worker2)))
441         goto err;
442
443     worker();
444
445     testresult = 1;
446     /*
447      * Don't combine these into one if statement; must wait for both threads.
448      */
449     if (!TEST_true(wait_for_thread(thread1)))
450         testresult = 0;
451     if (!TEST_true(wait_for_thread(thread2)))
452         testresult = 0;
453     if (!TEST_true(multi_success))
454         testresult = 0;
455
456  err:
457     EVP_MD_free(sha256);
458     OSSL_PROVIDER_unload(prov);
459     OSSL_PROVIDER_unload(prov2);
460     OSSL_LIB_CTX_free(multi_libctx);
461     EVP_PKEY_free(shared_evp_pkey);
462     shared_evp_pkey = NULL;
463     multi_libctx = NULL;
464     return testresult;
465 }
466
467 /*
468  * This test attempts to load several providers at the same time, and if
469  * run with a thread sanitizer, should crash if the core provider code
470  * doesn't synchronize well enough.
471  */
472 #define MULTI_LOAD_THREADS 3
473 static void test_multi_load_worker(void)
474 {
475     OSSL_PROVIDER *prov;
476
477     (void)TEST_ptr(prov = OSSL_PROVIDER_load(NULL, "default"));
478     (void)TEST_true(OSSL_PROVIDER_unload(prov));
479 }
480
481 static int test_multi_default(void)
482 {
483     thread_t thread1, thread2;
484     int testresult = 0;
485     OSSL_PROVIDER *prov = NULL;
486
487     /* Avoid running this test twice */
488     if (multidefault_run) {
489         TEST_skip("multi default test already run");
490         return 1;
491     }
492     multidefault_run = 1;
493
494     multi_success = 1;
495     multi_libctx = NULL;
496     prov = OSSL_PROVIDER_load(multi_libctx, "default");
497     if (!TEST_ptr(prov))
498         goto err;
499
500     if (!TEST_true(run_thread(&thread1, thread_multi_simple_fetch))
501             || !TEST_true(run_thread(&thread2, thread_multi_simple_fetch)))
502         goto err;
503
504     thread_multi_simple_fetch();
505
506     if (!TEST_true(wait_for_thread(thread1))
507             || !TEST_true(wait_for_thread(thread2))
508             || !TEST_true(multi_success))
509         goto err;
510
511     testresult = 1;
512
513  err:
514     OSSL_PROVIDER_unload(prov);
515     return testresult;
516 }
517
518 static int test_multi_load(void)
519 {
520     thread_t threads[MULTI_LOAD_THREADS];
521     int i, res = 1;
522
523     /* The multidefault test must run prior to this test */
524     if (!multidefault_run) {
525         TEST_info("Running multi default test first");
526         res = test_multi_default();
527     }
528
529     for (i = 0; i < MULTI_LOAD_THREADS; i++)
530         (void)TEST_true(run_thread(&threads[i], test_multi_load_worker));
531
532     for (i = 0; i < MULTI_LOAD_THREADS; i++)
533         (void)TEST_true(wait_for_thread(threads[i]));
534
535     return res;
536 }
537
538 typedef enum OPTION_choice {
539     OPT_ERR = -1,
540     OPT_EOF = 0,
541     OPT_FIPS, OPT_CONFIG_FILE,
542     OPT_TEST_ENUM
543 } OPTION_CHOICE;
544
545 const OPTIONS *test_get_options(void)
546 {
547     static const OPTIONS options[] = {
548         OPT_TEST_OPTIONS_DEFAULT_USAGE,
549         { "fips", OPT_FIPS, '-', "Test the FIPS provider" },
550         { "config", OPT_CONFIG_FILE, '<',
551           "The configuration file to use for the libctx" },
552         { NULL }
553     };
554     return options;
555 }
556
557 int setup_tests(void)
558 {
559     OPTION_CHOICE o;
560     char *datadir;
561
562     while ((o = opt_next()) != OPT_EOF) {
563         switch (o) {
564         case OPT_FIPS:
565             do_fips = 1;
566             break;
567         case OPT_CONFIG_FILE:
568             config_file = opt_arg();
569             break;
570         case OPT_TEST_CASES:
571             break;
572         default:
573             return 0;
574         }
575     }
576
577     if (!TEST_ptr(datadir = test_get_argument(0)))
578         return 0;
579
580     privkey = test_mk_file_path(datadir, "rsakey.pem");
581     if (!TEST_ptr(privkey))
582         return 0;
583
584     /* Keep first to validate auto creation of default library context */
585     ADD_TEST(test_multi_default);
586
587     ADD_TEST(test_lock);
588     ADD_TEST(test_once);
589     ADD_TEST(test_thread_local);
590     ADD_TEST(test_atomic);
591     ADD_TEST(test_multi_load);
592     ADD_ALL_TESTS(test_multi, 6);
593     return 1;
594 }
595
596 void cleanup_tests(void)
597 {
598     OPENSSL_free(privkey);
599 }