Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android WebView setCertificate issues SSL problems

I have seen a lot of posts and information about SSL errors and I have stumbled upon one myself.

I am trying to access a web page through Android WebView with a GlobalSign CA BE certificate, and I get a not-trusted error.

For most phones, it works fine to handle this, and just tell the handler to proceed.

Some phones, however, end up getting a onReceivedError in the webview-client, telling it that it can't establish contact with the server. This happens after it has gone through the onReceivedSslError and proceeded.

I searched for descriptions and found a lot of descriptions involving HttpClient and either installing your own certificate or just tricking it into accepting all.

However, since I was using WebView I thought I'd make use of WebView.setCertificate(SslCertificate crt) . I searched for discussions of this function, but did not find much/any info.

I got a hold of the certificate that was said to be untrusted, and did this code:

try{
     Certificate myCert = CertificateFactory.getInstance("X509").
     generateCertificate(this.getResources().
     openRawResource(R.raw.globalsign_ca_be));

     X509Certificate x509 = (X509Certificate) myCert;
     SslCertificate sslCert = new SslCertificate(x509);
     webView.setCertificate(sslCert);

    }
    catch (CertificateException ex){
        ex.printStackTrace();
    }

With a .cer file containing this:

-----BEGIN CERTIFICATE----- MIIEbjCCA1agAwIBAgILBAAAAAABElatYgQwDQYJKoZIhvcNAQEFBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0wNzA1MDQxMDAw MDBaFw0xNDAxMjcxMTAwMDBaMHExCzAJBgNVBAYTAkJFMR0wGwYDVQQLExREb21h aW4gVmFsaWRhdGlvbiBDQTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYG A1UEAxMfR2xvYmFsU2lnbiBEb21haW4gVmFsaWRhdGlvbiBDQTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBALSfSeaznwFVNtA2lWzLFlpscrXineL6OekK 3HNcoDt2bQUokw2lQvPoy+7TMxoTJwrfXNFUYmqaFzbWPFiHHrJmH1VpK4lWR7TC UAzlXcH9KRtmc0P0b9EUTyptSFI69eSQP96y9BDV+fqslg0QMiPS01GnlYVQ+g8p naeITg0xm0RBjkEvbpoatLalWfFJWQl+fknTaTNLAJLFG0Igafhk39inRNGQXv05 rWt9/tWLpAFk9qe0IITMBS8n7h7VJJauhEOkPkPzO5nX+fLePRnt0GXxScpI0jh9 xkjXcmG4xsJnCthlWv1b88X9voxpz5kgtursOYDpZqjuPZ1Ge4cCAwEAAaOCAR8w ggEbMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMEsGA1UdIARE MEIwQAYJKwYBBAGgMgEKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2xvYmFs c2lnbi5uZXQvcmVwb3NpdG9yeS8wHQYDVR0OBBYEFDYSTp5xxCZB8frxKUy/F6RT KLbrMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQv cm9vdC5jcmwwEQYJYIZIAYb4QgEBBAQDAgIEMCAGA1UdJQQZMBcGCisGAQQBgjcK AwMGCWCGSAGG+EIEATAfBgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzAN BgkqhkiG9w0BAQUFAAOCAQEAwyV5SvrNJm9AariUG+ag4WvSMZo/ifvFCiJ1ev27 QDScvJ6FSVl6lcwNLUQLx8sVEB7S3ON46l/1NVGmyD85kBWeXxXJt49da2OZaOFu XPydNzMKrodwSqLjqyZ9cwfk9wqqdY+m7psE0QVDdBq61MKdf7egbO0WmmdAVquD n0yc6yg0H43mWg9pQNmpnmr5iX/Q+IyzSC4LT/H5z/UOEQIMiRZzU10s0+/eXwsl utVOj4WQP4iTeaUgrP+wisvLpVV4gzlBMqpdJZOn6u4YcrXiHX8IdBG2ASdOls+o 8Cr5UqwkGhmen2xSfIs6plTewcchfTrTvBqobfK/33bKAw== -----END CERTIFICATE-----

It completed without exception, but I still got the same behaviour from my webview. First an SSL-error and then an error saying it could not communicate/load the page.

If anyone has some info, has been able to get SSL working properly in WebView, or even just help in ways to debug this. I would greatly appreciate it.

My head is also exploding a bit, because I'm not very experienced in SSL to begin with.

*it's a public key btw, nothing exciting ;) (GlobalSign CA BE)

some more info: the ssl exception: primary error: 3 certificate: Issued to: CN=GlobalSign Domain Validation CA,O=GlobalSign nv-sa,OU=Domain Validation CA,C=BE;

Issued by: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE;

error 3 is , SSL_UNTRUSTED

I do however have a feeling that the setCertificate function, is not to add a trusted certificate for a missing root or similar, but instead to add a client certificate to identify with a server expecting one. Would be good with some more info on this function though, it seems a bit undocumented.

I got the CA through running confied.payex.com:443 through a site called ssltest.net and downloading the cert from there.

like image 925
havchr Avatar asked Jun 28 '11 18:06

havchr


2 Answers

I tried to decode the certificate but it does not seem to be valid (actually I tested 2 distinct X509 implementations and both gave me an "incorrect encoding" error).

Can you give more details on the SSL exception?

I did not find much information about the setCertificate method. I think this method expects the server certificate. You should ensure that the certificate you decode is the end entity certificate and not a CA certificate.

like image 150
Jcs Avatar answered Nov 01 '22 02:11

Jcs


The method " setCertificate" is deprecated, so I think that it may not work.I solved a similar problem like yours.If you have your own ssl cacert, you can set networkSecurityConfig .networkSecurityConfig to learn more.

android:networkSecurityConfig="@xml/network_security_config"


<network-security-config>
<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <certificates src="system" overridePins="true" />
    </trust-anchors>
</base-config>
<debug-overrides>
    <trust-anchors>
        <certificates src="system" overridePins="true" />
        <certificates src="user" overridePins="true" />
        <certificates src="@raw/cacert" overridePins="true"></certificates>
    </trust-anchors>
</debug-overrides>
</network-security-config>

if you load a url from assets ,you should also set the follow settings. webSetting.setAllowUniversalAccessFromFileURLs(true);

like image 45
mryushen Avatar answered Nov 01 '22 00:11

mryushen