Search in sources :

Example 1 with SMIMESigned

use of org.bouncycastle.mail.smime.SMIMESigned in project ats-framework by Axway.

the class SMimePackageEncryptor method decrypt.

@PublicAtsApi
public Package decrypt(Package sourcePackage) throws ActionException {
    // for connection management to IMAP store
    boolean storeReconnected = false;
    if (sourcePackage instanceof MimePackage) {
        try {
            storeReconnected = ((MimePackage) sourcePackage).reconnectStoreIfClosed();
        } catch (MessagingException ex) {
            throw new ActionException("Could not reopen IMAP connection", ex);
        }
    }
    try {
        KeyStore ks = getKeystore();
        RecipientId recId = new JceKeyTransRecipientId((X509Certificate) ks.getCertificate(aliasOrCN));
        MimeMessage msg = getMimeMessage(sourcePackage);
        SMIMEEnveloped m = new SMIMEEnveloped(msg);
        RecipientInformationStore recipients = m.getRecipientInfos();
        RecipientInformation recipient = recipients.get(recId);
        PrivateKey privateKey = (PrivateKey) ks.getKey(aliasOrCN, certPassword.toCharArray());
        JceKeyTransRecipient jceKey = new JceKeyTransEnvelopedRecipient(privateKey).setProvider(BouncyCastleProvider.PROVIDER_NAME);
        MimeBodyPart result = null;
        try {
            result = SMIMEUtil.toMimeBodyPart(recipient.getContent(jceKey));
            if (LOG.isDebugEnabled()) {
                LOG.debug("Successfully decrypted message with subject '" + msg.getSubject() + "' with private key alias: " + aliasOrCN);
            }
        } catch (SMIMEException e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Could not decrypt message with subject '" + sourcePackage.getSubject() + "' with private key alias '" + aliasOrCN + "'", e);
            }
        }
        SMIMESigned signedMessage = null;
        MimeMessage decryptedMsg = new MimeMessage(Session.getInstance(new Properties()));
        if (result != null) {
            Object content = result.getContent();
            Enumeration<?> hLineEnum = msg.getAllHeaderLines();
            while (hLineEnum.hasMoreElements()) {
                decryptedMsg.addHeaderLine((String) hLineEnum.nextElement());
            }
            decryptedMsg.setContent(content, result.getContentType());
            // in order getPlainTextBody getHtmlTextBody to work as they do not work with attachments
            decryptedMsg.removeHeader("Content-Disposition");
            // check if the message is signed
            try {
                if (content instanceof MimeMultipart) {
                    MimeMultipart multipartContent = (MimeMultipart) content;
                    if (multipartContent.getContentType() != null && multipartContent.getContentType().toLowerCase().contains(CONTENT_TYPE_MULTIPART_SIGNED)) {
                        signedMessage = new SMIMESigned(multipartContent);
                    }
                } else if (content instanceof SMIMESigned) {
                    signedMessage = (SMIMESigned) content;
                } else if (content instanceof BASE64DecoderStream) {
                    // com.sun.mail.util.BASE64DecoderStream - JavaMail API dependency. Seems still available
                    // in JavaMail 2.0 so not an issue if using other non-Oracle/OpenJDK JVMs
                    // will throw exception if not signed
                    signedMessage = new SMIMESigned(decryptedMsg);
                }
            } catch (Exception e) {
            // the message is not signed
            // log.debug( "Could not construct signed message instance", e );
            }
        }
        if (signedMessage != null) {
            // remove signature from the message
            decryptedMsg.setContent(signedMessage.getContent().getContent(), signedMessage.getContent().getContentType());
            MimePackage mimePackage = new MimePackage(decryptedMsg);
            // keep the SMIMESigned message for further signature verification
            mimePackage.setSMIMESignedMessage(signedMessage);
            return mimePackage;
        }
        return new MimePackage(decryptedMsg);
    } catch (Exception e) {
        throw new ActionException(DECRYPTION_EXCEPTION, e);
    } finally {
        if (storeReconnected) {
            // and sourcePackage should be instanceof MimePackage
            try {
                ((MimePackage) sourcePackage).closeStoreConnection(true);
            } catch (MessagingException ex) {
                // do not hide possible exception thrown in catch block
                LOG.debug(ex);
            }
        }
    }
}
Also used : JceKeyTransRecipient(org.bouncycastle.cms.jcajce.JceKeyTransRecipient) SMIMESigned(org.bouncycastle.mail.smime.SMIMESigned) JceKeyTransRecipientId(org.bouncycastle.cms.jcajce.JceKeyTransRecipientId) RecipientId(org.bouncycastle.cms.RecipientId) PrivateKey(java.security.PrivateKey) MessagingException(javax.mail.MessagingException) BASE64DecoderStream(com.sun.mail.util.BASE64DecoderStream) JceKeyTransRecipientId(org.bouncycastle.cms.jcajce.JceKeyTransRecipientId) ActionException(com.axway.ats.action.model.ActionException) JceKeyTransEnvelopedRecipient(org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient) Properties(java.util.Properties) KeyStore(java.security.KeyStore) SMIMEEnveloped(org.bouncycastle.mail.smime.SMIMEEnveloped) MessagingException(javax.mail.MessagingException) ActionException(com.axway.ats.action.model.ActionException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) MimePackage(com.axway.ats.action.objects.MimePackage) RecipientInformation(org.bouncycastle.cms.RecipientInformation) MimeMessage(javax.mail.internet.MimeMessage) MimeMultipart(javax.mail.internet.MimeMultipart) RecipientInformationStore(org.bouncycastle.cms.RecipientInformationStore) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) MimeBodyPart(javax.mail.internet.MimeBodyPart) PublicAtsApi(com.axway.ats.common.PublicAtsApi)

