use of org.bouncycastle.cert.ocsp.OCSPResp 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.OCSPResp 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;
}
use of org.bouncycastle.cert.ocsp.OCSPResp in project xipki by xipki.
the class BaseOcspStatusAction method execute0.
@Override
protected final Object execute0() throws Exception {
if (StringUtil.isBlank(serialNumberList) && isEmpty(certFiles)) {
throw new IllegalCmdParamException("Neither serialNumbers nor certFiles is set");
}
X509Certificate issuerCert = X509Util.parseCert(issuerCertFile);
Map<BigInteger, byte[]> encodedCerts = null;
List<BigInteger> sns = new LinkedList<>();
if (isNotEmpty(certFiles)) {
encodedCerts = new HashMap<>(certFiles.size());
String ocspUrl = null;
X500Name issuerX500Name = null;
for (String certFile : certFiles) {
BigInteger sn;
List<String> ocspUrls;
if (isAttrCert) {
if (issuerX500Name == null) {
issuerX500Name = X500Name.getInstance(issuerCert.getSubjectX500Principal().getEncoded());
}
X509AttributeCertificateHolder cert = new X509AttributeCertificateHolder(IoUtil.read(certFile));
// no signature validation
AttributeCertificateIssuer reqIssuer = cert.getIssuer();
if (reqIssuer != null && issuerX500Name != null) {
X500Name reqIssuerName = reqIssuer.getNames()[0];
if (!issuerX500Name.equals(reqIssuerName)) {
throw new IllegalCmdParamException("certificate " + certFile + " is not issued by the given issuer");
}
}
ocspUrls = extractOcspUrls(cert);
sn = cert.getSerialNumber();
} else {
X509Certificate cert = X509Util.parseCert(certFile);
if (!X509Util.issues(issuerCert, cert)) {
throw new IllegalCmdParamException("certificate " + certFile + " is not issued by the given issuer");
}
ocspUrls = extractOcspUrls(cert);
sn = cert.getSerialNumber();
}
if (isBlank(serverUrl)) {
if (CollectionUtil.isEmpty(ocspUrls)) {
throw new IllegalCmdParamException("could not extract OCSP responder URL");
} else {
String url = ocspUrls.get(0);
if (ocspUrl != null && !ocspUrl.equals(url)) {
throw new IllegalCmdParamException("given certificates have different" + " OCSP responder URL in certificate");
} else {
ocspUrl = url;
}
}
}
// end if
sns.add(sn);
byte[] encodedCert = IoUtil.read(certFile);
encodedCerts.put(sn, encodedCert);
}
if (isBlank(serverUrl)) {
serverUrl = ocspUrl;
}
} else {
StringTokenizer st = new StringTokenizer(serialNumberList, ", ");
while (st.hasMoreTokens()) {
String token = st.nextToken();
StringTokenizer st2 = new StringTokenizer(token, "-");
BigInteger from = toBigInt(st2.nextToken(), hex);
BigInteger to = st2.hasMoreTokens() ? toBigInt(st2.nextToken(), hex) : null;
if (to == null) {
sns.add(from);
} else {
BigIntegerRange range = new BigIntegerRange(from, to);
if (range.getDiff().compareTo(BigInteger.valueOf(10)) > 0) {
throw new IllegalCmdParamException("to many serial numbers");
}
BigInteger sn = range.getFrom();
while (range.isInRange(sn)) {
sns.add(sn);
sn = sn.add(BigInteger.ONE);
}
}
}
}
if (isBlank(serverUrl)) {
throw new IllegalCmdParamException("could not get URL for the OCSP responder");
}
X509Certificate respIssuer = null;
if (respIssuerFile != null) {
respIssuer = X509Util.parseCert(IoUtil.expandFilepath(respIssuerFile));
}
URL serverUrlObj = new URL(serverUrl);
RequestOptions options = getRequestOptions();
checkParameters(respIssuer, sns, encodedCerts);
boolean saveReq = isNotBlank(reqout);
boolean saveResp = isNotBlank(respout);
RequestResponseDebug debug = null;
if (saveReq || saveResp) {
debug = new RequestResponseDebug(saveReq, saveResp);
}
IssuerHash issuerHash = new IssuerHash(HashAlgo.getNonNullInstance(options.getHashAlgorithmId()), Certificate.getInstance(issuerCert.getEncoded()));
OCSPResp response;
try {
response = requestor.ask(issuerCert, sns.toArray(new BigInteger[0]), serverUrlObj, options, debug);
} finally {
if (debug != null && debug.size() > 0) {
RequestResponsePair reqResp = debug.get(0);
if (saveReq) {
byte[] bytes = reqResp.getRequest();
if (bytes != null) {
IoUtil.save(reqout, bytes);
}
}
if (saveResp) {
byte[] bytes = reqResp.getResponse();
if (bytes != null) {
IoUtil.save(respout, bytes);
}
}
}
// end if
}
return processResponse(response, respIssuer, issuerHash, sns, encodedCerts);
}
use of org.bouncycastle.cert.ocsp.OCSPResp in project pdfbox by apache.
the class AddValidationInformation method addOcspData.
/**
* Fetches and adds OCSP data to storage for the given Certificate.
*
* @param certInfo the certificate info, for it to check OCSP data.
* @throws IOException
* @throws OCSPException
* @throws CertificateProccessingException
* @throws RevokedCertificateException
*/
private void addOcspData(CertSignatureInformation certInfo) throws IOException, OCSPException, CertificateProccessingException, RevokedCertificateException {
OcspHelper ocspHelper = new OcspHelper(certInfo.getCertificate(), certInfo.getIssuerCertificate(), certInfo.getOcspUrl());
OCSPResp ocspResp = ocspHelper.getResponseOcsp();
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResp.getResponseObject();
certInformationHelper.addAllCertsFromHolders(basicResponse.getCerts());
byte[] ocspData = ocspResp.getEncoded();
COSStream ocspStream = writeDataToStream(ocspData);
ocsps.add(ocspStream);
if (correspondingOCSPs != null) {
correspondingOCSPs.add(ocspStream);
}
foundRevocationInformation.add(certInfo.getCertificate().getSerialNumber());
}
use of org.bouncycastle.cert.ocsp.OCSPResp in project ddf by codice.
the class OcspChecker method sendOcspRequests.
/**
* Sends the {@param ocspReq} request to all configured {@code cspServerUrls} & the OCSP server
* urls optionally given in the given {@param cert}.
*
* @param cert - the {@link X509Certificate} to check.
* @param ocspRequest - the {@link OCSPReq} to send.
* @return a {@link List} of {@link OCSPResp}s for every configured {@code ocspServerUrls} & the
* OCSP server * urls optionally given in the given {@param cert}. Problematic responses are
* represented as null values.
*/
@VisibleForTesting
Map<URI, CertificateStatus> sendOcspRequests(X509Certificate cert, OCSPReq ocspRequest) {
Set<URI> urlsToCheck = new HashSet<>();
if (ocspServerUrls != null) {
urlsToCheck.addAll(ocspServerUrls);
}
// try and pull an OCSP server url off of the cert
urlsToCheck.addAll(getOcspUrlsFromCert(cert));
if (LOGGER.isTraceEnabled()) {
logRequest(ocspRequest);
}
Map<URI, CertificateStatus> ocspStatuses = new HashMap<>();
for (URI ocspServerUrl : urlsToCheck) {
try {
ClientBuilder<WebClient> clientBuilder = factory.getClientBuilder();
SecureCxfClientFactory<WebClient> cxfClientFactory = clientBuilder.endpoint(ocspServerUrl.toString()).interfaceClass(WebClient.class).build();
WebClient client = cxfClientFactory.getWebClient().accept("application/ocsp-response").type("application/ocsp-request");
LOGGER.debug("Sending OCSP request to URL: {}", ocspServerUrl);
Response response = client.post(ocspRequest.getEncoded());
OCSPResp ocspResponse = createOcspResponse(response);
if (LOGGER.isTraceEnabled()) {
logResponse(ocspResponse);
}
ocspStatuses.put(ocspServerUrl, getStatusFromOcspResponse(ocspResponse, cert));
continue;
} catch (IOException | OcspCheckerException | ProcessingException e) {
LOGGER.debug("Problem with the response from the OCSP Server at URL {}." + CONTINUING_MSG, ocspServerUrl, e);
}
ocspStatuses.put(ocspServerUrl, // if ocspServerUrl is null or if there was an exception
new UnknownStatus());
}
return ocspStatuses;
}
Aggregations