From 9299391814e620ae9ddaf187e05c2b6dd54340a7 Mon Sep 17 00:00:00 2001
From: david_page <david_page@localhost>
Date: Thu, 18 Oct 2007 05:07:12 +0000
Subject: [PATCH] no issue CryptoManager 1. remove shared secret key wrapping transformation (ds-cfg-key-wrapping-transformation) from configuration 2. other miscellaneous cleanup, including adding TODOs with issue numbers for some recently opened issues.

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoTestCase.java        |    2 
 opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java                             |  195 +++++++++++++++++++++++-------------------------
 opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java |    3 
 opends/src/server/org/opends/server/extensions/ExtensionsConstants.java                       |    5 +
 opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml              |   30 -------
 5 files changed, 103 insertions(+), 132 deletions(-)

diff --git a/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml
index 532e017..559635e 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml
@@ -187,33 +187,6 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
-  <adm:property name="key-wrapping-transformation" multi-valued="false" advanced="false">
-    <adm:synopsis>
-      The preferred key wrapping transformation for the Directory Server.
-    </adm:synopsis>
-    <adm:requires-admin-action>
-      <adm:none>
-        <adm:synopsis>
-          Changes to this property will take effect immediately but will
-          only affect cryptographic operations performed after the
-          change.
-        </adm:synopsis>
-      </adm:none>
-    </adm:requires-admin-action>
-    <adm:default-behavior>
-      <adm:defined>
-        <adm:value>RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING</adm:value>
-      </adm:defined>
-    </adm:default-behavior>
-    <adm:syntax>
-      <adm:string />
-    </adm:syntax>
-    <adm:profile name="ldap">
-      <ldap:attribute>
-        <ldap:name>ds-cfg-key-wrapping-transformation</ldap:name>
-      </ldap:attribute>
-    </adm:profile>
-  </adm:property>
   <adm:property name="ssl-protocol" multi-valued="true">
     <adm:synopsis>
       Specifies the names of the SSL protocols that will be allowed for
@@ -231,8 +204,7 @@
     <adm:default-behavior>
       <adm:alias>
         <adm:synopsis>
-          Uses the default set of SSL protocols provided by the server's
-          JVM.
+          Uses the default set of SSL protocols provided by the server's JVM.
         </adm:synopsis>
       </adm:alias>
     </adm:default-behavior>
diff --git a/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java b/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
index 36fa471..6827652 100644
--- a/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
+++ b/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
@@ -156,9 +156,6 @@
   private static final Random pseudoRandom
           = new Random(secureRandom.nextLong());
 
-  // The preferred message digest algorithm for the Directory Server.
-  private String preferredDigestAlgorithm;
-
   // The first byte in any ciphertext produced by CryptoManager is the
   // prologue version. At present, this constant is both the version written
   // and the expected version. If a new version is introduced (e.g., to allow
@@ -168,22 +165,29 @@
   // while signed backups might use version 2.
   private static final int CIPHERTEXT_PROLOGUE_VERSION = 1 ;
 
+  // The map from encryption key ID to CipherKeyEntry (cache). The
+  // cache is accessed by methods that request, publish, and import
+  // keys.
+  private final Map<KeyEntryID, CipherKeyEntry> cipherKeyEntryCache
+          = new ConcurrentHashMap<KeyEntryID, CipherKeyEntry>();
+
   // The map from encryption key ID to MacKeyEntry (cache). The cache
   // is accessed by methods that request, publish, and import keys.
   private final Map<KeyEntryID, MacKeyEntry> macKeyEntryCache
           = new ConcurrentHashMap<KeyEntryID, MacKeyEntry>();
 
-  // The preferred MAC algorithm for the Directory Server.
-  private String preferredMACAlgorithm;
+  // The shared secret key wrapping transformation.
+  // TODO: Trying OAEPWITHSHA-512ANDMGF1PADDING throws an exception "Key too
+  // TODO: small...". https://opends.dev.java.net/issues/show_bug.cgi?id=2474
+  private static final String sharedSecretKeyWrappingTransformation
+          = "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";
 
