summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2022-02-15 08:37:06 +0200
committerOran Agra <oran@redislabs.com>2022-04-27 16:31:52 +0300
commitec06e933198fd46e4a3a936b25a5c40ab05d20f1 (patch)
tree4722a4dad5d15df557d62f3e04bbcb915468fda1
parentd6a8e64e695babb2f654ec6cbdc7b153716930b0 (diff)
downloadredis-ec06e933198fd46e4a3a936b25a5c40ab05d20f1.tar.gz
Fix OpenSSL 3.0.x related issues. (#10291)
* Drop obsolete initialization calls. * Use decoder API for DH parameters. * Enable auto DH parameters if not explicitly used, which should be the preferred configuration going forward. (cherry picked from commit 3881f7850f9f81720315bd4f33f2f9dedcc242bb)
-rw-r--r--redis.conf4
-rw-r--r--src/tls.c45
2 files changed, 42 insertions, 7 deletions
diff --git a/redis.conf b/redis.conf
index e8eff2774..6ded8842b 100644
--- a/redis.conf
+++ b/redis.conf
@@ -173,7 +173,9 @@ tcp-keepalive 300
#
# tls-client-key-file-pass secret
-# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange:
+# Configure a DH parameters file to enable Diffie-Hellman (DH) key exchange,
+# required by older versions of OpenSSL (<3.0). Newer versions do not require
+# this configuration and recommend against it.
#
# tls-dh-params-file redis.dh
diff --git a/src/tls.c b/src/tls.c
index c36cc98fe..3657ab439 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -39,6 +39,9 @@
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/pem.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/decoder.h>
+#endif
#define REDIS_TLS_PROTO_TLSv1 (1<<0)
#define REDIS_TLS_PROTO_TLSv1_1 (1<<1)
@@ -146,14 +149,13 @@ void tlsInit(void) {
*/
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OPENSSL_config(NULL);
+ SSL_load_error_strings();
+ SSL_library_init();
#elif OPENSSL_VERSION_NUMBER < 0x10101000L
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG|OPENSSL_INIT_ATFORK, NULL);
#endif
- ERR_load_crypto_strings();
- SSL_load_error_strings();
- SSL_library_init();
#ifdef USE_CRYPTO_LOCKS
initCryptoLocks();
@@ -323,20 +325,46 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
if (ctx_config->prefer_server_ciphers)
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
-#if defined(SSL_CTX_set_ecdh_auto)
+#if ((OPENSSL_VERSION_NUMBER < 0x30000000L) && defined(SSL_CTX_set_ecdh_auto))
SSL_CTX_set_ecdh_auto(ctx, 1);
#endif
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
if (ctx_config->dh_params_file) {
FILE *dhfile = fopen(ctx_config->dh_params_file, "r");
- DH *dh = NULL;
if (!dhfile) {
serverLog(LL_WARNING, "Failed to load %s: %s", ctx_config->dh_params_file, strerror(errno));
goto error;
}
- dh = PEM_read_DHparams(dhfile, NULL, NULL, NULL);
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+ EVP_PKEY *pkey = NULL;
+ OSSL_DECODER_CTX *dctx = OSSL_DECODER_CTX_new_for_pkey(
+ &pkey, "PEM", NULL, "DH", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, NULL, NULL);
+ if (!dctx) {
+ serverLog(LL_WARNING, "No decoder for DH params.");
+ fclose(dhfile);
+ goto error;
+ }
+ if (!OSSL_DECODER_from_fp(dctx, dhfile)) {
+ serverLog(LL_WARNING, "%s: failed to read DH params.", ctx_config->dh_params_file);
+ OSSL_DECODER_CTX_free(dctx);
+ fclose(dhfile);
+ goto error;
+ }
+
+ OSSL_DECODER_CTX_free(dctx);
+ fclose(dhfile);
+
+ if (SSL_CTX_set0_tmp_dh_pkey(ctx, pkey) <= 0) {
+ ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
+ serverLog(LL_WARNING, "Failed to load DH params file: %s: %s", ctx_config->dh_params_file, errbuf);
+ EVP_PKEY_free(pkey);
+ goto error;
+ }
+ /* Not freeing pkey, it is owned by OpenSSL now */
+#else
+ DH *dh = PEM_read_DHparams(dhfile, NULL, NULL, NULL);
fclose(dhfile);
if (!dh) {
serverLog(LL_WARNING, "%s: failed to read DH params.", ctx_config->dh_params_file);
@@ -351,6 +379,11 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
}
DH_free(dh);
+#endif
+ } else {
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+ SSL_CTX_set_dh_auto(ctx, 1);
+#endif
}
/* If a client-side certificate is configured, create an explicit client context */