Search in sources :

Example 1 with RevokedCertificateException

use of org.apache.pdfbox.examples.signature.cert.RevokedCertificateException in project documentproduction by qld-gov-au.

the class OcspHelper method verifyOcspResponse.

/**
 * Verifies the status and the response itself (including nonce), but not the signature.
 *
 * @param ocspResponse to be verified
 * @throws OCSPException
 * @throws RevokedCertificateException
 * @throws IOException if the default security provider can't be instantiated
 */
private void verifyOcspResponse(OCSPResp ocspResponse) throws OCSPException, RevokedCertificateException, IOException {
    verifyRespStatus(ocspResponse);
    BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
    if (basicResponse != null) {
        ResponderID responderID = basicResponse.getResponderId().toASN1Primitive();
        // https://tools.ietf.org/html/rfc6960#section-4.2.2.3
        // The basic response type contains:
        // (...)
        // either the name of the responder or a hash of the responder's
        // public key as the ResponderID
        // (...)
        // The responder MAY include certificates in the certs field of
        // BasicOCSPResponse that help the OCSP client verify the responder's
        // signature.
        X500Name name = responderID.getName();
        if (name != null) {
            findResponderCertificateByName(basicResponse, name);
        } else {
            byte[] keyHash = responderID.getKeyHash();
            if (keyHash != null) {
                findResponderCertificateByKeyHash(basicResponse, keyHash);
            } else {
                throw new OCSPException("OCSP: basic response must provide name or key hash");
            }
        }
        if (ocspResponderCertificate == null) {
            throw new OCSPException("OCSP: certificate for responder " + name + " not found");
        }
        try {
            SigUtils.checkResponderCertificateUsage(ocspResponderCertificate);
        } catch (CertificateParsingException ex) {
            // unlikely to happen because the certificate existed as an object
            LOG.error(ex.getMessage(), ex);
        }
        checkOcspSignature(ocspResponderCertificate, basicResponse);
        boolean nonceChecked = checkNonce(basicResponse);
        SingleResp[] responses = basicResponse.getResponses();
        if (responses.length != 1) {
            throw new OCSPException("OCSP: Received " + responses.length + " responses instead of 1!");
        }
        SingleResp resp = responses[0];
        Object status = resp.getCertStatus();
        if (!nonceChecked) {
            // https://tools.ietf.org/html/rfc5019
            // fall back to validating the OCSPResponse based on time
            checkOcspResponseFresh(resp);
        }
        if (status instanceof RevokedStatus) {
            RevokedStatus revokedStatus = (RevokedStatus) status;
            if (revokedStatus.getRevocationTime().compareTo(signDate) <= 0) {
                throw new RevokedCertificateException("OCSP: Certificate is revoked since " + revokedStatus.getRevocationTime(), revokedStatus.getRevocationTime());
            }
            LOG.info("The certificate was revoked after signing by OCSP " + ocspUrl + " on " + revokedStatus.getRevocationTime());
        } else if (status != CertificateStatus.GOOD) {
            throw new OCSPException("OCSP: Status of Cert is unknown");
        }
    }
}
Also used : CertificateParsingException(java.security.cert.CertificateParsingException) RevokedStatus(org.bouncycastle.cert.ocsp.RevokedStatus) RevokedCertificateException(org.apache.pdfbox.examples.signature.cert.RevokedCertificateException) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) ResponderID(org.bouncycastle.asn1.ocsp.ResponderID) X500Name(org.bouncycastle.asn1.x500.X500Name) SingleResp(org.bouncycastle.cert.ocsp.SingleResp)

Example 2 with RevokedCertificateException

use of org.apache.pdfbox.examples.signature.cert.RevokedCertificateException in project documentproduction by qld-gov-au.

the class CRLVerifier method verifyCertificateCRLs.

/**
 * Extracts the CRL distribution points from the certificate (if available)
 * and checks the certificate revocation status against the CRLs coming from
 * the distribution points. Supports HTTP, HTTPS, FTP and LDAP based URLs.
 *
 * @param cert the certificate to be checked for revocation
 * @param signDate the date when the signing took place
 * @param additionalCerts set of trusted root CA certificates that will be
 * used as "trust anchors" and intermediate CA certificates that will be
 * used as part of the certification chain.
 * @throws CertificateVerificationException if the certificate could not be verified
 * @throws RevokedCertificateException if the certificate is revoked
 */
