Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8172163

ClientAuth failure is SocketException instead of SSLHandshakeException

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "9-ea"
      Java(TM) SE Runtime Environment (build 9-ea+149)
      Java HotSpot(TM) 64-Bit Server VM (build 9-ea+149, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Darwin iMac.local 16.3.0 Darwin Kernel Version 16.3.0: Thu Nov 17 20:23:58 PST 2016; root:xnu-3789.31.2~1/RELEASE_X86_64 x86_64

      A DESCRIPTION OF THE PROBLEM :
      In Java 7+8 a failed TLS connection because of missing but required client auth throws a SSLHandshakeException.

      In Java 9 it comes as a SocketException

      REGRESSION. Last worked in version 8u112

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      git clone https://github.com/square/okhttp

      comment out lines 166, 189 e.g.

          } catch (SSLHandshakeException expected) {
      // } catch (SocketException expected) {
            // JDK 9



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      SSLHandshakeException
      ACTUAL -
      invalidClientAuthFails(okhttp3.internal.tls.ClientAuthTest) Time elapsed: 2.868 sec <<< ERROR!
      java.net.SocketException: Broken pipe (Write failed)
      at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
      at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
      at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:153)
      at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:236)
      at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:79)
      at java.base/sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1171)
      at java.base/sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1336)
      at java.base/sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1240)
      at java.base/sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:414)
      at java.base/sun.security.ssl.Handshaker.processLoop(Handshaker.java:1061)
      at java.base/sun.security.ssl.Handshaker.processRecord(Handshaker.java:995)
      at java.base/sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1132)
      at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1069)
      at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:968)
      at java.base/sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1395)
      at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1422)
      at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1406)
      at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:242)
      at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:200)
      at okhttp3.internal.connection.RealConnection.buildConnection(RealConnection.java:174)
      at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:114)
      at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:196)
      at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:132)
      at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:101)
      at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
      at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
      at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
      at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
      at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
      at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:179)
      at okhttp3.RealCall.execute(RealCall.java:63)
      at okhttp3.internal.tls.ClientAuthTest.invalidClientAuthFails(ClientAuthTest.java:186)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :


      MockWebServer /127.0.0.1:59342, READ: TLSv1.2 Handshake, length = 77
      check handshake state: certificate[11]
      update handshake state: certificate[11]
      upcoming handshake states: client_key_exchange[16]
      upcoming handshake states: certificate_verify[15](optional)
      upcoming handshake states: client change_cipher_spec[-1]
      upcoming handshake states: client finished[20]
      upcoming handshake states: server change_cipher_spec[-1]
      upcoming handshake states: server finished[20]
      *** Certificate chain
      <Empty>
      ***
      %% Invalidated: [Session-2, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
      MockWebServer /127.0.0.1:59342, SEND TLSv1.2 ALERT: fatal, description = bad_certificate
      MockWebServer /127.0.0.1:59342, WRITE: TLSv1.2 Alert, length = 2
      [Raw write]: length = 7
      0000: 15 03 03 00 02 02 2A ......*
      MockWebServer /127.0.0.1:59342, called closeSocket()
      MockWebServer /127.0.0.1:59342, handling exception: javax.net.ssl.SSLHandshakeException: null cert chain
      [Raw write]: length = 82
      0000: 16 03 03 00 4D 0B 00 00 03 00 00 00 10 00 00 42 ....M..........B
      0010: 41 04 C4 E4 8B 28 D1 79 6F 82 E8 BD E2 8A 5D 48 A....(.yo.....]H
      0020: 37 E3 3F B7 88 5B 86 A3 E7 02 C6 3D BA 2A 34 F0 7.?..[.....=.*4.
      0030: 2D 9C 69 41 D3 ED D8 41 E8 DA A6 2C 99 FE 05 95 -.iA...A...,....
      0040: CB 9F 6D E5 3F 23 12 57 87 82 49 8D 1A AB D1 E3 ..m.?#.W..I.....
      0050: 6D 03 m.
      Dec 27, 2016 8:54:05 AM okhttp3.mockwebserver.MockWebServer$4 execute
      INFO: MockWebServer[59341] connection from /127.0.0.1 failed: javax.net.ssl.SSLHandshakeException: null cert chain
      SESSION KEYGEN:
      PreMaster Secret:
      0000: CC 90 1C B4 E4 6B D1 27 9F A6 88 28 6C 1B 7A 43 .....k.'...(l.zC
      0010: 79 B4 2E 6B F4 F5 F1 4A CC E5 48 FC 51 3F E7 20 y..k...J..H.Q?.
      CONNECTION KEYGEN:
      Client Nonce:
      0000: 15 D6 8C D7 E9 DE C9 AB 77 A9 5B 17 00 25 39 FB ........w.[..%9.
      0010: 38 B0 BF AB 4D 91 59 EA 40 35 B5 D2 95 79 51 35 8...M.Y.@5...yQ5
      Server Nonce:
      0000: 22 8A 16 72 47 79 8C 24 52 F9 4E 7D 88 E5 A2 FA "..rGy.$R.N.....
      0010: 4E 33 0B 34 3E DC D0 4C EF A4 63 A7 EB 04 6A A8 N3.4>..L..c...j.
      Master Secret:
      0000: 1B 6A FB CC 1B B2 56 4A 6A 40 44 35 58 C4 70 35 .j....VJj@D5X.p5
      0010: 51 A4 C5 9D 7E A5 F9 11 33 16 66 2C 12 3A 3B AF Q.......3.f,.:;.
      0020: 4E D6 3F 24 80 F1 E4 49 E5 BD 56 AF 7E 12 BF 82 N.?$...I..V.....
      ... no MAC keys used for this cipher
      Client write key:
      0000: 69 D7 94 D9 47 28 A6 DC 5B 33 B6 50 54 AA 87 D9 i...G(..[3.PT...
      Server write key:
      0000: 0B 97 5F A7 F8 6C 62 D1 F9 66 41 CF F9 13 51 84 .._..lb..fA...Q.
      Client write IV:
      0000: BD 24 36 3D .$6=
      Server write IV:
      0000: 2A E7 AF EE *...
      update handshake state: change_cipher_spec
      upcoming handshake states: client finished[20]
      upcoming handshake states: server change_cipher_spec[-1]
      upcoming handshake states: server finished[20]
      main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
      [Raw write]: length = 6
      0000: 14 03 03 00 01 01 ......
      *** Finished
      verify_data: { 230, 33, 24, 195, 32, 34, 244, 0, 174, 231, 234, 138 }
      ***
      update handshake state: finished[20]
      upcoming handshake states: server change_cipher_spec[-1]
      upcoming handshake states: server finished[20]
      main, WRITE: TLSv1.2 Handshake, length = 24
      Padded plaintext before ENCRYPTION: len = 16
      0000: 14 00 00 0C E6 21 18 C3 20 22 F4 00 AE E7 EA 8A .....!.. "......
      main, handling exception: java.net.SocketException: Broken pipe (Write failed)
      %% Invalidated: [Session-3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
      main, SEND TLSv1.2 ALERT: fatal, description = unexpected_message
      main, WRITE: TLSv1.2 Alert, length = 10
      Padded plaintext before ENCRYPTION: len = 2
      0000: 02 0A ..
      main, Exception sending alert: java.net.SocketException: Broken pipe (Write failed)
      main, called closeSocket()
      main, called close()
      main, called closeInternal(true)
      main, called closeSocket()
      MockWebServer 59341, called close()
      MockWebServer 59341, called closeInternal(true)
      MockWebServer 59341, called closeSocket()
      Dec 27, 2016 8:54:05 AM okhttp3.mockwebserver.MockWebServer$3 acceptConnections
      INFO: MockWebServer[59341] done accepting connections: Socket closed


      REPRODUCIBILITY :
      This bug can be reproduced always.

      CUSTOMER SUBMITTED WORKAROUND :
      Project PR to workaround - https://github.com/square/okhttp/pull/3069

      Temp Fix - https://github.com/square/okhttp/commit/3a1f393576899fad13465e6eec89245757c7350a

        1. keystore
          4 kB
        2. SSLSocketFailedClientTest.java
          12 kB
        3. truststore
          2 kB

            xuelei Xuelei Fan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: