Search code examples
javadatedigital-signaturecertificate-revocation

Signature validation with CertPathValidator including CRL revocation


In the context of validating a signature, I want to verify the validity of the signing certificate in the time when the document was signed. I realized that CRL revocation check method is not used if I especify a past date while if I used current time or null, the revocation checks works fine. I am using the next code

 CertificateFactory cf = CertificateFactory.getInstance( "X.509" );
 CertPath certPath =    cf.generateCertPath( certs );
 CertPathValidator cpv = CertPathValidator.getInstance( "PKIX", "SUN" );
PKIXParameters params = new PKIXParameters( ks );
params.setDate( signingTime );
params.setRevocationEnabled( true );                
cpvResult = (PKIXCertPathValidatorResult) cpv.validate( certPath, params ); 

I have already enabled the system property EnabledCRLDP. Besides, OCSP is not an universal solution since it does not works is some certificates.

There is some reason to not use CRL revocation method in a past time validation?

There is some way to force to use CRL in this case?


Solution

  • A Certificate Authority only have the current status of the certificates. It is not possible to request the status at a past date: the CA could have removed the CRLs issued at that date or even all records coud have been cleaned if the certificate has expired

    Therefore a past time validation only can be performed using the CRL or OCSP issued at that date. You need to keep the revocation evidences along with the signature to be used in the future.( There are specific digital signature format designed to contain the revocation evidences like AdES)

    I suspect that the underlying implementation of CertPathValidator is disabling the CRL request if a past date is provided. Note that PKIX does not define how revocation should be checked. See official Java security guide

    The setRevocationEnabled method allows a caller to disable revocation checking. Revocation checking is enabled by default, since it is a required check of the PKIX validation algorithm. However, PKIX does not define how revocation should be checked. An implementation may use CRLs or OCSP, for example.

    Using java 8 you can set the desired set of CRL and/or OCSP response using

     params.setCertStores(certStoreList);. //store containing crls
     PKIXRevocationChecker rc =  (PKIXRevocationChecker)cpv.getRevocationChecker();
     rc.setOcspResponses(responses)
    

    But as you said, this method is not available for java 6, so I think you could disable the revocation check and implement the OCSP and CRL validation manually after validating the certification chain.

    For example use this to validate a certificate using a CRL

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509CRL crl = (X509CRL)cf.generateCRL(inStream); 
    crl.isRevoked(certificate);
    

    OCSP responses can be processed using bouncycastle. See this question OCSP response does not give Certificate Status (omit the part where the ocsp is requested, because you should have a local response stored)