-  // The preferred key length for the preferred MAC algorithm.
-  private int preferredMACAlgorithmKeyLengthBits;
 
-  // The map from encryption key ID to CipherKeyEntry (cache). The
-  // cache is accessed by methods that request, publish, and import
-  // keys.
-  private final Map<KeyEntryID, CipherKeyEntry> cipherKeyEntryCache
-       = new ConcurrentHashMap<KeyEntryID, CipherKeyEntry>();
+  // TODO: Move the following configuration to backup or backend configuration.
+  // TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2472
+
+  // The preferred message digest algorithm for the Directory Server.
+  private String preferredDigestAlgorithm;
 
   // The preferred cipher for the Directory Server.
   private String preferredCipherTransformation;
@@ -191,8 +195,15 @@
   // The preferred key length for the preferred cipher.
   private int preferredCipherTransformationKeyLengthBits;
 
-  // The preferred key wrapping transformation
-  private String preferredKeyWrappingTransformation;
+  // The preferred MAC algorithm for the Directory Server.
+  private String preferredMACAlgorithm;
+
+  // The preferred key length for the preferred MAC algorithm.
+  private int preferredMACAlgorithmKeyLengthBits;
+
+
+  // TODO: Move the following configuration to replication configuration.
+  // TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2473
 
   // The name of the local certificate to use for SSL.
   private final String sslCertNickname;
@@ -297,7 +308,7 @@
        List<Message> unacceptableReasons)
   {
     // Acceptable until we find an error.
-    boolean acceptable = true;
+    boolean isAcceptable = true;
 
     // Requested digest validation.
     String requestedDigestAlgorithm =
@@ -314,7 +325,7 @@
         unacceptableReasons.add(
              ERR_CRYPTOMGR_CANNOT_GET_REQUESTED_DIGEST.get(
                   requestedDigestAlgorithm, getExceptionMessage(ex)));
-        acceptable = false;
+        isAcceptable = false;
       }
     }
 
@@ -331,7 +342,7 @@
         unacceptableReasons.add(
                 ERR_CRYPTOMGR_FULL_CIPHER_TRANSFORMATION_REQUIRED.get(
                         requestedCipherTransformation));
-        acceptable = false;
+        isAcceptable = false;
       }
       else {
         try {
@@ -346,7 +357,7 @@
           unacceptableReasons.add(
              ERR_CRYPTOMGR_CANNOT_GET_REQUESTED_ENCRYPTION_CIPHER.get(
                      requestedCipherTransformation, getExceptionMessage(ex)));
-          acceptable = false;
+          isAcceptable = false;
         }
       }
     }
@@ -372,68 +383,58 @@
         unacceptableReasons.add(
                 ERR_CRYPTOMGR_CANNOT_GET_REQUESTED_MAC_ENGINE.get(
                         requestedMACAlgorithm, getExceptionMessage(ex)));
-        acceptable = false;
+        isAcceptable = false;
       }
     }
 
