From 644ced68238c04ded4cc94e2ad1d2ce66397146e Mon Sep 17 00:00:00 2001 From: S-P Chan Date: Wed, 3 Jan 2024 20:00:46 +0800 Subject: [PATCH 1/3] tls: POC for OpenSSL 3 - avoid initializing ERR_STATE in the main thread of rank 0 - run configuration functions in a separate thread so that the main thread is not contaminated --- src/modules/tls/tls_init.c | 87 ++++++++++++++++++++++++-------------- src/modules/tls/tls_mod.c | 6 +++ 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/modules/tls/tls_init.c b/src/modules/tls/tls_init.c index 9be5e1d4fab..cc586f7aeff 100644 --- a/src/modules/tls/tls_init.c +++ b/src/modules/tls/tls_init.c @@ -771,6 +771,50 @@ int tls_pre_init(void) * tls mod pre-init function * - executed before any mod_init() */ + +/* + * OpenSSL 3.x: run in thread to avoid init'ing + * ERR_STATE + */ + +long tls_h_randctx(void *) { + do { + OSSL_LIB_CTX *osslglobal = NULL; + EVP_RAND_CTX *randctx = NULL; + + LM_DBG("enabling locking for rand ctx\n"); + + osslglobal = OSSL_LIB_CTX_get0_global_default(); + if(osslglobal == NULL) { + LM_ERR("failed to get lib ssl global ctx\n"); + return -1; + } + + randctx = RAND_get0_primary(osslglobal); + if(randctx == NULL) { + LM_ERR("primary rand ctx is null\n"); + return -1; + } + EVP_RAND_enable_locking(randctx); + + randctx = RAND_get0_public(osslglobal); + if(randctx == NULL) { + LM_ERR("public rand ctx is null\n"); + return -1; + } + EVP_RAND_enable_locking(randctx); + + randctx = RAND_get0_private(osslglobal); + if(randctx == NULL) { + LM_ERR("private rand ctx is null\n"); + return -1; + } + EVP_RAND_enable_locking(randctx); + } while(0); + + return 0; +} + int tls_h_mod_pre_init_f(void) { if(tls_mod_preinitialized == 1) { @@ -784,7 +828,8 @@ int tls_h_mod_pre_init_f(void) LM_DBG("preparing tls env for modules initialization\n"); #if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) LM_DBG("preparing tls env for modules initialization (libssl >=1.1)\n"); -#if OPENSSL_VERSION_NUMBER >= 0x010101000L +#if OPENSSL_VERSION_NUMBER == 0x010101000L + // not needed for OpenSSL 3 OPENSSL_init_ssl(OPENSSL_INIT_ATFORK, NULL); #else OPENSSL_init_ssl(0, NULL); @@ -793,42 +838,20 @@ int tls_h_mod_pre_init_f(void) LM_DBG("preparing tls env for modules initialization (libssl <=1.0)\n"); SSL_library_init(); #endif +#if OPENSSL_VERSION_NUMBER < 0x030000000L + // not needed for OpenSSL 3 SSL_load_error_strings(); +#endif #if OPENSSL_VERSION_NUMBER >= 0x030000000L - do { - OSSL_LIB_CTX *osslglobal = NULL; - EVP_RAND_CTX *randctx = NULL; - - LM_DBG("enabling locking for rand ctx\n"); - - osslglobal = OSSL_LIB_CTX_get0_global_default(); - if(osslglobal == NULL) { - LM_ERR("failed to get lib ssl global ctx\n"); - return -1; - } + pthread_t thread_id; + long retval; - randctx = RAND_get0_primary(osslglobal); - if(randctx == NULL) { - LM_ERR("primary rand ctx is null\n"); - return -1; - } - EVP_RAND_enable_locking(randctx); + pthread_create(&thread_id, NULL, (void *(*)(void *))tls_h_randctx, NULL); + pthread_join(thread_id, (void **)&retval); - randctx = RAND_get0_public(osslglobal); - if(randctx == NULL) { - LM_ERR("public rand ctx is null\n"); - return -1; - } - EVP_RAND_enable_locking(randctx); - - randctx = RAND_get0_private(osslglobal); - if(randctx == NULL) { - LM_ERR("private rand ctx is null\n"); - return -1; - } - EVP_RAND_enable_locking(randctx); - } while(0); + if (retval != 0) + return retval; #endif tls_mod_preinitialized = 1; diff --git a/src/modules/tls/tls_mod.c b/src/modules/tls/tls_mod.c index 3a047769ca4..fdda8eb4cc6 100644 --- a/src/modules/tls/tls_mod.c +++ b/src/modules/tls/tls_mod.c @@ -440,7 +440,13 @@ static int mod_child(int rank) /* fix tls config only from the main proc/PROC_INIT., when we know * the exact process number and before any other process starts*/ + + /* OpenSSL 3: initialization in PROC_SIPINIT to avoid init'ing ERR_STATE */ +#if OPENSSL_VERSION_NUMBER < 0x030000000L if(rank == PROC_INIT) { +#else + if(rank == PROC_SIPINIT) { +#endif if(cfg_get(tls, tls_cfg, config_file).s) { if(tls_fix_domains_cfg( *tls_domains_cfg, &srv_defaults, &cli_defaults) From 5abb3bd26ec31521ee8f02ff3e8c0eef0e0b4275 Mon Sep 17 00:00:00 2001 From: S-P Chan Date: Wed, 3 Jan 2024 20:06:22 +0800 Subject: [PATCH 2/3] outbound: OpenSSL 3 POC - call OpenSSL 3 functions in a thread to avoid contaminating the main thread of rank 0 --- src/modules/outbound/outbound_mod.c | 38 ++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/modules/outbound/outbound_mod.c b/src/modules/outbound/outbound_mod.c index 4e408e22356..a50d3c20cfb 100644 --- a/src/modules/outbound/outbound_mod.c +++ b/src/modules/outbound/outbound_mod.c @@ -75,6 +75,23 @@ struct module_exports exports = { destroy /* destroy function */ }; +static void *mod_openssl_init(void *) { + if(flow_token_secret.s) { + assert(ob_key.len == SHA_DIGEST_LENGTH); + LM_DBG("flow_token_secret mod param set. use persistent ob_key"); + SHA1((const unsigned char *)flow_token_secret.s, flow_token_secret.len, + (unsigned char *)ob_key.s); + } else { + if(RAND_bytes((unsigned char *)ob_key.s, ob_key.len) == 0) { + LM_ERR("unable to get %d cryptographically strong pseudo-" + "random bytes\n", + ob_key.len); + } + } + + return NULL; +} + static int mod_init(void) { if(ob_force_flag != -1 && !flag_in_range(ob_force_flag)) { @@ -93,18 +110,15 @@ static int mod_init(void) } ob_key.len = OB_KEY_LEN; - if(flow_token_secret.s) { - assert(ob_key.len == SHA_DIGEST_LENGTH); - LM_DBG("flow_token_secret mod param set. use persistent ob_key"); - SHA1((const unsigned char *)flow_token_secret.s, flow_token_secret.len, - (unsigned char *)ob_key.s); - } else { - if(RAND_bytes((unsigned char *)ob_key.s, ob_key.len) == 0) { - LM_ERR("unable to get %d cryptographically strong pseudo-" - "random bytes\n", - ob_key.len); - } - } +#if OPENSSL_VERSION_NUMBER < 0x030000000L + mod_openssl_init(NULL); +#else + // OpenSSL 3.x: run in thread to avoid contaminating rank 0 main thread + pthread_t thread_id; + void *retval; + pthread_create(&thread_id, NULL, mod_openssl_init, NULL); + pthread_join(thread_id, &retval); +#endif if(cfg_declare("outbound", outbound_cfg_def, &default_outbound_cfg, cfg_sizeof(outbound), &outbound_cfg)) { From fad97c6e5d9d541981d5d0df06051e9f03c223b2 Mon Sep 17 00:00:00 2001 From: S-P Chan Date: Wed, 3 Jan 2024 21:28:35 +0800 Subject: [PATCH 3/3] tls: skip OPENSSL_init_ssl --- src/modules/tls/tls_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/tls/tls_init.c b/src/modules/tls/tls_init.c index cc586f7aeff..e7268e3dfcc 100644 --- a/src/modules/tls/tls_init.c +++ b/src/modules/tls/tls_init.c @@ -828,10 +828,10 @@ int tls_h_mod_pre_init_f(void) LM_DBG("preparing tls env for modules initialization\n"); #if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) LM_DBG("preparing tls env for modules initialization (libssl >=1.1)\n"); -#if OPENSSL_VERSION_NUMBER == 0x010101000L +#if OPENSSL_VERSION_NUMBER == 0x010100000L // not needed for OpenSSL 3 OPENSSL_init_ssl(OPENSSL_INIT_ATFORK, NULL); -#else +#elif OPENSSL_VERSION_NUMBER < 0x010100000L OPENSSL_init_ssl(0, NULL); #endif #else