public static void verifyCertificateCRLs(X509Certificate cert, Date signDate, Set<X509Certificate> additionalCerts) throws CertificateVerificationException, RevokedCertificateException {
    try {
        Date now = Calendar.getInstance().getTime();
        Exception firstException = null;
        List<String> crlDistributionPointsURLs = getCrlDistributionPoints(cert);
        for (String crlDistributionPointsURL : crlDistributionPointsURLs) {
            LOG.info("Checking distribution point URL: " + crlDistributionPointsURL);
            X509CRL crl;
            try {
                crl = downloadCRL(crlDistributionPointsURL);
            } catch (Exception ex) {
                // e.g. LDAP behind corporate proxy
                LOG.warn("Caught " + ex.getClass().getSimpleName() + " downloading CRL, will try next distribution point if available");
                if (firstException == null) {
                    firstException = ex;
                }
                continue;
            }
            Set<X509Certificate> mergedCertSet = CertificateVerifier.downloadExtraCertificates(crl);
            mergedCertSet.addAll(additionalCerts);
            // Verify CRL, see wikipedia:
            // "To validate a specific CRL prior to relying on it,
            // the certificate of its corresponding CA is needed"
            X509Certificate crlIssuerCert = null;
            for (X509Certificate possibleCert : mergedCertSet) {
                try {
                    cert.verify(possibleCert.getPublicKey(), SecurityProvider.getProvider().getName());
                    crlIssuerCert = possibleCert;
                    break;
                } catch (GeneralSecurityException ex) {
                // not the issuer
                }
            }
            if (crlIssuerCert == null) {
                throw new CertificateVerificationException("Certificate for " + crl.getIssuerX500Principal() + "not found in certificate chain, so the CRL at " + crlDistributionPointsURL + " could not be verified");
            }
            crl.verify(crlIssuerCert.getPublicKey(), SecurityProvider.getProvider().getName());
            if (!crl.getIssuerX500Principal().equals(cert.getIssuerX500Principal())) {
                LOG.info("CRL issuer certificate is not identical to cert issuer, check needed");
                CertificateVerifier.verifyCertificate(crlIssuerCert, mergedCertSet, true, now);
                LOG.info("CRL issuer certificate checked successfully");
            } else {
                LOG.info("CRL issuer certificate is identical to cert issuer, no extra check needed");
            }
            checkRevocation(crl, cert, signDate, crlDistributionPointsURL);
            // => thus no need to check several protocols
            return;
        }
        if (firstException != null) {
            throw firstException;
        }
    } catch (CertificateVerificationException ex) {
        throw ex;
    } catch (RevokedCertificateException ex) {
        throw ex;
    } catch (Exception ex) {
        throw new CertificateVerificationException("Cannot verify CRL for certificate: " + cert.getSubjectX500Principal(), ex);
    }
}
Also used : X509CRL(java.security.cert.X509CRL) RevokedCertificateException(org.apache.pdfbox.examples.signature.cert.RevokedCertificateException) CertificateVerificationException(org.apache.pdfbox.examples.signature.cert.CertificateVerificationException) GeneralSecurityException(java.security.GeneralSecurityException) ASN1OctetString(org.bouncycastle.asn1.ASN1OctetString) DERIA5String(org.bouncycastle.asn1.DERIA5String) Date(java.util.Date) NamingException(javax.naming.NamingException) GeneralSecurityException(java.security.GeneralSecurityException) CertificateVerificationException(org.apache.pdfbox.examples.signature.cert.CertificateVerificationException) RevokedCertificateException(org.apache.pdfbox.examples.signature.cert.RevokedCertificateException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) ExecutionException(java.util.concurrent.ExecutionException) CRLException(java.security.cert.CRLException) X509Certificate(java.security.cert.X509Certificate)

Example 3 with RevokedCertificateException

use of org.apache.pdfbox.examples.signature.cert.RevokedCertificateException in project documentproduction by qld-gov-au.