-    // Requested secret key wrapping cipher and validation. Validation
-    // depends on MAC cipher for secret key.
-    String requestedKeyWrappingTransformation
-            = cfg.getKeyWrappingTransformation();
-    if (! requestedKeyWrappingTransformation.equals(
-            this.preferredKeyWrappingTransformation)) {
-      if (3 != requestedKeyWrappingTransformation.split("/", 0).length) {
+    // Shared secret key wrapping cipher and validation. Note that this value is
+    // not set from a configuration attribute, but it needs to be validated, and
+    // validation depends on the MAC cipher produced above for a secret key to
+    // wrap.
+    if (3 != sharedSecretKeyWrappingTransformation.split("/", 0).length) {
+      unacceptableReasons.add(
+              ERR_CRYPTOMGR_FULL_KEY_WRAPPING_TRANSFORMATION_REQUIRED.get(
+                      sharedSecretKeyWrappingTransformation));
+      isAcceptable = false;
+    }
+    else {
+      try {
+        /* Note that the TrustStoreBackend not available at initial,
+           CryptoManager configuration, hence a "dummy" certificate must be used
+           to validate the choice of secret key wrapping cipher. Otherwise, call
+           getInstanceKeyCertificateFromLocalTruststore() */
+        final String certificateBase64 =
+                "MIIB2jCCAUMCBEb7wpYwDQYJKoZIhvcNAQEEBQAwNDEbMBkGA1UEChMST3B" +
+                "lbkRTIENlcnRpZmljYXRlMRUwEwYDVQQDEwwxMC4wLjI0OC4yNTEwHhcNMD" +
+                "cwOTI3MTQ0NzUwWhcNMjcwOTIyMTQ0NzUwWjA0MRswGQYDVQQKExJPcGVuR" +
+                "FMgQ2VydGlmaWNhdGUxFTATBgNVBAMTDDEwLjAuMjQ4LjI1MTCBnzANBgkq" +
+                "hkiG9w0BAQEFAAOBjQAwgYkCgYEAnIm6ELyuNVbpaacBQ7fzHlHMmQO/CYJ" +
+                "b2gPTdb9n1HLOBqh2lmLLHvt2SgBeN5TSa1PAHW8zJy9LDhpWKZvsUOIdQD" +
+                "8Ula/0d/jvMEByEj/hr00P6yqgLXk+EudPgOkFXHA+IfkkOSghMooWc/L8H" +
+                "nD1REdqeZuxp+ARNU+cc/ECAwEAATANBgkqhkiG9w0BAQQFAAOBgQBemyCU" +
+                "jucN34MZwvzbmFHT/leUu3/cpykbGM9HL2QUX7iKvv2LJVqexhj7CLoXxZP" +
+                "oNL+HHKW0vi5/7W5KwOZsPqKI2SdYV7nDqTZklm5ZP0gmIuNO6mTqBRtC2D" +
+                "lplX1Iq+BrQJAmteiPtwhdZD+EIghe51CaseImjlLlY2ZK8w==";
+        final byte[] certificate = Base64.decode(certificateBase64);
+        final String keyID = getInstanceKeyID(certificate);
+        final SecretKey macKey = MacKeyEntry.generateKeyEntry(null,
+                requestedMACAlgorithm,
+                requestedMACAlgorithmKeyLengthBits).getSecretKey();
+        encodeSymmetricKeyAttribute(sharedSecretKeyWrappingTransformation,
+                keyID, certificate, macKey);
+      }
+      catch (Exception ex) {
+        if (debugEnabled()) {
+          TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+        }
         unacceptableReasons.add(
-                ERR_CRYPTOMGR_FULL_KEY_WRAPPING_TRANSFORMATION_REQUIRED.get(
-                        requestedKeyWrappingTransformation));
-        acceptable = false;
-      }
-      else {
-        try {
-          /* Note that the TrustStoreBackend not available at initial,
-             CryptoManager configuration, hence a "dummy" certificate
-             must be used to validate the choice of secret key
-             wrapping cipher. Otherwise, call
-             getInstanceKeyCertificateFromLocalTruststore() */
-          final String certificateBase64 =
-      "MIIB2jCCAUMCBEb7wpYwDQYJKoZIhvcNAQEEBQAwNDEbMBkGA1UEChMST3B" +
-      "lbkRTIENlcnRpZmljYXRlMRUwEwYDVQQDEwwxMC4wLjI0OC4yNTEwHhcNMD" +
-      "cwOTI3MTQ0NzUwWhcNMjcwOTIyMTQ0NzUwWjA0MRswGQYDVQQKExJPcGVuR" +
-      "FMgQ2VydGlmaWNhdGUxFTATBgNVBAMTDDEwLjAuMjQ4LjI1MTCBnzANBgkq" +
-      "hkiG9w0BAQEFAAOBjQAwgYkCgYEAnIm6ELyuNVbpaacBQ7fzHlHMmQO/CYJ" +
-      "b2gPTdb9n1HLOBqh2lmLLHvt2SgBeN5TSa1PAHW8zJy9LDhpWKZvsUOIdQD" +
-      "8Ula/0d/jvMEByEj/hr00P6yqgLXk+EudPgOkFXHA+IfkkOSghMooWc/L8H" +
-      "nD1REdqeZuxp+ARNU+cc/ECAwEAATANBgkqhkiG9w0BAQQFAAOBgQBemyCU" +
-      "jucN34MZwvzbmFHT/leUu3/cpykbGM9HL2QUX7iKvv2LJVqexhj7CLoXxZP" +
-      "oNL+HHKW0vi5/7W5KwOZsPqKI2SdYV7nDqTZklm5ZP0gmIuNO6mTqBRtC2D" +
-      "lplX1Iq+BrQJAmteiPtwhdZD+EIghe51CaseImjlLlY2ZK8w==";
-          final byte[] certificate = Base64.decode(certificateBase64);
-          final String keyID = getInstanceKeyID(certificate);
-          requestedKeyWrappingTransformation
-            = cfg.getKeyWrappingTransformation();
-          final SecretKey macKey =
-                  MacKeyEntry.generateKeyEntry(
-                          null,
-                          requestedMACAlgorithm,
-                          requestedMACAlgorithmKeyLengthBits).
-                          getSecretKey();
-          encodeSymmetricKeyAttribute(
-                  requestedKeyWrappingTransformation, keyID,
-                  certificate, macKey);
-        }
-        catch (Exception ex) {
-          if (debugEnabled()) {
-            TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-          }
-          unacceptableReasons.add(
-           ERR_CRYPTOMGR_CANNOT_GET_PREFERRED_KEY_WRAPPING_CIPHER.get(
-                          getExceptionMessage(ex)));
-          acceptable = false;
-        }
+                ERR_CRYPTOMGR_CANNOT_GET_PREFERRED_KEY_WRAPPING_CIPHER.get(
+                        getExceptionMessage(ex)));
+        isAcceptable = false;
       }
     }
 
-    return acceptable;
+    return isAcceptable;
   }
 
 
