]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Move most of the OpenSSL initialization to isc_tls
authorOndřej Surý <ondrej@sury.org>
Tue, 9 Feb 2021 12:25:46 +0000 (13:25 +0100)
committerOndřej Surý <ondrej@sury.org>
Thu, 18 Feb 2021 18:33:54 +0000 (19:33 +0100)
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.

lib/dns/dst_api.c
lib/dns/dst_internal.h
lib/dns/openssl_link.c
lib/isc/tls.c

index 7e89a72a2bea9ab50c5cd6788bded4eafc751dfa..9692ac66be4d963fc8db0a505bc3508eb3b8f002 100644 (file)
@@ -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],
index 776638fdc43ddc580edf9da29ae49e64904cf5b6..793606e013bae48c866e990d95d9dd0a1ff08aa4 100644 (file)
@@ -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
index ff4760b917baa9224e784d21582796d17113642d..bb26adcf26dffd5069ade9d24f2246c3ac60d6aa 100644 (file)
@@ -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);
+dst__openssl_init(const char *engine) {
+       isc_result_t result = ISC_R_SUCCESS;
 
-#if defined(OPENSSL_NO_ENGINE)
-       UNUSED(engine);
-#endif /* if defined(OPENSSL_NO_ENGINE) */
+       isc_tls_initialize();
 
        enable_fips_mode();
 
-       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) */
-
        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
index ea5de5dbf99eda9638995114033a7cf464d04e32..57066a412167945a35b697ea9314bc6416fa83dc 100644 (file)
@@ -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>
 #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
+       OpenSSL_add_all_algorithms();
+       OPENSSL_load_builtin_modules();
+
+       CONF_modules_load_file(NULL, NULL,
+                              CONF_MFLAGS_DEFAULT_SECTION |
+                                      CONF_MFLAGS_IGNORE_MISSING_FILE);
 #endif
-       atomic_store(&init_done, true);
+
+       /* 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)
-       ERR_free_strings();
+       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();
+
        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);