Search code examples
javassl-certificateelliptic-curvesslhandshakeexception

Recent Java upgrade causes TLS handshake failure with elliptic curve server certificate?


On October 19th, I upgraded to OpenJDK Java 1.8.0_232 and my Java processes started failing to connect to a service fronted by stunnel using an EC server certificate. I have an EC client certificate that I would present to the server if the initial handshake would succeed, but it's not getting that far.

I was unable to obtain the version number of the previous version of Java that was running -- I had a long-running process on the client that was able to connect to the service successfully. Java has been upgraded but that client hadn't been restarted since the upgrade. I restarted the client and it, too, began to fail.

I'm about to start reading the announcement to see if there is anything in there that would suggest a "fix" to something, but I believe I have everything configured correctly on both client and server. My current thinking is that this is a bug in the JVM.

Using ssltest, I have been able to confirm that I can handshake with the server using multiple cipher suites when providing the correct client certificate, as long as I use Java 1.8.0_181 or Java 11.0.3 (these are the two versions I happened to have laying around on my laptop for testing). Using the same files, command-line, etc. fails when using Java 1.8.0_232.

Has anyone seen anything like this?

UPDATE

I have downloaded x86-64 OpenJDK versions 8u222 and 8u232 from here and I can confirm that version 8u222 will connect and 8u232 will not connect.

UPDATE Downgrading to the previous version of OpenJDK has solved my problem for the time being. I'm using Debian Stretch, and I was able to downgrade with this command:

$ sudo apt-get install openjdk-8-jdk-headless=8u222-b10-1~deb9u1 openjdk-8-jre-headless=8u222-b10-1~deb9u1

Note that I only have the "headless" packages installed, so I only downgraded the "headless" packages.

UPDATE I can confirm that the client certificate is a red herring, here. I relaxed the requirements on my server to not require the client certificate and the initial TLS handshake still fails. I'm trying to narrow this down to the simplest test case I can get.

UPDATE Still trying to diagnose the problem, here. I have a test server where I can launch it under various configurations and see what happens. I have determined that while Java 8u222 supports the secp256k1 curve, Java 8u232 does not, and I get the handshake failure.


Solution

  • The secp256k1 curve has been disabled with jdk 8u232 (see https://java.com/en/download/faq/release_changes.xml). It can be re-enabled with the java system property jdk.tls.namedGroups.

    The example on the faq lists a few other Obsolete NIST EC Curves that are disabled as well. The curves listed there are sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1 and secp256k1. The system property jdk.tls.namedGroups takes a comma separated list of those names.