13 Replies Latest reply: May 9, 2012 3:19 PM by wetmore RSS

    Using TLSv1.2 with Java 7

    852668
      Hi,
      We're attempting to migrate our server so it can utilize TLSv1.2 in Java 7 but we are having some difficulty getting it to work. I took the EchoServer/EchoClient example from http://stilius.net/java/java_ssl.php, I ran it and it worked fine (using default SSL). I modified the code to get an SSLContext and get the TLSv1.2 protocol:

      SSLContext ret = SSLContext.getInstance("TLSv1.2");
      ret.init(null, null, null);

      This did not work, when the client sent data to the server we got an SSLHandShakeException. Through some searches it seemed as though I needed to use my own KeyStore instead of the default one that comes with Java, so I created one and modified the Echo tests to use that as the KeyStore (for the server) and the TrustStore (for the client).

      Doing this worked as expected, when using the default ciphers. Now I modified the server and client to call 'setEnabledCiphers' passing it a TLSv1.2 cipher ("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" to be specific). The client can 'connect' but when I type something I get a handshake excepiton, the server shows

      javax.net.ssl.SSLHandshakeException: no cipher suites in common


      Here is the modified server code:
      -----
      import java.io.BufferedReader;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.InputStream;
      import java.io.InputStreamReader;
      import java.security.KeyManagementException;
      import java.security.KeyStore;
      import java.security.NoSuchAlgorithmException;
      import java.util.Arrays;
      
      import javax.net.ssl.KeyManager;
      import javax.net.ssl.KeyManagerFactory;
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.SSLServerSocket;
      import javax.net.ssl.SSLServerSocketFactory;
      import javax.net.ssl.SSLSocket;
      
      public class EchoServer {
           
           private static KeyManager[] getKeyManagerArray(String keystore,
                     String keystorePasswd) {
                KeyManager[] ret = null;
                String keyFile = "mySrvKeystore";
      
                if (null != keystore) {
                     keyFile = keystore;
                } else {
                     keyFile = "mySrvKeystore";
                     File t = new File(keyFile);
                     if (!t.exists()) {
                          keyFile = "../" + keyFile;
                          t = new File(keyFile);
                          if (!t.exists()) {
                               throw new RuntimeException("Could not find key manager file");
                          }
                     }
                }
                if (null == keystorePasswd) {
                     keystorePasswd = "123456";
                }
                try {
                     System.out.println("Using keystore: " + keyFile);
                     KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
                     KeyStore ks = KeyStore.getInstance("JKS");
                     // initialize KeyStore object using keystore name
                     ks.load(new FileInputStream(keyFile), null);
                     kmf.init(ks, keystorePasswd.toCharArray());
                     ret = kmf.getKeyManagers();
                } catch (Exception e) {
                     e.printStackTrace();
                }
      
                return ret;
           }
           
           private static SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
                SSLContext ret = SSLContext.getInstance("TLSv1.2");
                KeyManager[] km = getKeyManagerArray(null, null);
                ret.init(km, null, null);
                return ret;
           }
           
           public static void main(String[] arstring) {
                try {
                     SSLContext sc = getSSLContext();
                     
                     SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) sc.getServerSocketFactory();
                     SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
                               .createServerSocket(9999);
                     
                     final String[] enabledCipherSuites = { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" };
                     sslserversocket.setEnabledCipherSuites(enabledCipherSuites);
                     
                     System.out.println("Enabled ciphers: " + Arrays.toString(sslserversocket.getEnabledCipherSuites()));
                     
                     SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
      
                     InputStream inputstream = sslsocket.getInputStream();
                     InputStreamReader inputstreamreader = new InputStreamReader(
                               inputstream);
                     BufferedReader bufferedreader = new BufferedReader(
                               inputstreamreader);
      
                     String string = null;
                     while ((string = bufferedreader.readLine()) != null) {
                          System.out.println(string);
                          System.out.flush();
                     }
                } catch (Exception exception) {
                     exception.printStackTrace();
                }
           }
      }
      -----
      Here is the updated client
      -----
      import java.io.BufferedReader;
      import java.io.BufferedWriter;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.InputStream;
      import java.io.InputStreamReader;
      import java.io.OutputStream;
      import java.io.OutputStreamWriter;
      import java.security.KeyManagementException;
      import java.security.KeyStore;
      import java.security.NoSuchAlgorithmException;
      import java.util.Arrays;
      
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.SSLSocket;
      import javax.net.ssl.SSLSocketFactory;
      import javax.net.ssl.TrustManager;
      import javax.net.ssl.TrustManagerFactory;
      
      public class EchoClient {
           
           private static TrustManager[] getTrustManagerArray(String truststore,
                     String pwd) {
                TrustManager[] ret = null;
                String trustFile = "mySrvKeystore";
                if (null != truststore) {
                     trustFile = truststore;
                } else {
                     File t = new File(trustFile);
                     if (!t.exists()) {
                          trustFile = "../" + trustFile;
                          t = new File(trustFile);
                          if (!t.exists()) {
                               throw new RuntimeException("Could not find trust file");
                          }
                     }
                     pwd = "123456";
                }
      
                try {
                     System.out.println("Using " + trustFile + " as truststore");
                     TrustManagerFactory tmf = TrustManagerFactory
                               .getInstance("SunX509");
                     KeyStore ts = KeyStore.getInstance("JKS");
                     // initialize truststore object using truststore name
                     ts.load(new FileInputStream(trustFile), pwd.toCharArray());
                     tmf.init(ts);
                     ret = tmf.getTrustManagers();
                } catch (Exception e) {
                     e.printStackTrace();
                }
                return ret;
           }
           
           private static SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
                SSLContext ret = SSLContext.getInstance("TLSv1.2");
                TrustManager[] tm = getTrustManagerArray(null, null);
                ret.init(null, tm, null);
                return ret;
           }
           
           public static void main(String[] arstring) {
                try {
                     SSLContext sc = getSSLContext();
                     
                     SSLSocketFactory sslsocketfactory = (SSLSocketFactory) sc.getSocketFactory();
                     
                     SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
                               "localhost", 9999);
                     
                     final String[] enabledCipherSuites = { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" };
                     sslsocket.setEnabledCipherSuites(enabledCipherSuites);
                     
                     System.out.println("Enabled ciphers: " + Arrays.toString(sslsocket.getEnabledCipherSuites()));
                     
                     InputStream inputstream = System.in;
                     InputStreamReader inputstreamreader = new InputStreamReader(
                               inputstream);
                     BufferedReader bufferedreader = new BufferedReader(
                               inputstreamreader);
      
                     OutputStream outputstream = sslsocket.getOutputStream();
                     OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
                               outputstream);
                     BufferedWriter bufferedwriter = new BufferedWriter(
                               outputstreamwriter);
      
                     String string = null;
                     while ((string = bufferedreader.readLine()) != null) {
                          bufferedwriter.write(string + '\n');
                          bufferedwriter.flush();
                     }
                } catch (Exception exception) {
                     exception.printStackTrace();
                }
           }
      }
        • 1. Re: Using TLSv1.2 with Java 7
          EJP
          You only need your own keystore etc if the server requires a client certificate.

          Post the stack trace.
          • 2. Re: Using TLSv1.2 with Java 7
            852668
            Hi,
            Thanks for taking the time to reply. Is there something in the above code which would cause the need for my own keystore, as it seems I have to have one?

            When I do not use my own KeyManager I get the following from the server
            C:\Java\projects\tests\tests\bin>java -classpath . EchoServer
            Getting SSL Context
            Enabled Protocol(s): [SSLv2Hello, SSLv3, TLSv1, TLSv1.1, TLSv1.2]
            Enabled cipher(s): [TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
            javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
                    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
                    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
                    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1943)
                    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1059)
                    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
                    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:848)
            
                    at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
                    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
                    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
                    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
                    at java.io.InputStreamReader.read(InputStreamReader.java:184)
                    at java.io.BufferedReader.fill(BufferedReader.java:154)
                    at java.io.BufferedReader.readLine(BufferedReader.java:317)
                    at java.io.BufferedReader.readLine(BufferedReader.java:382)
                    at others.EchoServer.main(EchoServer.java:126)
            and here is the client output, my input to the client app has an asterisk around it
            Getting SSL Context
            Enabled Protocol(s): [TLSv1.2]
            Enabled cipher(s): [TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
            *hello*
            javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
                    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
                    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
                    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1943)
                    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1059)
                    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
                    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685)
                    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111)
                    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
                    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
                    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
                    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
                    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
                    at java.io.BufferedWriter.flush(BufferedWriter.java:254)
                    at others.EchoClient.main(EchoClient.java:131)
            Thank you
            • 3. Re: Using TLSv1.2 with Java 7
              EJP
              Good, now can you please run the client with -Djavax.net.debug=handshake,failure and post the output here?
              • 4. Re: Using TLSv1.2 with Java 7
                852668
                Hi again,
                Adding
                -Djavax.net.debug=handshake,failure
                didn't, apeear to, produce any additional output:
                C:\Java\projects\tests\tests\bin>java -Djavax.net.debug=handshake,failure -classpath . EchoClient
                Getting SSL Context
                Enabled Protocol(s): [TLSv1.2]
                Enabled cipher(s): [TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
                *hello*
                javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
                        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
                        at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
                        at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1943)
                        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1059)
                        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
                        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685)
                        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111)
                        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
                        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
                        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
                        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
                        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
                        at java.io.BufferedWriter.flush(BufferedWriter.java:254)
                        at others.EchoClient.main(EchoClient.java:131)
                I modified it to be
                -Djavax.net.debug=ssl,handshake,failure
                and that produced a ton of output
                ... removed incorrect output ...
                and just to make this post even bigger, here is the output from the server with the same -D option used on the client I removed all the cert setup messages, hope that was OK
                 ... removed incorrect output ...
                Edited by: JimM on Apr 30, 2012 11:31 AM, removed output since it was not correct
                • 5. Re: Using TLSv1.2 with Java 7
                  EJP
                  Adding
                  -Djavax.net.debug=handshake,failure
                  didn't, apeear to, produce any additional output:
                  Oops, sorry, my bad.
                  I modified it to be
                  -Djavax.net.debug=ssl,handshake,failure
                  and that produced a ton of output
                  Well done. Sadly you have deleted everything of interest. I don't need to see all the certificates but I do need to see every line beginning with three asterisks.
                  • 6. Re: Using TLSv1.2 with Java 7
                    852668
                    Hi EJP,
                    I just re-ran the program and piped the output to a file, looking at the file (both server and client) I only see two lines with '***'

                    Server:
                    *** ClientHello, TLSv1.2
                    ...
                    ***
                    %% Initialized:  [Session-1, SSL_NULL_WITH_NULL_NULL]
                    %% Invalidated:  [Session-1, SSL_NULL_WITH_NULL_NULL]
                    main, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
                    main, WRITE: TLSv1.2 Alert, length = 2
                    main, called closeSocket()
                    main, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
                    Client:
                    *** ClientHello, TLSv1.2
                    ...
                    ***
                    main, WRITE: TLSv1.2 Handshake, length = 82
                    main, READ: TLSv1.2 Alert, length = 2
                    main, RECV TLSv1 ALERT:  fatal, handshake_failure
                    main, called closeSocket()
                    main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
                    Perhaps there is an additional debug setting I need?

                    Here is the debug option I am passing
                    -Djavax.net.debug=ssl,handshake,failure
                    thanks
                    Jim

                    Edited by: JimM on Apr 30, 2012 7:03 AM
                    • 7. Re: Using TLSv1.2 with Java 7
                      EJP
                      No cipher suites in common. The client has called setEnabledCipherSuites() with a list that has zero intersection with what the server has enabled. Looks like Java 7 has removed some. The fix is to review what the client is doing.
                      • 8. Re: Using TLSv1.2 with Java 7
                        852668
                        correct, but I am explicitly setting the cipher to be TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 in both the client and server.


                        It seems as though I pasted some incorrect output above, I think I put the server output up there twice. This is the correct debug. The first 3 lines are output from the client program (client calls getEnabledProtocols & getEnabledCiphers respectively)


                        Client:
                        Enabled Protocol(s): [TLSv1.2]
                        Enabled cipher(s): [TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
                        Text typed in
                        %% No cached client session
                        *** ClientHello, TLSv1.2
                        RandomCookie:  GMT: 1318967123 bytes = { 244, 79, 101, 121, 51, 56, 111, 180, 29, 87, 76, 119, 240, 31, 243, 139, 194, 49, 254, 49, 35, 115, 244, 132, 164, 233, 73, 61 }
                        Session ID:  {}
                        Cipher Suites: [TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
                        Compression Methods:  { 0 }
                        Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
                        Extension renegotiation_info, renegotiated_connection: <empty>
                        ***
                        main, WRITE: TLSv1.2 Handshake, length = 82
                        main, READ: TLSv1.2 Alert, length = 2
                        main, RECV TLSv1 ALERT:  fatal, handshake_failure
                        main, called closeSocket()
                        main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
                        javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
                        Server:
                        main, READ: TLSv1.2 Handshake, length = 82
                        *** ClientHello, TLSv1.2
                        RandomCookie:  GMT: 1318967234 bytes = { 23, 188, 168, 224, 115, 21, 136, 109, 205, 33, 9, 147, 224, 76, 92, 235, 186, 106, 100, 245, 219, 104, 255, 226, 117, 141, 218, 232 }
                        Session ID:  {}
                        Cipher Suites: [TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
                        Compression Methods:  { 0 }
                        Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
                        Extension renegotiation_info, renegotiated_connection: <empty>
                        ***
                        %% Initialized:  [Session-1, SSL_NULL_WITH_NULL_NULL]
                        %% Invalidated:  [Session-1, SSL_NULL_WITH_NULL_NULL]
                        main, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
                        main, WRITE: TLSv1.2 Alert, length = 2
                        main, called closeSocket()
                        main, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
                        javax.net.ssl.SSLHandshakeException: no cipher suites in common
                        Sorry about the mistake above.

                        Edited by: JimM on Apr 30, 2012 11:29 AM
                        • 9. Re: Using TLSv1.2 with Java 7
                          EJP
                          You need to check whether that is still a supported cipher in JDK 1.7. Find the 1.7 JSSE Reference Guide and chase the links through to Appendix A etc.

                          If possible it is best to avoid fiddling with the enabled cipher suites altogether.
                          • 10. Re: Using TLSv1.2 with Java 7
                            852668
                            Hi EJP,
                            Again thanks for the help so far. I have reviewed the Java SSE docs, http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html , and that cipher is listed as an enabled cipher.

                            Believe me, if I could avoid doing this I would but our customers are not making that an option.

                            OK - so lets (kind of) forget the above issue. The second issue I am having is that I seem to have to have a keystore/truststore setup in order for TLSv1.2 to work.

                            Lets say I start the server up using a TLSv1.2 protocol, using the default ciphers, when I send data from the client to the server it bombs out with the same 'no cipher suites in common'

                            However; if i do the exact same thing but specify a keystore/truststore (generating the key/trust store like this "keytool -genkey -keystore mySrvKeystore -keyalg RSA" it works as expected.

                            Here is the smallest example I could write to demonstrate (just the main function)

                            Server:
                                 public static void main(String[] args) {
                                      System.out.println("Java Version: " + System.getProperty("java.version"));
                                      try {
                                           KeyManager[] kmgr = null;
                                           if (args.length > 1) {
                                                System.out.println("Using key file " + args[0] + " with pwd: "
                                                          + args[1]);
                                                KeyManagerFactory kmf = KeyManagerFactory
                                                          .getInstance("SunX509");
                                                KeyStore ks = KeyStore.getInstance("JKS");
                                                // initialize KeyStore object using keystore name
                                                ks.load(new FileInputStream(args[0]), null);
                                                kmf.init(ks, args[1].toCharArray());
                                                kmgr = kmf.getKeyManagers();
                                           }
                            
                                           SSLContext ctx = SSLContext.getInstance("TLSV1.2");
                                           ctx.init(kmgr, null, null);
                                           SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) ctx
                                                     .getServerSocketFactory();
                                           SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
                                                     .createServerSocket(9999);
                                           SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
                            
                                           InputStreamReader inputstreamreader = new InputStreamReader(
                                                     sslsocket.getInputStream());
                                           BufferedReader bufferedreader = new BufferedReader(
                                                     inputstreamreader);
                                           String buf = bufferedreader.readLine();
                                           // Get here client has sent data, echo it out to console and exit
                                           System.out.println("Client said: " + buf);
                                      } catch (Throwable t) {
                                           t.printStackTrace();
                                      }
                                 }
                            Client:
                                 public static void main(String[] args) {
                                      System.out.println("Java Version: " + System.getProperty("java.version"));
                                      try {
                                           TrustManager[] tmgr = null;
                                           if (args.length > 1) {
                                                System.out.println("Using trust file " + args[0]
                                                          + " with pwd: " + args[1]);
                                                TrustManagerFactory tmf = TrustManagerFactory
                                                          .getInstance("SunX509");
                                                KeyStore ts = KeyStore.getInstance("JKS");
                                                // initialize truststore
                                                ts.load(new FileInputStream(args[0]), args[1].toCharArray());
                                                tmf.init(ts);
                                                tmgr = tmf.getTrustManagers();
                            
                                           }
                                           SSLContext ctx = SSLContext.getInstance("TLSV1.2");
                                           ctx.init(null, tmgr, null);
                                           SSLSocketFactory sslsocketfactory = (SSLSocketFactory) ctx
                                                     .getSocketFactory();
                                           SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
                                                     "localhost", 9999);
                                           sslsocket.setEnabledProtocols(new String[] { "TLSv1.2" });
                                           
                                           OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
                                                     sslsocket.getOutputStream());
                                           BufferedWriter bufferedwriter = new BufferedWriter(
                                                     outputstreamwriter);
                                           bufferedwriter.write("Hello Server\n");
                                           bufferedwriter.flush();
                                           
                                      } catch (Throwable t) {
                                           t.printStackTrace();
                                      }
                                 }
                            Can you tell if I am configuring something incorrectly or do we have to have a key/trust store for TLSv1.2 to work?

                            Jim
                            • 11. Re: Using TLSv1.2 with Java 7
                              EJP
                              Apart from inecure 'solutions' which I won't discuss here, JSSE and indeed TLS and SSL themselves have always required at least one peer to be authenticated. This means that that peer must have a private key and certificate in a keystore. By default that peer is the server, but you can turn it around with the API. The certificate must be trusted by the other peer, i.e. by default the client, which means it must be signed by a CA or else self-signed and imported into the client's truststore.
                              • 12. Re: Using TLSv1.2 with Java 7
                                852668
                                Hi EJP,
                                Thanks I had completely forgotten about setting the client up to allow unknown certificates once I added that it worked fine.

                                Again thanks
                                • 13. Re: Using TLSv1.2 with Java 7
                                  wetmore
                                  JSSE server code will iterate over the list of ciphersuites presented by the client. If you have a RSA/DSA-based suite and no RSA/DSA key, that suite is unusable and will have to go to the next one in the list. If it runs out of suites: guess what... "no cipher suites in common"