Example 2 with SMIMESigned

use of org.bouncycastle.mail.smime.SMIMESigned in project ats-framework by Axway.

the class SMimePackageEncryptor method checkSignature.

@SuppressWarnings("unchecked")
private boolean checkSignature(Package sourcePackage, String keystoreLocation, String keystorePassword, String keystoreAlias) throws ActionException {
    // for connection management to IMAP store
    boolean storeReconnected = false;
    if (sourcePackage instanceof MimePackage) {
        try {
            storeReconnected = ((MimePackage) sourcePackage).reconnectStoreIfClosed();
        } catch (MessagingException ex) {
            throw new ActionException("Could not reopen IMAP connection", ex);
        }
    }
    SMIMESigned signedMessage = getSMIMESignedMessage(sourcePackage);
    if (signedMessage == null) {
        throw new ActionException("The message is not signed");
    }
    try {
        // retrieve SignerInformation blocks which contains the signatures
        SignerInformationStore signers = signedMessage.getSignerInfos();
        Iterator<SignerInformation> it = signers.getSigners().iterator();
        if (keystoreLocation == null) {
            // extract public keys from the signature
            // a Store containing the public key certificates passed in the signature
            Store<?> certs = signedMessage.getCertificates();
            // Note: mail could be signed by multiple users. Currently we search for one/first signature match
            while (it.hasNext()) {
                SignerInformation signer = it.next();
                // extract the certificate for current signature - with first certificate only
                Iterator<?> certIt = certs.getMatches(signer.getSID()).iterator();
                X509Certificate cert = new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate((X509CertificateHolder) certIt.next());
                // verify that the signature is correct and generated with the current certificate
                if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build(cert))) {
                    return true;
                }
            }
            LOG.debug("No suitable public key found in the signature to verify it.");
        } else {
            // load public key from the certificate store file
            KeyStore ks;
            ks = KeyStore.getInstance(PKCS12_KEYSTORE_TYPE, BouncyCastleProvider.PROVIDER_NAME);
            ks.load(new FileInputStream(keystoreLocation), keystorePassword.toCharArray());
            String keyAlias = null;
            if (keystoreAlias == null) {
                Enumeration<String> aliases = ks.aliases();
                keyAlias = aliases.nextElement();
            } else {
                keyAlias = keystoreAlias;
            }
            while (it.hasNext()) {
                X509Certificate cert = (X509Certificate) ks.getCertificate(keyAlias);
                Key publicKey = cert.getPublicKey();
                if (publicKey == null) {
                    throw new Exception("The key for alias '" + keyAlias + "' was not found in keystore '" + keystoreLocation + "'");
                }
                // verify that the signature is correct and generated with the provided certificate
                if (it.next().verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build(cert))) {
                    return true;
                }
            }
            LOG.debug("Could not verify the signature with the public key alias: " + keyAlias);
        }
        return false;
    } catch (Exception e) {
        throw new ActionException(SIGNATURE_EXCEPTION, e);
    } finally {
        if (storeReconnected) {
            // and sourcePackage should be instanceof MimePackage
            try {
                ((MimePackage) sourcePackage).closeStoreConnection(false);
            } catch (MessagingException ex) {
                // do not hide possible exception thrown in catch block
                LOG.debug(ex);
            }
        }
    }
}
Also used : SMIMESigned(org.bouncycastle.mail.smime.SMIMESigned) MessagingException(javax.mail.MessagingException) ActionException(com.axway.ats.action.model.ActionException) SignerInformation(org.bouncycastle.cms.SignerInformation) JcaSimpleSignerInfoVerifierBuilder(org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) FileInputStream(java.io.FileInputStream) MessagingException(javax.mail.MessagingException) ActionException(com.axway.ats.action.model.ActionException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) MimePackage(com.axway.ats.action.objects.MimePackage) SignerInformationStore(org.bouncycastle.cms.SignerInformationStore) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) Key(java.security.Key) PrivateKey(java.security.PrivateKey)

Aggregations

ActionException (com.axway.ats.action.model.ActionException)2 MimePackage (com.axway.ats.action.objects.MimePackage)2 KeyStore (java.security.KeyStore)2 PrivateKey (java.security.PrivateKey)2 MessagingException (javax.mail.MessagingException)2 SMIMEException (org.bouncycastle.mail.smime.SMIMEException)2 SMIMESigned (org.bouncycastle.mail.smime.SMIMESigned)2 PublicAtsApi (com.axway.ats.common.PublicAtsApi)1 BASE64DecoderStream (com.sun.mail.util.BASE64DecoderStream)1 FileInputStream (java.io.FileInputStream)1 Key (java.security.Key)1 X509Certificate (java.security.cert.X509Certificate)1 Properties (java.util.Properties)1 MimeBodyPart (javax.mail.internet.MimeBodyPart)1 MimeMessage (javax.mail.internet.MimeMessage)1 MimeMultipart (javax.mail.internet.MimeMultipart)1 JcaX509CertificateConverter (org.bouncycastle.cert.jcajce.JcaX509CertificateConverter)1 RecipientId (org.bouncycastle.cms.RecipientId)1 RecipientInformation (org.bouncycastle.cms.RecipientInformation)1 RecipientInformationStore (org.bouncycastle.cms.RecipientInformationStore)1