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