Search in sources :

Example 1 with JcaSimpleSignerInfoVerifierBuilder

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;
}
Also used : BufferedInputStream(java.io.BufferedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) GeneralSecurityException(java.security.GeneralSecurityException) Store(org.bouncycastle.util.Store) SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) SignerInformation(org.bouncycastle.cms.SignerInformation) JcaSimpleSignerInfoVerifierBuilder(org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder) X500Name(org.bouncycastle.asn1.x500.X500Name) IOException(java.io.IOException) CertificateFactory(java.security.cert.CertificateFactory) JcaX509CertificateHolder(org.bouncycastle.cert.jcajce.JcaX509CertificateHolder) FileInputStream(java.io.FileInputStream) SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) BufferedInputStream(java.io.BufferedInputStream) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) JcaX509CertificateHolder(org.bouncycastle.cert.jcajce.JcaX509CertificateHolder) BigInteger(java.math.BigInteger) SignerInformationVerifier(org.bouncycastle.cms.SignerInformationVerifier) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException)

Aggregations

BufferedInputStream (java.io.BufferedInputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 BigInteger (java.math.BigInteger)1 GeneralSecurityException (java.security.GeneralSecurityException)1 CertificateFactory (java.security.cert.CertificateFactory)1 X500Name (org.bouncycastle.asn1.x500.X500Name)1 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)1 JcaX509CertificateHolder (org.bouncycastle.cert.jcajce.JcaX509CertificateHolder)1 SignerInformation (org.bouncycastle.cms.SignerInformation)1 SignerInformationStore (org.bouncycastle.cms.SignerInformationStore)1 SignerInformationVerifier (org.bouncycastle.cms.SignerInformationVerifier)1 JcaSimpleSignerInfoVerifierBuilder (org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder)1 OperatorCreationException (org.bouncycastle.operator.OperatorCreationException)1 Store (org.bouncycastle.util.Store)1