0

I'm facing a strange issue. I use OkHTTP to request a web form, parse it and show it as native Android UI.

Everything used to work fine but then recently, the requests started failing on Android versions below Lollipop. It started raising the following exception:

Caused by: javax.net.ssl.SSLException: Connection closed by peer
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)
        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.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:212)
        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)

I searched the internet and found out that it could be caused because Android had TLS1.2 disable before Lollipop and the server might have stopped supporting other protocols.

But I suspect that to be the issue since the same URLs load perfectly fine in a WebView on versions below Lollipop. This leads me to believe that it could be a configuration issue with the OkHTTP client.

What could be the reason for this bug?

Here is how I build the HTTP client:

public static synchronized OkHttpClient getAllAcceptingOkHttpClient() {
        if (sOkHttpClient == null) {
            SSLSocketFactory factory = getAllAcceptingSSLSocketFactory();
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.cookieJar(new JavaNetCookieJar(AadharApplication.cookieManager));
            if (factory != null) {
                builder.sslSocketFactory(factory);
            }
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            sOkHttpClient = builder.build();
        }
        return sOkHttpClient;
    }


private static SSLSocketFactory getAllAcceptingSSLSocketFactory() {
        try {
            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, sTrustAllCerts, new java.security.SecureRandom());
            return sslContext.getSocketFactory();
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            Log.d(TAG, "", e);
            return null;
        }
    }

    private static final TrustManager[] sTrustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
            }
    };

PS: I know this enables MITM attacks, but I know exactly what I'm doing. :)

dotgc
  • 500
  • 1
  • 7
  • 21
  • `SSLException: Connection closed by peer` mean server is closing connection so follow http://stackoverflow.com/a/24401795/5710872 and http://stackoverflow.com/a/25992879/5710872 – Qamar Jan 06 '17 at 11:15
  • @Qamar: I'm already doing that. Please check the edit – dotgc Jan 06 '17 at 11:22
  • FWIW, I just [answered a similar question, related to TLS 1.2 on Android 4.x when using Picasso](http://stackoverflow.com/questions/42166667/is-there-a-way-to-enable-tls-1-2-in-picasso-library-on-older-devices/42181470#42181470). My answer includes the hackery required to get OkHttp3 to accept TLS 1.2 on Android 4.x. – CommonsWare Feb 11 '17 at 21:37

0 Answers0