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/
This commit is contained in:
András Veres-Szentkirályi 2013-10-15 10:16:42 +02:00
parent bd42a7d06e
commit d84ce6ddb9
4 changed files with 36 additions and 0 deletions

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();

View File

@ -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;
}
}