Search code examples
certificatecertificate-authorityjavavalidation

How get X509 certificate's full cert chain programatically?


Imagine I have p12 container of private key and public certificate. When I export p12 public cert to separate .cer file with Java keytool I may click to .cer file and see full cert chain. How may I get that full path programatically?

I made little investigation. I used keytool's print cert -v command and saw property AuthorityInfoAccess with subproperty

accessMethod: caIssuers
accessLocation: URIName: http://.../some.crt

I downloaded that some.crt (it was PEM cert), and again used print cert -v and again saw accessLocation: URIName: http://.../some2.crt and repeated downloading .crt files and geting parent until reaching root .crt which hasn't such property.

I think, that I should programatically download chain as I described above and provide it to CertPathValidator as shown here.

If I really need to get chain as I described above, is there any libraries already doing this? Is there any way to do it with std lib? I didn't find bouncycastle examples and java's standart library code like

java.security.cert.Certificate[] cchain = keystore.getCertificateChain(alias);

returns one entry for certificate actually having 2 "parents".


Solution

  • Nitpick: you surely mean keytool -printcert (with hyphen, without space, -v not needed here).

    A privatekey entry created by Java in JKS or PKCS12 usually contains the full chain, but keytool -exportcert extracts only the leaf cert. A PKCS12 created by something else may contain the full chain or not, possibly depending on what you clicked when creating it. If the chain is there, KeyStore.getCertificateChain returns it, and keytool -list -v (here -v matters) shows it.

    If a certificate was imported, or reimported, as a trustedcert entry -- usually in JKS, PKCS12 isn't designed for lone certs -- that never contains the chain, so getCertificateChain on that entry won't work, but IIRC CertPathBuilder can build a chain combining multiple trustedcert entries in one store.

    If you do need a parent (chain) cert you don't already have, and the child specifies AIA.caIssuers, then yes using that to fetch is sensible. I'm pretty sure there is nothing in standard Java (JRE) library that does this for you, at least so far; I don't know about BouncyCastle or anybody else.