I have googled around all over the place for this, and asked in other communities, and I keep getting forwarded to the oracle document that discusses the spec. However, that document more covers the naming of methods, and the overall architecture, and doesn't actually come up with a way to discuss how to actually write some code to check if an x509 cert is revoked or not.
Maybe this one is just way over my head? But I would definitely appreciate if someone could just help me out with a snippet, I have been banging my head against a wall on this for about a week.
To check the revocation status of an SSL Certificate, the client connects to the URLs and downloads the CA's CRLs. Then, the client searches through the CRL for the serial number of the certificate to make sure that it hasn't been revoked.
In cryptography, a certificate revocation list (or CRL) is "a list of digital certificates that have been revoked by the issuing certificate authority (CA) before their scheduled expiration date and should no longer be trusted".
Every CA publishes the list of the certificates it has revoked. This list includes the serial number of the certificates and the revocation date
to get the url of the certificate revocation list (CRL) follow the below steps
It will show you the value something like this
[1]CRL Distribution Point Distribution Point Name: Full Name: URL=mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl URL=crl.microsoft.com/pki/mscorp/crl/msitwww2.crl
So in your code you need to download these files and check for the certificate serial number in them to see if it's revoked or not
Find below the sample code for it
public class CertVerification {
public static void main(String[] args) throws Exception {
String certificatePath = "C:\\Users\\user1\\Desktop\\test.cer";
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate certificate = null;
X509CRLEntry revokedCertificate = null;
X509CRL crl = null;
certificate = (X509Certificate) cf.generateCertificate(new FileInputStream(new File(certificatePath)));
URL url = new URL("http://<someUrl from certificate>.crl");
URLConnection connection = url.openConnection();
try(DataInputStream inStream = new DataInputStream(connection.getInputStream())){
crl = (X509CRL)cf.generateCRL(inStream);
}
revokedCertificate = crl.getRevokedCertificate(certificate.getSerialNumber());
if(revokedCertificate !=null){
System.out.println("Revoked");
}
else{
System.out.println("Valid");
}
}
}
Please See
These lists are updated periodically
You can get these Revocation URL's from the certificate as well, i have just given an example
This is just a basic example to give you a head start
Update
I found this sample class to check certificate, it also verifies with the CRL issued by the certificate's CA and certification chain, so you don't need to provide the CRL url as well
https://svn.cesecore.eu/svn/ejbca/branches/Branch_3_2_3_utf8/ejbca/doc/samples/ValidateCertUseCRL.java
A Certification Authority publish the status of the certificates using Online Certificate Service Protocol (OCSP) and Certificate Revocation Lists (CRL).
Check the revocation of a certificate involves several steps:
Extract the CRL distribution point and OCSP url from AIA extension included in the X509Certificate
Download the CRL and check if the serial number of your certificate is included. Verify the signing certificate of the CRL and ensure is trusted (root CA in your truststore)
Query online the OCSP service sending the serial number and the issuer to get the status. Check the signature of the OCSP response and ensure signing certificate is trusted (root CA in your truststore).
Certificate is revoked if it is present in CRL or OCSP status is revoked. OCSP is recommended over CRLs, but it usual to query both service because could be down.
As you can see the process is not simple at all. Check if a certificate is valid may consists in several invocations to OCSP service, downloading the certificate chain, verify signature of signing certificate of the CRLs and OCSP responses, and finally verify that the CA is trusted
So I recommend not to use Java native methods directly if you are not going to take into account all these factors
You can use BouncyCastle to manage CRL and query OCSP, but a better decision would be to use the SD-DSS framework (it uses also BouncyCastle), that pretty encapsulates all this stuff.
Github SD-DSS: https://github.com/esig/dss Documentation: http://dss.nowina.lu/doc/dss-documentation.html
Example
Full example to validate a certificate checking revocation. Omit the steps of loading the trusted source and intermediates if you only want to check revocation
//Load the certification chain, including the intemediate certificates and the trusted root.
CertificateToken issuerCert = DSSUtils.loadCertificate("/trusted.crt");
CommonTrustedCertificateSource trustedCertificateSource = new CommonTrustedCertificateSource();
trustedCertificateSource.addCertificate(issuerCert);
CommonCertificateSource adjunctCertificateSource = new CommonCertificateSource();
CertificateToken intermediateCert = DSSUtils.loadCertificate("/intermediate.cer");
adjunctCertificateSource.addCertificate(intermediateCert);
//Load the certificate to verify
CertificateToken toValidateX509Certificate = DSSUtils.loadCertificate("/toValidate.crt");
CertificateToken toValidateCertificateToken = adjunctCertificateSource.addCertificate(toValidateX509Certificate);
//Configure the certificate verifier using the trust store and the intermediate certificates
//OnlineOCSPSource and OnlineCRLSource will invoke the OCSP service and CRL
//distribution point extracting the URL from the certificate
CertificateVerifier certificateVerifier = new CommonCertificateVerifier();
certificateVerifier.setTrustedCertSource(trustedCertificateSource);
certificateVerifier.setAdjunctCertSource(adjunctCertificateSource);
certificateVerifier.setCrlSource(new OnlineCRLSource());
certificateVerifier.setOcspSource(new OnlineOCSPSource());
//Perform validation
CertificatePool validationPool = certificateVerifier.createValidationPool();
SignatureValidationContext validationContext = new SignatureValidationContext(validationPool);
validationContext.addCertificateTokenForVerification(toValidateCertificateToken);
validationContext.validate();
//Get revocation status
Boolean isRevoked = toValidateCertificateToken.isRevoked();
RevocationToken revocationToken = toValidateCertificateToken.getRevocationToken();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With