Tomcat 7 getting SSLv2Hello is disabled error when trying to make client server ssl authntication

17,699

You should probably not do this (please, just let SSL die!), but you can enable the SSLv2Hello protocol for clients using this shockingly obvious technique:

-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2,SSLv2Hello

As for the server, Tomcat configures its own SSL endpoint(s) using the sslProtocol and sslEnabledProtocols configuration settings. you should use those on the server side. For example:

<Connector
 sslProtocol="TLS"
 sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2,SSLv2Hello"
 ...
 />

You can find out more information about how to diagnose SSL/TLS issues on Oracle's blog about the subject.

Share:
17,699
user63898
Author by

user63898

developer

Updated on June 09, 2022

Comments

  • user63898
    user63898 almost 2 years

    I have tried to setup a self-signed TLS configuration for both client and server where the server is Tomcat 7 and the client is Apache httpclient 4.1. The server configuration is taken from this here and the client code is taken from here.

    My tomcat configuration looks like this:

     <Connector clientAuth="true" port="8443" minSpareThreads="5" maxSpareThreads="75"
               enableLookups="true" disableUploadTimeout="true"
               acceptCount="100" maxThreads="200"
               scheme="https" secure="true" SSLEnabled="true"
               keystoreFile="keys/server.jks" keystoreType="JKS" keystorePass="password"
               truststoreFile="keys/server.jks" truststoreType="JKS" truststorePass="password"
               SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2"
               sslProtocol="TLS" />
    

    My client code looks like this:

    final HttpParams httpParams = new BasicHttpParams();
    
    // load the keystore containing the client certificate - keystore type is probably jks or pkcs12
    final KeyStore keystore = KeyStore.getInstance("pkcs12");
    FileInputStream keystoreInput =  = new FileInputStream("d:/dev/java/conf/keys/client.p12");;
    // TODO get the keystore as an InputStream from somewhere
    keystore.load(keystoreInput, "password".toCharArray());
    
    // load the trustore, leave it null to rely on cacerts distributed with the JVM - truststore type is probably jks or pkcs12
    KeyStore truststore = KeyStore.getInstance("JKS");
    FileInputStream truststoreInput =  = new FileInputStream("d:/dev/java/conf/keys/client.jks");;
    // TODO get the trustore as an InputStream from somewhere
    truststore.load(truststoreInput, "password".toCharArray());
    
    final SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("https", new SSLSocketFactory(keystore, keystorePassword, truststore), 443));
    
    final DefaultHttpClient httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, schemeRegistry), httpParams);
    

    I launch Tomcat with the following CATALINA_OPTS:

    set CATALINA_OPTS=%CATALINA_OPTS% -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2  
    set CATALINA_OPTS=%CATALINA_OPTS% -Djavax.net.debug=all
    

    When launching, Tomcat gives me these errors in the log file:

    INFO: Starting ProtocolHandler ["http-bio-8080"]
    Oct 21, 2014 3:46:54 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["http-bio-8443"]
    Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    Oct 21, 2014 3:46:54 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["ajp-bio-8009"]
    Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
    Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
    Oct 21, 2014 3:46:54 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 3060 ms
    Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
    Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
    Allow unsafe renegotiation: false
    Allow legacy hello messages: true
    Is initial handshake: true
    Is secure renegotiation: false
    http-bio-8443-Acceptor-0, setSoTimeout(60000) called
    Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
    Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
    Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
    Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
    Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
    Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
    [Raw read]: length = 5
    0000: 80 65 01 03 01                                     .e...
    http-bio-8443-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled
    http-bio-8443-exec-1, SEND TLSv1 ALERT:  fatal, description = handshake_failure
    http-bio-8443-exec-1, WRITE: TLSv1 Alert, length = 2
    [Raw write]: length = 7
    0000: 15 03 01 00 02 02 28                               ......(
    http-bio-8443-exec-1, called closeSocket()
    http-bio-8443-exec-1, IOException in getSession():  javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled
    http-bio-8443-exec-1, called close()
    http-bio-8443-exec-1, called closeInternal(true)
    

    Why is SSLv2Hello disabled and how can I enable it?

    I'm launching the client with this configuration:

    -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djavax.net.debug=all
    

    Here is what httpclient logs when trying to connect to the server:

    adding as trusted cert:
      Subject: CN=GTE CyberTrust Root 5, OU="GTE CyberTrust Solutions, Inc.", O=GTE Corporation, C=US
      Issuer:  CN=GTE CyberTrust Root 5, OU="GTE CyberTrust Solutions, Inc.", O=GTE Corporation, C=US
      Algorithm: RSA; Serial number: 0x1b6
      Valid from Fri Aug 14 17:50:00 IDT 1998 until Thu Aug 15 02:59:00 IDT 2013
    
    adding as trusted cert:
      Subject: CN=UTN-USERFirst-Object, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, ST=UT, C=US
      Issuer:  CN=UTN-USERFirst-Object, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, ST=UT, C=US
      Algorithm: RSA; Serial number: 0x44be0c8b500024b411d3362de0b35f1b
      Valid from Fri Jul 09 21:31:20 IDT 1999 until Tue Jul 09 21:40:36 IDT 2019
    
    adding as trusted cert:
      Subject: CN=UTN - DATACorp SGC, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, ST=UT, C=US
      Issuer:  CN=UTN - DATACorp SGC, OU=http://www.usertrust.com, O=The USERTRUST Network, L=Salt Lake City, ST=UT, C=US
      Algorithm: RSA; Serial number: 0x44be0c8b500021b411d32a6806a9ad69
      Valid from Thu Jun 24 21:57:21 IDT 1999 until Mon Jun 24 22:06:30 IDT 2019
    
    adding as trusted cert:
      Subject: CN=Sonera Class2 CA, O=Sonera, C=FI
      Issuer:  CN=Sonera Class2 CA, O=Sonera, C=FI
      Algorithm: RSA; Serial number: 0x1d
      Valid from Fri Apr 06 09:29:40 IST 2001 until Tue Apr 06 10:29:40 IDT 2021
    
    adding as trusted cert:
      Subject: CN=TC TrustCenter Class 2 CA II, OU=TC TrustCenter Class 2 CA, O=TC TrustCenter GmbH, C=DE
      Issuer:  CN=TC TrustCenter Class 2 CA II, OU=TC TrustCenter Class 2 CA, O=TC TrustCenter GmbH, C=DE
      Algorithm: RSA; Serial number: 0x2e6a000100021fd752212c115c3b
      Valid from Thu Jan 12 16:38:43 IST 2006 until Thu Jan 01 00:59:59 IST 2026
    
    trigger seeding of SecureRandom
    done seeding SecureRandom
    2014-10-21 16:36:15,296 pool-1-thread-1 DEBUG [SingleClientConnManager] Get connection for route HttpRoute[{s}->https://127.0.0.1:8443]
     2014-10-21 16:36:15,316 pool-1-thread-1 DEBUG [DefaultClientConnectionOperator] Connecting to /127.0.0.1:8443
     pool-1-thread-1, setSoTimeout(500000) called
    Allow unsafe renegotiation: false
    Allow legacy hello messages: true
    Is initial handshake: true
    Is secure renegotiation: false
    %% No cached client session
    *** ClientHello, TLSv1
    RandomCookie:  GMT: 1413902175 bytes = { 166, 163, 15, 231, 223, 206, 71, 224, 11, 205, 126, 133, 216, 162, 9, 70, 183, 228, 17, 4, 187, 149, 177, 90, 209, 175, 23, 186 }
    Session ID:  {}
    Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_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 }
    ***
    [write] MD5 and SHA1 hashes:  len = 75
    0000: 01 00 00 47 03 01 54 46   6F 5F A6 A3 0F E7 DF CE  ...G..TFo_......
    0010: 47 E0 0B CD 7E 85 D8 A2   09 46 B7 E4 11 04 BB 95  G........F......
    0020: B1 5A D1 AF 17 BA 00 00   20 00 04 00 05 00 2F 00  .Z...... ...../.
    0030: 33 00 32 00 0A 00 16 00   13 00 09 00 15 00 12 00  3.2.............
    0040: 03 00 08 00 14 00 11 00   FF 01 00                 ...........
    pool-1-thread-1, WRITE: TLSv1 Handshake, length = 75
    [write] MD5 and SHA1 hashes:  len = 101
    0000: 01 03 01 00 3C 00 00 00   20 00 00 04 01 00 80 00  ....<... .......
    0010: 00 05 00 00 2F 00 00 33   00 00 32 00 00 0A 07 00  ..../..3..2.....
    0020: C0 00 00 16 00 00 13 00   00 09 06 00 40 00 00 15  ............@...
    0030: 00 00 12 00 00 03 02 00   80 00 00 08 00 00 14 00  ................
    0040: 00 11 00 00 FF 54 46 6F   5F A6 A3 0F E7 DF CE 47  .....TFo_......G
    0050: E0 0B CD 7E 85 D8 A2 09   46 B7 E4 11 04 BB 95 B1  ........F.......
    0060: 5A D1 AF 17 BA                                     Z....
    pool-1-thread-1, WRITE: SSLv2 client hello message, length = 101
    [Raw write]: length = 103
    0000: 80 65 01 03 01 00 3C 00   00 00 20 00 00 04 01 00  .e....<... .....
    0010: 80 00 00 05 00 00 2F 00   00 33 00 00 32 00 00 0A  ....../..3..2...
    0020: 07 00 C0 00 00 16 00 00   13 00 00 09 06 00 40 00  ..............@.
    0030: 00 15 00 00 12 00 00 03   02 00 80 00 00 08 00 00  ................
    0040: 14 00 00 11 00 00 FF 54   46 6F 5F A6 A3 0F E7 DF  .......TFo_.....
    0050: CE 47 E0 0B CD 7E 85 D8   A2 09 46 B7 E4 11 04 BB  .G........F.....
    0060: 95 B1 5A D1 AF 17 BA                               ..Z....
    [Raw read]: length = 5
    0000: 15 03 01 00 02                                     .....
    [Raw read]: length = 2
    0000: 02 28                                              .(
    pool-1-thread-1, READ: TLSv1 Alert, length = 2
    pool-1-thread-1, RECV TLSv1 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
    pool-1-thread-1, IOException in getSession():  javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    pool-1-thread-1, called close()
    pool-1-thread-1, called closeInternal(true)
    2014-10-21 16:36:15,336 pool-1-thread-1 DEBUG [DefaultClientConnection] Connection closed
     2014-10-21 16:36:15,336 pool-1-thread-1 DEBUG [HttpClientImpl] retry count:1
     2014-10-21 16:36:15,336 pool-1-thread-1 DEBUG [DefaultClientConnection] Connection shut down
     pool-1-thread-1, called close()
    pool-1-thread-1, called closeInternal(true)
    2014-10-21 16:36:15,336 pool-1-thread-1 DEBUG [SingleClientConnManager] Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@1a73d30
     Exception postHttpReqest function from http client :javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    Threads done working
    

    Does anyone know why I can't connect my client to me server?