From a1245cf4ae39e4a1a47b5f606bdbd2ce3e1b5814 Mon Sep 17 00:00:00 2001
From: Jan Dittberner <jan@dittberner.info>
Date: Sun, 12 Oct 2014 14:23:08 +0200
Subject: [PATCH] rename packages

---
 pom.xml                                       |  15 +-
 .../bcsmime_demo/SMIMEDecrypt.java            |  24 ++-
 .../bcsmime_demo/SMIMEEncrypt.java            |  65 ++++----
 .../sectest/ListAlgorithmNames.java           |  27 ++++
 .../bcsmime_demo/EncryptDecryptTest.java      | 149 ++++++++++--------
 5 files changed, 158 insertions(+), 122 deletions(-)
 rename src/main/java/{de/communardo/jdi => info/dittberner}/bcsmime_demo/SMIMEDecrypt.java (95%)
 rename src/main/java/{de/communardo/jdi => info/dittberner}/bcsmime_demo/SMIMEEncrypt.java (79%)
 create mode 100644 src/main/java/info/dittberner/jcajceprovidertest/sectest/ListAlgorithmNames.java
 rename src/test/java/{de/communardo/jdi => info/dittberner}/bcsmime_demo/EncryptDecryptTest.java (65%)

diff --git a/pom.xml b/pom.xml
index 79d263d..8d52dd0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,11 +44,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         </dependency>
         <dependency>
             <groupId>org.bouncycastle</groupId>
-            <artifactId>bcmail-jdk16</artifactId>
-            <version>1.46</version>
+            <artifactId>bcmail-jdk15on</artifactId>
+            <version>1.50</version>
         </dependency>
         <dependency>
-            <groupId>javax.mail</groupId>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <version>1.50</version>
+        </dependency>
+        <dependency>
+        <groupId>javax.mail</groupId>
             <artifactId>mail</artifactId>
             <version>1.4.4</version>
             <scope>compile</scope>
@@ -62,8 +67,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>2.3.2</version>
                 <configuration>
-                    <source>1.6</source>
-                    <target>1.6</target>
+                    <source>1.7</source>
+                    <target>1.7</target>
                     <showDeprecation>false</showDeprecation>
 
                     <!--<encoding>UTF-8</encoding>-->
diff --git a/src/main/java/de/communardo/jdi/bcsmime_demo/SMIMEDecrypt.java b/src/main/java/info/dittberner/bcsmime_demo/SMIMEDecrypt.java
similarity index 95%
rename from src/main/java/de/communardo/jdi/bcsmime_demo/SMIMEDecrypt.java
rename to src/main/java/info/dittberner/bcsmime_demo/SMIMEDecrypt.java
index e5e2023..d6abb0c 100644
--- a/src/main/java/de/communardo/jdi/bcsmime_demo/SMIMEDecrypt.java
+++ b/src/main/java/info/dittberner/bcsmime_demo/SMIMEDecrypt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Jan Dittberner
+ * Copyright (c) 2011-2014 Jan Dittberner
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -20,17 +20,7 @@
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-package de.communardo.jdi.bcsmime_demo;
-
-import java.io.ByteArrayInputStream;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Enumeration;
-
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.MimeMessage;
+package info.dittberner.bcsmime_demo;
 
 import org.bouncycastle.cms.RecipientInformation;
 import org.bouncycastle.cms.RecipientInformationStore;
@@ -38,6 +28,14 @@ import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
 import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId;
 import org.bouncycastle.mail.smime.SMIMEEnveloped;
 
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+import java.io.ByteArrayInputStream;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+
 /**
  * S/MIME encryption using the new BouncyCastle 1.46 APIs.
  * 
@@ -66,7 +64,7 @@ public class SMIMEDecrypt {
      *             if an error occurs
      */
     public MimeMessage decryptMessage(MimeMessage encrypted)
