Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check if an X509 certificate has been revoked in Java?

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.

like image 704
MickeyThreeSheds Avatar asked Feb 02 '17 17:02

MickeyThreeSheds


People also ask

How do you check if certificate is revoked or not?

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.

What identifies certificates that have 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".


2 Answers

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

  • open the certificate
  • go to Details Tab and find the field "CRL Distribution Point" in the details list

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

like image 143
Rajiv Kapoor Avatar answered Oct 19 '22 16:10

Rajiv Kapoor


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:

  1. Extract the CRL distribution point and OCSP url from AIA extension included in the X509Certificate

  2. 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)

  3. 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).

  4. 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();
like image 30
pedrofb Avatar answered Oct 19 '22 17:10

pedrofb