use of org.bouncycastle.cert.ocsp.SingleResp in project xipki by xipki.
the class OcspQa method checkOcsp.
public ValidationResult checkOcsp(OCSPResp response, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts, OcspError expectedOcspError, Map<BigInteger, OcspCertStatus> expectedOcspStatuses, Map<BigInteger, Date> expectedRevTimes, OcspResponseOption responseOption, boolean noSigVerify) {
ParamUtil.requireNonNull("response", response);
ParamUtil.requireNonEmpty("serialNumbers", serialNumbers);
ParamUtil.requireNonEmpty("expectedOcspStatuses", expectedOcspStatuses);
ParamUtil.requireNonNull("responseOption", responseOption);
List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>();
int status = response.getStatus();
// Response status
ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status");
resultIssues.add(issue);
if (expectedOcspError != null) {
if (status != expectedOcspError.getStatus()) {
issue.setFailureMessage("is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'");
}
} else {
if (status != 0) {
issue.setFailureMessage("is '" + status + "', but expected '0'");
}
}
if (status != 0) {
return new ValidationResult(resultIssues);
}
ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding");
resultIssues.add(encodingIssue);
BasicOCSPResp basicResp;
try {
basicResp = (BasicOCSPResp) response.getResponseObject();
} catch (OCSPException ex) {
encodingIssue.setFailureMessage(ex.getMessage());
return new ValidationResult(resultIssues);
}
SingleResp[] singleResponses = basicResp.getResponses();
issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses");
resultIssues.add(issue);
if (singleResponses == null || singleResponses.length == 0) {
issue.setFailureMessage("received no status from server");
return new ValidationResult(resultIssues);
}
final int n = singleResponses.length;
if (n != serialNumbers.size()) {
issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'");
return new ValidationResult(resultIssues);
}
boolean hasSignature = basicResp.getSignature() != null;
// check the signature if available
if (noSigVerify) {
issue = new ValidationIssue("OCSP.SIG", (hasSignature ? "signature presence (Ignore)" : "signature presence"));
} else {
issue = new ValidationIssue("OCSP.SIG", "signature presence");
}
resultIssues.add(issue);
if (!hasSignature) {
issue.setFailureMessage("response is not signed");
}
if (hasSignature & !noSigVerify) {
// signature algorithm
issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm");
resultIssues.add(issue);
String expectedSigalgo = responseOption.getSignatureAlgName();
if (expectedSigalgo != null) {
AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
try {
String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
if (!AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo)) {
issue.setFailureMessage("is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'");
}
} catch (NoSuchAlgorithmException ex) {
issue.setFailureMessage("could not extract the signature algorithm");
}
}
// end if (expectedSigalgo != null)
// signer certificate
ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate");
resultIssues.add(sigSignerCertIssue);
// signature validation
ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation");
resultIssues.add(sigValIssue);
X509CertificateHolder respSigner = null;
X509CertificateHolder[] responderCerts = basicResp.getCerts();
if (responderCerts == null || responderCerts.length < 1) {
sigSignerCertIssue.setFailureMessage("no responder certificate is contained in the response");
sigValIssue.setFailureMessage("could not find certificate to validate signature");
} else {
ResponderID respId = basicResp.getResponderId().toASN1Primitive();
X500Name respIdByName = respId.getName();
byte[] respIdByKey = respId.getKeyHash();
for (X509CertificateHolder cert : responderCerts) {
if (respIdByName != null) {
if (cert.getSubject().equals(respIdByName)) {
respSigner = cert;
}
} else {
byte[] spkiSha1 = HashAlgo.SHA1.hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
if (Arrays.equals(respIdByKey, spkiSha1)) {
respSigner = cert;
}
}
if (respSigner != null) {
break;
}
}
if (respSigner == null) {
sigSignerCertIssue.setFailureMessage("no responder certificate match the ResponderId");
sigValIssue.setFailureMessage("could not find certificate matching the" + " ResponderId to validate signature");
}
}
if (respSigner != null) {
issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST", "signer certificate validation");
resultIssues.add(issue);
for (int i = 0; i < singleResponses.length; i++) {
SingleResp singleResp = singleResponses[i];
if (!respSigner.isValidOn(singleResp.getThisUpdate())) {
issue.setFailureMessage(String.format("responder certificate is not valid on the thisUpdate[%d]: %s", i, singleResp.getThisUpdate()));
}
}
// end for
X509Certificate respIssuer = responseOption.getRespIssuer();
if (!issue.isFailed() && respIssuer != null) {
X509Certificate jceRespSigner;
try {
jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
if (X509Util.issues(respIssuer, jceRespSigner)) {
jceRespSigner.verify(respIssuer.getPublicKey());
} else {
issue.setFailureMessage("responder signer is not trusted");
}
} catch (Exception ex) {
issue.setFailureMessage("responder signer is not trusted");
}
}
try {
PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
boolean sigValid = basicResp.isSignatureValid(cvp);
if (!sigValid) {
sigValIssue.setFailureMessage("signature is invalid");
}
} catch (Exception ex) {
sigValIssue.setFailureMessage("could not validate signature");
}
}
// end if
}
// end if (hasSignature)
// nonce
Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence()));
boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;
for (int i = 0; i < singleResponses.length; i++) {
SingleResp singleResp = singleResponses[i];
BigInteger serialNumber = singleResp.getCertID().getSerialNumber();
OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber);
Date expectedRevTime = null;
if (expectedRevTimes != null) {
expectedRevTime = expectedRevTimes.get(serialNumber);
}
byte[] encodedCert = null;
if (encodedCerts != null) {
encodedCert = encodedCerts.get(serialNumber);
}
List<ValidationIssue> issues = checkSingleCert(i, singleResp, issuerHash, expectedStatus, encodedCert, expectedRevTime, extendedRevoke, responseOption.getNextUpdateOccurrence(), responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId());
resultIssues.addAll(issues);
}
return new ValidationResult(resultIssues);
}
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
*/
private void verifyOcspResponse(OCSPResp ocspResponse) throws OCSPException, RevokedCertificateException {
verifyRespStatus(ocspResponse);
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
if (basicResponse != null) {
checkOcspSignature(basicResponse.getCerts()[0], basicResponse);
checkNonce(basicResponse);
SingleResp[] responses = basicResponse.getResponses();
if (responses.length == 1) {
SingleResp resp = responses[0];
Object status = resp.getCertStatus();
if (status instanceof RevokedStatus) {
throw new RevokedCertificateException("OCSP: Certificate is revoked.");
} else if (status != CertificateStatus.GOOD) {
throw new OCSPException("OCSP: Status of Cert is unknown");
}
} else {
throw new OCSPException("OCSP: Recieved " + responses.length + " responses instead of 1!");
}
}
}
use of org.bouncycastle.cert.ocsp.SingleResp in project netty by netty.
the class OcspServerExample method main.
public static void main(String[] args) throws Exception {
// We assume there's a private key.
PrivateKey privateKey = null;
// Step 1: Load the certificate chain for netty.io. We'll need the certificate
// and the issuer's certificate and we don't need any of the intermediate certs.
// The array is assumed to be a certain order to keep things simple.
X509Certificate[] keyCertChain = parseCertificates(OcspServerExample.class, "netty_io_chain.pem");
X509Certificate certificate = keyCertChain[0];
X509Certificate issuer = keyCertChain[keyCertChain.length - 1];
// Step 2: We need the URL of the CA's OCSP responder server. It's somewhere encoded
// into the certificate! Notice that it's an HTTP URL.
URI uri = OcspUtils.ocspUri(certificate);
System.out.println("OCSP Responder URI: " + uri);
if (uri == null) {
throw new IllegalStateException("The CA/certificate doesn't have an OCSP responder");
}
// Step 3: Construct the OCSP request
OCSPReq request = new OcspRequestBuilder().certificate(certificate).issuer(issuer).build();
// Step 4: Do the request to the CA's OCSP responder
OCSPResp response = OcspUtils.request(uri, request, 5L, TimeUnit.SECONDS);
if (response.getStatus() != OCSPResponseStatus.SUCCESSFUL) {
throw new IllegalStateException("response-status=" + response.getStatus());
}
// Step 5: Is my certificate any good or has the CA revoked it?
BasicOCSPResp basicResponse = (BasicOCSPResp) response.getResponseObject();
SingleResp first = basicResponse.getResponses()[0];
CertificateStatus status = first.getCertStatus();
System.out.println("Status: " + (status == CertificateStatus.GOOD ? "Good" : status));
System.out.println("This Update: " + first.getThisUpdate());
System.out.println("Next Update: " + first.getNextUpdate());
if (status != null) {
throw new IllegalStateException("certificate-status=" + status);
}
BigInteger certSerial = certificate.getSerialNumber();
BigInteger ocspSerial = first.getCertID().getSerialNumber();
if (!certSerial.equals(ocspSerial)) {
throw new IllegalStateException("Bad Serials=" + certSerial + " vs. " + ocspSerial);
}
if (!OpenSsl.isAvailable()) {
throw new IllegalStateException("OpenSSL is not available!");
}
if (!OpenSsl.isOcspSupported()) {
throw new IllegalStateException("OCSP is not supported!");
}
if (privateKey == null) {
throw new IllegalStateException("Because we don't have a PrivateKey we can't continue past this point.");
}
ReferenceCountedOpenSslContext context = (ReferenceCountedOpenSslContext) SslContextBuilder.forServer(privateKey, keyCertChain).sslProvider(SslProvider.OPENSSL).enableOcsp(true).build();
try {
ServerBootstrap bootstrap = new ServerBootstrap().childHandler(newServerHandler(context, response));
// so on and so forth...
} finally {
context.release();
}
}
use of org.bouncycastle.cert.ocsp.SingleResp in project jruby-openssl by jruby.
the class OCSPBasicResponse method checkIssuer.
private boolean checkIssuer(BasicOCSPResp basicOCSPResp, IRubyObject chain) throws IOException {
boolean ret = false;
if (((RubyArray) chain).size() <= 0)
return false;
List<SingleResp> singleResponses = Arrays.asList(basicOCSPResp.getResponses());
CertificateID certId = checkCertIds(singleResponses);
X509Cert signer = (X509Cert) ((RubyArray) chain).first();
if (((RubyArray) chain).size() > 1) {
X509Cert signerCA = (X509Cert) ((RubyArray) chain).entry(1);
if (matchIssuerId(signerCA, certId, singleResponses)) {
return checkDelegated(signerCA);
}
} else {
ret = matchIssuerId(signer, certId, singleResponses);
}
return ret;
}
use of org.bouncycastle.cert.ocsp.SingleResp in project jruby-openssl by jruby.
the class OCSPBasicResponse method matchIssuerId.
private boolean matchIssuerId(X509Cert signerCA, CertificateID certId, List<SingleResp> singleResponses) throws IOException {
Ruby runtime = getRuntime();
if (certId == null) {
// gotta check em all
for (SingleResp resp : singleResponses) {
CertificateID tempId = resp.getCertID();
if (!matchIssuerId(signerCA, tempId, null))
return false;
}
return true;
} else {
// we have a matching cid
ASN1ObjectIdentifier alg = certId.getHashAlgOID();
String sym = ASN1.oid2Sym(runtime, alg);
MessageDigest md = Digest.getDigest(runtime, sym);
byte[] issuerNameDigest = md.digest(signerCA.getIssuer().getX500Name().getEncoded());
byte[] issuerKeyDigest = md.digest(signerCA.getAuxCert().getPublicKey().getEncoded());
if (!issuerNameDigest.equals(certId.getIssuerNameHash()))
return false;
if (!issuerKeyDigest.equals(certId.getIssuerKeyHash()))
return false;
return true;
}
}
Aggregations