Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android manual X509 certificate chain validation

I have implemented javax.net.ssl.X509TrustManager in my code so I can validate my self-signed cert, which my software accesses. However, I still need to validate some other "standard" website SSL certificates. I am using CertPathValidator.validate() to do that, but I just realized that one cert chain I am being passed (for maps.googleapis.com) doesn't actually contain the complete chain - it contains the whole chain but the Root CA (Equifax), which does exist on the phone, but validate() still fails because (apparently) it's not explicitly in the chain. What am I missing here, so that the validation succeeds? Thanks for any input.

Edit - Relevant code (with exception checking removed):

CertificateFactory cf = CertificateFactory.getInstance("X.509");
// chain is of type X509Certificate[]
CertPath cp = cf.generateCertPath(Arrays.asList(chain));

CertPathValidator cpv = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

FileInputStream is = new FileInputStream("/system/etc/security/cacerts.bks");
ks.load(is, null);

PKIXParameters params = new PKIXParameters(ks);
CertPathValidatorResult cpvr = cpv.validate(cp, params);
like image 608
Conrad Avatar asked Nov 04 '22 10:11

Conrad


1 Answers

Implementing your own TrustManager is generally a bad idea. The better way is to add your certificates to a keystore, and add it as a trust store. See this for an example of how to do it.

You probably need to add the default trust store to your validator. Also, Android does not do revocation (CRL) checking by default, so if you enabled it, you need to get the related CRL's manually. Post your code.

like image 136
Nikolay Elenkov Avatar answered Nov 09 '22 05:11

Nikolay Elenkov