]> granicus.if.org Git - mutt/commitdiff
Provide SSL cipher selection option. (closes #3167)
authorKevin McCarthy <kevin@8t8.us>
Sun, 3 May 2015 23:25:45 +0000 (16:25 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sun, 3 May 2015 23:25:45 +0000 (16:25 -0700)
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.

globals.h
init.h
mutt_ssl.c
mutt_ssl_gnutls.c

index c43cef7fd07f5e6864461734a834c070b0c46f44..e77030c71e252d8256d4e0a1d467cf7ae8a48a46 100644 (file)
--- 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 9a683b7110d9ffe94d636de90502fd611a5e49d5..9ae1383c75ab6891b2a0ea9a85a65601e4fb1341 100644 (file)
--- 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$<account-hook>\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" },
   /*
index ca6f42914c90c1793b0d90ffed2f001e3cbf715c..0dd0b258527f6ddd43ce72576759a3b632f7d918 100644 (file)
@@ -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);
 
index bdfcbea831c7457b59095f359ae101dbbf831551..8582bec8302287473c2572f8ba980c5cfcf66206 100644 (file)
@@ -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);