Search in sources :

Example 6 with ActionException

use of com.axway.ats.action.model.ActionException in project ats-framework by Axway.

the class SMimePackageEncryptor method sign.

@PublicAtsApi
public Package sign(Package sourcePackage) throws ActionException {
    try {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
        KeyStore ks = getKeystore();
        // TODO wrap exception with possible causes and add some hint
        PrivateKey privateKey = (PrivateKey) ks.getKey(aliasOrCN, certPassword.toCharArray());
        // Get whole certificate chain
        Certificate[] certArr = ks.getCertificateChain(aliasOrCN);
        // Pre 4.0.6 behavior was not to attach full cert. chain X509Certificate cer = (X509Certificate) ks.getCertificate(aliasOrCN);
        if (certArr.length >= 1) {
            LOG.debug("Found certificate of alias: " + aliasOrCN + ". Lenght of cert chain: " + certArr.length + ", child cert:" + certArr[0].toString());
        }
        X509Certificate childCert = (X509Certificate) certArr[0];
        /* Create the SMIMESignedGenerator */
        ASN1EncodableVector attributes = new ASN1EncodableVector();
        attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(new IssuerAndSerialNumber(new X500Name(childCert.getIssuerDN().getName()), childCert.getSerialNumber())));
        SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
        capabilities.addCapability(SMIMECapability.aES128_CBC);
        capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
        capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
        capabilities.addCapability(SMIMECapability.dES_CBC);
        attributes.add(new SMIMECapabilitiesAttribute(capabilities));
        if (signatureAlgorithm == null) {
            // not specified explicitly
            // TODO check defaults to be used
            signatureAlgorithm = SignatureAlgorithm.DSA.equals(privateKey.getAlgorithm()) ? "SHA1withDSA" : "MD5withRSA";
        }
        SMIMESignedGenerator signer = new SMIMESignedGenerator();
        JcaSimpleSignerInfoGeneratorBuilder signerGeneratorBuilder = new JcaSimpleSignerInfoGeneratorBuilder();
        signerGeneratorBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME);
        signerGeneratorBuilder.setSignedAttributeGenerator(new AttributeTable(attributes));
        signer.addSignerInfoGenerator(signerGeneratorBuilder.build(signatureAlgorithm, privateKey, childCert));
        /* Add the list of certs to the generator */
        List<X509Certificate> certList = new ArrayList<X509Certificate>();
        for (int i = 0; i < certArr.length; i++) {
            // first add child cert, and CAs
            certList.add((X509Certificate) certArr[i]);
        }
        Store<?> certs = new JcaCertStore(certList);
        signer.addCertificates(certs);
        /* Sign the message */
        Session session = Session.getDefaultInstance(System.getProperties(), null);
        MimeMultipart mm = signer.generate(getMimeMessage(sourcePackage));
        MimeMessage signedMessage = new MimeMessage(session);
        /* Set all original MIME headers in the signed message */
        Enumeration<?> headers = getMimeMessage(sourcePackage).getAllHeaderLines();
        while (headers.hasMoreElements()) {
            signedMessage.addHeaderLine((String) headers.nextElement());
        }
        /* Set the content of the signed message */
        signedMessage.setContent(mm);
        signedMessage.saveChanges();
        return new MimePackage(signedMessage);
    } catch (Exception e) {
        throw new ActionException(EXCEPTION_WHILE_SIGNING, e);
    }
}
Also used : IssuerAndSerialNumber(org.bouncycastle.asn1.cms.IssuerAndSerialNumber) PrivateKey(java.security.PrivateKey) AttributeTable(org.bouncycastle.asn1.cms.AttributeTable) ArrayList(java.util.ArrayList) SMIMESignedGenerator(org.bouncycastle.mail.smime.SMIMESignedGenerator) JcaCertStore(org.bouncycastle.cert.jcajce.JcaCertStore) X500Name(org.bouncycastle.asn1.x500.X500Name) MimePackage(com.axway.ats.action.objects.MimePackage) SMIMEEncryptionKeyPreferenceAttribute(org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute) SMIMECapabilityVector(org.bouncycastle.asn1.smime.SMIMECapabilityVector) MimeMultipart(javax.mail.internet.MimeMultipart) MimeMessage(javax.mail.internet.MimeMessage) ASN1EncodableVector(org.bouncycastle.asn1.ASN1EncodableVector) SMIMECapabilitiesAttribute(org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute) JcaSimpleSignerInfoGeneratorBuilder(org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider) ActionException(com.axway.ats.action.model.ActionException) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) MessagingException(javax.mail.MessagingException) ActionException(com.axway.ats.action.model.ActionException) SMIMEException(org.bouncycastle.mail.smime.SMIMEException) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate) Session(javax.mail.Session) PublicAtsApi(com.axway.ats.common.PublicAtsApi)

