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