From cf9a9cc42a5baf5ab94367b1ed535e279051ce33 Mon Sep 17 00:00:00 2001
From: david_page <david_page@localhost>
Date: Sun, 14 Oct 2007 01:32:43 +0000
Subject: [PATCH] No issue. CryptoManager Step 3. Factor interface from CryptoManager implementation.

---
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackupManager.java                                              |    1 
 opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java                                                    |    8 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java                                                        |    4 
 opendj-sdk/opends/src/server/org/opends/server/types/CryptoManagerException.java                                            |    5 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java                                                              |    2 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java                    |   10 
 opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java                                                | 1697 ++++++++++++++++++--------------------------
 opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java                                |    8 
 opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java                                                  |    1 
 opendj-sdk/opends/src/server/org/opends/server/backends/jeb/JebFormat.java                                                  |    6 
 opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java                               |    8 
 opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerSync.java                                                |    2 
 opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java                                                   |    1 
 opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java                                     |    8 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperationTestCase.java |    7 
 opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java                                            |   25 
 opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java                                 |    2 
 opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java                                     |    8 
 opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplSessionSecurity.java                                |    2 
 opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java                                                     |  423 +++++++++++
 20 files changed, 1,155 insertions(+), 1,073 deletions(-)

diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java
index 54f889b..54d6878 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -2172,7 +2172,7 @@
    value to ds-cfg-public-key-certificate;binary value. Note that the collection
    might be empty.
    @throws ADSContextException in case of problems with the entry search.
-   @see org.opends.server.crypto.CryptoManager#getTrustedCertificates
+   @see org.opends.server.crypto.CryptoManagerImpl#getTrustedCertificates
    */
   public Map<String,byte[]> getTrustedCertificates()
           throws ADSContextException
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
index bf3ebd5..b9581f2 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
@@ -50,7 +50,7 @@
 import org.opends.server.admin.std.meta.BackendCfgDefn;
 import org.opends.server.admin.std.meta.LDIFBackendCfgDefn;
 import org.opends.server.config.ConfigConstants;
-import org.opends.server.crypto.CryptoManager;
+import org.opends.server.crypto.CryptoManagerImpl;
 import org.opends.server.types.CryptoManagerException;
 import org.opends.server.types.DN;
 
