From bef34ff8af56487e6c60462d1870ab6dff138d7a Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Mon, 10 Sep 2007 00:56:52 +0000
Subject: [PATCH] Add support for password storage schemes using AES, 3DES, RC4, and Blowfish. The AES, RC4, and Blowfish implementations all use 128-bit ciphers, and the 3DES implementation uses a 168-bit cipher.
---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/BlowfishPasswordStorageSchemeTestCase.java | 75 ++
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/BlowfishPasswordStorageSchemeConfiguration.xml | 63 +
opendj-sdk/opends/src/messages/messages/extension.properties | 5
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TripleDESPasswordStorageSchemeTestCase.java | 76 ++
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/RC4PasswordStorageSchemeConfiguration.xml | 63 +
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RC4PasswordStorageSchemeTestCase.java | 75 ++
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/TripleDESPasswordStorageSchemeConfiguration.xml | 63 +
opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java | 310 +++++++++
opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java | 310 +++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AESPasswordStorageSchemeTestCase.java | 75 ++
opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java | 310 +++++++++
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/AESPasswordStorageSchemeConfiguration.xml | 63 +
opendj-sdk/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java | 98 ++
opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif | 36 +
opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java | 310 +++++++++
opendj-sdk/opends/resource/admin/abbreviations.xsl | 1
opendj-sdk/opends/resource/schema/02-config.ldif | 14
17 files changed, 1,946 insertions(+), 1 deletions(-)
diff --git a/opendj-sdk/opends/resource/admin/abbreviations.xsl b/opendj-sdk/opends/resource/admin/abbreviations.xsl
index def5a86..b8653d7 100644
--- a/opendj-sdk/opends/resource/admin/abbreviations.xsl
+++ b/opendj-sdk/opends/resource/admin/abbreviations.xsl
@@ -51,6 +51,7 @@
or $value = 'fifo' or $value = 'vlv' or $value = 'uuid'
or $value = 'md5' or $value = 'sha1' or $value = 'sha256'
or $value = 'sha384' or $value = 'sha512' or $value = 'tls'
+ or $value = 'des' or $value = 'aes' or $value = 'rc4'
"/>
</xsl:template>
</xsl:stylesheet>
diff --git a/opendj-sdk/opends/resource/schema/02-config.ldif b/opendj-sdk/opends/resource/schema/02-config.ldif
index 145aeae..5eafa48 100644
--- a/opendj-sdk/opends/resource/schema/02-config.ldif
+++ b/opendj-sdk/opends/resource/schema/02-config.ldif
@@ -2492,6 +2492,20 @@
NAME 'ds-cfg-ldif-connection-handler' SUP ds-cfg-connection-handler
MUST ( ds-cfg-ldif-directory $ ds-cfg-poll-interval )
X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.169
+ NAME 'ds-cfg-triple-des-password-storage-scheme'
+ SUP ds-cfg-password-storage-scheme STRUCTURAL
+ X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.170
+ NAME 'ds-cfg-aes-password-storage-scheme' SUP ds-cfg-password-storage-scheme
+ STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.171
+ NAME 'ds-cfg-rc4-password-storage-scheme' SUP ds-cfg-password-storage-scheme
+ STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.172
+ NAME 'ds-cfg-blowfish-password-storage-scheme'
+ SUP ds-cfg-password-storage-scheme STRUCTURAL
+ X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.173
NAME 'ds-cfg-entry-cache-monitor-provider' SUP ds-cfg-monitor-provider
STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/AESPasswordStorageSchemeConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/AESPasswordStorageSchemeConfiguration.xml
new file mode 100644
index 0000000..e738bfa
--- /dev/null
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/AESPasswordStorageSchemeConfiguration.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+! 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 2007 Sun Microsystems, Inc.
+! -->
+
+<adm:managed-object
+ name="aes-password-storage-scheme"
+ plural-name="aes-password-storage-schemes"
+ package="org.opends.server.admin.std"
+ extends="password-storage-scheme"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+
+ <adm:synopsis>
+ The <adm:user-friendly-name /> provides a mechanism for encoding user
+ passwords using the AES reversible encryption mechanism. This
+ implementation contains only an implementation for the user password syntax,
+ with a storage scheme name of "AES".
+ </adm:synopsis>
+
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.170</ldap:oid>
+ <ldap:name>ds-cfg-aes-password-storage-scheme</ldap:name>
+ <ldap:superior>ds-cfg-password-storage-scheme</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+
+ <adm:property-override name="scheme-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.extensions.AESPasswordStorageScheme
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+
+</adm:managed-object>
+
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/BlowfishPasswordStorageSchemeConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/BlowfishPasswordStorageSchemeConfiguration.xml
new file mode 100644
index 0000000..126d0fc
--- /dev/null
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/BlowfishPasswordStorageSchemeConfiguration.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+! 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 2007 Sun Microsystems, Inc.
+! -->
+
+<adm:managed-object
+ name="blowfish-password-storage-scheme"
+ plural-name="blowfish-password-storage-schemes"
+ package="org.opends.server.admin.std"
+ extends="password-storage-scheme"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+
+ <adm:synopsis>
+ The <adm:user-friendly-name /> provides a mechanism for encoding user
+ passwords using the Blowfish reversible encryption mechanism. This
+ implementation contains only an implementation for the user password syntax,
+ with a storage scheme name of "BLOWFISH".
+ </adm:synopsis>
+
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.172</ldap:oid>
+ <ldap:name>ds-cfg-blowfish-password-storage-scheme</ldap:name>
+ <ldap:superior>ds-cfg-password-storage-scheme</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+
+ <adm:property-override name="scheme-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.extensions.BlowfishPasswordStorageScheme
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+
+</adm:managed-object>
+
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/RC4PasswordStorageSchemeConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/RC4PasswordStorageSchemeConfiguration.xml
new file mode 100644
index 0000000..824b35b
--- /dev/null
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/RC4PasswordStorageSchemeConfiguration.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+! 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 2007 Sun Microsystems, Inc.
+! -->
+
+<adm:managed-object
+ name="rc4-password-storage-scheme"
+ plural-name="rc4-password-storage-schemes"
+ package="org.opends.server.admin.std"
+ extends="password-storage-scheme"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+
+ <adm:synopsis>
+ The <adm:user-friendly-name /> provides a mechanism for encoding user
+ passwords using the RC4 reversible encryption mechanism. This
+ implementation contains only an implementation for the user password syntax,
+ with a storage scheme name of "RC4".
+ </adm:synopsis>
+
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.171</ldap:oid>
+ <ldap:name>ds-cfg-rc4-password-storage-scheme</ldap:name>
+ <ldap:superior>ds-cfg-password-storage-scheme</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+
+ <adm:property-override name="scheme-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.extensions.RC4PasswordStorageScheme
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+
+</adm:managed-object>
+
diff --git a/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/TripleDESPasswordStorageSchemeConfiguration.xml b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/TripleDESPasswordStorageSchemeConfiguration.xml
new file mode 100644
index 0000000..d23057d
--- /dev/null
+++ b/opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/TripleDESPasswordStorageSchemeConfiguration.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+! 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 2007 Sun Microsystems, Inc.
+! -->
+
+<adm:managed-object
+ name="triple-des-password-storage-scheme"
+ plural-name="triple-des-password-storage-schemes"
+ package="org.opends.server.admin.std"
+ extends="password-storage-scheme"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+
+ <adm:synopsis>
+ The <adm:user-friendly-name /> provides a mechanism for encoding user
+ passwords using the triple-DES (DES/EDE) reversible encryption mechanism.
+ This implementation contains only an implementation for the user password
+ syntax, with a storage scheme name of "3DES".
+ </adm:synopsis>
+
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.169</ldap:oid>
+ <ldap:name>ds-cfg-triple-des-password-storage-scheme</ldap:name>
+ <ldap:superior>ds-cfg-password-storage-scheme</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+
+ <adm:property-override name="scheme-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.extensions.TripleDESPasswordStorageScheme
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+
+</adm:managed-object>
+
diff --git a/opendj-sdk/opends/src/messages/messages/extension.properties b/opendj-sdk/opends/src/messages/messages/extension.properties
index dece0b6..dfb31a3 100644
--- a/opendj-sdk/opends/src/messages/messages/extension.properties
+++ b/opendj-sdk/opends/src/messages/messages/extension.properties
@@ -1585,4 +1585,7 @@
SEVERE_ERR_SMTP_ASNH_CANNOT_SEND_MESSAGE_558=An error occurred while \
attempting to send an account status notification message for notification \
type %s for user entry %s: %s
-
+SEVERE_ERR_PWSCHEME_CANNOT_ENCRYPT_559=An error occurred while trying to \
+ encrypt a value using password storage scheme %s: %s
+SEVERE_ERR_PWSCHEME_CANNOT_DECRYPT_560=An error occurred while trying to \
+ decrypt a value using password storage scheme %s: %s
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
new file mode 100644
index 0000000..183f0bc
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
@@ -0,0 +1,310 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import java.util.Arrays;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.std.server.AESPasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+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.types.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.util.Base64;
+
+import static org.opends.messages.ExtensionMessages.*;
+import static org.opends.server.extensions.ExtensionsConstants.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This class defines a Directory Server password storage scheme that will
+ * encode values using the AES reversible encryption algorithm. This
+ * implementation supports only the user password syntax and not the auth
+ * password syntax.
+ */
+public class AESPasswordStorageScheme
+ extends PasswordStorageScheme<AESPasswordStorageSchemeCfg>
+{
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
+
+
+ // The reference to the Directory Server crypto manager that we will use to
+ // handle the encryption/decryption.
+ private CryptoManager cryptoManager;
+
+
+
+ /**
+ * Creates a new instance of this password storage scheme. Note that no
+ * initialization should be performed here, as all initialization should be
+ * done in the {@code initializePasswordStorageScheme} method.
+ */
+ public AESPasswordStorageScheme()
+ {
+ super();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void initializePasswordStorageScheme(
+ AESPasswordStorageSchemeCfg configuration)
+ throws ConfigException, InitializationException
+ {
+ cryptoManager = DirectoryServer.getCryptoManager();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public String getStorageSchemeName()
+ {
+ return STORAGE_SCHEME_NAME_AES;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_AES,
+ KEY_SIZE_AES,
+ plaintext.value());
+ return ByteStringFactory.create(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_AES,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePasswordWithScheme(ByteString plaintext)
+ throws DirectoryException
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('{');
+ buffer.append(STORAGE_SCHEME_NAME_AES);
+ buffer.append('}');
+
+ try
+ {
+ byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_AES,
+ KEY_SIZE_AES,
+ plaintext.value());
+ buffer.append(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_AES,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+
+ return ByteStringFactory.create(buffer.toString());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean passwordMatches(ByteString plaintextPassword,
+ ByteString storedPassword)
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return Arrays.equals(plaintextPassword.value(), decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ return false;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isReversible()
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getPlaintextValue(ByteString storedPassword)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return ByteStringFactory.create(decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_DECRYPT.get(STORAGE_SCHEME_NAME_AES,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsAuthPasswordSyntax()
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodeAuthPassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean authPasswordMatches(ByteString plaintextPassword,
+ String authInfo, String authValue)
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getAuthPasswordPlaintextValue(String authInfo,
+ String authValue)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isStorageSchemeSecure()
+ {
+ // This password storage scheme should be considered secure.
+ return true;
+ }
+}
+
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
new file mode 100644
index 0000000..909668c
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
@@ -0,0 +1,310 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import java.util.Arrays;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.std.server.BlowfishPasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+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.types.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.util.Base64;
+
+import static org.opends.messages.ExtensionMessages.*;
+import static org.opends.server.extensions.ExtensionsConstants.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This class defines a Directory Server password storage scheme that will
+ * encode values using the Blowfish reversible encryption algorithm. This
+ * implementation supports only the user password syntax and not the auth
+ * password syntax.
+ */
+public class BlowfishPasswordStorageScheme
+ extends PasswordStorageScheme<BlowfishPasswordStorageSchemeCfg>
+{
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
+
+
+ // The reference to the Directory Server crypto manager that we will use to
+ // handle the encryption/decryption.
+ private CryptoManager cryptoManager;
+
+
+
+ /**
+ * Creates a new instance of this password storage scheme. Note that no
+ * initialization should be performed here, as all initialization should be
+ * done in the {@code initializePasswordStorageScheme} method.
+ */
+ public BlowfishPasswordStorageScheme()
+ {
+ super();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void initializePasswordStorageScheme(
+ BlowfishPasswordStorageSchemeCfg configuration)
+ throws ConfigException, InitializationException
+ {
+ cryptoManager = DirectoryServer.getCryptoManager();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public String getStorageSchemeName()
+ {
+ return STORAGE_SCHEME_NAME_BLOWFISH;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] encodedBytes =
+ cryptoManager.encrypt(CIPHER_TRANSFORMATION_BLOWFISH,
+ KEY_SIZE_BLOWFISH, plaintext.value());
+ return ByteStringFactory.create(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_BLOWFISH,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePasswordWithScheme(ByteString plaintext)
+ throws DirectoryException
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('{');
+ buffer.append(STORAGE_SCHEME_NAME_BLOWFISH);
+ buffer.append('}');
+
+ try
+ {
+ byte[] encodedBytes =
+ cryptoManager.encrypt(CIPHER_TRANSFORMATION_BLOWFISH,
+ KEY_SIZE_BLOWFISH, plaintext.value());
+ buffer.append(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_BLOWFISH,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+
+ return ByteStringFactory.create(buffer.toString());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean passwordMatches(ByteString plaintextPassword,
+ ByteString storedPassword)
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return Arrays.equals(plaintextPassword.value(), decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ return false;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isReversible()
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getPlaintextValue(ByteString storedPassword)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return ByteStringFactory.create(decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_DECRYPT.get(STORAGE_SCHEME_NAME_BLOWFISH,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsAuthPasswordSyntax()
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodeAuthPassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean authPasswordMatches(ByteString plaintextPassword,
+ String authInfo, String authValue)
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getAuthPasswordPlaintextValue(String authInfo,
+ String authValue)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isStorageSchemeSecure()
+ {
+ // This password storage scheme should be considered secure.
+ return true;
+ }
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java b/opendj-sdk/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java
index 2aaac17..aece32e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/ExtensionsConstants.java
@@ -118,6 +118,88 @@
/**
+ * The cipher transformation that should be used when performing 3DES
+ * encryption/decription.
+ */
+ public static final String CIPHER_TRANSFORMATION_3DES =
+ "DESede/CFB/NoPadding";
+
+
+
+ /**
+ * The cipher transformation that should be used when performing AES
+ * encryption/decription.
+ */
+ public static final String CIPHER_TRANSFORMATION_AES = "AES/CFB/NoPadding";
+
+
+
+ /**
+ * The cipher transformation that should be used when performing blowfish
+ * encryption/decription.
+ */
+ public static final String CIPHER_TRANSFORMATION_BLOWFISH =
+ "Blowfish/CFB/NoPadding";
+
+
+
+ /**
+ * The cipher transformation that should be used when performing RC4
+ * encryption/decription.
+ */
+ public static final String CIPHER_TRANSFORMATION_RC4 = "RC4";
+
+
+
+ /**
+ * The key size (in bits) that should be used for the encryption key when
+ * using the 3DES cipher.
+ */
+ public static final int KEY_SIZE_3DES = 168;
+
+
+
+ /**
+ * The key size (in bits) that should be used for the encryption key when
+ * using the AES cipher.
+ */
+ public static final int KEY_SIZE_AES = 128;
+
+
+
+ /**
+ * The key size (in bits) that should be used for the encryption key when
+ * using the Blowfish cipher.
+ */
+ public static final int KEY_SIZE_BLOWFISH = 128;
+
+
+
+ /**
+ * The key size (in bits) that should be used for the encryption key when
+ * using the RC4 cipher.
+ */
+ public static final int KEY_SIZE_RC4 = 128;
+
+
+
+ /**
+ * The password storage scheme name that will be used for passwords that are
+ * stored in 3DES-encrypted form.
+ */
+ public static final String STORAGE_SCHEME_NAME_3DES = "3DES";
+
+
+
+ /**
+ * The password storage scheme name that will be used for passwords that are
+ * stored in AES-encrypted form.
+ */
+ public static final String STORAGE_SCHEME_NAME_AES = "AES";
+
+
+
+ /**
* The password storage scheme name that will be used for passwords that are
* stored in base64-encoded form (virtually no protection, but the value is
* reversible).
@@ -128,6 +210,14 @@
/**
* The password storage scheme name that will be used for passwords that are
+ * stored in Blowfish-encrypted form.
+ */
+ public static final String STORAGE_SCHEME_NAME_BLOWFISH = "BLOWFISH";
+
+
+
+ /**
+ * The password storage scheme name that will be used for passwords that are
* not encoded or obscured in any way.
*/
public static final String STORAGE_SCHEME_NAME_CLEAR = "CLEAR";
@@ -143,6 +233,14 @@
/**
+ * The password storage scheme name that will be used for passwords that are
+ * stored in RC4-encrypted form.
+ */
+ public static final String STORAGE_SCHEME_NAME_RC4 = "RC4";
+
+
+
+ /**
* The password storage scheme name that will be used for passwords stored in
* a salted MD5 representation.
*/
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
new file mode 100644
index 0000000..e0f48a3
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
@@ -0,0 +1,310 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import java.util.Arrays;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.std.server.RC4PasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+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.types.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.util.Base64;
+
+import static org.opends.messages.ExtensionMessages.*;
+import static org.opends.server.extensions.ExtensionsConstants.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This class defines a Directory Server password storage scheme that will
+ * encode values using the RC4 reversible encryption algorithm. This
+ * implementation supports only the user password syntax and not the auth
+ * password syntax.
+ */
+public class RC4PasswordStorageScheme
+ extends PasswordStorageScheme<RC4PasswordStorageSchemeCfg>
+{
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
+
+
+ // The reference to the Directory Server crypto manager that we will use to
+ // handle the encryption/decryption.
+ private CryptoManager cryptoManager;
+
+
+
+ /**
+ * Creates a new instance of this password storage scheme. Note that no
+ * initialization should be performed here, as all initialization should be
+ * done in the {@code initializePasswordStorageScheme} method.
+ */
+ public RC4PasswordStorageScheme()
+ {
+ super();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void initializePasswordStorageScheme(
+ RC4PasswordStorageSchemeCfg configuration)
+ throws ConfigException, InitializationException
+ {
+ cryptoManager = DirectoryServer.getCryptoManager();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public String getStorageSchemeName()
+ {
+ return STORAGE_SCHEME_NAME_RC4;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_RC4,
+ KEY_SIZE_RC4,
+ plaintext.value());
+ return ByteStringFactory.create(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_RC4,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePasswordWithScheme(ByteString plaintext)
+ throws DirectoryException
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('{');
+ buffer.append(STORAGE_SCHEME_NAME_RC4);
+ buffer.append('}');
+
+ try
+ {
+ byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_RC4,
+ KEY_SIZE_RC4,
+ plaintext.value());
+ buffer.append(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_RC4,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+
+ return ByteStringFactory.create(buffer.toString());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean passwordMatches(ByteString plaintextPassword,
+ ByteString storedPassword)
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return Arrays.equals(plaintextPassword.value(), decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ return false;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isReversible()
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getPlaintextValue(ByteString storedPassword)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return ByteStringFactory.create(decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_DECRYPT.get(STORAGE_SCHEME_NAME_RC4,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsAuthPasswordSyntax()
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodeAuthPassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean authPasswordMatches(ByteString plaintextPassword,
+ String authInfo, String authValue)
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getAuthPasswordPlaintextValue(String authInfo,
+ String authValue)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isStorageSchemeSecure()
+ {
+ // This password storage scheme should be considered secure.
+ return true;
+ }
+}
+
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
new file mode 100644
index 0000000..c3c0e2a
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
@@ -0,0 +1,310 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import java.util.Arrays;
+
+import org.opends.messages.Message;
+import org.opends.server.admin.std.server.TripleDESPasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+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.types.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.util.Base64;
+
+import static org.opends.messages.ExtensionMessages.*;
+import static org.opends.server.extensions.ExtensionsConstants.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.StaticUtils.*;
+
+
+
+/**
+ * This class defines a Directory Server password storage scheme that will
+ * encode values using the triple-DES (DES/EDE) reversible encryption algorithm.
+ * This implementation supports only the user password syntax and not the auth
+ * password syntax.
+ */
+public class TripleDESPasswordStorageScheme
+ extends PasswordStorageScheme<TripleDESPasswordStorageSchemeCfg>
+{
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
+
+
+ // The reference to the Directory Server crypto manager that we will use to
+ // handle the encryption/decryption.
+ private CryptoManager cryptoManager;
+
+
+
+ /**
+ * Creates a new instance of this password storage scheme. Note that no
+ * initialization should be performed here, as all initialization should be
+ * done in the {@code initializePasswordStorageScheme} method.
+ */
+ public TripleDESPasswordStorageScheme()
+ {
+ super();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void initializePasswordStorageScheme(
+ TripleDESPasswordStorageSchemeCfg configuration)
+ throws ConfigException, InitializationException
+ {
+ cryptoManager = DirectoryServer.getCryptoManager();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public String getStorageSchemeName()
+ {
+ return STORAGE_SCHEME_NAME_3DES;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_3DES,
+ KEY_SIZE_3DES,
+ plaintext.value());
+ return ByteStringFactory.create(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_3DES,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodePasswordWithScheme(ByteString plaintext)
+ throws DirectoryException
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('{');
+ buffer.append(STORAGE_SCHEME_NAME_3DES);
+ buffer.append('}');
+
+ try
+ {
+ byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_3DES,
+ KEY_SIZE_3DES,
+ plaintext.value());
+ buffer.append(Base64.encode(encodedBytes));
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_ENCRYPT.get(STORAGE_SCHEME_NAME_3DES,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+
+ return ByteStringFactory.create(buffer.toString());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean passwordMatches(ByteString plaintextPassword,
+ ByteString storedPassword)
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return Arrays.equals(plaintextPassword.value(), decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ return false;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isReversible()
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getPlaintextValue(ByteString storedPassword)
+ throws DirectoryException
+ {
+ try
+ {
+ byte[] decryptedPassword =
+ cryptoManager.decrypt(Base64.decode(storedPassword.stringValue()));
+ return ByteStringFactory.create(decryptedPassword);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message m = ERR_PWSCHEME_CANNOT_DECRYPT.get(STORAGE_SCHEME_NAME_3DES,
+ getExceptionMessage(e));
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ m, e);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean supportsAuthPasswordSyntax()
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString encodeAuthPassword(ByteString plaintext)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean authPasswordMatches(ByteString plaintextPassword,
+ String authInfo, String authValue)
+ {
+ // This storage scheme does not support the authentication password syntax.
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ByteString getAuthPasswordPlaintextValue(String authInfo,
+ String authValue)
+ throws DirectoryException
+ {
+ Message message =
+ ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public boolean isStorageSchemeSecure()
+ {
+ // This password storage scheme should be considered secure.
+ return true;
+ }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif b/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
index ac3a9bb..7491871 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
+++ b/opendj-sdk/opends/tests/unit-tests-testng/resource/config-changes.ldif
@@ -819,3 +819,39 @@
ds-cfg-alert-handler-class: org.opends.server.extensions.DummyAlertHandler
ds-cfg-alert-handler-enabled: true
+dn: cn=3DES,cn=Password Storage Schemes,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-password-storage-scheme
+objectClass: ds-cfg-triple-des-password-storage-scheme
+cn: 3DES
+ds-cfg-password-storage-scheme-class: org.opends.server.extensions.TripleDESPasswordStorageScheme
+ds-cfg-password-storage-scheme-enabled: true
+
+dn: cn=AES,cn=Password Storage Schemes,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-password-storage-scheme
+objectClass: ds-cfg-aes-password-storage-scheme
+cn: AES
+ds-cfg-password-storage-scheme-class: org.opends.server.extensions.AESPasswordStorageScheme
+ds-cfg-password-storage-scheme-enabled: true
+
+dn: cn=Blowfish,cn=Password Storage Schemes,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-password-storage-scheme
+objectClass: ds-cfg-blowfish-password-storage-scheme
+cn: Blowfish
+ds-cfg-password-storage-scheme-class: org.opends.server.extensions.BlowfishPasswordStorageScheme
+ds-cfg-password-storage-scheme-enabled: true
+
+dn: cn=RC4,cn=Password Storage Schemes,cn=config
+changetype: add
+objectClass: top
+objectClass: ds-cfg-password-storage-scheme
+objectClass: ds-cfg-rc4-password-storage-scheme
+cn: RC4
+ds-cfg-password-storage-scheme-class: org.opends.server.extensions.RC4PasswordStorageScheme
+ds-cfg-password-storage-scheme-enabled: true
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AESPasswordStorageSchemeTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AESPasswordStorageSchemeTestCase.java
new file mode 100644
index 0000000..93eea01
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AESPasswordStorageSchemeTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import org.opends.server.admin.server.AdminTestCaseUtils;
+import org.opends.server.admin.std.meta.AESPasswordStorageSchemeCfgDefn;
+import org.opends.server.admin.std.server.AESPasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+
+
+
+/**
+ * A set of test cases for the AES password storage scheme.
+ */
+public class AESPasswordStorageSchemeTestCase
+ extends PasswordStorageSchemeTestCase
+{
+ /**
+ * Creates a new instance of this storage scheme test case.
+ */
+ public AESPasswordStorageSchemeTestCase()
+ {
+ super("cn=AES,cn=Password Storage Schemes,cn=config");
+ }
+
+
+
+ /**
+ * Retrieves an initialized instance of this password storage scheme.
+ *
+ * @return An initialized instance of this password storage scheme.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ protected PasswordStorageScheme getScheme()
+ throws Exception
+ {
+ AESPasswordStorageScheme scheme = new AESPasswordStorageScheme();
+
+ AESPasswordStorageSchemeCfg configuration =
+ AdminTestCaseUtils.getConfiguration(
+ AESPasswordStorageSchemeCfgDefn.getInstance(),
+ configEntry.getEntry());
+
+ scheme.initializePasswordStorageScheme(configuration);
+ return scheme;
+ }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/BlowfishPasswordStorageSchemeTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/BlowfishPasswordStorageSchemeTestCase.java
new file mode 100644
index 0000000..f294fc9
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/BlowfishPasswordStorageSchemeTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import org.opends.server.admin.server.AdminTestCaseUtils;
+import org.opends.server.admin.std.meta.BlowfishPasswordStorageSchemeCfgDefn;
+import org.opends.server.admin.std.server.BlowfishPasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+
+
+
+/**
+ * A set of test cases for the Blowfish password storage scheme.
+ */
+public class BlowfishPasswordStorageSchemeTestCase
+ extends PasswordStorageSchemeTestCase
+{
+ /**
+ * Creates a new instance of this storage scheme test case.
+ */
+ public BlowfishPasswordStorageSchemeTestCase()
+ {
+ super("cn=Blowfish,cn=Password Storage Schemes,cn=config");
+ }
+
+
+
+ /**
+ * Retrieves an initialized instance of this password storage scheme.
+ *
+ * @return An initialized instance of this password storage scheme.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ protected PasswordStorageScheme getScheme()
+ throws Exception
+ {
+ BlowfishPasswordStorageScheme scheme = new BlowfishPasswordStorageScheme();
+
+ BlowfishPasswordStorageSchemeCfg configuration =
+ AdminTestCaseUtils.getConfiguration(
+ BlowfishPasswordStorageSchemeCfgDefn.getInstance(),
+ configEntry.getEntry());
+
+ scheme.initializePasswordStorageScheme(configuration);
+ return scheme;
+ }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RC4PasswordStorageSchemeTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RC4PasswordStorageSchemeTestCase.java
new file mode 100644
index 0000000..6ab26d9
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RC4PasswordStorageSchemeTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import org.opends.server.admin.server.AdminTestCaseUtils;
+import org.opends.server.admin.std.meta.RC4PasswordStorageSchemeCfgDefn;
+import org.opends.server.admin.std.server.RC4PasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+
+
+
+/**
+ * A set of test cases for the RC4 password storage scheme.
+ */
+public class RC4PasswordStorageSchemeTestCase
+ extends PasswordStorageSchemeTestCase
+{
+ /**
+ * Creates a new instance of this storage scheme test case.
+ */
+ public RC4PasswordStorageSchemeTestCase()
+ {
+ super("cn=RC4,cn=Password Storage Schemes,cn=config");
+ }
+
+
+
+ /**
+ * Retrieves an initialized instance of this password storage scheme.
+ *
+ * @return An initialized instance of this password storage scheme.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ protected PasswordStorageScheme getScheme()
+ throws Exception
+ {
+ RC4PasswordStorageScheme scheme = new RC4PasswordStorageScheme();
+
+ RC4PasswordStorageSchemeCfg configuration =
+ AdminTestCaseUtils.getConfiguration(
+ RC4PasswordStorageSchemeCfgDefn.getInstance(),
+ configEntry.getEntry());
+
+ scheme.initializePasswordStorageScheme(configuration);
+ return scheme;
+ }
+}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TripleDESPasswordStorageSchemeTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TripleDESPasswordStorageSchemeTestCase.java
new file mode 100644
index 0000000..118883d
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TripleDESPasswordStorageSchemeTestCase.java
@@ -0,0 +1,76 @@
+/*
+ * 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 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.extensions;
+
+
+
+import org.opends.server.admin.server.AdminTestCaseUtils;
+import org.opends.server.admin.std.meta.TripleDESPasswordStorageSchemeCfgDefn;
+import org.opends.server.admin.std.server.TripleDESPasswordStorageSchemeCfg;
+import org.opends.server.api.PasswordStorageScheme;
+
+
+
+/**
+ * A set of test cases for the 3DES password storage scheme.
+ */
+public class TripleDESPasswordStorageSchemeTestCase
+ extends PasswordStorageSchemeTestCase
+{
+ /**
+ * Creates a new instance of this storage scheme test case.
+ */
+ public TripleDESPasswordStorageSchemeTestCase()
+ {
+ super("cn=3DES,cn=Password Storage Schemes,cn=config");
+ }
+
+
+
+ /**
+ * Retrieves an initialized instance of this password storage scheme.
+ *
+ * @return An initialized instance of this password storage scheme.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ protected PasswordStorageScheme getScheme()
+ throws Exception
+ {
+ TripleDESPasswordStorageScheme scheme =
+ new TripleDESPasswordStorageScheme();
+
+ TripleDESPasswordStorageSchemeCfg configuration =
+ AdminTestCaseUtils.getConfiguration(
+ TripleDESPasswordStorageSchemeCfgDefn.getInstance(),
+ configEntry.getEntry());
+
+ scheme.initializePasswordStorageScheme(configuration);
+ return scheme;
+ }
+}
+
--
Gitblit v1.10.0