question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

OkHttp 3.13 on Android with custom trust manager fails with AssertionError

See original GitHub issue

TL;DR: How to use custom trust managers with OkHttp 3.13?

We have an app that uses a custom X509TrustManager (X509ExtendedTrustManager on API >= 24) to implement additional certificate whitelisting requirements. Basically the custom trust manager takes system trust manager as a delegate and adds custom whitelist checks on top.

This used to work fine up to OkHttp 3.12.1.

On OkHttp 3.13.0 this fails when initialising OkHttpClient.Builder#sslSocketFactory like:

        X509TrustManager trustManager;
        SSLSocketFactory sslSocketFactory;
        try {
            trustManager = buildTrustManager(...);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[] { trustManager }, null);
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new RuntimeException(e);
        }
        okClientBuilder.sslSocketFactory(sslSocketFactory, trustManager);

with stacktrace like:

java.lang.AssertionError: java.lang.reflect.InvocationTargetException
        at okhttp3.internal.platform.AndroidPlatform.buildCertificateChainCleaner(AndroidPlatform.java:201)
        at okhttp3.internal.tls.CertificateChainCleaner.get(CertificateChainCleaner.java:41)
        at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.java:821)

...

     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at okhttp3.internal.platform.AndroidPlatform.buildCertificateChainCleaner(AndroidPlatform.java:196)
        at okhttp3.internal.tls.CertificateChainCleaner.get(CertificateChainCleaner.java:41) 
        at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.java:821)  

...

Caused by: java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing
        at android.net.http.X509TrustManagerExtensions.<init>(X509TrustManagerExtensions.java:72)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
        at okhttp3.internal.platform.AndroidPlatform.buildCertificateChainCleaner(AndroidPlatform.java:196) 
        at okhttp3.internal.tls.CertificateChainCleaner.get(CertificateChainCleaner.java:41) 
        at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.java:821) 

From the commits I see https://github.com/square/okhttp/commit/bdc7681b3ba16ae311d2dd21160d61315e8942ca introduced this AssertionError while earlier execution would fall back to super implementation.

On API >= 24 (tested only on 28) I can get rid of this crash by adding the method looked up reflectively to our X509ExtendedTrustManager implementation:

        /** This is used reflectively by Android X509TrustManagerExtensions and okhttp CertificateChainCleaner **/
        @SuppressWarnings("unused")
        public void checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
            // TODO figure out if something could be done with the host param
            delegate.checkServerTrusted(chain, authType);
            whitelistChecker.checkCertWhitelisted(chain[0]);
        }

However this does not work on API < 24 (our min SDK is 21). Adding the same method to X509TrustManager (javax.net.ssl.X509TrustManager) just introduces another issue. This one on API 21 emulator:

Caused by: java.lang.IllegalArgumentException: tm is an instance of ...WhitelistingTrustManager which is not a supported type of X509TrustManager
        at android.net.http.X509TrustManagerExtensions.<init>(X509TrustManagerExtensions.java:51)
        at java.lang.reflect.Constructor.newInstance(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
        at okhttp3.internal.platform.AndroidPlatform.buildCertificateChainCleaner(AndroidPlatform.java:196) 
        at okhttp3.internal.tls.CertificateChainCleaner.get(CertificateChainCleaner.java:41) 
        at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.java:821) 

Looking up the platform source the code just allows TrustManagerImpls which is a platform-internal class and cannot really be used in app code.

Questions:

  1. How would one use custom X509TrustManagers with OkHttp 3.13 without crashes?
  2. Any alternative ideas for implementing custom certificate checks?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
laaltocommented, Feb 6, 2019

Verified with 3.13.1. No more crashes; connectivity-related tests passing.

0reactions
swankjessecommented, Jul 3, 2019

@dj-4war paste a stacktrace in a new issue please.

Read more comments on GitHub >

github_iconTop Results From Across the Web

android - Trusting all certificates with okHttp - Stack Overflow
private static OkHttpClient getUnsafeOkHttpClient() { try { // Create a trust manager that does not validate certificate chains final TrustManager[] ...
Read more >
java.lang.assertionerror: no system tls - You.com | The Search ...
I receive this error occasionally in my feedback, android version is 7.0, I have no idea why this error happen, below is the...
Read more >
3.x Change Log - OkHttp
Fix: Don't crash when using a custom X509TrustManager or SSLSocket on Android. When we removed obsolete code for Android 4.4 we inadvertently also...
Read more >
OkHttp 3.13 Requires Android 5+ | Square Corner Blog
Today we're releasing OkHttp 3.13. With this update we're bumping the project's requirements from this: Android 2.3+ / API 9+ (released ...
Read more >
Trusting All Certificates in OkHttp | Baeldung
Learn how to create an OkHttpClient and configure it to trust all certificates — not the best practice in production, but you may...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found