Hi folks,

I am on Tomcat 6.0.35, Java 6, HP-UX, Tomcat Native 1.1.22.

Recenly, I had to switch my Http11AprProtocol connector to TLSv1 due to a 
security scans in our company.
After that a CLI client with Java's HttpsURLConnection failed to connect to 
that server:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote host 
closed connection during handshake
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at 
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown 
Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown 
Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown 
Source)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at 
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown 
Source)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown 
Source)
        at java.net.HttpURLConnection.getResponseCode(Unknown Source)
        at 
sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown 
Source)
        at com.siemens.smartld.kerberos_request.App.main(App.java:80)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
        ... 10 more

After a short analysis, I have realized that the client sends:
main, WRITE: TLSv1 Handshake, length = 75
main, WRITE: SSLv2 client hello message, length = 101

Since the server does not support any form of SSL, it aborts the handshake. 
After a bit of Goole I found these [1], [2] SO threads saying that this is 
correct due to the RFC to retain backwards compat with older servers.

According to Oracle's docs, this has been dropped in Java 7 [3] and [4]:

Area: API: JSSE
Synopsis: Support for TLS 1.1 has been added to the SunJSSE provider, and the 
SSLv2Hello "pseudo protocol" is no longer active by default in the SunJSSE 
provider.

And

Area: Runtime
Synopsis: The SSLv2Hello Handshake Protocol is Now Disabled by Default
Description: The SSLv2Hello handshake protocol, which was used by SSLv3 server 
implementations to communicate with [...]

Java 7 is not an option here at the moment.

What you can do is to explicitly disable SSLv2Hello message with a system 
property [5] but still, other folks will stumble upon this problem anyway doing 
the same research as I did and waste their time.

I retried the same setup with OpenSSL as in my server.xml:

openssl s_server -cert /etc/opt/ssl/cert/server.crt \
-key /etc/opt/ssl/key/server.key -tls1 -cipher HIGH

Fails just as same as Tomcat. Though adding -ssl3 fails too.
To alleviate this issue for the Java client, I have patched Tomcat to allow 
SSLv3+TLSv1 [6] to make both work, the connection does not fail anymore.

Now, according to the citation in this SO answer [7] my question is: Should 
Tomcat ignore the SSLv2Hello wrapped compat message (which is a actually a 
SSLv3/TLSv1 version message according to Wireshark) and continue with the TLSv1 
handshake?

Shall I presume that both OpenSSL s_server and Tomcat are incorrect or is this 
some inconsistency in the RFC?

[1] 
http://stackoverflow.com/questions/10196436/ssl-handshaking-with-older-clients-using-sslengine-jsse
[2] 
http://stackoverflow.com/questions/4682957/why-does-javas-sslsocket-send-a-version-2-client-hello
[3] http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
[4] http://www.oracle.com/technetwork/java/javase/compatibility-417013.html
[5] 
http://docs.oracle.com/javase/1.4.2/docs/guide/plugin/developer_guide/faq/troubleshooting.html
[6] https://issues.apache.org/bugzilla/show_bug.cgi?id=53344
[7] http://stackoverflow.com/a/10198268/696632

With best regards,
Michael Osipov

Reply via email to