private SMIMESigned getSMIMESignedMessage( Package source ) throws ActionException {
//first make sure we have a MimePackage
try {
MimePackage mimePackage = (MimePackage) source;
return mimePackage.getSMIMESignedMessage();
} catch (ClassCastException cce) {
throw new ActionException("Source package " + source.getDescription()
+ " is not a MIME package");
}
}
/**
*
* @param smimeSignedMessage the SMIMESigned message object
*/
public void setSMIMESignedMessage(
SMIMESigned smimeSignedMessage ) {
this.smimeSignedMessage = smimeSignedMessage;
}
/**
* Verifies the signature of a SMIME message.
*
* It checks also if the signer's certificate is trusted using the loaded
* keystore as trusted certificate store.
*
* @param signed
* the signed mail to check.
* @return a list of SMIMESignerInfo which keeps the data of each mail
* signer.
* @throws Exception
* @throws MessagingException
*/
public List<SMIMESignerInfo> verifySignatures(SMIMESigned signed) throws Exception {
CertStore certs = new JcaCertStoreBuilder()
.addCertificates(signed.getCertificates())
.addCRLs(signed.getCRLs())
.build();
SignerInformationStore siginfo = signed.getSignerInfos();
Collection<SignerInformation> sigCol = siginfo.getSigners();
List<SMIMESignerInfo> result = new ArrayList<>(sigCol.size());
// I iterate over the signer collection
// checking if the signatures put
// on the message are valid.
for (SignerInformation info: sigCol) {
// I get the signer's certificate
X509CertificateHolderSelector x509CertificateHolderSelector = new X509CertificateHolderSelector(info.getSID().getSubjectKeyIdentifier());
X509CertSelector certSelector = new JcaX509CertSelectorConverter().getCertSelector(x509CertificateHolderSelector);
@SuppressWarnings("unchecked")
Collection<X509Certificate> certCollection = (Collection<X509Certificate>) certs.getCertificates(certSelector);
if (!certCollection.isEmpty()) {
X509Certificate signerCert = certCollection.iterator().next();
// The issuer's certifcate is searched in the list of trusted certificate.
CertPath path = verifyCertificate(signerCert, certs, keyStore);
try {
// if the signature is valid the SMIMESignedInfo is
// created using "true" as last argument. If it is
// invalid an exception is thrown by the "verify" method
// and the SMIMESignerInfo is created with "false".
//
// The second argument "path" is not null if the
// certificate can be trusted (it can be connected
// by a chain of trust to a trusted certificate), null
// otherwise.
if (info.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(signerCert))) {
result.add(new SMIMESignerInfo(signerCert, path, true));
}
} catch (Exception e) {
result.add(new SMIMESignerInfo(signerCert,path, false));
}
}
}
return result;
}