use of org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder in project jmeter by apache.
the class SMIMEAssertion method verifySignature.
private static AssertionResult verifySignature(SMIMEAssertionTestElement testElement, SMIMESignedParser s, String name) throws CMSException {
AssertionResult res = new AssertionResult(name);
try {
Store certs = s.getCertificates();
SignerInformationStore signers = s.getSignerInfos();
Iterator<?> signerIt = signers.getSigners().iterator();
if (signerIt.hasNext()) {
SignerInformation signer = (SignerInformation) signerIt.next();
Iterator<?> certIt = certs.getMatches(signer.getSID()).iterator();
if (certIt.hasNext()) {
// the signer certificate
X509CertificateHolder cert = (X509CertificateHolder) certIt.next();
if (testElement.isVerifySignature()) {
SignerInformationVerifier verifier = null;
try {
verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert);
} catch (OperatorCreationException e) {
log.error("Can't create a provider.", e);
}
if (verifier == null || !signer.verify(verifier)) {
res.setFailure(true);
res.setFailureMessage("Signature is invalid");
}
}
if (testElement.isSignerCheckConstraints()) {
StringBuilder failureMessage = new StringBuilder();
String serial = testElement.getSignerSerial();
if (!JOrphanUtils.isBlank(serial)) {
BigInteger serialNbr = readSerialNumber(serial);
if (!serialNbr.equals(cert.getSerialNumber())) {
res.setFailure(true);
failureMessage.append("Serial number ").append(serialNbr).append(" does not match serial from signer certificate: ").append(cert.getSerialNumber()).append("\n");
}
}
String email = testElement.getSignerEmail();
if (!JOrphanUtils.isBlank(email)) {
List<String> emailFromCert = getEmailFromCert(cert);
if (!emailFromCert.contains(email)) {
res.setFailure(true);
failureMessage.append("Email address \"").append(email).append("\" not present in signer certificate\n");
}
}
String subject = testElement.getSignerDn();
if (subject.length() > 0) {
final X500Name certPrincipal = cert.getSubject();
log.debug("DN from cert: {}", certPrincipal);
X500Name principal = new X500Name(subject);
log.debug("DN from assertion: {}", principal);
if (!principal.equals(certPrincipal)) {
res.setFailure(true);
failureMessage.append("Distinguished name of signer certificate does not match \"").append(subject).append("\"\n");
}
}
String issuer = testElement.getIssuerDn();
if (issuer.length() > 0) {
final X500Name issuerX500Name = cert.getIssuer();
log.debug("IssuerDN from cert: {}", issuerX500Name);
X500Name principal = new X500Name(issuer);
log.debug("IssuerDN from assertion: {}", principal);
if (!principal.equals(issuerX500Name)) {
res.setFailure(true);
failureMessage.append("Issuer distinguished name of signer certificate does not match \"").append(subject).append("\"\n");
}
}
if (failureMessage.length() > 0) {
res.setFailureMessage(failureMessage.toString());
}
}
if (testElement.isSignerCheckByFile()) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
try (InputStream fis = new FileInputStream(testElement.getSignerCertFile());
InputStream bis = new BufferedInputStream(fis)) {
X509CertificateHolder certFromFile = new JcaX509CertificateHolder((X509Certificate) cf.generateCertificate(bis));
if (!certFromFile.equals(cert)) {
res.setFailure(true);
res.setFailureMessage("Signer certificate does not match certificate " + testElement.getSignerCertFile());
}
} catch (IOException e) {
if (log.isDebugEnabled()) {
log.debug("Could not read cert file {}", testElement.getSignerCertFile(), e);
}
res.setFailure(true);
res.setFailureMessage("Could not read certificate file " + testElement.getSignerCertFile());
}
}
} else {
res.setFailure(true);
res.setFailureMessage("No signer certificate found in signature");
}
}
// TODO support multiple signers
if (signerIt.hasNext()) {
log.warn("SMIME message contains multiple signers! Checking multiple signers is not supported.");
}
} catch (GeneralSecurityException e) {
log.error(e.getMessage(), e);
res.setError(true);
res.setFailureMessage(e.getMessage());
}
return res;
}
Aggregations