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