br.ufpb.dicomflow.integrationAPI.mail.impl.SMTPServiceExtractor.java Source code

Java tutorial

Introduction

Here is the source code for br.ufpb.dicomflow.integrationAPI.mail.impl.SMTPServiceExtractor.java

Source

/*
 *    This file is part of DicomFlow.
 * 
 *    DicomFlow is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 * 
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 * 
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package br.ufpb.dicomflow.integrationAPI.mail.impl;

import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.RecipientId;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId;
import org.bouncycastle.mail.smime.SMIMEEnveloped;
import org.bouncycastle.mail.smime.SMIMEException;
import org.bouncycastle.mail.smime.SMIMESigned;
import org.bouncycastle.mail.smime.SMIMEUtil;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.Store;

import br.ufpb.dicomflow.integrationAPI.mail.MailContentBuilderIF;
import br.ufpb.dicomflow.integrationAPI.mail.MailHeadBuilderIF;
import br.ufpb.dicomflow.integrationAPI.mail.MailServiceExtractorIF;
import br.ufpb.dicomflow.integrationAPI.mail.MessageIF;
import br.ufpb.dicomflow.integrationAPI.message.xml.ServiceIF;
import br.ufpb.dicomflow.integrationAPI.message.xml.UnknownService;

public class SMTPServiceExtractor implements MailServiceExtractorIF {

    @Override
    public ServiceIF getService(Message message, X509Certificate signCert, X509Certificate encryptCert,
            PrivateKey privateKey) {

        try {

            MailHeadBuilderIF headBuilder = MailHeadBuilderFactory
                    .createHeadStrategy(MailHeadBuilderIF.SMTP_HEAD_STRATEGY);

            int contentBuilderType = Integer
                    .valueOf(headBuilder.getHeaderValue(message, MailXTags.CONTENT_BUILDER_X_TAG));
            MailContentBuilderIF contentStrategy = MailContentBuilderFactory
                    .createContentStrategy(contentBuilderType);

            int serviceType = Integer.valueOf(headBuilder.getHeaderValue(message, MailXTags.SERVICE_TYPE_X_TAG));

            ServiceIF service = new UnknownService();

            if (signCert != null && encryptCert != null && privateKey != null) {

                Multipart content = getDecryptedContent(message, signCert, encryptCert, privateKey);
                service = contentStrategy.getService(content, serviceType);

            } else {

                service = contentStrategy.getService((Multipart) message.getContent(), serviceType);
            }

            return service;

        } catch (IOException e) {
            e.printStackTrace();
            return new UnknownService(e.getMessage());
        } catch (MessagingException e) {
            e.printStackTrace();
            return new UnknownService(e.getMessage());
        } catch (CMSException e) {
            e.printStackTrace();
            return new UnknownService(e.getMessage());
        } catch (SMIMEException e) {
            e.printStackTrace();
            return new UnknownService(e.getMessage());
        } catch (OperatorCreationException e) {
            e.printStackTrace();
            return new UnknownService(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return new UnknownService(e.getMessage());
        }

    }

    private Multipart getDecryptedContent(Message message, X509Certificate signCert, X509Certificate encryptCert,
            PrivateKey privateKey) throws OperatorCreationException, Exception {
        RecipientId recId = new JceKeyTransRecipientId(encryptCert);
        SMIMEEnveloped m = new SMIMEEnveloped((MimeMessage) message);

        RecipientInformationStore recipients = m.getRecipientInfos();
        RecipientInformation recipient = recipients.get(recId);

        MimeBodyPart res = SMIMEUtil
                .toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(privateKey)));
        MimeMultipart content = (MimeMultipart) res.getContent();
        Multipart decryptedContent = null;
        if (checkSignature(content, signCert)) {
            for (int i = 0; i < content.getCount(); i++) {
                Part part = content.getBodyPart(i);

                String contentType = part.getContentType();

                if (contentType.toLowerCase().startsWith("multipart/mixed")) {
                    decryptedContent = (Multipart) part.getContent();
                }

            }
        }

        return decryptedContent;
    }

    private boolean checkSignature(MimeMultipart content, X509Certificate cert) throws OperatorCreationException,
            MessagingException, CMSException, IOException, SMIMEException, Exception {
        for (int i = 0; i < content.getCount(); i++) {
            Part part = content.getBodyPart(i);

            String contentType = part.getContentType();

            if (contentType.toLowerCase().startsWith("multipart/signed")
                    || contentType.toLowerCase().startsWith("application/pkcs7-mime")
                    || contentType.toLowerCase().startsWith("application/x-pkcs7-mime")
                    || contentType.toLowerCase().startsWith("application/pkcs7-signature")) {
                //
                // in this case the content is wrapped in the signature block.
                //
                SMIMESigned s = new SMIMESigned(content);

                return verify(s);
            }

        }
        return false;

    }

    /**
      * verify the signature (assuming the cert is contained in the message)
      */
    private boolean verify(SMIMESigned s) throws Exception {
        //
        // extract the information to verify the signatures.
        //

        //
        // certificates and crls passed in the signature - this must happen before
        // s.getSignerInfos()
        //
        Store certs = s.getCertificates();

        //
        // SignerInfo blocks which contain the signatures
        //
        SignerInformationStore signers = s.getSignerInfos();

        Collection c = signers.getSigners();
        Iterator it = c.iterator();

        //
        // check each signer
        //
        while (it.hasNext()) {
            SignerInformation signer = (SignerInformation) it.next();
            Collection certCollection = certs.getMatches(signer.getSID());

            Iterator certIt = certCollection.iterator();
            X509Certificate cert = new JcaX509CertificateConverter()
                    .getCertificate((X509CertificateHolder) certIt.next());

            //
            // verify that the sign is correct and that it was generated
            // when the certificate was current
            //
            if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(cert))) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    @Override
    public List<ServiceIF> getServices(List<Message> messages, X509Certificate signCert,
            X509Certificate encryptCert, PrivateKey privateKey) {

        List<ServiceIF> services = new ArrayList<ServiceIF>();

        Iterator<Message> iterator = messages.iterator();
        while (iterator.hasNext()) {

            Message message = (Message) iterator.next();
            ServiceIF service = getService(message, signCert, encryptCert, privateKey);
            services.add(service);

        }
        return services;
    }

    @Override
    public byte[] getAttach(Message message, X509Certificate signCert, X509Certificate encryptCert,
            PrivateKey privateKey) {

        try {

            MailHeadBuilderIF headBuilder = MailHeadBuilderFactory
                    .createHeadStrategy(MailHeadBuilderIF.SMTP_HEAD_STRATEGY);

            int contentType = Integer.valueOf(headBuilder.getHeaderValue(message, MailXTags.CONTENT_BUILDER_X_TAG));
            MailContentBuilderIF contentStrategy = MailContentBuilderFactory.createContentStrategy(contentType);

            byte[] attach = new byte[] {};
            if (signCert != null && encryptCert != null && privateKey != null) {

                Multipart content = getDecryptedContent(message, signCert, encryptCert, privateKey);
                attach = contentStrategy.getAttach(content);

            } else {

                attach = contentStrategy.getAttach((Multipart) message.getContent());
            }

            return attach;

        } catch (IOException e) {
            e.printStackTrace();
            return new byte[] {};
        } catch (MessagingException e) {
            e.printStackTrace();
            return new byte[] {};
        } catch (CMSException e) {
            e.printStackTrace();
            return new byte[] {};
        } catch (SMIMEException e) {
            e.printStackTrace();
            return new byte[] {};
        } catch (OperatorCreationException e) {
            e.printStackTrace();
            return new byte[] {};
        } catch (Exception e) {
            e.printStackTrace();
            return new byte[] {};
        }

    }

    @Override
    public List<byte[]> getAttachs(List<Message> messages, X509Certificate signCert, X509Certificate encryptCert,
            PrivateKey privateKey) {

        List<byte[]> attachs = new ArrayList<byte[]>();

        Iterator<Message> iterator = messages.iterator();
        while (iterator.hasNext()) {

            Message message = (Message) iterator.next();
            byte[] file = getAttach(message, signCert, encryptCert, privateKey);
            attachs.add(file);

        }
        return attachs;
    }

    @Override
    public MessageIF getServiceAndAttach(Message message, X509Certificate signCert, X509Certificate encryptCert,
            PrivateKey privateKey) {

        MailHeadBuilderIF headBuilder = MailHeadBuilderFactory
                .createHeadStrategy(MailHeadBuilderIF.SMTP_HEAD_STRATEGY);
        try {

            int contentType = Integer.valueOf(headBuilder.getHeaderValue(message, MailXTags.CONTENT_BUILDER_X_TAG));
            MailContentBuilderIF contentStrategy = MailContentBuilderFactory.createContentStrategy(contentType);
            int serviceType = Integer.valueOf(headBuilder.getHeaderValue(message, MailXTags.SERVICE_TYPE_X_TAG));

            MessageIF smtpMessage = new SMTPMessage();
            smtpMessage.setMailXTags(headBuilder.getMailXTags(message));

            if (signCert != null && encryptCert != null && privateKey != null) {

                Multipart content = getDecryptedContent(message, signCert, encryptCert, privateKey);
                smtpMessage.setService(contentStrategy.getService(content, serviceType));
                smtpMessage.setAttach(contentStrategy.getAttach(content));

            } else {

                smtpMessage.setService(contentStrategy.getService((Multipart) message.getContent(), serviceType));
                smtpMessage.setAttach(contentStrategy.getAttach((Multipart) message.getContent()));
            }

            return smtpMessage;

        } catch (IOException e) {
            e.printStackTrace();
            return createErrorMessageIF(message, headBuilder, e);
        } catch (MessagingException e) {
            e.printStackTrace();
            return createErrorMessageIF(message, headBuilder, e);
        } catch (CMSException e) {
            e.printStackTrace();
            return createErrorMessageIF(message, headBuilder, e);
        } catch (SMIMEException e) {
            e.printStackTrace();
            return createErrorMessageIF(message, headBuilder, e);
        } catch (OperatorCreationException e) {
            e.printStackTrace();
            return createErrorMessageIF(message, headBuilder, e);
        } catch (Exception e) {
            e.printStackTrace();
            return createErrorMessageIF(message, headBuilder, e);
        }

    }

    private MessageIF createErrorMessageIF(Message message, MailHeadBuilderIF headBuilder, Exception e) {
        MessageIF smtpMessage = new SMTPMessage();
        smtpMessage.setMailXTags(headBuilder.getMailXTags(message));
        smtpMessage.setService(new UnknownService(e.getMessage()));
        smtpMessage.setAttach(new byte[] {});
        return smtpMessage;
    }

    @Override
    public List<MessageIF> getServicesAndAttachs(List<Message> messages, X509Certificate signCert,
            X509Certificate encryptCert, PrivateKey privateKey) {

        List<MessageIF> servicesAndattachs = new ArrayList<MessageIF>();

        Iterator<Message> iterator = messages.iterator();
        while (iterator.hasNext()) {

            Message message = (Message) iterator.next();
            MessageIF messageIF = getServiceAndAttach(message, signCert, encryptCert, privateKey);
            servicesAndattachs.add(messageIF);

        }
        return servicesAndattachs;
    }

}