<<< Date Index >>>     <<< Thread Index >>>

[PATCH] TLS SNI support



Please find attached a patch which adjusts the TLS negotiation slightly.
If OpenSSL is new enough and was built with ServerNameIndication (SNI)
support, then this patch changes mutt to send the hostname it thinks it
is connecting to as part of the TLS negotiation.

I've made the same change to various https clients and it has worked
well there; for those changes, there exist patches to let Apache serve
up different certificates based upon the hostname seen.  There's no
equivalent server-side support that I know of for IMAP.

So why bother?  Well, if the client supports it then it becomes possible
for the servers to start using it.  If the server doesn't understand
SNI, then it should be silently ignored.  Why now?  Because a release
has gone out with SSLv2 support disabled by default, so AIUI mutt should
now be using a TLS-compatible negotiation for most users.

I ran mutt -d15 and see that TLS set up fine; there's nothing to
indicate that SNI was in use; should that be logged too?

----------------------------8< cut here >8------------------------------
Connected to imap.spodhuis.org:143 on fd=5
imap_cmd_step: grew buffer to 512 bytes
5< * OK [CAPABILITY IMAP4 IMAP4rev1 LITERAL+ ID STARTTLS LOGINDISABLED 
AUTH=GSSAPI AUTH=DIGEST-MD5 SASL-IR] imap.spodhuis.org Cyrus IMAP v2.3.14 
server ready
Handling CAPABILITY
IMAP queue drained
5> a0000 STARTTLS
5< a0000 OK Begin TLS negotiation now
IMAP queue drained
ssl_check_preauth: hostname check passed
ssl_check_preauth: signer check passed
5> a0001 CAPABILITY
----------------------------8< cut here >8------------------------------

So, at least for the case of Cyrus, this hasn't had any negative impact.
That test was done both with SSLv3 enabled and disabled.  mutt was
built/linked against OpenSSL 0.9.8k.  TLS support came in with 0.9.8f
but is not (AFAIK) yet enabled by default.  You need to build OpenSSL
with --enable-tlsext.  You can tell easily if your OpenSSL has support
by running "openssl s_client -h" and look in the options list for
-servername.

Regards,
-Phil
diff --git a/README.SSL b/README.SSL
--- a/README.SSL
+++ b/README.SSL
@@ -5,7 +5,7 @@ Compilation
 -----------
 If you want to have SSL support in mutt, you need to install OpenSSL
 (http://www.openssl.org) libraries and headers before compiling.
-OpenSSL versions 0.9.3 through 0.9.6a have been tested.
+OpenSSL versions 0.9.3 through 0.9.8k have been tested.
 
 For SSL support to be enabled, you need to run the ``configure''
 script with ``--enable-imap --with-ssl[=PFX]'' parameters.  If the
@@ -65,6 +65,12 @@ certificate, the connection will be esta
 can also be saved so that further connections to the server are
 automatically accepted. 
 
+If OpenSSL was built with support for ServerNameIndication (SNI) and TLS
+is used in the negotiation, mutt will send its idea of the server-name
+as part of the TLS negotiation.  This allows the server to select an
+appropriate certificate, in the event that one server handles multiple
+hostnames with different certificates.
+
 If your organization has several equivalent IMAP-servers, each of them
 should have a unique certificate which is signed with a common
 certificate.  If you want to use all of those servers, you don't need to
@@ -102,9 +108,15 @@ you know which options do not work, you 
 protocols to know.  The variables for the protocols are ssl_use_tlsv1, 
 ssl_use_sslv2, and ssl_use_sslv3.
 
+To verify TLS SNI, you can use:
+    openssl sl_client -host <imap server> -port <port> \
+        -tls1 -servername <imap server>
+
+
 -- 
 Tommi Komulainen
 Tommi.Komulainen@xxxxxx
 
-Updated by Jeremy Katz
-katzj@xxxxxxxxxxxxxx
+Updated by:
+  Jeremy Katz <katzj@xxxxxxxxxxxxxx>
+  Phil Pennock <mutt-dev@xxxxxxxxxxxx>
diff --git a/mutt_ssl.c b/mutt_ssl.c
--- a/mutt_ssl.c
+++ b/mutt_ssl.c
@@ -323,6 +323,20 @@ static int ssl_negotiate (CONNECTION *co
   SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY);
 #endif
 
+#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
+  /* TLS Virtual-hosting requires that the server present the correct
+   * certificate; to do this, the ServerNameIndication TLS extension is used.
+   * If TLS is negotiated, and OpenSSL is recent enough that it might have
+   * support, and support was enabled when OpenSSL was built, mutt supports
+   * sending the hostname we think we're connecting to, so a server can send
+   * back the correct certificate.
+   * NB: finding a server which uses this for IMAP is problematic, so this is
+   * untested.  Please report success or failure!  However, this code change
+   * has worked fine in other projects to which the contributor has added it,
+   * for HTTP usage. */
+  SSL_set_tlsext_host_name (ssldata->ssl, conn->account.host);
+#endif
+
   if ((err = SSL_connect (ssldata->ssl)) != 1)
   {
     switch (SSL_get_error (ssldata->ssl, err))