-            throws MessagingException, Exception {
+            throws Exception {
         SMIMEEnveloped message = new SMIMEEnveloped(encrypted);
 
         RecipientInformationStore recinfos = message.getRecipientInfos();
diff --git a/src/main/java/de/communardo/jdi/bcsmime_demo/SMIMEEncrypt.java b/src/main/java/info/dittberner/bcsmime_demo/SMIMEEncrypt.java
similarity index 79%
rename from src/main/java/de/communardo/jdi/bcsmime_demo/SMIMEEncrypt.java
rename to src/main/java/info/dittberner/bcsmime_demo/SMIMEEncrypt.java
index c3f65a1..59b84ed 100644
--- a/src/main/java/de/communardo/jdi/bcsmime_demo/SMIMEEncrypt.java
+++ b/src/main/java/info/dittberner/bcsmime_demo/SMIMEEncrypt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Jan Dittberner
+ * Copyright (c) 2011-2014 Jan Dittberner
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -20,32 +20,28 @@
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-package de.communardo.jdi.bcsmime_demo;
+package info.dittberner.bcsmime_demo;
 
-import java.security.KeyStore;
-import java.security.cert.CertStore;
-import java.security.cert.CertStoreParameters;
-import java.security.cert.Certificate;
-import java.security.cert.CollectionCertStoreParameters;
-import java.security.cert.X509CertSelector;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.List;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.cms.CMSAlgorithm;
+import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
+import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
+import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
+import org.bouncycastle.operator.OutputEncryptor;
 
 import javax.mail.Address;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
-
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.cms.CMSAlgorithm;
-import org.bouncycastle.cms.RecipientInfoGenerator;
-import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
-import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
-import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
-import org.bouncycastle.operator.OutputEncryptor;
+import java.security.KeyStore;
+import java.security.cert.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
 
 /**
  * S/MIME encryption using the new BouncyCastle 1.46 APIs.
@@ -57,12 +53,11 @@ public class SMIMEEncrypt {
 
     /**
      * Creates a new SMIMEEncrypt instance.
-     * 
-     * @param keystore
-     *            key store to use for recipient certificates
+     *
+     * @param keystore key store to use for recipient certificates
      */
     public SMIMEEncrypt(KeyStore keystore) {
-        List<Certificate> certificates = new ArrayList<Certificate>();
+        List<Certificate> certificates = new ArrayList<>();
 
         try {
             Enumeration<String> aliases = keystore.aliases();
@@ -85,19 +80,19 @@ public class SMIMEEncrypt {
     /**
      * Encrypts a MimeMessage to all its recipients.
      *
-     * @param message
-     *            MIME message to encrypt
+     * @param message MIME message to encrypt
      * @return encrypted S/MIME message
-     * @throws Exception
-     *             if an error occurs
+     * @throws Exception if an error occurs
      */
     public MimeMessage encryptMessage(MimeMessage message) throws Exception {
         SMIMEEnvelopedGenerator smeg = new SMIMEEnvelopedGenerator();
         for (Address recipient : message.getAllRecipients()) {
             Collection<? extends Certificate> certificates = getCertificates((InternetAddress) recipient);
             for (Certificate cert : certificates) {
-                RecipientInfoGenerator recipientInfoGen = new JceKeyTransRecipientInfoGenerator(
-                        (X509Certificate) cert);
+                RSAESOAEPparams params = new RSAESOAEPparams();
+                AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, params);
+                JceKeyTransRecipientInfoGenerator recipientInfoGen = new JceKeyTransRecipientInfoGenerator((X509Certificate) cert, algorithmIdentifier);
+                recipientInfoGen.setAlgorithmMapping(PKCSObjectIdentifiers.id_RSAES_OAEP, "RSA/OAEP");
                 smeg.addRecipientInfoGenerator(recipientInfoGen);
             }
         }
@@ -113,12 +108,10 @@ public class SMIMEEncrypt {
 
     /**
      * Helper method for getting certificates from a keystore.
-     * 
-     * @param recipient
-     *            recipient address
+     *
+     * @param recipient recipient address
      * @return X.509 certificate for recipient
-     * @throws Exception
-     *             if an error occurs
+     * @throws Exception if an error occurs
      */
     private Collection<? extends Certificate> getCertificates(
             InternetAddress recipient) throws Exception {
diff --git a/src/main/java/info/dittberner/jcajceprovidertest/sectest/ListAlgorithmNames.java b/src/main/java/info/dittberner/jcajceprovidertest/sectest/ListAlgorithmNames.java
new file mode 100644
index 0000000..06a96e4
--- /dev/null
+++ b/src/main/java/info/dittberner/jcajceprovidertest/sectest/ListAlgorithmNames.java
@@ -0,0 +1,27 @@
+package info.dittberner.jcajceprovidertest.sectest;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * Utility to list all available Security providers and their implemented algorithm names.
+ *
+ * @author Jan Dittberner &lt;<a href="mailto:jan@dittberner.info>jan@dittberner.info</a>&gt;
+ */
+public class ListAlgorithmNames {
+    public static void main(String[] args) {
+        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
+            Security.addProvider(new BouncyCastleProvider());
+        }
+
+        for (Provider provider : Security.getProviders()) {
+            System.out.println("Provider: " + provider.getName());
+            for (Provider.Service service : provider.getServices()) {
+                System.out.println("  Algorithm: " + service.getAlgorithm());
+            }
+        }
+
+    }
+}
diff --git a/src/test/java/de/communardo/jdi/bcsmime_demo/EncryptDecryptTest.java b/src/test/java/info/dittberner/bcsmime_demo/EncryptDecryptTest.java
similarity index 65%
rename from src/test/java/de/communardo/jdi/bcsmime_demo/EncryptDecryptTest.java
rename to src/test/java/info/dittberner/bcsmime_demo/EncryptDecryptTest.java
index 390c2a6..3712417 100644
--- a/src/test/java/de/communardo/jdi/bcsmime_demo/EncryptDecryptTest.java
+++ b/src/test/java/info/dittberner/bcsmime_demo/EncryptDecryptTest.java
@@ -20,8 +20,30 @@
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-package de.communardo.jdi.bcsmime_demo;
+package info.dittberner.bcsmime_demo;
 
+import junit.framework.TestCase;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.*;
+import org.bouncycastle.cert.CertIOException;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+
+import javax.mail.BodyPart;
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+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 java.io.IOException;
 import java.math.BigInteger;
 import java.security.KeyPair;
@@ -29,49 +51,63 @@ import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.Security;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
 import java.util.Date;
 
-import javax.mail.BodyPart;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Message.RecipientType;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-
-import junit.framework.TestCase;
-
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
-import org.bouncycastle.asn1.x509.GeneralName;
-import org.bouncycastle.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.KeyPurposeId;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.asn1.x509.X509Extension;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509v3CertificateBuilder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-
 /**
  * Test Encryption and Decryption.
- * 
+ *
  * @author Jan Dittberner &lt;<a href=
  *         "mailto:jan.dittberner@t-systems.com>jan.dittberner@t-systems.com</a>
  *         & g t ;
  */
 public class EncryptDecryptTest extends TestCase {
+    String[][] testEntries = new String[][]{
+            new String[]{"test1", "testrecpt1@example.org", "Test Recipient 1"},
+            new String[]{"test2", "testrecpt2@example.org", "Test Recipient 2"}
+    };
     private KeyStore keystore;
 
+    private class KeyEntryData {
+        private final X509CertificateHolder certificateHolder;
+        KeyPair keyPair;
+
+        private KeyEntryData(KeyPairGenerator kpg, String address) throws CertIOException, OperatorCreationException {
+            this.keyPair = kpg.generateKeyPair();
+
+            X500Name issuer = new X500Name(
+                    String.format("CN=Test Recipient,emailAddress=%s", address));
+            //noinspection UnnecessaryLocalVariable
+            X500Name subject = issuer;
+            X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
+                    issuer, BigInteger.valueOf(System.currentTimeMillis()),
+                    new Date(System.currentTimeMillis() - 50000), new Date(
+                    System.currentTimeMillis() + 50000), subject,
+                    keyPair.getPublic());
+            certificateBuilder.addExtension(Extension.basicConstraints, true,
+                    new BasicConstraints(true));
+            certificateBuilder.addExtension(Extension.keyUsage, true,
+                    new KeyUsage(KeyUsage.digitalSignature
+                            | KeyUsage.keyEncipherment));
+            certificateBuilder.addExtension(Extension.extendedKeyUsage, true,
+                    new ExtendedKeyUsage(KeyPurposeId.id_kp_emailProtection));
+            certificateBuilder.addExtension(Extension.subjectAlternativeName,
+                    false, new GeneralNames(new GeneralName(
+                            GeneralName.rfc822Name, address)));
+
+            ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA")
+                    .build(keyPair.getPrivate());
+            this.certificateHolder = certificateBuilder.build(signer);
+        }
+
+        private Certificate getCertificate() throws CertificateException, CertIOException, OperatorCreationException {
+            return (new JcaX509CertificateConverter()).getCertificate(certificateHolder);
+        }
+    }
+
     /**
      * {@inheritDoc}
-     * 
+     *
      * @see junit.framework.TestCase#setUp()
      */
     @Override
@@ -86,35 +122,12 @@ public class EncryptDecryptTest extends TestCase {
 
             KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
             kpg.initialize(2048);
-            KeyPair keypair = kpg.generateKeyPair();
 
-            X500Name issuer = new X500Name(
-                    "CN=Test Recipient,emailAddress=testrecpt@example.org");
-            X500Name subject = issuer;
-            X509v3CertificateBuilder certbuilder = new JcaX509v3CertificateBuilder(
-                    issuer, BigInteger.valueOf(System.currentTimeMillis()),
-                    new Date(System.currentTimeMillis() - 50000), new Date(
-                            System.currentTimeMillis() + 50000), subject,
-                    keypair.getPublic());
-            certbuilder.addExtension(X509Extension.basicConstraints, true,
-                    new BasicConstraints(true));
-            certbuilder.addExtension(X509Extension.keyUsage, true,
-                    new KeyUsage(KeyUsage.digitalSignature
-                            | KeyUsage.keyEncipherment));
-            certbuilder.addExtension(X509Extension.extendedKeyUsage, true,
-                    new ExtendedKeyUsage(KeyPurposeId.id_kp_emailProtection));
-            certbuilder.addExtension(X509Extension.subjectAlternativeName,
-                    false, new GeneralNames(new GeneralName(
-                            GeneralName.rfc822Name, "testrecpt@example.org")));
+            for (String[] entry : testEntries) {
+                KeyEntryData keyEntryData = new KeyEntryData(kpg, entry[1]);
+                keystore.setKeyEntry(entry[0], keyEntryData.keyPair.getPrivate(), "changeit".toCharArray(), new Certificate[]{keyEntryData.getCertificate()});
+            }
 
-            ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA")
-                    .build(keypair.getPrivate());
-            X509CertificateHolder certholder = certbuilder.build(signer);
-
-            keystore.setKeyEntry("test", keypair.getPrivate(), "changeit"
-                    .toCharArray(),
-                    new Certificate[] { (new JcaX509CertificateConverter())
-                            .getCertificate(certholder) });
         }
     }
 
@@ -137,11 +150,10 @@ public class EncryptDecryptTest extends TestCase {
     }
 
     /**
-     * Creates a new MimeMessage with one Bodypart.
-     * 
+     * Creates a new MimeMessage with one body part.
+     *
      * @return MimeMessage instance
-     * @throws MessagingException
-     *             on error creating the message
+     * @throws MessagingException on error creating the message
      */
     private MimeMessage getNewMultipartMessage() throws MessagingException,
             IOException {
@@ -149,14 +161,15 @@ public class EncryptDecryptTest extends TestCase {
                 .getProperties()));
         message.setFrom(new InternetAddress("testsender@example.org",
                 "Test Sender"));
-        message.addRecipient(RecipientType.TO, new InternetAddress(
-                "testrecpt@example.org", "Test Recipient"));
+        for (String[] entry : testEntries) {
+            message.addRecipient(RecipientType.TO, new InternetAddress(entry[1], entry[2]));
+        }
         message.setSubject("Test subject");
         Multipart multipart = new MimeMultipart();
-        BodyPart textpart = new MimeBodyPart();
-        textpart.setText("Das ist ein Text");
-        multipart.addBodyPart(textpart);
+        BodyPart textPart = new MimeBodyPart();
+        textPart.setText("Das ist ein Text");
+        multipart.addBodyPart(textPart);
         message.setContent(multipart);
         return message;
     }
-}
+}
\ No newline at end of file