Sunday, August 31, 2014

JSSE based SSL ciphersuite tester


Just performs a handshake with the list of JSSE ciphers with the SSL server. If handshake is successful it marks it as a success. This is more of a test for Java based SSL clients which use JSSE for SSL/TLS communication. This code relies heavily on the underlying implementation provided by Java JDK/JSSE. Use it with 1.7 as a lot of cipher support has been added. As I mentioned, this is not a true SSL cipher scanner, because it depends on what ciphersuites have been enabled by JSSE. The server might support other ciphers that are not yet implemented by JSSE, but they wont turn up in the results. Actually if you can read from the raw SSL handshake packets, you can understand what the server SSL supports, you do not need java implementation for that.

package com.ssl.test;

import java.util.ArrayList;
import java.util.Collections;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class SSLTesting {

 private static final int PORT_TARGET = 443;
 private static final String HOST = "www.example.com";
 private static final String PROTO_SSLV3 = "SSLv3";
 private static final String PROTO_TLSV1 = "TLSv1";
 private static final String PROTO_TLSV11 = "TLSv1.1";
 private static final String PROTO_TLSV12 = "TLSv1.2";
 private static final boolean VERBOSE = false;
 
 // Note 1: Standard names for all the cipher suites, not all are yet implemented
 // http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites

 // Note 2: All the ones supported by Java 7
 // http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider
 
 //See Note 2.
 private static final String jsseCiphersDisabledByDefault = "TLS_DH_anon_WITH_AES_256_CBC_SHA256:TLS_ECDH_anon_WITH_AES_256_CBC_SHA:TLS_DH_anon_WITH_AES_256_CBC_SHA:"
   + "TLS_DH_anon_WITH_AES_128_CBC_SHA256:TLS_ECDH_anon_WITH_AES_128_CBC_SHA:TLS_DH_anon_WITH_AES_128_CBC_SHA:TLS_ECDH_anon_WITH_RC4_128_SHA:"
   + "SSL_DH_anon_WITH_RC4_128_MD5:TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_NULL_SHA256:"
   + "TLS_ECDHE_ECDSA_WITH_NULL_SHA:TLS_ECDHE_RSA_WITH_NULL_SHA:SSL_RSA_WITH_NULL_SHA:TLS_ECDH_ECDSA_WITH_NULL_SHA:TLS_ECDH_RSA_WITH_NULL_SHA:"
   + "TLS_ECDH_anon_WITH_NULL_SHA:SSL_RSA_WITH_NULL_MD5:SSL_RSA_WITH_DES_CBC_SHA:SSL_DHE_RSA_WITH_DES_CBC_SHA:SSL_DHE_DSS_WITH_DES_CBC_SHA:"
   + "SSL_DH_anon_WITH_DES_CBC_SHA:SSL_RSA_EXPORT_WITH_RC4_40_MD5:SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:"
   + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:TLS_KRB5_WITH_RC4_128_SHA:"
   + "TLS_KRB5_WITH_RC4_128_MD5:TLS_KRB5_WITH_3DES_EDE_CBC_SHA:TLS_KRB5_WITH_3DES_EDE_CBC_MD5:TLS_KRB5_WITH_DES_CBC_SHA:TLS_KRB5_WITH_DES_CBC_MD5:"
   + "TLS_KRB5_EXPORT_WITH_RC4_40_SHA:TLS_KRB5_EXPORT_WITH_RC4_40_MD5:TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA:TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5";
    //See Note 2.
 private static final String jsseCiphersEnabledByDefault = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:TLS_RSA_WITH_AES_256_CBC_SHA256:"
   + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:"
   + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_AES_256_CBC_SHA:"
   + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:TLS_DHE_RSA_WITH_AES_256_CBC_SHA:TLS_DHE_DSS_WITH_AES_256_CBC_SHA:"
   + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:TLS_RSA_WITH_AES_128_CBC_SHA256:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:"
   + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:"
   + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_AES_128_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:"
   + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA:TLS_DHE_DSS_WITH_AES_128_CBC_SHA:TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:TLS_ECDHE_RSA_WITH_RC4_128_SHA:"
   + "SSL_RSA_WITH_RC4_128_SHA:TLS_ECDH_ECDSA_WITH_RC4_128_SHA:TLS_ECDH_RSA_WITH_RC4_128_SHA:TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:"
   + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:SSL_RSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:"
   + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:SSL_RSA_WITH_RC4_128_MD5:TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
 
 //A lot of them are not yet supported on jsse, See Note 1.
 private static final String jsseCompleteCipherList = "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:"
   + "TLS_DH_anon_WITH_AES_128_CBC_SHA:TLS_DH_anon_WITH_AES_128_CBC_SHA256:TLS_DH_anon_WITH_AES_128_GCM_SHA256:TLS_DH_anon_WITH_AES_256_CBC_SHA:"
   + "TLS_DH_anon_WITH_AES_256_CBC_SHA256:TLS_DH_anon_WITH_AES_256_GCM_SHA384:TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA:TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256:"
   + "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA:TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256:SSL_DH_anon_WITH_DES_CBC_SHA:SSL_DH_anon_WITH_RC4_128_MD5:"
   + "TLS_DH_anon_WITH_SEED_CBC_SHA:SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:TLS_DH_DSS_WITH_AES_128_CBC_SHA:"
   + "TLS_DH_DSS_WITH_AES_128_CBC_SHA256:TLS_DH_DSS_WITH_AES_128_GCM_SHA256:TLS_DH_DSS_WITH_AES_256_CBC_SHA:TLS_DH_DSS_WITH_AES_256_CBC_SHA256:"
   + "TLS_DH_DSS_WITH_AES_256_GCM_SHA384:TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA:TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256:TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA:"
   + "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256:SSL_DH_DSS_WITH_DES_CBC_SHA:TLS_DH_DSS_WITH_SEED_CBC_SHA:SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:"
   + "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:TLS_DH_RSA_WITH_AES_128_CBC_SHA:TLS_DH_RSA_WITH_AES_128_CBC_SHA256:TLS_DH_RSA_WITH_AES_128_GCM_SHA256:"
   + "TLS_DH_RSA_WITH_AES_256_CBC_SHA:TLS_DH_RSA_WITH_AES_256_CBC_SHA256:TLS_DH_RSA_WITH_AES_256_GCM_SHA384:TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA:"
   + "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256:TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA:TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256:SSL_DH_RSA_WITH_DES_CBC_SHA:"
   + "TLS_DH_RSA_WITH_SEED_CBC_SHA:SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA:SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA:"
   + "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:TLS_DHE_DSS_WITH_AES_128_CBC_SHA:TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:"
   + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA:TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:"
   + "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256:TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256:SSL_DHE_DSS_WITH_DES_CBC_SHA:"
   + "SSL_DHE_DSS_WITH_RC4_128_SHA:TLS_DHE_DSS_WITH_SEED_CBC_SHA:TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:TLS_DHE_PSK_WITH_AES_128_CBC_SHA:"
   + "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:TLS_DHE_PSK_WITH_AES_256_CBC_SHA:TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:"
   + "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:TLS_DHE_PSK_WITH_NULL_SHA:TLS_DHE_PSK_WITH_NULL_SHA256:TLS_DHE_PSK_WITH_NULL_SHA384:"
   + "TLS_DHE_PSK_WITH_RC4_128_SHA:SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:TLS_DHE_RSA_WITH_AES_128_CBC_SHA:"
   + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:"
   + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256:TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:"
   + "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256:SSL_DHE_RSA_WITH_DES_CBC_SHA:TLS_DHE_RSA_WITH_SEED_CBC_SHA:TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:"
   + "TLS_ECDH_anon_WITH_AES_128_CBC_SHA:TLS_ECDH_anon_WITH_AES_256_CBC_SHA:TLS_ECDH_anon_WITH_NULL_SHA:TLS_ECDH_anon_WITH_RC4_128_SHA:"
   + "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:"
   + "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDH_ECDSA_WITH_NULL_SHA:"
   + "TLS_ECDH_ECDSA_WITH_RC4_128_SHA:TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:"
   + "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:"
   + "TLS_ECDH_RSA_WITH_NULL_SHA:TLS_ECDH_RSA_WITH_RC4_128_SHA:TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:"
   + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:"
   + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_NULL_SHA:TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:"
   + "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA:TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA:TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA:"
   + "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384:TLS_ECDHE_PSK_WITH_NULL_SHA:TLS_ECDHE_PSK_WITH_NULL_SHA256:TLS_ECDHE_PSK_WITH_NULL_SHA384:"
   + "TLS_ECDHE_PSK_WITH_RC4_128_SHA:TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:"
   + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:"
   + "TLS_ECDHE_RSA_WITH_NULL_SHA:TLS_ECDHE_RSA_WITH_RC4_128_SHA:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:"
   + "SSL_FORTEZZA_DMS_WITH_NULL_SHA:TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5:TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA:TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5:"
   + "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA:TLS_KRB5_EXPORT_WITH_RC4_40_MD5:TLS_KRB5_EXPORT_WITH_RC4_40_SHA:TLS_KRB5_WITH_3DES_EDE_CBC_MD5:"
   + "TLS_KRB5_WITH_3DES_EDE_CBC_SHA:TLS_KRB5_WITH_DES_CBC_MD5:TLS_KRB5_WITH_DES_CBC_SHA:TLS_KRB5_WITH_IDEA_CBC_MD5:TLS_KRB5_WITH_IDEA_CBC_SHA:"
   + "TLS_KRB5_WITH_RC4_128_MD5:TLS_KRB5_WITH_RC4_128_SHA:TLS_PSK_WITH_3DES_EDE_CBC_SHA:TLS_PSK_WITH_AES_128_CBC_SHA:TLS_PSK_WITH_AES_128_CBC_SHA256:"
   + "TLS_PSK_WITH_AES_128_GCM_SHA256:TLS_PSK_WITH_AES_256_CBC_SHA:TLS_PSK_WITH_AES_256_CBC_SHA384:TLS_PSK_WITH_AES_256_GCM_SHA384:TLS_PSK_WITH_NULL_SHA:"
   + "TLS_PSK_WITH_NULL_SHA256:TLS_PSK_WITH_NULL_SHA384:TLS_PSK_WITH_RC4_128_SHA:SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:"
   + "SSL_RSA_EXPORT_WITH_RC4_40_MD5:SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA:SSL_RSA_EXPORT1024_WITH_RC4_56_SHA:SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA:"
   + "SSL_RSA_FIPS_WITH_DES_CBC_SHA:TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:TLS_RSA_PSK_WITH_AES_128_CBC_SHA:TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:"
   + "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:TLS_RSA_PSK_WITH_AES_256_CBC_SHA:TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:"
   + "TLS_RSA_PSK_WITH_NULL_SHA:TLS_RSA_PSK_WITH_NULL_SHA256:TLS_RSA_PSK_WITH_NULL_SHA384:TLS_RSA_PSK_WITH_RC4_128_SHA:SSL_RSA_WITH_3DES_EDE_CBC_SHA:"
   + "TLS_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_AES_128_CBC_SHA256:TLS_RSA_WITH_AES_128_GCM_SHA256:TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_AES_256_CBC_SHA256:"
   + "TLS_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256:TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:"
   + "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256:SSL_RSA_WITH_DES_CBC_SHA:SSL_RSA_WITH_IDEA_CBC_SHA:SSL_RSA_WITH_NULL_MD5:SSL_RSA_WITH_NULL_SHA:"
   + "TLS_RSA_WITH_NULL_SHA256:SSL_RSA_WITH_RC4_128_MD5:SSL_RSA_WITH_RC4_128_SHA:TLS_RSA_WITH_SEED_CBC_SHA:TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:"
   + "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:"
   + "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:TLS_SRP_SHA_WITH_AES_128_CBC_SHA:TLS_SRP_SHA_WITH_AES_256_CBC_SHA";
 
 public static void main(String[] args) throws Exception {
  String ciphers = jsseCiphersEnabledByDefault + ":" + jsseCiphersDisabledByDefault;
  System.out.println("Using Hostname : port = " + HOST + " : " + PORT_TARGET);
   
  //test enabled and the ones that disabled by default
   testSSL(HOST, PORT_TARGET, PROTO_SSLV3, ciphers);
   testSSL(HOST, PORT_TARGET, PROTO_TLSV1, ciphers);
   testSSL(HOST, PORT_TARGET, PROTO_TLSV11, ciphers);
   testSSL(HOST, PORT_TARGET, PROTO_TLSV12, ciphers);
     
  //test weak ciphers
  /* testSSL(HOST, PORT_TARGET, PROTO_SSLV3, jsseCiphersDisabledByDefault);
   testSSL(HOST, PORT_TARGET, PROTO_TLSV1, jsseCiphersDisabledByDefault);
   testSSL(HOST, PORT_TARGET, PROTO_TLSV11, jsseCiphersDisabledByDefault);
   testSSL(HOST, PORT_TARGET, PROTO_TLSV12, jsseCiphersDisabledByDefault);*/
 
 
 }

 private static void testSSL(String hostname, int port, String version, String cipherSuitesToTest) {
  try {
   System.out.println("-------------------------");
   System.out.println("Protocol : " + version);
   ArrayList success = new ArrayList();
   ArrayList unsupported = new ArrayList();
   ArrayList fail = new ArrayList();
   SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
     .getDefault();
   SSLSocket socket = (SSLSocket) factory.createSocket(hostname, port);
   //set the SSL version to be used
   String[] prots = { version };
   socket.setEnabledProtocols(prots);

   String[] cipherSuitesClient = cipherSuitesToTest.split(":");

   for (String ciphers : cipherSuitesClient) {
    socket = (SSLSocket) factory.createSocket(hostname, port);
    socket.setEnabledProtocols(prots);
    String[] array = { ciphers };
    //try making a handshake
    try {
    socket.setEnabledCipherSuites(array);
     socket.startHandshake();
     success.add(ciphers);
    } catch (javax.net.ssl.SSLHandshakeException e) {
     fail.add(ciphers);
    } catch (java.lang.IllegalArgumentException e){
     if (e.getMessage().contains("Unsupported ciphersuite") || e.getMessage().contains("Cannot support"))
      unsupported.add(ciphers);
     else
      e.printStackTrace();
    }
    catch (Exception e) {
     System.out.println(ciphers + ":" + e.getClass() + " "
       + e.getMessage());
    }
    socket.close();
   }
   System.out.println("Testing " + version + " ciphers. Count: "
     + cipherSuitesClient.length);
   System.out.println("Successful Handshake count = "
     + success.size());
   Collections.sort(success);
   for (String name : success) {
    System.out.println("[" + version + "]" + " +" + name);
   }
   
   System.out.println("Unsupported list. Count = " + unsupported.size());
   Collections.sort(unsupported);
   if(VERBOSE){
   for (String name : unsupported) {
    System.out.println("[" + version + "]" + "XXX " + name);
   }
   }

   System.out.println("Handshake Failed Count = " + fail.size());
   if(VERBOSE){
   for (String name : fail) {
     System.out.println("[" + version + "]" + "-" + name);
   }
   }

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Saturday, August 30, 2014

Java/JSSE Handshake SSL/TLS exceptions

If you are facing some of the below errors, it might mean you are using a Java that does not have the support for the thing you are trying to do:

Example 1: Illegal argument exceptions for protocol version
You are enabling TLS 1.1 and TLS 1.2, but it may give you an exception if you are using Java 1.6. 1.6 does not support TLS 1.1 and TLS 1.2. You can check here as it supports only SSLv3 and TLSv1 (See Support classes and Interfaces section and see the possible values for SSLContext):


http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html

...
String[] protocols = {"TLSv1.1", "TLSv1.2"};
socket = (SSLSocket) factory.createSocket(hostname, port);
    socket.setEnabledProtocols(protocols);
...

-------------------------
Protocol : TLSv1.1
java.lang.IllegalArgumentException: TLSv1.1
    at com.sun.net.ssl.internal.ssl.ProtocolVersion.valueOf(ProtocolVersion.java:133)
    at com.sun.net.ssl.internal.ssl.ProtocolList.(ProtocolList.java:38)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.setEnabledProtocols(SSLSocketImpl.java:2202)
    at com.ssl.test.SSLTesting.testSSL(SSLTesting.java:177)
    at com.ssl.test.SSLTesting.main(SSLTesting.java:154)
-------------------------
Protocol : TLSv1.2
java.lang.IllegalArgumentException: TLSv1.2
    at com.sun.net.ssl.internal.ssl.ProtocolVersion.valueOf(ProtocolVersion.java:133)
    at com.sun.net.ssl.internal.ssl.ProtocolList.(ProtocolList.java:38)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.setEnabledProtocols(SSLSocketImpl.java:2202)
    at com.ssl.test.SSLTesting.testSSL(SSLTesting.java:177)
    at com.ssl.test.SSLTesting.main(SSLTesting.java:164)


So, as an example, when I check, I see that my eclipse is still using 1.6 for execution.


So I need to change it to 1.7 to destroy these ugly exceptions. :D. You can check the page for JSSE 7.
http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html and see the values for SSLContext. Changed to 1.7.



Example 2: Cannot support cipher exceptions:

Cannot support exceptions again point to the use of an incorrect JRE like 1.6. However, unsupported exception (that you can get while using 1.7) might mean that the ciphersuite is still not implemented in JSSE 1.7.
To get a list of a complete list of JSSE cipher names you can use this link:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites

However, you must know that these are only the names that JSSE is going to use, some of the ciphers are still not implemented and can be expected to be implemented in Java 8. To see what all ciphers are implemendted in 1.7, you can use this link, check the Cipher suite section:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider

java.lang.IllegalArgumentException: Cannot support TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA with currently installed providers
    at com.sun.net.ssl.internal.ssl.CipherSuiteList.(CipherSuiteList.java:79)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.setEnabledCipherSuites(SSLSocketImpl.java:2162)
    at com.ssl.test.SSLTesting.testSSL(SSLTesting.java:186)

Friday, August 15, 2014

SSL/TLS cipher testing Notes and Tools

I am trying to gather some freely available tools, techniques and links that can help running SSL/TLS related tests. The more I learn, the more stuff I will add. SSL/TLS is not that simple, you cannot rely on the output of just 1 tool. You also need to understand how that tool/script works internally.

Tools and scripts (will keep adding)

Testing might be affected with what openssl version you have installed, because older versions may not have support for newer cipher suites or higher protocols. So while testing you need to take this into consideration.

1. Nmap ssl-enum-ciphers script

nmap --script ssl-enum-ciphers -p 443 hostname

http://nmap.org/nsedoc/scripts/ssl-enum-ciphers.html



2. sslscan. (based on openssl)
http://sourceforge.net/projects/sslscan/

Uses openssl internally. If you compile it on redhat, you may run into compilation issues because EC crypto is not there in openssl in redhat (depending on your version). If you are not interested in testing EC, then you can comment out the lines as mentioned in my previous post:

http://rhosted.blogspot.in/2014/02/using-sslscan-and-ssltests-for-testing.html



3. ssl_tests (based on sslscan/openssl)
ssl_tests is a shell script that uses sslscan and openssl internally to connect.

www.pentesterscripting.com/discovery/ssl_tests



4. Using OpenSSL directly
openssl s_client -connect host:port

5. sslyze
root@kali:~# sslyze --tlsv1 www.example.com

6. TestSSLServer : A simple java program that does the same kind of testing. The program uses plain sockets and raw packet level inspection and does not depend on any provider like JSSE or Openssl as such. So it is very good for learning at raw packet level as to how do you know whether compression is supported or not. The program also checks CRIME and BEAST status by checking the compression support in the connection and inspecting the protocol version. You can see how it does that in the comments.

However, I would recommend you develop your own understand about CRIME/BEAST working and its latest status depending on your own application implementation rather than relying on the output of the testing program. Things and assumptions keep changing with time.

http://www.bolet.org/TestSSLServer/

Original reference: http://security.stackexchange.com/questions/20376/tools-to-test-for-beast-crime-that-arent-internet-based

Here is a screenshot of running the tool using eclipse:



7. SSLDigger by Foundstone -
It is a windows based tool. However, it does not have support for a lot of latest ciphers probably because it has not been updated.



http://www.mcafee.com/uk/downloads/free-tools/ssldigger.aspx

8. If you want to play around writing your own tool, here is a small test I did in Java. This tool is an example of how you can use a crypto library for SSL testing. The drawback is that you can only test the cipher that your client library supports. In contrast to TestSSLServer (6) which does a packet level inspection and does not rely on a local crypto library.

http://rhosted.blogspot.in/2014/08/jsse-based-ssl-ciphersuite-tester.html



9. Testing the SSL for mysql and postgresql?
Databases do not really follow the procedures of a typical SSL/TLS handshake. You need to have a db client for that or you can use wireshark. Wanna see an example, check my earlier notes on mysql's ssl:

http://rhosted.blogspot.in/2014/10/mysql-tlsv1-capture-using-wireshark.html


10. SSLAudit - https://code.google.com/p/sslaudit/

I found SSLAudit pretty good.


11. SSL Breacher
http://bl0g.yehg.net/2014/07/ssl-breacher-yet-another-ssl-test-tool.html

12. TLSSLed (Based on sslscan/openssl)
http://blog.taddong.com/2011/05/tlssled-v10.html



To be continued..

Helpful references for testing




TLS learning

[*]  Listing of Openssl ciphers (meaning of examples like ALL:!ADH:@STRENGTH)
       https://www.openssl.org/docs/apps/ciphers.html#EXAMPLES

[*]  A little advanced but good learning material about TLS
       https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet

[*]  Explains a lot of common SSL problems in a very simple way.
       https://www.howsmyssl.com/s/about.html

[*]  Understanding the meaning of a cipher string like DHE-RSA-AES256-SHA
       http://nzbget.net/Choosing_a_cipher

[*]  High/Low/Med grade ciphers
       https://bto.bluecoat.com/packetguide/appcelera-3.0.2/configure/ssl-cipher-details-popup.htm

SSL/TLS best practices

[*]  https://www.ssllabs.com/projects/best-practices/index.html

Products using SSL

[*] Postgres using SSL (How to test SSL being used)
      https://kb.berkeley.edu/page.php?id=23113

BEAST

http://blog.cryptographyengineering.com/2011/09/brief-diversion-beast-attack-on-tlsssl.html