From 0aebfb2e9568fdf7fcc2c763180e80e89e330792 Mon Sep 17 00:00:00 2001 From: Anthony Alba Date: Wed, 1 Sep 2021 07:26:08 +0800 Subject: [PATCH] tls: fix OpenSSL engine in child processes tls_init.c calls OPENSSL_init_ssl(); this initializes the global engine linked-list and this cannot be reset in the child. To avoid linked-list corruption we manually instantiate the engine object required for loading private keys instead of relying on CONF_modules_load_file(). Updates to doc/. Addresses #2839 --- src/modules/tls/doc/hsm_howto.xml | 15 ++--- src/modules/tls/tls_mod.c | 93 ++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 34 deletions(-) diff --git a/src/modules/tls/doc/hsm_howto.xml b/src/modules/tls/doc/hsm_howto.xml index 985d86167d3..3c3547aa084 100644 --- a/src/modules/tls/doc/hsm_howto.xml +++ b/src/modules/tls/doc/hsm_howto.xml @@ -22,17 +22,17 @@ -AWS CloudHSM Example +Thales Luna Example -------------------- ... -# Example for AWS CloudHSM (SafeNet Luna) +# Example for Thales Luna modparam("tls", "engine", "gem") -modparam("tls", "engine_config", "/usr/local/etc/kamailio/luna.conf") -modparam("tls", "engine_algorithms", "ALL) +modparam("tls", "engine_config", "/usr/local/etc/kamailio/thales.cnf") +modparam("tls", "engine_algorithms", "EC") ... -/usr/local/etc/kamailio/luna.cnf is a OpenSSL config format file used to +/usr/local/etc/kamailio/thales.cnf is a OpenSSL config format file used to bootstrap the engine, e.g., pass the PIN. ... @@ -43,11 +43,12 @@ kamailio = openssl_init engines = engine_section [ engine_section ] -# gem is the name of the SafeNet Luna OpenSSL engine +# gem is the name of the Thales Luna OpenSSL engine gem = gem_section [ gem_section ] -# from SafeNet documentation +# from Thales documentation +dynamic_path = /usr/lib64/engines-1.1/gem.so ENGINE_INIT = 0:20:21:password=1234-ABCD-5678-EFGH ... diff --git a/src/modules/tls/tls_mod.c b/src/modules/tls/tls_mod.c index 6e421635cb2..8ad3c00f258 100644 --- a/src/modules/tls/tls_mod.c +++ b/src/modules/tls/tls_mod.c @@ -23,7 +23,7 @@ * Module: @ref tls */ - +#include #include #include #include @@ -651,39 +651,78 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2) */ static int tls_engine_init() { - LM_DBG("With OpenSSL engine support\n"); - if (strncmp(tls_engine_settings.engine.s, "NONE", 4)) { - int err = 0; - ENGINE_load_builtin_engines(); - OPENSSL_load_builtin_modules(); - if (strncmp(tls_engine_settings.engine_config.s, "NONE", 4)) { - err = CONF_modules_load_file(tls_engine_settings.engine_config.s, "kamailio", 0); - if (!err) { - LM_ERR("OpenSSL failed to load ENGINE configuration file: %*s\n", tls_engine_settings.engine_config.len, tls_engine_settings.engine_config.s); - goto error; - } - } - ksr_tls_engine = ENGINE_by_id(tls_engine_settings.engine.s); - if (!ksr_tls_engine) { - LM_ERR("OpenSSL failed to obtain ENGINE: %*s\n", tls_engine_settings.engine_config.len, tls_engine_settings.engine_config.s); + char *err, *section, *engines_section, *engine_section; + char *engine_id; + int rc; + long errline; + CONF* config; + STACK_OF(CONF_VALUE) *stack; + CONF_VALUE *confval; + ENGINE *e; + + LM_INFO("With OpenSSL engine support %*s\n", tls_engine_settings.engine_config.len, tls_engine_settings.engine_config.s); + + /* + * #2839: don't use CONF_modules_load_file(): + * We are in the child process and the global engine linked-list + * is initialized in the parent. + */ + e = ENGINE_by_id("dynamic"); + if (!e) { + err = "Error loading dynamic engine"; + goto error; + } + engine_id = tls_engine_settings.engine.s; + + config = NCONF_new(NULL); + rc = NCONF_load(config, tls_engine_settings.engine_config.s, &errline); + if (!rc) { + err = "Error loading OpenSSL configuration file"; + goto error; + } + + section = NCONF_get_string(config, NULL, "kamailio"); + engines_section = NCONF_get_string(config, section, "engines"); + engine_section = NCONF_get_string(config, engines_section, engine_id); + stack = NCONF_get_section(config, engine_section); + + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", NCONF_get_string(config, engine_section, "dynamic_path"), 0)) { + err = "SO_PATH"; + goto error; + } + if (!ENGINE_ctrl_cmd_string(e, "ID", engine_id, 0)) { + err = "ID"; + goto error; + } + if (!ENGINE_ctrl_cmd(e, "LOAD", 1, NULL, NULL, 0)) { + err = "LOAD"; + goto error; + } + while((confval = sk_CONF_VALUE_pop(stack))) { + if (strcmp(confval->name, "dynamic_path") == 0) continue; + LM_DBG("Configuring OpenSSL engine %s: %s(%s)\n", engine_id, confval->name, confval->value); + if (!ENGINE_ctrl_cmd_string(e, confval->name, confval->value, 0)) { + err = confval->name; goto error; } - err = ENGINE_init(ksr_tls_engine); - if (!err) { - LM_ERR("OpenSSL ENGINE_init() failed\n"); + } + + if (!ENGINE_init(e)) { + err = "ENGINE_init()"; + goto error; + } + if (strncmp(tls_engine_settings.engine_algorithms.s, "NONE", 4)) { + rc = ENGINE_set_default_string(e, tls_engine_settings.engine_algorithms.s); + if (!rc) { + err = "OpenSSL ENGINE could not set algorithms"; goto error; } - if (strncmp(tls_engine_settings.engine_algorithms.s, "NONE", 4)) { - err = ENGINE_set_default_string(ksr_tls_engine, tls_engine_settings.engine_algorithms.s); - if (!err) { - LM_ERR("OpenSSL ENGINE could not set algorithms\n"); - goto error; - } - } - LM_INFO("OpenSSL engine %*s initialized\n", tls_engine_settings.engine.len, tls_engine_settings.engine.s); } + ENGINE_free(e); + ksr_tls_engine = e; return 0; error: + LM_ERR("TLS Engine: %s\n", err); return -1; }