I'm currently writing a network TCP server using SSL. In production, we'll finally require clients to authenticate with a certificate.
In order to revoke certificates in case of a emergency, we would also like to establish a CRL.
My question is: Does Java check CRLs (if provided with the certificate) out of the box or do I need to manually implement such checks?
For testing, I prepared a certificate with a CRL set but Java does not seem to try to validate it (I dropped it into a local web server and there's no access).
I only found the com.sun.net.ssl.checkRevocation=true VM option, but apparently it doesn't query the CRL. VM debugging set to java.security.debug=certpath does not generate any output, either...
Java seems to have related classes in its subsystems (e.g. java.security.cert.X509CRLSelector), but it does not come into play, obviously.
edit: Removed outdated Dropbox link
I figured how to enable CRL checking within a SSLContext without implementing a custom validator, as suggested in the comments.
It is mainly about properly initializing the SSLContext's TrustManagers with a revocation checker, only a few lines, no custom check logic and the CRL is now checked automatically as well as the verification path.
Here's a snippet...
KeyStore ts = KeyStore.getInstance("JKS");
FileInputStream tfis = new FileInputStream(trustStorePath);
ts.load(tfis, trustStorePass.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// initialize certification path checking for the offered certificates and revocation checks against CLRs
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
rc.setOptions(EnumSet.of(
PKIXRevocationChecker.Option.PREFER_CRLS, // prefer CLR over OCSP
PKIXRevocationChecker.Option.ONLY_END_ENTITY,
PKIXRevocationChecker.Option.NO_FALLBACK)); // don't fall back to OCSP checking
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(ts, new X509CertSelector());
pkixParams.addCertPathChecker(rc);
tmf.init( new CertPathTrustManagerParameters(pkixParams) );
// init KeyManagerFactory
kmf.init(...)
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers), tmf.getTrustManagers(), null);
That essentially did what I needed in my application, checking whether a certificate issued to a client is revoked in our CRL. Only checking the end entity and allowing the CRL check to fail is accepted because its all our infrastructure.