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

david_page
03.29.2007 c00c2e9dc41f704704508e146dd56704b0c7ff50
Issue 466 (partial)
add some secret key tests - disabled pending ADS export
1 files modified
110 ■■■■■ changed files
opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java 110 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/types/CryptoManagerTestCase.java
@@ -31,10 +31,17 @@
import static org.testng.Assert.assertTrue;
import org.opends.server.TestCaseUtils;
import org.opends.server.schema.DirectoryStringSyntax;
import org.opends.server.schema.BinarySyntax;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.config.ConfigConstants;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.TimeThread;
import org.opends.server.core.DirectoryServer;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.admin.ads.ADSContext;
import org.opends.messages.Message;
import java.io.File;
@@ -45,6 +52,7 @@
import java.util.List;
import java.util.LinkedList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.lang.reflect.Method;
import java.security.MessageDigest;
@@ -79,7 +87,8 @@
   */
  @AfterClass()
  public void CleanUp() throws Exception {
    DirectoryServer.restart(this.getClass().getName(),
            Message.raw("CryptoManager: clean-up internal key caches."));
  }
@@ -189,7 +198,7 @@
    // default (preferred) AES/CBC/PKCS5Padding 128bit key.
    paramList.add(new CipherParameters(null, null, null, 128, 128));
    // custom
//    paramList.add(new CipherParameters("Blowfish", "CFB", "NoPadding", 192, 64));
// TODO:  paramList.add(new CipherParameters("Blowfish", "CFB", "NoPadding", 192, 64));
    paramList.add(new CipherParameters("Blowfish", "CFB", "NoPadding", 128, 64));
    paramList.add(new CipherParameters("RC4", null, null, 104, 0));
    paramList.add(new CipherParameters("DES", "CFB", "NoPadding", 56, 56));
@@ -316,7 +325,6 @@
  @Test(enabled=false)
  public void testKeyPersistence()
        throws Exception {
    final CryptoManager cm = DirectoryServer.getCryptoManager();
    final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
@@ -334,7 +342,97 @@
    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.
  /**
   Mark a key compromised; ensure 1) subsequent encryption requests use a new
   key; 2) ciphertext produced using the compromised key can still be decrypted.
   @throws Exception In case something exceptional happens.
   */
  @Test(enabled=false)
  public void testCompromisedKey() throws Exception {
    final CryptoManager cm = DirectoryServer.getCryptoManager();
    final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
    final String cipherTransformationName = "AES/CBC/PKCS5Padding";
    final int cipherKeyLength = 128;
    // Initial encryption ensures a cipher key entry is in ADS.
    final byte[] cipherText = cm.encrypt(cipherTransformationName,
            cipherKeyLength, secretMessage.getBytes());
    // Retrieve all uncompromised cipher key entries corresponding to the
    // specified transformation and key length. Mark each entry compromised.
    final String baseDNStr // TODO: is this DN a constant?
            = "cn=secret keys," + ADSContext.getAdministrationSuffixDN();
    final DN baseDN = DN.decode(baseDNStr);
    final String FILTER_OC_INSTANCE_KEY
            = new StringBuilder("(objectclass=")
            .append(ConfigConstants.OC_CRYPTO_CIPHER_KEY)
            .append(")").toString();
    final String FILTER_NOT_COMPROMISED = new StringBuilder("(!(")
            .append(ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME)
            .append("=*))").toString();
    final String FILTER_CIPHER_TRANSFORMATION_NAME = new StringBuilder("(")
            .append(ConfigConstants.ATTR_CRYPTO_CIPHER_TRANSFORMATION_NAME)
            .append("=").append(cipherTransformationName)
            .append(")").toString();
    final String FILTER_CIPHER_KEY_LENGTH = new StringBuilder("(")
            .append(ConfigConstants.ATTR_CRYPTO_KEY_LENGTH_BITS)
            .append("=").append(String.valueOf(cipherKeyLength))
            .append(")").toString();
    final String searchFilter = new StringBuilder("(&")
            .append(FILTER_OC_INSTANCE_KEY)
            .append(FILTER_NOT_COMPROMISED)
            .append(FILTER_CIPHER_TRANSFORMATION_NAME)
            .append(FILTER_CIPHER_KEY_LENGTH)
            .append(")").toString();
    final LinkedHashSet<String> requestedAttributes
            = new LinkedHashSet<String>();
    requestedAttributes.add("dn");
    final InternalClientConnection icc
            = InternalClientConnection.getRootConnection();
    InternalSearchOperation searchOp = icc.processSearch(
            baseDN,
            SearchScope.SINGLE_LEVEL,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            /* size limit */ 0, /* time limit */ 0,
            /* types only */ false,
            SearchFilter.createFilterFromString(searchFilter),
            requestedAttributes);
    assertTrue(0 < searchOp.getSearchEntries().size());
    String compromisedTime = TimeThread.getGeneralizedTime();
    for (Entry e : searchOp.getSearchEntries()) {
      TestCaseUtils.applyModifications(
        "dn: " + e.getDN().toNormalizedString(),
        "changetype: modify",
        "replace: " + ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME,
        ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME + ": "
                + compromisedTime);
    }
    // Use the transformation and key length again. A new cipher key
    // should be produced.
    final byte[] cipherText2 = cm.encrypt(cipherTransformationName,
            cipherKeyLength, secretMessage.getBytes());
    // test for identical keys
    try {
      Method m = Arrays.class.getMethod("copyOfRange", (new byte[16]).getClass(),
              Integer.TYPE, Integer.TYPE);
      final byte[] keyID = (byte[])m.invoke(null, cipherText, 0, 16);
      final byte[] keyID2 = (byte[])m.invoke(null, cipherText2, 0, 16);
      assertTrue(! Arrays.equals(keyID, keyID2));
    }
    catch (NoSuchMethodException ex) {
      // skip this test - requires at least Java 6
    }
    // confirm ciphertext produced using compromised key can still
    // be decrypted.
    final byte[] plainText = cm.decrypt(cipherText);
    assertEquals((new String(plainText)), secretMessage);
  }
}