/* * CipherSuiteNegotiationSimulation.java * * Created on Jul 9, 2012, 4:00:15 PM * * Description: Performs a simulation of the SSL/TLS cipher suite negotiation that occurs when an iOS client * connects with the Texai https server. * * Copyright (C) Jul 9, 2012, Stephen L. Reed, Texai.org. * */ package org.texai.ssl; import net.jcip.annotations.NotThreadSafe; import org.apache.log4j.Logger; import org.texai.util.StringUtils; /** Performs a simulation of the SSL/TLS cipher suite negotiation that occurs when an iOS client * connects with the Texai https server. * * @author reed */ @NotThreadSafe public class CipherSuiteNegotiationSimulation { private static final Logger LOGGER = Logger.getLogger(CipherSuiteNegotiationSimulation.class); /** the iOS cipher suites */ private static final String[] IOS_CIPHER_SUITES = { "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_RC4_128_SHA", "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5", "TLS_RSA_WITH_AES_256_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA" }; /** the Java cipher suites */ private static final String[] JAVA_CIPHER_SUITES = { "TLS_ECDH_ECDSA_WITH_NULL_SHA", "TLS_DH_anon_WITH_AES_128_CBC_SHA256", "TLS_ECDH_anon_WITH_RC4_128_SHA", "TLS_DH_anon_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_RC4_128_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_ECDH_anon_WITH_NULL_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DH_anon_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_NULL_SHA256", "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "TLS_KRB5_WITH_RC4_128_MD5", "SSL_RSA_WITH_DES_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_NULL_SHA", "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_RC4_128_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_DH_anon_WITH_AES_256_CBC_SHA256", "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "TLS_KRB5_WITH_RC4_128_SHA", "SSL_DH_anon_WITH_DES_CBC_SHA", "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_NULL_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5", "TLS_KRB5_WITH_DES_CBC_MD5", "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "SSL_DHE_DSS_WITH_DES_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_KRB5_WITH_DES_CBC_SHA", "SSL_RSA_WITH_NULL_MD5", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "SSL_DHE_RSA_WITH_DES_CBC_SHA", "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "SSL_RSA_WITH_NULL_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_NULL_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "SSL_DH_anon_WITH_RC4_128_MD5", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_RC4_128_MD5", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA" }; /** Constructs a new CipherSuiteNegotiationSimulation instance. */ public CipherSuiteNegotiationSimulation() { } /** Simulates an SSL cipher suite negotiation between an iOS client and the Texai server, in order to help find * compatible cipher suites for iOS clients which cannot be modified with respect to candidate cipher suites. */ private void simulate() { for (final String iOSCipherSuite : IOS_CIPHER_SUITES) { if (javaCipherSuitesContain(iOSCipherSuite)) { LOGGER.info("matched: " + iOSCipherSuite); } else { LOGGER.info(" " + iOSCipherSuite); } } } /** Returns whether the java cipher suites contain the given iOS cipher suite. * * @param iOSCipherSuite the given iOS cipher suite * @return whether the java cipher suites contain the given iOS cipher suite */ private boolean javaCipherSuitesContain(final String iOSCipherSuite) { //Preconditons assert StringUtils.isNonEmptyString(iOSCipherSuite) : "iOSCipherSuite must be a non-empty string"; for (final String javaCipherSuite : JAVA_CIPHER_SUITES) { if (iOSCipherSuite.equals(javaCipherSuite)) { return true; } } return false; } /** Executes this application. * * @param args the command line arguments - unused */ public static void main(final String[] args) { final CipherSuiteNegotiationSimulation cipherSuiteNegotiationSimulation = new CipherSuiteNegotiationSimulation(); cipherSuiteNegotiationSimulation.simulate(); } }