From d84ce6ddb996e0e17c3de974bf67cb2f1d42b668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Tue, 15 Oct 2013 10:16:42 +0200 Subject: [PATCH] Hardened TLS cipher suites and versions As Georg Lukas wrote in his blog post about how Android handles TLS handshake (http://op-co.de/blog/posts/android_ssl_downgrade/), an explicit order of cipher suites and TLS versions must be supplied to avoid having the weak (presumably broken) RC4 cipher at the top of the preference list. This commit adds the list included in the blog post to every TLS socket creation, including IMAP, POP3 and SMTP, see Wireshark screenshots done during testing at http://vsza.hu/k9mail-tls-hardening/ --- src/com/fsck/k9/mail/store/ImapStore.java | 3 ++ src/com/fsck/k9/mail/store/Pop3Store.java | 3 ++ .../fsck/k9/mail/transport/SmtpTransport.java | 2 ++ .../mail/transport/TrustedSocketFactory.java | 28 +++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index e2bbfa0f1..8334db923 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -50,6 +50,7 @@ import java.util.zip.InflaterInputStream; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import org.apache.commons.io.IOUtils; @@ -96,6 +97,7 @@ import com.fsck.k9.mail.store.ImapResponseParser.ImapList; import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse; import com.fsck.k9.mail.store.imap.ImapUtility; import com.fsck.k9.mail.transport.imap.ImapSettings; +import com.fsck.k9.mail.transport.TrustedSocketFactory; import com.jcraft.jzlib.JZlib; import com.jcraft.jzlib.ZOutputStream; @@ -2450,6 +2452,7 @@ public class ImapStore extends Store { TrustManagerFactory.get(mSettings.getHost(), secure) }, new SecureRandom()); mSocket = sslContext.getSocketFactory().createSocket(); + TrustedSocketFactory.hardenSocket((SSLSocket)mSocket); } else { mSocket = new Socket(); } diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java index 7cac7b48e..ff7e1a3ba 100644 --- a/src/com/fsck/k9/mail/store/Pop3Store.java +++ b/src/com/fsck/k9/mail/store/Pop3Store.java @@ -7,12 +7,14 @@ import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.controller.MessageRetrievalListener; import com.fsck.k9.helper.Utility; +import com.fsck.k9.mail.transport.TrustedSocketFactory; import com.fsck.k9.mail.*; import com.fsck.k9.mail.internet.MimeMessage; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import java.io.*; import java.net.*; @@ -331,6 +333,7 @@ public class Pop3Store extends Store { TrustManagerFactory.get(mHost, secure) }, new SecureRandom()); mSocket = sslContext.getSocketFactory().createSocket(); + TrustedSocketFactory.hardenSocket((SSLSocket)mSocket); } else { mSocket = new Socket(); } diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 30ad91b4d..1b4c57d25 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -17,6 +17,7 @@ import com.fsck.k9.mail.store.LocalStore.LocalMessage; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -245,6 +246,7 @@ public class SmtpTransport extends Transport { TrustManagerFactory.get(mHost, secure) }, new SecureRandom()); mSocket = sslContext.getSocketFactory().createSocket(); + TrustedSocketFactory.hardenSocket((SSLSocket)mSocket); mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT); } else { mSocket = new Socket(); diff --git a/src/com/fsck/k9/mail/transport/TrustedSocketFactory.java b/src/com/fsck/k9/mail/transport/TrustedSocketFactory.java index fa23f079b..264874fb9 100644 --- a/src/com/fsck/k9/mail/transport/TrustedSocketFactory.java +++ b/src/com/fsck/k9/mail/transport/TrustedSocketFactory.java @@ -21,6 +21,27 @@ public class TrustedSocketFactory implements LayeredSocketFactory { private SSLSocketFactory mSocketFactory; private org.apache.http.conn.ssl.SSLSocketFactory mSchemeSocketFactory; + protected static final String ENABLED_CIPHERS[] = { + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_RC4_128_SHA", + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "SSL_RSA_WITH_3DES_EDE_CBC_SHA", + "SSL_RSA_WITH_RC4_128_SHA", + "SSL_RSA_WITH_RC4_128_MD5", + }; + + protected static final String ENABLED_PROTOCOLS[] = { + "TLSv1.2", "TLSv1.1", "TLSv1" + }; + public TrustedSocketFactory(String host, boolean secure) throws NoSuchAlgorithmException, KeyManagementException { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[] { @@ -45,6 +66,12 @@ public class TrustedSocketFactory implements LayeredSocketFactory { public boolean isSecure(Socket sock) throws IllegalArgumentException { return mSchemeSocketFactory.isSecure(sock); } + + public static void hardenSocket(SSLSocket sock) { + sock.setEnabledCipherSuites(ENABLED_CIPHERS); + sock.setEnabledProtocols(ENABLED_PROTOCOLS); + } + public Socket createSocket( final Socket socket, final String host, @@ -59,6 +86,7 @@ public class TrustedSocketFactory implements LayeredSocketFactory { ); //hostnameVerifier.verify(host, sslSocket); // verifyHostName() didn't blowup - good! + hardenSocket(sslSocket); return sslSocket; } }