From b93c8bf6f5bb9560e9ba219eb6be1ea9bb12f3be Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Thu, 26 May 2016 11:15:14 +0000
Subject: [PATCH] OPENDJ-3027 Delete all references to old keys when importing new ones via replication
---
opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java | 14 ++++++++++++--
opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java b/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java
index 958f159..3e546dc 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java
@@ -1640,7 +1640,12 @@
}
getCipher(keyEntry, Cipher.DECRYPT_MODE, iv);
- // Cache new entry.
+ // Cache new entry, make sure it is the only one using the given transformation / key length.
+ CipherKeyEntry oldKeyEntry = getKeyEntry(cryptoManager, transformation, secretKeyLengthBits);
+ if (oldKeyEntry != null)
+ {
+ cryptoManager.cipherKeyEntryCache.remove(oldKeyEntry.getKeyID());
+ }
cryptoManager.cipherKeyEntryCache.put(keyEntry.getKeyID(), keyEntry);
return keyEntry;
@@ -2097,7 +2102,12 @@
// Validate new entry.
getMacEngine(keyEntry);
- // Cache new entry.
+ // Cache new entry, make sure it is the only one using the given transformation / key length.
+ MacKeyEntry oldKeyEntry = getKeyEntry(cryptoManager, algorithm, secretKeyLengthBits);
+ if (oldKeyEntry != null)
+ {
+ cryptoManager.macKeyEntryCache.remove(oldKeyEntry.getKeyID());
+ }
cryptoManager.macKeyEntryCache.put(keyEntry.getKeyID(),
keyEntry);
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java
index 6a4362d..765c86c 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/crypto/CryptoManagerTestCase.java
@@ -24,6 +24,7 @@
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.List;
+import java.util.UUID;
import javax.crypto.Mac;
@@ -33,6 +34,7 @@
import org.opends.admin.ads.ADSContext;
import org.opends.server.TestCaseUtils;
import org.opends.server.core.DirectoryServer;
+import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.internal.SearchRequest;
import org.opends.server.protocols.ldap.LDAPAttribute;
@@ -41,19 +43,24 @@
import org.opends.server.types.CryptoManager;
import org.opends.server.types.CryptoManagerException;
import org.forgerock.opendj.ldap.DN;
+import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
+import org.opends.server.types.Modification;
import org.opends.server.util.EmbeddedUtils;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.TimeThread;
+import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.assertj.core.api.Assertions.*;
+import static org.forgerock.opendj.ldap.ModificationType.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.protocols.internal.InternalClientConnection.*;
import static org.opends.server.protocols.internal.Requests.*;
+import static org.opends.server.types.Attributes.create;
import static org.testng.Assert.*;
/**
@@ -74,6 +81,36 @@
TestCaseUtils.restartServer();
}
+ @Test(expectedExceptions = CryptoManagerException.class)
+ public void testImportKeysReplacesExistingKeys()
+ throws Exception {
+ final CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
+ final int keyLength = 56;
+ final String cipher = "DES/CFB/NoPadding";
+ byte[] cipherText = cm.encrypt(cipher, keyLength, new byte[56]);
+ Entry oldKey = getKeyForCipher(cipher, keyLength);
+ // Force import by changing the keyID
+ Modification mod = new Modification(REPLACE, create("ds-cfg-key-id", UUID.randomUUID().toString()));
+ oldKey.applyModification(mod);
+ cm.importCipherKeyEntry(oldKey);
+ try
+ {
+ cm.decrypt(cipherText);
+ Assert.fail("Was expecting a CryptoManager exception, the key should be invalid.");
+ }
+ finally
+ {
+ }
+ }
+
+ private Entry getKeyForCipher(String cipher, int keyLength) throws DirectoryException
+ {
+ SearchRequest request = newSearchRequest("cn=secret keys, cn=admin data", SearchScope.WHOLE_SUBTREE,
+ "&(ds-cfg-cipher-transformation-name=" + cipher + ")(ds-cfg-key-length-bits=" + keyLength + ")");
+ InternalClientConnection conn = getRootConnection();
+ InternalSearchOperation search = conn.processSearch(request);
+ return search.getSearchEntries().get(0);
+ }
@Test
public void testGetInstanceKeyCertificate()
--
Gitblit v1.10.0