From 6db92eab5917e515c83fd773dad6111177a0207f Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 6 Nov 2021 20:56:05 +0000 Subject: [PATCH] Revert "GnuTLS: lose DH-param setup, for recent library versions where no longer needed". Bug 2822 It seems the documentation lies and the params really are needed. This reverts commits 041bf37266, 49132a3bb5c6 --- doc/doc-docbook/spec.xfpt | 7 +------ src/src/tls-gnu.c | 34 ++++++++++++++-------------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index dcda2ff79..a8cd63b19 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -18429,12 +18429,7 @@ larger prime than requested. The value of this option is expanded and indicates the source of DH parameters to be used by Exim. -This option is ignored for GnuTLS version 3.6.0 and later. -The library manages parameter negotiation internally. - -&*Note: The Exim Maintainers strongly recommend, -for other TLS library versions, -using a filename with site-generated +&*Note: The Exim Maintainers strongly recommend using a filename with site-generated local DH parameters*&, which has been supported across all versions of Exim. The other specific constants available are a fallback so that even when "unconfigured", Exim can offer Perfect Forward Secrecy in older ciphersuites in TLS. diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index aea1bd8b2..7b67bb793 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -89,9 +89,6 @@ require current GnuTLS, then we'll drop support for the ancient libraries). #if GNUTLS_VERSION_NUMBER >= 0x030506 && !defined(DISABLE_OCSP) # define SUPPORT_SRV_OCSP_STACK #endif -#if GNUTLS_VERSION_NUMBER >= 0x030600 -# define GNUTLS_AUTO_DHPARAMS -#endif #if GNUTLS_VERSION_NUMBER >= 0x030603 # define EXIM_HAVE_TLS1_3 # define SUPPORT_GNUTLS_EXT_RAW_PARSE @@ -265,13 +262,11 @@ static exim_gnutls_state_st state_server = { .fd_out = -1, }; -#ifndef GNUTLS_AUTO_DHPARAMS /* dh_params are initialised once within the lifetime of a process using TLS; if we used TLS in a long-lived daemon, we'd have to reconsider this. But we don't want to repeat this. */ static gnutls_dh_params_t dh_server_params = NULL; -#endif static int ssl_session_timeout = 7200; /* Two hours */ @@ -688,7 +683,6 @@ if (!state->host) -#ifndef GNUTLS_AUTO_DHPARAMS /************************************************* * Setup up DH parameters * *************************************************/ @@ -711,7 +705,7 @@ init_server_dh(uschar ** errstr) { int fd, rc; unsigned int dh_bits; -gnutls_datum_t m = {.data = NULL, .size = 0}; +gnutls_datum_t m; uschar filename_buf[PATH_MAX]; uschar *filename = NULL; size_t sz; @@ -724,6 +718,9 @@ DEBUG(D_tls) debug_printf("Initialising GnuTLS server params\n"); if ((rc = gnutls_dh_params_init(&dh_server_params))) return tls_error_gnu(NULL, US"gnutls_dh_params_init", rc, errstr); +m.data = NULL; +m.size = 0; + if (!expand_check(tls_dhparam, US"tls_dhparam", &exp_tls_dhparam, errstr)) return DEFER; @@ -873,12 +870,14 @@ if (rc < 0) return tls_error_sys(US"Unable to open temp file", errno, NULL, errstr); (void)exim_chown(temp_fn, exim_uid, exim_gid); /* Probably not necessary */ - /* GnuTLS overshoots! If we ask for 2236, we might get 2237 or more. But - there's no way to ask GnuTLS how many bits there really are. We can ask - how many bits were used in a TLS session, but that's it! The prime itself - is hidden behind too much abstraction. So we ask for less, and proceed on - a wing and a prayer. First attempt, subtracted 3 for 2233 and got 2240. */ - + /* GnuTLS overshoots! + * If we ask for 2236, we might get 2237 or more. + * But there's no way to ask GnuTLS how many bits there really are. + * We can ask how many bits were used in a TLS session, but that's it! + * The prime itself is hidden behind too much abstraction. + * So we ask for less, and proceed on a wing and a prayer. + * First attempt, subtracted 3 for 2233 and got 2240. + */ if (dh_bits >= EXIM_CLIENT_DH_MIN_BITS + 10) { dh_bits_gen = dh_bits - 10; @@ -941,7 +940,6 @@ if (rc < 0) DEBUG(D_tls) debug_printf("initialized server D-H parameters\n"); return OK; } -#endif @@ -1952,7 +1950,6 @@ tls_set_remaining_x509(exim_gnutls_state_st *state, uschar ** errstr) int rc; const host_item *host = state->host; /* macro should be reconsidered? */ -#ifndef GNUTLS_AUTO_DHPARAMS /* Create D-H parameters, or read them from the cache file. This function does its own SMTP error messaging. This only happens for the server, TLS D-H ignores client-side params. */ @@ -1962,13 +1959,10 @@ if (!state->host) if (!dh_server_params) if ((rc = init_server_dh(errstr)) != OK) return rc; - /* Unnecessary & discouraged with 3.6.0 or later */ + /* Unnecessary & discouraged with 3.6.0 or later, according to docs. But without it, + no DHE- ciphers are advertised. */ gnutls_certificate_set_dh_params(state->lib_state.x509_cred, dh_server_params); } -#else -DEBUG(D_tls) if (tls_dhparam) - debug_printf("Ignoring tls_dhparam (recent version GnuTLS)\n"); -#endif /* Link the credentials to the session. */ -- 2.30.2