koush / AndroidAsync

Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.
Other
7.52k stars 1.56k forks source link

ProGuard breaks SSL #512

Open Pitel opened 7 years ago

Pitel commented 7 years ago

I have the following code:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //Certificate is ok on newer Androids
    Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware().setHostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(final String hostname, final SSLSession session) {
            Log.w(TAG, hostname);
            return "my.host.name".equals(hostname);
        }
    });
}

It works fine without ProGuard, I can even remove the custom verifier.

But when I build it with ProGuard (or new minifier), it ends with following exception:

E: connection closed before response completed.
   com.koushikdutta.async.http.ConnectionClosedException: connection closed before response completed.
       at com.koushikdutta.async.http.AsyncHttpResponseImpl$2.onCompleted(AsyncHttpResponseImpl.java:54)
       at com.koushikdutta.async.AsyncSSLSocketWrapper.report(AsyncSSLSocketWrapper.java:438)
       at com.koushikdutta.async.AsyncSSLSocketWrapper.access$100(AsyncSSLSocketWrapper.java:30)
       at com.koushikdutta.async.AsyncSSLSocketWrapper$5.onDataAvailable(AsyncSSLSocketWrapper.java:224)
       at com.koushikdutta.async.Util.emitAllData(Util.java:23)
       at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:152)
       at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:820)
       at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:657)
       at com.koushikdutta.async.AsyncServer.access$800(AsyncServer.java:44)
       at com.koushikdutta.async.AsyncServer$14.run(AsyncServer.java:599)
    Caused by: javax.net.ssl.SSLException: Fatal alert received handshake_failure
       at org.apache.harmony.xnet.provider.jsse.SSLEngineImpl.unwrap(SSLEngineImpl.java:485)
       at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:383)
       at com.koushikdutta.async.AsyncSSLSocketWrapper$5.onDataAvailable(AsyncSSLSocketWrapper.java:194)
       at com.koushikdutta.async.Util.emitAllData(Util.java:23) 
       at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:152) 
       at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:820) 
       at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:657) 
       at com.koushikdutta.async.AsyncServer.access$800(AsyncServer.java:44) 
       at com.koushikdutta.async.AsyncServer$14.run(AsyncServer.java:599) 

and this, without the verifier:

E: Peer not trusted by any of the system trust managers.
   com.koushikdutta.async.AsyncSSLException: Peer not trusted by any of the system trust managers.
       at com.koushikdutta.async.AsyncSSLSocketWrapper.handleHandshakeStatus(AsyncSSLSocketWrapper.java:322)
       at com.koushikdutta.async.AsyncSSLSocketWrapper.access$000(AsyncSSLSocketWrapper.java:30)
       at com.koushikdutta.async.AsyncSSLSocketWrapper$5.onDataAvailable(AsyncSSLSocketWrapper.java:213)
       at com.koushikdutta.async.Util.emitAllData(Util.java:23)
       at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:152)
       at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:820)
       at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:657)
       at com.koushikdutta.async.AsyncServer.access$800(AsyncServer.java:44)
       at com.koushikdutta.async.AsyncServer$14.run(AsyncServer.java:599)
    Caused by: javax.net.ssl.SSLException: hostname <my.host.name> has been denied
       at com.koushikdutta.async.AsyncSSLSocketWrapper.handleHandshakeStatus(AsyncSSLSocketWrapper.java:306)
       at com.koushikdutta.async.AsyncSSLSocketWrapper.access$000(AsyncSSLSocketWrapper.java:30) 
       at com.koushikdutta.async.AsyncSSLSocketWrapper$5.onDataAvailable(AsyncSSLSocketWrapper.java:213) 
       at com.koushikdutta.async.Util.emitAllData(Util.java:23) 
       at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:152) 
       at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:820) 
       at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:657) 
       at com.koushikdutta.async.AsyncServer.access$800(AsyncServer.java:44) 
       at com.koushikdutta.async.AsyncServer$14.run(AsyncServer.java:599) 

My custom ProGuard rules are empty. And even adding the following line doesn't make any difference.

-keep class com.koushikdutta.** { *; }
eikaramba commented 7 years ago

same problem here, that is currently breaking a lot of things on android 4 for our users.

eikaramba commented 7 years ago

We were able to fix it by downgrading ION from 2.1.9 --> 2.1.7

ghost commented 7 years ago

How have you verified that it works fine without ProGuard?

I'm having the same issue even with minifyEnabled set to false.

ghost commented 7 years ago

At this point, I'm not sure my issue is also related to ProGuard, but I found a pair of host names that might be useful in reproducing it (links might be slightly nsfw):

So it seems that the bug occurs only when using the Bouncy Castle crypto in older versions of Android and conscrypt (OpenSSL) works fine.

Downgrading ion to 2.1.7 does indeed fix the issue.