appmattus / certificatetransparency

Certificate transparency for Android and JVM
Apache License 2.0
143 stars 29 forks source link

Getting net::ERR_FAILED failure from WebView with CertificateTransparencyProvider installed and proguard enabled #41

Closed ccodega closed 1 year ago

ccodega commented 2 years ago

I've just integrated my app with CertificateTransparency library using:

installCertificateTransparencyProvider { diskCache = AndroidDiskCache(context) }

and I have Proguard/R8 enabled:

minifyEnabled true

what happens is that while loading any WebView I always get a net::ERR_FAILED failure.

If I remove CertificateTransparency or disable Proguard it's working properly.

alexandru-lachimov commented 2 years ago

Hey @ccodega . Could you please show the sample of you proguard file? In sample app you can find proguard-rules.pro file with this comment. If your project uses WebView with JS, uncomment the following and specify the fully qualified class name to the JavaScript interface class: -keepclassmembers class fqcn.of.javascript.interface.for.webview { public *; }

ccodega commented 2 years ago

Hi @alexandru-lachimov thanks for your prompt response! Unfortunately also Webviews with no Javascript interface don't work... and if I disable CertificateTransparency they actually work properly

alexandru-lachimov commented 2 years ago

@ccodega could you please show your WebSettings for WebView client and your proguard file? It may be very useful.

ccodega commented 2 years ago

@alexandru-lachimov let's try this way. I've added a super simple WebView Activity in the library's sampleapp and I can reproduce the same issue. I didn't add any specific proguard rules or webview settings:

Activity code:

package com.appmattus.certificatetransparency.sampleapp

import android.os.Bundle
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity

class WebView : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_web_view)
        findViewById<WebView>(R.id.actwebview_webview)?.loadUrl("https://it.simplesite.com/")
    }
}

activity_web_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <WebView
        android:id="@+id/actwebview_webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

SampleApplication:

override fun onCreate() {
    super.onCreate()
    updateSecurityProvider()
    installCertificateTransparencyProvider { }
}
ccodega commented 2 years ago

I think I've found something: if I enable proguard on a debug build I see this in the logcat

com.appmattus.certificatetransparency.sampleapp E/X509Util: Error creating trust manager (j3.f): java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing com.appmattus.certificatetransparency.sampleapp E/X509Util: Could not find suitable trust manager

alexandru-lachimov commented 2 years ago

My assumption that you received SSL error. Could you please check in debug mode what error do you receive? You'll need to create your own WebViewClient and implement onReceivedSslError. Then you can try to catch SslError.SSL_UNTRUSTED and use CertificateTransparencyTrustManager or it's builder from the lib to validate cert. This answer on StackOverflow may be useful -> https://stackoverflow.com/a/41674490 .

Hey @mattmook what's your opinion here?

ccodega commented 2 years ago

Following my latest comment, if I add this entry in my proguard script it seems it makes it work:

-keep class com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyTrustManager { *; }

@alexandru-lachimov could you double check if this is really a fix and in case include it in the library consumer proguard file?

ccodega commented 2 years ago

I tried also to implement onReceivedSslError but I'm actually receiving the error through onReceivedError

alexandru-lachimov commented 2 years ago

I was reviewing the code and found these comments in CertificateTransparencyTrustManager.kt for the following methods: fun checkServerTrusted(chain: Array<out X509Certificate>, authType: String, host: String): List<X509Certificate> {...} fun isSameTrustConfiguration(hostname1: String?, hostname2: String?): Boolean {...}

Here is the comment: // Called through reflection by X509TrustManagerExtensions on Android

Looks like reflection is used here and to make it work with Proguard need to add proguard rule for this class as you mentioned.

I think you can open a PR and update consumer-proguard-rules.pro file with a new rule and then @mattmook will be able to merge the PR.

ccodega commented 2 years ago

Here it is: https://github.com/appmattus/certificatetransparency/pull/42

thanks for your support @alexandru-lachimov very appreciated!

mattmook commented 1 year ago

Will be releasing a version with the updated consumer proguard file shortly.

sudansh commented 3 months ago

I am still getting this error in 2.5.42 when opening a url in webview eg: https://facebook.com

Error creating trust manager (com.appmattus.certificatetransparency.internal.verifier.k): java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing