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