From dc85d3be1d993e170e6a2f0af6544ab3ee0b7d76 Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Wed, 08 Jun 2016 14:26:19 +0000
Subject: [PATCH] OPENDJ-3086 Acquire and distribute encryption keys when applying config changes to backends

---
 opendj-server-legacy/src/messages/org/opends/messages/backend.properties                    |    1 +
 opendj-server-legacy/src/main/java/org/opends/server/crypto/CryptoManagerImpl.java          |    6 ++++++
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java |   40 +++++++++++++++++++++++++++++-----------
 opendj-server-legacy/src/main/java/org/opends/server/types/CryptoManager.java               |   13 +++++++++++++
 4 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
index cac8f8a..82f78e8 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -2362,22 +2362,40 @@
   @Override
   public boolean isConfigurationChangeAcceptable(PluggableBackendCfg cfg, List<LocalizableMessage> unacceptableReasons)
   {
-    StringBuilder builder = new StringBuilder();
-    for (AttributeIndex attributeIndex : attrIndexMap.values())
+    if (cfg.isConfidentialityEnabled())
     {
-      if (attributeIndex.isConfidentialityEnabled() && !cfg.isConfidentialityEnabled())
+      final String cipherTransformation = cfg.getCipherTransformation();
+      final int keyLength = cfg.getCipherKeyLength();
+
+      try
       {
-        if (builder.length() > 0)
-        {
-          builder.append(", ");
-        }
-        builder.append(attributeIndex.getAttributeType().getNameOrOID());
+        serverContext.getCryptoManager().ensureCipherKeyIsAvailable(cipherTransformation, keyLength);
+      }
+      catch (Exception e)
+      {
+        unacceptableReasons.add(ERR_BACKEND_FAULTY_CRYPTO_TRANSFORMATION.get(cipherTransformation, keyLength, e));
+        return false;
       }
     }
-    if (builder.length() > 0)
+    else
     {
-      unacceptableReasons.add(ERR_BACKEND_CANNOT_CHANGE_CONFIDENTIALITY.get(getBaseDN(), builder.toString()));
-      return false;
+      StringBuilder builder = new StringBuilder();
+      for (AttributeIndex attributeIndex : attrIndexMap.values())
+      {
+        if (attributeIndex.isConfidentialityEnabled())
+        {
+          if (builder.length() > 0)
+          {
+            builder.append(", ");
+          }
+          builder.append(attributeIndex.getAttributeType().getNameOrOID());
+        }
+      }
+      if (builder.length() > 0)
+      {
+        unacceptableReasons.add(ERR_BACKEND_CANNOT_CHANGE_CONFIDENTIALITY.get(getBaseDN(), builder.toString()));
+        return false;
+      }
     }
     return true;
   }
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 2dbc160..a70073e 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
@@ -2503,6 +2503,12 @@
     return new CipherOutputStream(outputStream, cipher);
   }
 
+  @Override
+  public void ensureCipherKeyIsAvailable(String cipherTransformation, int cipherKeyLength) throws CryptoManagerException
+  {
+    getCipherKeyEntry(cipherTransformation, cipherKeyLength);
+  }
+
   private CipherKeyEntry getCipherKeyEntry(String cipherTransformation, int keyLengthBits) throws CryptoManagerException
   {
     CipherKeyEntry keyEntry = CipherKeyEntry.getCipherKeyEntryOrNull(this, cipherTransformation, keyLengthBits);
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/types/CryptoManager.java b/opendj-server-legacy/src/main/java/org/opends/server/types/CryptoManager.java
index 2e9ddc7..4717275 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/types/CryptoManager.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/types/CryptoManager.java
@@ -433,4 +433,17 @@
    * @param encrypt true if the user of the crypto suite needs encryption
    */
   CryptoSuite newCryptoSuite(String cipherTransformation, int cipherKeyLength, boolean encrypt);
+
+  /**
+   * Ensures that a key exists for the provided cipher transformation and key length.
+   * If none exists, a new one will be created.
+   *<p>
+   * Newly created keys will be published and propagated to the replication topology.
+   *
+   * @param cipherTransformation cipher transformation string specification
+   * @param cipherKeyLength length of key in bits
+   * @throws CryptoManagerException  If a problem occurs managing the encryption key
+   */
+  void ensureCipherKeyIsAvailable(String cipherTransformation, int cipherKeyLength) throws CryptoManagerException;
+
 }
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
index 46fc025..6b354fb 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/backend.properties
@@ -1093,3 +1093,4 @@
  following indexes have confidentiality still enabled: %s
 NOTE_CONFIG_INDEX_CONFIDENTIALITY_REQUIRES_REBUILD_607=Changing confidentiality for index '%s' requires the index \
  to be rebuilt before it can be used again
+ERR_BACKEND_FAULTY_CRYPTO_TRANSFORMATION_608=Error while enabling confidentiality with cipher %s, %d bits: %s

--
Gitblit v1.10.0