From 41690a4bce61fb970baff714699548b196541a7f Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Sat, 11 Jul 2020 17:03:01 +0200 Subject: [PATCH] Split TLS cipher settings for <= 1.2 and 1.3. The TLS 1.3 ciphersuites are entirely different and need to be treated on their own. Introduce FETCHMAIL_TLS13_CIPHERSUITES for that. --- NEWS | 12 ++++++++++-- socket.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index c9405e37..2877fa6c 100644 --- a/NEWS +++ b/NEWS @@ -126,10 +126,18 @@ fetchmail-6.5.0 (not yet released): incompabilities with servers because server-side data sizes are often too low. Valid range: 0 to 5 for OpenSSL 1.1.1 and 3.0.0-alpha4. * fetchmail supports a FETCHMAIL_SSL_CIPHERS environment variable that - sets the cipher string (through two different OpenSSL functions) for all TLS - versions. If setting the ciphers fails, fetchmail will not connect. + sets the cipher string (through two different OpenSSL functions) for SSL and + TLS versions up to TLSv1.2. + If setting the ciphers fails, fetchmail will not connect. If not given, defaults to Postfix's "medium" list, "aNULL:-aNULL:HIGH:MEDIUM:+RC4:@STRENGTH". +* fetchmail supports a FETCHMAIL_TLS13_CIPHERSUITES environment variable + that sets the ciphersuites (a colon-separated list, without + ! -) for + TLSv1.3. If not given, defaults to OpenSSL's built-in list. If setting the + ciphersuites fails, fetchmail refuses to connect. +* NOTE the features above are simplistic. For instance, even though you + configure --sslproto tls1.3, a failure to set tls1.2 ciphers could cause + a connection abort. # KNOWN BUGS AND WORKAROUNDS (This section floats upwards through the NEWS file so it stays with the diff --git a/socket.c b/socket.c index 8d09c672..2531e0e6 100644 --- a/socket.c +++ b/socket.c @@ -973,31 +973,47 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck return(-1); } - { + { // CIPHER LISTS for SSL and TLS <= 1.2 const char *envn_ciphers = "FETCHMAIL_SSL_CIPHERS"; const char *ciphers = getenv(envn_ciphers); if (!ciphers) { // Postfix nonprod 20200710, DEF_TLS_MEDIUM_CLIST from src/global/mail_params.h const char *default_ciphers = "aNULL:-aNULL:HIGH:MEDIUM:+RC4:@STRENGTH"; if (outlevel >= O_DEBUG) { - report(stdout, GT_("SSL/TLS: environment variable %s unset, using fetchmail built-in ciphers.\n"), envn_ciphers); + report(stdout, GT_("SSL/TLS <= 1.2: environment variable %s unset, using fetchmail built-in ciphers.\n"), envn_ciphers); } ciphers = default_ciphers; envn_ciphers = GT_("built-in defaults"); } - int r; - r = SSL_CTX_set_cipher_list( _ctx[sock], ciphers); // <= TLS1.2 - r |= SSL_CTX_set_ciphersuites(_ctx[sock], ciphers); // >= TLS1.3 - if (r != 0) { + int r = SSL_CTX_set_cipher_list( _ctx[sock], ciphers); // <= TLS1.2 + if (1 == r) { if (outlevel >= O_DEBUG) { - report(stdout, GT_("SSL/TLS: ciphers set from %s to \"%s\"\n"), envn_ciphers, ciphers); + report(stdout, GT_("SSL/TLS <= 1.2: ciphers set from %s to \"%s\"\n"), envn_ciphers, ciphers); } } else { - report(stderr, GT_("SSL/TLS: failed to set ciphers from %s to \"%s\"\n"), envn_ciphers, ciphers); + report(stderr, GT_("SSL/TLS: <= 1.2 failed to set ciphers from %s to \"%s\"\n"), envn_ciphers, ciphers); goto sslopen_bailout; } } + { // CIPHERSUITES for TLS >= 1.3 + const char *envn_ciphers = "FETCHMAIL_TLS13_CIPHERSUITES"; + const char *ciphers = getenv(envn_ciphers); + int r = 0; + if (ciphers) { + r = SSL_CTX_set_ciphersuites(_ctx[sock], ciphers); // >= TLS1.3 + if (1 == r) { + if (outlevel >= O_DEBUG) { + report(stdout, GT_("TLS >= 1.3: ciphersuite set from %s to \"%s\"\n"), envn_ciphers, ciphers); + } + } else { + report(stderr, GT_("TLS >= 1.3: failed to set ciphersuite from %s to \"%s\"\n"), envn_ciphers, ciphers); + goto sslopen_bailout; + } + } else if (outlevel >= O_DEBUG) { + report(stdout, GT_("TLS >= 1.3: environment variable %s unset, using OpenSSL built-in ciphersuites.\n"), envn_ciphers); + } + } { char *tmp = getenv("FETCHMAIL_DISABLE_CBC_IV_COUNTERMEASURE"); if (tmp == NULL || *tmp == '\0' || strspn(tmp, " \t") == strlen(tmp)) -- 2.43.2