All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.mail.smime.SMIMESignedParser Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java CMS and S/MIME APIs for handling the CMS and S/MIME protocols. This jar contains CMS and S/MIME APIs for JDK 1.6. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs. If the S/MIME API is used, the JavaMail API and the Java activation framework will also be needed.

There is a newer version: 1.46
Show newest version
package org.bouncycastle.mail.smime;

import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedDataParser;
import org.bouncycastle.cms.CMSTypedStream;

import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.BodyPart;
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 java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * general class for handling a pkcs7-signature message.
 * 

* 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... *

*

 *  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++;
 *      }   
 *  }
 * 
*

* 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". *

*/ public class SMIMESignedParser extends CMSSignedDataParser { 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); } } private static File getTmpFile() throws MessagingException { try { return File.createTempFile("bcMail", ".mime"); } catch (IOException e) { throw new MessagingException("can't extract input stream: " + e); } } private static CMSTypedStream getSignedInputStream( BodyPart bodyPart, String defaultContentTransferEncoding, File backingFile) throws MessagingException { try { OutputStream out = new BufferedOutputStream(new FileOutputStream(backingFile)); SMIMEUtil.outputBodyPart(out, bodyPart, defaultContentTransferEncoding); out.close(); InputStream in = new TemporaryFileInputStream(backingFile); return new CMSTypedStream(in); } 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. A temporary backing file * will be created for the signed data. * * @param message signed message with signature. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( MimeMultipart message) throws MessagingException, CMSException { this(message, getTmpFile()); } /** * base constructor using a defaultContentTransferEncoding of 7bit and a specified backing file. * * @param message signed message with signature. * @param backingFile the temporary file to use to back the signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( MimeMultipart message, File backingFile) throws MessagingException, CMSException { this(message, "7bit", backingFile); } /** * base constructor with settable contentTransferEncoding. A temporary backing file will be created * to contain the signed data. * * @param message the signed message with signature. * @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 SMIMESignedParser( MimeMultipart message, String defaultContentTransferEncoding) throws MessagingException, CMSException { this(message, defaultContentTransferEncoding, getTmpFile()); } /** * base constructor with settable contentTransferEncoding and a specified backing file. * * @param message the signed message with signature. * @param defaultContentTransferEncoding new default to use. * @param backingFile the temporary file to use to back the signed data. * @exception MessagingException on an error extracting the signature or * otherwise processing the message. * @exception CMSException if some other problem occurs. */ public SMIMESignedParser( MimeMultipart message, String defaultContentTransferEncoding, File backingFile) throws MessagingException, CMSException { super(getSignedInputStream(message.getBodyPart(0), defaultContentTransferEncoding, backingFile), getInputStream(message.getBodyPart(1))); this.message = message; this.content = (MimeBodyPart)message.getBodyPart(0); drainContent(); } /** * base constructor for a signed message with encapsulated content. *

* Note: in this case the encapsulated MimeBody part will only be suitable for a single * writeTo - once writeTo has been called the file containing the body part will be deleted. *

* @param message the message containing the encapsulated signed data. * @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 SMIMESignedParser( Part message) throws MessagingException, CMSException, SMIMEException { super(getInputStream(message)); this.message = message; CMSTypedStream cont = this.getSignedContent(); if (cont != null) { this.content = SMIMEUtil.toWriteOnceBodyPart(cont); } } /** * Constructor for a signed message with encapsulated content. The encapsulated * content, if it exists, is written to the file represented by the File object * passed in. * * @param message the Part containing the signed content. * @param file the file the encapsulated part is to be written to after it has been decoded. * * @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 SMIMESignedParser( Part message, File file) throws MessagingException, CMSException, SMIMEException { super(getInputStream(message)); this.message = message; CMSTypedStream cont = this.getSignedContent(); if (cont != null) { this.content = SMIMEUtil.toMimeBodyPart(cont, file); } } /** * return the content that was signed. * @return the signed body part in this message. */ public MimeBodyPart getContent() { return content; } /** * Return the content that was signed as a mime message. * * @param session the session to base the MimeMessage around. * @return a MimeMessage holding the content. * @throws MessagingException if there is an issue creating the MimeMessage. * @throws IOException if there is an issue reading the content. */ public MimeMessage getContentAsMimeMessage(Session session) throws MessagingException, IOException { return new MimeMessage(session, getSignedContent().getContentStream()); } /** * return the content that was signed with its signature attached. * @return depending on whether this was unencapsulated or not it will return a MimeMultipart * or a MimeBodyPart */ public Object getContentWithSignature() { return message; } private void drainContent() throws CMSException { try { this.getSignedContent().drain(); } catch (IOException e) { throw new CMSException("unable to read content for verification: " + e, e); } } private static class TemporaryFileInputStream extends BufferedInputStream { private final File _file; TemporaryFileInputStream(File file) throws FileNotFoundException { super(new FileInputStream(file)); _file = file; } public void close() throws IOException { super.close(); _file.delete(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy