aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java')
-rw-r--r--libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java230
1 files changed, 230 insertions, 0 deletions
diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java
new file mode 100644
index 000000000..01d7d2ada
--- /dev/null
+++ b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java
@@ -0,0 +1,230 @@
+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;
+ }
+}