Package org.bouncycastle.mail.smime

Source Code of org.bouncycastle.mail.smime.SMIMESigned

package org.bouncycastle.mail.smime;

import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSSignedData;

import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* general class for handling a pkcs7-signature message.
* <p>
* A simple example of usage - note, in the example below the validity of
* the certificate isn't verified, just the fact that one of the certs
* matches the given signer...
* <p>
* <pre>
*  CertStore               certs = s.getCertificates("Collection", "BC");
*  SignerInformationStore  signers = s.getSignerInfos();
*  Collection              c = signers.getSigners();
*  Iterator                it = c.iterator();
*  while (it.hasNext())
*  {
*      SignerInformation   signer = (SignerInformation)it.next();
*      Collection          certCollection = certs.getCertificates(signer.getSID());
*      Iterator        certIt = certCollection.iterator();
*      X509Certificate cert = (X509Certificate)certIt.next();
*      if (signer.verify(cert.getPublicKey()))
*      {
*          verified++;
*      }  
*  }
* </pre>
* <p>
* Note: if you are using this class with AS2 or some other protocol
* that does not use 7bit as the default content transfer encoding you
* will need to use the constructor that allows you to specify the default
* content transfer encoding, such as "binary".
* </p>
*/
public class SMIMESigned
    extends CMSSignedData
{
    Object                  message;
    MimeBodyPart            content;

    private static InputStream getInputStream(
        Part    bodyPart)
        throws MessagingException
    {
        try
        {
            if (bodyPart.isMimeType("multipart/signed"))
            {
                throw new MessagingException("attempt to create signed data object from multipart content - use MimeMultipart constructor.");
            }
           
            return bodyPart.getInputStream();
        }
        catch (IOException e)
        {
            throw new MessagingException("can't extract input stream: " + e);
        }
    }

    static
    {
        MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap();

        mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
        mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
        mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
        mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
        mc.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
       
        CommandMap.setDefaultCommandMap(mc);
    }
   
    /**
     * base constructor using a defaultContentTransferEncoding of 7bit
     *
     * @exception MessagingException on an error extracting the signature or
     * otherwise processing the message.
     * @exception CMSException if some other problem occurs.
     */
    public SMIMESigned(
        MimeMultipart message)
        throws MessagingException, CMSException
    {
        super(new CMSProcessableBodyPartInbound(message.getBodyPart(0)), getInputStream(message.getBodyPart(1)));

        this.message = message;
        this.content = (MimeBodyPart)message.getBodyPart(0);
    }

    /**
     * base constructor with settable contentTransferEncoding
     *
     * @param message the signed message
     * @param defaultContentTransferEncoding new default to use
     * @exception MessagingException on an error extracting the signature or
     * otherwise processing the message.
     * @exception CMSException if some other problem occurs.
     */
    public SMIMESigned(
        MimeMultipart message,
        String        defaultContentTransferEncoding)
        throws MessagingException, CMSException
    {
        super(new CMSProcessableBodyPartInbound(message.getBodyPart(0), defaultContentTransferEncoding), getInputStream(message.getBodyPart(1)));

        this.message = message;
        this.content = (MimeBodyPart)message.getBodyPart(0);
    }
   
    /**
     * base constructor for a signed message with encapsulated content.
     *
     * @exception MessagingException on an error extracting the signature or
     * otherwise processing the message.
     * @exception SMIMEException if the body part encapsulated in the message cannot be extracted.
     * @exception CMSException if some other problem occurs.
     */
    public SMIMESigned(
        Part message)
        throws MessagingException, CMSException, SMIMEException
    {
        super(getInputStream(message));

        this.message = message;

        CMSProcessable  cont = this.getSignedContent();

        if (cont != null)
        {
            byte[]  contBytes = (byte[])cont.getContent();
   
            this.content = SMIMEUtil.toMimeBodyPart(contBytes);
        }
    }

    /**
     * return the content that was signed.
     */
    public MimeBodyPart getContent()
    {
        return content;
    }

    /**
     * Return the content that was signed as a mime message.
     *
     * @param session
     * @return a MimeMessage holding the content.
     * @throws MessagingException
     */
    public MimeMessage getContentAsMimeMessage(Session session)
        throws MessagingException, IOException
    {
        Object content = getSignedContent().getContent();
        byte[] contentBytes = null;

        if (content instanceof byte[])
        {
            contentBytes = (byte[])content;
        }
        else if (content instanceof MimePart)
        {
            MimePart part = (MimePart)content;
            ByteArrayOutputStream out;
           
            if (part.getSize() > 0)
            {
                out = new ByteArrayOutputStream(part.getSize());
            }
            else
            {
                out = new ByteArrayOutputStream();
            }
           
            part.writeTo(out);
            contentBytes = out.toByteArray();
        }
        else
        {
            String type = "<null>";
            if (content != null)
            {
                type = content.getClass().getName();
            }

            throw new MessagingException(
                "Could not transfrom content of type "
                    + type
                    + " into MimeMessage.");
        }

        if (contentBytes != null)
        {
            ByteArrayInputStream in = new ByteArrayInputStream(contentBytes);

            return new MimeMessage(session, in);
        }

        return null;
    }

    /**
     * return the content that was signed - depending on whether this was
     * unencapsulated or not it will return a MimeMultipart or a MimeBodyPart
     */
    public Object getContentWithSignature()
    {
        return message;
    }
}
TOP

Related Classes of org.bouncycastle.mail.smime.SMIMESigned

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.