@@ -447,21 +448,13 @@
     boolean adminActionRequired = false;
     List<Message> messages = new ArrayList<Message>();
 
-    preferredDigestAlgorithm =
-         cfg.getDigestAlgorithm();
-    preferredMACAlgorithm =
-         cfg.getMacAlgorithm();
-    preferredMACAlgorithmKeyLengthBits =
-         cfg.getMacKeyLength();
-    preferredCipherTransformation =
-         cfg.getCipherTransformation();
-    preferredCipherTransformationKeyLengthBits =
-         cfg.getCipherKeyLength();
-    preferredKeyWrappingTransformation =
-         cfg.getKeyWrappingTransformation();
+    preferredDigestAlgorithm = cfg.getDigestAlgorithm();
+    preferredMACAlgorithm = cfg.getMacAlgorithm();
+    preferredMACAlgorithmKeyLengthBits = cfg.getMacKeyLength();
+    preferredCipherTransformation = cfg.getCipherTransformation();
+    preferredCipherTransformationKeyLengthBits = cfg.getCipherKeyLength();
 
-    return new ConfigChangeResult(resultCode,
-                                  adminActionRequired, messages);
+    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   }
 
 
@@ -615,8 +608,8 @@
    * @throws CryptoManagerException If there is a problem computing
    * the identifier from the instance key.
    *
