eak12913
eak12913

Reputation: 303

Java 8 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated, but not Java 7

I have an issue when switching my application from Java 7 to Java 8. After changing the JDK I start getting this SSLPeerUnverified Exception. Changing back to Java7, there is no exception.

I found this question: SSL connection failing for Java 7 which implies that this may be related to a server side issue. Our server is indeed running on an Ubuntu machine, but it is running Java8 as well (sun Java8)

Not sure what else would be helpful to post. I can provide code samples if needed/useful. I didn't incude them now because it appears as though the code is not the issue.

Edit - link to my extension of SSLSocketFactory: http://pastebin.com/2j6HDHE7

Edit2 - Http client code:

    private HttpClient getHttpClient() throws GeneralSecurityException, IOException {
        final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());

        trustStore.load(CommandChannel.class.getResourceAsStream("myKeystore"), "myPassword".toCharArray());

        final SSLSocketFactory sslSocketFactory = new TrustingSSLSocketFactory(trustStore);

        final SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
        registry.register(new Scheme("https", 443, sslSocketFactory));

        final HttpParams params = new BasicHttpParams();
        HttpProtocolParamBean paramsBean = new HttpProtocolParamBean(params);
        paramsBean.setVersion(HttpVersion.HTTP_1_1);
        paramsBean.setContentCharset("UTF_8");

        final ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
        final DefaultHttpClient httpClient = new DefaultHttpClient(ccm, params);

        return httpClient;
    }

Including the SSL-debug information from java8 & java7 below.

Java 8 SSL debug trace:

%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1389745002 bytes = { 220, 201, 110, 4, 38, 166, 25, 166, 235, 253, 71, 242, 226, 124, 22, 149, 28, 207, 242, 25, 201, 123, 218, 56, 207, 67, 195, 17 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_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_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
JavaFX Application Thread, WRITE: TLSv1.2 Handshake, length = 207
JavaFX Application Thread, received EOFException: error
JavaFX Application Thread, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
JavaFX Application Thread, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
JavaFX Application Thread, WRITE: TLSv1.2 Alert, length = 2
JavaFX Application Thread, called closeSocket()
JavaFX Application Thread, IOException in getSession():  javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
JavaFX Application Thread, called close()
JavaFX Application Thread, called closeInternal(true)
JavaFX Application Thread, called close()
JavaFX Application Thread, called closeInternal(true)
18:49:14,951 ERROR [logger] [LoginController] Error logging in due to: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
com.limebrokerage.portal.communication.command.CommandChannelException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

Java 7 SSL debug trace of the same bit of code:

%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1389746267 bytes = { 91, 88, 192, 29, 58, 48, 211, 105, 40, 40, 138, 204, 154, 113, 233, 213, 120, 99, 3, 223, 26, 233, 123, 150, 251, 245, 186, 246 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_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_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
JavaFX Application Thread, WRITE: TLSv1 Handshake, length = 149
JavaFX Application Thread, READ: TLSv1 Handshake, length = 74
*** ServerHello, TLSv1
RandomCookie:  GMT: 1389746267 bytes = { 179, 44, 184, 192, 189, 56, 33, 48, 248, 204, 248, 129, 1, 214, 77, 185, 206, 200, 3, 148, 58, 49, 98, 42, 213, 229, 106, 218 }
Session ID:  {83, 214, 216, 91, 179, 44, 184, 192, 189, 56, 33, 48, 248, 204, 248, 129, 1, 214, 77, 185, 206, 200, 3, 148, 58, 49, 98, 42, 213, 229, 106, 218}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
***
Warning: No renegotiation indication extension in ServerHello
%% Initialized:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
JavaFX Application Thread, READ: TLSv1 Handshake, length = 1522
*** Certificate chain
chain [0] = [
[
  Version: V3

Upvotes: 4

Views: 8894

Answers (1)

dave_thompson_085
dave_thompson_085

Reputation: 38821

Not for sure an answer, but too long for a comment.

Your real problem is the server disconnect on hello and resulting SSLHandshakeException; SSLPeerUnverifiedException is collateral damage because the handshake didn't reach the authentication stage. The obvious difference is that Java 8 is sending TLSv1.2 ClientHello where Java 7 sent TLSv1.

Java 7 implemented 1.1 and 1.2, but didn't enable them on client by default; 8 does, see https://bugs.openjdk.java.net/browse/JDK-7093640 . A correctly written server stack that doesn't support 1.2 should negotiate down to 1.1 or 1(.0), but your unidentified server apparently doesn't, or possibly something in-between like a firewall is messing up your connection. If you have or get OpenSSL, commandline openssl s_client will let you easily try different versions (and ciphers and some options) to see what does and does not work. Or you could have https://www.ssllabs.com/ssltest/ do their canned but fairly thorough tests.

The bug entry says you can set sysprop jdk.tls.client.protocols and that works for me in a minimal SSLSocket (not HTTP) app on 8u05. Or since you're already doing a modified SSLSocketFactory, I expect you could do setEnabledProtocols on the sockets you create.

FWIW, when OpenSSL release 1.0.1 in March 2012 "silently" turned on protocols 1.1 and 1.2 (it was prominent in the release notes, but approximately nobody reads release notes), the support list got lots of complaints, I'd guess over a hundred total, of servers that suddenly started failing, crashing, or hanging until clients reverted to 1.0. OpenSSL ended up implementing a workaround that can artificially decrease or increase some data in the ClientHello to avoid the most "provocative" sizes; I don't know if JSSE does or can do something similar.

Upvotes: 5

Related Questions