use of org.bouncycastle.cert.ocsp.SingleResp in project ddf by codice.
the class OcspChecker method getStatusFromOcspResponse.
/**
* Gets the {@link CertificateStatus} from the given {@param ocspResponse}.
*
* @param ocspResponse - the {@link OCSPResp} to get the {@link CertificateStatus} from.
* @return the {@link CertificateStatus} from the given {@param ocspResponse}. Returns an {@link
* UnknownStatus} if the status could not be found.
*/
private CertificateStatus getStatusFromOcspResponse(OCSPResp ocspResponse, X509Certificate certificate) {
try {
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
if (basicResponse == null) {
return new UnknownStatus();
}
SingleResp[] singleResps = basicResponse.getResponses();
if (singleResps == null) {
return new UnknownStatus();
}
SingleResp response = Arrays.stream(singleResps).filter(singleResp -> singleResp.getCertID() != null).filter(singleResp -> singleResp.getCertID().getSerialNumber().equals(certificate.getSerialNumber())).findFirst().orElse(null);
if (response == null) {
LOGGER.debug("Certificate status from OCSP response is unknown.");
return new UnknownStatus();
}
if (response.getCertStatus() == null) {
LOGGER.debug("Certificate status from OCSP response is good.");
return CertificateStatus.GOOD;
}
return response.getCertStatus();
} catch (OCSPException e) {
return new UnknownStatus();
}
}
use of org.bouncycastle.cert.ocsp.SingleResp in project ddf by codice.
the class OcspChecker method logResponse.
private void logResponse(OCSPResp response) {
BasicOCSPResp basicOCSPResp;
BasicOCSPResponse basicOCSPResponse;
try {
basicOCSPResp = (BasicOCSPResp) response.getResponseObject();
basicOCSPResponse = BasicOCSPResponse.getInstance(((BasicOCSPResp) response.getResponseObject()).getEncoded());
StringBuilder logBuilder = new StringBuilder();
logBuilder.append("OCSP Response: \n");
logBuilder.append(" responseStatus: " + getValueOrDefault(response.getStatus(), "") + "\n");
logBuilder.append(" responseBytes:\n");
logBuilder.append(" responseType: " + getValueOrDefault(basicOCSPResponse, "").getClass().getSimpleName() + "\n");
logBuilder.append(" response:\n");
logBuilder.append(" tbsResponseData:\n");
if (basicOCSPResponse.getTbsResponseData() != null) {
logBuilder.append(" version: " + getValueOrDefault(basicOCSPResponse.getTbsResponseData().getVersion(), "").toString() + "\n");
logBuilder.append(" responderId:\n");
if (basicOCSPResponse.getTbsResponseData().getResponderID() != null) {
logBuilder.append(" byName: " + getValueOrDefault(basicOCSPResponse.getTbsResponseData().getResponderID().getName(), "").toString() + "\n");
logBuilder.append(" byKey: " + getValueOrDefault(Arrays.toString(basicOCSPResponse.getTbsResponseData().getResponderID().getKeyHash()), "") + "\n");
} else {
logBuilder.append(" byName:\n");
}
if (basicOCSPResponse.getTbsResponseData().getProducedAt() != null) {
logBuilder.append(" producedAt: " + getValueOrDefault(basicOCSPResponse.getTbsResponseData().getProducedAt().getTimeString(), "") + "\n");
} else {
logBuilder.append(" producedAt:\n");
}
}
logBuilder.append(" responses:\n");
if (basicOCSPResp.getResponses() != null) {
SingleResp[] singleResps = basicOCSPResp.getResponses();
for (int i = 0; i < singleResps.length; i++) {
CertificateID certificateID = singleResps[i].getCertID();
if (certificateID != null) {
logBuilder.append(" certID #: " + i + "\n");
logBuilder.append(" hashAlgorithm: " + getValueOrDefault(certificateID.getHashAlgOID(), "").toString() + "\n");
logBuilder.append(" issuerNameHash: " + getValueOrDefault(Arrays.toString(certificateID.getIssuerNameHash()), "") + "\n");
logBuilder.append(" issuerKeyHash: " + getValueOrDefault(Arrays.toString(certificateID.getIssuerKeyHash()), "") + "\n");
logBuilder.append(" cert serial number: " + getValueOrDefault(certificateID.getSerialNumber(), "") + "\n");
logBuilder.append(" certStatus: " + getValueOrDefault(singleResps[i].getCertStatus(), "good").getClass().getSimpleName() + "\n");
logBuilder.append(" thisUpdate: " + getValueOrDefault(singleResps[i].getThisUpdate(), "").toString() + "\n");
logBuilder.append(" nextUpdate: " + getValueOrDefault(singleResps[i].getNextUpdate(), "").toString() + "\n");
}
}
}
if (basicOCSPResp.getSignatureAlgorithmID() != null) {
logBuilder.append(" signatureAlgorithm: " + getValueOrDefault(basicOCSPResp.getSignatureAlgorithmID().getAlgorithm(), "").toString() + "\n");
}
logBuilder.append(" signature: " + getValueOrDefault(Arrays.toString(basicOCSPResp.getSignature()), "") + "\n");
logBuilder.append(" certs:\n");
if (basicOCSPResp.getCerts() != null) {
X509CertificateHolder[] x509CertificateHolders = basicOCSPResp.getCerts();
for (int i = 0; i < x509CertificateHolders.length; i++) {
logBuilder.append(" certificate: " + i + "\n");
logBuilder.append(" issuer: " + getValueOrDefault(x509CertificateHolders[i].getIssuer(), "").toString() + "\n");
logBuilder.append(" subject: " + getValueOrDefault(x509CertificateHolders[i].getSubject(), "").toString() + "\n");
if (basicOCSPResp.getSignatureAlgorithmID() != null) {
logBuilder.append(" signatureAlgorithm: " + getValueOrDefault(x509CertificateHolders[i].getSignatureAlgorithm().getAlgorithm(), "").toString() + "\n");
}
logBuilder.append(" start date: " + getValueOrDefault(x509CertificateHolders[i].toASN1Structure().getStartDate(), "").toString() + "\n");
logBuilder.append(" end date: " + getValueOrDefault(x509CertificateHolders[i].toASN1Structure().getEndDate(), "").toString() + "\n");
logBuilder.append(" cert serial number: " + getValueOrDefault(x509CertificateHolders[i].getSerialNumber(), "") + "\n");
}
}
LOGGER.trace(logBuilder.toString());
} catch (IOException | OCSPException e) {
LOGGER.trace("Could not log response, issue converting response to a BasicOcspResponse.", e);
}
}
use of org.bouncycastle.cert.ocsp.SingleResp in project pdfbox by apache.
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, 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.bouncycastle.cert.ocsp.SingleResp in project oxAuth by GluuFederation.
the class OCSPCertificateVerifier method validate.
@Override
public ValidationStatus validate(X509Certificate certificate, List<X509Certificate> issuers, Date validationDate) {
X509Certificate issuer = issuers.get(0);
ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate, ValidatorSourceType.OCSP, CertificateValidity.UNKNOWN);
try {
Principal subjectX500Principal = certificate.getSubjectX500Principal();
String ocspUrl = getOCSPUrl(certificate);
if (ocspUrl == null) {
log.error("OCSP URL for '" + subjectX500Principal + "' is empty");
return status;
}
log.debug("OCSP URL for '" + subjectX500Principal + "' is '" + ocspUrl + "'");
DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build().get(CertificateID.HASH_SHA1);
CertificateID certificateId = new CertificateID(digestCalculator, new JcaX509CertificateHolder(certificate), certificate.getSerialNumber());
// Generate OCSP request
OCSPReq ocspReq = generateOCSPRequest(certificateId);
// Get OCSP response from server
OCSPResp ocspResp = requestOCSPResponse(ocspUrl, ocspReq);
if (ocspResp.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
log.error("OCSP response is invalid!");
status.setValidity(CertificateValidity.INVALID);
return status;
}
boolean foundResponse = false;
BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResp.getResponseObject();
SingleResp[] singleResps = basicOCSPResp.getResponses();
for (SingleResp singleResp : singleResps) {
CertificateID responseCertificateId = singleResp.getCertID();
if (!certificateId.equals(responseCertificateId)) {
continue;
}
foundResponse = true;
log.debug("OCSP validationDate: " + validationDate);
log.debug("OCSP thisUpdate: " + singleResp.getThisUpdate());
log.debug("OCSP nextUpdate: " + singleResp.getNextUpdate());
status.setRevocationObjectIssuingTime(basicOCSPResp.getProducedAt());
Object certStatus = singleResp.getCertStatus();
if (certStatus == CertificateStatus.GOOD) {
log.debug("OCSP status is valid for '" + certificate.getSubjectX500Principal() + "'");
status.setValidity(CertificateValidity.VALID);
} else {
if (singleResp.getCertStatus() instanceof RevokedStatus) {
log.warn("OCSP status is revoked for: " + subjectX500Principal);
if (validationDate.before(((RevokedStatus) singleResp.getCertStatus()).getRevocationTime())) {
log.warn("OCSP revocation time after the validation date, the certificate '" + subjectX500Principal + "' was valid at " + validationDate);
status.setValidity(CertificateValidity.VALID);
} else {
Date revocationDate = ((RevokedStatus) singleResp.getCertStatus()).getRevocationTime();
log.info("OCSP for certificate '" + subjectX500Principal + "' is revoked since " + revocationDate);
status.setRevocationDate(revocationDate);
status.setRevocationObjectIssuingTime(singleResp.getThisUpdate());
status.setValidity(CertificateValidity.REVOKED);
}
}
}
}
if (!foundResponse) {
log.error("There is no matching OCSP response entries");
}
} catch (Exception ex) {
log.error("OCSP exception: ", ex);
}
return status;
}
use of org.bouncycastle.cert.ocsp.SingleResp in project nifi by apache.
the class OcspCertificateValidator method getOcspStatus.
/**
* Gets the OCSP status for the specified subject and issuer certificates.
*
* @param ocspStatusKey status key
* @return ocsp status
*/
private OcspStatus getOcspStatus(final OcspRequest ocspStatusKey) {
final X509Certificate subjectCertificate = ocspStatusKey.getSubjectCertificate();
final X509Certificate issuerCertificate = ocspStatusKey.getIssuerCertificate();
// initialize the default status
final OcspStatus ocspStatus = new OcspStatus();
ocspStatus.setVerificationStatus(VerificationStatus.Unknown);
ocspStatus.setValidationStatus(ValidationStatus.Unknown);
try {
// prepare the request
final BigInteger subjectSerialNumber = subjectCertificate.getSerialNumber();
final DigestCalculatorProvider calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build();
final CertificateID certificateId = new CertificateID(calculatorProviderBuilder.get(CertificateID.HASH_SHA1), new X509CertificateHolder(issuerCertificate.getEncoded()), subjectSerialNumber);
// generate the request
final OCSPReqBuilder requestGenerator = new OCSPReqBuilder();
requestGenerator.addRequest(certificateId);
// Create a nonce to avoid replay attack
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, new DEROctetString(nonce.toByteArray()));
requestGenerator.setRequestExtensions(new Extensions(new Extension[] { ext }));
final OCSPReq ocspRequest = requestGenerator.build();
// perform the request
final Response response = getClientResponse(ocspRequest);
// ensure the request was completed successfully
if (Response.Status.OK.getStatusCode() != response.getStatusInfo().getStatusCode()) {
logger.warn(String.format("OCSP request was unsuccessful (%s).", response.getStatus()));
return ocspStatus;
}
// interpret the response
OCSPResp ocspResponse = new OCSPResp(response.readEntity(InputStream.class));
// verify the response status
switch(ocspResponse.getStatus()) {
case OCSPRespBuilder.SUCCESSFUL:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Successful);
break;
case OCSPRespBuilder.INTERNAL_ERROR:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.InternalError);
break;
case OCSPRespBuilder.MALFORMED_REQUEST:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.MalformedRequest);
break;
case OCSPRespBuilder.SIG_REQUIRED:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.SignatureRequired);
break;
case OCSPRespBuilder.TRY_LATER:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.TryLater);
break;
case OCSPRespBuilder.UNAUTHORIZED:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unauthorized);
break;
default:
ocspStatus.setResponseStatus(OcspStatus.ResponseStatus.Unknown);
break;
}
// only proceed if the response was successful
if (ocspResponse.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
logger.warn(String.format("OCSP request was unsuccessful (%s).", ocspStatus.getResponseStatus().toString()));
return ocspStatus;
}
// ensure the appropriate response object
final Object ocspResponseObject = ocspResponse.getResponseObject();
if (ocspResponseObject == null || !(ocspResponseObject instanceof BasicOCSPResp)) {
logger.warn(String.format("Unexpected OCSP response object: %s", ocspResponseObject));
return ocspStatus;
}
// get the response object
final BasicOCSPResp basicOcspResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
// attempt to locate the responder certificate
final X509CertificateHolder[] responderCertificates = basicOcspResponse.getCerts();
if (responderCertificates.length != 1) {
logger.warn(String.format("Unexpected number of OCSP responder certificates: %s", responderCertificates.length));
return ocspStatus;
}
// get the responder certificate
final X509Certificate trustedResponderCertificate = getTrustedResponderCertificate(responderCertificates[0], issuerCertificate);
if (trustedResponderCertificate != null) {
// verify the response
if (basicOcspResponse.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider("BC").build(trustedResponderCertificate.getPublicKey()))) {
ocspStatus.setVerificationStatus(VerificationStatus.Verified);
} else {
ocspStatus.setVerificationStatus(VerificationStatus.Unverified);
}
} else {
ocspStatus.setVerificationStatus(VerificationStatus.Unverified);
}
// validate the response
final SingleResp[] responses = basicOcspResponse.getResponses();
for (SingleResp singleResponse : responses) {
final CertificateID responseCertificateId = singleResponse.getCertID();
final BigInteger responseSerialNumber = responseCertificateId.getSerialNumber();
if (responseSerialNumber.equals(subjectSerialNumber)) {
Object certStatus = singleResponse.getCertStatus();
// interpret the certificate status
if (CertificateStatus.GOOD == certStatus) {
ocspStatus.setValidationStatus(ValidationStatus.Good);
} else if (certStatus instanceof RevokedStatus) {
ocspStatus.setValidationStatus(ValidationStatus.Revoked);
} else {
ocspStatus.setValidationStatus(ValidationStatus.Unknown);
}
}
}
} catch (final OCSPException | IOException | ProcessingException | OperatorCreationException e) {
logger.error(e.getMessage(), e);
} catch (CertificateException e) {
e.printStackTrace();
}
return ocspStatus;
}
Aggregations