use of org.bouncycastle.asn1.ocsp.SingleResponse in project xipki by xipki.
the class AbstractOcspRequestor method ask.
@Override
public OCSPResp ask(X509Certificate issuerCert, BigInteger[] serialNumbers, URL responderUrl, RequestOptions requestOptions, RequestResponseDebug debug) throws OcspResponseException, OcspRequestorException {
ParamUtil.requireNonNull("issuerCert", issuerCert);
ParamUtil.requireNonNull("requestOptions", requestOptions);
ParamUtil.requireNonNull("responderUrl", responderUrl);
byte[] nonce = null;
if (requestOptions.isUseNonce()) {
nonce = nextNonce(requestOptions.getNonceLen());
}
OCSPRequest ocspReq = buildRequest(issuerCert, serialNumbers, nonce, requestOptions);
byte[] encodedReq;
try {
encodedReq = ocspReq.getEncoded();
} catch (IOException ex) {
throw new OcspRequestorException("could not encode OCSP request: " + ex.getMessage(), ex);
}
RequestResponsePair msgPair = null;
if (debug != null) {
msgPair = new RequestResponsePair();
debug.add(msgPair);
if (debug.saveRequest()) {
msgPair.setRequest(encodedReq);
}
}
byte[] encodedResp;
try {
encodedResp = send(encodedReq, responderUrl, requestOptions);
} catch (IOException ex) {
throw new ResponderUnreachableException("IOException: " + ex.getMessage(), ex);
}
if (msgPair != null && debug.saveResponse()) {
msgPair.setResponse(encodedResp);
}
OCSPResp ocspResp;
try {
ocspResp = new OCSPResp(encodedResp);
} catch (IOException ex) {
throw new InvalidOcspResponseException("IOException: " + ex.getMessage(), ex);
}
Object respObject;
try {
respObject = ocspResp.getResponseObject();
} catch (OCSPException ex) {
throw new InvalidOcspResponseException("responseObject is invalid");
}
if (ocspResp.getStatus() != 0) {
return ocspResp;
}
if (!(respObject instanceof BasicOCSPResp)) {
return ocspResp;
}
BasicOCSPResp basicOcspResp = (BasicOCSPResp) respObject;
if (nonce != null) {
Extension nonceExtn = basicOcspResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
if (nonceExtn == null) {
throw new OcspNonceUnmatchedException(nonce, null);
}
byte[] receivedNonce = nonceExtn.getExtnValue().getOctets();
if (!Arrays.equals(nonce, receivedNonce)) {
throw new OcspNonceUnmatchedException(nonce, receivedNonce);
}
}
SingleResp[] singleResponses = basicOcspResp.getResponses();
if (singleResponses == null || singleResponses.length == 0) {
String msg = StringUtil.concat("response with no singleResponse is returned, expected is ", Integer.toString(serialNumbers.length));
throw new OcspTargetUnmatchedException(msg);
}
final int countSingleResponses = singleResponses.length;
if (countSingleResponses != serialNumbers.length) {
String msg = StringUtil.concat("response with ", Integer.toString(countSingleResponses), " singleResponse", (countSingleResponses > 1 ? "s" : ""), " is returned, expected is ", Integer.toString(serialNumbers.length));
throw new OcspTargetUnmatchedException(msg);
}
Request reqAt0 = Request.getInstance(ocspReq.getTbsRequest().getRequestList().getObjectAt(0));
CertID certId = reqAt0.getReqCert();
ASN1ObjectIdentifier issuerHashAlg = certId.getHashAlgorithm().getAlgorithm();
byte[] issuerKeyHash = certId.getIssuerKeyHash().getOctets();
byte[] issuerNameHash = certId.getIssuerNameHash().getOctets();
if (serialNumbers.length == 1) {
SingleResp singleResp = singleResponses[0];
CertificateID cid = singleResp.getCertID();
boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
if (!issuerMatch) {
throw new OcspTargetUnmatchedException("the issuer is not requested");
}
BigInteger serialNumber = cid.getSerialNumber();
if (!serialNumbers[0].equals(serialNumber)) {
throw new OcspTargetUnmatchedException("the serialNumber is not requested");
}
} else {
List<BigInteger> tmpSerials1 = Arrays.asList(serialNumbers);
List<BigInteger> tmpSerials2 = new ArrayList<>(tmpSerials1);
for (int i = 0; i < countSingleResponses; i++) {
SingleResp singleResp = singleResponses[i];
CertificateID cid = singleResp.getCertID();
boolean issuerMatch = issuerHashAlg.equals(cid.getHashAlgOID()) && Arrays.equals(issuerKeyHash, cid.getIssuerKeyHash()) && Arrays.equals(issuerNameHash, cid.getIssuerNameHash());
if (!issuerMatch) {
throw new OcspTargetUnmatchedException("the issuer specified in singleResponse[" + i + "] is not requested");
}
BigInteger serialNumber = cid.getSerialNumber();
if (!tmpSerials2.remove(serialNumber)) {
if (tmpSerials1.contains(serialNumber)) {
throw new OcspTargetUnmatchedException("serialNumber " + LogUtil.formatCsn(serialNumber) + "is contained in at least two singleResponses");
} else {
throw new OcspTargetUnmatchedException("serialNumber " + LogUtil.formatCsn(serialNumber) + " specified in singleResponse[" + i + "] is not requested");
}
}
}
// end for
}
return ocspResp;
}
use of org.bouncycastle.asn1.ocsp.SingleResponse in project jruby-openssl by jruby.
the class OCSPBasicResponse method add_status.
@JRubyMethod(name = "add_status", rest = true)
public OCSPBasicResponse add_status(final ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.getRuntime();
Arity.checkArgumentCount(runtime, args, 7, 7);
IRubyObject certificateId = args[0];
IRubyObject status = args[1];
IRubyObject reason = args[2];
IRubyObject revocation_time = args[3];
IRubyObject this_update = args[4];
IRubyObject next_update = args[5];
IRubyObject extensions = args[6];
CertStatus certStatus = null;
switch(RubyFixnum.fix2int((RubyFixnum) status)) {
case 0:
certStatus = new CertStatus();
break;
case 1:
ASN1GeneralizedTime revTime = rubyIntOrTimeToGenTime(revocation_time);
RevokedInfo revokedInfo = new RevokedInfo(revTime, CRLReason.lookup(RubyFixnum.fix2int((RubyFixnum) reason)));
certStatus = new CertStatus(revokedInfo);
break;
case 2:
certStatus = new CertStatus(2, DERNull.INSTANCE);
break;
default:
break;
}
ASN1GeneralizedTime thisUpdate = rubyIntOrTimeToGenTime(this_update);
ASN1GeneralizedTime nextUpdate = rubyIntOrTimeToGenTime(next_update);
Extensions singleExtensions = convertRubyExtensions(extensions);
CertID certID = ((OCSPCertificateId) certificateId).getCertID();
SingleResponse ocspSingleResp = new SingleResponse(certID, certStatus, thisUpdate, nextUpdate, singleExtensions);
OCSPSingleResponse rubySingleResp = new OCSPSingleResponse(runtime);
try {
rubySingleResp.initialize(context, RubyString.newString(runtime, ocspSingleResp.getEncoded()));
singleResponses.add(rubySingleResp);
} catch (IOException e) {
throw newOCSPError(runtime, e);
}
return this;
}
use of org.bouncycastle.asn1.ocsp.SingleResponse 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