@@ -252,7 +252,7 @@
       else {
         /* create key ID, if it was not supplied in serverProperties */
         if (null == keyID) {
-          keyID = CryptoManager.getInstanceKeyID(
+          keyID = CryptoManagerImpl.getInstanceKeyID(
               (byte[])serverProperties.get(
                   ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE));
           keyAttrs.put(new BasicAttribute(
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
index 77d6c91..bd9a312 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -80,7 +80,6 @@
 import org.opends.server.schema.MatchingRuleUseSyntax;
 import org.opends.server.schema.NameFormSyntax;
 import org.opends.server.schema.ObjectClassSyntax;
-import org.opends.server.crypto.CryptoManager;
 import org.opends.server.types.CryptoManagerException;
 import org.opends.server.types.*;
 import org.opends.server.util.DynamicConstants;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackupManager.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackupManager.java
index ef878da..ccd5b5c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackupManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/BackupManager.java
@@ -30,7 +30,6 @@
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.util.DynamicConstants;
-import org.opends.server.crypto.CryptoManager;
 import org.opends.server.types.CryptoManagerException;
 
 import javax.crypto.Mac;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/JebFormat.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/JebFormat.java
index f7eab1b..042ca38 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/JebFormat.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/JebFormat.java
@@ -34,11 +34,7 @@
 import org.opends.server.protocols.asn1.ASN1Integer;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.protocols.asn1.ASN1Sequence;
-import org.opends.server.crypto.CryptoManager;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.Entry;
-import org.opends.server.types.EntryEncodeConfig;
-import org.opends.server.types.LDAPException;
+import org.opends.server.types.*;
 
 import static org.opends.server.loggers.debug.DebugLogger.*;
 import org.opends.server.loggers.debug.DebugTracer;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index 47d58a2..4807b44 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -145,7 +145,7 @@
 import org.opends.server.types.AttributeValue;
 import org.opends.server.types.BackupConfig;
 import org.opends.server.types.Control;
-import org.opends.server.crypto.CryptoManager;
+import org.opends.server.crypto.CryptoManagerImpl;
 import org.opends.server.types.DITContentRule;
 import org.opends.server.types.DITStructureRule;
 import org.opends.server.types.DN;
@@ -521,7 +521,7 @@
   private CoreConfigManager coreConfigManager;
 
   // The crypto manager for the Directory Server.
-  private CryptoManager cryptoManager;
+  private CryptoManagerImpl cryptoManager;
 
   // The default compressed schema manager.
   private DefaultCompressedSchema compressedSchema;
@@ -2211,7 +2211,7 @@
     RootCfg root =
          ServerManagementContext.getInstance().getRootConfiguration();
     CryptoManagerCfg cryptoManagerCfg = root.getCryptoManager();
-    cryptoManager = new CryptoManager(cryptoManagerCfg);
+    cryptoManager = new CryptoManagerImpl(cryptoManagerCfg);
   }
 
 
@@ -2221,7 +2221,7 @@
    *
    * @return  A reference to the Directory Server crypto manager.
    */
-  public static CryptoManager getCryptoManager()
+  public static CryptoManagerImpl getCryptoManager()
   {
     return directoryServer.cryptoManager;
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManager.java b/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
similarity index 88%
rename from opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManager.java
rename to opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
index 8ec0244..d1a7a3c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerImpl.java
@@ -103,19 +103,15 @@
  are a lot of similarities and it is conceivable at some point that
  accelerated compression may be available just as it is for
  cryptographic operations.
-
+ <p>
+ Other components of CryptoManager:
  @see "src/admin/defn/org/opends/server/admin/std\
                                       /CryptoManagerConfiguration.xml"
  @see org.opends.server.crypto.CryptoManagerSync
  @see org.opends.server.crypto.GetSymmetricKeyExtendedOperation
  */
-@org.opends.server.types.PublicAPI(
-     stability=org.opends.server.types.StabilityLevel.VOLATILE,
-     mayInstantiate=false,
-     mayExtend=false,
-     mayInvoke=true)
-public class CryptoManager
-     implements ConfigurationChangeListener<CryptoManagerCfg>
+public class CryptoManagerImpl
+        implements ConfigurationChangeListener<CryptoManagerCfg>, CryptoManager
 {
   /**
    * The tracer object for the debug logger.
@@ -131,7 +127,7 @@
   private static AttributeType attrInitVectorLength;
   private static AttributeType attrKeyLength;
   private static AttributeType attrCompromisedTime;
-  private static ObjectClass ocCertRequest;
+  private static ObjectClass   ocCertRequest;
   private static ObjectClass   ocInstanceKey;
   private static ObjectClass   ocCipherKey;
   private static ObjectClass   ocMacKey;
@@ -215,7 +211,7 @@
    occurs while creating this {@code CryptoManager} that is not the result of a
    problem in the configuration.
    */
-  public CryptoManager(CryptoManagerCfg cfg)
+  public CryptoManagerImpl(CryptoManagerCfg cfg)
          throws ConfigException, InitializationException {
     if (!schemaInitDone) {
       // Initialize various schema references.
@@ -464,6 +460,35 @@
 
 
   /**
+   * Retrieve the ADS trust store backend.
+   * @return The ADS trust store backend.
+   * @throws ConfigException If the ADS trust store backend is
+   *                         not configured.
+   */
+  private TrustStoreBackend getTrustStoreBackend()
+       throws ConfigException
+  {
+    Backend b = DirectoryServer.getBackend(
+         ConfigConstants.ID_ADS_TRUST_STORE_BACKEND);
+    if (b == null)
+    {
+      Message msg =
+           ERR_CRYPTOMGR_ADS_TRUST_STORE_BACKEND_NOT_ENABLED.get(
+                ConfigConstants.ID_ADS_TRUST_STORE_BACKEND);
+      throw new ConfigException(msg);
+    }
+    if (!(b instanceof TrustStoreBackend))
+    {
+      Message msg =
+           ERR_CRYPTOMGR_ADS_TRUST_STORE_BACKEND_WRONG_CLASS.get(
+                ConfigConstants.ID_ADS_TRUST_STORE_BACKEND);
+      throw new ConfigException(msg);
+    }
+    return (TrustStoreBackend)b;
+  }
+
+
+  /**
    * Returns this instance's instance-key public-key certificate from
    * the local keystore (i.e., from the truststore-backend and not
    * from the ADS backed keystore). If the certificate entry does not
@@ -1014,878 +1039,120 @@
 
 
   /**
-   * Retrieves the name of the preferred message digest algorithm.
+   * Given a set of other servers' symmetric key values for
+   * a given secret key, use the Get Symmetric Key extended
+   * operation to request this server's symmetric key value.
    *
-   * @return  The name of the preferred message digest algorithm
+   * @param  symmetricKeys  The known symmetric key values for
+   *                        a given secret key.
+   *
+   * @return The symmetric key value for this server, or null if
+   *         none could be obtained.
    */
-  public String getPreferredMessageDigestAlgorithm()
+  private String getSymmetricKey(List<String> symmetricKeys)
   {
-    return preferredDigestAlgorithm;
-  }
-
-
-  /**
-   * Retrieves a <CODE>MessageDigest</CODE> object that may be used to
-   * generate digests using the preferred digest algorithm.
-   *
-   * @return  A <CODE>MessageDigest</CODE> object that may be used to
-   *          generate digests using the preferred digest algorithm.
-   *
-   * @throws  NoSuchAlgorithmException  If the requested algorithm is
-   *                                    not supported or is
-   *                                    unavailable.
-   */
-  public MessageDigest getPreferredMessageDigest()
-         throws NoSuchAlgorithmException
-  {
-    return MessageDigest.getInstance(preferredDigestAlgorithm);
-  }
-
-
-
-  /**
-   * Retrieves a <CODE>MessageDigest</CODE> object that may be used to
-   * generate digests using the specified algorithm.
-   *
-   * @param  digestAlgorithm  The algorithm to use to generate the
-   *                          message digest.
-   *
-   * @return  A <CODE>MessageDigest</CODE> object that may be used to
-   *          generate digests using the specified algorithm.
-   *
-   * @throws  NoSuchAlgorithmException  If the requested algorithm is
-   *                                    not supported or is
-   *                                    unavailable.
-   */
-  public MessageDigest getMessageDigest(String digestAlgorithm)
-         throws NoSuchAlgorithmException
-  {
-    return MessageDigest.getInstance(digestAlgorithm);
-  }
-
-
-
-  /**
-   * Retrieves a byte array containing a message digest based on the
-   * provided data, using the preferred digest algorithm.
-   *
-   * @param  data  The data to be digested.
-   *
-   * @return  A byte array containing the generated message digest.
-   *
-   * @throws  NoSuchAlgorithmException  If the requested algorithm is
-   *                                    not supported or is
-   *                                    unavailable.
-   */
-  public byte[] digest(byte[] data)
-         throws NoSuchAlgorithmException
-  {
-    return MessageDigest.getInstance(preferredDigestAlgorithm).
-                digest(data);
-  }
-
-
-
-  /**
-   * Retrieves a byte array containing a message digest based on the
-   * provided data, using the requested digest algorithm.
-   *
-   * @param  digestAlgorithm  The algorithm to use to generate the
-   *                          message digest.
-   * @param  data             The data to be digested.
-   *
-   * @return  A byte array containing the generated message digest.
-   *
-   * @throws  NoSuchAlgorithmException  If the requested algorithm is
-   *                                    not supported or is
-   *                                    unavailable.
-   */
-  public byte[] digest(String digestAlgorithm, byte[] data)
-         throws NoSuchAlgorithmException
-  {
-    return MessageDigest.getInstance(digestAlgorithm).digest(data);
-  }
-
-
-
-  /**
-   * Retrieves a byte array containing a message digest based on the
-   * data read from the provided input stream, using the preferred
-   * digest algorithm.  Data will be read until the end of the stream
-   * is reached.
-   *
-   * @param  inputStream  The input stream from which the data is to
-   *                      be read.
-   *
-   * @return  A byte array containing the generated message digest.
-   *
-   * @throws  IOException  If a problem occurs while reading data from
-   *                       the provided stream.
-   *
-   * @throws  NoSuchAlgorithmException  If the requested algorithm is
-   *                                    not supported or is
-   *                                    unavailable.
-   */
-  public byte[] digest(InputStream inputStream)
-         throws IOException, NoSuchAlgorithmException
-  {
-    MessageDigest digest =
-         MessageDigest.getInstance(preferredDigestAlgorithm);
-
-    byte[] buffer = new byte[8192];
-    while (true)
+    InternalClientConnection internalConnection =
+         InternalClientConnection.getRootConnection();
+    for (String symmetricKey : symmetricKeys)
     {
-      int bytesRead = inputStream.read(buffer);
-      if (bytesRead < 0)
+      try
       {
-        break;
-      }
+        // Get the server instance key ID from the symmetric key.
+        String[] elements = symmetricKey.split(":", 0);
+        String instanceKeyID = elements[0];
 
-      digest.update(buffer, 0, bytesRead);
-    }
+        // Find the server entry from the instance key ID.
+        String filter = "(" +
+             ConfigConstants.ATTR_CRYPTO_KEY_ID + "=" +
+             instanceKeyID + ")";
+        InternalSearchOperation internalSearch =
+             internalConnection.processSearch(
+                  serversDN, SearchScope.SUBORDINATE_SUBTREE,
+                  SearchFilter.createFilterFromString(filter));
+        if (internalSearch.getResultCode() != ResultCode.SUCCESS)
+          continue;
 
-    return digest.digest();
-  }
-
-
-
-  /**
-   * Retrieves a byte array containing a message digest based on the
-   * data read from the provided input stream, using the requested
-   * digest algorithm.  Data will be read until the end of the stream
-   * is reached.
-   *
-   * @param  digestAlgorithm  The algorithm to use to generate the
-   *                          message digest.
-   * @param  inputStream      The input stream from which the data is
-   *                          to be read.
-   *
-   * @return  A byte array containing the generated message digest.
-   *
-   * @throws  IOException  If a problem occurs while reading data from
-   *                       the provided stream.
-   *
-   * @throws  NoSuchAlgorithmException  If the requested algorithm is
-   *                                    not supported or is
-   *                                    unavailable.
-   */
-  public byte[] digest(String digestAlgorithm,
-                       InputStream inputStream)
-         throws IOException, NoSuchAlgorithmException
-  {
-    MessageDigest digest = MessageDigest.getInstance(digestAlgorithm);
-
-    byte[] buffer = new byte[8192];
-    while (true)
-    {
-      int bytesRead = inputStream.read(buffer);
-      if (bytesRead < 0)
-      {
-        break;
-      }
-
-      digest.update(buffer, 0, bytesRead);
-    }
-
-    return digest.digest();
-  }
-
-
-
-  /**
-   * For the current preferred MAC algorithm and key length, return
-   * the identifier of the corresponding key entry. Note: the result
-   * (key identifier) might change across invocations, due to either
-   * of the perferred parameters changing, or because the original
-   * key was marked compromised and a replacement key generated.
-   *
-   * @return A String representation of the identifier of a key entry
-   * corresponding to the preferred MAC algorithm and key length.
-   *
-   * @throws CryptoManagerException In case one or more of the key
-   * parameters is invalid, or there is a problem instantiating the
-   * key entry in case it does not already exist.
-   */
-  public String getMacEngineKeyEntryID()
-          throws CryptoManagerException
-  {
-    return getMacEngineKeyEntryID(preferredMACAlgorithm,
-            preferredMACAlgorithmKeyLengthBits);
-  }
-
-
-  /**
-   * For the specified MAC algorithm and key length, return
-   * the identifier of the corresponding key entry. Note: the result
-   * (key identifier) might change across invocations, due to either
-   * of the perferred parameters changing, or because the original
-   * key was marked compromised and a replacement key generated.
-   *
-   * @param  macAlgorithm  The algorithm to use for the MAC engine.
-   *
-   * @param  keyLengthBits  The key length in bits to use with the
-   *         specified algorithm.
-   *
-   * @return A String representation of the identifier of a key entry
-   * corresponding to the specified MAC algorithm and key length.
-   *
-   * @throws CryptoManagerException In case one or more of the key
-   * parameters is invalid, or there is a problem instantiating the
-   * key entry in case it does not already exist.
-   */
-  public String getMacEngineKeyEntryID(final String macAlgorithm,
-                                       final int keyLengthBits)
-         throws CryptoManagerException {
-    Validator.ensureNotNull(macAlgorithm);
-
-    MacKeyEntry keyEntry = MacKeyEntry.getKeyEntry(this, macAlgorithm,
-                                                   keyLengthBits);
-    if (null == keyEntry) {
-      keyEntry = MacKeyEntry.generateKeyEntry(this, macAlgorithm,
-                                              keyLengthBits);
-    }
-
-    return keyEntry.getKeyID().getStringValue();
-  }
-
-
-  /**
-   * For the specified key entry identifier, instantiate a MAC engine.
-   *
-   * @param keyEntryID The identifier of the key entry containing the
-   * desired MAC algorithm name and key length.
-   *
-   * @return The MAC engine instantiated with the parameters from the
-   * referenced key entry, or null if no such entry exists.
-   *
-   * @throws CryptoManagerException  In case the key entry identifier
-   * is invalid or there is a problem instatiating the MAC engine from
-   * the parameters in the referenced key entry.
-   */
-  public Mac getMacEngine(String keyEntryID)
-          throws CryptoManagerException
-  {
-    final MacKeyEntry keyEntry = MacKeyEntry.getKeyEntry(this,
-            new KeyEntryID(keyEntryID));
-    return (null == keyEntry) ? null : getMacEngine(keyEntry);
-  }
-
-
-  /**
-   * This method produces an initialized MAC engine based on the
-   * supplied MacKeyEntry's state.
-   *
-   * @param keyEntry The MacKeyEntry specifying the Mac properties.
-   *
-   * @return  An initialized Mac object.
-   *
-   * @throws CryptoManagerException  In case there was a error
-   * instantiating the Mac object.
-   */
-  private static Mac getMacEngine(MacKeyEntry keyEntry)
-          throws CryptoManagerException
-  {
-    Mac mac;
-    try {
-      mac = Mac.getInstance(keyEntry.getType());
-    }
-    catch (NoSuchAlgorithmException ex){
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      throw new CryptoManagerException(
-              ERR_CRYPTOMGR_GET_MAC_ENGINE_INVALID_MAC_ALGORITHM.get(
-                      keyEntry.getType(), getExceptionMessage(ex)),
-              ex);
-    }
-
-    try {
-      mac.init(keyEntry.getSecretKey());
-    }
-    catch (InvalidKeyException ex) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      throw new CryptoManagerException(
-           ERR_CRYPTOMGR_GET_MAC_ENGINE_CANNOT_INITIALIZE.get(
-                   getExceptionMessage(ex)), ex);
-    }
-
-    return mac;
-  }
-
-
-  /**
-   * This method produces an initialized Cipher based on the supplied
-   * CipherKeyEntry's state.
-   *
-   * @param keyEntry  The secret key entry containing the cipher
-   * transformation and secret key for which to instantiate
-   * the cipher.
-   *
-   * @param mode  Either Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE.
-   *
-   * @param initializationVector  For Cipher.DECRYPT_MODE, supply
-   * any initialzation vector used in the corresponding encryption
-   * cipher. May be null.
-   *
-   * @return  The initialized cipher object.
-   *
-   * @throws  CryptoManagerException In case of a problem creating
-   * or initializing the requested cipher object. Possible causes
-   * include NoSuchAlgorithmException, NoSuchPaddingException,
-   * InvalidKeyException, and InvalidAlgorithmParameterException.
-   */
-  private static Cipher getCipher(final CipherKeyEntry keyEntry,
-                                  final int mode,
-                                  final byte[] initializationVector)
-          throws CryptoManagerException {
-    Validator.ensureTrue(Cipher.ENCRYPT_MODE == mode
-            || Cipher.DECRYPT_MODE == mode);
-    Validator.ensureTrue(Cipher.ENCRYPT_MODE != mode
-            || null == initializationVector);
-    Validator.ensureTrue(-1 != keyEntry.getIVLengthBits()
-            || Cipher.ENCRYPT_MODE == mode);
-    Validator.ensureTrue(null == initializationVector
-            || initializationVector.length * Byte.SIZE
-                                       == keyEntry.getIVLengthBits());
-
-    Cipher cipher;
-    try {
-      cipher = Cipher.getInstance(keyEntry.getType());
-    }
-    catch (GeneralSecurityException ex) {
-      // NoSuchAlgorithmException, NoSuchPaddingException
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      throw new CryptoManagerException(
-           ERR_CRYPTOMGR_GET_CIPHER_INVALID_CIPHER_TRANSFORMATION.get(
-                   keyEntry.getType(), getExceptionMessage(ex)), ex);
-    }
-
-    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));
-      }
-      else {
-        cipher.init(mode, keyEntry.getSecretKey());
-      }
-    }
-    catch (GeneralSecurityException ex) {
-      // InvalidKeyException, InvalidAlgorithmParameterException
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      throw new CryptoManagerException(
-              ERR_CRYPTOMGR_GET_CIPHER_CANNOT_INITIALIZE.get(
-                      getExceptionMessage(ex)), ex);
-    }
-
-    return cipher;
-  }
-
-
-  /**
-   * Encrypts the data in the provided byte array using the preferred
-   * cipher transformation.
-   *
-   * @param  data  The plain-text data to be encrypted.
-   *
-   * @return  A byte array containing the encrypted representation of
-   *          the provided data.
-   *
-   * @throws  GeneralSecurityException  If a problem occurs while
-   *          encrypting the data.
-   *
-   * @throws  CryptoManagerException  If a problem occurs managing the
-   *          encryption key or producing the cipher.
-   */
-  public byte[] encrypt(byte[] data)
-         throws GeneralSecurityException, CryptoManagerException
-  {
-    return encrypt(preferredCipherTransformation,
-            preferredCipherTransformationKeyLengthBits, data);
-  }
-
-
-  /**
-   * Encrypts the data in the provided byte array using the requested
-   * cipher algorithm.
-   *
-   * @param  cipherTransformation  The algorithm/mode/padding to use
-   *         for the cipher.
-   *
-   * @param  keyLengthBits  The length in bits of the encryption key
-   *         this method is to use. Note the specified key length and
-   *         transformation must be compatible.
-   *
-   * @param  data  The plain-text data to be encrypted.
-   *
-   * @return  A byte array containing the encrypted representation of
-   *          the provided data.
-   *
-   * @throws  GeneralSecurityException  If a problem occurs while
-   *          encrypting the data.
-   *
-   * @throws  CryptoManagerException  If a problem occurs managing the
-   *          encryption key or producing the cipher.
-   */
-  public byte[] encrypt(String cipherTransformation,
-                        int keyLengthBits,
-                        byte[] data)
-         throws GeneralSecurityException, CryptoManagerException
-  {
-    Validator.ensureNotNull(cipherTransformation, data);
-
-    CipherKeyEntry keyEntry = CipherKeyEntry.getKeyEntry(
-            this, cipherTransformation, keyLengthBits);
-    if (null == keyEntry) {
-      keyEntry = CipherKeyEntry.generateKeyEntry(this,
-              cipherTransformation, keyLengthBits);
-    }
-
-    final Cipher cipher
-            = getCipher(keyEntry, Cipher.ENCRYPT_MODE, null);
-
-    final byte[] keyID = keyEntry.getKeyID().getByteValue();
-    final byte[] iv = cipher.getIV();
-    final int prologueLength
-            = keyID.length + ((null == iv) ? 0 : iv.length);
-    final int dataLength = cipher.getOutputSize(data.length);
-    final byte[] cipherText = new byte[prologueLength + dataLength];
-    System.arraycopy(keyID, 0, cipherText, 0, keyID.length);
-    if (null != iv) {
-      System.arraycopy(iv, 0, cipherText, keyID.length, iv.length);
-    }
-    System.arraycopy(cipher.doFinal(data), 0, cipherText,
-                     prologueLength, dataLength);
-    return cipherText;
-  }
-
-
-  /**
-   * Writes encrypted data to the provided output stream using the
-   * preferred cipher transformation.
-   *
-   * @param  outputStream The output stream to be wrapped by the
-   *         returned cipher output stream.
-   *
-   * @return  The output stream wrapped with a CipherOutputStream.
-   *
-   * @throws  CryptoManagerException  If a problem occurs managing the
-   *          encryption key or producing the cipher.
-   */
-  public CipherOutputStream getCipherOutputStream(
-          OutputStream outputStream) throws CryptoManagerException
-  {
-    return getCipherOutputStream(preferredCipherTransformation,
-            preferredCipherTransformationKeyLengthBits, outputStream);
-  }
-
-
-  /**
-   * Writes encrypted data to the provided output stream using the
-   * requested cipher transformation.
-   *
-   * @param  cipherTransformation  The algorithm/mode/padding to use
-   *         for the cipher.
-   *
-   * @param  keyLengthBits  The length in bits of the encryption key
-   *         this method will generate. Note the specified key length
-   *         must be compatible with the transformation.
-   *
-   * @param  outputStream The output stream to be wrapped by the
-   *         returned cipher output stream.
-   *
-   * @return  The output stream wrapped with a CipherOutputStream.
-   *
-   * @throws  CryptoManagerException  If a problem occurs managing the
-   *          encryption key or producing the cipher.
-   */
-  public CipherOutputStream getCipherOutputStream(
-          String cipherTransformation, int keyLengthBits,
-          OutputStream outputStream)
-         throws CryptoManagerException
-  {
-    Validator.ensureNotNull(cipherTransformation, outputStream);
-
-    CipherKeyEntry keyEntry = CipherKeyEntry.getKeyEntry(
-            this, cipherTransformation, keyLengthBits);
-    if (null == keyEntry) {
-      keyEntry = CipherKeyEntry.generateKeyEntry(this,
-              cipherTransformation, keyLengthBits);
-    }
-
-    final Cipher cipher
-            = getCipher(keyEntry, Cipher.ENCRYPT_MODE, null);
-    final byte[] keyID = keyEntry.getKeyID().getByteValue();
-    try {
-      outputStream.write(keyID);
-      if (null != cipher.getIV()) {
-        outputStream.write(cipher.getIV());
-      }
-    }
-    catch (IOException ex) {
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      throw new CryptoManagerException(
-             ERR_CRYPTOMGR_GET_CIPHER_STREAM_PROLOGUE_WRITE_ERROR.get(
-                     getExceptionMessage(ex)), ex);
-    }
-
-    return new CipherOutputStream(outputStream, cipher);
-  }
-
-
-  /**
-   * Decrypts the data in the provided byte array using cipher
-   * specified by the key identifier prologue to the data.
-   * cipher.
-   *
-   * @param  data  The cipher-text data to be decrypted.
-   *
-   * @return  A byte array containing the clear-text representation of
-   *          the provided data.
-   *
-   * @throws  GeneralSecurityException  If a problem occurs while
-   *          encrypting the data.
-   *
-   * @throws  CryptoManagerException  If a problem occurs reading the
-   *          key identifier or initialization vector from the data
-   *          prologue, or using these values to initialize a Cipher.
-   */
-  public byte[] decrypt(byte[] data)
-         throws GeneralSecurityException,
-                CryptoManagerException
-  {
-    KeyEntryID keyID;
-    try {
-      final byte[] keyIDBytes
-              = new byte[KeyEntryID.getByteValueLength()];
-      System.arraycopy(data, 0, keyIDBytes, 0, keyIDBytes.length);
-      keyID = new KeyEntryID(keyIDBytes);
-    }
-    catch (Exception ex) {
-      // IndexOutOfBoundsException, ArrayStoreException, ...
-      if (debugEnabled()) {
-        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-      }
-      throw new CryptoManagerException(
-           ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_KEY_IDENTIFIER.get(),
-              ex);
-    }
-
-    CipherKeyEntry keyEntry = CipherKeyEntry.getKeyEntry(this, keyID);
-    if (null == keyEntry) {
-      throw new CryptoManagerException(
-              ERR_CRYPTOMGR_DECRYPT_UNKNOWN_KEY_IDENTIFIER.get());
-    }
-
-    byte[] iv = null;
-    if (0 < keyEntry.getIVLengthBits()) {
-      iv = new byte[keyEntry.getIVLengthBits()/Byte.SIZE];
-      try {
-        System.arraycopy(data, KeyEntryID.getByteValueLength(), iv, 0,
-                iv.length);
-      }
-      catch (Exception ex) {
-        // IndexOutOfBoundsException, ArrayStoreException, ...
-        if (debugEnabled()) {
-          TRACER.debugCaught(DebugLogLevel.ERROR, ex);
-        }
-        throw new CryptoManagerException(
-               ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_IV.get(), ex);
-      }
-    }
-
-    final Cipher cipher = getCipher(keyEntry, Cipher.DECRYPT_MODE,
-            iv);
-    final int prologueLength = KeyEntryID.getByteValueLength()
-                                     + ((null == iv) ? 0 : iv.length);
-    return cipher.doFinal(data, prologueLength,
-                          data.length - prologueLength);
-  }
-
-
-
-  /**
-   * Returns a CipherInputStream instantiated with a cipher
-   * corresponding to the key identifier prologue to the data.
-   *
-   * @param  inputStream The input stream be wrapped with the
-   *         CipherInputStream.
-   *
-   * @return The CiperInputStream instantiated as specified.
-   *
-   * @throws  CryptoManagerException If there is a problem reading the
-   *          key ID or initialization vector from the input stream,
-   *          or using these values to inititalize a Cipher.
-   */
-  public CipherInputStream getCipherInputStream(
-          InputStream inputStream) throws CryptoManagerException
-  {
-    CipherKeyEntry keyEntry;
-    byte[] iv = null;
-    try {
-      final byte[] keyID = new byte[KeyEntryID.getByteValueLength()];
-      if (keyID.length != inputStream.read(keyID)){
-        throw new CryptoManagerException(
-           ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_KEY_IDENTIFIER.get());
-      }
-      keyEntry = CipherKeyEntry.getKeyEntry(this,
-              new KeyEntryID(keyID));
-      if (null == keyEntry) {
-        throw new CryptoManagerException(
-                ERR_CRYPTOMGR_DECRYPT_UNKNOWN_KEY_IDENTIFIER.get());
-      }
-
-      if (0 < keyEntry.getIVLengthBits()) {
-        iv = new byte[keyEntry.getIVLengthBits() / Byte.SIZE];
-        if (iv.length != inputStream.read(iv)) {
-          throw new CryptoManagerException(
-                  ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_IV.get());
-        }
-      }
-    }
-    catch (IOException ex) {
-      throw new CryptoManagerException(
-             ERR_CRYPTOMGR_DECRYPT_CIPHER_INPUT_STREAM_ERROR.get(
-                     getExceptionMessage(ex)), ex);
-    }
-
-    return new CipherInputStream(inputStream,
-            getCipher(keyEntry, Cipher.DECRYPT_MODE, iv));
-  }
-
-
-  /**
-   * Attempts to compress the data in the provided source array into
-   * the given destination array.  If the compressed data will fit
-   * into the destination array, then this method will return the
-   * number of bytes of compressed data in the array.  Otherwise, it
-   * will return -1 to indicate that the compression was not
-   * successful.  Note that if -1 is returned, then the data in the
-   * destination array should be considered invalid.
-   *
-   * @param  src  The array containing the raw data to compress.
-   * @param  dst  The array into which the compressed data should be
-   *              written.
-   *
-   * @return  The number of bytes of compressed data, or -1 if it was
-   *          not possible to actually compress the data.
-   */
-  public int compress(byte[] src, byte[] dst)
-  {
-    Deflater deflater = new Deflater();
-    try
-    {
-      deflater.setInput(src);
-      deflater.finish();
-
-      int compressedLength = deflater.deflate(dst);
-      if (deflater.finished())
-      {
-        return compressedLength;
-      }
-      else
-      {
-        return -1;
-      }
-    }
-    finally
-    {
-      deflater.end();
-    }
-  }
-
-
-
-  /**
-   * Attempts to uncompress the data in the provided source array into
-   * the given destination array.  If the uncompressed data will fit
-   * into the given destination array, then this method will return
-   * the number of bytes of uncompressed data written into the
-   * destination buffer.  Otherwise, it will return a negative value
-   * to indicate that the destination buffer was not large enough.
-   * The absolute value of that negative return value will indicate
-   * the buffer size required to fully decompress the data.  Note that
-   * if a negative value is returned, then the data in the destination
-   * array should be considered invalid.
-   *
-   * @param  src  The array containing the compressed data.
-   * @param  dst  The array into which the uncompressed data should be
-   *              written.
-   *
-   * @return  A positive value containing the number of bytes of
-   *          uncompressed data written into the destination buffer,
-   *          or a negative value whose absolute value is the size of
-   *          the destination buffer required to fully decompress the
-   *          provided data.
-   *
-   * @throws  DataFormatException  If a problem occurs while
-   *                               attempting to uncompress the data.
-   */
-  public int uncompress(byte[] src, byte[] dst)
-         throws DataFormatException
-  {
-    Inflater inflater = new Inflater();
-    try
-    {
-      inflater.setInput(src);
-
-      int decompressedLength = inflater.inflate(dst);
-      if (inflater.finished())
-      {
-        return decompressedLength;
-      }
-      else
-      {
-        int totalLength = decompressedLength;
-
-        while (! inflater.finished())
+        LinkedList<SearchResultEntry> resultEntries =
+             internalSearch.getSearchEntries();
+        for (SearchResultEntry resultEntry : resultEntries)
         {
-          totalLength += inflater.inflate(dst);
+          AttributeType hostnameAttr =
+               DirectoryServer.getAttributeType("hostname", true);
+          String hostname = resultEntry.getAttributeValue(
+               hostnameAttr, DirectoryStringSyntax.DECODER);
+          AttributeType ldapPortAttr =
+               DirectoryServer.getAttributeType("ldapport", true);
+          Integer ldapPort = resultEntry.getAttributeValue(
+               ldapPortAttr, IntegerSyntax.DECODER);
+
+          // Connect to the server.
+          AtomicInteger nextMessageID = new AtomicInteger(1);
+          LDAPConnectionOptions connectionOptions =
+               new LDAPConnectionOptions();
+          PrintStream nullPrintStream =
+               new PrintStream(new OutputStream() {
+                 public void write ( int b ) { }
+               });
+          LDAPConnection connection =
+               new LDAPConnection(hostname, ldapPort,
+                                  connectionOptions,
+                                  nullPrintStream,
+                                  nullPrintStream);
+
+          connection.connectToHost(null, null, nextMessageID);
+
+          try
+          {
+            LDAPReader reader = connection.getLDAPReader();
+            LDAPWriter writer = connection.getLDAPWriter();
+
+            // Send the Get Symmetric Key extended request.
+
+            ASN1OctetString requestValue =
+                 GetSymmetricKeyExtendedOperation.encodeRequestValue(
+                      symmetricKey, getInstanceKeyID());
+
+            ExtendedRequestProtocolOp extendedRequest =
+                 new ExtendedRequestProtocolOp(
+                      ServerConstants.
+                           OID_GET_SYMMETRIC_KEY_EXTENDED_OP,
+                      requestValue);
+
+            ArrayList<LDAPControl> controls =
+                 new ArrayList<LDAPControl>();
+            LDAPMessage requestMessage =
+                 new LDAPMessage(nextMessageID.getAndIncrement(),
+                                 extendedRequest, controls);
+            writer.writeMessage(requestMessage);
+            LDAPMessage responseMessage = reader.readMessage();
+
+            ExtendedResponseProtocolOp extendedResponse =
+                 responseMessage.getExtendedResponseProtocolOp();
+            if (extendedResponse.getResultCode() ==
+                 LDAPResultCode.SUCCESS)
+            {
+              // Got our symmetric key value.
+              return extendedResponse.getValue().stringValue();
+            }
+          }
+          finally
+          {
+            connection.close(nextMessageID);
+          }
         }
-
-        return -totalLength;
       }
-    }
-    finally
-    {
-      inflater.end();
-    }
-  }
-
-
-  /**
-   * Retrieve the ADS trust store backend.
-   * @return The ADS trust store backend.
-   * @throws ConfigException If the ADS trust store backend is
-   *                         not configured.
-   */
-  private TrustStoreBackend getTrustStoreBackend()
-       throws ConfigException
-  {
-    Backend b = DirectoryServer.getBackend(
-         ConfigConstants.ID_ADS_TRUST_STORE_BACKEND);
-    if (b == null)
-    {
-      Message msg =
-           ERR_CRYPTOMGR_ADS_TRUST_STORE_BACKEND_NOT_ENABLED.get(
-                ConfigConstants.ID_ADS_TRUST_STORE_BACKEND);
-      throw new ConfigException(msg);
-    }
-    if (!(b instanceof TrustStoreBackend))
-    {
-      Message msg =
-           ERR_CRYPTOMGR_ADS_TRUST_STORE_BACKEND_WRONG_CLASS.get(
-                ConfigConstants.ID_ADS_TRUST_STORE_BACKEND);
-      throw new ConfigException(msg);
-    }
-    return (TrustStoreBackend)b;
-  }
-
-  /**
-   * Create an SSL context that may be used for communication to
-   * another ADS component.
-   *
-   * @param sslCertNickname The name of the local certificate to use,
-   *                        or null if none is specified.
-   * @return A new SSL Context.
-   * @throws ConfigException If the context could not be created.
-   */
-  public SSLContext getSslContext(String sslCertNickname)
-       throws ConfigException
-  {
-    SSLContext sslContext;
-    try
-    {
-      TrustStoreBackend trustStoreBackend = getTrustStoreBackend();
-      KeyManager[] keyManagers = trustStoreBackend.getKeyManagers();
-      TrustManager[] trustManagers =
-           trustStoreBackend.getTrustManagers();
-
-      sslContext = SSLContext.getInstance("TLS");
-
-      if (sslCertNickname == null)
+      catch (Exception e)
       {
-        sslContext.init(keyManagers, trustManagers, null);
-      }
-      else
-      {
-        X509ExtendedKeyManager[] extendedKeyManagers =
-             SelectableCertificateKeyManager.wrap(
-                  keyManagers,
-                  sslCertNickname);
-        sslContext.init(extendedKeyManagers, trustManagers, null);
+        // Just try another server.
       }
     }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        TRACER.debugCaught(DebugLogLevel.ERROR, e);
-      }
 
-      Message message =
-           ERR_CRYPTOMGR_SSL_CONTEXT_CANNOT_INITIALIZE.get(
-                getExceptionMessage(e));
-      throw new ConfigException(message, e);
-    }
-
-    return sslContext;
+    // Give up.
+    return null;
   }
 
 
   /**
-   * Get the name of the local certificate to use for SSL.
-   * @return The name of the local certificate to use for SSL.
-   */
-  public String getSslCertNickname()
-  {
-    return sslCertNickname;
-  }
-
-  /**
-   * Determine whether SSL encryption is enabled.
-   * @return true if SSL encryption is enabled.
-   */
-  public boolean isSslEncryption()
-  {
-    return sslEncryption;
-  }
-
-  /**
-   * Get the set of enabled SSL protocols.
-   * @return The set of enabled SSL protocols.
-   */
-  public SortedSet<String> getSslProtocols()
-  {
-    return sslProtocols;
-  }
-
-  /**
-   * Get the set of enabled SSL cipher suites.
-   * @return The set of enabled SSL cipher suites.
-   */
-  public SortedSet<String> getSslCipherSuites()
-  {
-    return sslCipherSuites;
-  }
-
-  /**
    * Imports a cipher key entry from an entry in ADS.
    *
    * @param entry  The ADS cipher key entry to be imported.
@@ -1999,119 +1266,6 @@
     }
   }
 
-  /**
-   * Given a set of other servers' symmetric key values for
-   * a given secret key, use the Get Symmetric Key extended
-   * operation to request this server's symmetric key value.
-   *
-   * @param  symmetricKeys  The known symmetric key values for
-   *                        a given secret key.
-   *
-   * @return The symmetric key value for this server, or null if
-   *         none could be obtained.
-   */
-  private String getSymmetricKey(List<String> symmetricKeys)
-  {
-    InternalClientConnection internalConnection =
-         InternalClientConnection.getRootConnection();
-    for (String symmetricKey : symmetricKeys)
-    {
-      try
-      {
-        // Get the server instance key ID from the symmetric key.
-        String[] elements = symmetricKey.split(":", 0);
-        String instanceKeyID = elements[0];
-
-        // Find the server entry from the instance key ID.
-        String filter = "(" +
-             ConfigConstants.ATTR_CRYPTO_KEY_ID + "=" +
-             instanceKeyID + ")";
-        InternalSearchOperation internalSearch =
-             internalConnection.processSearch(
-                  serversDN, SearchScope.SUBORDINATE_SUBTREE,
-                  SearchFilter.createFilterFromString(filter));
-        if (internalSearch.getResultCode() != ResultCode.SUCCESS)
-          continue;
-
-        LinkedList<SearchResultEntry> resultEntries =
-             internalSearch.getSearchEntries();
-        for (SearchResultEntry resultEntry : resultEntries)
-        {
-          AttributeType hostnameAttr =
-               DirectoryServer.getAttributeType("hostname", true);
-          String hostname = resultEntry.getAttributeValue(
-               hostnameAttr, DirectoryStringSyntax.DECODER);
-          AttributeType ldapPortAttr =
-               DirectoryServer.getAttributeType("ldapport", true);
-          Integer ldapPort = resultEntry.getAttributeValue(
-               ldapPortAttr, IntegerSyntax.DECODER);
-
-          // Connect to the server.
-          AtomicInteger nextMessageID = new AtomicInteger(1);
-          LDAPConnectionOptions connectionOptions =
-               new LDAPConnectionOptions();
-          PrintStream nullPrintStream =
-               new PrintStream(new OutputStream() {
-                 public void write ( int b ) { }
-               });
-          LDAPConnection connection =
-               new LDAPConnection(hostname, ldapPort,
-                                  connectionOptions,
-                                  nullPrintStream,
-                                  nullPrintStream);
-
-          connection.connectToHost(null, null, nextMessageID);
-
-          try
-          {
-            LDAPReader reader = connection.getLDAPReader();
-            LDAPWriter writer = connection.getLDAPWriter();
-
-            // Send the Get Symmetric Key extended request.
-
-            ASN1OctetString requestValue =
-                 GetSymmetricKeyExtendedOperation.encodeRequestValue(
-                      symmetricKey, getInstanceKeyID());
-
-            ExtendedRequestProtocolOp extendedRequest =
-                 new ExtendedRequestProtocolOp(
-                      ServerConstants.
-                           OID_GET_SYMMETRIC_KEY_EXTENDED_OP,
-                      requestValue);
-
-            ArrayList<LDAPControl> controls =
-                 new ArrayList<LDAPControl>();
-            LDAPMessage requestMessage =
-                 new LDAPMessage(nextMessageID.getAndIncrement(),
-                                 extendedRequest, controls);
-            writer.writeMessage(requestMessage);
-            LDAPMessage responseMessage = reader.readMessage();
-
-            ExtendedResponseProtocolOp extendedResponse =
-                 responseMessage.getExtendedResponseProtocolOp();
-            if (extendedResponse.getResultCode() ==
-                 LDAPResultCode.SUCCESS)
-            {
-              // Got our symmetric key value.
-              return extendedResponse.getValue().stringValue();
-            }
-          }
-          finally
-          {
-            connection.close(nextMessageID);
-          }
-        }
-      }
-      catch (Exception e)
-      {
-        // Just try another server.
-      }
-    }
-
-    // Give up.
-    return null;
-  }
-
 
   /**
    * Imports a mac key entry from an entry in ADS.
@@ -2219,6 +1373,7 @@
     }
   }
 
+
   /**
    * This class implements a utility interface to the unique
    * identifier corresponding to a cryptographic key. For each key
@@ -2517,10 +1672,10 @@
      * instantiating a Cipher object in order to validate the supplied
      * parameters when creating a new entry.
      *
-     * @see CipherKeyEntry#getKeyEntry(CryptoManager, String, int)
+     * @see CipherKeyEntry#getKeyEntry(CryptoManagerImpl, String, int)
      */
     public static CipherKeyEntry generateKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final String transformation,
             final int keyLengthBits)
     throws CryptoManagerException {
@@ -2563,7 +1718,7 @@
      *                       If the key entry could not be added to
      *                       ADS.
      */
-    private static void publishKeyEntry(CryptoManager cryptoManager,
+    private static void publishKeyEntry(CryptoManagerImpl cryptoManager,
                                         CipherKeyEntry keyEntry)
          throws CryptoManagerException
     {
@@ -2644,7 +1799,7 @@
 
       // Need to add our own instance certificate.
       byte[] instanceKeyCertificate =
-         CryptoManager.getInstanceKeyCertificateFromLocalTruststore();
+         CryptoManagerImpl.getInstanceKeyCertificateFromLocalTruststore();
       trustedCerts.put(getInstanceKeyID(instanceKeyCertificate),
                        instanceKeyCertificate);
 
@@ -2720,7 +1875,7 @@
      * parameters used to initialize or validate the key entry.
      */
     public static CipherKeyEntry importCipherKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final String keyIDString,
             final String transformation,
             final SecretKey secretKey,
@@ -2791,7 +1946,7 @@
      * {@code null} if no such entry exists.
      */
     public static CipherKeyEntry getKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final String transformation,
             final int keyLengthBits) {
       Validator.ensureNotNull(cryptoManager, transformation);
@@ -2838,12 +1993,12 @@
      * @return  The key entry associated with the key identifier, or
      * {@code null} if no such entry exists.
      *
-     * @see org.opends.server.crypto.CryptoManager.MacKeyEntry
+     * @see CryptoManagerImpl.MacKeyEntry
      *  #getKeyEntry(org.opends.server.types.CryptoManager,
      *               java.lang.String, int)
      */
     public static CipherKeyEntry getKeyEntry(
-            CryptoManager cryptoManager,
+            CryptoManagerImpl cryptoManager,
             final KeyEntryID keyID) {
       return cryptoManager.cipherKeyEntryCache.get(keyID);
     }
@@ -2983,6 +2138,86 @@
   }
 
 
+  /**
+   * This method produces an initialized Cipher based on the supplied
+   * CipherKeyEntry's state.
+   *
+   * @param keyEntry  The secret key entry containing the cipher
+   * transformation and secret key for which to instantiate
+   * the cipher.
+   *
+   * @param mode  Either Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE.
+   *
+   * @param initializationVector  For Cipher.DECRYPT_MODE, supply
+   * any initialzation vector used in the corresponding encryption
+   * cipher. May be null.
+   *
+   * @return  The initialized cipher object.
+   *
+   * @throws  CryptoManagerException In case of a problem creating
+   * or initializing the requested cipher object. Possible causes
+   * include NoSuchAlgorithmException, NoSuchPaddingException,
+   * InvalidKeyException, and InvalidAlgorithmParameterException.
+   */
+  private static Cipher getCipher(final CipherKeyEntry keyEntry,
+                                  final int mode,
+                                  final byte[] initializationVector)
+          throws CryptoManagerException {
+    Validator.ensureTrue(Cipher.ENCRYPT_MODE == mode
+            || Cipher.DECRYPT_MODE == mode);
+    Validator.ensureTrue(Cipher.ENCRYPT_MODE != mode
+            || null == initializationVector);
+    Validator.ensureTrue(-1 != keyEntry.getIVLengthBits()
+            || Cipher.ENCRYPT_MODE == mode);
+    Validator.ensureTrue(null == initializationVector
+            || initializationVector.length * Byte.SIZE
+                                       == keyEntry.getIVLengthBits());
+
+    Cipher cipher;
+    try {
+      cipher = Cipher.getInstance(keyEntry.getType());
+    }
+    catch (GeneralSecurityException ex) {
+      // NoSuchAlgorithmException, NoSuchPaddingException
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      throw new CryptoManagerException(
+           ERR_CRYPTOMGR_GET_CIPHER_INVALID_CIPHER_TRANSFORMATION.get(
+                   keyEntry.getType(), getExceptionMessage(ex)), ex);
+    }
+
+    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));
+      }
+      else {
+        cipher.init(mode, keyEntry.getSecretKey());
+      }
+    }
+    catch (GeneralSecurityException ex) {
+      // InvalidKeyException, InvalidAlgorithmParameterException
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      throw new CryptoManagerException(
+              ERR_CRYPTOMGR_GET_CIPHER_CANNOT_INITIALIZE.get(
+                      getExceptionMessage(ex)), ex);
+    }
+
+    return cipher;
+  }
+
 
   /**
    * This class corresponds to the MAC key entry in ADS. It is
@@ -3014,10 +2249,10 @@
      * instantiating a Mac object in order to validate the supplied
      * parameters when creating a new entry.
      *
-     * @see MacKeyEntry#getKeyEntry(CryptoManager, String, int)
+     * @see MacKeyEntry#getKeyEntry(CryptoManagerImpl, String, int)
      */
     public static MacKeyEntry generateKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final String algorithm,
             final int keyLengthBits)
     throws CryptoManagerException {
@@ -3056,7 +2291,7 @@
      *                       If the key entry could not be added to
      *                       ADS.
      */
-    private static void publishKeyEntry(CryptoManager cryptoManager,
+    private static void publishKeyEntry(CryptoManagerImpl cryptoManager,
                                         MacKeyEntry keyEntry)
          throws CryptoManagerException
     {
@@ -3123,7 +2358,7 @@
 
       // Need to add our own instance certificate.
       byte[] instanceKeyCertificate =
-         CryptoManager.getInstanceKeyCertificateFromLocalTruststore();
+         CryptoManagerImpl.getInstanceKeyCertificateFromLocalTruststore();
       trustedCerts.put(getInstanceKeyID(instanceKeyCertificate),
                        instanceKeyCertificate);
 
@@ -3193,7 +2428,7 @@
      * parameters used to initialize or validate the key entry.
      */
     public static MacKeyEntry importMacKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final String keyIDString,
             final String algorithm,
             final SecretKey secretKey,
@@ -3257,7 +2492,7 @@
      * {@code null} if no such entry exists.
      */
     public static MacKeyEntry getKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final String algorithm,
             final int keyLengthBits) {
       Validator.ensureNotNull(cryptoManager, algorithm);
@@ -3304,12 +2539,12 @@
      * @return  The key entry associated with the key identifier, or
      * {@code null} if no such entry exists.
      *
-     * @see org.opends.server.crypto.CryptoManager.CipherKeyEntry
+     * @see CryptoManagerImpl.CipherKeyEntry
      *     #getKeyEntry(org.opends.server.types.CryptoManager,
      *                  java.lang.String, int)
      */
     public static MacKeyEntry getKeyEntry(
-            final CryptoManager cryptoManager,
+            final CryptoManagerImpl cryptoManager,
             final KeyEntryID keyID) {
       return cryptoManager.macKeyEntryCache.get(keyID);
     }
@@ -3379,8 +2614,482 @@
       return fType;
     }
 
-
     // state
     private final String fType;
   }
