diff options
Diffstat (limited to 'libraries/spongycastle/mail/src/main/java/org')
43 files changed, 0 insertions, 7123 deletions
diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPart.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPart.java deleted file mode 100644 index 040def416..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPart.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.mail.BodyPart; -import javax.mail.MessagingException; - -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSProcessable; - -/** - * a holding class for a BodyPart to be processed. - */ -public class CMSProcessableBodyPart - implements CMSProcessable -{ - private BodyPart bodyPart; - - public CMSProcessableBodyPart( - BodyPart bodyPart) - { - this.bodyPart = bodyPart; - } - - public void write( - OutputStream out) - throws IOException, CMSException - { - try - { - bodyPart.writeTo(out); - } - catch (MessagingException e) - { - throw new CMSException("can't write BodyPart to stream.", e); - } - } - - public Object getContent() - { - return bodyPart; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPartInbound.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPartInbound.java deleted file mode 100644 index 1497590d7..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPartInbound.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.mail.BodyPart; -import javax.mail.MessagingException; - -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSProcessable; - -/** - * a holding class for a BodyPart to be processed which does CRLF canonicalisation if - * dealing with non-binary data. - */ -public class CMSProcessableBodyPartInbound - implements CMSProcessable -{ - private final BodyPart bodyPart; - private final String defaultContentTransferEncoding; - - /** - * Create a processable with the default transfer encoding of 7bit - * - * @param bodyPart body part to be processed - */ - public CMSProcessableBodyPartInbound( - BodyPart bodyPart) - { - this(bodyPart, "7bit"); - } - - /** - * Create a processable with the a default transfer encoding of - * the passed in value. - * - * @param bodyPart body part to be processed - * @param defaultContentTransferEncoding the new default to use. - */ - public CMSProcessableBodyPartInbound( - BodyPart bodyPart, - String defaultContentTransferEncoding) - { - this.bodyPart = bodyPart; - this.defaultContentTransferEncoding = defaultContentTransferEncoding; - } - - public void write( - OutputStream out) - throws IOException, CMSException - { - try - { - SMIMEUtil.outputBodyPart(out, bodyPart, defaultContentTransferEncoding); - } - catch (MessagingException e) - { - throw new CMSException("can't write BodyPart to stream: " + e, e); - } - } - - public Object getContent() - { - return bodyPart; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPartOutbound.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPartOutbound.java deleted file mode 100644 index 4c4b3b110..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/CMSProcessableBodyPartOutbound.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.mail.BodyPart; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; - -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSProcessable; -import org.bouncycastle.mail.smime.util.CRLFOutputStream; - -/** - * a holding class for a BodyPart to be processed which does CRLF canocicalisation if - * dealing with non-binary data. - */ -public class CMSProcessableBodyPartOutbound - implements CMSProcessable -{ - private BodyPart bodyPart; - private String defaultContentTransferEncoding; - - /** - * Create a processable with the default transfer encoding of 7bit - * - * @param bodyPart body part to be processed - */ - public CMSProcessableBodyPartOutbound( - BodyPart bodyPart) - { - this.bodyPart = bodyPart; - } - - /** - * Create a processable with the a default transfer encoding of - * the passed in value. - * - * @param bodyPart body part to be processed - * @param defaultContentTransferEncoding the new default to use. - */ - public CMSProcessableBodyPartOutbound( - BodyPart bodyPart, - String defaultContentTransferEncoding) - { - this.bodyPart = bodyPart; - this.defaultContentTransferEncoding = defaultContentTransferEncoding; - } - - public void write( - OutputStream out) - throws IOException, CMSException - { - try - { - if (SMIMEUtil.isCanonicalisationRequired((MimeBodyPart)bodyPart, defaultContentTransferEncoding)) - { - out = new CRLFOutputStream(out); - } - - bodyPart.writeTo(out); - } - catch (MessagingException e) - { - throw new CMSException("can't write BodyPart to stream.", e); - } - } - - public Object getContent() - { - return bodyPart; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressed.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressed.java deleted file mode 100644 index 2fca93660..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressed.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.InputStream; - -import javax.mail.MessagingException; -import javax.mail.Part; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimePart; - -import org.bouncycastle.cms.CMSCompressedData; -import org.bouncycastle.cms.CMSException; - -/** - * containing class for an S/MIME pkcs7-mime MimePart. - */ -public class SMIMECompressed - extends CMSCompressedData -{ - MimePart message; - - private static InputStream getInputStream( - Part bodyPart) - throws MessagingException - { - try - { - return bodyPart.getInputStream(); - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - - public SMIMECompressed( - MimeBodyPart message) - throws MessagingException, CMSException - { - super(getInputStream(message)); - - this.message = message; - } - - public SMIMECompressed( - MimeMessage message) - throws MessagingException, CMSException - { - super(getInputStream(message)); - - this.message = message; - } - - public MimePart getCompressedContent() - { - return message; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedGenerator.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedGenerator.java deleted file mode 100644 index 06ad6c211..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedGenerator.java +++ /dev/null @@ -1,142 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.activation.CommandMap; -import javax.activation.MailcapCommandMap; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.CMSCompressedDataGenerator; -import org.bouncycastle.cms.CMSCompressedDataStreamGenerator; -import org.bouncycastle.operator.OutputCompressor; - -/** - * General class for generating a pkcs7-mime compressed message. - * - * A simple example of usage. - * - * <pre> - * SMIMECompressedGenerator fact = new SMIMECompressedGenerator(); - * - * MimeBodyPart smime = fact.generate(content, algorithm); - * </pre> - * - * <b>Note:<b> Most clients expect the MimeBodyPart to be in a MimeMultipart - * when it's sent. - */ -public class SMIMECompressedGenerator - extends SMIMEGenerator -{ - public static final String ZLIB = CMSCompressedDataGenerator.ZLIB; - - private static final String COMPRESSED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7z\"; smime-type=compressed-data"; - - static - { - MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap(); - - mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); - mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); - - CommandMap.setDefaultCommandMap(mc); - } - - /** - * generate an compressed object that contains an SMIME Compressed - * object using the given compression algorithm. - */ - private MimeBodyPart make( - MimeBodyPart content, - OutputCompressor compressor) - throws SMIMEException - { - try - { - MimeBodyPart data = new MimeBodyPart(); - - data.setContent(new ContentCompressor(content, compressor), COMPRESSED_CONTENT_TYPE); - data.addHeader("Content-Type", COMPRESSED_CONTENT_TYPE); - data.addHeader("Content-Disposition", "attachment; filename=\"smime.p7z\""); - data.addHeader("Content-Description", "S/MIME Compressed Message"); - data.addHeader("Content-Transfer-Encoding", encoding); - - return data; - } - catch (MessagingException e) - { - throw new SMIMEException("exception putting multi-part together.", e); - } - } - - /** - * generate an compressed object that contains an SMIME Compressed - * object using the given provider from the contents of the passed in - * message - */ - public MimeBodyPart generate( - MimeBodyPart content, - OutputCompressor compressor) - throws SMIMEException - { - return make(makeContentBodyPart(content), compressor); - } - - /** - * generate an compressed object that contains an SMIME Compressed - * object using the given provider from the contents of the passed in - * message - */ - public MimeBodyPart generate( - MimeMessage message, - OutputCompressor compressor) - throws SMIMEException - { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } - - return make(makeContentBodyPart(message), compressor); - } - - private class ContentCompressor - implements SMIMEStreamingProcessor - { - private final MimeBodyPart content; - private final OutputCompressor compressor; - - ContentCompressor( - MimeBodyPart content, - OutputCompressor compressor) - { - this.content = content; - this.compressor = compressor; - } - - public void write(OutputStream out) - throws IOException - { - CMSCompressedDataStreamGenerator cGen = new CMSCompressedDataStreamGenerator(); - - OutputStream compressed = cGen.open(out, compressor); - - try - { - content.writeTo(compressed); - - compressed.close(); - } - catch (MessagingException e) - { - throw new IOException(e.toString()); - } - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedParser.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedParser.java deleted file mode 100644 index 23214a4d8..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMECompressedParser.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - -import javax.mail.MessagingException; -import javax.mail.Part; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimePart; - -import org.bouncycastle.cms.CMSCompressedDataParser; -import org.bouncycastle.cms.CMSException; - -/** - * Stream based containing class for an S/MIME pkcs7-mime compressed MimePart. - */ -public class SMIMECompressedParser - extends CMSCompressedDataParser -{ - private final MimePart message; - - private static InputStream getInputStream( - Part bodyPart, - int bufferSize) - throws MessagingException - { - try - { - InputStream in = bodyPart.getInputStream(); - - if (bufferSize == 0) - { - return new BufferedInputStream(in); - } - else - { - return new BufferedInputStream(in, bufferSize); - } - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - - public SMIMECompressedParser( - MimeBodyPart message) - throws MessagingException, CMSException - { - this(message, 0); - } - - public SMIMECompressedParser( - MimeMessage message) - throws MessagingException, CMSException - { - this(message, 0); - } - - /** - * Create a parser from a MimeBodyPart using the passed in buffer size - * for reading it. - * - * @param message body part to be parsed. - * @param bufferSize bufferSoze to be used. - */ - public SMIMECompressedParser( - MimeBodyPart message, - int bufferSize) - throws MessagingException, CMSException - { - super(getInputStream(message, bufferSize)); - - this.message = message; - } - - /** - * Create a parser from a MimeMessage using the passed in buffer size - * for reading it. - * - * @param message message to be parsed. - * @param bufferSize bufferSoze to be used. - */ - public SMIMECompressedParser( - MimeMessage message, - int bufferSize) - throws MessagingException, CMSException - { - super(getInputStream(message, bufferSize)); - - this.message = message; - } - - public MimePart getCompressedContent() - { - return message; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnveloped.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnveloped.java deleted file mode 100644 index bf7a7ff4a..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnveloped.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.InputStream; - -import javax.mail.MessagingException; -import javax.mail.Part; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimePart; - -import org.bouncycastle.cms.CMSEnvelopedData; -import org.bouncycastle.cms.CMSException; - -/** - * containing class for an S/MIME pkcs7-mime encrypted MimePart. - */ -public class SMIMEEnveloped - extends CMSEnvelopedData -{ - MimePart message; - - private static InputStream getInputStream( - Part bodyPart) - throws MessagingException - { - try - { - return bodyPart.getInputStream(); - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - - public SMIMEEnveloped( - MimeBodyPart message) - throws MessagingException, CMSException - { - super(getInputStream(message)); - - this.message = message; - } - - public SMIMEEnveloped( - MimeMessage message) - throws MessagingException, CMSException - { - super(getInputStream(message)); - - this.message = message; - } - - public MimePart getEncryptedContent() - { - return message; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnvelopedGenerator.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnvelopedGenerator.java deleted file mode 100644 index 3dfe78ec8..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnvelopedGenerator.java +++ /dev/null @@ -1,272 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.activation.CommandMap; -import javax.activation.MailcapCommandMap; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.cms.CMSEnvelopedDataGenerator; -import org.bouncycastle.cms.CMSEnvelopedDataStreamGenerator; -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.RecipientInfoGenerator; -import org.bouncycastle.operator.OutputEncryptor; - -/** - * General class for generating a pkcs7-mime message. - * - * A simple example of usage. - * - * <pre> - * SMIMEEnvelopedGenerator fact = new SMIMEEnvelopedGenerator(); - * - * fact.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC")); - * - * MimeBodyPart mp = fact.generate(content, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider("BC").build()); - * </pre> - * - * <b>Note:<b> Most clients expect the MimeBodyPart to be in a MimeMultipart - * when it's sent. - */ -public class SMIMEEnvelopedGenerator - extends SMIMEGenerator -{ - public static final String DES_EDE3_CBC = CMSEnvelopedDataGenerator.DES_EDE3_CBC; - public static final String RC2_CBC = CMSEnvelopedDataGenerator.RC2_CBC; - public static final String IDEA_CBC = CMSEnvelopedDataGenerator.IDEA_CBC; - public static final String CAST5_CBC = CMSEnvelopedDataGenerator.CAST5_CBC; - - public static final String AES128_CBC = CMSEnvelopedDataGenerator.AES128_CBC; - public static final String AES192_CBC = CMSEnvelopedDataGenerator.AES192_CBC; - public static final String AES256_CBC = CMSEnvelopedDataGenerator.AES256_CBC; - - public static final String CAMELLIA128_CBC = CMSEnvelopedDataGenerator.CAMELLIA128_CBC; - public static final String CAMELLIA192_CBC = CMSEnvelopedDataGenerator.CAMELLIA192_CBC; - public static final String CAMELLIA256_CBC = CMSEnvelopedDataGenerator.CAMELLIA256_CBC; - - public static final String SEED_CBC = CMSEnvelopedDataGenerator.SEED_CBC; - - public static final String DES_EDE3_WRAP = CMSEnvelopedDataGenerator.DES_EDE3_WRAP; - public static final String AES128_WRAP = CMSEnvelopedDataGenerator.AES128_WRAP; - public static final String AES256_WRAP = CMSEnvelopedDataGenerator.AES256_WRAP; - public static final String CAMELLIA128_WRAP = CMSEnvelopedDataGenerator.CAMELLIA128_WRAP; - public static final String CAMELLIA192_WRAP = CMSEnvelopedDataGenerator.CAMELLIA192_WRAP; - public static final String CAMELLIA256_WRAP = CMSEnvelopedDataGenerator.CAMELLIA256_WRAP; - public static final String SEED_WRAP = CMSEnvelopedDataGenerator.SEED_WRAP; - - public static final String ECDH_SHA1KDF = CMSEnvelopedDataGenerator.ECDH_SHA1KDF; - - private static final String ENCRYPTED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data"; - - private EnvelopedGenerator fact; - private List recipients = new ArrayList(); - - static - { - CommandMap.setDefaultCommandMap(addCommands(CommandMap.getDefaultCommandMap())); - } - - private static MailcapCommandMap addCommands(CommandMap cm) - { - MailcapCommandMap mc = (MailcapCommandMap)cm; - - 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"); - - return mc; - } - - /** - * base constructor - */ - public SMIMEEnvelopedGenerator() - { - fact = new EnvelopedGenerator(); - } - - /** - * add a recipientInfoGenerator. - */ - public void addRecipientInfoGenerator( - RecipientInfoGenerator recipientInfoGen) - throws IllegalArgumentException - { - fact.addRecipientInfoGenerator(recipientInfoGen); - } - - /** - * Use a BER Set to store the recipient information - */ - public void setBerEncodeRecipients( - boolean berEncodeRecipientSet) - { - fact.setBEREncodeRecipients(berEncodeRecipientSet); - } - - /** - * if we get here we expect the Mime body part to be well defined. - */ - private MimeBodyPart make( - MimeBodyPart content, - OutputEncryptor encryptor) - throws SMIMEException - { - try - { - MimeBodyPart data = new MimeBodyPart(); - - data.setContent(new ContentEncryptor(content, encryptor), ENCRYPTED_CONTENT_TYPE); - data.addHeader("Content-Type", ENCRYPTED_CONTENT_TYPE); - data.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); - data.addHeader("Content-Description", "S/MIME Encrypted Message"); - data.addHeader("Content-Transfer-Encoding", encoding); - - return data; - } - catch (MessagingException e) - { - throw new SMIMEException("exception putting multi-part together.", e); - } - } - - /** - * generate an enveloped object that contains an SMIME Enveloped - * object using the given content encryptor - */ - public MimeBodyPart generate( - MimeBodyPart content, - OutputEncryptor encryptor) - throws SMIMEException - { - return make(makeContentBodyPart(content), encryptor); - } - - /** - * generate an enveloped object that contains an SMIME Enveloped - * object using the given provider from the contents of the passed in - * message - */ - public MimeBodyPart generate( - MimeMessage message, - OutputEncryptor encryptor) - throws SMIMEException - { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } - - return make(makeContentBodyPart(message), encryptor); - } - - private class ContentEncryptor - implements SMIMEStreamingProcessor - { - private final MimeBodyPart _content; - private OutputEncryptor _encryptor; - - private boolean _firstTime = true; - - ContentEncryptor( - MimeBodyPart content, - OutputEncryptor encryptor) - { - _content = content; - _encryptor = encryptor; - } - - public void write(OutputStream out) - throws IOException - { - OutputStream encrypted; - - try - { - if (_firstTime) - { - encrypted = fact.open(out, _encryptor); - - _firstTime = false; - } - else - { - encrypted = fact.regenerate(out, _encryptor); - } - - _content.getDataHandler().setCommandMap(addCommands(CommandMap.getDefaultCommandMap())); - - _content.writeTo(encrypted); - - encrypted.close(); - } - catch (MessagingException e) - { - throw new WrappingIOException(e.toString(), e); - } - catch (CMSException e) - { - throw new WrappingIOException(e.toString(), e); - } - } - } - - private class EnvelopedGenerator - extends CMSEnvelopedDataStreamGenerator - { - private ASN1ObjectIdentifier dataType; - private ASN1EncodableVector recipientInfos; - - protected OutputStream open( - ASN1ObjectIdentifier dataType, - OutputStream out, - ASN1EncodableVector recipientInfos, - OutputEncryptor encryptor) - throws IOException - { - this.dataType = dataType; - this.recipientInfos = recipientInfos; - - return super.open(dataType, out, recipientInfos, encryptor); - } - - OutputStream regenerate( - OutputStream out, - OutputEncryptor encryptor) - throws IOException - { - return super.open(dataType, out, recipientInfos, encryptor); - } - } - - private static class WrappingIOException - extends IOException - { - private Throwable cause; - - WrappingIOException(String msg, Throwable cause) - { - super(msg); - - this.cause = cause; - } - - public Throwable getCause() - { - return cause; - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnvelopedParser.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnvelopedParser.java deleted file mode 100644 index 95849472f..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEEnvelopedParser.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; - -import javax.mail.MessagingException; -import javax.mail.Part; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimePart; - -import org.bouncycastle.cms.CMSEnvelopedDataParser; -import org.bouncycastle.cms.CMSException; - -/** - * Stream based containing class for an S/MIME pkcs7-mime encrypted MimePart. - */ -public class SMIMEEnvelopedParser - extends CMSEnvelopedDataParser -{ - private final MimePart message; - - private static InputStream getInputStream( - Part bodyPart, - int bufferSize) - throws MessagingException - { - try - { - InputStream in = bodyPart.getInputStream(); - - if (bufferSize == 0) - { - return new BufferedInputStream(in); - } - else - { - return new BufferedInputStream(in, bufferSize); - } - } - catch (IOException e) - { - throw new MessagingException("can't extract input stream: " + e); - } - } - - public SMIMEEnvelopedParser( - MimeBodyPart message) - throws IOException, MessagingException, CMSException - { - this(message, 0); - } - - public SMIMEEnvelopedParser( - MimeMessage message) - throws IOException, MessagingException, CMSException - { - this(message, 0); - } - - /** - * Create a parser from a MimeBodyPart using the passed in buffer size - * for reading it. - * - * @param message body part to be parsed. - * @param bufferSize bufferSoze to be used. - */ - public SMIMEEnvelopedParser( - MimeBodyPart message, - int bufferSize) - throws IOException, MessagingException, CMSException - { - super(getInputStream(message, bufferSize)); - - this.message = message; - } - - /** - * Create a parser from a MimeMessage using the passed in buffer size - * for reading it. - * - * @param message message to be parsed. - * @param bufferSize bufferSoze to be used. - */ - public SMIMEEnvelopedParser( - MimeMessage message, - int bufferSize) - throws IOException, MessagingException, CMSException - { - super(getInputStream(message, bufferSize)); - - this.message = message; - } - - public MimePart getEncryptedContent() - { - return message; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEException.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEException.java deleted file mode 100644 index fe7499cfb..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEException.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.bouncycastle.mail.smime; - -public class SMIMEException - extends Exception -{ - Exception e; - - public SMIMEException( - String name) - { - super(name); - } - - public SMIMEException( - String name, - Exception e) - { - super(name); - - this.e = e; - } - - public Exception getUnderlyingException() - { - return e; - } - - public Throwable getCause() - { - return e; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEGenerator.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEGenerator.java deleted file mode 100644 index 168cc4a42..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEGenerator.java +++ /dev/null @@ -1,223 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.security.Provider; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; - -import javax.crypto.KeyGenerator; -import javax.mail.Header; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.CMSEnvelopedGenerator; -import org.bouncycastle.util.Strings; - -/** - * super class of the various generators. - */ -public class SMIMEGenerator -{ - private static Map BASE_CIPHER_NAMES = new HashMap(); - - static - { - BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.DES_EDE3_CBC, "DESEDE"); - BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES128_CBC, "AES"); - BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES192_CBC, "AES"); - BASE_CIPHER_NAMES.put(CMSEnvelopedGenerator.AES256_CBC, "AES"); - } - - protected boolean useBase64 = true; - protected String encoding = "base64"; // default sets base64 - - /** - * base constructor - */ - protected SMIMEGenerator() - { - } - - /** - * set the content-transfer-encoding for the CMS block (enveloped data, signature, etc...) in the message. - * - * @param encoding the encoding to use, default "base64", use "binary" for a binary encoding. - */ - public void setContentTransferEncoding( - String encoding) - { - this.encoding = encoding; - this.useBase64 = Strings.toLowerCase(encoding).equals("base64"); - } - - /** - * Make sure we have a valid content body part - setting the headers - * with defaults if neccessary. - */ - protected MimeBodyPart makeContentBodyPart( - MimeBodyPart content) - throws SMIMEException - { - // - // add the headers to the body part - if they are missing, in - // the event they have already been set the content settings override - // any defaults that might be set. - // - try - { - MimeMessage msg = new MimeMessage((Session)null); - - Enumeration e = content.getAllHeaders(); - - msg.setDataHandler(content.getDataHandler()); - - while (e.hasMoreElements()) - { - Header hdr =(Header)e.nextElement(); - - msg.setHeader(hdr.getName(), hdr.getValue()); - } - - msg.saveChanges(); - - // - // we do this to make sure at least the default headers are - // set in the body part. - // - e = msg.getAllHeaders(); - - while (e.hasMoreElements()) - { - Header hdr =(Header)e.nextElement(); - - if (Strings.toLowerCase(hdr.getName()).startsWith("content-")) - { - content.setHeader(hdr.getName(), hdr.getValue()); - } - } - } - catch (MessagingException e) - { - throw new SMIMEException("exception saving message state.", e); - } - - return content; - } - - /** - * extract an appropriate body part from the passed in MimeMessage - */ - protected MimeBodyPart makeContentBodyPart( - MimeMessage message) - throws SMIMEException - { - MimeBodyPart content = new MimeBodyPart(); - - // - // add the headers to the body part. - // - try - { - message.removeHeader("Message-Id"); - message.removeHeader("Mime-Version"); - - // JavaMail has a habit of reparsing some content types, if the bodypart is - // a multipart it might be signed, we rebuild the body part using the raw input stream for the message. - try - { - if (message.getContent() instanceof Multipart) - { - content.setContent(message.getRawInputStream(), message.getContentType()); - - extractHeaders(content, message); - - return content; - } - } - catch (MessagingException e) - { - // fall back to usual method below - } - - content.setContent(message.getContent(), message.getContentType()); - - content.setDataHandler(message.getDataHandler()); - - extractHeaders(content, message); - } - catch (MessagingException e) - { - throw new SMIMEException("exception saving message state.", e); - } - catch (IOException e) - { - throw new SMIMEException("exception getting message content.", e); - } - - return content; - } - - private void extractHeaders(MimeBodyPart content, MimeMessage message) - throws MessagingException - { - Enumeration e = message.getAllHeaders(); - - while (e.hasMoreElements()) - { - Header hdr =(Header)e.nextElement(); - - content.addHeader(hdr.getName(), hdr.getValue()); - } - } - - protected KeyGenerator createSymmetricKeyGenerator( - String encryptionOID, - Provider provider) - throws NoSuchAlgorithmException - { - try - { - return createKeyGenerator(encryptionOID, provider); - } - catch (NoSuchAlgorithmException e) - { - try - { - String algName = (String)BASE_CIPHER_NAMES.get(encryptionOID); - if (algName != null) - { - return createKeyGenerator(algName, provider); - } - } - catch (NoSuchAlgorithmException ex) - { - // ignore - } - if (provider != null) - { - return createSymmetricKeyGenerator(encryptionOID, null); - } - throw e; - } - } - - private KeyGenerator createKeyGenerator( - String algName, - Provider provider) - throws NoSuchAlgorithmException - { - if (provider != null) - { - return KeyGenerator.getInstance(algName, provider); - } - else - { - return KeyGenerator.getInstance(algName); - } - } -} 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 deleted file mode 100644 index 01d7d2ada..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESigned.java +++ /dev/null @@ -1,230 +0,0 @@ -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; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESignedGenerator.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESignedGenerator.java deleted file mode 100644 index e2fd8c71d..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESignedGenerator.java +++ /dev/null @@ -1,606 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import javax.activation.CommandMap; -import javax.activation.MailcapCommandMap; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.internet.ContentType; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; -import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; -import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; -import org.bouncycastle.cms.CMSAlgorithm; -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSSignedDataStreamGenerator; -import org.bouncycastle.cms.SignerInfoGenerator; -import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.cms.SignerInformationStore; -import org.bouncycastle.mail.smime.util.CRLFOutputStream; -import org.bouncycastle.util.Store; - -/** - * general class for generating a pkcs7-signature message. - * <p> - * A simple example of usage. - * - * <pre> - * X509Certificate signCert = ... - * KeyPair signKP = ... - * - * List certList = new ArrayList(); - * - * certList.add(signCert); - * - * Store certs = new JcaCertStore(certList); - * - * SMIMESignedGenerator gen = new SMIMESignedGenerator(); - * - * gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA1withRSA", signKP.getPrivate(), signCert)); - * - * gen.addCertificates(certs); - * - * MimeMultipart smime = fact.generate(content); - * </pre> - * <p> - * Note 1: 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> - * <p> - * Note 2: between RFC 3851 and RFC 5751 the values used in the micalg parameter - * for signed messages changed. We will accept both, but the default is now to use - * RFC 5751. In the event you are dealing with an older style system you will also need - * to use a constructor that sets the micalgs table and call it with RFC3851_MICALGS. - * </p> - */ -public class SMIMESignedGenerator - extends SMIMEGenerator -{ - public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); - public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); - public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); - public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); - public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); - public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); - public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); - public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); - public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); - public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); - - public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); - public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); - public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); - public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); - public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); - public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); - - private static final String CERTIFICATE_MANAGEMENT_CONTENT = "application/pkcs7-mime; name=smime.p7c; smime-type=certs-only"; - private static final String DETACHED_SIGNATURE_TYPE = "application/pkcs7-signature; name=smime.p7s; smime-type=signed-data"; - private static final String ENCAPSULATED_SIGNED_CONTENT_TYPE = "application/pkcs7-mime; name=smime.p7m; smime-type=signed-data"; - - public static final Map RFC3851_MICALGS; - public static final Map RFC5751_MICALGS; - public static final Map STANDARD_MICALGS; - - private static MailcapCommandMap addCommands(CommandMap cm) - { - MailcapCommandMap mc = (MailcapCommandMap)cm; - - 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"); - - return mc; - } - - static - { - CommandMap.setDefaultCommandMap(addCommands(CommandMap.getDefaultCommandMap())); - - Map stdMicAlgs = new HashMap(); - - stdMicAlgs.put(CMSAlgorithm.MD5, "md5"); - stdMicAlgs.put(CMSAlgorithm.SHA1, "sha-1"); - stdMicAlgs.put(CMSAlgorithm.SHA224, "sha-224"); - stdMicAlgs.put(CMSAlgorithm.SHA256, "sha-256"); - stdMicAlgs.put(CMSAlgorithm.SHA384, "sha-384"); - stdMicAlgs.put(CMSAlgorithm.SHA512, "sha-512"); - stdMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94"); - - RFC5751_MICALGS = Collections.unmodifiableMap(stdMicAlgs); - - Map oldMicAlgs = new HashMap(); - - oldMicAlgs.put(CMSAlgorithm.MD5, "md5"); - oldMicAlgs.put(CMSAlgorithm.SHA1, "sha1"); - oldMicAlgs.put(CMSAlgorithm.SHA224, "sha224"); - oldMicAlgs.put(CMSAlgorithm.SHA256, "sha256"); - oldMicAlgs.put(CMSAlgorithm.SHA384, "sha384"); - oldMicAlgs.put(CMSAlgorithm.SHA512, "sha512"); - oldMicAlgs.put(CMSAlgorithm.GOST3411, "gostr3411-94"); - - RFC3851_MICALGS = Collections.unmodifiableMap(oldMicAlgs); - - STANDARD_MICALGS = RFC5751_MICALGS; - } - - private final String defaultContentTransferEncoding; - private final Map micAlgs; - - private List _certStores = new ArrayList(); - private List certStores = new ArrayList(); - private List crlStores = new ArrayList(); - private List attrCertStores = new ArrayList(); - private List signerInfoGens = new ArrayList(); - private List _signers = new ArrayList(); - private List _oldSigners = new ArrayList(); - private List _attributeCerts = new ArrayList(); - private Map _digests = new HashMap(); - - /** - * base constructor - default content transfer encoding 7bit - */ - public SMIMESignedGenerator() - { - this("7bit", STANDARD_MICALGS); - } - - /** - * base constructor - default content transfer encoding explicitly set - * - * @param defaultContentTransferEncoding new default to use. - */ - public SMIMESignedGenerator( - String defaultContentTransferEncoding) - { - this(defaultContentTransferEncoding, STANDARD_MICALGS); - } - - /** - * base constructor - default content transfer encoding explicitly set - * - * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. - */ - public SMIMESignedGenerator( - Map micAlgs) - { - this("7bit", micAlgs); - } - - /** - * base constructor - default content transfer encoding explicitly set - * - * @param defaultContentTransferEncoding new default to use. - * @param micAlgs a map of ANS1ObjectIdentifiers to strings hash algorithm names. - */ - public SMIMESignedGenerator( - String defaultContentTransferEncoding, - Map micAlgs) - { - this.defaultContentTransferEncoding = defaultContentTransferEncoding; - this.micAlgs = micAlgs; - } - - /** - * Add a store of precalculated signers to the generator. - * - * @param signerStore store of signers - */ - public void addSigners( - SignerInformationStore signerStore) - { - Iterator it = signerStore.getSigners().iterator(); - - while (it.hasNext()) - { - _oldSigners.add(it.next()); - } - } - - /** - * - * @param sigInfoGen - */ - public void addSignerInfoGenerator(SignerInfoGenerator sigInfoGen) - { - signerInfoGens.add(sigInfoGen); - } - - public void addCertificates( - Store certStore) - { - certStores.add(certStore); - } - - public void addCRLs( - Store crlStore) - { - crlStores.add(crlStore); - } - - public void addAttributeCertificates( - Store certStore) - { - attrCertStores.add(certStore); - } - - private void addHashHeader( - StringBuffer header, - List signers) - { - int count = 0; - - // - // build the hash header - // - Iterator it = signers.iterator(); - Set micAlgSet = new TreeSet(); - - while (it.hasNext()) - { - Object signer = it.next(); - ASN1ObjectIdentifier digestOID; - - if (signer instanceof SignerInformation) - { - digestOID = ((SignerInformation)signer).getDigestAlgorithmID().getAlgorithm(); - } - else - { - digestOID = ((SignerInfoGenerator)signer).getDigestAlgorithm().getAlgorithm(); - } - - String micAlg = (String)micAlgs.get(digestOID); - - if (micAlg == null) - { - micAlgSet.add("unknown"); - } - else - { - micAlgSet.add(micAlg); - } - } - - it = micAlgSet.iterator(); - - while (it.hasNext()) - { - String alg = (String)it.next(); - - if (count == 0) - { - if (micAlgSet.size() != 1) - { - header.append("; micalg=\""); - } - else - { - header.append("; micalg="); - } - } - else - { - header.append(','); - } - - header.append(alg); - - count++; - } - - if (count != 0) - { - if (micAlgSet.size() != 1) - { - header.append('\"'); - } - } - } - - private MimeMultipart make( - MimeBodyPart content) - throws SMIMEException - { - try - { - MimeBodyPart sig = new MimeBodyPart(); - - sig.setContent(new ContentSigner(content, false), DETACHED_SIGNATURE_TYPE); - sig.addHeader("Content-Type", DETACHED_SIGNATURE_TYPE); - sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7s\""); - sig.addHeader("Content-Description", "S/MIME Cryptographic Signature"); - sig.addHeader("Content-Transfer-Encoding", encoding); - - // - // build the multipart header - // - StringBuffer header = new StringBuffer( - "signed; protocol=\"application/pkcs7-signature\""); - - List allSigners = new ArrayList(_signers); - - allSigners.addAll(_oldSigners); - - allSigners.addAll(signerInfoGens); - - addHashHeader(header, allSigners); - - MimeMultipart mm = new MimeMultipart(header.toString()); - - mm.addBodyPart(content); - mm.addBodyPart(sig); - - return mm; - } - catch (MessagingException e) - { - throw new SMIMEException("exception putting multi-part together.", e); - } - } - - /* - * at this point we expect our body part to be well defined - generate with data in the signature - */ - private MimeBodyPart makeEncapsulated( - MimeBodyPart content) - throws SMIMEException - { - try - { - MimeBodyPart sig = new MimeBodyPart(); - - sig.setContent(new ContentSigner(content, true), ENCAPSULATED_SIGNED_CONTENT_TYPE); - sig.addHeader("Content-Type", ENCAPSULATED_SIGNED_CONTENT_TYPE); - sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7m\""); - sig.addHeader("Content-Description", "S/MIME Cryptographic Signed Data"); - sig.addHeader("Content-Transfer-Encoding", encoding); - - return sig; - } - catch (MessagingException e) - { - throw new SMIMEException("exception putting body part together.", e); - } - } - - /** - * Return a map of oids and byte arrays representing the digests calculated on the content during - * the last generate. - * - * @return a map of oids (as String objects) and byte[] representing digests. - */ - public Map getGeneratedDigests() - { - return new HashMap(_digests); - } - - public MimeMultipart generate( - MimeBodyPart content) - throws SMIMEException - { - return make(makeContentBodyPart(content)); - } - - public MimeMultipart generate( - MimeMessage message) - throws SMIMEException - { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } - - return make(makeContentBodyPart(message)); - } - - /** - * generate a signed message with encapsulated content - * <p> - * Note: doing this is strongly <b>not</b> recommended as it means a - * recipient of the message will have to be able to read the signature to read the - * message. - */ - public MimeBodyPart generateEncapsulated( - MimeBodyPart content) - throws SMIMEException - { - return makeEncapsulated(makeContentBodyPart(content)); - } - - public MimeBodyPart generateEncapsulated( - MimeMessage message) - throws SMIMEException - { - try - { - message.saveChanges(); // make sure we're up to date. - } - catch (MessagingException e) - { - throw new SMIMEException("unable to save message", e); - } - - return makeEncapsulated(makeContentBodyPart(message)); - } - - /** - * Creates a certificate management message which is like a signed message with no content - * or signers but that still carries certificates and CRLs. - * - * @return a MimeBodyPart containing the certs and CRLs. - */ - public MimeBodyPart generateCertificateManagement() - throws SMIMEException - { - try - { - MimeBodyPart sig = new MimeBodyPart(); - - sig.setContent(new ContentSigner(null, true), CERTIFICATE_MANAGEMENT_CONTENT); - sig.addHeader("Content-Type", CERTIFICATE_MANAGEMENT_CONTENT); - sig.addHeader("Content-Disposition", "attachment; filename=\"smime.p7c\""); - sig.addHeader("Content-Description", "S/MIME Certificate Management Message"); - sig.addHeader("Content-Transfer-Encoding", encoding); - - return sig; - } - catch (MessagingException e) - { - throw new SMIMEException("exception putting body part together.", e); - } - } - - private class ContentSigner - implements SMIMEStreamingProcessor - { - private final MimeBodyPart content; - private final boolean encapsulate; - private final boolean noProvider; - - ContentSigner( - MimeBodyPart content, - boolean encapsulate) - { - this.content = content; - this.encapsulate = encapsulate; - this.noProvider = true; - } - - protected CMSSignedDataStreamGenerator getGenerator() - throws CMSException - { - CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); - - for (Iterator it = certStores.iterator(); it.hasNext();) - { - gen.addCertificates((Store)it.next()); - } - - for (Iterator it = crlStores.iterator(); it.hasNext();) - { - gen.addCRLs((Store)it.next()); - } - - for (Iterator it = attrCertStores.iterator(); it.hasNext();) - { - gen.addAttributeCertificates((Store)it.next()); - } - - for (Iterator it = signerInfoGens.iterator(); it.hasNext();) - { - gen.addSignerInfoGenerator((SignerInfoGenerator)it.next()); - } - - gen.addSigners(new SignerInformationStore(_oldSigners)); - - return gen; - } - - private void writeBodyPart( - OutputStream out, - MimeBodyPart bodyPart) - throws IOException, MessagingException - { - if (bodyPart.getContent() instanceof Multipart) - { - Multipart mp = (Multipart)bodyPart.getContent(); - ContentType contentType = new ContentType(mp.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - - SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); - - Enumeration headers = bodyPart.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - lOut.writeln((String)headers.nextElement()); - } - - lOut.writeln(); // CRLF separator - - SMIMEUtil.outputPreamble(lOut, bodyPart, boundary); - - for (int i = 0; i < mp.getCount(); i++) - { - lOut.writeln(boundary); - writeBodyPart(out, (MimeBodyPart)mp.getBodyPart(i)); - lOut.writeln(); // CRLF terminator - } - - lOut.writeln(boundary + "--"); - } - else - { - if (SMIMEUtil.isCanonicalisationRequired(bodyPart, defaultContentTransferEncoding)) - { - out = new CRLFOutputStream(out); - } - - bodyPart.writeTo(out); - } - } - - public void write(OutputStream out) - throws IOException - { - try - { - CMSSignedDataStreamGenerator gen = getGenerator(); - - OutputStream signingStream = gen.open(out, encapsulate); - - if (content != null) - { - if (!encapsulate) - { - writeBodyPart(signingStream, content); - } - else - { - content.getDataHandler().setCommandMap(addCommands(CommandMap.getDefaultCommandMap())); - - content.writeTo(signingStream); - } - } - - signingStream.close(); - - _digests = gen.getGeneratedDigests(); - } - catch (MessagingException e) - { - throw new IOException(e.toString()); - } - catch (CMSException e) - { - throw new IOException(e.toString()); - } - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESignedParser.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESignedParser.java deleted file mode 100644 index f6c132c01..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMESignedParser.java +++ /dev/null @@ -1,358 +0,0 @@ -package org.bouncycastle.mail.smime; - -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; - -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 org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.CMSSignedDataParser; -import org.bouncycastle.cms.CMSTypedStream; -import org.bouncycastle.operator.DigestCalculatorProvider; - -/** - * 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 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 digCalcProvider provider for digest calculators. - * @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( - DigestCalculatorProvider digCalcProvider, - MimeMultipart message) - throws MessagingException, CMSException - { - this(digCalcProvider, message, getTmpFile()); - } - - /** - * base constructor using a defaultContentTransferEncoding of 7bit and a specified backing file. - * - * @param digCalcProvider provider for digest calculators. - * @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( - DigestCalculatorProvider digCalcProvider, - MimeMultipart message, - File backingFile) - throws MessagingException, CMSException - { - this(digCalcProvider, message, "7bit", backingFile); - } - - /** - * base constructor with settable contentTransferEncoding. A temporary backing file will be created - * to contain the signed data. - * - * @param digCalcProvider provider for digest calculators. - * @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.r - */ - public SMIMESignedParser( - DigestCalculatorProvider digCalcProvider, - MimeMultipart message, - String defaultContentTransferEncoding) - throws MessagingException, CMSException - { - this(digCalcProvider, message, defaultContentTransferEncoding, getTmpFile()); - } - - /** - * base constructor with settable contentTransferEncoding and a specified backing file. - * - * @param digCalcProvider provider for digest calculators. - * @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( - DigestCalculatorProvider digCalcProvider, - MimeMultipart message, - String defaultContentTransferEncoding, - File backingFile) - throws MessagingException, CMSException - { - super(digCalcProvider, 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. - * <p> - * 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. If writeTo is not - * called the file will be left in the temp directory. - * </p> - * @param digCalcProvider provider for digest calculators. - * @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( - DigestCalculatorProvider digCalcProvider, - Part message) - throws MessagingException, CMSException, SMIMEException - { - super(digCalcProvider, 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 digCalcProvider provider for digest calculators. - * @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( - DigestCalculatorProvider digCalcProvider, - Part message, - File file) - throws MessagingException, CMSException, SMIMEException - { - super(digCalcProvider, 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 - { - if (message instanceof MimeMultipart) - { - BodyPart bp = ((MimeMultipart)message).getBodyPart(0); - return new MimeMessage(session, bp.getInputStream()); - } - else - { - 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(); - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEStreamingProcessor.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEStreamingProcessor.java deleted file mode 100644 index e773232d9..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEStreamingProcessor.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.IOException; -import java.io.OutputStream; - -public interface SMIMEStreamingProcessor -{ - public void write(OutputStream out) - throws IOException; -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java deleted file mode 100644 index b2f36e6f0..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/SMIMEUtil.java +++ /dev/null @@ -1,623 +0,0 @@ -package org.bouncycastle.mail.smime; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.NoSuchProviderException; -import java.security.Provider; -import java.security.Security; -import java.security.cert.CertificateParsingException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; - -import javax.mail.BodyPart; -import javax.mail.MessagingException; -import javax.mail.internet.ContentType; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; -import org.bouncycastle.cms.CMSTypedStream; -import org.bouncycastle.jce.PrincipalUtil; -import org.bouncycastle.mail.smime.util.CRLFOutputStream; -import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart; - -public class SMIMEUtil -{ - private static final int BUF_SIZE = 32760; - - static boolean isCanonicalisationRequired( - MimeBodyPart bodyPart, - String defaultContentTransferEncoding) - throws MessagingException - { - String[] cte = bodyPart.getHeader("Content-Transfer-Encoding"); - String contentTransferEncoding; - - if (cte == null) - { - contentTransferEncoding = defaultContentTransferEncoding; - } - else - { - contentTransferEncoding = cte[0]; - } - - return !contentTransferEncoding.equalsIgnoreCase("binary"); - } - - public static Provider getProvider(String providerName) - throws NoSuchProviderException - { - if (providerName != null) - { - Provider prov = Security.getProvider(providerName); - - if (prov != null) - { - return prov; - } - - throw new NoSuchProviderException("provider " + providerName + " not found."); - } - - return null; - } - - static class LineOutputStream extends FilterOutputStream - { - private static byte newline[]; - - public LineOutputStream(OutputStream outputstream) - { - super(outputstream); - } - - public void writeln(String s) - throws MessagingException - { - try - { - byte abyte0[] = getBytes(s); - super.out.write(abyte0); - super.out.write(newline); - } - catch(Exception exception) - { - throw new MessagingException("IOException", exception); - } - } - - public void writeln() - throws MessagingException - { - try - { - super.out.write(newline); - } - catch(Exception exception) - { - throw new MessagingException("IOException", exception); - } - } - - static - { - newline = new byte[2]; - newline[0] = 13; - newline[1] = 10; - } - - private static byte[] getBytes(String s) - { - char ac[] = s.toCharArray(); - int i = ac.length; - byte abyte0[] = new byte[i]; - int j = 0; - - while (j < i) - { - abyte0[j] = (byte)ac[j++]; - } - - return abyte0; - } - } - - /** - * internal preamble is generally included in signatures, while this is technically wrong, - * if we find internal preamble we include it by default. - */ - static void outputPreamble(LineOutputStream lOut, MimeBodyPart part, String boundary) - throws MessagingException, IOException - { - InputStream in; - - try - { - in = part.getRawInputStream(); - } - catch (MessagingException e) - { - return; // no underlying content rely on default generation - } - - String line; - - while ((line = readLine(in)) != null) - { - if (line.equals(boundary)) - { - break; - } - - lOut.writeln(line); - } - - in.close(); - - if (line == null) - { - throw new MessagingException("no boundary found"); - } - } - - /** - * internal postamble is generally included in signatures, while this is technically wrong, - * if we find internal postamble we include it by default. - */ - static void outputPostamble(LineOutputStream lOut, MimeBodyPart part, int count, String boundary) - throws MessagingException, IOException - { - InputStream in; - - try - { - in = part.getRawInputStream(); - } - catch (MessagingException e) - { - return; // no underlying content rely on default generation - } - - String line; - int boundaries = count + 1; - - while ((line = readLine(in)) != null) - { - if (line.startsWith(boundary)) - { - boundaries--; - - if (boundaries == 0) - { - break; - } - } - } - - while ((line = readLine(in)) != null) - { - lOut.writeln(line); - } - - in.close(); - - if (boundaries != 0) - { - throw new MessagingException("all boundaries not found for: " + boundary); - } - } - - static void outputPostamble(LineOutputStream lOut, BodyPart parent, String parentBoundary, BodyPart part) - throws MessagingException, IOException - { - InputStream in; - - try - { - in = ((MimeBodyPart)parent).getRawInputStream(); - } - catch (MessagingException e) - { - return; // no underlying content rely on default generation - } - - - MimeMultipart multipart = (MimeMultipart)part.getContent(); - ContentType contentType = new ContentType(multipart.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - int count = multipart.getCount() + 1; - String line; - while (count != 0 && (line = readLine(in)) != null) - { - if (line.startsWith(boundary)) - { - count--; - } - } - - while ((line = readLine(in)) != null) - { - if (line.startsWith(parentBoundary)) - { - break; - } - lOut.writeln(line); - } - - in.close(); - } - - /* - * read a line of input stripping of the tailing \r\n - */ - private static String readLine(InputStream in) - throws IOException - { - StringBuffer b = new StringBuffer(); - - int ch; - while ((ch = in.read()) >= 0 && ch != '\n') - { - if (ch != '\r') - { - b.append((char)ch); - } - } - - if (ch < 0 && b.length() == 0) - { - return null; - } - - return b.toString(); - } - - static void outputBodyPart( - OutputStream out, - BodyPart bodyPart, - String defaultContentTransferEncoding) - throws MessagingException, IOException - { - if (bodyPart instanceof MimeBodyPart) - { - MimeBodyPart mimePart = (MimeBodyPart)bodyPart; - String[] cte = mimePart.getHeader("Content-Transfer-Encoding"); - String contentTransferEncoding; - - if (mimePart.getContent() instanceof MimeMultipart) - { - MimeMultipart mp = (MimeMultipart)bodyPart.getContent(); - ContentType contentType = new ContentType(mp.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - - SMIMEUtil.LineOutputStream lOut = new SMIMEUtil.LineOutputStream(out); - - Enumeration headers = mimePart.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - String header = (String)headers.nextElement(); - lOut.writeln(header); - } - - lOut.writeln(); // CRLF separator - - outputPreamble(lOut, mimePart, boundary); - - for (int i = 0; i < mp.getCount(); i++) - { - lOut.writeln(boundary); - BodyPart part = mp.getBodyPart(i); - outputBodyPart(out, part, defaultContentTransferEncoding); - if (!(part.getContent() instanceof MimeMultipart)) - { - lOut.writeln(); // CRLF terminator needed - } - else - { - outputPostamble(lOut, mimePart, boundary, part); - } - } - - lOut.writeln(boundary + "--"); - - outputPostamble(lOut, mimePart, mp.getCount(), boundary); - - return; - } - - if (cte == null) - { - contentTransferEncoding = defaultContentTransferEncoding; - } - else - { - contentTransferEncoding = cte[0]; - } - - if (!contentTransferEncoding.equalsIgnoreCase("base64") - && !contentTransferEncoding.equalsIgnoreCase("quoted-printable")) - { - if (!contentTransferEncoding.equalsIgnoreCase("binary")) - { - out = new CRLFOutputStream(out); - } - bodyPart.writeTo(out); - out.flush(); - return; - } - - boolean base64 = contentTransferEncoding.equalsIgnoreCase("base64"); - - // - // Write raw content, performing canonicalization - // - InputStream inRaw; - - try - { - inRaw = mimePart.getRawInputStream(); - } - catch (MessagingException e) - { - // this is less than ideal, but if the raw output stream is unavailable it's the - // best option we've got. - out = new CRLFOutputStream(out); - bodyPart.writeTo(out); - out.flush(); - return; - } - - // - // Write headers - // - LineOutputStream outLine = new LineOutputStream(out); - for (Enumeration e = mimePart.getAllHeaderLines(); e.hasMoreElements();) - { - String header = (String)e.nextElement(); - - outLine.writeln(header); - } - - outLine.writeln(); - outLine.flush(); - - - OutputStream outCRLF; - - if (base64) - { - outCRLF = new Base64CRLFOutputStream(out); - } - else - { - outCRLF = new CRLFOutputStream(out); - } - - byte[] buf = new byte[BUF_SIZE]; - - int len; - while ((len = inRaw.read(buf, 0, buf.length)) > 0) - { - - outCRLF.write(buf, 0, len); - } - - outCRLF.flush(); - } - else - { - if (!defaultContentTransferEncoding.equalsIgnoreCase("binary")) - { - out = new CRLFOutputStream(out); - } - - bodyPart.writeTo(out); - - out.flush(); - } - } - - /** - * return the MimeBodyPart described in the raw bytes provided in content - */ - public static MimeBodyPart toMimeBodyPart( - byte[] content) - throws SMIMEException - { - return toMimeBodyPart(new ByteArrayInputStream(content)); - } - - /** - * return the MimeBodyPart described in the input stream content - */ - public static MimeBodyPart toMimeBodyPart( - InputStream content) - throws SMIMEException - { - try - { - return new MimeBodyPart(content); - } - catch (MessagingException e) - { - throw new SMIMEException("exception creating body part.", e); - } - } - - static FileBackedMimeBodyPart toWriteOnceBodyPart( - CMSTypedStream content) - throws SMIMEException - { - try - { - return new WriteOnceFileBackedMimeBodyPart(content.getContentStream(), File.createTempFile("bcMail", ".mime")); - } - catch (IOException e) - { - throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e); - } - catch (MessagingException e) - { - throw new SMIMEException("can't create part: " + e, e); - } - } - - /** - * return a file backed MimeBodyPart described in {@link CMSTypedStream} content. - * </p> - */ - public static FileBackedMimeBodyPart toMimeBodyPart( - CMSTypedStream content) - throws SMIMEException - { - try - { - return toMimeBodyPart(content, File.createTempFile("bcMail", ".mime")); - } - catch (IOException e) - { - throw new SMIMEException("IOException creating tmp file:" + e.getMessage(), e); - } - } - - /** - * Return a file based MimeBodyPart represented by content and backed - * by the file represented by file. - * - * @param content content stream containing body part. - * @param file file to store the decoded body part in. - * @return the decoded body part. - * @throws SMIMEException - */ - public static FileBackedMimeBodyPart toMimeBodyPart( - CMSTypedStream content, - File file) - throws SMIMEException - { - try - { - return new FileBackedMimeBodyPart(content.getContentStream(), file); - } - catch (IOException e) - { - throw new SMIMEException("can't save content to file: " + e, e); - } - catch (MessagingException e) - { - throw new SMIMEException("can't create part: " + e, e); - } - } - - /** - * Return a CMS IssuerAndSerialNumber structure for the passed in X.509 certificate. - * - * @param cert the X.509 certificate to get the issuer and serial number for. - * @return an IssuerAndSerialNumber structure representing the certificate. - */ - public static IssuerAndSerialNumber createIssuerAndSerialNumberFor( - X509Certificate cert) - throws CertificateParsingException - { - try - { - return new IssuerAndSerialNumber(PrincipalUtil.getIssuerX509Principal(cert), cert.getSerialNumber()); - } - catch (Exception e) - { - throw new CertificateParsingException("exception extracting issuer and serial number: " + e); - } - } - - private static class WriteOnceFileBackedMimeBodyPart - extends FileBackedMimeBodyPart - { - public WriteOnceFileBackedMimeBodyPart(InputStream content, File file) - throws MessagingException, IOException - { - super(content, file); - } - - public void writeTo(OutputStream out) - throws MessagingException, IOException - { - super.writeTo(out); - - this.dispose(); - } - } - - static class Base64CRLFOutputStream extends FilterOutputStream - { - protected int lastb; - protected static byte newline[]; - private boolean isCrlfStream; - - public Base64CRLFOutputStream(OutputStream outputstream) - { - super(outputstream); - lastb = -1; - } - - public void write(int i) - throws IOException - { - if (i == '\r') - { - out.write(newline); - } - else if (i == '\n') - { - if (lastb != '\r') - { // imagine my joy... - if (!(isCrlfStream && lastb == '\n')) - { - out.write(newline); - } - } - else - { - isCrlfStream = true; - } - } - else - { - out.write(i); - } - - lastb = i; - } - - public void write(byte[] buf) - throws IOException - { - this.write(buf, 0, buf.length); - } - - public void write(byte buf[], int off, int len) - throws IOException - { - for (int i = off; i != off + len; i++) - { - this.write(buf[i]); - } - } - - public void writeln() - throws IOException - { - super.out.write(newline); - } - - static - { - newline = new byte[2]; - newline[0] = '\r'; - newline[1] = '\n'; - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateCompressedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateCompressedMail.java deleted file mode 100644 index 5d1df6953..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateCompressedMail.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileOutputStream; -import java.util.Properties; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.jcajce.ZlibCompressor; -import org.bouncycastle.mail.smime.SMIMECompressedGenerator; - -/** - * a simple example that creates a single compressed mail message. - */ -public class CreateCompressedMail -{ - public static void main( - String args[]) - throws Exception - { - // - // create the generator for creating an smime/compressed message - // - SMIMECompressedGenerator gen = new SMIMECompressedGenerator(); - - // - // create the base for our message - // - MimeBodyPart msg = new MimeBodyPart(); - - msg.setText("Hello world!"); - - MimeBodyPart mp = gen.generate(msg, new ZlibCompressor()); - - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example compressed message"); - body.setContent(mp.getContent(), mp.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("compressed.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateEncryptedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateEncryptedMail.java deleted file mode 100644 index 40e114bd7..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateEncryptedMail.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.Properties; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.CMSAlgorithm; -import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; -import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; - -/** - * a simple example that creates a single encrypted mail message. - * <p> - * The key store can be created using the class in - * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one - * key to be present in the key file. - * <p> - * Note: while this means that both the private key is available to - * the program, the private key is retrieved from the keystore only for - * the purposes of locating the corresponding public key, in normal circumstances - * you would only be doing this with a certificate available. - */ -public class CreateEncryptedMail -{ - public static void main( - String args[]) - throws Exception - { - if (args.length != 2) - { - System.err.println("usage: CreateEncryptedMail pkcs12Keystore password"); - System.exit(0); - } - - // - // Open the key store - // - KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); - - ks.load(new FileInputStream(args[0]), args[1].toCharArray()); - - Enumeration e = ks.aliases(); - String keyAlias = null; - - while (e.hasMoreElements()) - { - String alias = (String)e.nextElement(); - - if (ks.isKeyEntry(alias)) - { - keyAlias = alias; - } - } - - if (keyAlias == null) - { - System.err.println("can't find a private key!"); - System.exit(0); - } - - Certificate[] chain = ks.getCertificateChain(keyAlias); - - // - // create the generator for creating an smime/encrypted message - // - SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); - - gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator((X509Certificate)chain[0]).setProvider("BC")); - - // - // create a subject key id - this has to be done the same way as - // it is done in the certificate associated with the private key - // version 3 only. - // - /* - MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); - - dig.update(cert.getPublicKey().getEncoded()); - - gen.addKeyTransRecipient(cert.getPublicKey(), dig.digest()); - */ - - // - // create the base for our message - // - MimeBodyPart msg = new MimeBodyPart(); - - msg.setText("Hello world!"); - - MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC).setProvider("BC").build()); - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example encrypted message"); - body.setContent(mp.getContent(), mp.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("encrypted.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeCompressedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeCompressedMail.java deleted file mode 100644 index 63c5125d7..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeCompressedMail.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.util.Properties; - -import javax.activation.DataHandler; -import javax.activation.FileDataSource; -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.jcajce.ZlibCompressor; -import org.bouncycastle.mail.smime.SMIMECompressedGenerator; - -/** - * a simple example that creates a single compressed mail message using the large - * file model. - */ -public class CreateLargeCompressedMail -{ - public static void main( - String args[]) - throws Exception - { - // - // create the generator for creating an smime/compressed message - // - SMIMECompressedGenerator gen = new SMIMECompressedGenerator(); - - // - // create the base for our message - // - MimeBodyPart msg = new MimeBodyPart(); - - msg.setDataHandler(new DataHandler(new FileDataSource(new File(args[0])))); - msg.setHeader("Content-Type", "application/octet-stream"); - msg.setHeader("Content-Transfer-Encoding", "binary"); - - MimeBodyPart mp = gen.generate(msg, new ZlibCompressor()); - - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example compressed message"); - body.setContent(mp.getContent(), mp.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("compressed.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeEncryptedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeEncryptedMail.java deleted file mode 100644 index 5fc7663a9..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeEncryptedMail.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.util.Properties; - -import javax.activation.DataHandler; -import javax.activation.FileDataSource; -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.CMSAlgorithm; -import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; -import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; - -/** - * a simple example that creates a single encrypted mail message. - * <p> - * The key store can be created using the class in - * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one - * key to be present in the key file. - * <p> - * Note: while this means that both the private key is available to - * the program, the private key is retrieved from the keystore only for - * the purposes of locating the corresponding public key, in normal circumstances - * you would only be doing this with a certificate available. - */ -public class CreateLargeEncryptedMail -{ - public static void main( - String args[]) - throws Exception - { - if (args.length != 3) - { - System.err.println("usage: CreateLargeEncryptedMail pkcs12Keystore password inputFile"); - System.exit(0); - } - - // - // Open the key store - // - KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); - String keyAlias = ExampleUtils.findKeyAlias(ks, args[0], args[1].toCharArray()); - - Certificate[] chain = ks.getCertificateChain(keyAlias); - - // - // create the generator for creating an smime/encrypted message - // - SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator(); - - gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator((X509Certificate)chain[0]).setProvider("BC")); - - // - // create a subject key id - this has to be done the same way as - // it is done in the certificate associated with the private key - // version 3 only. - // - /* - MessageDigest dig = MessageDigest.getInstance("SHA1", "BC"); - - dig.update(cert.getPublicKey().getEncoded()); - - gen.addKeyTransRecipient(cert.getPublicKey(), dig.digest()); - */ - - // - // create the base for our message - // - MimeBodyPart msg = new MimeBodyPart(); - - msg.setDataHandler(new DataHandler(new FileDataSource(new File(args[2])))); - msg.setHeader("Content-Type", "application/octet-stream"); - msg.setHeader("Content-Transfer-Encoding", "binary"); - - MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC).setProvider("BC").build()); - - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example encrypted message"); - body.setContent(mp.getContent(), mp.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("encrypted.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeSignedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeSignedMail.java deleted file mode 100644 index ffb092ab6..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateLargeSignedMail.java +++ /dev/null @@ -1,198 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Properties; - -import javax.activation.DataHandler; -import javax.activation.FileDataSource; -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.cms.AttributeTable; -import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; -import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; -import org.bouncycastle.asn1.smime.SMIMECapability; -import org.bouncycastle.asn1.smime.SMIMECapabilityVector; -import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; -import org.bouncycastle.mail.smime.SMIMESignedGenerator; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.util.Store; - -/** - * a simple example that creates a single signed mail message. - */ -public class CreateLargeSignedMail -{ - // - // certificate serial number seed. - // - static int serialNo = 1; - - /** - * create a basic X509 certificate from the given keys - */ - static X509Certificate makeCertificate( - KeyPair subKP, - String subDN, - KeyPair issKP, - String issDN) - throws GeneralSecurityException, IOException, OperatorCreationException - { - PublicKey subPub = subKP.getPublic(); - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); - X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); - - v3CertGen.addExtension( - X509Extension.subjectKeyIdentifier, - false, - extUtils.createSubjectKeyIdentifier(subPub)); - - v3CertGen.addExtension( - X509Extension.authorityKeyIdentifier, - false, - extUtils.createAuthorityKeyIdentifier(issPub)); - - return new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv))); - } - - public static void main( - String args[]) - throws Exception - { - // - // set up our certs - // - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); - - kpg.initialize(1024, new SecureRandom()); - - // - // cert that issued the signing certificate - // - String signDN = "O=Bouncy Castle, C=AU"; - KeyPair signKP = kpg.generateKeyPair(); - X509Certificate signCert = makeCertificate( - signKP, signDN, signKP, signDN); - - // - // cert we sign against - // - String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; - KeyPair origKP = kpg.generateKeyPair(); - X509Certificate origCert = makeCertificate( - origKP, origDN, signKP, signDN); - - List certList = new ArrayList(); - - certList.add(origCert); - certList.add(signCert); - - // - // create a CertStore containing the certificates we want carried - // in the signature - // - Store certs = new JcaCertStore(certList); - - // - // create some smime capabilities in case someone wants to respond - // - ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); - SMIMECapabilityVector caps = new SMIMECapabilityVector(); - - caps.addCapability(SMIMECapability.dES_EDE3_CBC); - caps.addCapability(SMIMECapability.rC2_CBC, 128); - caps.addCapability(SMIMECapability.dES_CBC); - - signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); - - // - // add an encryption key preference for encrypted responses - - // normally this would be different from the signing certificate... - // - IssuerAndSerialNumber issAndSer = new IssuerAndSerialNumber( - new X500Name(signDN), origCert.getSerialNumber()); - - signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer)); - - // - // create the generator for creating an smime/signed message - // - SMIMESignedGenerator gen = new SMIMESignedGenerator(); - - // - // add a signer to the generator - this specifies we are using SHA1 and - // adding the smime attributes above to the signed attributes that - // will be generated as part of the signature. The encryption algorithm - // used is taken from the key - in this RSA with PKCS1Padding - // - gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); - - // - // add our pool of certs and cerls (if any) to go with the signature - // - gen.addCertificates(certs); - - // - // create the base for our message - // - MimeBodyPart msg = new MimeBodyPart(); - - msg.setDataHandler(new DataHandler(new FileDataSource(new File(args[0])))); - msg.setHeader("Content-Type", "application/octet-stream"); - msg.setHeader("Content-Transfer-Encoding", "base64"); - - // - // extract the multipart object from the SMIMESigned object. - // - MimeMultipart mm = gen.generate(msg); - - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example signed message"); - body.setContent(mm, mm.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("signed.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateSignedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateSignedMail.java deleted file mode 100644 index 03c6a0676..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateSignedMail.java +++ /dev/null @@ -1,220 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.ByteArrayInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Properties; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.cms.AttributeTable; -import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; -import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; -import org.bouncycastle.asn1.smime.SMIMECapability; -import org.bouncycastle.asn1.smime.SMIMECapabilityVector; -import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; -import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; -import org.bouncycastle.mail.smime.SMIMESignedGenerator; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.util.Store; - -/** - * a simple example that creates a single signed mail message. - */ -public class CreateSignedMail -{ - // - // certificate serial number seed. - // - static int serialNo = 1; - - static AuthorityKeyIdentifier createAuthorityKeyId( - PublicKey pub) - throws IOException - { - ByteArrayInputStream bIn = new ByteArrayInputStream(pub.getEncoded()); - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( - (ASN1Sequence)new ASN1InputStream(bIn).readObject()); - - return new AuthorityKeyIdentifier(info); - } - - static SubjectKeyIdentifier createSubjectKeyId( - PublicKey pub) - throws IOException - { - ByteArrayInputStream bIn = new ByteArrayInputStream(pub.getEncoded()); - - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( - (ASN1Sequence)new ASN1InputStream(bIn).readObject()); - - return new SubjectKeyIdentifier(info); - } - - /** - * create a basic X509 certificate from the given keys - */ - static X509Certificate makeCertificate( - KeyPair subKP, - String subDN, - KeyPair issKP, - String issDN) - throws GeneralSecurityException, IOException, OperatorCreationException - { - PublicKey subPub = subKP.getPublic(); - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); - - v3CertGen.addExtension( - X509Extension.subjectKeyIdentifier, - false, - createSubjectKeyId(subPub)); - - v3CertGen.addExtension( - X509Extension.authorityKeyIdentifier, - false, - createAuthorityKeyId(issPub)); - - return new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv))); - } - - public static void main( - String args[]) - throws Exception - { - // - // set up our certs - // - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); - - kpg.initialize(1024, new SecureRandom()); - - // - // cert that issued the signing certificate - // - String signDN = "O=Bouncy Castle, C=AU"; - KeyPair signKP = kpg.generateKeyPair(); - X509Certificate signCert = makeCertificate( - signKP, signDN, signKP, signDN); - - // - // cert we sign against - // - String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; - KeyPair origKP = kpg.generateKeyPair(); - X509Certificate origCert = makeCertificate( - origKP, origDN, signKP, signDN); - - List certList = new ArrayList(); - - certList.add(origCert); - certList.add(signCert); - - // - // create a CertStore containing the certificates we want carried - // in the signature - // - Store certs = new JcaCertStore(certList); - - // - // create some smime capabilities in case someone wants to respond - // - ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); - SMIMECapabilityVector caps = new SMIMECapabilityVector(); - - caps.addCapability(SMIMECapability.dES_EDE3_CBC); - caps.addCapability(SMIMECapability.rC2_CBC, 128); - caps.addCapability(SMIMECapability.dES_CBC); - - signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); - - // - // add an encryption key preference for encrypted responses - - // normally this would be different from the signing certificate... - // - IssuerAndSerialNumber issAndSer = new IssuerAndSerialNumber( - new X500Name(signDN), origCert.getSerialNumber()); - - signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer)); - - // - // create the generator for creating an smime/signed message - // - SMIMESignedGenerator gen = new SMIMESignedGenerator(); - - // - // add a signer to the generator - this specifies we are using SHA1 and - // adding the smime attributes above to the signed attributes that - // will be generated as part of the signature. The encryption algorithm - // used is taken from the key - in this RSA with PKCS1Padding - // - gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); - - // - // add our pool of certs and cerls (if any) to go with the signature - // - gen.addCertificates(certs); - - // - // create the base for our message - // - MimeBodyPart msg = new MimeBodyPart(); - - msg.setText("Hello world!"); - - // - // extract the multipart object from the SMIMESigned object. - // - MimeMultipart mm = gen.generate(msg); - - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example signed message"); - body.setContent(mm, mm.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("signed.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateSignedMultipartMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateSignedMultipartMail.java deleted file mode 100644 index 20d1b3ea3..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/CreateSignedMultipartMail.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Properties; - -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.cms.AttributeTable; -import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; -import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; -import org.bouncycastle.asn1.smime.SMIMECapability; -import org.bouncycastle.asn1.smime.SMIMECapabilityVector; -import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; -import org.bouncycastle.mail.smime.SMIMESignedGenerator; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.util.Store; - -/** - * a simple example that creates a single signed multipart mail message. - */ -public class CreateSignedMultipartMail -{ - // - // certificate serial number seed. - // - static int serialNo = 1; - - /** - * create a basic X509 certificate from the given keys - */ - static X509Certificate makeCertificate( - KeyPair subKP, - String subDN, - KeyPair issKP, - String issDN) - throws GeneralSecurityException, IOException, OperatorCreationException - { - PublicKey subPub = subKP.getPublic(); - PrivateKey issPriv = issKP.getPrivate(); - PublicKey issPub = issKP.getPublic(); - - JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); - X509v3CertificateBuilder v3CertGen = new JcaX509v3CertificateBuilder(new X500Name(issDN), BigInteger.valueOf(serialNo++), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 100)), new X500Name(subDN), subPub); - - v3CertGen.addExtension( - X509Extension.subjectKeyIdentifier, - false, - extUtils.createSubjectKeyIdentifier(subPub)); - - v3CertGen.addExtension( - X509Extension.authorityKeyIdentifier, - false, - extUtils.createAuthorityKeyIdentifier(issPub)); - - return new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertGen.build(new JcaContentSignerBuilder("MD5withRSA").setProvider("BC").build(issPriv))); - } - - public static void main( - String args[]) - throws Exception - { - // - // set up our certs - // - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); - - kpg.initialize(1024, new SecureRandom()); - - // - // cert that issued the signing certificate - // - String signDN = "O=Bouncy Castle, C=AU"; - KeyPair signKP = kpg.generateKeyPair(); - X509Certificate signCert = makeCertificate( - signKP, signDN, signKP, signDN); - - // - // cert we sign against - // - String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; - KeyPair origKP = kpg.generateKeyPair(); - X509Certificate origCert = makeCertificate( - origKP, origDN, signKP, signDN); - - List certList = new ArrayList(); - - certList.add(origCert); - certList.add(signCert); - - // - // create a CertStore containing the certificates we want carried - // in the signature - // - Store certs = new JcaCertStore(certList); - - // - // create some smime capabilities in case someone wants to respond - // - ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); - SMIMECapabilityVector caps = new SMIMECapabilityVector(); - - caps.addCapability(SMIMECapability.dES_EDE3_CBC); - caps.addCapability(SMIMECapability.rC2_CBC, 128); - caps.addCapability(SMIMECapability.dES_CBC); - - signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); - - // - // add an encryption key preference for encrypted responses - - // normally this would be different from the signing certificate... - // - IssuerAndSerialNumber issAndSer = new IssuerAndSerialNumber( - new X500Name(signDN), origCert.getSerialNumber()); - - signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(issAndSer)); - - // - // create the generator for creating an smime/signed message - // - SMIMESignedGenerator gen = new SMIMESignedGenerator(); - - // - // add a signer to the generator - this specifies we are using SHA1 and - // adding the smime attributes above to the signed attributes that - // will be generated as part of the signature. The encryption algorithm - // used is taken from the key - in this RSA with PKCS1Padding - // - gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); - - // - // add our pool of certs and cerls (if any) to go with the signature - // - gen.addCertificates(certs); - - // - // create the base for our message - // - MimeBodyPart msg1 = new MimeBodyPart(); - - msg1.setText("Hello part 1!"); - - MimeBodyPart msg2 = new MimeBodyPart(); - - msg2.setText("Hello part 2!"); - - MimeMultipart mp = new MimeMultipart(); - - mp.addBodyPart(msg1); - mp.addBodyPart(msg2); - - MimeBodyPart m = new MimeBodyPart(); - - // - // be careful about setting extra headers here. Some mail clients - // ignore the To and From fields (for example) in the body part - // that contains the multipart. The result of this will be that the - // signature fails to verify... Outlook Express is an example of - // a client that exhibits this behaviour. - // - m.setContent(mp); - - // - // extract the multipart object from the SMIMESigned object. - // - MimeMultipart mm = gen.generate(m); - - // - // Get a Session object and create the mail message - // - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>"); - Address toUser = new InternetAddress("example@bouncycastle.org"); - - MimeMessage body = new MimeMessage(session); - body.setFrom(fromUser); - body.setRecipient(Message.RecipientType.TO, toUser); - body.setSubject("example signed message"); - body.setContent(mm, mm.getContentType()); - body.saveChanges(); - - body.writeTo(new FileOutputStream("signed.message")); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ExampleUtils.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ExampleUtils.java deleted file mode 100644 index 10c0f06c2..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ExampleUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.KeyStore; -import java.util.Enumeration; - -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; - -public class ExampleUtils -{ - /** - * Dump the content of the passed in BodyPart to the file fileName. - * - * @throws MessagingException - * @throws IOException - */ - public static void dumpContent( - MimeBodyPart bodyPart, - String fileName) - throws MessagingException, IOException - { - // - // print mime type of compressed content - // - System.out.println("content type: " + bodyPart.getContentType()); - - // - // recover the compressed content - // - OutputStream out = new FileOutputStream(fileName); - InputStream in = bodyPart.getInputStream(); - - byte[] buf = new byte[10000]; - int len; - - while ((len = in.read(buf, 0, buf.length)) > 0) - { - out.write(buf, 0, len); - } - - out.close(); - } - - public static String findKeyAlias( - KeyStore store, - String storeName, - char[] password) - throws Exception - { - store.load(new FileInputStream(storeName), password); - - Enumeration e = store.aliases(); - String keyAlias = null; - - while (e.hasMoreElements()) - { - String alias = (String)e.nextElement(); - - if (store.isKeyEntry(alias)) - { - keyAlias = alias; - } - } - - if (keyAlias == null) - { - throw new IllegalArgumentException("can't find a private key in keyStore: " + storeName); - } - - return keyAlias; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadCompressedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadCompressedMail.java deleted file mode 100644 index b462b336e..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadCompressedMail.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileInputStream; -import java.util.Properties; - -import javax.mail.Session; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.jcajce.ZlibExpanderProvider; -import org.bouncycastle.mail.smime.SMIMECompressed; -import org.bouncycastle.mail.smime.SMIMEUtil; - -/** - * a simple example that reads a compressed email. - * <p> - */ -public class ReadCompressedMail -{ - public static void main( - String args[]) - throws Exception - { - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - MimeMessage msg = new MimeMessage(session, new FileInputStream("compressed.message")); - - SMIMECompressed m = new SMIMECompressed(msg); - - MimeBodyPart res = SMIMEUtil.toMimeBodyPart(m.getContent(new ZlibExpanderProvider())); - - System.out.println("Message Contents"); - System.out.println("----------------"); - System.out.println(res.getContent()); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadEncryptedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadEncryptedMail.java deleted file mode 100644 index a180994f9..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadEncryptedMail.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileInputStream; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.Properties; - -import javax.mail.Session; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.RecipientId; -import org.bouncycastle.cms.RecipientInformation; -import org.bouncycastle.cms.RecipientInformationStore; -import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; -import org.bouncycastle.mail.smime.SMIMEEnveloped; -import org.bouncycastle.mail.smime.SMIMEUtil; - -/** - * a simple example that reads an encrypted email. - * <p> - * The key store can be created using the class in - * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one - * key to be present. - */ -public class ReadEncryptedMail -{ - public static void main( - String args[]) - throws Exception - { - if (args.length != 2) - { - System.err.println("usage: ReadEncryptedMail pkcs12Keystore password"); - System.exit(0); - } - - // - // Open the key store - // - KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); - - ks.load(new FileInputStream(args[0]), args[1].toCharArray()); - - Enumeration e = ks.aliases(); - String keyAlias = null; - - while (e.hasMoreElements()) - { - String alias = (String)e.nextElement(); - - if (ks.isKeyEntry(alias)) - { - keyAlias = alias; - } - } - - if (keyAlias == null) - { - System.err.println("can't find a private key!"); - System.exit(0); - } - - // - // find the certificate for the private key and generate a - // suitable recipient identifier. - // - X509Certificate cert = (X509Certificate)ks.getCertificate(keyAlias); - RecipientId recId = new JceKeyTransRecipientId(cert); - - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - MimeMessage msg = new MimeMessage(session, new FileInputStream("encrypted.message")); - - SMIMEEnveloped m = new SMIMEEnveloped(msg); - - RecipientInformationStore recipients = m.getRecipientInfos(); - RecipientInformation recipient = recipients.get(recId); - - MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient((PrivateKey)ks.getKey(keyAlias, null)).setProvider("BC"))); - - System.out.println("Message Contents"); - System.out.println("----------------"); - System.out.println(res.getContent()); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeCompressedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeCompressedMail.java deleted file mode 100644 index 795d0497b..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeCompressedMail.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.util.Properties; - -import javax.mail.Session; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.jcajce.ZlibExpanderProvider; -import org.bouncycastle.mail.smime.SMIMECompressedParser; -import org.bouncycastle.mail.smime.SMIMEUtil; -import org.bouncycastle.mail.smime.util.SharedFileInputStream; - -/** - * a simple example that reads an oversize compressed email and writes data contained - * in the compressed part into a file. - */ -public class ReadLargeCompressedMail -{ - public static void main( - String args[]) - throws Exception - { - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("compressed.message")); - - SMIMECompressedParser m = new SMIMECompressedParser(msg); - MimeBodyPart res = SMIMEUtil.toMimeBodyPart(m.getContent(new ZlibExpanderProvider())); - - ExampleUtils.dumpContent(res, args[0]); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeEncryptedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeEncryptedMail.java deleted file mode 100644 index 8389b443b..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeEncryptedMail.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.util.Properties; - -import javax.mail.Session; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; - -import org.bouncycastle.cms.RecipientId; -import org.bouncycastle.cms.RecipientInformation; -import org.bouncycastle.cms.RecipientInformationStore; -import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId; -import org.bouncycastle.mail.smime.SMIMEEnvelopedParser; -import org.bouncycastle.mail.smime.SMIMEUtil; -import org.bouncycastle.mail.smime.util.SharedFileInputStream; - -/** - * a simple example that reads an encrypted email using the large file model. - * <p> - * The key store can be created using the class in - * org.bouncycastle.jce.examples.PKCS12Example - the program expects only one - * key to be present. - */ -public class ReadLargeEncryptedMail -{ - public static void main( - String args[]) - throws Exception - { - if (args.length != 3) - { - System.err.println("usage: ReadLargeEncryptedMail pkcs12Keystore password outputFile"); - System.exit(0); - } - - // - // Open the key store - // - KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); - String keyAlias = ExampleUtils.findKeyAlias(ks, args[0], args[1].toCharArray()); - - // - // find the certificate for the private key and generate a - // suitable recipient identifier. - // - X509Certificate cert = (X509Certificate)ks.getCertificate(keyAlias); - RecipientId recId = new JceKeyTransRecipientId(cert); - - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("encrypted.message")); - - SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(msg); - - RecipientInformationStore recipients = m.getRecipientInfos(); - RecipientInformation recipient = recipients.get(recId); - - MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient((PrivateKey)ks.getKey(keyAlias, null)).setProvider("BC"))); - - ExampleUtils.dumpContent(res, args[2]); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeSignedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeSignedMail.java deleted file mode 100644 index 910743370..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadLargeSignedMail.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.security.cert.X509Certificate; -import java.util.Collection; -import java.util.Iterator; -import java.util.Properties; - -import javax.mail.Session; -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.SignerInformation; -import org.bouncycastle.cms.SignerInformationStore; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.mail.smime.SMIMESignedParser; -import org.bouncycastle.mail.smime.util.SharedFileInputStream; -import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; -import org.bouncycastle.util.Store; - -/** - * a simple example that reads a basic SMIME signed mail file. - */ -public class ReadLargeSignedMail -{ - private static final String BC = BouncyCastleProvider.PROVIDER_NAME; - - /** - * verify the signature (assuming the cert is contained in the message) - */ - private static void verify( - SMIMESignedParser 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().setProvider(BC).getCertificate((X509CertificateHolder)certIt.next()); - - - // - // verify that the sig is correct and that it was generated - // when the certificate was current - // - if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) - { - System.out.println("signature verified"); - } - else - { - System.out.println("signature failed!"); - } - } - } - - public static void main( - String[] args) - throws Exception - { - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("signed.message")); - - // - // make sure this was a multipart/signed message - there should be - // two parts as we have one part for the content that was signed and - // one part for the actual signature. - // - if (msg.isMimeType("multipart/signed")) - { - SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().build(), - (MimeMultipart)msg.getContent()); - - System.out.println("Status:"); - - verify(s); - } - else if (msg.isMimeType("application/pkcs7-mime")) - { - // - // in this case the content is wrapped in the signature block. - // - SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().build(), msg); - - System.out.println("Status:"); - - verify(s); - } - else - { - System.err.println("Not a signed message!"); - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadSignedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadSignedMail.java deleted file mode 100644 index 370106d96..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ReadSignedMail.java +++ /dev/null @@ -1,176 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileInputStream; -import java.security.cert.X509Certificate; -import java.util.Collection; -import java.util.Iterator; -import java.util.Properties; - -import javax.mail.BodyPart; -import javax.mail.Multipart; -import javax.mail.Session; -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.SignerInformation; -import org.bouncycastle.cms.SignerInformationStore; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.mail.smime.SMIMESigned; -import org.bouncycastle.util.Store; - -/** - * a simple example that reads a basic SMIME signed mail file. - */ -public class ReadSignedMail -{ - private static final String BC = BouncyCastleProvider.PROVIDER_NAME; - - /** - * verify the signature (assuming the cert is contained in the message) - */ - private static void verify( - SMIMESigned s) - throws Exception - { - // - // extract the information to verify the signatures. - // - - // - // certificates and crls passed in the signature - // - 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().setProvider(BC).getCertificate((X509CertificateHolder)certIt.next()); - - // - // verify that the sig is correct and that it was generated - // when the certificate was current - // - if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert))) - { - System.out.println("signature verified"); - } - else - { - System.out.println("signature failed!"); - } - } - } - - public static void main( - String[] args) - throws Exception - { - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - MimeMessage msg = new MimeMessage(session, new FileInputStream("signed.message")); - - // - // make sure this was a multipart/signed message - there should be - // two parts as we have one part for the content that was signed and - // one part for the actual signature. - // - if (msg.isMimeType("multipart/signed")) - { - SMIMESigned s = new SMIMESigned( - (MimeMultipart)msg.getContent()); - - // - // extract the content - // - MimeBodyPart content = s.getContent(); - - System.out.println("Content:"); - - Object cont = content.getContent(); - - if (cont instanceof String) - { - System.out.println((String)cont); - } - else if (cont instanceof Multipart) - { - Multipart mp = (Multipart)cont; - int count = mp.getCount(); - for (int i = 0; i < count; i++) - { - BodyPart m = mp.getBodyPart(i); - Object part = m.getContent(); - - System.out.println("Part " + i); - System.out.println("---------------------------"); - - if (part instanceof String) - { - System.out.println((String)part); - } - else - { - System.out.println("can't print..."); - } - } - } - - System.out.println("Status:"); - - verify(s); - } - else if (msg.isMimeType("application/pkcs7-mime") - || msg.isMimeType("application/x-pkcs7-mime")) - { - // - // in this case the content is wrapped in the signature block. - // - SMIMESigned s = new SMIMESigned(msg); - - // - // extract the content - // - MimeBodyPart content = s.getContent(); - - System.out.println("Content:"); - - Object cont = content.getContent(); - - if (cont instanceof String) - { - System.out.println((String)cont); - } - - System.out.println("Status:"); - - verify(s); - } - else - { - System.err.println("Not a signed message!"); - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/SendSignedAndEncryptedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/SendSignedAndEncryptedMail.java deleted file mode 100644 index 8861152ef..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/SendSignedAndEncryptedMail.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.Security; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; - -import javax.activation.CommandMap; -import javax.activation.MailcapCommandMap; -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.cms.AttributeTable; -import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; -import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; -import org.bouncycastle.asn1.smime.SMIMECapability; -import org.bouncycastle.asn1.smime.SMIMECapabilityVector; -import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.cms.CMSAlgorithm; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; -import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; -import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; -import org.bouncycastle.mail.smime.SMIMEException; -import org.bouncycastle.mail.smime.SMIMESignedGenerator; -import org.bouncycastle.util.Store; -import org.bouncycastle.util.Strings; - -/** - * Example that sends a signed and encrypted mail message. - */ -public class SendSignedAndEncryptedMail -{ - public static void main(String args[]) - { - if (args.length != 5) - { - System.err - .println("usage: SendSignedAndEncryptedMail <pkcs12Keystore> <password> <keyalias> <smtp server> <email address>"); - System.exit(0); - } - - try - { - MailcapCommandMap mailcap = (MailcapCommandMap)CommandMap - .getDefaultCommandMap(); - - mailcap - .addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); - mailcap - .addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); - mailcap - .addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); - mailcap - .addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); - mailcap - .addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); - - CommandMap.setDefaultCommandMap(mailcap); - - /* Add BC */ - Security.addProvider(new BouncyCastleProvider()); - - /* Open the keystore */ - KeyStore keystore = KeyStore.getInstance("PKCS12", "BC"); - keystore.load(new FileInputStream(args[0]), args[1].toCharArray()); - Certificate[] chain = keystore.getCertificateChain(args[2]); - - /* Get the private key to sign the message with */ - PrivateKey privateKey = (PrivateKey)keystore.getKey(args[2], - args[1].toCharArray()); - if (privateKey == null) - { - throw new Exception("cannot find private key for alias: " - + args[2]); - } - - /* Create the message to sign and encrypt */ - Properties props = System.getProperties(); - props.put("mail.smtp.host", args[3]); - Session session = Session.getDefaultInstance(props, null); - - MimeMessage body = new MimeMessage(session); - body.setFrom(new InternetAddress(args[4])); - body.setRecipient(Message.RecipientType.TO, new InternetAddress( - args[4])); - body.setSubject("example encrypted message"); - body.setContent("example encrypted message", "text/plain"); - body.saveChanges(); - - /* Create the SMIMESignedGenerator */ - SMIMECapabilityVector capabilities = new SMIMECapabilityVector(); - capabilities.addCapability(SMIMECapability.dES_EDE3_CBC); - capabilities.addCapability(SMIMECapability.rC2_CBC, 128); - capabilities.addCapability(SMIMECapability.dES_CBC); - - ASN1EncodableVector attributes = new ASN1EncodableVector(); - attributes.add(new SMIMEEncryptionKeyPreferenceAttribute( - new IssuerAndSerialNumber( - new X500Name(((X509Certificate)chain[0]) - .getIssuerDN().getName()), - ((X509Certificate)chain[0]).getSerialNumber()))); - attributes.add(new SMIMECapabilitiesAttribute(capabilities)); - - SMIMESignedGenerator signer = new SMIMESignedGenerator(); - signer.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(attributes)).build("DSA".equals(privateKey.getAlgorithm()) ? "SHA1withDSA" : "MD5withRSA", privateKey, (X509Certificate)chain[0])); - - - /* Add the list of certs to the generator */ - List certList = new ArrayList(); - certList.add(chain[0]); - Store certs = new JcaCertStore(certList); - signer.addCertificates(certs); - - /* Sign the message */ - MimeMultipart mm = signer.generate(body); - MimeMessage signedMessage = new MimeMessage(session); - - /* Set all original MIME headers in the signed message */ - Enumeration headers = body.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - signedMessage.addHeaderLine((String)headers.nextElement()); - } - - /* Set the content of the signed message */ - signedMessage.setContent(mm); - signedMessage.saveChanges(); - - /* Create the encrypter */ - SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator(); - encrypter.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator((X509Certificate)chain[0]).setProvider("BC")); - - /* Encrypt the message */ - MimeBodyPart encryptedPart = encrypter.generate(signedMessage, - new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC).setProvider("BC").build()); - - /* - * Create a new MimeMessage that contains the encrypted and signed - * content - */ - ByteArrayOutputStream out = new ByteArrayOutputStream(); - encryptedPart.writeTo(out); - - MimeMessage encryptedMessage = new MimeMessage(session, - new ByteArrayInputStream(out.toByteArray())); - - /* Set all original MIME headers in the encrypted message */ - headers = body.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - String headerLine = (String)headers.nextElement(); - /* - * Make sure not to override any content-* headers from the - * original message - */ - if (!Strings.toLowerCase(headerLine).startsWith("content-")) - { - encryptedMessage.addHeaderLine(headerLine); - } - } - - Transport.send(encryptedMessage); - } - catch (SMIMEException ex) - { - ex.getUnderlyingException().printStackTrace(System.err); - ex.printStackTrace(System.err); - } - catch (Exception ex) - { - ex.printStackTrace(System.err); - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ValidateSignedMail.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ValidateSignedMail.java deleted file mode 100644 index 31961f1e1..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/examples/ValidateSignedMail.java +++ /dev/null @@ -1,352 +0,0 @@ -package org.bouncycastle.mail.smime.examples; - -import java.io.FileInputStream; -import java.io.InputStream; -import java.security.KeyPairGenerator; -import java.security.KeyStore; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.Security; -import java.security.cert.CertStore; -import java.security.cert.CertificateFactory; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXParameters; -import java.security.cert.TrustAnchor; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Properties; -import java.util.Set; - -import javax.mail.Session; -import javax.mail.internet.MimeMessage; -import javax.security.auth.x500.X500Principal; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.x509.X509Extension; -import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.i18n.ErrorBundle; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.mail.smime.validator.SignedMailValidator; -import org.bouncycastle.x509.PKIXCertPathReviewer; -import org.bouncycastle.x509.extension.X509ExtensionUtil; - -/** - * An Example that reads a signed mail and validates its signature. Also - * validating the certificate path from the signers key to a trusted entity - */ -public class ValidateSignedMail -{ - - /* - * Use trusted certificates from $JAVA_HOME/lib/security/cacerts as - * trustanchors - */ - public static final boolean useCaCerts = false; - - public static void main(String[] args) throws Exception - { - - Security.addProvider(new BouncyCastleProvider()); - - // - // Get a Session object with the default properties. - // - Properties props = System.getProperties(); - - Session session = Session.getDefaultInstance(props, null); - - // read message - MimeMessage msg = new MimeMessage(session, new FileInputStream( - "signed.message")); - - // create PKIXparameters - PKIXParameters param; - - if (useCaCerts) - { - KeyStore caCerts = KeyStore.getInstance("JKS"); - String javaHome = System.getProperty("java.home"); - caCerts.load( - new FileInputStream(javaHome + "/lib/security/cacerts"), - "changeit".toCharArray()); - - param = new PKIXParameters(caCerts); - } - else - { - // load trustanchors from files (here we only load one) - Set trustanchors = new HashSet(); - TrustAnchor trust = getTrustAnchor("trustanchor"); - - // create a dummy trustanchor if we can not find any trustanchor. so - // we can still try to validate the message - if (trust == null) - { - System.out - .println("no trustanchor file found, using a dummy trustanchor"); - trust = getDummyTrustAnchor(); - } - trustanchors.add(trust); - - param = new PKIXParameters(trustanchors); - } - - // load one ore more crls from files (here we only load one crl) - List crls = new ArrayList(); - X509CRL crl = loadCRL("crl.file"); - if (crl != null) - { - crls.add(crl); - } - CertStore certStore = CertStore.getInstance("Collection", - new CollectionCertStoreParameters(crls), "BC"); - - // add crls and enable revocation checking - param.addCertStore(certStore); - param.setRevocationEnabled(true); - - // or disable revocation checking - // param.setRevocationEnabled(false); - - verifySignedMail(msg, param); - } - - public static final int TITLE = 0; - public static final int TEXT = 1; - public static final int SUMMARY = 2; - public static final int DETAIL = 3; - - static int dbgLvl = DETAIL; - - private static final String RESOURCE_NAME = "org.bouncycastle.mail.smime.validator.SignedMailValidatorMessages"; - - public static void verifySignedMail(MimeMessage msg, PKIXParameters param) - throws Exception - { - // set locale for the output - Locale loc = Locale.ENGLISH; - // Locale loc = Locale.GERMAN; - - // validate signatures - SignedMailValidator validator = new SignedMailValidator(msg, param); - - // iterate over all signatures and print results - Iterator it = validator.getSignerInformationStore().getSigners() - .iterator(); - while (it.hasNext()) - { - SignerInformation signer = (SignerInformation) it.next(); - SignedMailValidator.ValidationResult result = validator - .getValidationResult(signer); - if (result.isValidSignature()) - { - ErrorBundle errMsg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.sigValid"); - System.out.println(errMsg.getText(loc)); - } - else - { - ErrorBundle errMsg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.sigInvalid"); - System.out.println(errMsg.getText(loc)); - // print errors - System.out.println("Errors:"); - Iterator errorsIt = result.getErrors().iterator(); - while (errorsIt.hasNext()) - { - ErrorBundle errorMsg = (ErrorBundle) errorsIt.next(); - if (dbgLvl == DETAIL) - { - System.out.println("\t\t" + errorMsg.getDetail(loc)); - } - else - { - System.out.println("\t\t" + errorMsg.getText(loc)); - } - } - } - if (!result.getNotifications().isEmpty()) - { - System.out.println("Notifications:"); - Iterator notIt = result.getNotifications().iterator(); - while (notIt.hasNext()) - { - ErrorBundle notMsg = (ErrorBundle) notIt.next(); - if (dbgLvl == DETAIL) - { - System.out.println("\t\t" + notMsg.getDetail(loc)); - } - else - { - System.out.println("\t\t" + notMsg.getText(loc)); - } - } - } - PKIXCertPathReviewer review = result.getCertPathReview(); - if (review != null) - { - if (review.isValidCertPath()) - { - System.out.println("Certificate path valid"); - } - else - { - System.out.println("Certificate path invalid"); - } - - System.out.println("\nCertificate path validation results:"); - // global errors - System.out.println("Errors:"); - Iterator errorsIt = review.getErrors(-1).iterator(); - while (errorsIt.hasNext()) - { - ErrorBundle errorMsg = (ErrorBundle) errorsIt.next(); - if (dbgLvl == DETAIL) - { - System.out.println("\t\t" + errorMsg.getDetail(loc)); - } - else - { - System.out.println("\t\t" + errorMsg.getText(loc)); - } - } - - System.out.println("Notifications:"); - Iterator notificationsIt = review.getNotifications(-1) - .iterator(); - while (notificationsIt.hasNext()) - { - ErrorBundle noteMsg = (ErrorBundle) notificationsIt.next(); - System.out.println("\t" + noteMsg.getText(loc)); - } - - // per certificate errors and notifications - Iterator certIt = review.getCertPath().getCertificates() - .iterator(); - int i = 0; - while (certIt.hasNext()) - { - X509Certificate cert = (X509Certificate) certIt.next(); - System.out.println("\nCertificate " + i + "\n========"); - System.out.println("Issuer: " - + cert.getIssuerDN().getName()); - System.out.println("Subject: " - + cert.getSubjectDN().getName()); - - // errors - System.out.println("\tErrors:"); - errorsIt = review.getErrors(i).iterator(); - while (errorsIt.hasNext()) - { - ErrorBundle errorMsg = (ErrorBundle) errorsIt.next(); - if (dbgLvl == DETAIL) - { - System.out - .println("\t\t" + errorMsg.getDetail(loc)); - } - else - { - System.out.println("\t\t" + errorMsg.getText(loc)); - } - } - - // notifications - System.out.println("\tNotifications:"); - notificationsIt = review.getNotifications(i).iterator(); - while (notificationsIt.hasNext()) - { - ErrorBundle noteMsg = (ErrorBundle) notificationsIt - .next(); - if (dbgLvl == DETAIL) - { - System.out.println("\t\t" + noteMsg.getDetail(loc)); - } - else - { - System.out.println("\t\t" + noteMsg.getText(loc)); - } - } - - i++; - } - } - } - - } - - protected static TrustAnchor getTrustAnchor(String trustcert) - throws Exception - { - X509Certificate cert = loadCert(trustcert); - if (cert != null) - { - byte[] ncBytes = cert - .getExtensionValue(X509Extension.nameConstraints.getId()); - - if (ncBytes != null) - { - ASN1Encodable extValue = X509ExtensionUtil - .fromExtensionValue(ncBytes); - return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER)); - } - return new TrustAnchor(cert, null); - } - return null; - } - - protected static X509Certificate loadCert(String certfile) - { - X509Certificate cert = null; - try - { - InputStream in = new FileInputStream(certfile); - - CertificateFactory cf = CertificateFactory.getInstance("X.509", - "BC"); - cert = (X509Certificate) cf.generateCertificate(in); - } - catch (Exception e) - { - System.out.println("certfile \"" + certfile - + "\" not found - classpath is " - + System.getProperty("java.class.path")); - } - return cert; - } - - protected static X509CRL loadCRL(String crlfile) - { - X509CRL crl = null; - try - { - InputStream in = new FileInputStream(crlfile); - - CertificateFactory cf = CertificateFactory.getInstance("X.509", - "BC"); - crl = (X509CRL) cf.generateCRL(in); - } - catch (Exception e) - { - System.out.println("crlfile \"" + crlfile - + "\" not found - classpath is " - + System.getProperty("java.class.path")); - } - return crl; - } - - private static TrustAnchor getDummyTrustAnchor() throws Exception - { - X500Principal principal = new X500Principal("CN=Dummy Trust Anchor"); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC"); - kpg.initialize(1024, new SecureRandom()); - PublicKey trustPubKey = kpg.generateKeyPair().getPublic(); - return new TrustAnchor(principal, trustPubKey, null); - } - -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/PKCS7ContentHandler.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/PKCS7ContentHandler.java deleted file mode 100644 index d3db7fd6e..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/PKCS7ContentHandler.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.bouncycastle.mail.smime.handlers; - -import java.awt.datatransfer.DataFlavor; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.activation.ActivationDataFlavor; -import javax.activation.DataContentHandler; -import javax.activation.DataSource; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; - -import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; - -public class PKCS7ContentHandler - implements DataContentHandler -{ - private final ActivationDataFlavor _adf; - private final DataFlavor[] _dfs; - - PKCS7ContentHandler( - ActivationDataFlavor adf, - DataFlavor[] dfs) - { - _adf = adf; - _dfs = dfs; - } - - public Object getContent( - DataSource ds) - throws IOException - { - return ds.getInputStream(); - } - - public Object getTransferData( - DataFlavor df, - DataSource ds) - throws IOException - { - if (_adf.equals(df)) - { - return getContent(ds); - } - else - { - return null; - } - } - - public DataFlavor[] getTransferDataFlavors() - { - return _dfs; - } - - public void writeTo( - Object obj, - String mimeType, - OutputStream os) - throws IOException - { - if (obj instanceof MimeBodyPart) - { - try - { - ((MimeBodyPart)obj).writeTo(os); - } - catch (MessagingException ex) - { - throw new IOException(ex.getMessage()); - } - } - else if (obj instanceof byte[]) - { - os.write((byte[])obj); - } - else if (obj instanceof InputStream) - { - int b; - InputStream in = (InputStream)obj; - - if (!(in instanceof BufferedInputStream)) - { - in = new BufferedInputStream(in); - } - - while ((b = in.read()) >= 0) - { - os.write(b); - } - } - else if (obj instanceof SMIMEStreamingProcessor) - { - SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; - - processor.write(os); - } - else - { - // TODO it would be even nicer if we could attach the object to the exception - // as well since in deeply nested messages, it is not always clear which - // part caused the problem. Thus I guess we would have to subclass the - // IOException - - throw new IOException("unknown object in writeTo " + obj); - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/multipart_signed.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/multipart_signed.java deleted file mode 100644 index dd5ef193a..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/multipart_signed.java +++ /dev/null @@ -1,280 +0,0 @@ -package org.bouncycastle.mail.smime.handlers; - -import org.bouncycastle.mail.smime.SMIMEStreamingProcessor; - -import javax.activation.ActivationDataFlavor; -import javax.activation.DataContentHandler; -import javax.activation.DataSource; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.internet.ContentType; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMultipart; -import java.awt.datatransfer.DataFlavor; -import java.io.BufferedInputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Enumeration; - -public class multipart_signed - implements DataContentHandler -{ - private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeMultipart.class, "multipart/signed", "Multipart Signed"); - private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; - - public Object getContent(DataSource ds) - throws IOException - { - try - { - return new MimeMultipart(ds); - } - catch (MessagingException ex) - { - return null; - } - } - - public Object getTransferData(DataFlavor df, DataSource ds) - throws IOException - { - if (ADF.equals(df)) - { - return getContent(ds); - } - else - { - return null; - } - } - - public DataFlavor[] getTransferDataFlavors() - { - return DFS; - } - - public void writeTo(Object obj, String _mimeType, OutputStream os) - throws IOException - { - - if (obj instanceof MimeMultipart) - { - try - { - outputBodyPart(os, obj); - } - catch (MessagingException ex) - { - throw new IOException(ex.getMessage()); - } - } - else if(obj instanceof byte[]) - { - os.write((byte[])obj); - } - else if (obj instanceof InputStream) - { - int b; - InputStream in = (InputStream)obj; - - if (!(in instanceof BufferedInputStream)) - { - in = new BufferedInputStream(in); - } - - while ((b = in.read()) >= 0) - { - os.write(b); - } - } - else if (obj instanceof SMIMEStreamingProcessor) - { - SMIMEStreamingProcessor processor = (SMIMEStreamingProcessor)obj; - - processor.write(os); - } - else - { - throw new IOException("unknown object in writeTo " + obj); - } - } - - /* - * Output the mulitpart as a collection of leaves to make sure preamble text is not included. - */ - private void outputBodyPart( - OutputStream out, - Object bodyPart) - throws MessagingException, IOException - { - if (bodyPart instanceof Multipart) - { - Multipart mp = (Multipart)bodyPart; - ContentType contentType = new ContentType(mp.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - - LineOutputStream lOut = new LineOutputStream(out); - - for (int i = 0; i < mp.getCount(); i++) - { - lOut.writeln(boundary); - outputBodyPart(out, mp.getBodyPart(i)); - lOut.writeln(); // CRLF terminator - } - - lOut.writeln(boundary + "--"); - return; - } - - MimeBodyPart mimePart = (MimeBodyPart)bodyPart; - - if (mimePart.getContent() instanceof Multipart) - { - Multipart mp = (Multipart)mimePart.getContent(); - ContentType contentType = new ContentType(mp.getContentType()); - String boundary = "--" + contentType.getParameter("boundary"); - - LineOutputStream lOut = new LineOutputStream(out); - - Enumeration headers = mimePart.getAllHeaderLines(); - while (headers.hasMoreElements()) - { - lOut.writeln((String)headers.nextElement()); - } - - lOut.writeln(); // CRLF separator - - outputPreamble(lOut, mimePart, boundary); - - outputBodyPart(out, mp); - return; - } - - mimePart.writeTo(out); - } - - /** - * internal preamble is generally included in signatures, while this is technically wrong, - * if we find internal preamble we include it by default. - */ - static void outputPreamble(LineOutputStream lOut, MimeBodyPart part, String boundary) - throws MessagingException, IOException - { - InputStream in; - - try - { - in = part.getRawInputStream(); - } - catch (MessagingException e) - { - return; // no underlying content, rely on default generation - } - - String line; - - while ((line = readLine(in)) != null) - { - if (line.equals(boundary)) - { - break; - } - - lOut.writeln(line); - } - - in.close(); - - if (line == null) - { - throw new MessagingException("no boundary found"); - } - } - - /* - * read a line of input stripping of the tailing \r\n - */ - private static String readLine(InputStream in) - throws IOException - { - StringBuffer b = new StringBuffer(); - - int ch; - while ((ch = in.read()) >= 0 && ch != '\n') - { - if (ch != '\r') - { - b.append((char)ch); - } - } - - if (ch < 0) - { - return null; - } - - return b.toString(); - } - - private static class LineOutputStream extends FilterOutputStream - { - private static byte newline[]; - - public LineOutputStream(OutputStream outputstream) - { - super(outputstream); - } - - public void writeln(String s) - throws MessagingException - { - try - { - byte abyte0[] = getBytes(s); - super.out.write(abyte0); - super.out.write(newline); - } - catch(Exception exception) - { - throw new MessagingException("IOException", exception); - } - } - - public void writeln() - throws MessagingException - { - try - { - super.out.write(newline); - } - catch(Exception exception) - { - throw new MessagingException("IOException", exception); - } - } - - static - { - newline = new byte[2]; - newline[0] = 13; - newline[1] = 10; - } - - private static byte[] getBytes(String s) - { - char ac[] = s.toCharArray(); - int i = ac.length; - byte abyte0[] = new byte[i]; - int j = 0; - - while (j < i) - { - abyte0[j] = (byte)ac[j++]; - } - - return abyte0; - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/pkcs7_mime.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/pkcs7_mime.java deleted file mode 100644 index abdf1251e..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/pkcs7_mime.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.mail.smime.handlers; - -import java.awt.datatransfer.DataFlavor; - -import javax.activation.ActivationDataFlavor; -import javax.mail.internet.MimeBodyPart; - -public class pkcs7_mime - extends PKCS7ContentHandler -{ - private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/pkcs7-mime", "Encrypted Data"); - private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; - - public pkcs7_mime() - { - super(ADF, DFS); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/pkcs7_signature.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/pkcs7_signature.java deleted file mode 100644 index 0c669508f..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/pkcs7_signature.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.mail.smime.handlers; - -import java.awt.datatransfer.DataFlavor; - -import javax.activation.ActivationDataFlavor; -import javax.mail.internet.MimeBodyPart; - -public class pkcs7_signature - extends PKCS7ContentHandler -{ - private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/pkcs7-signature", "Signature"); - private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; - - public pkcs7_signature() - { - super(ADF, DFS); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/x_pkcs7_mime.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/x_pkcs7_mime.java deleted file mode 100644 index 7e28f281d..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/x_pkcs7_mime.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.mail.smime.handlers; - -import java.awt.datatransfer.DataFlavor; - -import javax.activation.ActivationDataFlavor; -import javax.mail.internet.MimeBodyPart; - -public class x_pkcs7_mime - extends PKCS7ContentHandler -{ - private static final ActivationDataFlavor ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/x-pkcs7-mime", "Encrypted Data"); - private static final DataFlavor[] DFS = new DataFlavor[] { ADF }; - - public x_pkcs7_mime() - { - super(ADF, DFS); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/x_pkcs7_signature.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/x_pkcs7_signature.java deleted file mode 100644 index a58fd5310..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/handlers/x_pkcs7_signature.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.bouncycastle.mail.smime.handlers; - -import java.awt.datatransfer.DataFlavor; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.activation.ActivationDataFlavor; -import javax.activation.DataContentHandler; -import javax.activation.DataSource; -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; - -public class x_pkcs7_signature - implements DataContentHandler -{ - - /* - * - * VARIABLES - * - */ - - private static final ActivationDataFlavor ADF; - private static final DataFlavor[] ADFs; - - static - { - ADF = new ActivationDataFlavor(MimeBodyPart.class, "application/x-pkcs7-signature", "Signature"); - ADFs = new DataFlavor[] { ADF }; - } - - public Object getContent(DataSource _ds) - throws IOException - { - return _ds.getInputStream(); - } - - public Object getTransferData(DataFlavor _df, DataSource _ds) - throws IOException - { - if (ADF.equals(_df)) - { - return getContent(_ds); - } - else - { - return null; - } - } - - public DataFlavor[] getTransferDataFlavors() - { - return ADFs; - } - - public void writeTo(Object _obj, String _mimeType, OutputStream _os) - throws IOException - { - if (_obj instanceof MimeBodyPart) - { - try - { - ((MimeBodyPart)_obj).writeTo(_os); - } - catch (MessagingException ex) - { - throw new IOException(ex.getMessage()); - } - } - else if (_obj instanceof byte[]) - { - _os.write((byte[])_obj); - } - else if (_obj instanceof InputStream) - { - int b; - InputStream in = (InputStream)_obj; - - while ((b = in.read()) >= 0) - { - _os.write(b); - } - } - else - { - throw new IOException("unknown object in writeTo " + _obj); - } - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/CRLFOutputStream.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/CRLFOutputStream.java deleted file mode 100644 index b11583d0d..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/CRLFOutputStream.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.bouncycastle.mail.smime.util; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -public class CRLFOutputStream extends FilterOutputStream -{ - protected int lastb; - protected static byte newline[]; - - public CRLFOutputStream(OutputStream outputstream) - { - super(outputstream); - lastb = -1; - } - - public void write(int i) - throws IOException - { - if (i == '\r') - { - out.write(newline); - } - else if (i == '\n') - { - if (lastb != '\r') - { - out.write(newline); - } - } - else - { - out.write(i); - } - - lastb = i; - } - - public void write(byte[] buf) - throws IOException - { - this.write(buf, 0, buf.length); - } - - public void write(byte buf[], int off, int len) - throws IOException - { - for (int i = off; i != off + len; i++) - { - this.write(buf[i]); - } - } - - public void writeln() - throws IOException - { - super.out.write(newline); - } - - static - { - newline = new byte[2]; - newline[0] = '\r'; - newline[1] = '\n'; - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java deleted file mode 100644 index 6bae91c9e..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/FileBackedMimeBodyPart.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.bouncycastle.mail.smime.util; - -import javax.mail.MessagingException; -import javax.mail.internet.InternetHeaders; -import javax.mail.internet.MimeBodyPart; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Enumeration; - -public class FileBackedMimeBodyPart - extends MimeBodyPart -{ - private static final int BUF_SIZE = 32760; - - private final File _file; - - /** - * Create a MimeBodyPart backed by the data in file. - * - * @param file file containing the body part. - * @throws MessagingException an exception occurs parsing file. - * @throws IOException an exception occurs accessing file. - */ - public FileBackedMimeBodyPart( - File file) - throws MessagingException, IOException - { - super(new SharedFileInputStream(file)); - - _file = file; - } - - /** - * Create a MimeBodyPart backed by file based on the headers and - * content data in content. - * - * @param content an inputstream containing the body part. - * @param file a handle to the backing file to use for storage. - * @throws MessagingException an exception occurs parsing the resulting body part in file. - * @throws IOException an exception occurs accessing file or content. - */ - public FileBackedMimeBodyPart( - InputStream content, - File file) - throws MessagingException, IOException - { - this(saveStreamToFile(content, file)); - } - - /** - * Create a MimeBodyPart backed by file, with the headers - * given in headers and body content taken from the stream body. - * - * @param headers headers for the body part. - * @param body internal content for the body part. - * @param file backing file to use. - * - * @throws MessagingException if the body part can't be produced. - * @throws IOException if there is an issue reading stream or writing to file. - */ - public FileBackedMimeBodyPart( - InternetHeaders headers, - InputStream body, - File file) - throws MessagingException, IOException - { - this(saveStreamToFile(headers, body, file)); - } - - public void writeTo( - OutputStream out) - throws IOException, MessagingException - { - if (!_file.exists()) - { - throw new IOException("file " + _file.getCanonicalPath() + " no longer exists."); - } - - super.writeTo(out); - } - - /** - * Close off the underlying shared streams and remove the backing file. - * - * @throws IOException if streams cannot be closed or the file cannot be deleted. - */ - public void dispose() - throws IOException - { - ((SharedFileInputStream)contentStream).getRoot().dispose(); - - if (_file.exists() && !_file.delete()) - { - throw new IOException("deletion of underlying file <" + _file.getCanonicalPath() + "> failed."); - } - } - - private static File saveStreamToFile(InputStream content, File tempFile) - throws IOException - { - saveContentToStream(new FileOutputStream(tempFile), content); - - return tempFile; - } - - private static File saveStreamToFile(InternetHeaders headers, InputStream content, File tempFile) - throws IOException - { - OutputStream out = new FileOutputStream(tempFile); - Enumeration en = headers.getAllHeaderLines(); - - while (en.hasMoreElements()) - { - writeHeader(out, (String)en.nextElement()); - } - - writeSeperator(out); - - saveContentToStream(out, content); - - return tempFile; - } - - - private static void writeHeader(OutputStream out, String header) - throws IOException - { - for (int i = 0; i != header.length(); i++) - { - out.write(header.charAt(i)); - } - - writeSeperator(out); - } - - private static void writeSeperator(OutputStream out) - throws IOException - { - out.write('\r'); - out.write('\n'); - } - - private static void saveContentToStream( - OutputStream out, - InputStream content) - throws IOException - { - byte[] buf = new byte[BUF_SIZE]; - int len; - - while ((len = content.read(buf, 0, buf.length)) > 0) - { - out.write(buf, 0, len); - } - - out.close(); - content.close(); - } - } diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java deleted file mode 100644 index 97cfd9c03..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java +++ /dev/null @@ -1,241 +0,0 @@ -package org.bouncycastle.mail.smime.util; - -import javax.mail.internet.SharedInputStream; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -public class SharedFileInputStream - extends FilterInputStream - implements SharedInputStream -{ - private final SharedFileInputStream _parent; - private final File _file; - private final long _start; - private final long _length; - - private long _position; - private long _markedPosition; - - private List _subStreams = new LinkedList(); - - public SharedFileInputStream( - String fileName) - throws IOException - { - this(new File(fileName)); - } - - public SharedFileInputStream( - File file) - throws IOException - { - this(file, 0, file.length()); - } - - private SharedFileInputStream( - File file, - long start, - long length) - throws IOException - { - super(new BufferedInputStream(new FileInputStream(file))); - - _parent = null; - _file = file; - _start = start; - _length = length; - - in.skip(start); - } - - private SharedFileInputStream( - SharedFileInputStream parent, - long start, - long length) - throws IOException - { - super(new BufferedInputStream(new FileInputStream(parent._file))); - - _parent = parent; - _file = parent._file; - _start = start; - _length = length; - - in.skip(start); - } - - public long getPosition() - { - return _position; - } - - public InputStream newStream(long start, long finish) - { - try - { - SharedFileInputStream stream; - - if (finish < 0) - { - if (_length > 0) - { - stream = new SharedFileInputStream(this, _start + start, _length - start); - } - else if (_length == 0) - { - stream = new SharedFileInputStream(this, _start + start, 0); - } - else - { - stream = new SharedFileInputStream(this, _start + start, -1); - } - } - else - { - stream = new SharedFileInputStream(this, _start + start, finish - start); - } - - _subStreams.add(stream); - - return stream; - } - catch (IOException e) - { - throw new IllegalStateException("unable to create shared stream: " + e); - } - } - - public int read( - byte[] buf) - throws IOException - { - return this.read(buf, 0, buf.length); - } - - public int read( - byte[] buf, - int off, - int len) - throws IOException - { - int count = 0; - - if (len == 0) - { - return 0; - } - - while (count < len) - { - int ch = this.read(); - - if (ch < 0) - { - break; - } - - buf[off + count] = (byte)ch; - count++; - } - - if (count == 0) - { - return -1; // EOF - } - - return count; - } - - public int read() - throws IOException - { - if (_position == _length) - { - return -1; - } - - _position++; - return in.read(); - } - - public boolean markSupported() - { - return true; - } - - public long skip(long n) - throws IOException - { - long count; - - for (count = 0; count != n; count++) - { - if (this.read() < 0) - { - break; - } - } - - return count; - } - - public void mark( - int readLimit) - { - _markedPosition = _position; - in.mark(readLimit); - } - - public void reset() - throws IOException - { - _position = _markedPosition; - in.reset(); - } - - /** - * Return the shared stream that represents the top most stream that - * this stream inherits from. - * @return the base of the shared stream tree. - */ - public SharedFileInputStream getRoot() - { - if (_parent != null) - { - return _parent.getRoot(); - } - - return this; - } - - /** - * Close of this stream and any substreams that have been created from it. - * @throws IOException on problem closing the main stream. - */ - public void dispose() - throws IOException - { - Iterator it = _subStreams.iterator(); - - while (it.hasNext()) - { - try - { - ((SharedFileInputStream)it.next()).dispose(); - } - catch (IOException e) - { - // ignore - } - } - - in.close(); - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/validator/SignedMailValidator.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/validator/SignedMailValidator.java deleted file mode 100644 index 21132852c..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/validator/SignedMailValidator.java +++ /dev/null @@ -1,960 +0,0 @@ -package org.bouncycastle.mail.smime.validator; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.PublicKey; -import java.security.cert.CertPath; -import java.security.cert.CertStore; -import java.security.cert.CertStoreException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateFactory; -import java.security.cert.CertificateNotYetValidException; -import java.security.cert.PKIXParameters; -import java.security.cert.TrustAnchor; -import java.security.cert.X509CertSelector; -import java.security.cert.X509Certificate; -import java.security.interfaces.DSAPublicKey; -import java.security.interfaces.RSAPublicKey; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Vector; - -import javax.mail.Address; -import javax.mail.MessagingException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1Sequence; -import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.cms.Attribute; -import org.bouncycastle.asn1.cms.AttributeTable; -import org.bouncycastle.asn1.cms.CMSAttributes; -import org.bouncycastle.asn1.cms.Time; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; -import org.bouncycastle.asn1.x509.ExtendedKeyUsage; -import org.bouncycastle.asn1.x509.KeyPurposeId; -import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; -import org.bouncycastle.cms.SignerInformation; -import org.bouncycastle.cms.SignerInformationStore; -import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; -import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; -import org.bouncycastle.i18n.ErrorBundle; -import org.bouncycastle.i18n.filter.TrustedInput; -import org.bouncycastle.i18n.filter.UntrustedInput; -import org.bouncycastle.jce.PrincipalUtil; -import org.bouncycastle.jce.X509Principal; -import org.bouncycastle.mail.smime.SMIMESigned; -import org.bouncycastle.util.Integers; -import org.bouncycastle.x509.CertPathReviewerException; -import org.bouncycastle.x509.PKIXCertPathReviewer; - -public class SignedMailValidator -{ - private static final String RESOURCE_NAME = "org.bouncycastle.mail.smime.validator.SignedMailValidatorMessages"; - - private static final Class DEFAULT_CERT_PATH_REVIEWER = PKIXCertPathReviewer.class; - - private static final String EXT_KEY_USAGE = X509Extensions.ExtendedKeyUsage - .getId(); - - private static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName - .getId(); - - private static final int shortKeyLength = 512; - - // (365.25*30)*24*3600*1000 - private static final long THIRTY_YEARS_IN_MILLI_SEC = 21915l*12l*3600l*1000l; - - private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); - - private CertStore certs; - - private SignerInformationStore signers; - - private Map results; - - private String[] fromAddresses; - - private Class certPathReviewerClass; - - /** - * Validates the signed {@link MimeMessage} message. The - * {@link PKIXParameters} from param are used for the certificate path - * validation. The actual PKIXParameters used for the certificate path - * validation is a copy of param with the followin changes: <br> - The - * validation date is changed to the signature time <br> - A CertStore with - * certificates and crls from the mail message is added to the CertStores.<br> - * <br> - * In <code>param</code> it's also possible to add additional CertStores - * with intermediate Certificates and/or CRLs which then are also used for - * the validation. - * - * @param message - * the signed MimeMessage - * @param param - * the parameters for the certificate path validation - * @throws SignedMailValidatorException - * if the message is no signed message or if an exception occurs - * reading the message - */ - public SignedMailValidator(MimeMessage message, PKIXParameters param) - throws SignedMailValidatorException - { - this(message, param, DEFAULT_CERT_PATH_REVIEWER); - } - - /** - * Validates the signed {@link MimeMessage} message. The - * {@link PKIXParameters} from param are used for the certificate path - * validation. The actual PKIXParameters used for the certificate path - * validation is a copy of param with the followin changes: <br> - The - * validation date is changed to the signature time <br> - A CertStore with - * certificates and crls from the mail message is added to the CertStores.<br> - * <br> - * In <code>param</code> it's also possible to add additional CertStores - * with intermediate Certificates and/or CRLs which then are also used for - * the validation. - * - * @param message - * the signed MimeMessage - * @param param - * the parameters for the certificate path validation - * @param certPathReviewerClass - * a subclass of {@link PKIXCertPathReviewer}. The SignedMailValidator - * uses objects of this type for the cert path vailidation. The class must - * have an empty constructor. - * @throws SignedMailValidatorException - * if the message is no signed message or if an exception occurs - * reading the message - * @throws IllegalArgumentException if the certPathReviewerClass is not a - * subclass of {@link PKIXCertPathReviewer} or objects of - * certPathReviewerClass can not be instantiated - */ - public SignedMailValidator(MimeMessage message, PKIXParameters param, Class certPathReviewerClass) - throws SignedMailValidatorException - { - this.certPathReviewerClass = certPathReviewerClass; - boolean isSubclass = DEFAULT_CERT_PATH_REVIEWER.isAssignableFrom(certPathReviewerClass); - if(!isSubclass) - { - throw new IllegalArgumentException("certPathReviewerClass is not a subclass of " + DEFAULT_CERT_PATH_REVIEWER.getName()); - } - - SMIMESigned s; - - try - { - // check if message is multipart signed - if (message.isMimeType("multipart/signed")) - { - MimeMultipart mimemp = (MimeMultipart) message.getContent(); - s = new SMIMESigned(mimemp); - } - else if (message.isMimeType("application/pkcs7-mime") - || message.isMimeType("application/x-pkcs7-mime")) - { - s = new SMIMESigned(message); - } - else - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.noSignedMessage"); - throw new SignedMailValidatorException(msg); - } - - // save certstore and signerInformationStore - certs = new JcaCertStoreBuilder().addCertificates(s.getCertificates()).addCRLs(s.getCRLs()).setProvider("BC").build(); - signers = s.getSignerInfos(); - - // save "from" addresses from message - Address[] froms = message.getFrom(); - InternetAddress sender = null; - try - { - if(message.getHeader("Sender") != null) - { - sender = new InternetAddress(message.getHeader("Sender")[0]); - } - } - catch (MessagingException ex) - { - //ignore garbage in Sender: header - } - fromAddresses = new String[froms.length + (sender!=null?1:0)]; - for (int i = 0; i < froms.length; i++) - { - InternetAddress inetAddr = (InternetAddress) froms[i]; - fromAddresses[i] = inetAddr.getAddress(); - } - if(sender!=null) - { - fromAddresses[froms.length] = sender.getAddress(); - } - - // initialize results - results = new HashMap(); - } - catch (Exception e) - { - if (e instanceof SignedMailValidatorException) - { - throw (SignedMailValidatorException) e; - } - // exception reading message - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.exceptionReadingMessage", - new Object[] { e.getMessage(), e , e.getClass().getName()}); - throw new SignedMailValidatorException(msg, e); - } - - // validate signatues - validateSignatures(param); - } - - protected void validateSignatures(PKIXParameters pkixParam) - { - PKIXParameters usedParameters = (PKIXParameters) pkixParam.clone(); - - // add crls and certs from mail - usedParameters.addCertStore(certs); - - Collection c = signers.getSigners(); - Iterator it = c.iterator(); - - // check each signer - while (it.hasNext()) - { - List errors = new ArrayList(); - List notifications = new ArrayList(); - - SignerInformation signer = (SignerInformation) it.next(); - // signer certificate - X509Certificate cert = null; - - try - { - Collection certCollection = findCerts(usedParameters - .getCertStores(), selectorConverter.getCertSelector(signer.getSID())); - - Iterator certIt = certCollection.iterator(); - if (certIt.hasNext()) - { - cert = (X509Certificate) certIt.next(); - } - } - catch (CertStoreException cse) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.exceptionRetrievingSignerCert", - new Object[] { cse.getMessage(), cse , cse.getClass().getName()}); - errors.add(msg); - } - - if (cert != null) - { - // check signature - boolean validSignature = false; - try - { - validSignature = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert.getPublicKey())); - if (!validSignature) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.signatureNotVerified"); - errors.add(msg); - } - } - catch (Exception e) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.exceptionVerifyingSignature", - new Object[] { e.getMessage(), e, e.getClass().getName() }); - errors.add(msg); - } - - // check signer certificate (mail address, key usage, etc) - checkSignerCert(cert, errors, notifications); - - // notify if a signed receip request is in the message - AttributeTable atab = signer.getSignedAttributes(); - if (atab != null) - { - Attribute attr = atab.get(PKCSObjectIdentifiers.id_aa_receiptRequest); - if (attr != null) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.signedReceiptRequest"); - notifications.add(msg); - } - } - - // check certificate path - - // get signing time if possible, otherwise use current time as - // signing time - Date signTime = getSignatureTime(signer); - if (signTime == null) // no signing time was found - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.noSigningTime"); - errors.add(msg); - signTime = new Date(); - } - else - { - // check if certificate was valid at signing time - try - { - cert.checkValidity(signTime); - } - catch (CertificateExpiredException e) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.certExpired", - new Object[] { new TrustedInput(signTime), new TrustedInput(cert.getNotAfter()) }); - errors.add(msg); - } - catch (CertificateNotYetValidException e) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.certNotYetValid", - new Object[] { new TrustedInput(signTime), new TrustedInput(cert.getNotBefore()) }); - errors.add(msg); - } - } - usedParameters.setDate(signTime); - - try - { - // construct cert chain - CertPath certPath; - List userProvidedList; - - List userCertStores = new ArrayList(); - userCertStores.add(certs); - Object[] cpres = createCertPath(cert, usedParameters.getTrustAnchors(), pkixParam.getCertStores(), userCertStores); - certPath = (CertPath) cpres[0]; - userProvidedList = (List) cpres[1]; - - // validate cert chain - PKIXCertPathReviewer review; - try - { - review = (PKIXCertPathReviewer)certPathReviewerClass.newInstance(); - } - catch (IllegalAccessException e) - { - throw new IllegalArgumentException("Cannot instantiate object of type " + - certPathReviewerClass.getName() + ": " + e.getMessage()); - } - catch (InstantiationException e) - { - throw new IllegalArgumentException("Cannot instantiate object of type " + - certPathReviewerClass.getName() + ": " + e.getMessage()); - } - review.init(certPath, usedParameters); - if (!review.isValidCertPath()) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.certPathInvalid"); - errors.add(msg); - } - results.put(signer, new ValidationResult(review, - validSignature, errors, notifications, userProvidedList)); - } - catch (GeneralSecurityException gse) - { - // cannot create cert path - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.exceptionCreateCertPath", - new Object[] { gse.getMessage(), gse, gse.getClass().getName() }); - errors.add(msg); - results.put(signer, new ValidationResult(null, - validSignature, errors, notifications, null)); - } - catch (CertPathReviewerException cpre) - { - // cannot initialize certpathreviewer - wrong parameters - errors.add(cpre.getErrorMessage()); - results.put(signer, new ValidationResult(null, - validSignature, errors, notifications, null)); - } - } - else - // no signer certificate found - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.noSignerCert"); - errors.add(msg); - results.put(signer, new ValidationResult(null, false, errors, - notifications, null)); - } - } - } - - public static Set getEmailAddresses(X509Certificate cert) throws IOException, CertificateEncodingException - { - Set addresses = new HashSet(); - - X509Principal name = PrincipalUtil.getSubjectX509Principal(cert); - Vector oids = name.getOIDs(); - Vector names = name.getValues(); - for (int i = 0; i < oids.size(); i++) - { - if (oids.get(i).equals(X509Principal.EmailAddress)) - { - String email = ((String) names.get(i)).toLowerCase(); - addresses.add(email); - break; - } - } - - byte[] ext = cert.getExtensionValue(SUBJECT_ALTERNATIVE_NAME); - if (ext != null) - { - ASN1Sequence altNames = ASN1Sequence.getInstance(getObject(ext)); - for (int j = 0; j < altNames.size(); j++) - { - ASN1TaggedObject o = (ASN1TaggedObject) altNames - .getObjectAt(j); - - if (o.getTagNo() == 1) - { - String email = DERIA5String.getInstance(o, false) - .getString().toLowerCase(); - addresses.add(email); - } - } - } - - return addresses; - } - - private static ASN1Primitive getObject(byte[] ext) throws IOException - { - ASN1InputStream aIn = new ASN1InputStream(ext); - ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); - - aIn = new ASN1InputStream(octs.getOctets()); - return aIn.readObject(); - } - - protected void checkSignerCert(X509Certificate cert, List errors, - List notifications) - { - // get key length - PublicKey key = cert.getPublicKey(); - int keyLenght = -1; - if (key instanceof RSAPublicKey) - { - keyLenght = ((RSAPublicKey) key).getModulus().bitLength(); - } - else if (key instanceof DSAPublicKey) - { - keyLenght = ((DSAPublicKey) key).getParams().getP().bitLength(); - } - if (keyLenght != -1 && keyLenght <= shortKeyLength) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.shortSigningKey", - new Object[]{Integers.valueOf(keyLenght)}); - notifications.add(msg); - } - - // warn if certificate has very long validity period - long validityPeriod = cert.getNotAfter().getTime() - cert.getNotBefore().getTime(); - if (validityPeriod > THIRTY_YEARS_IN_MILLI_SEC) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.longValidity", - new Object[] {new TrustedInput(cert.getNotBefore()), new TrustedInput(cert.getNotAfter())}); - notifications.add(msg); - } - - // check key usage if digitalSignature or nonRepudiation is set - boolean[] keyUsage = cert.getKeyUsage(); - if (keyUsage != null && !keyUsage[0] && !keyUsage[1]) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.signingNotPermitted"); - errors.add(msg); - } - - // check extended key usage - try - { - byte[] ext = cert.getExtensionValue(EXT_KEY_USAGE); - if (ext != null) - { - ExtendedKeyUsage extKeyUsage = ExtendedKeyUsage - .getInstance(getObject(ext)); - if (!extKeyUsage - .hasKeyPurposeId(KeyPurposeId.anyExtendedKeyUsage) - && !extKeyUsage - .hasKeyPurposeId(KeyPurposeId.id_kp_emailProtection)) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.extKeyUsageNotPermitted"); - errors.add(msg); - } - } - } - catch (Exception e) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.extKeyUsageError", new Object[] { - e.getMessage(), e, e.getClass().getName() }); - errors.add(msg); - } - - // cert has an email address - try - { - Set certEmails = getEmailAddresses(cert); - if (certEmails.isEmpty()) - { - // error no email address in signing certificate - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.noEmailInCert"); - errors.add(msg); - } - else - { - // check if email in cert is equal to the from address in the - // message - boolean equalsFrom = false; - for (int i = 0; i < fromAddresses.length; i++) - { - if (certEmails.contains(fromAddresses[i].toLowerCase())) - { - equalsFrom = true; - break; - } - } - if (!equalsFrom) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.emailFromCertMismatch", - new Object[] { - new UntrustedInput( - addressesToString(fromAddresses)), - new UntrustedInput(certEmails) }); - errors.add(msg); - } - } - } - catch (Exception e) - { - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.certGetEmailError", new Object[] { - e.getMessage(), e, e.getClass().getName() }); - errors.add(msg); - } - } - - static String addressesToString(Object[] a) - { - if (a == null) - { - return "null"; - } - - StringBuffer b = new StringBuffer(); - b.append('['); - - for (int i = 0; i != a.length; i++) - { - if (i > 0) - { - b.append(", "); - } - b.append(String.valueOf(a[i])); - } - - return b.append(']').toString(); - } - - public static Date getSignatureTime(SignerInformation signer) - { - AttributeTable atab = signer.getSignedAttributes(); - Date result = null; - if (atab != null) - { - Attribute attr = atab.get(CMSAttributes.signingTime); - if (attr != null) - { - Time t = Time.getInstance(attr.getAttrValues().getObjectAt(0) - .toASN1Primitive()); - result = t.getDate(); - } - } - return result; - } - - private static List findCerts(List certStores, X509CertSelector selector) - throws CertStoreException - { - List result = new ArrayList(); - Iterator it = certStores.iterator(); - while (it.hasNext()) - { - CertStore store = (CertStore) it.next(); - Collection coll = store.getCertificates(selector); - result.addAll(coll); - } - return result; - } - - private static X509Certificate findNextCert(List certStores, X509CertSelector selector, Set certSet) - throws CertStoreException - { - Iterator certIt = findCerts(certStores, selector).iterator(); - - boolean certFound = false; - X509Certificate nextCert = null; - while (certIt.hasNext()) - { - nextCert = (X509Certificate) certIt.next(); - if (!certSet.contains(nextCert)) - { - certFound = true; - break; - } - } - - return certFound ? nextCert : null; - } - - /** - * - * @param signerCert the end of the path - * @param trustanchors trust anchors for the path - * @param certStores - * @return the resulting certificate path. - * @throws GeneralSecurityException - */ - public static CertPath createCertPath(X509Certificate signerCert, - Set trustanchors, List certStores) throws GeneralSecurityException - { - Object[] results = createCertPath(signerCert, trustanchors, certStores, null); - return (CertPath) results[0]; - } - - /** - * Returns an Object array containing a CertPath and a List of Booleans. The list contains the value <code>true</code> - * if the corresponding certificate in the CertPath was taken from the user provided CertStores. - * @param signerCert the end of the path - * @param trustanchors trust anchors for the path - * @param systemCertStores list of {@link CertStore} provided by the system - * @param userCertStores list of {@link CertStore} provided by the user - * @return a CertPath and a List of booleans. - * @throws GeneralSecurityException - */ - public static Object[] createCertPath(X509Certificate signerCert, - Set trustanchors, List systemCertStores, List userCertStores) throws GeneralSecurityException - { - Set certSet = new LinkedHashSet(); - List userProvidedList = new ArrayList(); - - // add signer certificate - - X509Certificate cert = signerCert; - certSet.add(cert); - userProvidedList.add(new Boolean(true)); - - boolean trustAnchorFound = false; - - X509Certificate taCert = null; - - // add other certs to the cert path - while (cert != null && !trustAnchorFound) - { - // check if cert Issuer is Trustanchor - Iterator trustIt = trustanchors.iterator(); - while (trustIt.hasNext()) - { - TrustAnchor anchor = (TrustAnchor) trustIt.next(); - X509Certificate anchorCert = anchor.getTrustedCert(); - if (anchorCert != null) - { - if (anchorCert.getSubjectX500Principal().equals( - cert.getIssuerX500Principal())) - { - try - { - cert.verify(anchorCert.getPublicKey(), "BC"); - trustAnchorFound = true; - taCert = anchorCert; - break; - } - catch (Exception e) - { - // trustanchor not found - } - } - } - else - { - if (anchor.getCAName().equals( - cert.getIssuerX500Principal().getName())) - { - try - { - cert.verify(anchor.getCAPublicKey(), "BC"); - trustAnchorFound = true; - break; - } - catch (Exception e) - { - // trustanchor not found - } - } - } - } - - if (!trustAnchorFound) - { - // add next cert to path - X509CertSelector select = new X509CertSelector(); - try - { - select.setSubject(cert.getIssuerX500Principal().getEncoded()); - } - catch (IOException e) - { - throw new IllegalStateException(e.toString()); - } - byte[] authKeyIdentBytes = cert.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId()); - if (authKeyIdentBytes != null) - { - try - { - AuthorityKeyIdentifier kid = AuthorityKeyIdentifier.getInstance(getObject(authKeyIdentBytes)); - if (kid.getKeyIdentifier() != null) - { - select.setSubjectKeyIdentifier(new DEROctetString(kid.getKeyIdentifier()).getEncoded(ASN1Encoding.DER)); - } - } - catch (IOException ioe) - { - // ignore - } - } - boolean userProvided = false; - - cert = findNextCert(systemCertStores, select, certSet); - if (cert == null && userCertStores != null) - { - userProvided = true; - cert = findNextCert(userCertStores, select, certSet); - } - - if (cert != null) - { - // cert found - certSet.add(cert); - userProvidedList.add(new Boolean(userProvided)); - } - } - } - - // if a trustanchor was found - try to find a selfsigned certificate of - // the trustanchor - if (trustAnchorFound) - { - if (taCert != null && taCert.getSubjectX500Principal().equals(taCert.getIssuerX500Principal())) - { - certSet.add(taCert); - userProvidedList.add(new Boolean(false)); - } - else - { - X509CertSelector select = new X509CertSelector(); - - try - { - select.setSubject(cert.getIssuerX500Principal().getEncoded()); - select.setIssuer(cert.getIssuerX500Principal().getEncoded()); - } - catch (IOException e) - { - throw new IllegalStateException(e.toString()); - } - - boolean userProvided = false; - - taCert = findNextCert(systemCertStores, select, certSet); - if (taCert == null && userCertStores != null) - { - userProvided = true; - taCert = findNextCert(userCertStores, select, certSet); - } - if (taCert != null) - { - try - { - cert.verify(taCert.getPublicKey(), "BC"); - certSet.add(taCert); - userProvidedList.add(new Boolean(userProvided)); - } - catch (GeneralSecurityException gse) - { - // wrong cert - } - } - } - } - - CertPath certPath = CertificateFactory.getInstance("X.509", "BC").generateCertPath(new ArrayList(certSet)); - return new Object[] {certPath, userProvidedList}; - } - - public CertStore getCertsAndCRLs() - { - return certs; - } - - public SignerInformationStore getSignerInformationStore() - { - return signers; - } - - public ValidationResult getValidationResult(SignerInformation signer) - throws SignedMailValidatorException - { - if (signers.getSigners(signer.getSID()).isEmpty()) - { - // the signer is not part of the SignerInformationStore - // he has not signed the message - ErrorBundle msg = new ErrorBundle(RESOURCE_NAME, - "SignedMailValidator.wrongSigner"); - throw new SignedMailValidatorException(msg); - } - else - { - return (ValidationResult) results.get(signer); - } - } - - public class ValidationResult - { - - private PKIXCertPathReviewer review; - - private List errors; - - private List notifications; - - private List userProvidedCerts; - - private boolean signVerified; - - ValidationResult(PKIXCertPathReviewer review, boolean verified, - List errors, List notifications, List userProvidedCerts) - { - this.review = review; - this.errors = errors; - this.notifications = notifications; - signVerified = verified; - this.userProvidedCerts = userProvidedCerts; - } - - /** - * Returns a list of error messages of type {@link ErrorBundle}. - * - * @return List of error messages - */ - public List getErrors() - { - return errors; - } - - /** - * Returns a list of notification messages of type {@link ErrorBundle}. - * - * @return List of notification messages - */ - public List getNotifications() - { - return notifications; - } - - /** - * - * @return the PKIXCertPathReviewer for the CertPath of this signature - * or null if an Exception occured. - */ - public PKIXCertPathReviewer getCertPathReview() - { - return review; - } - - /** - * - * @return the CertPath for this signature - * or null if an Exception occured. - */ - public CertPath getCertPath() - { - return review != null ? review.getCertPath() : null; - } - - /** - * - * @return a List of Booleans that are true if the corresponding certificate in the CertPath was taken from - * the CertStore of the SMIME message - */ - public List getUserProvidedCerts() - { - return userProvidedCerts; - } - - /** - * - * @return true if the signature corresponds to the public key of the - * signer - */ - public boolean isVerifiedSignature() - { - return signVerified; - } - - /** - * - * @return true if the signature is valid (ie. if it corresponds to the - * public key of the signer and the cert path for the signers - * certificate is also valid) - */ - public boolean isValidSignature() - { - if (review != null) - { - return signVerified && review.isValidCertPath() - && errors.isEmpty(); - } - else - { - return false; - } - } - - } -} diff --git a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/validator/SignedMailValidatorException.java b/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/validator/SignedMailValidatorException.java deleted file mode 100644 index 06f146182..000000000 --- a/libraries/spongycastle/mail/src/main/java/org/spongycastle/mail/smime/validator/SignedMailValidatorException.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.bouncycastle.mail.smime.validator; - -import org.bouncycastle.i18n.ErrorBundle; -import org.bouncycastle.i18n.LocalizedException; - -public class SignedMailValidatorException extends LocalizedException -{ - - public SignedMailValidatorException(ErrorBundle errorMessage, Throwable throwable) - { - super(errorMessage, throwable); - } - - public SignedMailValidatorException(ErrorBundle errorMessage) - { - super(errorMessage); - } - -} |