2016-02-09 11:26:14 +00:00
|
|
|
/*
|
2019-02-26 14:05:09 +00:00
|
|
|
* Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
|
2016-02-09 11:26:14 +00:00
|
|
|
*
|
2016-05-17 18:51:34 +00:00
|
|
|
* Licensed under the OpenSSL license (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
|
2016-02-09 11:26:14 +00:00
|
|
|
*/
|
|
|
|
|
2017-08-23 23:05:07 +00:00
|
|
|
#include "e_os.h"
|
2017-08-22 12:35:43 +00:00
|
|
|
#include "internal/cryptlib_int.h"
|
2016-02-09 11:26:14 +00:00
|
|
|
#include <openssl/err.h>
|
2017-08-22 12:35:43 +00:00
|
|
|
#include "internal/rand_int.h"
|
|
|
|
#include "internal/bio.h"
|
2016-02-09 11:26:14 +00:00
|
|
|
#include <openssl/evp.h>
|
2017-08-22 12:35:43 +00:00
|
|
|
#include "internal/evp_int.h"
|
|
|
|
#include "internal/conf.h"
|
|
|
|
#include "internal/async.h"
|
|
|
|
#include "internal/engine.h"
|
|
|
|
#include "internal/comp.h"
|
|
|
|
#include "internal/err.h"
|
|
|
|
#include "internal/err_int.h"
|
|
|
|
#include "internal/objects.h"
|
2016-02-09 11:26:14 +00:00
|
|
|
#include <stdlib.h>
|
2016-02-10 05:39:29 +00:00
|
|
|
#include <assert.h>
|
2017-08-22 12:35:43 +00:00
|
|
|
#include "internal/thread_once.h"
|
2018-03-23 00:05:23 +00:00
|
|
|
#include "internal/dso_conf.h"
|
2017-08-22 12:35:43 +00:00
|
|
|
#include "internal/dso.h"
|
|
|
|
#include "internal/store.h"
|
2016-02-10 05:39:29 +00:00
|
|
|
|
|
|
|
static int stopped = 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2018-07-20 11:23:42 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2019-07-02 14:29:29 +00:00
|
|
|
* and it doesn't matter if they pick "impossible" or dereference real
|
2018-07-20 11:23:42 +00:00
|
|
|
* key value and pull NULL past initialization in the first thread that
|
|
|
|
* intends to use libcrypto.
|
|
|
|
*/
|
2018-08-16 07:26:12 +00:00
|
|
|
static union {
|
|
|
|
long sane;
|
|
|
|
CRYPTO_THREAD_LOCAL value;
|
|
|
|
} destructor_key = { -1 };
|
2016-02-09 09:13:45 +00:00
|
|
|
|
2018-07-20 11:23:42 +00:00
|
|
|
static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2018-07-20 11:23:42 +00:00
|
|
|
static void ossl_init_thread_destructor(void *local)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
ossl_init_thread_stop((struct thread_local_inits_st *)local);
|
|
|
|
}
|
|
|
|
|
2016-02-09 23:09:44 +00:00
|
|
|
static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
2016-03-02 15:23:57 +00:00
|
|
|
struct thread_local_inits_st *local =
|
2018-08-16 07:26:12 +00:00
|
|
|
CRYPTO_THREAD_get_local(&destructor_key.value);
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2018-07-20 11:23:42 +00:00
|
|
|
if (alloc) {
|
|
|
|
if (local == NULL
|
|
|
|
&& (local = OPENSSL_zalloc(sizeof(*local))) != NULL
|
2018-08-16 07:26:12 +00:00
|
|
|
&& !CRYPTO_THREAD_set_local(&destructor_key.value, local)) {
|
2017-06-19 11:33:41 +00:00
|
|
|
OPENSSL_free(local);
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-07-20 11:23:42 +00:00
|
|
|
} else {
|
2018-08-16 07:26:12 +00:00
|
|
|
CRYPTO_THREAD_set_local(&destructor_key.value, NULL);
|
2016-02-09 23:09:44 +00:00
|
|
|
}
|
2016-02-09 11:26:14 +00:00
|
|
|
|
|
|
|
return local;
|
|
|
|
}
|
|
|
|
|
2016-02-10 14:55:48 +00:00
|
|
|
typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
|
2016-02-09 11:26:14 +00:00
|
|
|
struct ossl_init_stop_st {
|
|
|
|
void (*handler)(void);
|
|
|
|
OPENSSL_INIT_STOP *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
static OPENSSL_INIT_STOP *stop_handlers = NULL;
|
2016-03-07 14:39:22 +00:00
|
|
|
static CRYPTO_RWLOCK *init_lock = NULL;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
|
2016-02-09 11:26:14 +00:00
|
|
|
static int base_inited = 0;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_base)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
2018-07-20 11:23:42 +00:00
|
|
|
CRYPTO_THREAD_LOCAL key;
|
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
|
2016-07-08 17:40:08 +00:00
|
|
|
#endif
|
|
|
|
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
|
|
|
|
ossl_malloc_setup_failures();
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2018-07-20 11:23:42 +00:00
|
|
|
if (!CRYPTO_THREAD_init_local(&key, ossl_init_thread_destructor))
|
2018-04-20 13:45:06 +00:00
|
|
|
return 0;
|
|
|
|
if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
|
|
|
|
goto err;
|
2016-02-09 11:26:14 +00:00
|
|
|
OPENSSL_cpuid_setup();
|
2016-11-14 23:58:51 +00:00
|
|
|
|
2018-08-16 07:26:12 +00:00
|
|
|
destructor_key.value = key;
|
2016-02-09 11:26:14 +00:00
|
|
|
base_inited = 1;
|
2018-04-20 13:45:06 +00:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
err:
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_base not ok!\n");
|
|
|
|
#endif
|
|
|
|
CRYPTO_THREAD_lock_free(init_lock);
|
|
|
|
init_lock = NULL;
|
2016-10-18 13:13:25 +00:00
|
|
|
|
2018-07-20 11:23:42 +00:00
|
|
|
CRYPTO_THREAD_cleanup_local(&key);
|
2018-04-20 13:45:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-11-15 16:27:34 +00:00
|
|
|
static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
|
2018-11-16 17:26:23 +00:00
|
|
|
#if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32)
|
|
|
|
static int win32atexit(void)
|
|
|
|
{
|
|
|
|
OPENSSL_cleanup();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-11-15 16:27:34 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
|
|
|
|
{
|
2018-11-16 17:26:23 +00:00
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
2018-11-15 16:27:34 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
|
2018-11-16 17:26:23 +00:00
|
|
|
#endif
|
2018-11-15 16:27:34 +00:00
|
|
|
#ifndef OPENSSL_SYS_UEFI
|
2018-11-16 17:26:23 +00:00
|
|
|
# ifdef _WIN32
|
|
|
|
/* We use _onexit() in preference because it gets called on DLL unload */
|
|
|
|
if (_onexit(win32atexit) == NULL)
|
|
|
|
return 0;
|
|
|
|
# else
|
2018-11-15 16:27:34 +00:00
|
|
|
if (atexit(OPENSSL_cleanup) != 0)
|
|
|
|
return 0;
|
2018-11-16 17:26:23 +00:00
|
|
|
# endif
|
2018-11-15 16:27:34 +00:00
|
|
|
#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_no_register_atexit ok!\n");
|
|
|
|
#endif
|
|
|
|
/* Do nothing in this case */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-04-20 13:45:06 +00:00
|
|
|
static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
|
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
|
|
|
|
{
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_nodelete()\n");
|
|
|
|
#endif
|
2019-04-01 04:40:33 +00:00
|
|
|
#if !defined(OPENSSL_USE_NODELETE) \
|
2018-11-16 14:05:14 +00:00
|
|
|
&& !defined(OPENSSL_NO_PINSHARED)
|
2019-03-27 08:30:47 +00:00
|
|
|
# if defined(DSO_WIN32) && !defined(_WIN32_WCE)
|
2016-10-28 10:03:22 +00:00
|
|
|
{
|
|
|
|
HMODULE handle = NULL;
|
|
|
|
BOOL ret;
|
|
|
|
|
|
|
|
/* We don't use the DSO route for WIN32 because there is a better way */
|
|
|
|
ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
|
|
|
|
| GET_MODULE_HANDLE_EX_FLAG_PIN,
|
|
|
|
(void *)&base_inited, &handle);
|
|
|
|
|
2018-04-20 13:45:06 +00:00
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: obtained DSO reference? %s\n",
|
|
|
|
(ret == TRUE ? "No!" : "Yes."));
|
|
|
|
# endif
|
2016-10-28 10:03:22 +00:00
|
|
|
return (ret == TRUE) ? 1 : 0;
|
|
|
|
}
|
2019-04-01 04:40:33 +00:00
|
|
|
# elif !defined(DSO_NONE)
|
2016-10-18 13:13:25 +00:00
|
|
|
/*
|
|
|
|
* Deliberately leak a reference to ourselves. This will force the library
|
2017-05-04 11:51:18 +00:00
|
|
|
* to remain loaded until the atexit() handler is run at process exit.
|
2016-10-18 13:13:25 +00:00
|
|
|
*/
|
|
|
|
{
|
2018-04-20 13:45:06 +00:00
|
|
|
DSO *dso;
|
|
|
|
void *err;
|
|
|
|
|
|
|
|
if (!err_shelve_state(&err))
|
|
|
|
return 0;
|
2016-10-18 13:13:25 +00:00
|
|
|
|
|
|
|
dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
|
2018-03-19 17:37:46 +00:00
|
|
|
# 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
|
2016-10-18 13:13:25 +00:00
|
|
|
DSO_free(dso);
|
2018-04-20 13:45:06 +00:00
|
|
|
err_unshelve_state(err);
|
2016-10-18 13:13:25 +00:00
|
|
|
}
|
2016-10-28 10:03:22 +00:00
|
|
|
# endif
|
2016-10-18 14:11:57 +00:00
|
|
|
#endif
|
2016-10-18 13:13:25 +00:00
|
|
|
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
|
2016-02-09 11:26:14 +00:00
|
|
|
static int load_crypto_strings_inited = 0;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
2016-07-12 13:50:06 +00:00
|
|
|
int ret = 1;
|
2016-02-09 09:39:07 +00:00
|
|
|
/*
|
|
|
|
* OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
|
|
|
|
* pulling in all the error strings during static linking
|
|
|
|
*/
|
|
|
|
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
|
2016-02-09 11:26:14 +00:00
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"err_load_crypto_strings_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-07-12 13:50:06 +00:00
|
|
|
ret = err_load_crypto_strings_int();
|
2016-02-09 11:26:14 +00:00
|
|
|
load_crypto_strings_inited = 1;
|
2017-06-06 15:35:43 +00:00
|
|
|
#endif
|
2016-07-12 13:50:06 +00:00
|
|
|
return ret;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2018-11-20 15:32:55 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,
|
|
|
|
ossl_init_load_crypto_strings)
|
|
|
|
{
|
|
|
|
/* Do nothing in this case */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
|
|
|
|
* 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: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"openssl_add_all_ciphers_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
openssl_add_all_ciphers_int();
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2018-11-20 15:32:55 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,
|
|
|
|
ossl_init_add_all_ciphers)
|
|
|
|
{
|
|
|
|
/* Do nothing */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
|
|
|
|
* 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: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"openssl_add_all_digests()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
openssl_add_all_digests_int();
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2018-11-20 15:32:55 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
|
|
|
|
ossl_init_add_all_digests)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
/* Do nothing */
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
|
2016-02-09 11:26:14 +00:00
|
|
|
static int config_inited = 0;
|
2019-01-01 07:53:24 +00:00
|
|
|
static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_config)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
2019-01-01 07:53:24 +00:00
|
|
|
int ret = openssl_config_int(conf_settings);
|
2016-02-09 11:26:14 +00:00
|
|
|
config_inited = 1;
|
2019-01-01 07:53:24 +00:00
|
|
|
return ret;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
2018-11-20 15:32:55 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr,
|
2016-04-12 11:20:16 +00:00
|
|
|
"OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2016-04-12 11:20:16 +00:00
|
|
|
openssl_no_config_int();
|
2016-02-09 11:26:14 +00:00
|
|
|
config_inited = 1;
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
|
2016-02-09 11:26:14 +00:00
|
|
|
static int async_inited = 0;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_async)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
|
|
|
|
#endif
|
2016-07-19 17:42:11 +00:00
|
|
|
if (!async_init())
|
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
async_inited = 1;
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef OPENSSL_NO_ENGINE
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_load_openssl_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_load_openssl_int();
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
2017-03-24 15:19:00 +00:00
|
|
|
# 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
|
2016-02-09 11:26:14 +00:00
|
|
|
|
|
|
|
# ifndef OPENSSL_NO_RDRAND
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_load_rdrand_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_load_rdrand_int();
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
# endif
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_load_dynamic_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_load_dynamic_int();
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
# ifndef OPENSSL_NO_STATIC_ENGINE
|
|
|
|
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_load_padlock_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_load_padlock_int();
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
# endif
|
|
|
|
# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_load_capi_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_load_capi_int();
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
# endif
|
2016-02-23 08:01:01 +00:00
|
|
|
# if !defined(OPENSSL_NO_AFALGENG)
|
2016-03-15 13:06:34 +00:00
|
|
|
static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
|
2016-02-23 08:01:01 +00:00
|
|
|
{
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_load_afalg_int()\n");
|
2016-02-23 08:01:01 +00:00
|
|
|
# endif
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_load_afalg_int();
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-23 08:01:01 +00:00
|
|
|
}
|
|
|
|
# endif
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2016-03-11 20:13:19 +00:00
|
|
|
#ifndef OPENSSL_NO_COMP
|
2016-03-02 14:51:00 +00:00
|
|
|
static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
|
2016-03-11 20:13:19 +00:00
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
static int zlib_inited = 0;
|
2016-07-19 17:42:11 +00:00
|
|
|
DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
/* Do nothing - we need to know about this for the later cleanup */
|
|
|
|
zlib_inited = 1;
|
2016-07-19 17:42:11 +00:00
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
2016-03-11 20:13:19 +00:00
|
|
|
#endif
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-02-09 09:13:45 +00:00
|
|
|
static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
/* 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: "
|
2018-04-26 16:39:51 +00:00
|
|
|
"async_delete_thread_state()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2018-04-26 16:39:51 +00:00
|
|
|
async_delete_thread_state();
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (locals->err_state) {
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
|
2016-05-08 15:01:09 +00:00
|
|
|
"err_delete_thread_state()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2016-05-08 15:01:09 +00:00
|
|
|
err_delete_thread_state();
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-07 18:25:55 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
OPENSSL_free(locals);
|
|
|
|
}
|
|
|
|
|
2016-02-09 16:52:40 +00:00
|
|
|
void OPENSSL_thread_stop(void)
|
2016-02-09 09:13:45 +00:00
|
|
|
{
|
2018-08-16 07:26:12 +00:00
|
|
|
if (destructor_key.sane != -1)
|
2018-07-20 11:23:42 +00:00
|
|
|
ossl_init_thread_stop(ossl_init_get_thread_local(0));
|
2016-02-09 09:13:45 +00:00
|
|
|
}
|
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
int ossl_init_thread_start(uint64_t opts)
|
|
|
|
{
|
2017-06-19 11:33:41 +00:00
|
|
|
struct thread_local_inits_st *locals;
|
|
|
|
|
|
|
|
if (!OPENSSL_init_crypto(0, NULL))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
locals = ossl_init_get_thread_local(1);
|
2016-02-09 11:26:14 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-03-07 18:25:55 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-02-09 16:52:40 +00:00
|
|
|
void OPENSSL_cleanup(void)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
OPENSSL_INIT_STOP *currhandler, *lasthandler;
|
2018-07-20 11:23:42 +00:00
|
|
|
CRYPTO_THREAD_LOCAL key;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-02-10 09:47:51 +00:00
|
|
|
/* If we've not been inited then no need to deinit */
|
|
|
|
if (!base_inited)
|
|
|
|
return;
|
|
|
|
|
2016-02-10 05:39:29 +00:00
|
|
|
/* Might be explicitly called and also by atexit */
|
|
|
|
if (stopped)
|
|
|
|
return;
|
|
|
|
stopped = 1;
|
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
/*
|
|
|
|
* 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));
|
|
|
|
|
|
|
|
currhandler = stop_handlers;
|
|
|
|
while (currhandler != NULL) {
|
|
|
|
currhandler->handler();
|
|
|
|
lasthandler = currhandler;
|
|
|
|
currhandler = currhandler->next;
|
|
|
|
OPENSSL_free(lasthandler);
|
|
|
|
}
|
|
|
|
stop_handlers = NULL;
|
2016-03-07 14:39:22 +00:00
|
|
|
|
|
|
|
CRYPTO_THREAD_lock_free(init_lock);
|
2018-01-26 15:32:40 +00:00
|
|
|
init_lock = NULL;
|
2016-03-07 14:39:22 +00:00
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
/*
|
|
|
|
* We assume we are single-threaded for this function, i.e. no race
|
|
|
|
* conditions for the various "*_inited" vars below.
|
|
|
|
*/
|
|
|
|
|
2016-03-11 20:13:19 +00:00
|
|
|
#ifndef OPENSSL_NO_COMP
|
2016-02-09 11:26:14 +00:00
|
|
|
if (zlib_inited) {
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
2016-02-09 16:52:40 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"comp_zlib_cleanup_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2016-04-12 11:20:16 +00:00
|
|
|
comp_zlib_cleanup_int();
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
2016-03-11 20:13:19 +00:00
|
|
|
#endif
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 16:52:43 +00:00
|
|
|
if (async_inited) {
|
|
|
|
# ifdef OPENSSL_INIT_DEBUG
|
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
|
|
|
"async_deinit()\n");
|
|
|
|
# endif
|
|
|
|
async_deinit();
|
|
|
|
}
|
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
if (load_crypto_strings_inited) {
|
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
2016-02-09 16:52:40 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"err_free_strings_int()\n");
|
2016-02-09 11:26:14 +00:00
|
|
|
#endif
|
2016-04-12 11:20:16 +00:00
|
|
|
err_free_strings_int();
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 07:26:12 +00:00
|
|
|
key = destructor_key.value;
|
|
|
|
destructor_key.sane = -1;
|
2018-07-20 11:23:42 +00:00
|
|
|
CRYPTO_THREAD_cleanup_local(&key);
|
2016-02-18 12:24:09 +00:00
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
#ifdef OPENSSL_INIT_DEBUG
|
2016-03-14 10:34:59 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"rand_cleanup_int()\n");
|
2016-03-14 10:34:59 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"conf_modules_free_int()\n");
|
2016-03-09 11:52:50 +00:00
|
|
|
#ifndef OPENSSL_NO_ENGINE
|
2016-03-09 00:53:38 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"engine_cleanup_int()\n");
|
2016-03-09 11:52:50 +00:00
|
|
|
#endif
|
2016-03-14 10:34:59 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"crypto_cleanup_all_ex_data_int()\n");
|
2016-03-14 10:34:59 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"bio_sock_cleanup_int()\n");
|
2016-03-11 21:53:18 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
|
|
|
"bio_cleanup()\n");
|
2016-03-14 10:34:59 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"evp_cleanup_int()\n");
|
2016-03-14 10:34:59 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
2016-04-12 11:20:16 +00:00
|
|
|
"obj_cleanup_int()\n");
|
2016-03-11 21:53:18 +00:00
|
|
|
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
|
|
|
|
"err_cleanup()\n");
|
2016-03-09 11:52:50 +00:00
|
|
|
#endif
|
2016-03-14 10:34:59 +00:00
|
|
|
/*
|
|
|
|
* Note that cleanup order is important:
|
2016-04-13 11:11:59 +00:00
|
|
|
* - rand_cleanup_int could call an ENGINE's RAND cleanup function so
|
2016-04-12 11:20:16 +00:00
|
|
|
* must be called before engine_cleanup_int()
|
2016-03-14 10:34:59 +00:00
|
|
|
* - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
|
|
|
|
* before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
|
2016-04-12 11:20:16 +00:00
|
|
|
* - conf_modules_free_int() can end up in ENGINE code so must be called
|
|
|
|
* before engine_cleanup_int()
|
2016-04-13 11:11:59 +00:00
|
|
|
* - ENGINEs and additional EVP algorithms might use added OIDs names so
|
|
|
|
* obj_cleanup_int() must be called last
|
2016-03-14 10:34:59 +00:00
|
|
|
*/
|
2016-04-12 11:20:16 +00:00
|
|
|
rand_cleanup_int();
|
2017-08-31 21:16:22 +00:00
|
|
|
rand_drbg_cleanup_int();
|
2016-04-12 11:20:16 +00:00
|
|
|
conf_modules_free_int();
|
2016-03-11 09:52:52 +00:00
|
|
|
#ifndef OPENSSL_NO_ENGINE
|
2016-04-12 11:20:16 +00:00
|
|
|
engine_cleanup_int();
|
2016-03-11 09:52:52 +00:00
|
|
|
#endif
|
2016-12-08 14:51:31 +00:00
|
|
|
ossl_store_cleanup_int();
|
2016-04-12 11:20:16 +00:00
|
|
|
crypto_cleanup_all_ex_data_int();
|
2016-03-11 21:53:18 +00:00
|
|
|
bio_cleanup();
|
2016-04-12 11:20:16 +00:00
|
|
|
evp_cleanup_int();
|
|
|
|
obj_cleanup_int();
|
2016-03-11 21:53:18 +00:00
|
|
|
err_cleanup();
|
|
|
|
|
2018-02-12 01:37:27 +00:00
|
|
|
CRYPTO_secure_malloc_done();
|
|
|
|
|
2016-02-10 09:47:51 +00:00
|
|
|
base_inited = 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If this function is called with a non NULL settings value then it must be
|
|
|
|
* called prior to any threads making calls to any OpenSSL functions,
|
|
|
|
* i.e. passing a non-null settings value is assumed to be single-threaded.
|
|
|
|
*/
|
2016-02-10 13:59:15 +00:00
|
|
|
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
2016-02-10 15:16:06 +00:00
|
|
|
if (stopped) {
|
2018-04-20 13:45:06 +00:00
|
|
|
if (!(opts & OPENSSL_INIT_BASE_ONLY))
|
|
|
|
CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
|
2016-02-10 13:59:15 +00:00
|
|
|
return 0;
|
2016-02-10 15:16:06 +00:00
|
|
|
}
|
2016-02-10 05:39:29 +00:00
|
|
|
|
2019-01-01 07:53:24 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2018-04-20 13:45:06 +00:00
|
|
|
if (!RUN_ONCE(&base, ossl_init_base))
|
|
|
|
return 0;
|
2019-01-01 07:53:24 +00:00
|
|
|
if (opts & OPENSSL_INIT_BASE_ONLY)
|
|
|
|
return 1;
|
2018-04-20 13:45:06 +00:00
|
|
|
|
2019-01-01 07:53:24 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2018-11-15 16:27:34 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-01-01 07:53:24 +00:00
|
|
|
if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
|
2018-11-20 15:32:55 +00:00
|
|
|
&& !RUN_ONCE_ALT(&load_crypto_strings,
|
|
|
|
ossl_init_no_load_crypto_strings,
|
|
|
|
ossl_init_load_crypto_strings))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
|
2018-11-20 15:32:55 +00:00
|
|
|
&& !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers,
|
|
|
|
ossl_init_add_all_ciphers))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
|
2018-11-20 15:32:55 +00:00
|
|
|
&& !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests,
|
|
|
|
ossl_init_add_all_digests))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
2017-06-30 17:55:08 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ATFORK)
|
2017-06-22 18:00:06 +00:00
|
|
|
&& !openssl_init_fork_handlers())
|
|
|
|
return 0;
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
|
2018-11-20 15:32:55 +00:00
|
|
|
&& !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
|
|
|
|
if (opts & OPENSSL_INIT_LOAD_CONFIG) {
|
2016-03-02 14:51:00 +00:00
|
|
|
int ret;
|
2016-03-07 14:39:22 +00:00
|
|
|
CRYPTO_THREAD_write_lock(init_lock);
|
2019-01-01 07:53:24 +00:00
|
|
|
conf_settings = settings;
|
2016-07-19 17:42:11 +00:00
|
|
|
ret = RUN_ONCE(&config, ossl_init_config);
|
2019-01-01 07:53:24 +00:00
|
|
|
conf_settings = NULL;
|
2016-03-07 14:39:22 +00:00
|
|
|
CRYPTO_THREAD_unlock(init_lock);
|
2019-04-05 08:28:32 +00:00
|
|
|
if (ret <= 0)
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ASYNC)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&async, ossl_init_async))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-03-17 17:06:28 +00:00
|
|
|
|
2016-02-09 11:26:14 +00:00
|
|
|
#ifndef OPENSSL_NO_ENGINE
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2017-03-24 15:19:00 +00:00
|
|
|
# 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
|
2016-02-09 11:26:14 +00:00
|
|
|
# ifndef OPENSSL_NO_RDRAND
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
# ifndef OPENSSL_NO_STATIC_ENGINE
|
|
|
|
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
|
|
|
# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ENGINE_CAPI)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
2016-02-23 08:01:01 +00:00
|
|
|
# if !defined(OPENSSL_NO_AFALGENG)
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ENGINE_AFALG)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-02-23 08:01:01 +00:00
|
|
|
# endif
|
2016-02-09 11:26:14 +00:00
|
|
|
# endif
|
|
|
|
if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
|
2016-08-17 13:06:23 +00:00
|
|
|
| OPENSSL_INIT_ENGINE_OPENSSL
|
2016-02-23 08:01:01 +00:00
|
|
|
| OPENSSL_INIT_ENGINE_AFALG)) {
|
2016-02-09 11:26:14 +00:00
|
|
|
ENGINE_register_all_complete();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-03-11 20:13:19 +00:00
|
|
|
#ifndef OPENSSL_NO_COMP
|
2016-03-02 14:51:00 +00:00
|
|
|
if ((opts & OPENSSL_INIT_ZLIB)
|
2016-07-19 17:42:11 +00:00
|
|
|
&& !RUN_ONCE(&zlib, ossl_init_zlib))
|
2016-03-02 14:51:00 +00:00
|
|
|
return 0;
|
2016-03-11 20:13:19 +00:00
|
|
|
#endif
|
2016-02-10 13:59:15 +00:00
|
|
|
|
|
|
|
return 1;
|
2016-02-09 11:26:14 +00:00
|
|
|
}
|
|
|
|
|
2016-02-09 16:52:40 +00:00
|
|
|
int OPENSSL_atexit(void (*handler)(void))
|
2016-02-09 11:26:14 +00:00
|
|
|
{
|
|
|
|
OPENSSL_INIT_STOP *newhand;
|
|
|
|
|
2019-04-01 04:40:33 +00:00
|
|
|
#if !defined(OPENSSL_USE_NODELETE)\
|
2018-11-16 14:05:14 +00:00
|
|
|
&& !defined(OPENSSL_NO_PINSHARED)
|
2016-10-18 13:13:25 +00:00
|
|
|
{
|
|
|
|
union {
|
|
|
|
void *sym;
|
|
|
|
void (*func)(void);
|
|
|
|
} handlersym;
|
|
|
|
|
|
|
|
handlersym.func = handler;
|
2019-03-27 08:30:47 +00:00
|
|
|
# if defined(DSO_WIN32) && !defined(_WIN32_WCE)
|
2016-10-28 10:03:22 +00:00
|
|
|
{
|
|
|
|
HMODULE handle = NULL;
|
|
|
|
BOOL ret;
|
2016-10-18 13:13:25 +00:00
|
|
|
|
2016-10-28 10:03:22 +00:00
|
|
|
/*
|
|
|
|
* We don't use the DSO route for WIN32 because there is a better
|
|
|
|
* way
|
|
|
|
*/
|
|
|
|
ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
|
|
|
|
| GET_MODULE_HANDLE_EX_FLAG_PIN,
|
|
|
|
handlersym.sym, &handle);
|
|
|
|
|
|
|
|
if (!ret)
|
|
|
|
return 0;
|
|
|
|
}
|
2019-04-01 04:40:33 +00:00
|
|
|
# elif !defined(DSO_NONE)
|
2016-10-28 10:03:22 +00:00
|
|
|
/*
|
|
|
|
* Deliberately leak a reference to the handler. This will force the
|
|
|
|
* library/code containing the handler to remain loaded until we run the
|
|
|
|
* atexit handler. If -znodelete has been used then this is
|
2017-08-04 05:10:41 +00:00
|
|
|
* unnecessary.
|
2016-10-28 10:03:22 +00:00
|
|
|
*/
|
|
|
|
{
|
|
|
|
DSO *dso = NULL;
|
|
|
|
|
2017-05-04 11:51:18 +00:00
|
|
|
ERR_set_mark();
|
2016-10-28 10:03:22 +00:00
|
|
|
dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
|
2018-03-19 17:37:46 +00:00
|
|
|
# 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
|
2016-10-28 10:03:22 +00:00
|
|
|
DSO_free(dso);
|
2017-05-04 11:51:18 +00:00
|
|
|
ERR_pop_to_mark();
|
2016-10-28 10:03:22 +00:00
|
|
|
}
|
|
|
|
# endif
|
2016-10-18 13:13:25 +00:00
|
|
|
}
|
2016-10-18 14:11:57 +00:00
|
|
|
#endif
|
2016-10-18 13:13:25 +00:00
|
|
|
|
2018-04-03 15:31:16 +00:00
|
|
|
if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL) {
|
|
|
|
CRYPTOerr(CRYPTO_F_OPENSSL_ATEXIT, ERR_R_MALLOC_FAILURE);
|
2016-02-09 11:26:14 +00:00
|
|
|
return 0;
|
2018-04-03 15:31:16 +00:00
|
|
|
}
|
2016-02-09 11:26:14 +00:00
|
|
|
|
|
|
|
newhand->handler = handler;
|
|
|
|
newhand->next = stop_handlers;
|
|
|
|
stop_handlers = newhand;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2017-06-22 18:00:06 +00:00
|
|
|
|
Revert the crypto "global lock" implementation
Conceptually, this is a squashed version of:
Revert "Address feedback"
This reverts commit 75551e07bd2339dfea06ef1d31d69929e13a4495.
and
Revert "Add CRYPTO_thread_glock_new"
This reverts commit ed6b2c7938ec6f07b15745d4183afc276e74c6dd.
But there were some intervening commits that made neither revert apply
cleanly, so instead do it all as one shot.
The crypto global locks were an attempt to cope with the awkward
POSIX semantics for pthread_atfork(); its documentation (the "RATIONALE"
section) indicates that the expected usage is to have the prefork handler
lock all "global" locks, and the parent and child handlers release those
locks, to ensure that forking happens with a consistent (lock) state.
However, the set of functions available in the child process is limited
to async-signal-safe functions, and pthread_mutex_unlock() is not on
the list of async-signal-safe functions! The only synchronization
primitives that are async-signal-safe are the semaphore primitives,
which are not really appropriate for general-purpose usage.
However, the state consistency problem that the global locks were
attempting to solve is not actually a serious problem, particularly for
OpenSSL. That is, we can consider four cases of forking application
that might use OpenSSL:
(1) Single-threaded, does not call into OpenSSL in the child (e.g.,
the child calls exec() immediately)
For this class of process, no locking is needed at all, since there is
only ever a single thread of execution and the only reentrancy is due to
signal handlers (which are themselves limited to async-signal-safe
operation and should not be doing much work at all).
(2) Single-threaded, calls into OpenSSL after fork()
The application must ensure that it does not fork() with an unexpected
lock held (that is, one that would get unlocked in the parent but
accidentally remain locked in the child and cause deadlock). Since
OpenSSL does not expose any of its internal locks to the application
and the application is single-threaded, the OpenSSL internal locks
will be unlocked for the fork(), and the state will be consistent.
(OpenSSL will need to reseed its PRNG in the child, but that is
an orthogonal issue.) If the application makes use of locks from
libcrypto, proper handling for those locks is the responsibility of
the application, as for any other locking primitive that is available
for application programming.
(3) Multi-threaded, does not call into OpenSSL after fork()
As for (1), the OpenSSL state is only relevant in the parent, so
no particular fork()-related handling is needed. The internal locks
are relevant, but there is no interaction with the child to consider.
(4) Multi-threaded, calls into OpenSSL after fork()
This is the case where the pthread_atfork() hooks to ensure that all
global locks are in a known state across fork() would come into play,
per the above discussion. However, these "calls into OpenSSL after
fork()" are still subject to the restriction to async-signal-safe
functions. Since OpenSSL uses all sorts of locking and libc functions
that are not on the list of safe functions (e.g., malloc()), this
case is not currently usable and is unlikely to ever be usable,
independently of the locking situation. So, there is no need to
go through contortions to attempt to support this case in the one small
area of locking interaction with fork().
In light of the above analysis (thanks @davidben and @achernya), go
back to the simpler implementation that does not need to distinguish
"library-global" locks or to have complicated atfork handling for locks.
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/5089)
2018-01-16 15:49:54 +00:00
|
|
|
#ifdef OPENSSL_SYS_UNIX
|
2017-06-22 18:00:06 +00:00
|
|
|
/*
|
|
|
|
* The following three functions are for OpenSSL developers. This is
|
|
|
|
* where we set/reset state across fork (called via pthread_atfork when
|
|
|
|
* it exists, or manually by the application when it doesn't).
|
|
|
|
*
|
|
|
|
* WARNING! If you put code in either OPENSSL_fork_parent or
|
|
|
|
* OPENSSL_fork_child, you MUST MAKE SURE that they are async-signal-
|
|
|
|
* safe. See this link, for example:
|
|
|
|
* http://man7.org/linux/man-pages/man7/signal-safety.7.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
void OPENSSL_fork_prepare(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void OPENSSL_fork_parent(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void OPENSSL_fork_child(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|