Example 7 with ActionException

use of com.axway.ats.action.model.ActionException in project ats-framework by Axway.

the class MailSender method send.

/**
 * Sends a MIME package by invoking the following actions:
 *
 * <blockquote> 1. Tags the package, this can be later used for IMAP verification<br>
 * 2. Sings the package when a signer is specified<br>
 * 3. Encrypts the package when a encryptor is specified<br>
 * 4. Sends it </blockquote>
 *
 * @see com.axway.ats.action.model.PackageSender#send(com.axway.ats.action.objects.model.Package)
 */
@Override
@PublicAtsApi
public void send(Package sourcePackage) throws ActionException {
    if (!(sourcePackage instanceof MimePackage)) {
        throw new WrongPackageException("Could not send '" + sourcePackage.getClass().getSimpleName() + "' packages. " + MimePackage.class.getSimpleName() + " is expected");
    }
    // initialize the SMTP session
    initSession();
    MimePackage mimePackage = (MimePackage) sourcePackage;
    // tag the package
    mimePackage.tag();
    // sign the package if needed
    mimePackage = sign(mimePackage);
    // encrypt the package if needed
    mimePackage = encrypt(mimePackage);
    // then send
    final DELIVERY_STATE messageDeliveryState;
    try {
        log.info("Connect to mail server " + mailHost + " at port " + mailPort);
        Object messageSendingMutex = new Object();
        MailTransportListener transListener = new MailTransportListener(messageSendingMutex);
        transport.addTransportListener(transListener);
        transport.connect();
        log.info("Sending " + mimePackage.getDescription());
        transport.sendMessage(mimePackage.getMimeMessage(), extractAllRecipients(mimePackage));
        synchronized (messageSendingMutex) {
            /*
                 * Wait some time for message delivery.
                 *
                 * We are either notified by the mail transport listener when the send has finished(successfully or not)
                 * or we have reached the wait timeout
                 */
            messageSendingMutex.wait(configurator.getMailTimeout());
        }
        messageDeliveryState = transListener.getDeliveryState();
        transport.close();
        transport.removeTransportListener(transListener);
    } catch (MessagingException e) {
        throw new ActionException("Could not send package via SMTP to host '" + mailHost + "' and port " + mailPort, e);
    } catch (InterruptedException e) {
        throw new ActionException("Could not send package", e);
    }
    // evaluate the mail send result
    if (messageDeliveryState == DELIVERY_STATE.DELIVERED) {
        log.info(mimePackage.getDescription() + " " + messageDeliveryState);
    } else {
        throw new ActionException("Result of sending " + mimePackage.getDescription() + ": " + messageDeliveryState.toString());
    }
}
Also used : MimePackage(com.axway.ats.action.objects.MimePackage) WrongPackageException(com.axway.ats.action.objects.model.WrongPackageException) MessagingException(javax.mail.MessagingException) MailTransportListener(com.axway.ats.action.mail.model.MailTransportListener) ActionException(com.axway.ats.action.model.ActionException) DELIVERY_STATE(com.axway.ats.action.mail.model.MailTransportListener.DELIVERY_STATE) PublicAtsApi(com.axway.ats.common.PublicAtsApi)

Example 8 with ActionException

use of com.axway.ats.action.model.ActionException 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)8 MessagingException (javax.mail.MessagingException)7 KeyStore (java.security.KeyStore)6 SMIMEException (org.bouncycastle.mail.smime.SMIMEException)6 MimePackage (com.axway.ats.action.objects.MimePackage)5 PublicAtsApi (com.axway.ats.common.PublicAtsApi)5 FileInputStream (java.io.FileInputStream)3 PrivateKey (java.security.PrivateKey)3 X509Certificate (java.security.cert.X509Certificate)3 MimeMessage (javax.mail.internet.MimeMessage)3 Certificate (java.security.cert.Certificate)2 ArrayList (java.util.ArrayList)2 Properties (java.util.Properties)2 MimeBodyPart (javax.mail.internet.MimeBodyPart)2 MimeMultipart (javax.mail.internet.MimeMultipart)2 BouncyCastleProvider (org.bouncycastle.jce.provider.BouncyCastleProvider)2 MailTransportListener (com.axway.ats.action.mail.model.MailTransportListener)1 DELIVERY_STATE (com.axway.ats.action.mail.model.MailTransportListener.DELIVERY_STATE)1 WrongPackageException (com.axway.ats.action.objects.model.WrongPackageException)1 BASE64DecoderStream (com.sun.mail.util.BASE64DecoderStream)1