mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

david_page
03.47.2007 804876778e046d54e785fb7caf1c01021d24922c
Issue 466 (partial)
more secret key stuff
2 files modified
81 ■■■■ changed files
opends/src/server/org/opends/server/types/CryptoManager.java 21 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java 60 ●●●● patch | view | raw | blame | history
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);
  }
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;
@@ -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++)
    {
@@ -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
  }
  // TODO: ensure ciphers using IV output differs for successive
  // encryptions of the same clear-text.
    // test for distinct ciphertext
    assertTrue(! Arrays.equals(cipherText, cipherText2));
  }
  /**
   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.
}