the class CertificateVerifier method verifyOCSP.

/**
 * Verify whether the certificate has been revoked at signing date, and verify whether the
 * certificate of the responder has been revoked now.
 *
 * @param ocspHelper the OCSP helper.
 * @param additionalCerts
 * @throws RevokedCertificateException
 * @throws IOException
 * @throws OCSPException
 * @throws CertificateVerificationException
 */
private static void verifyOCSP(OcspHelper ocspHelper, Set<X509Certificate> additionalCerts) throws RevokedCertificateException, IOException, OCSPException, CertificateVerificationException {
    Date now = Calendar.getInstance().getTime();
    OCSPResp ocspResponse = ocspHelper.getResponseOcsp();
    if (ocspResponse.getStatus() != OCSPResp.SUCCESSFUL) {
        throw new CertificateVerificationException("OCSP check not successful, status: " + ocspResponse.getStatus());
    }
    LOG.info("OCSP check successful");
    BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
    X509Certificate ocspResponderCertificate = ocspHelper.getOcspResponderCertificate();
    if (ocspResponderCertificate.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId()) != null) {
        // https://tools.ietf.org/html/rfc6960#section-4.2.2.2.1
        // A CA may specify that an OCSP client can trust a responder for the
        // lifetime of the responder's certificate.  The CA does so by
        // including the extension id-pkix-ocsp-nocheck.
        LOG.info("Revocation check of OCSP responder certificate skipped (id-pkix-ocsp-nocheck is set)");
        return;
    }
    if (ocspHelper.getCertificateToCheck().equals(ocspResponderCertificate)) {
        LOG.info("OCSP responder certificate is identical to certificate to check");
        return;
    }
    LOG.info("Check of OCSP responder certificate");
    Set<X509Certificate> additionalCerts2 = new HashSet<X509Certificate>(additionalCerts);
    JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter();
    for (X509CertificateHolder certHolder : basicResponse.getCerts()) {
        try {
            X509Certificate cert = certificateConverter.getCertificate(certHolder);
            if (!ocspResponderCertificate.equals(cert)) {
                additionalCerts2.add(cert);
            }
        } catch (CertificateException ex) {
            // unlikely to happen because the certificate existed as an object
            LOG.error(ex.getMessage(), ex);
        }
    }
    CertificateVerifier.verifyCertificate(ocspResponderCertificate, additionalCerts2, true, now);
    LOG.info("Check of OCSP responder certificate done");
}
Also used : CertificateVerificationException(org.apache.pdfbox.examples.signature.cert.CertificateVerificationException) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) RevokedCertificateException(org.apache.pdfbox.examples.signature.cert.RevokedCertificateException) CertificateException(java.security.cert.CertificateException) Date(java.util.Date) X509Certificate(java.security.cert.X509Certificate) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) HashSet(java.util.HashSet)

Aggregations

RevokedCertificateException (org.apache.pdfbox.examples.signature.cert.RevokedCertificateException)3 CertificateException (java.security.cert.CertificateException)2 X509Certificate (java.security.cert.X509Certificate)2 Date (java.util.Date)2 CertificateVerificationException (org.apache.pdfbox.examples.signature.cert.CertificateVerificationException)2 BasicOCSPResp (org.bouncycastle.cert.ocsp.BasicOCSPResp)2 IOException (java.io.IOException)1 GeneralSecurityException (java.security.GeneralSecurityException)1 CRLException (java.security.cert.CRLException)1 CertificateParsingException (java.security.cert.CertificateParsingException)1 X509CRL (java.security.cert.X509CRL)1 HashSet (java.util.HashSet)1 ExecutionException (java.util.concurrent.ExecutionException)1 NamingException (javax.naming.NamingException)1 ASN1OctetString (org.bouncycastle.asn1.ASN1OctetString)1 DERIA5String (org.bouncycastle.asn1.DERIA5String)1 ResponderID (org.bouncycastle.asn1.ocsp.ResponderID)1 X500Name (org.bouncycastle.asn1.x500.X500Name)1 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)1 JcaX509CertificateConverter (org.bouncycastle.cert.jcajce.JcaX509CertificateConverter)1