From ef50c789d61e47789f342837a3479fccef23c64b Mon Sep 17 00:00:00 2001
From: coulbeck <coulbeck@localhost>
Date: Wed, 10 Oct 2007 20:29:24 +0000
Subject: [PATCH] Add configuration properties for the crypto manager's preferred digest algorithm, its preferred cipher and mac algorithms and the associated key lengths.
---
opends/resource/schema/02-config.ldif | 36 ++++
opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml | 162 ++++++++++++++++++++
opends/src/server/org/opends/server/types/CryptoManager.java | 228 ++++++++++++++++++++++++++--
3 files changed, 407 insertions(+), 19 deletions(-)
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index fa1b379..e83ca56 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2098,6 +2098,36 @@
DESC 'A cryptographic secret-key wrapped by a public-key'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.428
+ NAME 'ds-cfg-digest-algorithm'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.429
+ NAME 'ds-cfg-mac-algorithm'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.430
+ NAME 'ds-cfg-mac-key-length'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.431
+ NAME 'ds-cfg-cipher-transformation'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.432
+ NAME 'ds-cfg-cipher-key-length'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.433
+ NAME 'ds-cfg-key-wrapping-transformation'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
NAME 'ds-cfg-access-control-handler'
SUP top
@@ -3455,6 +3485,12 @@
SUP top
STRUCTURAL
MAY ( cn $
+ ds-cfg-digest-algorithm $
+ ds-cfg-mac-algorithm $
+ ds-cfg-mac-key-length $
+ ds-cfg-cipher-transformation $
+ ds-cfg-cipher-key-length $
+ ds-cfg-key-wrapping-transformation $
ds-cfg-ssl-protocol $
ds-cfg-ssl-cipher-suite $
ds-cfg-ssl-cert-nickname $
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml
index e997077..64b3c46 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/CryptoManagerConfiguration.xml
@@ -44,6 +44,168 @@
<ldap:superior>top</ldap:superior>
</ldap:object-class>
</adm:profile>
+ <adm:property name="digest-algorithm" multi-valued="false" advanced="false">
+ <adm:synopsis>
+ The preferred message digest algorithm for the Directory Server.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property will take effect immediately but will
+ only affect cryptographic operations performed after the
+ change.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>SHA-1</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:string />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-digest-algorithm</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="mac-algorithm" multi-valued="false" advanced="false">
+ <adm:synopsis>
+ The preferred MAC algorithm for the Directory Server.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property will take effect immediately but will
+ only affect cryptographic operations performed after the
+ change.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>HmacSHA1</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:string />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-mac-algorithm</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="mac-key-length" multi-valued="false" advanced="false">
+ <adm:synopsis>
+ The preferred key length in bits for the preferred MAC algorithm.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property will take effect immediately but will
+ only affect cryptographic operations performed after the
+ change.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>128</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-mac-key-length</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="cipher-transformation" multi-valued="false" advanced="false">
+ <adm:synopsis>
+ The preferred cipher for the Directory Server.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property will take effect immediately but will
+ only affect cryptographic operations performed after the
+ change.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>AES/CBC/PKCS5Padding</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:string />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-cipher-transformation</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="cipher-key-length" multi-valued="false" advanced="false">
+ <adm:synopsis>
+ The preferred key length in bits for the preferred cipher.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property will take effect immediately but will
+ only affect cryptographic operations performed after the
+ change.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>128</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-cipher-key-length</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="key-wrapping-transformation" multi-valued="false" advanced="false">
+ <adm:synopsis>
+ The preferred key wrapping transformation for the Directory Server.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:none>
+ <adm:synopsis>
+ Changes to this property will take effect immediately but will
+ only affect cryptographic operations performed after the
+ change.
+ </adm:synopsis>
+ </adm:none>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:string />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-key-wrapping-transformation</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
<adm:property name="ssl-protocol" multi-valued="true">
<adm:synopsis>
Specifies the names of the SSL protocols that will be allowed for
diff --git a/opends/src/server/org/opends/server/types/CryptoManager.java b/opends/src/server/org/opends/server/types/CryptoManager.java
index 2278b96..0b18896 100644
--- a/opends/src/server/org/opends/server/types/CryptoManager.java
+++ b/opends/src/server/org/opends/server/types/CryptoManager.java
@@ -53,6 +53,7 @@
import org.opends.admin.ads.ADSContext;
import org.opends.server.admin.std.server.CryptoManagerCfg;
+import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.api.Backend;
import org.opends.server.backends.TrustStoreBackend;
import org.opends.server.config.ConfigException;
@@ -108,6 +109,7 @@
mayExtend=false,
mayInvoke=true)
public class CryptoManager
+ implements ConfigurationChangeListener<CryptoManagerCfg>
{
/**
* The tracer object for the debug logger.
@@ -153,30 +155,30 @@
= new Random(secureRandom.nextLong());
// The preferred message digest algorithm for the Directory Server.
- private final String preferredDigestAlgorithm;
+ private String preferredDigestAlgorithm;
// The map from encryption key ID to MacKeyEntry (cache).
private final Map<KeyEntryID, MacKeyEntry> macKeyEntryCache
= new ConcurrentHashMap<KeyEntryID, MacKeyEntry>();
// The preferred MAC algorithm for the Directory Server.
- private final String preferredMACAlgorithm;
+ private String preferredMACAlgorithm;
// The preferred key length for the preferred MAC algorithm.
- private final int preferredMACAlgorithmKeyLengthBits;
+ private int preferredMACAlgorithmKeyLengthBits;
// The map from encryption key ID to CipherKeyEntry (cache).
private final Map<KeyEntryID, CipherKeyEntry> cipherKeyEntryCache
= new ConcurrentHashMap<KeyEntryID, CipherKeyEntry>();
// The preferred cipher for the Directory Server.
- private final String preferredCipherTransformation;
+ private String preferredCipherTransformation;
// The preferred key length for the preferred cipher.
- private final int preferredCipherTransformationKeyLengthBits;
+ private int preferredCipherTransformationKeyLengthBits;
// The preferred key wrapping transformation
- private final String preferredKeyWrappingTransformation;
+ private String preferredKeyWrappingTransformation;
// The name of the local certificate to use for SSL.
private final String sslCertNickname;
@@ -257,10 +259,8 @@
schemaInitDone = true;
}
- // TODO -- Get the crypto defaults from the configuration.
-
// Preferred digest and validation.
- preferredDigestAlgorithm = "SHA-1";
+ preferredDigestAlgorithm = cfg.getDigestAlgorithm();
try{
MessageDigest.getInstance(preferredDigestAlgorithm);
}
@@ -274,8 +274,9 @@
}
// Preferred MAC engine and validation.
- preferredMACAlgorithm = "HmacSHA1";
- preferredMACAlgorithmKeyLengthBits = 128;
+ preferredMACAlgorithm = cfg.getMacAlgorithm();
+ preferredMACAlgorithmKeyLengthBits =
+ cfg.getMacKeyLength();
try {
MacKeyEntry.generateKeyEntry(null,
preferredMACAlgorithm,
@@ -291,8 +292,10 @@
}
// Preferred encryption cipher and validation.
- preferredCipherTransformation = "AES/CBC/PKCS5Padding";
- preferredCipherTransformationKeyLengthBits = 128;
+ preferredCipherTransformation =
+ cfg.getCipherTransformation();
+ preferredCipherTransformationKeyLengthBits =
+ cfg.getCipherKeyLength();
try {
CipherKeyEntry.generateKeyEntry(null,
preferredCipherTransformation,
@@ -315,7 +318,7 @@
// TODO: Trying OAEPWITHSHA-512ANDMGF1PADDING throws an exception
// "Key too small...".
preferredKeyWrappingTransformation
- = "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";
+ = cfg.getKeyWrappingTransformation();
try {
final String certificateBase64 =
"MIIB2jCCAUMCBEb7wpYwDQYJKoZIhvcNAQEEBQAwNDEbMBkGA1UEChMST3B" +
@@ -349,6 +352,9 @@
sslEncryption = cfg.isSSLEncryption();
sslProtocols = cfg.getSSLProtocol();
sslCipherSuites = cfg.getSSLCipherSuite();
+
+ // Register as a configuration change listener.
+ cfg.addChangeListener(this);
}
@@ -676,8 +682,8 @@
/**
- * Encodes a ds-cfg-symmetric-key attribute value using the supplied
- * arguments.
+ * Encodes a ds-cfg-symmetric-key attribute value with the preferred
+ * key wrapping transformation and using the supplied arguments.
*
* The syntax of the ds-cfg-symmetric-key attribute:
* <pre>
@@ -713,9 +719,45 @@
final byte[] wrappingKeyCertificateData,
final SecretKey secretKey)
throws CryptoManagerException {
+ return encodeSymmetricKeyAttribute(
+ preferredKeyWrappingTransformation,
+ wrappingKeyID,
+ wrappingKeyCertificateData,
+ secretKey);
+ }
+
+
+ /**
+ * Encodes a ds-cfg-symmetric-key attribute value with a specified
+ * key wrapping transformation and using the supplied arguments.
+ *
+ * @param wrappingTransformationName The name of the key wrapping
+ * transformation.
+ *
+ * @param wrappingKeyID The key identifier of the wrapping key. This
+ * parameter is the first field in the encoded value and identifies
+ * the instance that will be able to unwrap the secret key.
+ *
+ * @param wrappingKeyCertificateData The public key certificate used
+ * to derive the wrapping key.
+ *
+ * @param secretKey The secret key value to be wrapped for the
+ * encoded value.
+ *
+ * @return The encoded representation of the ds-cfg-symmetric-key
+ * attribute with the secret key wrapped with the supplied public
+ * key.
+ *
+ * @throws CryptoManagerException If there is a problem wrapping
+ * the secret key.
+ */
+ private String encodeSymmetricKeyAttribute(
+ final String wrappingTransformationName,
+ final String wrappingKeyID,
+ final byte[] wrappingKeyCertificateData,
+ final SecretKey secretKey)
+ throws CryptoManagerException {
// Wrap secret key.
- final String wrappingTransformationName
- = preferredKeyWrappingTransformation;
String wrappedKeyElement;
try {
final CertificateFactory cf
@@ -877,7 +919,8 @@
final byte[] wrappingKeyCert =
certMap.get(requestedInstanceKeyID);
return encodeSymmetricKeyAttribute(
- requestedInstanceKeyID, wrappingKeyCert, secretKey);
+ preferredKeyWrappingTransformation,
+ requestedInstanceKeyID, wrappingKeyCert, secretKey);
}
@@ -3284,5 +3327,152 @@
super(message, cause);
}
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ CryptoManagerCfg cfg,
+ List<Message> unacceptableReasons)
+ {
+ // Acceptable until we find an error.
+ boolean acceptable = true;
+
+ // Preferred digest validation.
+ String preferredDigestAlgorithm =
+ cfg.getDigestAlgorithm();
+ if (!preferredDigestAlgorithm.equals(
+ this.preferredDigestAlgorithm))
+ {
+ try{
+ MessageDigest.getInstance(preferredDigestAlgorithm);
+ }
+ catch (Exception ex) {
+ if (debugEnabled()) {
+ TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+ }
+ unacceptableReasons.add(
+ ERR_CRYPTOMGR_CANNOT_GET_PREFERRED_DIGEST.get(
+ getExceptionMessage(ex)));
+ acceptable = false;
+ }
+ }
+
+ // Preferred MAC algorithm validation.
+ String preferredMACAlgorithm = cfg.getMacAlgorithm();
+ Integer preferredMACAlgorithmKeyLengthBits =
+ cfg.getMacKeyLength();
+ if (!preferredMACAlgorithm.equals(this.preferredMACAlgorithm) ||
+ preferredMACAlgorithmKeyLengthBits !=
+ this.preferredMACAlgorithmKeyLengthBits)
+ {
+ try {
+ MacKeyEntry.generateKeyEntry(
+ null,
+ preferredMACAlgorithm,
+ preferredMACAlgorithmKeyLengthBits);
+ }
+ catch (Exception ex) {
+ if (debugEnabled()) {
+ TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+ }
+ unacceptableReasons.add(
+ ERR_CRYPTOMGR_CANNOT_GET_PREFERRED_MAC_ENGINE.get(
+ getExceptionMessage(ex)));
+ acceptable = false;
+ }
+ }
+
+ // Preferred encryption cipher validation.
+ String preferredCipherTransformation =
+ cfg.getCipherTransformation();
+ Integer preferredCipherTransformationKeyLengthBits =
+ cfg.getCipherKeyLength();
+ if (!preferredCipherTransformation.equals(
+ this.preferredCipherTransformation) ||
+ preferredCipherTransformationKeyLengthBits !=
+ this.preferredCipherTransformationKeyLengthBits)
+ {
+ try {
+ CipherKeyEntry.generateKeyEntry(
+ null,
+ preferredCipherTransformation,
+ preferredCipherTransformationKeyLengthBits);
+ }
+ catch (Exception ex) {
+ if (debugEnabled()) {
+ TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+ }
+ unacceptableReasons.add(
+ ERR_CRYPTOMGR_CANNOT_GET_PREFERRED_ENCRYPTION_CIPHER.get(
+ getExceptionMessage(ex)));
+ acceptable = false;
+ }
+ }
+
+ // Preferred secret key wrapping cipher and validation. Depends
+ // on MAC cipher for secret key. Note that the TrustStoreBackend
+ // not available at this point, hence a "dummy" certificate must
+ // be used to validate the choice of secret key wrapping cipher.
+ String preferredKeyWrappingTransformation
+ = cfg.getKeyWrappingTransformation();
+ if (!preferredKeyWrappingTransformation.equals(
+ this.preferredKeyWrappingTransformation))
+ {
+ try {
+ final byte[] certificate =
+ getInstanceKeyCertificateFromLocalTruststore();
+ final String keyID = getInstanceKeyID(certificate);
+ final SecretKey macKey =
+ MacKeyEntry.generateKeyEntry(
+ null,
+ preferredMACAlgorithm,
+ preferredMACAlgorithmKeyLengthBits).
+ getSecretKey();
+ encodeSymmetricKeyAttribute(
+ preferredKeyWrappingTransformation, keyID,
+ certificate, macKey);
+ }
+ catch (Exception ex) {
+ if (debugEnabled()) {
+ TRACER.debugCaught(DebugLogLevel.ERROR, ex);
+ }
+ unacceptableReasons.add(
+ ERR_CRYPTOMGR_CANNOT_GET_PREFERRED_KEY_WRAPPING_CIPHER.get(
+ getExceptionMessage(ex)));
+ acceptable = false;
+ }
+ }
+
+ return acceptable;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ CryptoManagerCfg cfg)
+ {
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
+ List<Message> messages = new ArrayList<Message>();
+
+ preferredDigestAlgorithm =
+ cfg.getDigestAlgorithm();
+ preferredMACAlgorithm =
+ cfg.getMacAlgorithm();
+ preferredMACAlgorithmKeyLengthBits =
+ cfg.getMacKeyLength();
+ preferredCipherTransformation =
+ cfg.getCipherTransformation();
+ preferredCipherTransformationKeyLengthBits =
+ cfg.getCipherKeyLength();
+ preferredKeyWrappingTransformation =
+ cfg.getKeyWrappingTransformation();
+
+ return new ConfigChangeResult(resultCode,
+ adminActionRequired, messages);
+ }
}
--
Gitblit v1.10.0