Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSLHandshakeException on v2.3.0 #1543

Closed
phileo opened this issue Apr 1, 2015 · 12 comments
Closed

SSLHandshakeException on v2.3.0 #1543

phileo opened this issue Apr 1, 2015 · 12 comments

Comments

@phileo
Copy link

phileo commented Apr 1, 2015

discovered this on Android v5.0.1

javax.net.ssl.SSLHandshakeException: Handshake failed
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
       at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:242)
       at com.squareup.okhttp.Connection.connect(Connection.java:159)
       at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
       at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
       at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
       at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
       at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
       at com.squareup.okhttp.Call.getResponse(Call.java:271)
       at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
       at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
       at com.squareup.okhttp.Call.execute(Call.java:79)
       at com.pnimedia.api.gateway.OkHttpClientWrapper.sendGETRequest(OkHttpClientWrapper.java:79)
       at com.pnimedia.api.commands.GetProductDetailsCommand.execute(GetProductDetailsCommand.java:54)
       at com.pnimedia.api.gateway.PniApiGateway.executeCommand(PniApiGateway.java:82)
       at com.pnimedia.api.service.PniRetailManager.executeCommand(PniRetailManager.java:160)
       at com.pnimedia.api.service.PniRetailManager.access$1000(PniRetailManager.java:125)
       at com.pnimedia.api.service.PniRetailManager$19.run(PniRetailManager.java:918)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1120)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:820)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb860a980: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:765 0xaeaaf0dd:0x00000000)
       at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(NativeCrypto.java)
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:302)
       at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:242)
       at com.squareup.okhttp.Connection.connect(Connection.java:159)
       at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
       at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
       at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
       at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
       at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
       at com.squareup.okhttp.Call.getResponse(Call.java:271)
       at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
       at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
       at com.squareup.okhttp.Call.execute(Call.java:79)
       at com.pnimedia.api.gateway.OkHttpClientWrapper.sendGETRequest(OkHttpClientWrapper.java:79)
       at com.pnimedia.api.commands.GetProductDetailsCommand.execute(GetProductDetailsCommand.java:54)
       at com.pnimedia.api.gateway.PniApiGateway.executeCommand(PniApiGateway.java:82)
       at com.pnimedia.api.service.PniRetailManager.executeCommand(PniRetailManager.java:160)
       at com.pnimedia.api.service.PniRetailManager.access$1000(PniRetailManager.java:125)
       at com.pnimedia.api.service.PniRetailManager$19.run(PniRetailManager.java:918)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1120)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:820)

Just a few questions:

  1. Is this the same issue as SSL handshake aborted on 2.3.X & 3.X devices #1209 ?
  2. Is the problem that the Server is using SSLv3 and Android doesn't support it?
  3. Will this SO post on a workaround work ? http://stackoverflow.com/questions/26633349/disable-ssl-as-a-protocol-in-httpsurlconnection
@nfuller
Copy link
Collaborator

nfuller commented Apr 1, 2015

The final failure you are seeing may be SSLv3 based, but if it is it should have tried other protocols first. The error message may be slightly misleading and may not specifically be SSLv3, but a general handshake failure that happens to be incorrectly tagged with sslv3 for historic reasons.

