Okhttp: "SSLProtocolException: SSL handshake aborted" exception on Android 5.1 after migrationg to 4.7.1

Created on 26 Jun 2020  路  11Comments  路  Source: square/okhttp

Hi guys!

After migrating from 3.12.0 to 4.7.1
On Android 5.1 I'm getting SSLProtocolException :

Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7f2719a89e80: 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 0x7f2728a53ea0:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:318)

The host I'm trying to connect is admin-api-stg.oitchau.com.br

I have tried this:

.connectionSpecs(
                listOf(
                    ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
                        .build()
                )
            )

But no luck

bug

Most helpful comment

Guys, thanks for help!
I have fixed this by adding

private fun updateAndroidSecurityProvider() {
        try {
            ProviderInstaller.installIfNeeded(this)
        } catch (e: GooglePlayServicesRepairableException) {
            // Thrown when Google Play Services is not installed, up-to-date, or enabled
            // Show dialog to allow users to install, update, or otherwise enable Google Play services.
            // IGNORE
        } catch (e: GooglePlayServicesNotAvailableException) {
            Timber.e("SecurityException Google Play Services not available.")
        }
    }

to my App.onCreate() Important updateAndroidSecurityProvider() invocation must be before OkHttpClient initialization

Successful Handshake on 4.7.1 return:

Handshake{tlsVersion=TLS_1_2 cipherSuite=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 peerCertificates=[CN=sni.cloudflaressl.com, O="Cloudflare, Inc.", L=San Francisco, ST=CA, C=US, CN=CloudFlare Inc ECC CA-2, O="CloudFlare, Inc.", L=San Francisco, ST=CA, C=US, CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE] localCertificates=[]}

To reproduce this Exception I have used this method:

private fun testCall() {
        val client = OkHttpClient.Builder()
            .connectTimeout(40, TimeUnit.SECONDS)
            .writeTimeout(40, TimeUnit.SECONDS)
            .readTimeout(40, TimeUnit.SECONDS)
            .connectionSpecs(
                listOf(
                    ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
                        .build()
                )
            )
            .addInterceptor { chain ->
                val response = chain.proceed(chain.request())
                Timber.i(response.handshake.toString())
                response
            }
            .apply {
                if (com.oitchau.tablet.BuildConfig.DEBUG)
                    addNetworkInterceptor(
                        HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
                    )
            }
            .build()

        val JSON = "application/json; charset=utf-8".toMediaTypeOrNull()
        val body = RequestBody.create(JSON, "{ }" )
        val request = Request.Builder()
            .url("https://admin-api-stg.oitchau.com.br/v1/public/structure/tablets/register")
            .post(body)
            .build()

        GlobalScope.launch {
            Timber.i(client.newCall(request).execute().toString())
        }
    }

I have tested it on this emulator:

Target: google_apis [Google APIs] (API level 22)
CPU/ABI: Google APIs Intel Atom (x86_64)`

All 11 comments

I can't reproduce on an Android 5.0 (21) device.

You can see the changes we have made to connection specs here https://github.com/square/okhttp/blob/7e4870537e33e2f0c4ea39f97b3a7d41a6ba0711/docs/tls_configuration_history.md

This is the sort of information we'd like with 3.12.0 to work out why it's failing

https://github.com/square/okhttp/issues/6138#issuecomment-647345231

Yep, and you can get that by printing the response鈥檚 handshake.

My guess is you're getting this cipher suite which is gone in even our COMPATIBLE_TLS config:
REMOVED: TLS_AES_128_CCM_SHA256鹿
REMOVED: TLS_AES_128_CCM_8_SHA256鹿

Nope, that's a bad guess because those cipher suites don't really exist on 3.12 either. Please print the handshake from OkHttp 3.12!

One more resource:
http://tinyurl.com/okhttp-cipher-suites

Somehow the intersection of Andoid 5, OkHttp 4.7, and your server is empty.

... and I think the reason is that Android 5 has the wrong version of a cipher suite:
https://security.stackexchange.com/questions/117078/what-does-old-mean-in-old-tls-ecdhe-rsa-with-chacha20-poly1305-sha256#117084

(I'd never heard of this before)

How can I print the handshake information?

Guys, thanks for help!
I have fixed this by adding

private fun updateAndroidSecurityProvider() {
        try {
            ProviderInstaller.installIfNeeded(this)
        } catch (e: GooglePlayServicesRepairableException) {
            // Thrown when Google Play Services is not installed, up-to-date, or enabled
            // Show dialog to allow users to install, update, or otherwise enable Google Play services.
            // IGNORE
        } catch (e: GooglePlayServicesNotAvailableException) {
            Timber.e("SecurityException Google Play Services not available.")
        }
    }

to my App.onCreate() Important updateAndroidSecurityProvider() invocation must be before OkHttpClient initialization

Successful Handshake on 4.7.1 return:

Handshake{tlsVersion=TLS_1_2 cipherSuite=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 peerCertificates=[CN=sni.cloudflaressl.com, O="Cloudflare, Inc.", L=San Francisco, ST=CA, C=US, CN=CloudFlare Inc ECC CA-2, O="CloudFlare, Inc.", L=San Francisco, ST=CA, C=US, CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE] localCertificates=[]}

To reproduce this Exception I have used this method:

private fun testCall() {
        val client = OkHttpClient.Builder()
            .connectTimeout(40, TimeUnit.SECONDS)
            .writeTimeout(40, TimeUnit.SECONDS)
            .readTimeout(40, TimeUnit.SECONDS)
            .connectionSpecs(
                listOf(
                    ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
                        .build()
                )
            )
            .addInterceptor { chain ->
                val response = chain.proceed(chain.request())
                Timber.i(response.handshake.toString())
                response
            }
            .apply {
                if (com.oitchau.tablet.BuildConfig.DEBUG)
                    addNetworkInterceptor(
                        HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
                    )
            }
            .build()

        val JSON = "application/json; charset=utf-8".toMediaTypeOrNull()
        val body = RequestBody.create(JSON, "{ }" )
        val request = Request.Builder()
            .url("https://admin-api-stg.oitchau.com.br/v1/public/structure/tablets/register")
            .post(body)
            .build()

        GlobalScope.launch {
            Timber.i(client.newCall(request).execute().toString())
        }
    }

I have tested it on this emulator:

Target: google_apis [Google APIs] (API level 22)
CPU/ABI: Google APIs Intel Atom (x86_64)`

Awesome. Since you鈥檙e using the security provider you can remove the line that configures the connectionSpecs. Both the security provider and your server are capable of our default configuration which is a bit more locked down.

Any chance you can print the old handshake from 3.12? I鈥檓 curious if my theory holds that it鈥檚 the old OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 cipher suite.

@swankjesse going to update docs to point to instructions, this is only going to get more painful over time

https://github.com/square/okhttp/pull/6149

@swankjesse
Oddly it uses the same cipher suite with User-Agent: okhttp/3.12.0
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_1_2

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yschimke picture yschimke  路  3Comments

yschimke picture yschimke  路  3Comments

sargunv picture sargunv  路  3Comments

TheLester picture TheLester  路  3Comments

yschimke picture yschimke  路  3Comments