mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
Move most of the OpenSSL initialization to isc_tls
Since we now require both libcrypto and libssl to be initialized for netmgr, we move all the OpenSSL initialization code except the engine initialization to isc_tls API. The isc_tls_initialize() and isc_tls_destroy() has been made idempotent, so they could be called multiple time. However when isc_tls_destroy() has been called, the isc_tls_initialize() could not be called again.
This commit is contained in:
@@ -201,7 +201,7 @@ dst_lib_init(isc_mem_t *mctx, const char *engine) {
|
||||
RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256]));
|
||||
RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384]));
|
||||
RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512]));
|
||||
RETERR(dst__openssl_init(mctx, engine));
|
||||
RETERR(dst__openssl_init(engine));
|
||||
RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH]));
|
||||
#if USE_OPENSSL
|
||||
RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1],
|
||||
|
@@ -201,7 +201,7 @@ struct dst_func {
|
||||
* Initializers
|
||||
*/
|
||||
isc_result_t
|
||||
dst__openssl_init(isc_mem_t *, const char *engine);
|
||||
dst__openssl_init(const char *engine);
|
||||
#define dst__pkcs11_init pk11_initialize
|
||||
|
||||
isc_result_t
|
||||
|
@@ -39,8 +39,6 @@
|
||||
#include "dst_internal.h"
|
||||
#include "dst_openssl.h"
|
||||
|
||||
static isc_mem_t *dst__mctx = NULL;
|
||||
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
#include <openssl/engine.h>
|
||||
#endif /* if !defined(OPENSSL_NO_ENGINE) */
|
||||
@@ -67,36 +65,14 @@ enable_fips_mode(void) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dst__openssl_init(isc_mem_t *mctx, const char *engine) {
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(dst__mctx == NULL);
|
||||
isc_mem_attach(mctx, &dst__mctx);
|
||||
|
||||
#if defined(OPENSSL_NO_ENGINE)
|
||||
UNUSED(engine);
|
||||
#endif /* if defined(OPENSSL_NO_ENGINE) */
|
||||
|
||||
enable_fips_mode();
|
||||
dst__openssl_init(const char *engine) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
isc_tls_initialize();
|
||||
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
#if !defined(CONF_MFLAGS_DEFAULT_SECTION)
|
||||
OPENSSL_config(NULL);
|
||||
#else /* if !defined(CONF_MFLAGS_DEFAULT_SECTION) */
|
||||
/*
|
||||
* OPENSSL_config() can only be called a single time as of
|
||||
* 1.0.2e so do the steps individually.
|
||||
*/
|
||||
OPENSSL_load_builtin_modules();
|
||||
ENGINE_load_builtin_engines();
|
||||
ERR_clear_error();
|
||||
CONF_modules_load_file(NULL, NULL,
|
||||
CONF_MFLAGS_DEFAULT_SECTION |
|
||||
CONF_MFLAGS_IGNORE_MISSING_FILE);
|
||||
#endif /* if !defined(CONF_MFLAGS_DEFAULT_SECTION) */
|
||||
enable_fips_mode();
|
||||
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
if (engine != NULL && *engine == '\0') {
|
||||
engine = NULL;
|
||||
}
|
||||
@@ -114,54 +90,27 @@ dst__openssl_init(isc_mem_t *mctx, const char *engine) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined(OPENSSL_NO_ENGINE) */
|
||||
|
||||
/* Protect ourselves against unseeded PRNG */
|
||||
if (RAND_status() != 1) {
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
"OpenSSL pseudorandom number generator "
|
||||
"cannot be initialized (see the `PRNG not "
|
||||
"seeded' message in the OpenSSL FAQ)");
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
cleanup_rm:
|
||||
if (e != NULL) {
|
||||
ENGINE_free(e);
|
||||
}
|
||||
e = NULL;
|
||||
#else
|
||||
UNUSED(engine);
|
||||
#endif /* if !defined(OPENSSL_NO_ENGINE) */
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
dst__openssl_destroy(void) {
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
/*
|
||||
* Sequence taken from apps_shutdown() in <apps/apps.h>.
|
||||
*/
|
||||
CONF_modules_free();
|
||||
OBJ_cleanup();
|
||||
EVP_cleanup();
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
if (e != NULL) {
|
||||
ENGINE_free(e);
|
||||
}
|
||||
e = NULL;
|
||||
ENGINE_cleanup();
|
||||
#endif /* if !defined(OPENSSL_NO_ENGINE) */
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_clear_error();
|
||||
|
||||
#ifdef DNS_CRYPTO_LEAKS
|
||||
CRYPTO_mem_leaks_fp(stderr);
|
||||
#endif /* ifdef DNS_CRYPTO_LEAKS */
|
||||
|
||||
#endif
|
||||
isc_tls_destroy();
|
||||
isc_mem_detach(&dst__mctx);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
111
lib/isc/tls.c
111
lib/isc/tls.c
@@ -9,8 +9,10 @@
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/log.h>
|
||||
@@ -24,10 +26,12 @@
|
||||
#include "openssl_shim.h"
|
||||
|
||||
static isc_once_t init_once = ISC_ONCE_INIT;
|
||||
static isc_once_t shut_once = ISC_ONCE_INIT;
|
||||
static atomic_bool init_done = ATOMIC_VAR_INIT(false);
|
||||
static atomic_bool shut_done = ATOMIC_VAR_INIT(false);
|
||||
static isc_mem_t *isc__tls_mctx = NULL;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
static isc_mem_t *isc__tls_mctx = NULL;
|
||||
static isc_mutex_t *locks = NULL;
|
||||
static int nlocks;
|
||||
|
||||
@@ -48,22 +52,82 @@ isc__tls_set_thread_id(CRYPTO_THREADID *id) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void *
|
||||
isc__tls_malloc(size_t size, const char *file, int line) {
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
|
||||
return (isc_mem_allocate(isc__tls_mctx, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
isc__tls_realloc(void *ptr, size_t size, const char *file, int line) {
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
|
||||
return (isc__mem_reallocate(isc__tls_mctx, ptr, size));
|
||||
}
|
||||
|
||||
static void
|
||||
isc__tls_free(void *ptr, const char *file, int line) {
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
isc__mem_free(isc__tls_mctx, ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
isc__tls_initialize(void) {
|
||||
REQUIRE(!atomic_load(&init_done));
|
||||
RUNTIME_CHECK(OPENSSL_init_ssl(0, NULL) == 1);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
isc_mem_create(&isc__tls_mctx);
|
||||
/* isc_mem_setdestroycheck(isc__tls_mctx, false); */
|
||||
|
||||
/* REQUIRE(CRYPTO_set_mem_functions(isc__tls_malloc, isc__tls_realloc,
|
||||
* isc__tls_free) == 1); */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
RUNTIME_CHECK(OPENSSL_init_ssl(OPENSSL_INIT_ENGINE_ALL_BUILTIN |
|
||||
OPENSSL_INIT_LOAD_CONFIG,
|
||||
NULL) == 1);
|
||||
#else
|
||||
nlocks = CRYPTO_num_locks();
|
||||
locks = isc_mem_get(isc__tls_mctx, nlocks * sizeof(locks[0]));
|
||||
isc_mutexblock_init(locks, nlocks);
|
||||
CRYPTO_set_locking_callback(isc__tls_lock_callback);
|
||||
CRYPTO_THREADID_set_callback(isc__tls_set_thread_id);
|
||||
|
||||
CRYPTO_malloc_init();
|
||||
ERR_load_crypto_strings();
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
atomic_store(&init_done, true);
|
||||
OpenSSL_add_all_algorithms();
|
||||
OPENSSL_load_builtin_modules();
|
||||
|
||||
CONF_modules_load_file(NULL, NULL,
|
||||
CONF_MFLAGS_DEFAULT_SECTION |
|
||||
CONF_MFLAGS_IGNORE_MISSING_FILE);
|
||||
#endif
|
||||
|
||||
/* Protect ourselves against unseeded PRNG */
|
||||
if (RAND_status() != 1) {
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
"OpenSSL pseudorandom number generator "
|
||||
"cannot be initialized (see the `PRNG not "
|
||||
"seeded' message in the OpenSSL FAQ)");
|
||||
}
|
||||
|
||||
atomic_compare_exchange_strong(&init_done, &(bool){ false }, true);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -73,26 +137,45 @@ isc_tls_initialize(void) {
|
||||
REQUIRE(atomic_load(&init_done));
|
||||
}
|
||||
|
||||
void
|
||||
isc_tls_destroy(void) {
|
||||
static void
|
||||
isc__tls_destroy(void) {
|
||||
REQUIRE(atomic_load(&init_done));
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
REQUIRE(!atomic_load(&shut_done));
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
|
||||
CONF_modules_unload(1);
|
||||
OBJ_cleanup();
|
||||
EVP_cleanup();
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
ENGINE_cleanup();
|
||||
#endif
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_thread_state(NULL);
|
||||
RAND_cleanup();
|
||||
ERR_free_strings();
|
||||
|
||||
ERR_remove_thread_state(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
|
||||
/* REQUIRE(CRYPTO_set_mem_functions(OPENSSL_malloc, OPENSSL_realloc,
|
||||
* OPENSSL_free) == 1); */
|
||||
|
||||
if (locks != NULL) {
|
||||
INSIST(isc__tls_mctx != NULL);
|
||||
isc_mutexblock_destroy(locks, nlocks);
|
||||
isc_mem_put(isc__tls_mctx, locks, nlocks * sizeof(locks[0]));
|
||||
locks = NULL;
|
||||
}
|
||||
|
||||
if (isc__tls_mctx != NULL) {
|
||||
isc_mem_detach(&isc__tls_mctx);
|
||||
}
|
||||
#endif
|
||||
isc_mem_detach(&isc__tls_mctx);
|
||||
|
||||
atomic_compare_exchange_strong(&shut_done, &(bool){ false }, true);
|
||||
}
|
||||
|
||||
void
|
||||
isc_tls_destroy(void) {
|
||||
isc_result_t result = isc_once_do(&shut_once, isc__tls_destroy);
|
||||
REQUIRE(result == ISC_R_SUCCESS);
|
||||
REQUIRE(atomic_load(&shut_done));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -115,6 +198,8 @@ isc_tlsctx_createclient(isc_tlsctx_t **ctxp) {
|
||||
|
||||
REQUIRE(ctxp != NULL && *ctxp == NULL);
|
||||
|
||||
isc_tls_initialize();
|
||||
|
||||
method = TLS_client_method();
|
||||
if (method == NULL) {
|
||||
goto ssl_error;
|
||||
@@ -163,6 +248,8 @@ isc_tlsctx_createserver(const char *keyfile, const char *certfile,
|
||||
|
||||
REQUIRE(ctxp != NULL && *ctxp == NULL);
|
||||
|
||||
isc_tls_initialize();
|
||||
|
||||
if (ephemeral) {
|
||||
INSIST(keyfile == NULL);
|
||||
INSIST(certfile == NULL);
|
||||
|
Reference in New Issue
Block a user