summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2022-02-15 08:37:06 +0200
committerGitHub <noreply@github.com>2022-02-15 08:37:06 +0200
commit3881f7850f9f81720315bd4f33f2f9dedcc242bb (patch)
tree35f3c2fe9dd45bfee1e93879ac5846f6a6c0c82c
parente6478cfd10ae5ce8312c49823142d4dfcf0f45bb (diff)
downloadredis-3881f7850f9f81720315bd4f33f2f9dedcc242bb.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.
-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 55ed8a13e..d9644a776 100644
--- a/redis.conf
+++ b/redis.conf
@@ -213,7 +213,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 2fcf57b8f..c6449b2a7 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 */