From d18ae25f28e72831dc3c51f78e0735342540098b Mon Sep 17 00:00:00 2001 From: beck <> Date: Sat, 17 Mar 2018 16:20:01 +0000 Subject: Bring in compatibility for OpenSSL 1.1 style init functions. This adds OPENSSL_init_crypto and OPENSSL_init_ssl, as well thread safety modifications for the existing LibreSSL init functions. The initialization routines are called automatically by the normal entry points into the library, as in newer OpenSSL ok jsing@, nits by tb@ and deraadt@ --- src/lib/libcrypto/Makefile | 4 +-- src/lib/libcrypto/Symbols.list | 1 + src/lib/libcrypto/bio/b_posix.c | 4 ++- src/lib/libcrypto/comp/c_zlib.c | 4 ++- src/lib/libcrypto/conf/conf_sap.c | 46 ++++++++++++++++++++++++------- src/lib/libcrypto/crypto.h | 36 +++++++++++++++++++++++- src/lib/libcrypto/crypto_init.c | 56 ++++++++++++++++++++++++++++++++++++++ src/lib/libcrypto/engine/eng_all.c | 20 ++++++++++---- src/lib/libcrypto/engine/eng_lib.c | 5 +++- src/lib/libcrypto/err/err.c | 32 ++++++++++++++++++++-- src/lib/libcrypto/err/err_all.c | 18 +++++++++--- src/lib/libcrypto/evp/c_all.c | 23 +++++++++++++--- src/lib/libcrypto/evp/names.c | 20 +++++++++++++- src/lib/libcrypto/ex_data.c | 5 +++- src/lib/libssl/Makefile | 4 +-- src/lib/libssl/Symbols.list | 3 ++ src/lib/libssl/ssl.h | 15 +++++++++- src/lib/libssl/ssl_init.c | 50 ++++++++++++++++++++++++++++++++++ src/lib/libssl/ssl_lib.c | 7 ++++- src/lib/libssl/ssl_sess.c | 7 ++++- 20 files changed, 322 insertions(+), 38 deletions(-) create mode 100644 src/lib/libcrypto/crypto_init.c create mode 100644 src/lib/libssl/ssl_init.c (limited to 'src/lib') diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile index 4817a4c260..8c5e46b169 100644 --- a/src/lib/libcrypto/Makefile +++ b/src/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.26 2018/03/17 15:19:12 tb Exp $ +# $OpenBSD: Makefile,v 1.27 2018/03/17 16:20:01 beck Exp $ LIB= crypto LIBREBUILD=y @@ -37,7 +37,7 @@ SYMBOL_LIST= ${.CURDIR}/Symbols.list # crypto/ SRCS+= cryptlib.c malloc-wrapper.c mem_dbg.c cversion.c ex_data.c cpt_err.c SRCS+= o_time.c o_str.c o_init.c -SRCS+= mem_clr.c +SRCS+= mem_clr.c crypto_init.c # aes/ SRCS+= aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list index 8931abaf52..eb22f62278 100644 --- a/src/lib/libcrypto/Symbols.list +++ b/src/lib/libcrypto/Symbols.list @@ -1898,6 +1898,7 @@ OPENSSL_cpu_caps OPENSSL_cpuid_setup OPENSSL_ia32cap_P OPENSSL_init +OPENSSL_init_crypto OPENSSL_load_builtin_modules OPENSSL_no_config OPENSSL_strcasecmp diff --git a/src/lib/libcrypto/bio/b_posix.c b/src/lib/libcrypto/bio/b_posix.c index a850bc6aea..aed51bd717 100644 --- a/src/lib/libcrypto/bio/b_posix.c +++ b/src/lib/libcrypto/bio/b_posix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: b_posix.c,v 1.1 2014/12/03 22:14:38 bcook Exp $ */ +/* $OpenBSD: b_posix.c,v 1.2 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -68,6 +68,8 @@ int BIO_sock_init(void) { + if (!OPENSSL_init_crypto(0, NULL)) /* XXX do we need this? */ + return (0); return (1); } diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c index 1802cffd99..0cdbb205a4 100644 --- a/src/lib/libcrypto/comp/c_zlib.c +++ b/src/lib/libcrypto/comp/c_zlib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: c_zlib.c,v 1.19 2017/01/29 17:49:22 beck Exp $ */ +/* $OpenBSD: c_zlib.c,v 1.20 2018/03/17 16:20:01 beck Exp $ */ #include #include #include @@ -191,6 +191,8 @@ COMP_zlib(void) if (zlib_stateful_ex_idx == -1) goto err; } + if (!OPENSSL_init_crypto(0, NULL)) + goto err; meth = &zlib_stateful_method; } diff --git a/src/lib/libcrypto/conf/conf_sap.c b/src/lib/libcrypto/conf/conf_sap.c index a29acea7c1..f1844f69f4 100644 --- a/src/lib/libcrypto/conf/conf_sap.c +++ b/src/lib/libcrypto/conf/conf_sap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf_sap.c,v 1.11 2015/02/11 03:19:37 doug Exp $ */ +/* $OpenBSD: conf_sap.c,v 1.12 2018/03/17 16:20:01 beck Exp $ */ /* Written by Stephen Henson (steve@openssl.org) for the OpenSSL * project 2001. */ @@ -56,6 +56,7 @@ * */ +#include #include #include @@ -75,23 +76,24 @@ * unless this is overridden by calling OPENSSL_no_config() */ -static int openssl_configured = 0; +static pthread_once_t openssl_configured = PTHREAD_ONCE_INIT; -void -OPENSSL_config(const char *config_name) -{ - if (openssl_configured) - return; +static const char *openssl_config_name; +void ENGINE_load_builtin_engines_internal(void); + +static void +OPENSSL_config_internal(void) +{ OPENSSL_load_builtin_modules(); #ifndef OPENSSL_NO_ENGINE /* Need to load ENGINEs */ - ENGINE_load_builtin_engines(); + ENGINE_load_builtin_engines_internal(); #endif /* Add others here? */ ERR_clear_error(); - if (CONF_modules_load_file(NULL, config_name, + if (CONF_modules_load_file(NULL, openssl_config_name, CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) { BIO *bio_err; ERR_load_crypto_strings(); @@ -106,8 +108,32 @@ OPENSSL_config(const char *config_name) return; } +void +OPENSSL_config(const char *config_name) +{ + /* Don't override if NULL */ + /* + * Note - multiple threads calling this with *different* config names + * is probably not advisable. One thread will win, but you don't know + * if it will be the same thread as wins the pthread_once. + */ + if (config_name != NULL) + openssl_config_name = config_name; + + (void) OPENSSL_init_crypto(0, NULL); + + (void) pthread_once(&openssl_configured, OPENSSL_config_internal); + + return; +} + +static void +OPENSSL_no_config_internal(void) +{ +} + void OPENSSL_no_config(void) { - openssl_configured = 1; + (void) pthread_once(&openssl_configured, OPENSSL_no_config_internal); } diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h index 90c2875349..0eb29610b4 100644 --- a/src/lib/libcrypto/crypto.h +++ b/src/lib/libcrypto/crypto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.h,v 1.42 2018/02/14 16:32:06 jsing Exp $ */ +/* $OpenBSD: crypto.h,v 1.43 2018/03/17 16:20:01 beck Exp $ */ /* ==================================================================== * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * @@ -542,6 +542,40 @@ void ERR_load_CRYPTO_strings(void); #define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 #define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 +/* + * OpenSSL compatible OPENSSL_INIT options. + */ + +#define OPENSSL_INIT_NO_LOAD_CONFIG 0x00000001L + +/* LibreSSL specific */ +#define _OPENSSL_INIT_FLAG_NOOP 0x80000000L + +/* + * These are provided for compatibiliy, but have no effect + * on how LibreSSL is initialized. + */ +#define OPENSSL_INIT__LOAD_CONFIG _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ADD_ALL_CIPHERS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ADD_ALL_DIGESTS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_NO_ADD_ALL_CIPHERS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_NO_ADD_ALL_DIGESTS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ASYNC _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_RDRAND _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_DYNAMIC _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_OPENSSL _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_CRYPTODEV _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_CAPI _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_PADLOCK _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_AFALG _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_reserved_internal _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ATFORK _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_ENGINE_ALL_BUILTIN _OPENSSL_INIT_FLAG_NOOP + +int OPENSSL_init_crypto(uint64_t opts, const void *settings); + #ifdef __cplusplus } #endif diff --git a/src/lib/libcrypto/crypto_init.c b/src/lib/libcrypto/crypto_init.c new file mode 100644 index 0000000000..f3d1a2bce9 --- /dev/null +++ b/src/lib/libcrypto/crypto_init.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OpenSSL style init */ + +#include +#include + +#include +#include +#include +#include +#include "cryptlib.h" + +static pthread_t crypto_init_thread; + +static void +OPENSSL_init_crypto_internal(void) +{ + crypto_init_thread = pthread_self(); + OPENSSL_cpuid_setup(); + ERR_load_crypto_strings(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + OPENSSL_config(NULL); +} + +int +OPENSSL_init_crypto(uint64_t opts, const void *settings) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + if (pthread_equal(pthread_self(), crypto_init_thread)) + return 1; /* don't recurse */ + + if (opts & OPENSSL_INIT_NO_LOAD_CONFIG) + OPENSSL_no_config(); + + if (pthread_once(&once, OPENSSL_init_crypto_internal) != 0) + return 0; + + return 1; +} diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c index 7640cf7fcd..403ca6865d 100644 --- a/src/lib/libcrypto/engine/eng_all.c +++ b/src/lib/libcrypto/engine/eng_all.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eng_all.c,v 1.29 2015/07/19 22:34:27 doug Exp $ */ +/* $OpenBSD: eng_all.c,v 1.30 2018/03/17 16:20:01 beck Exp $ */ /* Written by Richard Levitte for the OpenSSL * project 2000. */ @@ -56,17 +56,16 @@ * */ +#include + #include #include "cryptlib.h" #include "eng_int.h" void -ENGINE_load_builtin_engines(void) +ENGINE_load_builtin_engines_internal(void) { - /* Some ENGINEs need this */ - OPENSSL_cpuid_setup(); - #ifndef OPENSSL_NO_STATIC_ENGINE #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW_PADLOCK @@ -76,3 +75,14 @@ ENGINE_load_builtin_engines(void) #endif ENGINE_register_all_complete(); } + +void +ENGINE_load_builtin_engines(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + (void) pthread_once(&once, ENGINE_load_builtin_engines_internal); +} diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c index d2da29fe69..11ad771109 100644 --- a/src/lib/libcrypto/engine/eng_lib.c +++ b/src/lib/libcrypto/engine/eng_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eng_lib.c,v 1.12 2017/01/29 17:49:23 beck Exp $ */ +/* $OpenBSD: eng_lib.c,v 1.13 2018/03/17 16:20:01 beck Exp $ */ /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL * project 2000. */ @@ -70,6 +70,9 @@ ENGINE_new(void) { ENGINE *ret; + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + ret = malloc(sizeof(ENGINE)); if (ret == NULL) { ENGINEerror(ERR_R_MALLOC_FAILURE); diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c index ffe25bf465..320078da66 100644 --- a/src/lib/libcrypto/err/err.c +++ b/src/lib/libcrypto/err/err.c @@ -1,4 +1,4 @@ -/* $OpenBSD: err.c,v 1.45 2017/02/20 23:21:19 beck Exp $ */ +/* $OpenBSD: err.c,v 1.46 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -109,6 +109,7 @@ * */ +#include #include #include #include @@ -282,6 +283,8 @@ static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; static int int_thread_hash_references = 0; static int int_err_library_number = ERR_LIB_USER; +static pthread_t err_init_thread; + /* Internal function that checks whether "err_fns" is set and if not, sets it to * the defaults. */ static void @@ -650,8 +653,9 @@ ERR_STATE_free(ERR_STATE *s) } void -ERR_load_ERR_strings(void) +ERR_load_ERR_strings_internal(void) { + err_init_thread = pthread_self(); err_fns_check(); #ifndef OPENSSL_NO_ERR err_load_strings(0, ERR_str_libraries); @@ -662,6 +666,21 @@ ERR_load_ERR_strings(void) #endif } + +void +ERR_load_ERR_strings(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + if (pthread_equal(pthread_self(), err_init_thread)) + return; /* don't recurse */ + + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + + (void) pthread_once(&once, ERR_load_ERR_strings_internal); +} + static void err_load_strings(int lib, ERR_STRING_DATA *str) { @@ -683,6 +702,9 @@ ERR_load_strings(int lib, ERR_STRING_DATA *str) void ERR_unload_strings(int lib, ERR_STRING_DATA *str) { + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + while (str->error) { if (lib) str->error |= ERR_PACK(lib, 0, 0); @@ -694,6 +716,9 @@ ERR_unload_strings(int lib, ERR_STRING_DATA *str) void ERR_free_strings(void) { + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + err_fns_check(); ERRFN(err_del)(); } @@ -953,6 +978,9 @@ ERR_lib_error_string(unsigned long e) ERR_STRING_DATA d, *p; unsigned long l; + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + err_fns_check(); l = ERR_GET_LIB(e); d.error = ERR_PACK(l, 0, 0); diff --git a/src/lib/libcrypto/err/err_all.c b/src/lib/libcrypto/err/err_all.c index 40009cbe88..24de3c9c15 100644 --- a/src/lib/libcrypto/err/err_all.c +++ b/src/lib/libcrypto/err/err_all.c @@ -1,4 +1,4 @@ -/* $OpenBSD: err_all.c,v 1.23 2016/10/19 16:49:11 jsing Exp $ */ +/* $OpenBSD: err_all.c,v 1.24 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -56,6 +56,7 @@ * [including the GNU Public Licence.] */ +#include #include #include @@ -103,11 +104,13 @@ #include #endif -void -ERR_load_crypto_strings(void) +void ERR_load_ERR_strings_internal(void); + +static void +ERR_load_crypto_strings_internal(void) { #ifndef OPENSSL_NO_ERR - ERR_load_ERR_strings(); /* include error strings for SYSerr */ + ERR_load_ERR_strings_internal(); /* include error strings for SYSerr */ ERR_load_BN_strings(); #ifndef OPENSSL_NO_RSA ERR_load_RSA_strings(); @@ -153,3 +156,10 @@ ERR_load_crypto_strings(void) #endif #endif } + +void +ERR_load_crypto_strings(void) +{ + static pthread_once_t loaded = PTHREAD_ONCE_INIT; + (void) pthread_once(&loaded, ERR_load_crypto_strings_internal); +} diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c index 8ab93fece8..87657eded3 100644 --- a/src/lib/libcrypto/evp/c_all.c +++ b/src/lib/libcrypto/evp/c_all.c @@ -1,4 +1,4 @@ -/* $OpenBSD: c_all.c,v 1.21 2017/03/01 13:53:58 jsing Exp $ */ +/* $OpenBSD: c_all.c,v 1.22 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -57,6 +57,7 @@ */ #include +#include #include @@ -66,8 +67,8 @@ #include "cryptlib.h" -void -OpenSSL_add_all_ciphers(void) +static void +OpenSSL_add_all_ciphers_internal(void) { #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cfb()); @@ -226,7 +227,14 @@ OpenSSL_add_all_ciphers(void) } void -OpenSSL_add_all_digests(void) +OpenSSL_add_all_ciphers(void) +{ + static pthread_once_t add_all_ciphers_once = PTHREAD_ONCE_INIT; + (void) pthread_once(&add_all_ciphers_once, OpenSSL_add_all_ciphers_internal); +} + +static void +OpenSSL_add_all_digests_internal(void) { #ifndef OPENSSL_NO_MD4 EVP_add_digest(EVP_md4()); @@ -283,6 +291,13 @@ OpenSSL_add_all_digests(void) #endif } +void +OpenSSL_add_all_digests(void) +{ + static pthread_once_t add_all_digests_once = PTHREAD_ONCE_INIT; + (void) pthread_once(&add_all_digests_once, OpenSSL_add_all_digests_internal); +} + void OPENSSL_add_all_algorithms_noconf(void) { diff --git a/src/lib/libcrypto/evp/names.c b/src/lib/libcrypto/evp/names.c index ebaa3a2f6f..dfcf9ee225 100644 --- a/src/lib/libcrypto/evp/names.c +++ b/src/lib/libcrypto/evp/names.c @@ -1,4 +1,4 @@ -/* $OpenBSD: names.c,v 1.13 2017/04/29 21:48:44 jsing Exp $ */ +/* $OpenBSD: names.c,v 1.14 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -113,6 +113,9 @@ EVP_get_cipherbyname(const char *name) { const EVP_CIPHER *cp; + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); return (cp); } @@ -122,6 +125,9 @@ EVP_get_digestbyname(const char *name) { const EVP_MD *cp; + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; + cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); return (cp); } @@ -167,6 +173,9 @@ EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, const char *from, { struct doall_cipher dc; + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + dc.fn = fn; dc.arg = arg; OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); @@ -178,6 +187,9 @@ EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, const char *from, { struct doall_cipher dc; + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + dc.fn = fn; dc.arg = arg; OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, @@ -207,6 +219,9 @@ EVP_MD_do_all(void (*fn)(const EVP_MD *md, const char *from, const char *to, { struct doall_md dc; + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + dc.fn = fn; dc.arg = arg; OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); @@ -218,6 +233,9 @@ EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md, { struct doall_md dc; + /* Prayer and clean living lets you ignore errors, OpenSSL style */ + (void) OPENSSL_init_crypto(0, NULL); + dc.fn = fn; dc.arg = arg; OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); diff --git a/src/lib/libcrypto/ex_data.c b/src/lib/libcrypto/ex_data.c index 63885af3af..b1e3913662 100644 --- a/src/lib/libcrypto/ex_data.c +++ b/src/lib/libcrypto/ex_data.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ex_data.c,v 1.19 2017/01/29 17:49:22 beck Exp $ */ +/* $OpenBSD: ex_data.c,v 1.20 2018/03/17 16:20:01 beck Exp $ */ /* * Overhaul notes; @@ -312,6 +312,8 @@ def_get_class(int class_index) EX_CLASS_ITEM d, *p, *gen; EX_DATA_CHECK(return NULL;) d.class_index = class_index; + if (!OPENSSL_init_crypto(0, NULL)) + return NULL; CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); if (!p) { @@ -500,6 +502,7 @@ int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) EX_CLASS_ITEM *item; void *ptr; CRYPTO_EX_DATA_FUNCS **storage = NULL; + if ((item = def_get_class(class_index)) == NULL) return; CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index 66dae58874..6a397a7df7 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.38 2017/08/13 19:42:33 doug Exp $ +# $OpenBSD: Makefile,v 1.39 2018/03/17 16:20:01 beck Exp $ .include .ifndef NOMAN @@ -33,7 +33,7 @@ SRCS= \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ ssl_asn1.c ssl_txt.c ssl_algs.c \ bio_ssl.c ssl_err.c \ - ssl_packet.c ssl_tlsext.c ssl_versions.c pqueue.c + ssl_packet.c ssl_tlsext.c ssl_versions.c pqueue.c ssl_init.c SRCS+= s3_cbc.c SRCS+= bs_ber.c bs_cbb.c bs_cbs.c diff --git a/src/lib/libssl/Symbols.list b/src/lib/libssl/Symbols.list index 581b292a74..3b513d5c28 100644 --- a/src/lib/libssl/Symbols.list +++ b/src/lib/libssl/Symbols.list @@ -298,3 +298,6 @@ SSL_version SSL_version_str SSL_want SSL_write + +/* OpenSSL compatible init */ +OPENSSL_init_ssl diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index 05939f214d..97d1c40a66 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.h,v 1.152 2018/03/17 15:55:52 tb Exp $ */ +/* $OpenBSD: ssl.h,v 1.153 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -2112,6 +2112,19 @@ void ERR_load_SSL_strings(void); #define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 #define SSL_R_PEER_BEHAVING_BADLY 666 +/* + * OpenSSL compatible OPENSSL_INIT options + */ + +/* + * These are provided for compatibiliy, but have no effect + * on how LibreSSL is initialized. + */ +#define OPENSSL_INIT_LOAD_SSL_STRINGS _OPENSSL_INIT_FLAG_NOOP +#define OPENSSL_INIT_SSL_DEFAULT _OPENSSL_INIT_FLAG_NOOP + +int OPENSSL_init_ssl(uint64_t opts, const void *settings); + #ifdef __cplusplus } #endif diff --git a/src/lib/libssl/ssl_init.c b/src/lib/libssl/ssl_init.c new file mode 100644 index 0000000000..0ef80956ed --- /dev/null +++ b/src/lib/libssl/ssl_init.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018 Bob Beck + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OpenSSL style init */ + +#include +#include + +#include + +#include "ssl_locl.h" + +static pthread_t ssl_init_thread; + +static void +OPENSSL_init_ssl_internal(void) +{ + ssl_init_thread = pthread_self(); + SSL_load_error_strings(); + SSL_library_init(); +} + +int +OPENSSL_init_ssl(uint64_t opts, const void *settings) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + + if (pthread_equal(pthread_self(), ssl_init_thread)) + return 1; /* don't recurse */ + + OPENSSL_init_crypto(opts, settings); + + if (pthread_once(&once, OPENSSL_init_ssl_internal) != 0) + return 0; + + return 1; +} diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index eca3c97fac..573e63c934 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_lib.c,v 1.181 2018/03/17 15:48:31 tb Exp $ */ +/* $OpenBSD: ssl_lib.c,v 1.182 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1791,6 +1791,11 @@ SSL_CTX_new(const SSL_METHOD *meth) { SSL_CTX *ret; + if (!OPENSSL_init_ssl(0, NULL)) { + SSLerrorx(SSL_R_LIBRARY_BUG); + return (NULL); + } + if (meth == NULL) { SSLerrorx(SSL_R_NULL_SSL_METHOD_PASSED); return (NULL); diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c index 4903719fb3..51aa2eac04 100644 --- a/src/lib/libssl/ssl_sess.c +++ b/src/lib/libssl/ssl_sess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_sess.c,v 1.77 2018/03/17 15:55:53 tb Exp $ */ +/* $OpenBSD: ssl_sess.c,v 1.78 2018/03/17 16:20:01 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -199,6 +199,11 @@ SSL_SESSION_new(void) { SSL_SESSION *ss; + if (!OPENSSL_init_ssl(0, NULL)) { + SSLerrorx(SSL_R_LIBRARY_BUG); + return(NULL); + } + if ((ss = calloc(1, sizeof(*ss))) == NULL) { SSLerrorx(ERR_R_MALLOC_FAILURE); return (NULL); -- cgit v1.2.3-55-g6feb