xref: /openssl/crypto/context.c (revision 6f20c680)
1 /*
2  * Copyright 2019-2024 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 #include "crypto/cryptlib.h"
11 #include <openssl/conf.h>
12 #include "internal/thread_once.h"
13 #include "internal/property.h"
14 #include "internal/cryptlib.h"
15 #include "internal/core.h"
16 #include "internal/bio.h"
17 #include "internal/provider.h"
18 #include "crypto/decoder.h"
19 #include "crypto/context.h"
20 
21 struct ossl_lib_ctx_st {
22     CRYPTO_RWLOCK *lock;
23     OSSL_EX_DATA_GLOBAL global;
24 
25     void *property_string_data;
26     void *evp_method_store;
27     void *provider_store;
28     void *namemap;
29     void *property_defns;
30     void *global_properties;
31     void *drbg;
32     void *drbg_nonce;
33     CRYPTO_THREAD_LOCAL rcu_local_key;
34 #ifndef FIPS_MODULE
35     void *provider_conf;
36     void *bio_core;
37     void *child_provider;
38     OSSL_METHOD_STORE *decoder_store;
39     void *decoder_cache;
40     OSSL_METHOD_STORE *encoder_store;
41     OSSL_METHOD_STORE *store_loader_store;
42     void *self_test_cb;
43     void *indicator_cb;
44 #endif
45 #if defined(OPENSSL_THREADS)
46     void *threads;
47 #endif
48 #ifdef FIPS_MODULE
49     void *thread_event_handler;
50     void *fips_prov;
51 #endif
52     STACK_OF(SSL_COMP) *comp_methods;
53 
54     int ischild;
55     int conf_diagnostics;
56 };
57 
ossl_lib_ctx_write_lock(OSSL_LIB_CTX * ctx)58 int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx)
59 {
60     return CRYPTO_THREAD_write_lock(ossl_lib_ctx_get_concrete(ctx)->lock);
61 }
62 
ossl_lib_ctx_read_lock(OSSL_LIB_CTX * ctx)63 int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx)
64 {
65     return CRYPTO_THREAD_read_lock(ossl_lib_ctx_get_concrete(ctx)->lock);
66 }
67 
ossl_lib_ctx_unlock(OSSL_LIB_CTX * ctx)68 int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx)
69 {
70     return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock);
71 }
72 
ossl_lib_ctx_is_child(OSSL_LIB_CTX * ctx)73 int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx)
74 {
75     ctx = ossl_lib_ctx_get_concrete(ctx);
76 
77     if (ctx == NULL)
78         return 0;
79     return ctx->ischild;
80 }
81 
82 static void context_deinit_objs(OSSL_LIB_CTX *ctx);
83 
context_init(OSSL_LIB_CTX * ctx)84 static int context_init(OSSL_LIB_CTX *ctx)
85 {
86     int exdata_done = 0;
87 
88     if (!CRYPTO_THREAD_init_local(&ctx->rcu_local_key, NULL))
89         return 0;
90 
91     ctx->lock = CRYPTO_THREAD_lock_new();
92     if (ctx->lock == NULL)
93         goto err;
94 
95     /* Initialize ex_data. */
96     if (!ossl_do_ex_data_init(ctx))
97         goto err;
98     exdata_done = 1;
99 
100     /* P2. We want evp_method_store to be cleaned up before the provider store */
101     ctx->evp_method_store = ossl_method_store_new(ctx);
102     if (ctx->evp_method_store == NULL)
103         goto err;
104 
105 #ifndef FIPS_MODULE
106     /* P2. Must be freed before the provider store is freed */
107     ctx->provider_conf = ossl_prov_conf_ctx_new(ctx);
108     if (ctx->provider_conf == NULL)
109         goto err;
110 #endif
111 
112     /* P2. */
113     ctx->drbg = ossl_rand_ctx_new(ctx);
114     if (ctx->drbg == NULL)
115         goto err;
116 
117 #ifndef FIPS_MODULE
118     /*
119      * P2. We want decoder_store/decoder_cache to be cleaned up before the
120      * provider store
121      */
122     ctx->decoder_store = ossl_method_store_new(ctx);
123     if (ctx->decoder_store == NULL)
124         goto err;
125     ctx->decoder_cache = ossl_decoder_cache_new(ctx);
126     if (ctx->decoder_cache == NULL)
127         goto err;
128 
129     /* P2. We want encoder_store to be cleaned up before the provider store */
130     ctx->encoder_store = ossl_method_store_new(ctx);
131     if (ctx->encoder_store == NULL)
132         goto err;
133 
134     /* P2. We want loader_store to be cleaned up before the provider store */
135     ctx->store_loader_store = ossl_method_store_new(ctx);
136     if (ctx->store_loader_store == NULL)
137         goto err;
138 #endif
139 
140     /* P1. Needs to be freed before the child provider data is freed */
141     ctx->provider_store = ossl_provider_store_new(ctx);
142     if (ctx->provider_store == NULL)
143         goto err;
144 
145     /* Default priority. */
146     ctx->property_string_data = ossl_property_string_data_new(ctx);
147     if (ctx->property_string_data == NULL)
148         goto err;
149 
150     ctx->namemap = ossl_stored_namemap_new(ctx);
151     if (ctx->namemap == NULL)
152         goto err;
153 
154     ctx->property_defns = ossl_property_defns_new(ctx);
155     if (ctx->property_defns == NULL)
156         goto err;
157 
158     ctx->global_properties = ossl_ctx_global_properties_new(ctx);
159     if (ctx->global_properties == NULL)
160         goto err;
161 
162 #ifndef FIPS_MODULE
163     ctx->bio_core = ossl_bio_core_globals_new(ctx);
164     if (ctx->bio_core == NULL)
165         goto err;
166 #endif
167 
168     ctx->drbg_nonce = ossl_prov_drbg_nonce_ctx_new(ctx);
169     if (ctx->drbg_nonce == NULL)
170         goto err;
171 
172 #ifndef FIPS_MODULE
173     ctx->self_test_cb = ossl_self_test_set_callback_new(ctx);
174     if (ctx->self_test_cb == NULL)
175         goto err;
176     ctx->indicator_cb = ossl_indicator_set_callback_new(ctx);
177     if (ctx->indicator_cb == NULL)
178         goto err;
179 #endif
180 
181 #ifdef FIPS_MODULE
182     ctx->thread_event_handler = ossl_thread_event_ctx_new(ctx);
183     if (ctx->thread_event_handler == NULL)
184         goto err;
185 
186     ctx->fips_prov = ossl_fips_prov_ossl_ctx_new(ctx);
187     if (ctx->fips_prov == NULL)
188         goto err;
189 #endif
190 
191 #ifndef OPENSSL_NO_THREAD_POOL
192     ctx->threads = ossl_threads_ctx_new(ctx);
193     if (ctx->threads == NULL)
194         goto err;
195 #endif
196 
197     /* Low priority. */
198 #ifndef FIPS_MODULE
199     ctx->child_provider = ossl_child_prov_ctx_new(ctx);
200     if (ctx->child_provider == NULL)
201         goto err;
202 #endif
203 
204     /* Everything depends on properties, so we also pre-initialise that */
205     if (!ossl_property_parse_init(ctx))
206         goto err;
207 
208 #ifndef FIPS_MODULE
209     ctx->comp_methods = ossl_load_builtin_compressions();
210 #endif
211 
212     return 1;
213 
214  err:
215     context_deinit_objs(ctx);
216 
217     if (exdata_done)
218         ossl_crypto_cleanup_all_ex_data_int(ctx);
219 
220     CRYPTO_THREAD_lock_free(ctx->lock);
221     CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key);
222     memset(ctx, '\0', sizeof(*ctx));
223     return 0;
224 }
225 
context_deinit_objs(OSSL_LIB_CTX * ctx)226 static void context_deinit_objs(OSSL_LIB_CTX *ctx)
227 {
228     /* P2. We want evp_method_store to be cleaned up before the provider store */
229     if (ctx->evp_method_store != NULL) {
230         ossl_method_store_free(ctx->evp_method_store);
231         ctx->evp_method_store = NULL;
232     }
233 
234     /* P2. */
235     if (ctx->drbg != NULL) {
236         ossl_rand_ctx_free(ctx->drbg);
237         ctx->drbg = NULL;
238     }
239 
240 #ifndef FIPS_MODULE
241     /* P2. */
242     if (ctx->provider_conf != NULL) {
243         ossl_prov_conf_ctx_free(ctx->provider_conf);
244         ctx->provider_conf = NULL;
245     }
246 
247     /*
248      * P2. We want decoder_store/decoder_cache to be cleaned up before the
249      * provider store
250      */
251     if (ctx->decoder_store != NULL) {
252         ossl_method_store_free(ctx->decoder_store);
253         ctx->decoder_store = NULL;
254     }
255     if (ctx->decoder_cache != NULL) {
256         ossl_decoder_cache_free(ctx->decoder_cache);
257         ctx->decoder_cache = NULL;
258     }
259 
260 
261     /* P2. We want encoder_store to be cleaned up before the provider store */
262     if (ctx->encoder_store != NULL) {
263         ossl_method_store_free(ctx->encoder_store);
264         ctx->encoder_store = NULL;
265     }
266 
267     /* P2. We want loader_store to be cleaned up before the provider store */
268     if (ctx->store_loader_store != NULL) {
269         ossl_method_store_free(ctx->store_loader_store);
270         ctx->store_loader_store = NULL;
271     }
272 #endif
273 
274     /* P1. Needs to be freed before the child provider data is freed */
275     if (ctx->provider_store != NULL) {
276         ossl_provider_store_free(ctx->provider_store);
277         ctx->provider_store = NULL;
278     }
279 
280     /* Default priority. */
281     if (ctx->property_string_data != NULL) {
282         ossl_property_string_data_free(ctx->property_string_data);
283         ctx->property_string_data = NULL;
284     }
285 
286     if (ctx->namemap != NULL) {
287         ossl_stored_namemap_free(ctx->namemap);
288         ctx->namemap = NULL;
289     }
290 
291     if (ctx->property_defns != NULL) {
292         ossl_property_defns_free(ctx->property_defns);
293         ctx->property_defns = NULL;
294     }
295 
296     if (ctx->global_properties != NULL) {
297         ossl_ctx_global_properties_free(ctx->global_properties);
298         ctx->global_properties = NULL;
299     }
300 
301 #ifndef FIPS_MODULE
302     if (ctx->bio_core != NULL) {
303         ossl_bio_core_globals_free(ctx->bio_core);
304         ctx->bio_core = NULL;
305     }
306 #endif
307 
308     if (ctx->drbg_nonce != NULL) {
309         ossl_prov_drbg_nonce_ctx_free(ctx->drbg_nonce);
310         ctx->drbg_nonce = NULL;
311     }
312 
313 #ifndef FIPS_MODULE
314     if (ctx->indicator_cb != NULL) {
315         ossl_indicator_set_callback_free(ctx->indicator_cb);
316         ctx->indicator_cb = NULL;
317     }
318 
319     if (ctx->self_test_cb != NULL) {
320         ossl_self_test_set_callback_free(ctx->self_test_cb);
321         ctx->self_test_cb = NULL;
322     }
323 #endif
324 
325 #ifdef FIPS_MODULE
326     if (ctx->thread_event_handler != NULL) {
327         ossl_thread_event_ctx_free(ctx->thread_event_handler);
328         ctx->thread_event_handler = NULL;
329     }
330 
331     if (ctx->fips_prov != NULL) {
332         ossl_fips_prov_ossl_ctx_free(ctx->fips_prov);
333         ctx->fips_prov = NULL;
334     }
335 #endif
336 
337 #ifndef OPENSSL_NO_THREAD_POOL
338     if (ctx->threads != NULL) {
339         ossl_threads_ctx_free(ctx->threads);
340         ctx->threads = NULL;
341     }
342 #endif
343 
344     /* Low priority. */
345 #ifndef FIPS_MODULE
346     if (ctx->child_provider != NULL) {
347         ossl_child_prov_ctx_free(ctx->child_provider);
348         ctx->child_provider = NULL;
349     }
350 #endif
351 
352 #ifndef FIPS_MODULE
353     if (ctx->comp_methods != NULL) {
354         ossl_free_compression_methods_int(ctx->comp_methods);
355         ctx->comp_methods = NULL;
356     }
357 #endif
358 
359 }
360 
context_deinit(OSSL_LIB_CTX * ctx)361 static int context_deinit(OSSL_LIB_CTX *ctx)
362 {
363     if (ctx == NULL)
364         return 1;
365 
366     ossl_ctx_thread_stop(ctx);
367 
368     context_deinit_objs(ctx);
369 
370     ossl_crypto_cleanup_all_ex_data_int(ctx);
371 
372     CRYPTO_THREAD_lock_free(ctx->lock);
373     ctx->lock = NULL;
374     CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key);
375     return 1;
376 }
377 
378 #ifndef FIPS_MODULE
379 /* The default default context */
380 static OSSL_LIB_CTX default_context_int;
381 
382 static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
383 static CRYPTO_THREAD_LOCAL default_context_thread_local;
384 static int default_context_inited = 0;
385 
DEFINE_RUN_ONCE_STATIC(default_context_do_init)386 DEFINE_RUN_ONCE_STATIC(default_context_do_init)
387 {
388     if (!CRYPTO_THREAD_init_local(&default_context_thread_local, NULL))
389         goto err;
390 
391     if (!context_init(&default_context_int))
392         goto deinit_thread;
393 
394     default_context_inited = 1;
395     return 1;
396 
397 deinit_thread:
398     CRYPTO_THREAD_cleanup_local(&default_context_thread_local);
399 err:
400     return 0;
401 }
402 
ossl_lib_ctx_default_deinit(void)403 void ossl_lib_ctx_default_deinit(void)
404 {
405     if (!default_context_inited)
406         return;
407     context_deinit(&default_context_int);
408     CRYPTO_THREAD_cleanup_local(&default_context_thread_local);
409     default_context_inited = 0;
410 }
411 
get_thread_default_context(void)412 static OSSL_LIB_CTX *get_thread_default_context(void)
413 {
414     if (!RUN_ONCE(&default_context_init, default_context_do_init))
415         return NULL;
416 
417     return CRYPTO_THREAD_get_local(&default_context_thread_local);
418 }
419 
get_default_context(void)420 static OSSL_LIB_CTX *get_default_context(void)
421 {
422     OSSL_LIB_CTX *current_defctx = get_thread_default_context();
423 
424     if (current_defctx == NULL)
425         current_defctx = &default_context_int;
426     return current_defctx;
427 }
428 
set_default_context(OSSL_LIB_CTX * defctx)429 static int set_default_context(OSSL_LIB_CTX *defctx)
430 {
431     if (defctx == &default_context_int)
432         defctx = NULL;
433 
434     return CRYPTO_THREAD_set_local(&default_context_thread_local, defctx);
435 }
436 #endif
437 
OSSL_LIB_CTX_new(void)438 OSSL_LIB_CTX *OSSL_LIB_CTX_new(void)
439 {
440     OSSL_LIB_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
441 
442     if (ctx != NULL && !context_init(ctx)) {
443         OPENSSL_free(ctx);
444         ctx = NULL;
445     }
446     return ctx;
447 }
448 
449 #ifndef FIPS_MODULE
OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE * handle,const OSSL_DISPATCH * in)450 OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle,
451                                              const OSSL_DISPATCH *in)
452 {
453     OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new();
454 
455     if (ctx == NULL)
456         return NULL;
457 
458     if (!ossl_bio_init_core(ctx, in)) {
459         OSSL_LIB_CTX_free(ctx);
460         return NULL;
461     }
462 
463     return ctx;
464 }
465 
OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE * handle,const OSSL_DISPATCH * in)466 OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle,
467                                      const OSSL_DISPATCH *in)
468 {
469     OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new_from_dispatch(handle, in);
470 
471     if (ctx == NULL)
472         return NULL;
473 
474     if (!ossl_provider_init_as_child(ctx, handle, in)) {
475         OSSL_LIB_CTX_free(ctx);
476         return NULL;
477     }
478     ctx->ischild = 1;
479 
480     return ctx;
481 }
482 
OSSL_LIB_CTX_load_config(OSSL_LIB_CTX * ctx,const char * config_file)483 int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file)
484 {
485     return CONF_modules_load_file_ex(ctx, config_file, NULL, 0) > 0;
486 }
487 #endif
488 
OSSL_LIB_CTX_free(OSSL_LIB_CTX * ctx)489 void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx)
490 {
491     if (ctx == NULL || ossl_lib_ctx_is_default(ctx))
492         return;
493 
494 #ifndef FIPS_MODULE
495     if (ctx->ischild)
496         ossl_provider_deinit_child(ctx);
497 #endif
498     context_deinit(ctx);
499     OPENSSL_free(ctx);
500 }
501 
502 #ifndef FIPS_MODULE
OSSL_LIB_CTX_get0_global_default(void)503 OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void)
504 {
505     if (!RUN_ONCE(&default_context_init, default_context_do_init))
506         return NULL;
507 
508     return &default_context_int;
509 }
510 
OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX * libctx)511 OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx)
512 {
513     OSSL_LIB_CTX *current_defctx;
514 
515     if ((current_defctx = get_default_context()) != NULL) {
516         if (libctx != NULL)
517             set_default_context(libctx);
518         return current_defctx;
519     }
520 
521     return NULL;
522 }
523 
ossl_release_default_drbg_ctx(void)524 void ossl_release_default_drbg_ctx(void)
525 {
526     /* early release of the DRBG in global default libctx */
527     if (default_context_int.drbg != NULL) {
528         ossl_rand_ctx_free(default_context_int.drbg);
529         default_context_int.drbg = NULL;
530     }
531 }
532 #endif
533 
ossl_lib_ctx_get_concrete(OSSL_LIB_CTX * ctx)534 OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx)
535 {
536 #ifndef FIPS_MODULE
537     if (ctx == NULL)
538         return get_default_context();
539 #endif
540     return ctx;
541 }
542 
ossl_lib_ctx_is_default(OSSL_LIB_CTX * ctx)543 int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx)
544 {
545 #ifndef FIPS_MODULE
546     if (ctx == NULL || ctx == get_default_context())
547         return 1;
548 #endif
549     return 0;
550 }
551 
ossl_lib_ctx_is_global_default(OSSL_LIB_CTX * ctx)552 int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx)
553 {
554 #ifndef FIPS_MODULE
555     if (ossl_lib_ctx_get_concrete(ctx) == &default_context_int)
556         return 1;
557 #endif
558     return 0;
559 }
560 
ossl_lib_ctx_get_data(OSSL_LIB_CTX * ctx,int index)561 void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
562 {
563     ctx = ossl_lib_ctx_get_concrete(ctx);
564     if (ctx == NULL)
565         return NULL;
566 
567     switch (index) {
568     case OSSL_LIB_CTX_PROPERTY_STRING_INDEX:
569         return ctx->property_string_data;
570     case OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX:
571         return ctx->evp_method_store;
572     case OSSL_LIB_CTX_PROVIDER_STORE_INDEX:
573         return ctx->provider_store;
574     case OSSL_LIB_CTX_NAMEMAP_INDEX:
575         return ctx->namemap;
576     case OSSL_LIB_CTX_PROPERTY_DEFN_INDEX:
577         return ctx->property_defns;
578     case OSSL_LIB_CTX_GLOBAL_PROPERTIES:
579         return ctx->global_properties;
580     case OSSL_LIB_CTX_DRBG_INDEX:
581         return ctx->drbg;
582     case OSSL_LIB_CTX_DRBG_NONCE_INDEX:
583         return ctx->drbg_nonce;
584 #ifndef FIPS_MODULE
585     case OSSL_LIB_CTX_PROVIDER_CONF_INDEX:
586         return ctx->provider_conf;
587     case OSSL_LIB_CTX_BIO_CORE_INDEX:
588         return ctx->bio_core;
589     case OSSL_LIB_CTX_CHILD_PROVIDER_INDEX:
590         return ctx->child_provider;
591     case OSSL_LIB_CTX_DECODER_STORE_INDEX:
592         return ctx->decoder_store;
593     case OSSL_LIB_CTX_DECODER_CACHE_INDEX:
594         return ctx->decoder_cache;
595     case OSSL_LIB_CTX_ENCODER_STORE_INDEX:
596         return ctx->encoder_store;
597     case OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX:
598         return ctx->store_loader_store;
599     case OSSL_LIB_CTX_SELF_TEST_CB_INDEX:
600         return ctx->self_test_cb;
601     case OSSL_LIB_CTX_INDICATOR_CB_INDEX:
602         return ctx->indicator_cb;
603 #endif
604 #ifndef OPENSSL_NO_THREAD_POOL
605     case OSSL_LIB_CTX_THREAD_INDEX:
606         return ctx->threads;
607 #endif
608 
609 #ifdef FIPS_MODULE
610     case OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX:
611         return ctx->thread_event_handler;
612 
613     case OSSL_LIB_CTX_FIPS_PROV_INDEX:
614         return ctx->fips_prov;
615 #endif
616 
617     case OSSL_LIB_CTX_COMP_METHODS:
618         return (void *)&ctx->comp_methods;
619 
620     default:
621         return NULL;
622     }
623 }
624 
OSSL_LIB_CTX_get_data(OSSL_LIB_CTX * ctx,int index)625 void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX *ctx, int index)
626 {
627     return ossl_lib_ctx_get_data(ctx, index);
628 }
629 
ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX * ctx)630 OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx)
631 {
632     ctx = ossl_lib_ctx_get_concrete(ctx);
633     if (ctx == NULL)
634         return NULL;
635     return &ctx->global;
636 }
637 
ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX * libctx)638 const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx)
639 {
640 #ifdef FIPS_MODULE
641     return "FIPS internal library context";
642 #else
643     if (ossl_lib_ctx_is_global_default(libctx))
644         return "Global default library context";
645     if (ossl_lib_ctx_is_default(libctx))
646         return "Thread-local default library context";
647     return "Non-default library context";
648 #endif
649 }
650 
ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX * libctx)651 CRYPTO_THREAD_LOCAL *ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX *libctx)
652 {
653     libctx = ossl_lib_ctx_get_concrete(libctx);
654     if (libctx == NULL)
655         return NULL;
656     return &libctx->rcu_local_key;
657 }
658 
OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX * libctx)659 int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX *libctx)
660 {
661     libctx = ossl_lib_ctx_get_concrete(libctx);
662     if (libctx == NULL)
663         return 0;
664     return libctx->conf_diagnostics;
665 }
666 
OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX * libctx,int value)667 void OSSL_LIB_CTX_set_conf_diagnostics(OSSL_LIB_CTX *libctx, int value)
668 {
669     libctx = ossl_lib_ctx_get_concrete(libctx);
670     if (libctx == NULL)
671         return;
672     libctx->conf_diagnostics = value;
673 }
674