Https connection completed with connection closed by peer on Android 6.0

I have a problem with SSL (TSL) communication between an Android device (Samsung Galaxy with Android 6.0) and a Simple Java application that uses com.sun.net.httpserver.HttpsServer. I have to say that on another device with Android 4.4 everything works fine.

When Android 6.0 tries to make a handshake, the server side terminates the connection, on the Android phone they see the underlying stacktrace

W/System.err: javax.net.ssl.SSLHandshakeException: Connection closed by peer
W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) 
W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:353)
W/System.err:     at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:212)
W/System.err:     at com.android.okhttp.Connection.connect(Connection.java:1322)
W/System.err:     at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:1410) 
W/System.err:     at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:466)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:447) 
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:353)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:468) 08-28 06:47:21.322 3676-5603/pl.com.szb.gateopener W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:118) 08-28 06:47:21.322 3676-5603/pl.com.szb.gateopener W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:249)
W/System.err:     at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
W/System.err:     at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:25)
W/System.err:     at org.ksoap2.transport.HttpsServiceConnectionSE.openOutputStream(HttpsServiceConnectionSE.java:127)
W/System.err:     at org.ksoap2.transport.HttpTransportSE.sendData(HttpTransportSE.java:292) 
W/System.err:     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:184)
W/System.err:     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:118) 
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding.sendRequest(PSBGOImplPortBinding.java:99)
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding.execute(PSBGOImplPortBinding.java:284)
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding.getGates(PSBGOImplPortBinding.java:142)
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding$2.Func(PSBGOImplPortBinding.java:165)
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding$2.Func(PSBGOImplPortBinding.java:163)
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding$7.doInBackground(PSBGOImplPortBinding.java:318)
W/System.err:     at pl.com.szb.gateopener.client.PSBGOImplPortBinding$7.doInBackground(PSBGOImplPortBinding.java:308)
W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:295) 
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err:     at java.lang.Thread.run(Thread.java:818)

Android code to initiate SSL

 `private void initSSL() throws Exception {
    Log.d(TAG,"initSSL");
    TrustManager tm = new CustomX509TrustManager();
    SSLContext customSSLContext = SSLContext.getInstance("TLSv1.1");
    customSSLContext.init(null , new TrustManager[] { tm } , null);
    sslSocketFactory = customSSLContext.getSocketFactory();

    HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);

    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            Log.d(TAG, String.format("Verifying %s , sessionId: %s", hostname, Arrays.toString(session.getId())));
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(hv);
}


public class CustomX509TrustManager implements X509TrustManager {
    private String TAG = "CustomX509TrustManager";
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
    {
        Log.d(TAG, "checkClientTrusted");
    }

    @Override
    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws CertificateException
    {
        Log.d(TAG, "checkServerTrusted");
        // Here you can verify the servers certificate. (e.g. against one which is stored on mobile device)

        InputStream inStream = null;
        try {
            inStream = getResources().openRawResource(R.raw.goserver_10y);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate ca = (X509Certificate) cf.generateCertificate(inStream);
            inStream.close();

            for (X509Certificate cert : certs) {
                // Verifing by public key
                cert.verify(ca.getPublicKey());
            }
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
            throw new CertificateException(e);
        } finally {
            try {
                inStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public X509Certificate[] getAcceptedIssuers() {
        Log.d(TAG, "getAcceptedIssuers");
        return null;
    }
}`

And server code:

`private void initServer() throws Exception{
    Config config = getContext().system().settings().config();
    host = getConfigString("pl.com.szb.GOImpl.host", config, "0.0.0.0");
    port = getConfigInt("port", config, 10000);
    useSSL = getConfigBoolean("use_ssl", config, true);
    endpointLocation = getConfigString("endpointLocation", config, "/go");

    String fullURL = String.format("%s://%s:%d%s",(useSSL ? "https" : "http"), host, port, endpointLocation);
    log.info(String.format("WSDL : %s?wsdl", fullURL));

    if (useSSL) {
        keystorePass = getConfigString("keystorePass", config, "secret");
        keystoreName = getConfigString("keystoreName", config, "second/server.bks");

        char[] pass = keystorePass.toCharArray();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream is = classLoader.getResourceAsStream(keystoreName);

        KeyStore ks = KeyStore.getInstance("BKS");
        ks.load(is, pass);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
        kmf.init(ks, pass);

        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(kmf.getKeyManagers(), null, null);
        server = HttpsServer.create(new InetSocketAddress(host, port), 0);

        ((HttpsServer)server).setHttpsConfigurator(new HttpsConfigurator(sslContext) {
            public void configure(HttpsParameters params) {
                try {
                    log.debug(String.format("Got client: %s, wantAuth: %b, needAuth: %b",
                        params.getClientAddress().toString(),
                        params.getWantClientAuth(),
                        params.getNeedClientAuth()
                    ));

                    params.setWantClientAuth(false);
                    params.setNeedClientAuth(false);

                    //what to do more??

                } catch (Exception ex) {
                    log.warn(String.format("Failed to create HTTPS port, cause " + ex.getMessage()));
                }
            }
        });
    } else {
        server = HttpServer.create(new InetSocketAddress(host, port), 0);
    }
   server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
    server.start();

    HttpContext httpContext = server.createContext(endpointLocation);
    endpoint = Endpoint.create(SOAPBinding.SOAP11HTTP_BINDING,this);
    endpoint.publish(httpContext);
}

`

What I checked:

  • every link that google and stackoverflow offer after the name has been printed (especially the Https link closed by the peer in Android 5.0 lexicon), but with no luck
  • Cipher siute . .
  • wirehark. , delcare ( Android) TLSv1.2 TLS 1.0 SSL (. - - Decode as '- > SSL) 140 Android 6.0, Bellow ( 145 , Android 4.4). 10.0.0.203 - Android 6.0, 10.0.0.99 - , 10.0.0.200 - Android 4.4
  • ", ", , , SSL ( ).

( SOAP-), , , .

, , .

+4

Source: https://habr.com/ru/post/1652739/


All Articles