mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
10.56.2007 66e851eb4f47f909a235549ead09ef159fd20f88
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.

Note that while these password storage schemes are functional, they rely on the
crypto manager, which is not fully implemented. The storage schemes are not
exposed in the server configuration because the crypto manager does not have
any mechanism to persist secret keys for symmetric encryption. Until the
crypto manager provides persistence for these keys, passwords encoded using
these schemes will not be usable after the server is restarted. Once the
crypto manager implementation is complete, these schemes should be exposed in
the server configuration.

OpenDS Issue Numbers: 315, 316, 317, 318
12 files added
5 files modified
1947 ■■■■■ changed files
opends/resource/admin/abbreviations.xsl 1 ●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif 14 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/AESPasswordStorageSchemeConfiguration.xml 63 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/BlowfishPasswordStorageSchemeConfiguration.xml 63 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/RC4PasswordStorageSchemeConfiguration.xml 63 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/TripleDESPasswordStorageSchemeConfiguration.xml 63 ●●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension.properties 5 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java 310 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java 310 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/ExtensionsConstants.java 98 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java 310 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java 310 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/resource/config-changes.ldif 36 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AESPasswordStorageSchemeTestCase.java 75 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/BlowfishPasswordStorageSchemeTestCase.java 75 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RC4PasswordStorageSchemeTestCase.java 75 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TripleDESPasswordStorageSchemeTestCase.java 76 ●●●●● patch | view | raw | blame | history
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>
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' )
opends/src/admin/defn/org/opends/server/admin/std/AESPasswordStorageSchemeConfiguration.xml
New file
@@ -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>
opends/src/admin/defn/org/opends/server/admin/std/BlowfishPasswordStorageSchemeConfiguration.xml
New file
@@ -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>
opends/src/admin/defn/org/opends/server/admin/std/RC4PasswordStorageSchemeConfiguration.xml
New file
@@ -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>
opends/src/admin/defn/org/opends/server/admin/std/TripleDESPasswordStorageSchemeConfiguration.xml
New file
@@ -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>
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
opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
New file
@@ -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;
  }
}
opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
New file
@@ -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;
  }
}
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.
   */
opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
New file
@@ -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;
  }
}
opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
New file
@@ -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;
  }
}
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
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/AESPasswordStorageSchemeTestCase.java
New file
@@ -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;
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/BlowfishPasswordStorageSchemeTestCase.java
New file
@@ -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;
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/RC4PasswordStorageSchemeTestCase.java
New file
@@ -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;
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/TripleDESPasswordStorageSchemeTestCase.java
New file
@@ -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;
  }
}