3

I have an Android application where I use HttpURLConnection for SSL connection to my server. The server certificate contains CRL Distribution Points with valid URI. This certificate was revoked and CRL by URI contains this information. But I don’t receive any exception during the handshake and I can receive any information from my server. I use Android 6 and 7.

I found some posts where developers write that Android disables revocation checks by default. Also, I saw some examples with setting PREFER_CRLS option to PKIXRevocationChecker and setting it to TrustManagerFactory but seems that it applied only for Java SE, when I try this code in my app I receive exception initializing TrustManagerFactory:

java.security.InvalidAlgorithmParameterException: Unsupported spec: javax.net.ssl.CertPathTrustManagerParameters@dccac9. Only android.security.net.config.RootTrustManagerFactorySpi$ApplicationConfigParameters supported
    at android.security.net.config.RootTrustManagerFactorySpi.engineInit(RootTrustManagerFactorySpi.java:44)

network_security_config.xml file is correct:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
     <base-config>
         <trust-anchors>
             <certificates src="@raw/ca_test"/>
         </trust-anchors>
     </base-config>
</network-security-config>

here is my code:

CertificateFactory cf = CertificateFactory.getInstance("X.509");
AssetManager am = getResources().getAssets();
Certificate ca;
try (InputStream caInput = am.open("ca_test.pem")) {
    ca = cf.generateCertificate(caInput);
    Log.d(LOG_TAG, "ca = " + ((X509Certificate) ca).getSubjectDN());
}

// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

KeyManagerFactory kmf =  
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
PKIXRevocationChecker rc =(PKIXRevocationChecker)cpb.getRevocationChecker();
rc.setOptions(EnumSet.of(
    PKIXRevocationChecker.Option.PREFER_CRLS, // prefer CLR over OCSP
    PKIXRevocationChecker.Option.SOFT_FAIL)); // handshake should not fail when CRL is not available
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(keyStore, new X509CertSelector());
pkixParams.addCertPathChecker(rc);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(new CertPathTrustManagerParameters(pkixParams));
kmf.init(keyStore, null);

So I try to understand how can I enable CRL check for my app. Can it be done via shell for root device? Is there any way to override parameters for your own key store? Or there is any way to enable it for system android key store?

Also, I found the bug on this here: https://issuetracker.google.com/issues/36993981 but I don't see any updates for this issue. Someone knows any solution for Android app developers?

IrM
  • 41
  • 5
  • Similar question here - https://stackoverflow.com/questions/49646832/fine-grain-x509-certificate-checks-and-trustmanagerfactory-initialization – MediumOne Aug 11 '18 at 04:17

0 Answers0