diff options
author | Viktor Dukhovni <openssl-users@dukhovni.org> | 2019-01-01 02:53:24 -0500 |
---|---|---|
committer | Viktor Dukhovni <openssl-users@dukhovni.org> | 2019-01-07 14:02:28 -0500 |
commit | df1f538f28c10f2954757164b17781040d2355ef (patch) | |
tree | 983b999d0b4625fc67a05897c38c37f48aedbeba /crypto | |
parent | b2f16a2271c40faed168c8bd89b562919a18cb3f (diff) |
More configurable crypto and ssl library initialization
1. In addition to overriding the default application name,
one can now also override the configuration file name
and flags passed to CONF_modules_load_file().
2. By default we still keep going when configuration file
processing fails. But, applications that want to be strict
about initialization errors can now make explicit flag
choices via non-null OPENSSL_INIT_SETTINGS that omit the
CONF_MFLAGS_IGNORE_RETURN_CODES flag (which had so far been
both undocumented and unused).
3. In OPENSSL_init_ssl() do not request OPENSSL_INIT_LOAD_CONFIG
if the options already include OPENSSL_INIT_NO_LOAD_CONFIG.
4. Don't set up atexit() handlers when called with INIT_BASE_ONLY.
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7986)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/conf/conf_lib.c | 26 | ||||
-rw-r--r-- | crypto/conf/conf_mod.c | 3 | ||||
-rw-r--r-- | crypto/conf/conf_sap.c | 23 | ||||
-rw-r--r-- | crypto/err/err.c | 12 | ||||
-rw-r--r-- | crypto/init.c | 38 |
5 files changed, 85 insertions, 17 deletions
diff --git a/crypto/conf/conf_lib.c b/crypto/conf/conf_lib.c index 860ac6765b..606563a4fa 100644 --- a/crypto/conf/conf_lib.c +++ b/crypto/conf/conf_lib.c @@ -358,11 +358,36 @@ OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void) if (ret != NULL) memset(ret, 0, sizeof(*ret)); + ret->flags = DEFAULT_CONF_MFLAGS; + return ret; } #ifndef OPENSSL_NO_STDIO +int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, + const char *filename) +{ + char *newfilename = NULL; + + if (filename != NULL) { + newfilename = strdup(filename); + if (newfilename == NULL) + return 0; + } + + free(settings->filename); + settings->filename = newfilename; + + return 1; +} + +void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, + unsigned long flags) +{ + settings->flags = flags; +} + int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, const char *appname) { @@ -383,6 +408,7 @@ int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings) { + free(settings->filename); free(settings->appname); free(settings); } diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index 4ce3951ddc..3ad09a79a1 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -142,6 +142,9 @@ int CONF_modules_load_file(const char *filename, const char *appname, OPENSSL_free(file); NCONF_free(conf); + if (flags & CONF_MFLAGS_IGNORE_RETURN_CODES) + return 1; + return ret; } diff --git a/crypto/conf/conf_sap.c b/crypto/conf/conf_sap.c index c0876cbbc0..38621db3c8 100644 --- a/crypto/conf/conf_sap.c +++ b/crypto/conf/conf_sap.c @@ -39,10 +39,24 @@ void OPENSSL_config(const char *appname) } #endif -void openssl_config_int(const char *appname) +int openssl_config_int(const OPENSSL_INIT_SETTINGS *settings) { + int ret; + const char *filename; + const char *appname; + unsigned long flags; + if (openssl_configured) - return; + return 1; + + filename = settings ? settings->filename : NULL; + appname = settings ? settings->appname : NULL; + flags = settings ? settings->flags : DEFAULT_CONF_MFLAGS; + +#ifdef OPENSSL_INIT_DEBUG + fprintf(stderr, "OPENSSL_INIT: openssl_config_int(%s, %s, %lu)\n", + filename, appname, flags); +#endif OPENSSL_load_builtin_modules(); #ifndef OPENSSL_NO_ENGINE @@ -51,11 +65,10 @@ void openssl_config_int(const char *appname) #endif ERR_clear_error(); #ifndef OPENSSL_SYS_UEFI - CONF_modules_load_file(NULL, appname, - CONF_MFLAGS_DEFAULT_SECTION | - CONF_MFLAGS_IGNORE_MISSING_FILE); + ret = CONF_modules_load_file(filename, appname, flags); #endif openssl_configured = 1; + return ret; } void openssl_no_config_int(void) diff --git a/crypto/err/err.c b/crypto/err/err.c index c80aa6be2b..44e7115f9c 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -741,6 +741,18 @@ int err_shelve_state(void **state) { int saveerrno = get_last_sys_error(); + /* + * Note, at present our only caller is OPENSSL_init_crypto(), indirectly + * via ossl_init_load_crypto_nodelete(), by which point the requested + * "base" initialization has already been performed, so the below call is a + * NOOP, that re-enters OPENSSL_init_crypto() only to quickly return. + * + * If are no other valid callers of this function, the call below can be + * removed, avoiding the re-entry into OPENSSL_init_crypto(). If there are + * potential uses that are not from inside OPENSSL_init_crypto(), then this + * call is needed, but some care is required to make sure that the re-entry + * remains a NOOP. + */ if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL)) return 0; diff --git a/crypto/init.c b/crypto/init.c index 5e6be10fca..22d28a9865 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -311,17 +311,12 @@ DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_macs, ossl_init_add_all_macs) static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT; static int config_inited = 0; -static const char *appname; +static const OPENSSL_INIT_SETTINGS *conf_settings = NULL; DEFINE_RUN_ONCE_STATIC(ossl_init_config) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, - "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n", - appname == NULL ? "NULL" : appname); -#endif - openssl_config_int(appname); + int ret = openssl_config_int(conf_settings); config_inited = 1; - return 1; + return ret; } DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config) { @@ -654,9 +649,29 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; } + /* + * 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. + */ if (!RUN_ONCE(&base, ossl_init_base)) return 0; + if (opts & OPENSSL_INIT_BASE_ONLY) + return 1; + + /* + * 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. + */ if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) { if (!RUN_ONCE_ALT(®ister_atexit, ossl_init_no_register_atexit, ossl_init_register_atexit)) @@ -665,9 +680,7 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; } - if (!(opts & OPENSSL_INIT_BASE_ONLY) - && !RUN_ONCE(&load_crypto_nodelete, - ossl_init_load_crypto_nodelete)) + if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete)) return 0; if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS) @@ -718,8 +731,9 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if (opts & OPENSSL_INIT_LOAD_CONFIG) { int ret; CRYPTO_THREAD_write_lock(init_lock); - appname = (settings == NULL) ? NULL : settings->appname; + conf_settings = settings; ret = RUN_ONCE(&config, ossl_init_config); + conf_settings = NULL; CRYPTO_THREAD_unlock(init_lock); if (!ret) return 0; |