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");
}
}
}
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);
}
}
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");
}
Aggregations