5

I have some code that's been working for a long time that gets data from webapps over HTTP. It uses Apache HTTPClient (v. 4.5.2) and works great for sites with and without SSL.

Recently, I've tried to use if for another site that happens to use SNI. Everything works great on my Windows machine, but if I try to run it on an AWS EC2 Linux instance, I get a handshake failure (because of the SNI).

Here's what I'm running:

Windows Java

  • java version "1.8.0_101"
  • Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
  • Java HotSpot(TM) Client VM (build 25.101-b13, mixed mode, sharing)

AWS Linux Java

  • openjdk version "1.8.0_91"
  • OpenJDK Runtime Environment (build 1.8.0_91-b14)
  • OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

I'm not sure which component is ultimately responsible for the failure (Java 8, the runtime environment, HTTPClient).

I have seen this (https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#SNIExtension), but I'm not sure how to adapt this for HTTPClient. And besides, if I had to make code changes, why would it work on Windows?

Anyone have any idea what I should do?

Edit: As suggested, I looked into the jsse.enableSNIExtension property. This seemed wrong because it looks like it's a way to turn SSL off which isn't what I want.

I tried it turned on/off on Windows, and things only worked with it on. On Linux, when it was turned on I continue to get a handshake failure.

Here's the output:

Windows - System.setProperty("jsse.enableSNIExtension", "false");
=================================================================

pool-1-thread-1, WRITE: TLSv1.2 Handshake, length = 189
pool-1-thread-1, READ: TLSv1.2 Alert, length = 2
pool-1-thread-1, RECV TLSv1.2 ALERT:  fatal, internal_error
pool-1-thread-1, called closeSocket()
pool-1-thread-1, handling exception: javax.net.ssl.SSLException: Received fatal alert: internal_error


Windows - System.setProperty("jsse.enableSNIExtension", "true");
================================================================

pool-1-thread-1, WRITE: TLSv1.2 Handshake, length = 215
pool-1-thread-1, READ: TLSv1.2 Handshake, length = 93
*** ServerHello, TLSv1.2


Linux - System.setProperty("jsse.enableSNIExtension", "true");
==============================================================

pool-1-thread-1, WRITE: TLSv1.2 Handshake, length = 143
pool-1-thread-1, READ: TLSv1.2 Alert, length = 2
pool-1-thread-1, RECV TLSv1.2 ALERT:  fatal, handshake_failure
pool-1-thread-1, called closeSocket()
pool-1-thread-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
David Soroko
  • 6,773
  • 28
  • 39
Sander Smith
  • 1,243
  • 1
  • 19
  • 27
  • Have you tried to use the debugger option : `java -Djavax.net.debug=all MyApp` Also https://stackoverflow.com/q/6353849/1140748 contains a lot of clues for this kind of issue. – alain.janinm Dec 14 '18 at 10:51

2 Answers2

0

In our case the root cause was that the (Java) client and the server could not agree on a sufficently strong cipher suite. The solution was to install "Unlimited Strength JCE" from https://www.oracle.com/technetwork/java/javase/downloads/jce-all-download-5170447.html

This should not be a problem for Java version >= 1.8.0_161

David Soroko
  • 6,773
  • 28
  • 39
-1

I had the same issue, not sure if you are allowed to do this or if you noticed this in the documentation but I added the option -Djsse.enableSNIExtension=false and it worked for me.

jiveturkey
  • 2,301
  • 17
  • 37
  • Nope, in fact turning this property off makes Windows not work also. See the edit on the original post. The irony here is that I don't even care about SSL here, but am forced to use it because that's what this webapp uses. – Sander Smith Aug 05 '16 at 18:54