From a0d7b97f58006f650bcbd888997e10488d6a3eed Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Sat, 17 Mar 2018 18:54:44 +0100 Subject: [PATCH] add compatibility for openssl < 1.1 (solves RADSECPROXY-74) --- ChangeLog | 3 ++- radsecproxy.c | 9 +++++---- tlscommon.c | 38 ++++++++++++++++++++++++++++++++++++++ tlscommon.h | 1 + 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8342b1b..0e8fd2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,7 +5,8 @@ Changes between 1.6.9 and the master branch - 3-clause BSD license only, no GPL. Enhancements: - - Support the use of OpenSSL version 1.1 series (RADSECPROXY-66). + - Support the use of OpenSSL version 1.1 and 1.0 series + (RADSECPROXY-66, RADSECPROXY-74). - Reload TLS certificate CRLs on SIGHUP (RADSECPROXY-78). - Make use of SO_KEEPALIVE for tcp sockets (RADSECPROXY-12). diff --git a/radsecproxy.c b/radsecproxy.c index d9d0888..71e379c 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -1971,13 +1971,10 @@ void createlisteners(uint8_t type) { createlistener(type, NULL); } -void sslinit() { +void randinit() { time_t t; pid_t pid; - SSL_load_error_strings(); - SSL_library_init(); - while (!RAND_status()) { t = time(NULL); pid = getpid(); @@ -3306,7 +3303,11 @@ int radsecproxy_main(int argc, char **argv) { protodefs[i] = protoinits[i](i); /* needed even if no TLS/DTLS transport */ + randinit(); + +#if defined(RADPROT_TLS) || defined(RADPROT_DTLS) sslinit(); +#endif getargs(argc, argv, &foreground, &pretend, &loglevel, &configfile, &pidfile); if (loglevel) diff --git a/tlscommon.c b/tlscommon.c index d5b5325..7ffef3f 100644 --- a/tlscommon.c +++ b/tlscommon.c @@ -34,6 +34,44 @@ static struct hash *tlsconfs = NULL; +/* callbacks for making OpenSSL < 1.1 thread safe */ +#if OPENSSL_VERSION_NUMBER < 0x10100000 +static pthread_mutex_t *ssl_locks = NULL; + +unsigned long ssl_thread_id() { + return (unsigned long)pthread_self(); +} + +void ssl_locking_callback(int mode, int type, const char *file, int line) { + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&ssl_locks[type]); + else + pthread_mutex_unlock(&ssl_locks[type]); +} +#endif + +void sslinit() { +#if OPENSSL_VERSION_NUMBER < 0x10100000 + int i; + + SSL_library_init(); + + ssl_locks = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + if (!ssl_locks) + debugx(1, DBG_ERR, "malloc failed"); + + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_init(&ssl_locks[i], NULL); + } + CRYPTO_set_id_callback(ssl_thread_id); + CRYPTO_set_locking_callback(ssl_locking_callback); +#else + OPENSSL_init_ssl(0, NULL); +#endif + + SSL_load_error_strings(); +} + static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) { int pwdlen = strlen(userdata); if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */ diff --git a/tlscommon.h b/tlscommon.h index 317d1e4..b273148 100644 --- a/tlscommon.h +++ b/tlscommon.h @@ -28,6 +28,7 @@ struct tls { }; #if defined(RADPROT_TLS) || defined(RADPROT_DTLS) +void sslinit(); struct tls *tlsgettls(char *alt1, char *alt2); SSL_CTX *tlsgetctx(uint8_t type, struct tls *t); X509 *verifytlscert(SSL *ssl);