Tomcat with APR connector is disconnecting Java clients with SSL -


i trying use ssl tomcat , apr connector. can make changes server, not existing java client.

for reason, whenever java client connects tomcat server using ssl, not able connect - connection reset server. however, exact same java code can connect same server on different port hosted apache ssl. in addition, non-java code (like curl) can connect tomcat ssl connection.

i have gotten work forcing java client use tlsv1 protocol (-dhttps.protocols=tlsv1). however, not practical solution, because cannot release update @ time our java clients.

since works apache on server, seems me should able make sort of configuration change on server work tomcat, without needing change java clients.

in summary: java connecting tomcat ssl = fail

curl connecting tomcat ssl = good

java connecting apache ssl = good

curl connecting apache ssl = good

here example java code illustrates problem. i'm running java 6 on mac os x.

public class sslconnecttest {     public static void main(string[] args) throws exception {         system.setproperty( "javax.net.debug", "all" );          testconnection( "https://secure2.360works.com" ); //apache running ssl. works.         testconnection( "https://secure2.360works.com:8443/" ); //tomcat running ssl , apr. fails.     }      private static void testconnection( string urlstring ) throws ioexception {         new url( urlstring ).openstream().close();     } } 

here happens in ssl handshake:

trigger seeding of securerandom done seeding securerandom allow unsafe renegotiation: false allow legacy hello messages: true initial handshake: true secure renegotiation: false %% no cached client session *** clienthello, tlsv1 randomcookie:  gmt: 1377233856 bytes = { 69, 128, 29, 114, 252, 186, 13, 192, 212, 243, 179, 208, 124, 196, 220, 137, 23, 124, 30, 226, 98, 148, 243, 6, 188, 230, 109, 119 } session id:  {} cipher suites: [ssl_rsa_with_rc4_128_md5, ssl_rsa_with_rc4_128_sha, tls_rsa_with_aes_128_cbc_sha, tls_rsa_with_aes_256_cbc_sha, tls_dhe_rsa_with_aes_128_cbc_sha, tls_dhe_rsa_with_aes_256_cbc_sha, tls_dhe_dss_with_aes_128_cbc_sha, tls_dhe_dss_with_aes_256_cbc_sha, ssl_rsa_with_3des_ede_cbc_sha, ssl_dhe_rsa_with_3des_ede_cbc_sha, ssl_dhe_dss_with_3des_ede_cbc_sha, ssl_rsa_with_des_cbc_sha, ssl_dhe_rsa_with_des_cbc_sha, ssl_dhe_dss_with_des_cbc_sha, ssl_rsa_export_with_rc4_40_md5, ssl_rsa_export_with_des40_cbc_sha, ssl_dhe_rsa_export_with_des40_cbc_sha, ssl_dhe_dss_export_with_des40_cbc_sha, tls_empty_renegotiation_info_scsv] compression methods:  { 0 } *** main, write: tlsv1 handshake, length = 81 main, write: sslv2 client hello message, length = 110 main, handling exception: java.net.socketexception: connection reset main, send tlsv1 alert:  fatal, description = unexpected_message main, write: tlsv1 alert, length = 2 main, exception sending alert: java.net.socketexception: broken pipe main, called closesocket() disconnected target vm, address: '127.0.0.1:62146', transport: 'socket' exception in thread "main" java.net.socketexception: connection reset     @ java.net.socketinputstream.read(socketinputstream.java:168)     @ com.sun.net.ssl.internal.ssl.inputrecord.readfully(inputrecord.java:422)     @ com.sun.net.ssl.internal.ssl.inputrecord.read(inputrecord.java:460)     @ com.sun.net.ssl.internal.ssl.sslsocketimpl.readrecord(sslsocketimpl.java:863)     @ com.sun.net.ssl.internal.ssl.sslsocketimpl.performinitialhandshake(sslsocketimpl.java:1188)     @ com.sun.net.ssl.internal.ssl.sslsocketimpl.starthandshake(sslsocketimpl.java:1215)     @ com.sun.net.ssl.internal.ssl.sslsocketimpl.starthandshake(sslsocketimpl.java:1199)     @ sun.net.www.protocol.https.httpsclient.afterconnect(httpsclient.java:434)     @ sun.net.www.protocol.https.abstractdelegatehttpsurlconnection.connect(abstractdelegatehttpsurlconnection.java:166)     @ sun.net.www.protocol.http.httpurlconnection.getinputstream(httpurlconnection.java:1172)     @ sun.net.www.protocol.https.httpsurlconnectionimpl.getinputstream(httpsurlconnectionimpl.java:234)     @ java.net.url.openstream(url.java:1010)     @ com.prosc.license.client.network.sslconnecttest.testconnection(sslconnecttest.java:22)     @ com.prosc.license.client.network.sslconnecttest.main(sslconnecttest.java:18) 

here connector configuration in server.xml. i'm hoping change here fix problem:

<connector port="8443" sslenabled="true" maxthreads="150" scheme="https" secure="true" sslprotocol="sslv2+tlsv1+sslv3" sslhonorcipherorder="true" protocol="org.apache.coyote.http11.http11aprprotocol" clientauth="false" sslcertificatefile="/etc/apache2/ssl.crt/secure2.360works.com.crt" sslcertificatekeyfile="/etc/apache2/ssl.crt/secure2.360works.com.key" sslcertificatechainfile="/etc/apache2/ssl.crt/secure2.360works.com.chcrt" /> 

main, write: tlsv1 handshake, length = 81 main, write: sslv2 client hello message, length = 110 

i presume coming java 6 environment (unless client has explicitly enabled sslv2hello protocol). have tried see if client able connect when run on java 7 jre (which doesn't enable sslv2hello default).

i guess problem happens because apr connector might not receiving sslv2 client hello (which, coming java, isn't sslv2 client hello, v3 wrapped v2, see ejp's answer).

a couple of suggestions may fix this:

  • try make apr accept sslv2 connections, @ least sslv3 or above wrapped v2 hello. (using sslv2 isn't idea, sslv2hello sslv3/tls shouldn't problem.)
  • switch apr in apache tomcat pure java connector (bio or nio, see comparative table). might need convert certificate , key keystore, shouldn't difficult, pkcs12 keystore.

Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -