DraxDomax
DraxDomax

Reputation: 1068

How to implement a partial SSL handshake to test arbitrary cipher suites?

The "server" needs to be tested to make sure it does not include a specific cipher suite, which sometimes, despite our developer's best intentions, still occasionally makes it into the server.

However:

(= we have to roll our own, using standard Java 8)

Furthermore, we are not interested to test just the cipher suites that the test client has installed but "any" cipher suite that will be provided as arbitrary text.

I found online (OpenSSL Cookbook by Ivan Ristić):

For SSL Labs, I resorted to using partial handshakes for this purpose, with a custom client that pretends to support arbitrary suites. It actually can’t negotiate even a single suite, but just proposing to negotiate is enough for servers to tell you if they support a suite or not. Not only can you test all the suites this way, but you can also do it very efficiently.

This custom client sounds ideal for our purposes now and will be useful for similar SSL tests in the future - but I don't know what a "partial handshake" or "propose to negotiate" looks like in Java-8's SSL Sockets code. My best effort is the following:

String[] enabledSuites = {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"};
mySocket.setEnabledCipherSuites(enabledSuites);
mySocket.startHandshake();

The suite mentioned above works, because the client has it and the server allows it. However, when I try "MY_SUITE", the code stops at setEnabledCipherSuites() with: Unsupported CipherSuite: MY_SUITE
Which, to me, means the client didn't even try this, because it's not part of the list shown when doing getSupportedCipherSuites()

So, can a partial handshake be even implemented in Java 8 (without rewriting all the extra code that's on top of Socket)?

Upvotes: 0

Views: 401

Answers (1)

Christopher Schultz
Christopher Schultz

Reputation: 20862

You may be interested in this project which I think includes all the code you might want for this type of thing:

https://github.com/ChristopherSchultz/ssltest

When you say a "partial handshake" I think what you mean is that you want to probe the server for support for a specific protocol/cipher suite pair (or group, etc.). You can use an SSLSocket for this purpose, and you don't need to make e.g. an HTTPS connection and actually perform a transaction.

In order to get anything but the JVM default protocols and ciphers, you'll need to supply your own SSLSocketFactory which customizes an SSLSocket as it's being created / connected. That code is in the CustomSSLSocketFactory class in the above project, and of course there is code in there showing how to use it.

Remember that the JVM has a group of cipher suites and protocols that have been implemented, but many of them have been disabled over the years and you may have to take steps to re-enable them. The code in this project sets system properties immediately after startup in order to remove as many restrictions as possible. That may not be possible (or advisable!) in your environment because you don't want to allow "regular code" to use these insecure algorithms and protocols.

Upvotes: 1

Related Questions