From f05fbb28e23f731192191608507485c364a126ff Mon Sep 17 00:00:00 2001
From: david_page <david_page@localhost>
Date: Wed, 03 Oct 2007 15:47:57 +0000
Subject: [PATCH] Issue 466 (partial) more secret key stuff

---
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java |   66 +++++++++++++++++++++++++++------
 opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java                                 |   21 +++++++---
 2 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java b/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java
index 016e79b..1329671 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java
@@ -695,7 +695,7 @@
 
 
   /**
-   * Unwraps the supplied symmetric key attribute value and re-wraps
+   * Decodes the supplied symmetric key attribute value and re-encodes
    * it with the public key referred to by the requested instance key
    * identifier. The symmetric key attribute must be wrapped in this
    * instance's instance-key-pair public key.
@@ -703,10 +703,11 @@
    * unwrap and rewrap.
    * @param requestedInstanceKeyID The key identifier of the public
    * key to use in the re-wrapping.
-   * @return The symmetric key re-wrapped in the requested public key.
-   * @throws CryptoManagerException If there is a problem unwrapping
-   * the supplied symmetric key attribute value or retrieving the
-   * requested public key.
+   * @return The symmetric key attribute value with the symmetric key
+   * re-wrapped in the requested public key.
+   * @throws CryptoManagerException If there is a problem decoding
+   * the supplied symmetric key attribute value, unwrapping the
+   * embedded secret key, or retrieving the requested public key.
    */
   public String rewrapSymmetricKeyAttribute(
           final String symmetricKeyAttribute,
@@ -714,8 +715,16 @@
           throws CryptoManagerException {
     final SecretKey secretKey
             = decodeSymmetricKeyAttribute(symmetricKeyAttribute);
+    final Map<String, byte[]> certMap = getTrustedCertificates();
+    if (! certMap.containsKey(requestedInstanceKeyID)) {
+      throw new CryptoManagerException(
+              // TODO: i18n
+              Message.raw("The public key certificate specified by" +
+                      " the identifier %s cannot be found.",
+                      requestedInstanceKeyID));
+    }
     final byte[] wrappingKeyCert
-            = getTrustedCertificates().get(requestedInstanceKeyID);
+            = certMap.get(requestedInstanceKeyID);
     return encodeSymmetricKeyAttribute(
             requestedInstanceKeyID, wrappingKeyCert, secretKey);
   }
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java
index 3ef7a28..108ae12 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java
@@ -35,6 +35,7 @@
 
 import org.opends.server.core.DirectoryServer;
 import org.opends.admin.ads.util.ConnectionUtils;
+import org.opends.messages.Message;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -64,7 +65,7 @@
 {
   /**
    Setup..
-   @throws  Exception  If an unexpected problem occurs.
+   @throws Exception  If an unexpected problem occurs.
    */
   @BeforeClass()
   public void setUp()
@@ -173,7 +174,7 @@
     public int getIVLength() {
       return fIVLength;
     }
-  }
+    }
 
 
   /**
@@ -194,7 +195,6 @@
     paramList.add(new CipherParameters("DES", "CFB", "NoPadding", 56, 56));
     paramList.add(new CipherParameters("DESede", "ECB", "PKCS5Padding", 168, 56));
 
-
     Object[][] cipherParameters = new Object[paramList.size()][1];
     for (int i=0; i < paramList.size(); i++)
     {
@@ -213,7 +213,7 @@
 
    @throws Exception If an exceptional condition arises.
    */
-  @Test(dataProvider = "cipherParametersData")
+@Test(dataProvider="cipherParametersData")
   public void testEncryptDecryptSuccess(CipherParameters cp)
           throws Exception {
     final CryptoManager cm = DirectoryServer.getCryptoManager();
@@ -238,7 +238,7 @@
 
    @throws Exception If an exceptional condition arises.
    */
-  @Test(dataProvider = "cipherParametersData")
+  @Test(dataProvider="cipherParametersData")
   public void testStreamEncryptDecryptSuccess(CipherParameters cp)
           throws Exception {
     final CryptoManager cm = DirectoryServer.getCryptoManager();
@@ -269,6 +269,9 @@
   /**
    Tests to ensure the same key identifier (and hence, key) is used for
    successive encryptions specifying the same algorithm and key length.
+   <p>
+   The default encryption cipher requires an initialization vector. Confirm
+   successive uses of a key produces distinct ciphertext.
 
    @throws Exception  In case an error occurs in the encryption routine.
    */
@@ -277,22 +280,61 @@
           throws Exception {
 
     final CryptoManager cm = DirectoryServer.getCryptoManager();
-    final String secretMessage = "1234";
+    final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
 
+    final byte[] cipherText = cm.encrypt(secretMessage.getBytes());
+    final byte[] cipherText2 = cm.encrypt(secretMessage.getBytes());
+
+    // test cycle
+    final byte[] plainText = cm.decrypt(cipherText2);
+    assertEquals((new String(plainText)), secretMessage);
+
+    // test for identical keys
     try {
       Method m = Arrays.class.getMethod("copyOfRange", (new byte[16]).getClass(),
               Integer.TYPE, Integer.TYPE);
-      final byte[] cipherText = cm.encrypt(secretMessage.getBytes());
       final byte[] keyID = (byte[])m.invoke(null, cipherText, 0, 16);
-      final byte[] cipherText2 = cm.encrypt(secretMessage.getBytes());
       final byte[] keyID2 = (byte[])m.invoke(null, cipherText2, 0, 16);
-      assertTrue(Arrays.equals(keyID, keyID2));
+      assertEquals(keyID, keyID2);
     }
     catch (NoSuchMethodException ex) {
-      // ignore - requires Java 6
+      // skip this test - requires at least Java 6
     }
+
+    // test for distinct ciphertext
+    assertTrue(! Arrays.equals(cipherText, cipherText2));
   }
 
-  // TODO: ensure ciphers using IV output differs for successive
-  // encryptions of the same clear-text.
+
+  /**
+   Test that secret keys are persisted: Encrypt some data using a
+   variety of transformations, restart the instance, and decrypt the
+   retained ciphertext.
+
+   @throws Exception  In case an error occurs in the encryption routine.
+   */
+  @Test(enabled=false)
+  public void testKeyPersistence()
+        throws Exception {
+
+    final CryptoManager cm = DirectoryServer.getCryptoManager();
+    final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
+
+    final byte[] cipherText = cm.encrypt("Blowfish/CFB/NoPadding", 128,
+            secretMessage.getBytes());
+    final byte[] cipherText2 = cm.encrypt("RC4", 104,
+            secretMessage.getBytes());
+
+    DirectoryServer.restart(this.getClass().getName(),
+            Message.raw("CryptoManager: testing persistent secret keys."));
+
+    byte[] plainText = cm.decrypt(cipherText);
+    assertEquals((new String(plainText)), secretMessage);
+    plainText = cm.decrypt(cipherText2);
+    assertEquals((new String(plainText)), secretMessage);
+  }
+
+  // TODO: mark a key compromised; ensure 1) subsequent encryption
+  // requests use a new key; 2) ciphertext produced using the compromised
+  // key can still be decrypted.
 }

--
Gitblit v1.10.0