X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Finit.c;h=4aa3fc83da91495abd4d80082c5afbfd80adcdbe;hb=2b5e12f5096e1fba7dd91a682f4c34759469c34b;hp=7b69927218980e4747fe0722268793f205c7814c;hpb=80ae7285e1994d35c84519bf9e038b11d9942875;p=openssl.git diff --git a/crypto/init.c b/crypto/init.c index 7b69927218..4aa3fc83da 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -1,77 +1,37 @@ /* * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "e_os.h" -#include "internal/cryptlib_int.h" +#include "crypto/cryptlib.h" #include -#include "internal/rand_int.h" +#include "crypto/rand.h" #include "internal/bio.h" #include -#include "internal/evp_int.h" +#include "crypto/evp.h" #include "internal/conf.h" -#include "internal/async.h" -#include "internal/engine.h" +#include "crypto/async.h" +#include "crypto/engine.h" #include "internal/comp.h" #include "internal/err.h" -#include "internal/err_int.h" -#include "internal/objects.h" +#include "crypto/err.h" +#include "crypto/objects.h" #include #include #include "internal/thread_once.h" -#include "internal/dso_conf.h" +#include "crypto/dso_conf.h" #include "internal/dso.h" -#include "internal/store.h" +#include "crypto/store.h" +#include /* for OSSL_CMP_log_close() */ +#include static int stopped = 0; -/* - * Since per-thread-specific-data destructors are not universally - * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key - * is assumed to have destructor associated. And then an effort is made - * to call this single destructor on non-pthread platform[s]. - * - * Initial value is "impossible". It is used as guard value to shortcut - * destructor for threads terminating before libcrypto is initialized or - * after it's de-initialized. Access to the key doesn't have to be - * serialized for the said threads, because they didn't use libcrypto - * and it doesn't matter if they pick "impossible" or derefernce real - * key value and pull NULL past initialization in the first thread that - * intends to use libcrypto. - */ -static CRYPTO_THREAD_LOCAL destructor_key = (CRYPTO_THREAD_LOCAL)-1; - -static void ossl_init_thread_stop(struct thread_local_inits_st *locals); - -static void ossl_init_thread_destructor(void *local) -{ - ossl_init_thread_stop((struct thread_local_inits_st *)local); -} - -static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc) -{ - struct thread_local_inits_st *local = - CRYPTO_THREAD_get_local(&destructor_key); - - if (alloc) { - if (local == NULL - && (local = OPENSSL_zalloc(sizeof(*local))) != NULL - && !CRYPTO_THREAD_set_local(&destructor_key, local)) { - OPENSSL_free(local); - return NULL; - } - } else { - CRYPTO_THREAD_set_local(&destructor_key, NULL); - } - - return local; -} - typedef struct ossl_init_stop_st OPENSSL_INIT_STOP; struct ossl_init_stop_st { void (*handler)(void); @@ -85,47 +45,77 @@ static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; static int base_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_base) { - CRYPTO_THREAD_LOCAL key; + /* no need to init trace */ -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n"); -#endif + OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n"); #ifndef OPENSSL_NO_CRYPTO_MDEBUG ossl_malloc_setup_failures(); #endif - if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor)) - return 0; + if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL) goto err; -#ifndef OPENSSL_SYS_UEFI - if (atexit(OPENSSL_cleanup) != 0) - goto err; -#endif OPENSSL_cpuid_setup(); - destructor_key = key; + if (!ossl_init_thread()) + return 0; + base_inited = 1; return 1; err: -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n"); -#endif + OSSL_TRACE(INIT, "ossl_init_base failed!\n"); CRYPTO_THREAD_lock_free(init_lock); init_lock = NULL; - CRYPTO_THREAD_cleanup_local(&key); return 0; } -static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) +static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT; +#if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32) +static int win32atexit(void) +{ + OPENSSL_cleanup(); + return 0; +} +#endif + +DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit) +{ +#ifdef OPENSSL_INIT_DEBUG + fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n"); +#endif +#ifndef OPENSSL_SYS_UEFI +# ifdef _WIN32 + /* We use _onexit() in preference because it gets called on DLL unload */ + if (_onexit(win32atexit) == NULL) + return 0; +# else + if (atexit(OPENSSL_cleanup) != 0) + return 0; +# endif +#endif + + return 1; +} + +DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit, + ossl_init_register_atexit) { #ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_nodelete()\n"); + fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n"); #endif -#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE) -# ifdef DSO_WIN32 + /* Do nothing in this case */ + return 1; +} + +static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) +{ + OSSL_TRACE(INIT, "ossl_init_load_crypto_nodelete()\n"); + +#if !defined(OPENSSL_USE_NODELETE) \ + && !defined(OPENSSL_NO_PINSHARED) +# if defined(DSO_WIN32) && !defined(_WIN32_WCE) { HMODULE handle = NULL; BOOL ret; @@ -135,13 +125,13 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) | GET_MODULE_HANDLE_EX_FLAG_PIN, (void *)&base_inited, &handle); -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n", - (ret == TRUE ? "No!" : "Yes.")); -# endif + OSSL_TRACE1(INIT, + "ossl_init_load_crypto_nodelete: " + "obtained DSO reference? %s\n", + (ret == TRUE ? "No!" : "Yes.")); return (ret == TRUE) ? 1 : 0; } -# else +# elif !defined(DSO_NONE) /* * Deliberately leak a reference to ourselves. This will force the library * to remain loaded until the atexit() handler is run at process exit. @@ -154,15 +144,13 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) return 0; dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE); -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n", - (dso == NULL ? "No!" : "Yes.")); /* * In case of No!, it is uncertain our exit()-handlers can still be * called. After dlclose() the whole library might have been unloaded * already. */ -# endif + OSSL_TRACE1(INIT, "obtained DSO reference? %s\n", + (dso == NULL ? "No!" : "Yes.")); DSO_free(dso); err_unshelve_state(err); } @@ -174,12 +162,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete) static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT; static int load_crypto_strings_inited = 0; -DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings) -{ - /* Do nothing in this case */ - return 1; -} - DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) { int ret = 1; @@ -188,16 +170,20 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) * pulling in all the error strings during static linking */ #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: " - "err_load_crypto_strings_int()\n"); -# endif + OSSL_TRACE(INIT, "err_load_crypto_strings_int()\n"); ret = err_load_crypto_strings_int(); load_crypto_strings_inited = 1; #endif return ret; } +DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings, + ossl_init_load_crypto_strings) +{ + /* Do nothing in this case */ + return 1; +} + static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers) { @@ -206,15 +192,19 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers) * pulling in all the ciphers during static linking */ #ifndef OPENSSL_NO_AUTOALGINIT -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: " - "openssl_add_all_ciphers_int()\n"); -# endif + OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n"); openssl_add_all_ciphers_int(); #endif return 1; } +DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers, + ossl_init_add_all_ciphers) +{ + /* Do nothing */ + return 1; +} + static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests) { @@ -223,16 +213,14 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests) * pulling in all the ciphers during static linking */ #ifndef OPENSSL_NO_AUTOALGINIT -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: " - "openssl_add_all_digests()\n"); -# endif + OSSL_TRACE(INIT, "openssl_add_all_digests()\n"); openssl_add_all_digests_int(); #endif return 1; } -DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs) +DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests, + ossl_init_add_all_digests) { /* Do nothing */ return 1; @@ -240,24 +228,16 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs) static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT; static int config_inited = 0; -static const char *appname; +static const OPENSSL_INIT_SETTINGS *conf_settings = NULL; DEFINE_RUN_ONCE_STATIC(ossl_init_config) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, - "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n", - appname == NULL ? "NULL" : appname); -#endif - openssl_config_int(appname); + int ret = openssl_config_int(conf_settings); config_inited = 1; - return 1; + return ret; } -DEFINE_RUN_ONCE_STATIC(ossl_init_no_config) +DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, - "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n"); -#endif + OSSL_TRACE(INIT, "openssl_no_config_int()\n"); openssl_no_config_int(); config_inited = 1; return 1; @@ -267,9 +247,7 @@ static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT; static int async_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_async) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n"); -#endif + OSSL_TRACE(INIT, "async_init()\n"); if (!async_init()) return 0; async_inited = 1; @@ -280,34 +258,15 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_async) static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: " - "engine_load_openssl_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_openssl_int()\n"); engine_load_openssl_int(); return 1; } -# ifndef OPENSSL_NO_DEVCRYPTOENG -static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; -DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) -{ -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: " - "engine_load_devcrypto_int()\n"); -# endif - engine_load_devcrypto_int(); - return 1; -} -# endif - # ifndef OPENSSL_NO_RDRAND static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: " - "engine_load_rdrand_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_rdrand_int()\n"); engine_load_rdrand_int(); return 1; } @@ -315,22 +274,25 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: " - "engine_load_dynamic_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_dynamic_int()\n"); engine_load_dynamic_int(); return 1; } # ifndef OPENSSL_NO_STATIC_ENGINE -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) +# ifndef OPENSSL_NO_DEVCRYPTOENG +static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto) +{ + OSSL_TRACE(INIT, "engine_load_devcrypto_int()\n"); + engine_load_devcrypto_int(); + return 1; +} +# endif +# if !defined(OPENSSL_NO_PADLOCKENG) static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: " - "engine_load_padlock_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_padlock_int()\n"); engine_load_padlock_int(); return 1; } @@ -339,10 +301,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: " - "engine_load_capi_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_capi_int()\n"); engine_load_capi_int(); return 1; } @@ -351,10 +310,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: " - "engine_load_afalg_int()\n"); -# endif + OSSL_TRACE(INIT, "engine_load_afalg_int()\n"); engine_load_afalg_int(); return 1; } @@ -374,88 +330,14 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_zlib) } #endif -static void ossl_init_thread_stop(struct thread_local_inits_st *locals) -{ - /* Can't do much about this */ - if (locals == NULL) - return; - - if (locals->async) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " - "async_delete_thread_state()\n"); -#endif - async_delete_thread_state(); - } - - if (locals->err_state) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " - "err_delete_thread_state()\n"); -#endif - err_delete_thread_state(); - } - - if (locals->rand) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " - "drbg_delete_thread_state()\n"); -#endif - drbg_delete_thread_state(); - } - - OPENSSL_free(locals); -} - -void OPENSSL_thread_stop(void) -{ - if (destructor_key != (CRYPTO_THREAD_LOCAL)-1) - ossl_init_thread_stop(ossl_init_get_thread_local(0)); -} - -int ossl_init_thread_start(uint64_t opts) -{ - struct thread_local_inits_st *locals; - - if (!OPENSSL_init_crypto(0, NULL)) - return 0; - - locals = ossl_init_get_thread_local(1); - - if (locals == NULL) - return 0; - - if (opts & OPENSSL_INIT_THREAD_ASYNC) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " - "marking thread for async\n"); -#endif - locals->async = 1; - } - - if (opts & OPENSSL_INIT_THREAD_ERR_STATE) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " - "marking thread for err_state\n"); -#endif - locals->err_state = 1; - } - - if (opts & OPENSSL_INIT_THREAD_RAND) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " - "marking thread for rand\n"); -#endif - locals->rand = 1; - } - - return 1; -} - void OPENSSL_cleanup(void) { OPENSSL_INIT_STOP *currhandler, *lasthandler; - CRYPTO_THREAD_LOCAL key; + + /* + * TODO(3.0): This function needs looking at with a view to moving most/all + * of this into onfree handlers in OPENSSL_CTX. + */ /* If we've not been inited then no need to deinit */ if (!base_inited) @@ -470,7 +352,7 @@ void OPENSSL_cleanup(void) * Thread stop may not get automatically called by the thread library for * the very last thread in some situations, so call it directly. */ - ossl_init_thread_stop(ossl_init_get_thread_local(0)); + OPENSSL_thread_stop(); currhandler = stop_handlers; while (currhandler != NULL) { @@ -491,82 +373,73 @@ void OPENSSL_cleanup(void) #ifndef OPENSSL_NO_COMP if (zlib_inited) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "comp_zlib_cleanup_int()\n"); -#endif + OSSL_TRACE(INIT, "OPENSSL_cleanup: comp_zlib_cleanup_int()\n"); comp_zlib_cleanup_int(); } #endif if (async_inited) { -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "async_deinit()\n"); -# endif + OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n"); async_deinit(); } if (load_crypto_strings_inited) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "err_free_strings_int()\n"); -#endif + OSSL_TRACE(INIT, "OPENSSL_cleanup: err_free_strings_int()\n"); err_free_strings_int(); } - key = destructor_key; - destructor_key = (CRYPTO_THREAD_LOCAL)-1; - CRYPTO_THREAD_cleanup_local(&key); - -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "rand_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "conf_modules_free_int()\n"); -#ifndef OPENSSL_NO_ENGINE - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "engine_cleanup_int()\n"); -#endif - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "crypto_cleanup_all_ex_data_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "bio_sock_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "bio_cleanup()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "evp_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "obj_cleanup_int()\n"); - fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " - "err_cleanup()\n"); -#endif /* * Note that cleanup order is important: * - rand_cleanup_int could call an ENGINE's RAND cleanup function so * must be called before engine_cleanup_int() * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up - * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data(). + * before the ex data handlers are wiped during default openssl_ctx deinit. * - conf_modules_free_int() can end up in ENGINE code so must be called * before engine_cleanup_int() * - ENGINEs and additional EVP algorithms might use added OIDs names so * obj_cleanup_int() must be called last */ + OSSL_TRACE(INIT, "OPENSSL_cleanup: rand_cleanup_int()\n"); rand_cleanup_int(); - rand_drbg_cleanup_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: conf_modules_free_int()\n"); conf_modules_free_int(); + #ifndef OPENSSL_NO_ENGINE + OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n"); engine_cleanup_int(); #endif + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n"); ossl_store_cleanup_int(); - crypto_cleanup_all_ex_data_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: openssl_ctx_default_deinit()\n"); + openssl_ctx_default_deinit(); + + ossl_cleanup_thread(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n"); bio_cleanup(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n"); evp_cleanup_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: obj_cleanup_int()\n"); obj_cleanup_int(); + + OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n"); err_cleanup(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n"); CRYPTO_secure_malloc_done(); +#ifndef OPENSSL_NO_CMP + OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n"); + OSSL_CMP_log_close(); +#endif + + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n"); + ossl_trace_cleanup(); + base_inited = 0; } @@ -577,23 +450,55 @@ void OPENSSL_cleanup(void) */ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + /* + * TODO(3.0): This function needs looking at with a view to moving most/all + * of this into OPENSSL_CTX. + */ + if (stopped) { if (!(opts & OPENSSL_INIT_BASE_ONLY)) CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL); return 0; } + /* + * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the + * *only* option specified. With that option we return immediately after + * doing the requested limited initialization. Note that + * err_shelve_state() called by us via ossl_init_load_crypto_nodelete() + * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with + * base already initialized this is a harmless NOOP. + * + * If we remain the only caller of err_shelve_state() the recursion should + * perhaps be removed, but if in doubt, it can be left in place. + */ if (!RUN_ONCE(&base, ossl_init_base)) return 0; - if (!(opts & OPENSSL_INIT_BASE_ONLY) - && !RUN_ONCE(&load_crypto_nodelete, - ossl_init_load_crypto_nodelete)) + if (opts & OPENSSL_INIT_BASE_ONLY) + return 1; + + /* + * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls + * should not have the side-effect of setting up exit handlers, and + * therefore, this code block is below the INIT_BASE_ONLY-conditioned early + * return above. + */ + if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) { + if (!RUN_ONCE_ALT(®ister_atexit, ossl_init_no_register_atexit, + ossl_init_register_atexit)) + return 0; + } else if (!RUN_ONCE(®ister_atexit, ossl_init_register_atexit)) { + return 0; + } + + if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete)) return 0; if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS) - && !RUN_ONCE(&load_crypto_strings, - ossl_init_no_load_crypto_strings)) + && !RUN_ONCE_ALT(&load_crypto_strings, + ossl_init_no_load_crypto_strings, + ossl_init_load_crypto_strings)) return 0; if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS) @@ -601,7 +506,8 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS) - && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs)) + && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers, + ossl_init_add_all_ciphers)) return 0; if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS) @@ -609,7 +515,8 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS) - && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs)) + && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests, + ossl_init_add_all_digests)) return 0; if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS) @@ -621,16 +528,17 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) - && !RUN_ONCE(&config, ossl_init_no_config)) + && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config)) return 0; if (opts & OPENSSL_INIT_LOAD_CONFIG) { int ret; CRYPTO_THREAD_write_lock(init_lock); - appname = (settings == NULL) ? NULL : settings->appname; + conf_settings = settings; ret = RUN_ONCE(&config, ossl_init_config); + conf_settings = NULL; CRYPTO_THREAD_unlock(init_lock); - if (!ret) + if (ret <= 0) return 0; } @@ -642,11 +550,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) return 0; -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG) - if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) - && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) - return 0; -# endif # ifndef OPENSSL_NO_RDRAND if ((opts & OPENSSL_INIT_ENGINE_RDRAND) && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) @@ -656,7 +559,12 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) return 0; # ifndef OPENSSL_NO_STATIC_ENGINE -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) +# ifndef OPENSSL_NO_DEVCRYPTOENG + if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) + && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto)) + return 0; +# endif +# if !defined(OPENSSL_NO_PADLOCKENG) if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) return 0; @@ -692,7 +600,8 @@ int OPENSSL_atexit(void (*handler)(void)) { OPENSSL_INIT_STOP *newhand; -#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE) +#if !defined(OPENSSL_USE_NODELETE)\ + && !defined(OPENSSL_NO_PINSHARED) { union { void *sym; @@ -700,7 +609,7 @@ int OPENSSL_atexit(void (*handler)(void)) } handlersym; handlersym.func = handler; -# ifdef DSO_WIN32 +# if defined(DSO_WIN32) && !defined(_WIN32_WCE) { HMODULE handle = NULL; BOOL ret; @@ -716,7 +625,7 @@ int OPENSSL_atexit(void (*handler)(void)) if (!ret) return 0; } -# else +# elif !defined(DSO_NONE) /* * Deliberately leak a reference to the handler. This will force the * library/code containing the handler to remain loaded until we run the @@ -728,12 +637,10 @@ int OPENSSL_atexit(void (*handler)(void)) ERR_set_mark(); dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, - "OPENSSL_INIT: OPENSSL_atexit: obtained DSO reference? %s\n", - (dso == NULL ? "No!" : "Yes.")); /* See same code above in ossl_init_base() for an explanation. */ -# endif + OSSL_TRACE1(INIT, + "atexit: obtained DSO reference? %s\n", + (dso == NULL ? "No!" : "Yes.")); DSO_free(dso); ERR_pop_to_mark(); } @@ -775,6 +682,6 @@ void OPENSSL_fork_parent(void) void OPENSSL_fork_child(void) { - rand_fork(); + /* TODO(3.0): Inform all providers about a fork event */ } #endif