use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.
the class OcspServerImpl method checkSignature.
// method initStore
private Object checkSignature(byte[] request, RequestOption requestOption) throws OCSPException, CertificateParsingException, InvalidAlgorithmParameterException {
OCSPRequest req;
try {
if (!requestOption.isValidateSignature()) {
return OcspRequest.getInstance(request);
}
if (!OcspRequest.containsSignature(request)) {
if (requestOption.isSignatureRequired()) {
LOG.warn("signature in request required");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.sigRequired);
} else {
return OcspRequest.getInstance(request);
}
}
try {
req = OCSPRequest.getInstance(request);
} catch (IllegalArgumentException ex) {
throw new EncodingException("could not parse OCSP request", ex);
}
} catch (EncodingException ex) {
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
OCSPReq ocspReq = new OCSPReq(req);
X509CertificateHolder[] certs = ocspReq.getCerts();
if (certs == null || certs.length < 1) {
LOG.warn("no certificate found in request to verify the signature");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
}
ContentVerifierProvider cvp;
try {
cvp = securityFactory.getContentVerifierProvider(certs[0]);
} catch (InvalidKeyException ex) {
String message = ex.getMessage();
LOG.warn("securityFactory.getContentVerifierProvider, InvalidKeyException: {}", message);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
}
boolean sigValid = ocspReq.isSignatureValid(cvp);
if (!sigValid) {
LOG.warn("request signature is invalid");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
}
// validate the certPath
Date referenceTime = new Date();
if (canBuildCertpath(certs, requestOption, referenceTime)) {
try {
return OcspRequest.getInstance(req);
} catch (EncodingException ex) {
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
}
LOG.warn("could not build certpath for the request's signer certificate");
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.unauthorized);
}
use of org.bouncycastle.operator.ContentVerifierProvider 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.operator.ContentVerifierProvider in project xipki by xipki.
the class X509CaCmpResponderImpl method verifyPopo.
// method revokePendingCertificates
private boolean verifyPopo(CertificateRequestMessage certRequest, boolean allowRaPopo) {
int popType = certRequest.getProofOfPossessionType();
if (popType == CertificateRequestMessage.popRaVerified && allowRaPopo) {
return true;
}
if (popType != CertificateRequestMessage.popSigningKey) {
LOG.error("unsupported POP type: " + popType);
return false;
}
// check the POP signature algorithm
ProofOfPossession pop = certRequest.toASN1Structure().getPopo();
POPOSigningKey popoSign = POPOSigningKey.getInstance(pop.getObject());
AlgorithmIdentifier popoAlgId = popoSign.getAlgorithmIdentifier();
AlgorithmValidator algoValidator = getCmpControl().getPopoAlgoValidator();
if (!algoValidator.isAlgorithmPermitted(popoAlgId)) {
String algoName;
try {
algoName = AlgorithmUtil.getSignatureAlgoName(popoAlgId);
} catch (NoSuchAlgorithmException ex) {
algoName = popoAlgId.getAlgorithm().getId();
}
LOG.error("POPO signature algorithm {} not permitted", algoName);
return false;
}
try {
PublicKey publicKey = securityFactory.generatePublicKey(certRequest.getCertTemplate().getPublicKey());
ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(publicKey);
return certRequest.isValidSigningKeyPOP(cvp);
} catch (InvalidKeyException | IllegalStateException | CRMFException ex) {
LogUtil.error(LOG, ex);
}
return false;
}
use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.
the class SecurityFactoryImpl method verifyPopo.
@Override
public boolean verifyPopo(PKCS10CertificationRequest csr, AlgorithmValidator algoValidator) {
if (algoValidator != null) {
AlgorithmIdentifier algId = csr.getSignatureAlgorithm();
if (!algoValidator.isAlgorithmPermitted(algId)) {
String algoName;
try {
algoName = AlgorithmUtil.getSignatureAlgoName(algId);
} catch (NoSuchAlgorithmException ex) {
algoName = algId.getAlgorithm().getId();
}
LOG.error("POPO signature algorithm {} not permitted", algoName);
return false;
}
}
try {
SubjectPublicKeyInfo pkInfo = csr.getSubjectPublicKeyInfo();
PublicKey pk = KeyUtil.generatePublicKey(pkInfo);
ContentVerifierProvider cvp = getContentVerifierProvider(pk);
return csr.isSignatureValid(cvp);
} catch (InvalidKeyException | PKCSException | NoSuchAlgorithmException | InvalidKeySpecException ex) {
LogUtil.error(LOG, ex, "could not validate POPO of CSR");
return false;
}
}
use of org.bouncycastle.operator.ContentVerifierProvider in project xipki by xipki.
the class CaEmulator method verifyPopo.
// method getCrl
private boolean verifyPopo(CertificationRequest csr) {
Args.notNull(csr, "csr");
try {
PKCS10CertificationRequest p10Req = new PKCS10CertificationRequest(csr);
SubjectPublicKeyInfo pkInfo = p10Req.getSubjectPublicKeyInfo();
PublicKey pk = generatePublicKey(pkInfo);
ContentVerifierProvider cvp = getContentVerifierProvider(pk);
return p10Req.isSignatureValid(cvp);
} catch (InvalidKeyException | PKCSException | InvalidKeySpecException ex) {
LOG.error("could not validate POPO of CSR", ex);
return false;
}
}
Aggregations