From: Kevin McCarthy Date: Sun, 3 May 2015 23:25:45 +0000 (-0700) Subject: Provide SSL cipher selection option. (closes #3167) X-Git-Tag: mutt-1-5-24-rel~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=00ef859faf7e3b706d0b53fb061db725569a3932;p=mutt Provide SSL cipher selection option. (closes #3167) Creates a $ssl_ciphers option that allows direct selection of the ciphers for OpenSSL (via SSL_CTX_set_cipher_list) and GnuTLS (via gnutls_priority_set_direct). Thank you Sergio Gelato for the patch. --- diff --git a/globals.h b/globals.h index c43cef7f..e77030c7 100644 --- a/globals.h +++ b/globals.h @@ -131,6 +131,7 @@ WHERE char *SpamSep; WHERE char *SslCertFile INITVAL (NULL); WHERE char *SslClientCert INITVAL (NULL); WHERE char *SslEntropyFile INITVAL (NULL); +WHERE char *SslCiphers INITVAL (NULL); #ifdef USE_SSL_GNUTLS WHERE short SslDHPrimeBits; WHERE char *SslCACertFile INITVAL (NULL); diff --git a/init.h b/init.h index 9a683b71..9ae1383c 100644 --- a/init.h +++ b/init.h @@ -3092,6 +3092,17 @@ struct option_t MuttVars[] = { ** URL. You should only unset this for particular known hosts, using ** the \fC$\fP function. */ + { "ssl_ciphers", DT_STR, R_NONE, UL &SslCiphers, UL 0 }, + /* + ** .pp + ** Contains a colon-seperated list of ciphers to use when using SSL. + ** For OpenSSL, see ciphers(1) for the syntax of the string. + ** .pp + ** For GnuTLS, this option will be used in place of "NORMAL" at the + ** start of the priority string. See gnutls_priority_init(3) for the + ** syntax and more details. (Note: GnuTLS version 2.1.7 or higher is + ** required.) + */ #endif /* defined(USE_SSL) */ { "status_chars", DT_STR, R_BOTH, UL &StChars, UL "-*%A" }, /* diff --git a/mutt_ssl.c b/mutt_ssl.c index ca6f4291..0dd0b258 100644 --- a/mutt_ssl.c +++ b/mutt_ssl.c @@ -140,6 +140,13 @@ int mutt_ssl_starttls (CONNECTION* conn) ssl_get_client_cert(ssldata, conn); + if (SslCiphers) { + if (!SSL_CTX_set_cipher_list (ssldata->ctx, SslCiphers)) { + dprint (1, (debugfile, "mutt_ssl_starttls: Could not select prefered ciphers\n")); + goto bail_ctx; + } + } + if (! (ssldata->ssl = SSL_new (ssldata->ctx))) { dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL\n")); @@ -360,6 +367,10 @@ static int ssl_socket_open (CONNECTION * conn) ssl_get_client_cert(data, conn); + if (SslCiphers) { + SSL_CTX_set_cipher_list (data->ctx, SslCiphers); + } + data->ssl = SSL_new (data->ctx); SSL_set_fd (data->ssl, conn->fd); diff --git a/mutt_ssl_gnutls.c b/mutt_ssl_gnutls.c index bdfcbea8..8582bec8 100644 --- a/mutt_ssl_gnutls.c +++ b/mutt_ssl_gnutls.c @@ -273,36 +273,44 @@ err_crt: static int tls_set_priority(tlssockdata *data) { size_t nproto = 4; - char priority[SHORT_STRING]; + char *priority; + size_t priority_size; int err; + priority_size = SHORT_STRING + mutt_strlen (SslCiphers); + priority = safe_malloc (priority_size); + priority[0] = 0; - safe_strcat (priority, sizeof (priority), "NORMAL"); + if (SslCiphers) + safe_strcat (priority, priority_size, SslCiphers); + else + safe_strcat (priority, priority_size, "NORMAL"); if (! option(OPTTLSV1_2)) { nproto--; - safe_strcat (priority, sizeof (priority), ":-VERS-TLS1.2"); + safe_strcat (priority, priority_size, ":-VERS-TLS1.2"); } if (! option(OPTTLSV1_1)) { nproto--; - safe_strcat (priority, sizeof (priority), ":-VERS-TLS1.1"); + safe_strcat (priority, priority_size, ":-VERS-TLS1.1"); } if (! option(OPTTLSV1)) { nproto--; - safe_strcat (priority, sizeof (priority), ":-VERS-TLS1.0"); + safe_strcat (priority, priority_size, ":-VERS-TLS1.0"); } if (! option(OPTSSLV3)) { nproto--; - safe_strcat (priority, sizeof (priority), ":-VERS-SSL3.0"); + safe_strcat (priority, priority_size, ":-VERS-SSL3.0"); } if (nproto == 0) { mutt_error (_("All available protocols for TLS/SSL connection disabled")); + FREE (&priority); return -1; } @@ -310,9 +318,11 @@ static int tls_set_priority(tlssockdata *data) { mutt_error ("gnutls_priority_set_direct(%s): %s", priority, gnutls_strerror(err)); mutt_sleep (2); + FREE (&priority); return -1; } + FREE (&priority); return 0; } #else @@ -342,6 +352,12 @@ static int tls_set_priority(tlssockdata *data) return -1; } + if (SslCiphers) + { + mutt_error (_("Explicit ciphersuite selection via $ssl_ciphers not supported")); + mutt_sleep (2); + } + /* We use default priorities (see gnutls documentation), except for protocol version */ gnutls_set_default_priority (data->state);