+
+
+  /**
+   * This method produces an initialized MAC engine based on the
+   * supplied MacKeyEntry's state.
+   *
+   * @param keyEntry The MacKeyEntry specifying the Mac properties.
+   *
+   * @return  An initialized Mac object.
+   *
+   * @throws CryptoManagerException  In case there was a error
+   * instantiating the Mac object.
+   */
+  private static Mac getMacEngine(MacKeyEntry keyEntry)
+          throws CryptoManagerException
+  {
+    Mac mac;
+    try {
+      mac = Mac.getInstance(keyEntry.getType());
+    }
+    catch (NoSuchAlgorithmException ex){
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      throw new CryptoManagerException(
+              ERR_CRYPTOMGR_GET_MAC_ENGINE_INVALID_MAC_ALGORITHM.get(
+                      keyEntry.getType(), getExceptionMessage(ex)),
+              ex);
+    }
+
+    try {
+      mac.init(keyEntry.getSecretKey());
+    }
+    catch (InvalidKeyException ex) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      throw new CryptoManagerException(
+           ERR_CRYPTOMGR_GET_MAC_ENGINE_CANNOT_INITIALIZE.get(
+                   getExceptionMessage(ex)), ex);
+    }
+
+    return mac;
+  }
+
+
+  /** {@inheritDoc} */
+  public String getPreferredMessageDigestAlgorithm()
+  {
+    return preferredDigestAlgorithm;
+  }
+
+
+  /** {@inheritDoc} */
+  public MessageDigest getPreferredMessageDigest()
+         throws NoSuchAlgorithmException
+  {
+    return MessageDigest.getInstance(preferredDigestAlgorithm);
+  }
+
+
+  /** {@inheritDoc} */
+  public MessageDigest getMessageDigest(String digestAlgorithm)
+         throws NoSuchAlgorithmException
+  {
+    return MessageDigest.getInstance(digestAlgorithm);
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] digest(byte[] data)
+         throws NoSuchAlgorithmException
+  {
+    return MessageDigest.getInstance(preferredDigestAlgorithm).
+                digest(data);
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] digest(String digestAlgorithm, byte[] data)
+         throws NoSuchAlgorithmException
+  {
+    return MessageDigest.getInstance(digestAlgorithm).digest(data);
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] digest(InputStream inputStream)
+         throws IOException, NoSuchAlgorithmException
+  {
+    MessageDigest digest =
+         MessageDigest.getInstance(preferredDigestAlgorithm);
+
+    byte[] buffer = new byte[8192];
+    while (true)
+    {
+      int bytesRead = inputStream.read(buffer);
+      if (bytesRead < 0)
+      {
+        break;
+      }
+
+      digest.update(buffer, 0, bytesRead);
+    }
+
+    return digest.digest();
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] digest(String digestAlgorithm,
+                       InputStream inputStream)
+         throws IOException, NoSuchAlgorithmException
+  {
+    MessageDigest digest = MessageDigest.getInstance(digestAlgorithm);
+
+    byte[] buffer = new byte[8192];
+    while (true)
+    {
+      int bytesRead = inputStream.read(buffer);
+      if (bytesRead < 0)
+      {
+        break;
+      }
+
+      digest.update(buffer, 0, bytesRead);
+    }
+
+    return digest.digest();
+  }
+
+
+  /** {@inheritDoc} */
+  public String getMacEngineKeyEntryID()
+          throws CryptoManagerException
+  {
+    return getMacEngineKeyEntryID(preferredMACAlgorithm,
+            preferredMACAlgorithmKeyLengthBits);
+  }
+
+
+  /** {@inheritDoc} */
+  public String getMacEngineKeyEntryID(final String macAlgorithm,
+                                       final int keyLengthBits)
+         throws CryptoManagerException {
+    Validator.ensureNotNull(macAlgorithm);
+
+    MacKeyEntry keyEntry = MacKeyEntry.getKeyEntry(this, macAlgorithm,
+                                                   keyLengthBits);
+    if (null == keyEntry) {
+      keyEntry = MacKeyEntry.generateKeyEntry(this, macAlgorithm,
+                                              keyLengthBits);
+    }
+
+    return keyEntry.getKeyID().getStringValue();
+  }
+
+
+  /** {@inheritDoc} */
+  public Mac getMacEngine(String keyEntryID)
+          throws CryptoManagerException
+  {
+    final MacKeyEntry keyEntry = MacKeyEntry.getKeyEntry(this,
+            new KeyEntryID(keyEntryID));
+    return (null == keyEntry) ? null : getMacEngine(keyEntry);
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] encrypt(byte[] data)
+         throws GeneralSecurityException, CryptoManagerException
+  {
+    return encrypt(preferredCipherTransformation,
+            preferredCipherTransformationKeyLengthBits, data);
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] encrypt(String cipherTransformation,
+                        int keyLengthBits,
+                        byte[] data)
+         throws GeneralSecurityException, CryptoManagerException
+  {
+    Validator.ensureNotNull(cipherTransformation, data);
+
+    CipherKeyEntry keyEntry = CipherKeyEntry.getKeyEntry(
+            this, cipherTransformation, keyLengthBits);
+    if (null == keyEntry) {
+      keyEntry = CipherKeyEntry.generateKeyEntry(this,
+              cipherTransformation, keyLengthBits);
+    }
+
+    final Cipher cipher
+            = getCipher(keyEntry, Cipher.ENCRYPT_MODE, null);
+
+    final byte[] keyID = keyEntry.getKeyID().getByteValue();
+    final byte[] iv = cipher.getIV();
+    final int prologueLength
+            = keyID.length + ((null == iv) ? 0 : iv.length);
+    final int dataLength = cipher.getOutputSize(data.length);
+    final byte[] cipherText = new byte[prologueLength + dataLength];
+    System.arraycopy(keyID, 0, cipherText, 0, keyID.length);
+    if (null != iv) {
+      System.arraycopy(iv, 0, cipherText, keyID.length, iv.length);
+    }
+    System.arraycopy(cipher.doFinal(data), 0, cipherText,
+                     prologueLength, dataLength);
+    return cipherText;
+  }
+
+
+  /** {@inheritDoc} */
+  public CipherOutputStream getCipherOutputStream(
+          OutputStream outputStream) throws CryptoManagerException
+  {
+    return getCipherOutputStream(preferredCipherTransformation,
+            preferredCipherTransformationKeyLengthBits, outputStream);
+  }
+
+
+  /** {@inheritDoc} */
+  public CipherOutputStream getCipherOutputStream(
+          String cipherTransformation, int keyLengthBits,
+          OutputStream outputStream)
+         throws CryptoManagerException
+  {
+    Validator.ensureNotNull(cipherTransformation, outputStream);
+
+    CipherKeyEntry keyEntry = CipherKeyEntry.getKeyEntry(
+            this, cipherTransformation, keyLengthBits);
+    if (null == keyEntry) {
+      keyEntry = CipherKeyEntry.generateKeyEntry(this,
+              cipherTransformation, keyLengthBits);
+    }
+
+    final Cipher cipher
+            = getCipher(keyEntry, Cipher.ENCRYPT_MODE, null);
+    final byte[] keyID = keyEntry.getKeyID().getByteValue();
+    try {
+      outputStream.write(keyID);
+      if (null != cipher.getIV()) {
+        outputStream.write(cipher.getIV());
+      }
+    }
+    catch (IOException ex) {
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      throw new CryptoManagerException(
+             ERR_CRYPTOMGR_GET_CIPHER_STREAM_PROLOGUE_WRITE_ERROR.get(
+                     getExceptionMessage(ex)), ex);
+    }
+
+    return new CipherOutputStream(outputStream, cipher);
+  }
+
+
+  /** {@inheritDoc} */
+  public byte[] decrypt(byte[] data)
+         throws GeneralSecurityException,
+                CryptoManagerException
+  {
+    KeyEntryID keyID;
+    try {
+      final byte[] keyIDBytes
+              = new byte[KeyEntryID.getByteValueLength()];
+      System.arraycopy(data, 0, keyIDBytes, 0, keyIDBytes.length);
+      keyID = new KeyEntryID(keyIDBytes);
+    }
+    catch (Exception ex) {
+      // IndexOutOfBoundsException, ArrayStoreException, ...
+      if (debugEnabled()) {
+        TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+      }
+      throw new CryptoManagerException(
+           ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_KEY_IDENTIFIER.get(),
+              ex);
+    }
+
+    CipherKeyEntry keyEntry = CipherKeyEntry.getKeyEntry(this, keyID);
+    if (null == keyEntry) {
+      throw new CryptoManagerException(
+              ERR_CRYPTOMGR_DECRYPT_UNKNOWN_KEY_IDENTIFIER.get());
+    }
+
+    byte[] iv = null;
+    if (0 < keyEntry.getIVLengthBits()) {
+      iv = new byte[keyEntry.getIVLengthBits()/Byte.SIZE];
+      try {
+        System.arraycopy(data, KeyEntryID.getByteValueLength(), iv, 0,
+                iv.length);
+      }
+      catch (Exception ex) {
+        // IndexOutOfBoundsException, ArrayStoreException, ...
+        if (debugEnabled()) {
+          TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+        }
+        throw new CryptoManagerException(
+               ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_IV.get(), ex);
+      }
+    }
+
+    final Cipher cipher = getCipher(keyEntry, Cipher.DECRYPT_MODE,
+            iv);
+    final int prologueLength = KeyEntryID.getByteValueLength()
+                                     + ((null == iv) ? 0 : iv.length);
+    return cipher.doFinal(data, prologueLength,
+                          data.length - prologueLength);
+  }
+
+
+ /** {@inheritDoc} */
+  public CipherInputStream getCipherInputStream(
+          InputStream inputStream) throws CryptoManagerException
+  {
+    CipherKeyEntry keyEntry;
+    byte[] iv = null;
+    try {
+      final byte[] keyID = new byte[KeyEntryID.getByteValueLength()];
+      if (keyID.length != inputStream.read(keyID)){
+        throw new CryptoManagerException(
+           ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_KEY_IDENTIFIER.get());
+      }
+      keyEntry = CipherKeyEntry.getKeyEntry(this,
+              new KeyEntryID(keyID));
+      if (null == keyEntry) {
+        throw new CryptoManagerException(
+                ERR_CRYPTOMGR_DECRYPT_UNKNOWN_KEY_IDENTIFIER.get());
+      }
+
+      if (0 < keyEntry.getIVLengthBits()) {
+        iv = new byte[keyEntry.getIVLengthBits() / Byte.SIZE];
+        if (iv.length != inputStream.read(iv)) {
+          throw new CryptoManagerException(
+                  ERR_CRYPTOMGR_DECRYPT_FAILED_TO_READ_IV.get());
+        }
+      }
+    }
+    catch (IOException ex) {
+      throw new CryptoManagerException(
+             ERR_CRYPTOMGR_DECRYPT_CIPHER_INPUT_STREAM_ERROR.get(
+                     getExceptionMessage(ex)), ex);
+    }
+
+    return new CipherInputStream(inputStream,
+            getCipher(keyEntry, Cipher.DECRYPT_MODE, iv));
+  }
+
+
+  /** {@inheritDoc} */
+  public int compress(byte[] src, byte[] dst)
+  {
+    Deflater deflater = new Deflater();
+    try
+    {
+      deflater.setInput(src);
+      deflater.finish();
+
+      int compressedLength = deflater.deflate(dst);
+      if (deflater.finished())
+      {
+        return compressedLength;
+      }
+      else
+      {
+        return -1;
+      }
+    }
+    finally
+    {
+      deflater.end();
+    }
+  }
+
+
+  /** {@inheritDoc} */
+  public int uncompress(byte[] src, byte[] dst)
+         throws DataFormatException
+  {
+    Inflater inflater = new Inflater();
+    try
+    {
+      inflater.setInput(src);
+
+      int decompressedLength = inflater.inflate(dst);
+      if (inflater.finished())
+      {
+        return decompressedLength;
+      }
+      else
+      {
+        int totalLength = decompressedLength;
+
+        while (! inflater.finished())
+        {
+          totalLength += inflater.inflate(dst);
+        }
+
+        return -totalLength;
+      }
+    }
+    finally
+    {
+      inflater.end();
+    }
+  }
+
+
+  /** {@inheritDoc} */
+  public SSLContext getSslContext(String sslCertNickname)
+       throws ConfigException
+  {
+    SSLContext sslContext;
+    try
+    {
+      TrustStoreBackend trustStoreBackend = getTrustStoreBackend();
+      KeyManager[] keyManagers = trustStoreBackend.getKeyManagers();
+      TrustManager[] trustManagers =
+           trustStoreBackend.getTrustManagers();
+
+      sslContext = SSLContext.getInstance("TLS");
+
+      if (sslCertNickname == null)
+      {
+        sslContext.init(keyManagers, trustManagers, null);
+      }
+      else
+      {
+        X509ExtendedKeyManager[] extendedKeyManagers =
+             SelectableCertificateKeyManager.wrap(
+                  keyManagers,
+                  sslCertNickname);
+        sslContext.init(extendedKeyManagers, trustManagers, null);
+      }
+    }
+    catch (Exception e)
+    {
+      if (debugEnabled())
+      {
+        TRACER.debugCaught(DebugLogLevel.ERROR, e);
+      }
+
+      Message message =
+           ERR_CRYPTOMGR_SSL_CONTEXT_CANNOT_INITIALIZE.get(
+                getExceptionMessage(e));
+      throw new ConfigException(message, e);
+    }
+
+    return sslContext;
+  }
+
+
+  /** {@inheritDoc} */
+  public String getSslCertNickname()
+  {
+    return sslCertNickname;
+  }
+
+  /** {@inheritDoc} */
+  public boolean isSslEncryption()
+  {
+    return sslEncryption;
+  }
+
+  /** {@inheritDoc} */
+  public SortedSet<String> getSslProtocols()
+  {
+    return sslProtocols;
+  }
+
+  /** {@inheritDoc} */
+  public SortedSet<String> getSslCipherSuites()
+  {
+    return sslCipherSuites;
+  }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerSync.java b/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerSync.java
index 728718d..cb9a1ca 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerSync.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/crypto/CryptoManagerSync.java
@@ -123,7 +123,7 @@
           throws InitializationException
   {
     try {
-      CryptoManager.publishInstanceKeyEntryInADS();
+      CryptoManagerImpl.publishInstanceKeyEntryInADS();
     }
     catch (CryptoManagerException ex) {
       throw new InitializationException(ex.getMessageObject());
diff --git a/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java b/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java
index 412be12..d98dd77 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperation.java
@@ -218,7 +218,7 @@
       return;
     }
 
-    CryptoManager cm = DirectoryServer.getCryptoManager();
+    CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
     try
     {
       String responseSymmetricKey = cm.reencodeSymmetricKeyAttribute(
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
index 0220c25..0c6ce60 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
@@ -36,13 +36,7 @@
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ByteStringFactory;
-import org.opends.server.crypto.CryptoManager;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.util.Base64;
 
 import static org.opends.messages.ExtensionMessages.*;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
index 4b84b6f..2d4907e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
@@ -36,13 +36,7 @@
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ByteStringFactory;
-import org.opends.server.crypto.CryptoManager;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.util.Base64;
 
 import static org.opends.messages.ExtensionMessages.*;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
index a0831aa..61b6b32 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/ConfigFileHandler.java
@@ -76,30 +76,7 @@
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.schema.GeneralizedTimeSyntax;
 import org.opends.server.tools.LDIFModify;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.BackupConfig;
-import org.opends.server.types.BackupDirectory;
-import org.opends.server.types.BackupInfo;
-import org.opends.server.types.ConditionResult;
-import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.crypto.CryptoManager;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryEnvironmentConfig;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DN;
-import org.opends.server.types.Entry;
-import org.opends.server.types.ExistingFileBehavior;
-import org.opends.server.types.IndexType;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.LDIFExportConfig;
-import org.opends.server.types.LDIFImportConfig;
-import org.opends.server.types.LDIFImportResult;
-import org.opends.server.types.Modification;
-import org.opends.server.types.Privilege;
-import org.opends.server.types.RestoreConfig;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.SearchScope;
+import org.opends.server.types.*;
 import org.opends.server.util.DynamicConstants;
 import org.opends.server.util.LDIFException;
 import org.opends.server.util.LDIFReader;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
index 730f73a..5ea3d19 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
@@ -36,13 +36,7 @@
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ByteStringFactory;
-import org.opends.server.crypto.CryptoManager;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.util.Base64;
 
 import static org.opends.messages.ExtensionMessages.*;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
index b7b1761..ff9c5ad 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
@@ -36,13 +36,7 @@
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ByteStringFactory;
-import org.opends.server.crypto.CryptoManager;
-import org.opends.server.types.DebugLogLevel;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.InitializationException;
-import org.opends.server.types.ResultCode;
+import org.opends.server.types.*;
 import org.opends.server.util.Base64;
 
 import static org.opends.messages.ExtensionMessages.*;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplSessionSecurity.java b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplSessionSecurity.java
index 2a4d2e8..1133867 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplSessionSecurity.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplSessionSecurity.java
@@ -30,7 +30,7 @@
 import org.opends.server.admin.std.server.ReplicationServerCfg;
 import org.opends.server.admin.std.server.ReplicationDomainCfg;
 import org.opends.server.types.DirectoryConfig;
-import org.opends.server.crypto.CryptoManager;
+import org.opends.server.types.CryptoManager;
 import org.opends.server.config.ConfigException;
 
 import javax.net.ssl.SSLSocket;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java b/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java
new file mode 100644
index 0000000..f63936a
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManager.java
@@ -0,0 +1,423 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.types;
+
+import org.opends.server.config.ConfigException;
+
+import javax.crypto.Mac;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.CipherInputStream;
+import javax.net.ssl.SSLContext;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.GeneralSecurityException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.DataFormatException;
+import java.util.SortedSet;
+
+/**
+ This interface defines the methods to call to access cryptographic
+ services including encryption and hashing; in particular, when the
+ ciphertext or HMAC is produced on one directory server instance and
+ is to be consumed on another.
+ */
+@org.opends.server.types.PublicAPI(
+     stability=org.opends.server.types.StabilityLevel.VOLATILE,
+     mayInstantiate=false,
+     mayExtend=false,
+     mayInvoke=true)public interface CryptoManager {
+  /**
+   * Retrieves the name of the preferred message digest algorithm.
+   *
+   * @return  The name of the preferred message digest algorithm
+   */
+  String getPreferredMessageDigestAlgorithm();
+
+  /**
+   * Retrieves a <CODE>MessageDigest</CODE> object that may be used to
+   * generate digests using the preferred digest algorithm.
+   *
+   * @return  A <CODE>MessageDigest</CODE> object that may be used to
+   *          generate digests using the preferred digest algorithm.
+   *
+   * @throws java.security.NoSuchAlgorithmException  If the requested
+   * algorithm is not supported or is unavailable.
+   */
+  MessageDigest getPreferredMessageDigest()
+         throws NoSuchAlgorithmException;
+
+  /**
+   * Retrieves a <CODE>MessageDigest</CODE> object that may be used to
+   * generate digests using the specified algorithm.
+   *
+   * @param  digestAlgorithm  The algorithm to use to generate the
+   *                          message digest.
+   *
+   * @return  A <CODE>MessageDigest</CODE> object that may be used to
+   *          generate digests using the specified algorithm.
+   *
+   * @throws  java.security.NoSuchAlgorithmException  If the requested
+   * algorithm is not supported or is unavailable.
+   */
+  MessageDigest getMessageDigest(String digestAlgorithm)
+         throws NoSuchAlgorithmException;
+
+  /**
+   * Retrieves a byte array containing a message digest based on the
+   * provided data, using the preferred digest algorithm.
+   *
+   * @param  data  The data to be digested.
+   *
+   * @return  A byte array containing the generated message digest.
+   *
+   * @throws  java.security.NoSuchAlgorithmException  If the requested
+   * algorithm is not supported or is unavailable.
+   */
+  byte[] digest(byte[] data)
+         throws NoSuchAlgorithmException;
+
+  /**
+   * Retrieves a byte array containing a message digest based on the
+   * provided data, using the requested digest algorithm.
+   *
+   * @param  digestAlgorithm  The algorithm to use to generate the
+   *                          message digest.
+   * @param  data             The data to be digested.
+   *
+   * @return  A byte array containing the generated message digest.
+   *
+   * @throws  java.security.NoSuchAlgorithmException  If the requested
+   * algorithm is not supported or is unavailable.
+   */
+  byte[] digest(String digestAlgorithm, byte[] data)
+         throws NoSuchAlgorithmException;
+
+  /**
+   * Retrieves a byte array containing a message digest based on the
+   * data read from the provided input stream, using the preferred
+   * digest algorithm.  Data will be read until the end of the stream
+   * is reached.
+   *
+   * @param  inputStream  The input stream from which the data is to
+   *                      be read.
+   *
+   * @return  A byte array containing the generated message digest.
+   *
+   * @throws java.io.IOException  If a problem occurs while reading
+   * data from the provided stream.
+   *
+   * @throws  java.security.NoSuchAlgorithmException  If the requested
+   * algorithm is not supported or is unavailable.
+   */
+  byte[] digest(InputStream inputStream)
+         throws IOException, NoSuchAlgorithmException;
+
+  /**
+   * Retrieves a byte array containing a message digest based on the
+   * data read from the provided input stream, using the requested
+   * digest algorithm.  Data will be read until the end of the stream
+   * is reached.
+   *
+   * @param  digestAlgorithm  The algorithm to use to generate the
+   *                          message digest.
+   * @param  inputStream      The input stream from which the data is
+   *                          to be read.
+   *
+   * @return  A byte array containing the generated message digest.
+   *
+   * @throws  java.io.IOException  If a problem occurs while reading
+   * data from the provided stream.
+   *
+   * @throws  java.security.NoSuchAlgorithmException  If the requested
+   * algorithm is not supported or is unavailable.
+   */
+  byte[] digest(String digestAlgorithm,
+                       InputStream inputStream)
+         throws IOException, NoSuchAlgorithmException;
+
+  /**
+   * For the current preferred MAC algorithm and key length, return
+   * the identifier of the corresponding key entry. Note: the result
+   * (key identifier) might change across invocations, due to either
+   * of the perferred parameters changing, or because the original
+   * key was marked compromised and a replacement key generated.
+   *
+   * @return A String representation of the identifier of a key entry
+   * corresponding to the preferred MAC algorithm and key length.
+   *
+   * @throws CryptoManagerException In case one or more of the key
+   * parameters is invalid, or there is a problem instantiating the
+   * key entry in case it does not already exist.
+   */
+  String getMacEngineKeyEntryID()
+          throws CryptoManagerException;
+
+  /**
+   * For the specified MAC algorithm and key length, return
+   * the identifier of the corresponding key entry. Note: the result
+   * (key identifier) might change across invocations, due to either
+   * of the perferred parameters changing, or because the original
+   * key was marked compromised and a replacement key generated.
+   *
+   * @param  macAlgorithm  The algorithm to use for the MAC engine.
+   *
+   * @param  keyLengthBits  The key length in bits to use with the
+   *         specified algorithm.
+   *
+   * @return A String representation of the identifier of a key entry
+   * corresponding to the specified MAC algorithm and key length.
+   *
+   * @throws CryptoManagerException In case one or more of the key
+   * parameters is invalid, or there is a problem instantiating the
+   * key entry in case it does not already exist.
+   */
+  String getMacEngineKeyEntryID(String macAlgorithm,
+                                       int keyLengthBits)
+         throws CryptoManagerException;
+
+  /**
+   * For the specified key entry identifier, instantiate a MAC engine.
+   *
+   * @param keyEntryID The identifier of the key entry containing the
+   * desired MAC algorithm name and key length.
+   *
+   * @return The MAC engine instantiated with the parameters from the
+   * referenced key entry, or null if no such entry exists.
+   *
+   * @throws CryptoManagerException  In case the key entry identifier
+   * is invalid or there is a problem instantiating the MAC engine
+   * from the parameters in the referenced key entry.
+   */
+  Mac getMacEngine(String keyEntryID)
+          throws CryptoManagerException;
+
+  /**
+   * Encrypts the data in the provided byte array using the preferred
+   * cipher transformation.
+   *
+   * @param  data  The plain-text data to be encrypted.
+   *
+   * @return  A byte array containing the encrypted representation of
+   *          the provided data.
+   *
+   * @throws java.security.GeneralSecurityException  If a problem
+   * occurs while encrypting the data.
+   *
+   * @throws  CryptoManagerException  If a problem occurs managing the
+   *          encryption key or producing the cipher.
+   */
+  byte[] encrypt(byte[] data)
+         throws GeneralSecurityException, CryptoManagerException;
+
+  /**
+   * Encrypts the data in the provided byte array using the requested
+   * cipher algorithm.
+   *
+   * @param  cipherTransformation  The algorithm/mode/padding to use
+   *         for the cipher.
+   *
+   * @param  keyLengthBits  The length in bits of the encryption key
+   *         this method is to use. Note the specified key length and
+   *         transformation must be compatible.
+   *
+   * @param  data  The plain-text data to be encrypted.
+   *
+   * @return  A byte array containing the encrypted representation of
+   *          the provided data.
+   *
+   * @throws  java.security.GeneralSecurityException  If a problem
+   * occurs while encrypting the data.
+   *
+   * @throws  CryptoManagerException  If a problem occurs managing the
+   *          encryption key or producing the cipher.
+   */
+  byte[] encrypt(String cipherTransformation,
+                        int keyLengthBits,
+                        byte[] data)
+         throws GeneralSecurityException, CryptoManagerException;
+
+  /**
+   * Writes encrypted data to the provided output stream using the
+   * preferred cipher transformation.
+   *
+   * @param  outputStream The output stream to be wrapped by the
+   *         returned cipher output stream.
+   *
+   * @return  The output stream wrapped with a CipherOutputStream.
+   *
+   * @throws  CryptoManagerException  If a problem occurs managing the
+   *          encryption key or producing the cipher.
+   */
+  CipherOutputStream getCipherOutputStream(
+          OutputStream outputStream) throws CryptoManagerException;
+
+  /**
+   * Writes encrypted data to the provided output stream using the
+   * requested cipher transformation.
+   *
+   * @param  cipherTransformation  The algorithm/mode/padding to use
+   *         for the cipher.
+   *
+   * @param  keyLengthBits  The length in bits of the encryption key
+   *         this method will generate. Note the specified key length
+   *         must be compatible with the transformation.
+   *
+   * @param  outputStream The output stream to be wrapped by the
+   *         returned cipher output stream.
+   *
+   * @return  The output stream wrapped with a CipherOutputStream.
+   *
+   * @throws  CryptoManagerException  If a problem occurs managing the
+   *          encryption key or producing the cipher.
+   */
+  CipherOutputStream getCipherOutputStream(
+          String cipherTransformation, int keyLengthBits,
+          OutputStream outputStream)
+         throws CryptoManagerException;
+
+  /**
+   * Decrypts the data in the provided byte array using cipher
+   * specified by the key identifier prologue to the data.
+   * cipher.
+   *
+   * @param  data  The cipher-text data to be decrypted.
+   *
+   * @return  A byte array containing the clear-text representation of
+   *          the provided data.
+   *
+   * @throws  java.security.GeneralSecurityException  If a problem
+   * occurs while encrypting the data.
+   *
+   * @throws  CryptoManagerException  If a problem occurs reading the
+   *          key identifier or initialization vector from the data
+   *          prologue, or using these values to initialize a Cipher.
+   */
+  byte[] decrypt(byte[] data)
+         throws GeneralSecurityException,
+                CryptoManagerException;
+
+  /**
+   * Returns a CipherInputStream instantiated with a cipher
+   * corresponding to the key identifier prologue to the data.
+   *
+   * @param  inputStream The input stream be wrapped with the
+   *         CipherInputStream.
+   *
+   * @return The CiperInputStream instantiated as specified.
+   *
+   * @throws  CryptoManagerException If there is a problem reading the
+   *          key ID or initialization vector from the input stream,
+   *          or using these values to inititalize a Cipher.
+   */
+  CipherInputStream getCipherInputStream(
+          InputStream inputStream) throws CryptoManagerException;
+
+  /**
+   * Attempts to compress the data in the provided source array into
+   * the given destination array.  If the compressed data will fit
+   * into the destination array, then this method will return the
+   * number of bytes of compressed data in the array.  Otherwise, it
+   * will return -1 to indicate that the compression was not
+   * successful.  Note that if -1 is returned, then the data in the
+   * destination array should be considered invalid.
+   *
+   * @param  src  The array containing the raw data to compress.
+   * @param  dst  The array into which the compressed data should be
+   *              written.
+   *
+   * @return  The number of bytes of compressed data, or -1 if it was
+   *          not possible to actually compress the data.
+   */
+  int compress(byte[] src, byte[] dst);
+
+  /**
+   * Attempts to uncompress the data in the provided source array into
+   * the given destination array.  If the uncompressed data will fit
+   * into the given destination array, then this method will return
+   * the number of bytes of uncompressed data written into the
+   * destination buffer.  Otherwise, it will return a negative value
+   * to indicate that the destination buffer was not large enough.
+   * The absolute value of that negative return value will indicate
+   * the buffer size required to fully decompress the data.  Note that
+   * if a negative value is returned, then the data in the destination
+   * array should be considered invalid.
+   *
+   * @param  src  The array containing the compressed data.
+   * @param  dst  The array into which the uncompressed data should be
+   *              written.
+   *
+   * @return  A positive value containing the number of bytes of
+   *          uncompressed data written into the destination buffer,
+   *          or a negative value whose absolute value is the size of
+   *          the destination buffer required to fully decompress the
+   *          provided data.
+   *
+   * @throws java.util.zip.DataFormatException  If a problem occurs
+   * while attempting to uncompress the data.
+   */
+  int uncompress(byte[] src, byte[] dst)
+         throws DataFormatException;
+
+  /**
+   * Create an SSL context that may be used for communication to
+   * another ADS component.
+   *
+   * @param sslCertNickname The name of the local certificate to use,
+   *                        or null if none is specified.
+   * @return A new SSL Context.
+   * @throws org.opends.server.config.ConfigException If the context
+   * could not be created.
+   */
+  SSLContext getSslContext(String sslCertNickname)
+       throws ConfigException;
+
+  /**
+   * Get the name of the local certificate to use for SSL.
+   * @return The name of the local certificate to use for SSL.
+   */
+  String getSslCertNickname();
+
+  /**
+   * Determine whether SSL encryption is enabled.
+   * @return true if SSL encryption is enabled.
+   */
+  boolean isSslEncryption();
+
+  /**
+   * Get the set of enabled SSL protocols.
+   * @return The set of enabled SSL protocols.
+   */
+  SortedSet<String> getSslProtocols();
+
+  /**
+   * Get the set of enabled SSL cipher suites.
+   * @return The set of enabled SSL cipher suites.
+   */
+  SortedSet<String> getSslCipherSuites();
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManagerException.java b/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManagerException.java
index 8867067..00693d3 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManagerException.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/CryptoManagerException.java
@@ -34,6 +34,11 @@
  * problems with encryption key managagment, and is a wrapper for a
  * variety of other cipher related exceptions.
  */
+@org.opends.server.types.PublicAPI(
+     stability=org.opends.server.types.StabilityLevel.VOLATILE,
+     mayInstantiate=false,
+     mayExtend=false,
+     mayInvoke=true)
 public class CryptoManagerException extends OpenDsException {
   /**
    * The serial version identifier required to satisfy the compiler
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java b/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java
index f34bd3d..66ccc9b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java
@@ -48,7 +48,6 @@
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
 import org.opends.server.core.DirectoryServer;
-import org.opends.server.crypto.CryptoManager;
 
 
 /**
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java
index 6f6652e..a9a304c 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/CryptoManagerTestCase.java
@@ -94,9 +94,9 @@
   @Test
   public void testGetInstanceKeyCertificate()
           throws Exception {
-    final CryptoManager cm = DirectoryServer.getCryptoManager();
+    final CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
     final byte[] cert
-            = CryptoManager.getInstanceKeyCertificateFromLocalTruststore();
+            = CryptoManagerImpl.getInstanceKeyCertificateFromLocalTruststore();
     assertNotNull(cert);
 
     // The certificate should now be accessible in the truststore backend via LDAP.
@@ -129,8 +129,8 @@
          md.digest(ldapCert)).equals(cm.getInstanceKeyID()));
 
     // Call twice to ensure idempotent. 
-    CryptoManager.publishInstanceKeyEntryInADS();
-    CryptoManager.publishInstanceKeyEntryInADS();
+    CryptoManagerImpl.publishInstanceKeyEntryInADS();
+    CryptoManagerImpl.publishInstanceKeyEntryInADS();
   }
 
   @Test
@@ -254,7 +254,7 @@
   @Test(dataProvider="cipherParametersData")
   public void testStreamEncryptDecryptSuccess(CipherParameters cp)
           throws Exception {
-    final CryptoManager cm = DirectoryServer.getCryptoManager();
+    final CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
     final String secretMessage = "56789";
 
     final File tempFile
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperationTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperationTestCase.java
index f6eab0f..8f6eb0e 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperationTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/crypto/GetSymmetricKeyExtendedOperationTestCase.java
@@ -30,7 +30,6 @@
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import org.opends.server.TestCaseUtils;
-import org.opends.server.extensions.ExtensionsTestCase;
 import org.opends.server.schema.DirectoryStringSyntax;
 import org.opends.server.config.ConfigConstants;
 import org.opends.server.types.*;
@@ -68,12 +67,12 @@
   @Test(enabled=true)
   public void testValidRequest() throws Exception
   {
-    final CryptoManager cm = DirectoryServer.getCryptoManager();
+    final CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
     final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
     final String cipherTransformationName = "AES/CBC/PKCS5Padding";
     final int cipherKeyLength = 128;
 
-    CryptoManager.publishInstanceKeyEntryInADS();
+    CryptoManagerImpl.publishInstanceKeyEntryInADS();
 
     // Initial encryption ensures a cipher key entry is in ADS.
     cm.encrypt(cipherTransformationName, cipherKeyLength,
@@ -154,7 +153,7 @@
   @Test()
   public void testInvalidRequest() throws Exception
   {
-    CryptoManager cm = DirectoryServer.getCryptoManager();
+    CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
 
     String symmetricKey = "1";
     String instanceKeyID = cm.getInstanceKeyID();

--
Gitblit v1.10.0