By default, OkHttp 2.3 should not be using SSLv3 at all (https://github.com/square/okhttp/blob/okhttp_23/okhttp/src/main/java/com/squareup/okhttp/ConnectionSpec.java#L56), so I think you'll only see an actual SSLv3 error if you are specifying your own ConnectionSpecs. OkHttp should be picking the intersection between the connection spec and the enabled protocols / ciphers set on the socket.

Only the last connection failure is reported. The interesting question to me is why both connection attempts failed: it could be because of no intersection between the protocols / cipher suites supported by Android's socket, the list OkHttp restricts it to and the server. Ciphers seems more likely to me unless it is a very old server that doesn't support (even) TLSv1.0.

To investigate, you could look at the intersection between the default enabled ciphers on the Android socket (create a socket and call sslSocket.getEnabledCipherSuites(), or look here: http://developer.android.com/reference/javax/net/ssl/SSLEngine.html) and the list here: https://github.com/square/okhttp/blob/okhttp_23/okhttp/src/main/java/com/squareup/okhttp/ConnectionSpec.java#L37

I don't think we get an API that would allow us to see what ciphers / protocols the server offered up, only what was eventually picked. To look at the server capabilities (assuming you don't have more direct access to the server config/docs), you can use something like wireshark or the openssl command line tool. This looked informative as a way of probing with the openssl commandline, but I haven't tried it myself:

http://superuser.com/questions/109213/how-do-i-list-the-ssl-tls-cipher-suites-a-particular-website-offers

FYI - I have a pull request pending that will record all the connection exceptions generated (nfuller@60f5406#diff-4778a03b127c5e671306623d5c9a7a1bR138), but even with that OkHttp won't report them to the caller. It would probably be trivial on newer Java / Android releases to add the prior exceptions as "suppressed" exceptions to the IOExecption ultimately thrown so a developer could see the exceptions for debugging. Worth considering if that PR is accepted. I added the record because I get Android bugs reported and I have no real option but to ask engineers to look at tcpdump/wireshark or go looking in a debugger to see what's actually going wrong.

If connections fail it might be nice to be able to set a debug system property and log the client-side ciphers / protocols being used. If you are using newer OkHttp APIs I suppose it might be possible to roll your own using interceptors, but I'm not at all familiar with the APIs.

@nfuller
Copy link
Collaborator

nfuller commented Apr 2, 2015

mcliment@ If you have details of the URL you're actually trying to hit and versions of Android I could look into this. Please provide complete code that demonstrates the problem if possible.

@mcliment
Copy link

mcliment commented Apr 2, 2015

@nfuller Forget about my previous comment (deleted). I have an error like that one but only then stepping through the code on the client.newCall(...).execute(). If the breakpoint if after that call everything works fine. The code is running on Android 5.0.1 btw and happens with OkHttp 2.3.0 and 2.2.0 too.

@nfuller
Copy link
Collaborator

nfuller commented Apr 2, 2015

@mcliment Ok, will do. The debugger can introduce entertaining issues because of timeouts.

@swankjesse
Copy link
Member

Not clear if any action needs to be taken here.

@juliocotta
Copy link

I am having the same issue. Is there any workaround, test or something I can do (to solve or to help debug the problem)? It is happening with Android 4.4.* and 5.*, many different manufactors.

javax.net.ssl.SSLHandshakeException: Handshake failed
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
       at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:242)
       at com.squareup.okhttp.Connection.connect(Connection.java:159)
       at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
       at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
       at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
       at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
       at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
       at com.squareup.okhttp.Call.getResponse(Call.java:271)
       at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
       at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
       at com.squareup.okhttp.Call.access$100(Call.java:34)
       at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:162)
       at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb7928f58: Failure in SSL library, usually a protocol error
error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:765 0xadeb0edd:0x00000000)
       at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(NativeCrypto.java)
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:302)
       at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:242)
       at com.squareup.okhttp.Connection.connect(Connection.java:159)
       at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
       at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
       at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
       at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
       at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
       at com.squareup.okhttp.Call.getResponse(Call.java:271)
       at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
       at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
       at com.squareup.okhttp.Call.access$100(Call.java:34)
       at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:162)
       at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

@swankjesse
Copy link
Member

@juliocotta mind opening a separate issue, and including the address of the HTTPS server you're trying to reach? Most of the time issues like this are due to bad server behavior!

@juliocotta
Copy link

ok

@lucalooz
Copy link

I'm encountering this issue too right now on a Nexus 5 with Lollipop 5.1 and OkHttp 2.3.0 and i'm able to reproduce systematically
If i downgrade to 2.2.0 it works fine

Example code:

OkHttpClient client = new OkHttpClient();
final String src = "https://lvl3.vimeocdn.com/video/125301949/357769076.mp4?expires=1429890503&token=0d578d524d0972e164bba";
final Request.Builder request = new Request.Builder()
        .get().url(src);
client.newCall(request.build()).enqueue(new Callback() {
    @Override
    public void onFailure(Request request, IOException e) {
        Log.e(TAG, "onFailure", e);
    }

    @Override
    public void onResponse(Response response) throws IOException {
        Log.v(TAG, "onResponse " + response.isSuccessful());
        response.body().close();
    }
});

Stacktrace:

javax.net.ssl.SSLHandshakeException: Handshake failed
            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:390)
            at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:242)
            at com.squareup.okhttp.Connection.connect(Connection.java:159)
            at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:175)
            at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
            at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:330)
            at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:319)
            at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
            at com.squareup.okhttp.Call.getResponse(Call.java:271)
            at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:228)
            at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:199)
            at com.squareup.okhttp.Call.access$100(Call.java:34)
            at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:162)
            at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb4888200: Failure in SSL library, usually a protocol error
    error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:770 0xaba0ef89:0x00000000)
            at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
            at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:318)
            ... 16 more

@IgorGanapolsky
Copy link

Downgrading from okhttp 2.5.0 to 2.2.0 doesn't help. I get the exact same error on my Lollipop device.

@iNoles
Copy link
Contributor

iNoles commented Oct 22, 2015

Please test it with setEnabledCipherSuites to your server cipher suites. https://www.ssllabs.com/ssltest/

@IgorGanapolsky
Copy link

@iNoles ssllabs shows

Unable to resolve domain name.

This server sits behind VPN, and IPs are whitelisted. And instead of calling setEnabledCipherSuites, wouldn't it be better to call setConnectionSpecs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants