title: SSL/TLS problems with Android 6+ clients, javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
body: <p>I got a multiplayer game with a client server setup that has been working fine on Desktop and my own Android test devices (4.x - 5.x) but everyone that have tried using a mobile device with Android 6+ can not complete a handshake with the server.</p>
  
  <p>The client get: Connection closed by peer exception in com.android.org.conscrypt.SSL_do_handshake(Native Method)</p>
  
  <p>I turned on full output for the javax.net package on the server and this is what I see:</p>
  
  <pre><code>Thread-5, called closeInbound()
  Thread-5, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
  javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
  %% Invalidated:  [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
  Thread-5, SEND TLSv1.2 ALERT:  fatal, description = internal_error
  Thread-5, WRITE: TLSv1.2 Alert, length = 2
  Thread-5, called closeOutbound()
  Thread-5, closeOutboundInternal()
  </code></pre>
  
  <p>Log is actually 90k+ chars but I could not paste it all. But basically server client goes through TLS1.2, 1.1 and 1.0 and the result is the same "javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?"</p>
  
  <p>I am using an self signed certificate and the truststore hack:</p>
  
  <pre><code>    public LoginClient() throws Exception{
               // Create a trust manager that does not validate certificate chains
              TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
  //                      return null;
                          return new X509Certificate[0];
                      }
                      public void checkClientTrusted(X509Certificate[] certs, String authType) {
                      }
                      public void checkServerTrusted(X509Certificate[] certs, String authType) {
                      }
                  }
              };
  
              // Install the all-trusting trust manager
              SSLContext sc = SSLContext.getInstance("SSL");
              sc.init(null, trustAllCerts, new java.security.SecureRandom());
              HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
  
              // Create all-trusting host name verifier
              HostnameVerifier allHostsValid = new HostnameVerifier() {
                  public boolean verify(String hostname, SSLSession session) {
                      return true;
                  }
              };
  
              // Install the all-trusting host verifier
              HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
  
          }
  </code></pre>
  
  <p>Does anyone have any idea what is going wrong and how I can fix this? I find it a bit strange that it only occurs for Android 6+</p>
  
  <p>Edit: Added the *** Diffie-Hellman ServerKeyExchange</p>
  
  <pre><code>DH Modulus:  { 233, 230, 66, 89, 157, 53, 95, 55, 201, 127, 253, 53, 103, 18, 11, 142, 37, 201, 205, 67, 233, 39, 179, 169, 103, 15, 190, 197, 216, 144, 20, 25, 34, 210, 195, 179, 173, 36, 128, 9, 55, 153, 134, 157, 30, 132, 106, 171, 73, 250, 176, 173, 38, 210, 206, 106, 34, 33, 157, 71, 11, 206, 125, 119, 125, 74, 33, 251, 233, 194, 112, 181, 127, 96, 112, 2, 243, 206, 248, 57, 54, 148, 207, 69, 238, 54, 136, 193, 26, 140, 86, 171, 18, 122, 61, 175 }
  DH Base:  { 48, 71, 10, 213, 160, 5, 251, 20, 206, 45, 157, 205, 135, 227, 139, 199, 209, 177, 197, 250, 203, 174, 203, 233, 95, 25, 10, 167, 163, 29, 35, 196, 219, 188, 190, 6, 23, 69, 68, 64, 26, 91, 44, 2, 9, 101, 216, 194, 189, 33, 113, 211, 102, 132, 69, 119, 31, 116, 186, 8, 77, 32, 41, 216, 60, 28, 21, 133, 71, 243, 169, 241, 162, 113, 91, 226, 61, 81, 174, 77, 62, 90, 31, 106, 112, 100, 243, 22, 147, 58, 52, 109, 63, 82, 146, 82 }
  Server DH Public Key:  { 23, 79, 111, 200, 124, 159, 143, 170, 244, 139, 127, 154, 15, 184, 207, 89, 0, 30, 234, 138, 254, 90, 48, 244, 171, 46, 100, 55, 220, 87, 23, 2, 3, 243, 132, 144, 17, 75, 191, 90, 239, 112, 13, 71, 150, 127, 34, 219, 174, 161, 188, 204, 151, 97, 179, 129, 103, 89, 188, 211, 14, 216, 71, 115, 12, 105, 63, 219, 23, 70, 110, 231, 202, 153, 121, 59, 194, 97, 105, 215, 57, 211, 48, 184, 22, 149, 176, 64, 186, 103, 240, 237, 224, 217, 233, 4 }
  Signature Algorithm SHA512withRSA
  Signed with a DSA or RSA public key
  *** ServerHelloDone
  </code></pre>
  
  <p><em>Update</em>
  I finally got hold of an Android 6.0.1 device so I could test this some more.
  In my development environment I run Oracle Java 7u25 on the production server there is openjdk 7 and the funny thing is that Android 6 works in my development environment with the exact same setup but fails when I try to connect to the production server. I can now see the full exception and it is:</p>
  
  <pre><code>11-01 05:18:50.793: W/System.err(23793): javax.net.ssl.SSLHandshakeException: Handshake failed
  11-01 05:18:50.796: W/System.err(23793):    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:396)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.Connection.connect(Connection.java:143)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
  11-01 05:18:50.796: W/System.err(23793):    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:245)
  11-01 05:18:50.797: W/System.err(23793):    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
  11-01 05:18:50.797: W/System.err(23793):    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java)
  11-01 05:18:50.797: W/System.err(23793):    at com.aperico.game.sylvass.netcode.LoginClient.doLogin(LoginClient.java:105)
  11-01 05:18:50.797: W/System.err(23793):    at com.aperico.game.sylvass.CryptCardsGame$4.run(CryptCardsGame.java:343)
  11-01 05:18:50.797: W/System.err(23793):    at java.lang.Thread.run(Thread.java:818)
  11-01 05:18:50.797: W/System.err(23793):    Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
  11-01 05:18:50.797: W/System.err(23793):        ... 16 more
  11-01 05:18:50.797: W/System.err(23793):        Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
  11-01 05:18:50.797: W/System.err(23793):            ... 16 more
  11-01 05:18:50.798: W/System.err(23793):        Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x941df080: Failure in SSL library, usually a protocol error
  11-01 05:18:50.798: W/System.err(23793): error:100c1069:SSL routines:ssl3_get_server_key_exchange:BAD_DH_P_LENGTH (external/boringssl/src/ssl/s3_clnt.c:1193 0xa9e31ad5:0x00000000)
  11-01 05:18:50.798: W/System.err(23793):            at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
  11-01 05:18:50.798: W/System.err(23793):            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
  11-01 05:18:50.798: W/System.err(23793):            ... 15 more
  11-01 05:18:50.798: W/System.err(23793):    Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x941df080: Failure in SSL library, usually a protocol error
  11-01 05:18:50.798: W/System.err(23793): error:100c1069:SSL routines:ssl3_get_server_key_exchange:BAD_DH_P_LENGTH (external/boringssl/src/ssl/s3_clnt.c:1193 0xa9e31ad5:0x00000000)
  11-01 05:18:50.798: W/System.err(23793):        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
  11-01 05:18:50.799: W/System.err(23793):        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
  11-01 05:18:50.799: W/System.err(23793):        ... 15 more
  11-01 05:18:50.799: W/System.err(23793): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x941df080: Failure in SSL library, usually a protocol error
  11-01 05:18:50.799: W/System.err(23793): error:100c1069:SSL routines:ssl3_get_server_key_exchange:BAD_DH_P_LENGTH (external/boringssl/src/ssl/s3_clnt.c:1193 0xa9e31ad5:0x00000000)
  11-01 05:18:50.799: W/System.err(23793):    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
  11-01 05:18:50.799: W/System.err(23793):    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
  11-01 05:18:50.799: W/System.err(23793):    ... 15 more
  </code></pre>