-   * TODO: make package-private if ADSContextHelper can get keyID from ADS
-   * suffix: Issue https://opends.dev.java.net/issues/show_bug.cgi?id=2442
+   * TODO: Make package-private if ADSContextHelper can get keyID from ADS
+   * TODO: suffix: Issue https://opends.dev.java.net/issues/show_bug.cgi?id=2442
    */
   public static String getInstanceKeyID(byte[] instanceKeyCertificate)
             throws CryptoManagerException {
@@ -840,7 +833,7 @@
           final SecretKey secretKey)
           throws CryptoManagerException {
     return encodeSymmetricKeyAttribute(
-         preferredKeyWrappingTransformation,
+            sharedSecretKeyWrappingTransformation,
          wrappingKeyID,
          wrappingKeyCertificateData,
          secretKey);
@@ -1037,7 +1030,7 @@
     final byte[] wrappingKeyCert =
             certMap.get(requestedInstanceKeyID);
     return encodeSymmetricKeyAttribute(
-         preferredKeyWrappingTransformation,
+            sharedSecretKeyWrappingTransformation,
          requestedInstanceKeyID, wrappingKeyCert, secretKey);
   }
 
@@ -1700,6 +1693,7 @@
       // Validate the key entry. Record the initialization vector length, if
       // any.
       final Cipher cipher = getCipher(keyEntry, Cipher.ENCRYPT_MODE, null);
+      // TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2471
       final byte[] iv = cipher.getIV();
       keyEntry.setIVLengthBits((null == iv) ? 0 : iv.length * Byte.SIZE);
 
@@ -2209,15 +2203,16 @@
 
     try {
       if (0 < keyEntry.getIVLengthBits()) {
-          byte[] iv;
-          if (Cipher.ENCRYPT_MODE == mode && null == initializationVector) {
-            iv = new byte[keyEntry.getIVLengthBits() / Byte.SIZE];
-            pseudoRandom.nextBytes(iv);
-          }
-          else {
-            iv = initializationVector;
-          }
-          cipher.init(mode, keyEntry.getSecretKey(), new IvParameterSpec(iv));
+        byte[] iv;
+        if (Cipher.ENCRYPT_MODE == mode && null == initializationVector) {
+          iv = new byte[keyEntry.getIVLengthBits() / Byte.SIZE];
+          pseudoRandom.nextBytes(iv);
+        }
+        else {
+          iv = initializationVector;
+        }
+        // TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2471
+        cipher.init(mode, keyEntry.getSecretKey(), new IvParameterSpec(iv));
       }
       else {
         cipher.init(mode, keyEntry.getSecretKey());
diff --git a/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java b/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java
index f087d3e..93a9e3e 100644
--- a/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java
+++ b/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java
@@ -146,6 +146,8 @@
   /**
    * The cipher transformation that should be used when performing RC4
    * encryption/decription.
+   *
+   * TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2471
    */
   public static final String CIPHER_TRANSFORMATION_RC4 = "RC4/NONE/NoPadding";
 
@@ -162,6 +164,7 @@
   /**
    * The key size (in bits) that should be used for the encryption key when
    * using the AES cipher.
+   * TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2475
    */
   public static final int KEY_SIZE_AES = 128;
 
@@ -170,6 +173,7 @@
   /**
    * The key size (in bits) that should be used for the encryption key when
    * using the Blowfish cipher.
+   * TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2475
    */
   public static final int KEY_SIZE_BLOWFISH = 128;
 
@@ -178,6 +182,7 @@
   /**
    * The key size (in bits) that should be used for the encryption key when
    * using the RC4 cipher.
+   * TODO: https://opends.dev.java.net/issues/show_bug.cgi?id=2475
    */
   public static final int KEY_SIZE_RC4 = 128;
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java
index b2a7ec5..a0e69b3 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java
@@ -457,8 +457,7 @@
   }
 
   /**
-   TODO: Test key wrapping
-   Trying OAEPWITHSHA-512ANDMGF1PADDING throws an exception "Key too small...".
+   TODO: Test shared secret key wrapping (various wrapping ciphers, if configurable).
    */
 
 
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoTestCase.java
index 65ce24c..8d21c2f 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoTestCase.java
@@ -30,7 +30,7 @@
 import org.opends.server.DirectoryServerTestCase;
 
 /**
- * An abstract class that all types unit tests should extend.
+ * An abstract class that all crypto unit tests should extend.
  */
 
 @Test(groups = { "precommit", "crypto" }, sequential = true)

--
Gitblit v1.10.0