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

Jean-Noel Rouvignac
12.36.2014 b5841e02419f1d685fdbe4eebcacd6337060b480
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
@@ -62,14 +62,14 @@
 * implementation uses a configurable number of iterations.
 */
public class PBKDF2PasswordStorageScheme
  extends PasswordStorageScheme<PBKDF2PasswordStorageSchemeCfg>
  implements ConfigurationChangeListener<PBKDF2PasswordStorageSchemeCfg>
    extends PasswordStorageScheme<PBKDF2PasswordStorageSchemeCfg>
    implements ConfigurationChangeListener<PBKDF2PasswordStorageSchemeCfg>
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /** The fully-qualified name of this class. */
  private static final String CLASS_NAME =
       "org.opends.server.extensions.PBKDF2PasswordStorageScheme";
      "org.opends.server.extensions.PBKDF2PasswordStorageScheme";
  /**
@@ -93,7 +93,6 @@
  /** The current configuration for this storage scheme. */
  private volatile PBKDF2PasswordStorageSchemeCfg config;
  /**
   * Creates a new instance of this password storage scheme.  Note that no
   * initialization should be performed here, as all initialization should be
@@ -107,8 +106,8 @@
  /** {@inheritDoc} */
  @Override
  public void initializePasswordStorageScheme(
                   PBKDF2PasswordStorageSchemeCfg configuration)
         throws ConfigException, InitializationException
      PBKDF2PasswordStorageSchemeCfg configuration)
      throws ConfigException, InitializationException
  {
    try
    {
@@ -152,18 +151,13 @@
  /** {@inheritDoc} */
  @Override
  public ByteString encodePassword(ByteSequence plaintext)
         throws DirectoryException
      throws DirectoryException
  {
    byte[] saltBytes      = new byte[NUM_SALT_BYTES];
    int    iterations     = config.getPBKDF2Iterations();
    byte[] digestBytes = getDigestBytes(plaintext, saltBytes, iterations);
    // Append the salt to the hashed value and base64-the whole thing.
    byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
    System.arraycopy(digestBytes, 0, hashPlusSalt, 0, digestBytes.length);
    System.arraycopy(saltBytes, 0, hashPlusSalt, digestBytes.length,
                     NUM_SALT_BYTES);
    byte[] digestBytes = encodeWithRandomSalt(plaintext, saltBytes, iterations);
    byte[] hashPlusSalt = concatenateHashPlusSalt(saltBytes, digestBytes);
    return ByteString.valueOf(iterations + ":" + Base64.encode(hashPlusSalt));
  }
@@ -171,7 +165,7 @@
  /** {@inheritDoc} */
  @Override
  public ByteString encodePasswordWithScheme(ByteSequence plaintext)
         throws DirectoryException
      throws DirectoryException
  {
    return ByteString.valueOf('{' + STORAGE_SCHEME_NAME_PBKDF2 + '}'
        + encodePassword(plaintext));
@@ -186,8 +180,8 @@
    // Base64-decode the remaining value and take the last 8 bytes as the salt.
    try
    {
      String stored = storedPassword.toString();
      int pos = stored.indexOf(':');
      final String stored = storedPassword.toString();
      final int pos = stored.indexOf(':');
      if (pos == -1)
      {
        throw new Exception();
@@ -217,43 +211,6 @@
    }
  }
  private boolean encodeAndMatch(ByteSequence plaintextPassword,
      final byte[] saltBytes, byte[] digestBytes, int iterations)
  {
    // Use the salt to generate a digest based on the provided plain-text value.
    int plainBytesLength = plaintextPassword.length();
    byte[] plainPlusSalt = new byte[plainBytesLength + saltBytes.length];
    plaintextPassword.copyTo(plainPlusSalt);
    System.arraycopy(saltBytes, 0, plainPlusSalt, plainBytesLength, saltBytes.length);
    char[] plaintextChars = null;
    synchronized (factoryLock)
    {
      try
      {
        plaintextChars = plaintextPassword.toString().toCharArray();
        KeySpec spec = new PBEKeySpec(
            plaintextChars, saltBytes,
            iterations, SHA1_LENGTH * 8);
        final byte[] userDigestBytes = factory.generateSecret(spec).getEncoded();
        return Arrays.equals(digestBytes, userDigestBytes);
      }
      catch (Exception e)
      {
        logger.traceException(e);
        return false;
      }
      finally
      {
        if (plaintextChars != null)
        {
          Arrays.fill(plaintextChars, '0');
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean supportsAuthPasswordSyntax()
@@ -271,11 +228,11 @@
  /** {@inheritDoc} */
  @Override
  public ByteString encodeAuthPassword(ByteSequence plaintext)
         throws DirectoryException
      throws DirectoryException
  {
    byte[] saltBytes      = new byte[NUM_SALT_BYTES];
    int    iterations     = config.getPBKDF2Iterations();
    byte[] digestBytes = getDigestBytes(plaintext, saltBytes, iterations);
    byte[] digestBytes = encodeWithRandomSalt(plaintext, saltBytes, iterations);
    // Encode and return the value.
    return ByteString.valueOf(AUTH_PASSWORD_SCHEME_NAME_PBKDF2 + '$'
@@ -283,41 +240,6 @@
        + Base64.encode(digestBytes));
  }
  private byte[] getDigestBytes(ByteSequence plaintext, byte[] saltBytes,
      int iterations) throws DirectoryException
  {
    char[] plaintextChars = null;
    synchronized (factoryLock)
    {
      try
      {
        random.nextBytes(saltBytes);
        plaintextChars = plaintext.toString().toCharArray();
        KeySpec spec = new PBEKeySpec(
            plaintextChars, saltBytes,
            iterations, SHA1_LENGTH * 8);
        return factory.generateSecret(spec).getEncoded();
      }
      catch (Exception e)
      {
        logger.traceException(e);
        LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
            CLASS_NAME, getExceptionMessage(e));
        throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
                                     message, e);
      }
      finally
      {
        if (plaintextChars != null)
        {
          Arrays.fill(plaintextChars, '0');
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean authPasswordMatches(ByteSequence plaintextPassword,
@@ -352,7 +274,7 @@
  /** {@inheritDoc} */
  @Override
  public ByteString getPlaintextValue(ByteSequence storedPassword)
         throws DirectoryException
      throws DirectoryException
  {
    LocalizableMessage message =
        ERR_PWSCHEME_NOT_REVERSIBLE.get(STORAGE_SCHEME_NAME_PBKDF2);
@@ -363,7 +285,7 @@
  @Override
  public ByteString getAuthPasswordPlaintextValue(String authInfo,
                                                  String authValue)
         throws DirectoryException
      throws DirectoryException
  {
    LocalizableMessage message =
        ERR_PWSCHEME_NOT_REVERSIBLE.get(AUTH_PASSWORD_SCHEME_NAME_PBKDF2);
@@ -386,54 +308,56 @@
   * user password).
   *
   * @param  passwordBytes  The bytes that make up the clear-text password.
   *
   * @return  The encoded password string, including the scheme name in curly
   *          braces.
   *
   * @throws  DirectoryException  If a problem occurs during processing.
   */
  public static String encodeOffline(byte[] passwordBytes)
         throws DirectoryException
      throws DirectoryException
  {
    byte[] saltBytes      = new byte[NUM_SALT_BYTES];
    int    iterations     = 10000;
    byte[] digestBytes = getDigestBytes(passwordBytes, saltBytes, iterations);
    // Append the salt to the hashed value and base64-the whole thing.
    byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
    final ByteString password = ByteString.wrap(passwordBytes);
    byte[] digestBytes = encodeWithRandomSalt(password, saltBytes, iterations);
    byte[] hashPlusSalt = concatenateHashPlusSalt(saltBytes, digestBytes);
    System.arraycopy(digestBytes, 0, hashPlusSalt, 0, digestBytes.length);
    System.arraycopy(saltBytes, 0, hashPlusSalt, digestBytes.length,
                     NUM_SALT_BYTES);
    return '{' + STORAGE_SCHEME_NAME_PBKDF2 + '}' + iterations + ':' +
      Base64.encode(hashPlusSalt);
    return '{' + STORAGE_SCHEME_NAME_PBKDF2 + '}' + iterations + ':'
        + Base64.encode(hashPlusSalt);
  }
  private static byte[] getDigestBytes(byte[] plaintext, byte[] saltBytes,
  private static byte[] encodeWithRandomSalt(ByteString plaintext, byte[] saltBytes,
      int iterations) throws DirectoryException
  {
    char[] plaintextChars = null;
    try
    {
      SecureRandom.getInstance(SECURE_PRNG_SHA1).nextBytes(saltBytes);
      plaintextChars = plaintext.toString().toCharArray();
      KeySpec spec = new PBEKeySpec(
          plaintextChars, saltBytes,
          iterations, SHA1_LENGTH * 8);
      return SecretKeyFactory
          .getInstance(MESSAGE_DIGEST_ALGORITHM_PBKDF2)
          .generateSecret(spec).getEncoded();
      final SecureRandom random = SecureRandom.getInstance(SECURE_PRNG_SHA1);
      final SecretKeyFactory factory = SecretKeyFactory.getInstance(MESSAGE_DIGEST_ALGORITHM_PBKDF2);
      return encodeWithRandomSalt(plaintext, saltBytes, iterations, random, factory);
    }
    catch (DirectoryException e)
    {
      throw e;
    }
    catch (Exception e)
    {
      logger.traceException(e);
      throw cannotEncodePassword(e);
    }
  }
      LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
          CLASS_NAME, getExceptionMessage(e));
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
          message, e);
  private static byte[] encodeWithSalt(ByteSequence plaintext, byte[] saltBytes,
      int iterations, final SecretKeyFactory factory) throws DirectoryException
  {
    final char[] plaintextChars = plaintext.toString().toCharArray();
    try
    {
      KeySpec spec =
          new PBEKeySpec(plaintextChars, saltBytes, iterations, SHA1_LENGTH * 8);
      return factory.generateSecret(spec).getEncoded();
    }
    catch (Exception e)
    {
      throw cannotEncodePassword(e);
    }
    finally
    {
@@ -444,4 +368,53 @@
    }
  }
  private boolean encodeAndMatch(ByteSequence plaintext, byte[] saltBytes,
      byte[] digestBytes, int iterations)
  {
    synchronized (factoryLock)
    {
      try
      {
        final byte[] userDigestBytes =
            encodeWithSalt(plaintext, saltBytes, iterations, factory);
        return Arrays.equals(digestBytes, userDigestBytes);
      }
      catch (Exception e)
      {
        return false;
      }
    }
  }
  private byte[] encodeWithRandomSalt(ByteSequence plaintext, byte[] saltBytes,
      int iterations) throws DirectoryException
  {
    synchronized (factoryLock)
    {
      return encodeWithRandomSalt(plaintext, saltBytes, iterations, random, factory);
    }
  }
  private static byte[] encodeWithRandomSalt(ByteSequence plaintext, byte[] saltBytes,
      int iterations, SecureRandom random, final SecretKeyFactory factory) throws DirectoryException
  {
    random.nextBytes(saltBytes);
    return encodeWithSalt(plaintext, saltBytes, iterations, factory);
  }
  private static DirectoryException cannotEncodePassword(Exception e)
  {
    logger.traceException(e);
    LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(CLASS_NAME, getExceptionMessage(e));
    return new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e);
  }
  private static byte[] concatenateHashPlusSalt(byte[] saltBytes, byte[] digestBytes) {
    final byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
    System.arraycopy(digestBytes, 0, hashPlusSalt, 0, digestBytes.length);
    System.arraycopy(saltBytes, 0, hashPlusSalt, digestBytes.length, NUM_SALT_BYTES);
    return hashPlusSalt;
  }
}
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/extensions/PKCS5S2PasswordStorageScheme.java
@@ -90,7 +90,6 @@
  /** The secure random number generator to use to generate the salt values. */
  private SecureRandom random;
  /**
   * Creates a new instance of this password storage scheme.  Note that no
   * initialization should be performed here, as all initialization should be
@@ -131,8 +130,7 @@
      throws DirectoryException
  {
    byte[] saltBytes      = new byte[NUM_SALT_BYTES];
    byte[] digestBytes = createRandomSaltAndEncode(plaintext, saltBytes);
    // Append the hashed value to the salt and base64-the whole thing.
    byte[] digestBytes = encodeWithRandomSalt(plaintext, saltBytes);
    byte[] hashPlusSalt = concatenateSaltPlusHash(saltBytes, digestBytes);
    return ByteString.valueOf(Base64.encode(hashPlusSalt));
@@ -156,7 +154,6 @@
    try
    {
      String stored = storedPassword.toString();
      byte[] decodedBytes = Base64.decode(stored);
      if (decodedBytes.length != NUM_SALT_BYTES + SHA1_LENGTH)
@@ -167,8 +164,8 @@
      }
      final int saltLength = NUM_SALT_BYTES;
      byte[] saltBytes = new byte[saltLength];
      byte[] digestBytes = new byte[SHA1_LENGTH];
      final byte[] digestBytes = new byte[SHA1_LENGTH];
      final byte[] saltBytes = new byte[saltLength];
      System.arraycopy(decodedBytes, 0, saltBytes, 0, saltLength);
      System.arraycopy(decodedBytes, saltLength, digestBytes, 0, SHA1_LENGTH);
      return encodeAndMatch(plaintextPassword, saltBytes, digestBytes, iterations);
@@ -202,7 +199,7 @@
      throws DirectoryException
  {
    byte[] saltBytes      = new byte[NUM_SALT_BYTES];
    byte[] digestBytes = createRandomSaltAndEncode(plaintext, saltBytes);
    byte[] digestBytes = encodeWithRandomSalt(plaintext, saltBytes);
    // Encode and return the value.
    return ByteString.valueOf(AUTH_PASSWORD_SCHEME_NAME_PKCS5S2 + '$'
        + iterations + ':' + Base64.encode(saltBytes) + '$'
@@ -219,7 +216,7 @@
      int pos = authInfo.indexOf(':');
      if (pos == -1)
      {
        return false;
        throw new Exception();
      }
      int iterations = Integer.parseInt(authInfo.substring(0, pos));
      byte[] saltBytes   = Base64.decode(authInfo.substring(pos + 1));
@@ -277,87 +274,53 @@
   * user password).
   *
   * @param  passwordBytes  The bytes that make up the clear-text password.
   *
   * @return  The encoded password string, including the scheme name in curly
   *          braces.
   *
   * @throws  DirectoryException  If a problem occurs during processing.
   */
  public static String encodeOffline(byte[] passwordBytes)
      throws DirectoryException
  {
    byte[] saltBytes = new byte[NUM_SALT_BYTES];
    byte[] digestBytes;
    try
    {
      SecureRandom.getInstance(SECURE_PRNG_SHA1).nextBytes(saltBytes);
      char[] plaintextChars = Arrays.toString(passwordBytes).toCharArray();
      KeySpec spec = new PBEKeySpec(plaintextChars, saltBytes,iterations,
          SHA1_LENGTH * 8);
      digestBytes = SecretKeyFactory
          .getInstance(MESSAGE_DIGEST_ALGORITHM_PBKDF2)
          .generateSecret(spec).getEncoded();
    }
    catch (Exception e)
    {
      logger.traceException(e);
      LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
          CLASS_NAME, getExceptionMessage(e));
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
          message, e);
    }
    // Append the hashed value to the salt and base64-the whole thing.
    byte[] digestBytes = encodeWithRandomSalt(ByteString.wrap(passwordBytes), saltBytes);
    byte[] hashPlusSalt = concatenateSaltPlusHash(saltBytes, digestBytes);
    return '{' + STORAGE_SCHEME_NAME_PKCS5S2 + '}' +
        Base64.encode(hashPlusSalt);
  }
  private boolean encodeAndMatch(ByteSequence plaintext,
                                 byte[] saltBytes, byte[] digestBytes, int iterations)
  private static byte[] encodeWithRandomSalt(ByteString plaintext, byte[] saltBytes)
      throws DirectoryException
  {
    try
    {
      byte[] userDigestBytes = encodeWithSalt(plaintext, saltBytes, iterations);
      return Arrays.equals(digestBytes, userDigestBytes);
      final SecureRandom random = SecureRandom.getInstance(SECURE_PRNG_SHA1);
      final SecretKeyFactory factory = SecretKeyFactory.getInstance(MESSAGE_DIGEST_ALGORITHM_PBKDF2);
      return encodeWithRandomSalt(plaintext, saltBytes, random, factory);
    }
    catch (DirectoryException e)
    {
      throw e;
    }
    catch (Exception e)
    {
      return false;
      throw cannotEncodePassword(e);
    }
  }
  private byte[] createRandomSaltAndEncode(ByteSequence plaintext, byte[] saltBytes) throws DirectoryException {
    synchronized(factoryLock)
    {
      random.nextBytes(saltBytes);
      return encodeWithSalt(plaintext, saltBytes, iterations);
    }
  }
  private byte[] encodeWithSalt(ByteSequence plaintext, byte[] saltBytes, int iterations) throws DirectoryException {
    char[] plaintextChars = null;
  private static byte[] encodeWithSalt(ByteSequence plaintext, byte[] saltBytes,
      int iterations, final SecretKeyFactory factory) throws DirectoryException
  {
    final char[] plaintextChars = plaintext.toString().toCharArray();
    try
    {
      plaintextChars = plaintext.toString().toCharArray();
      KeySpec spec = new PBEKeySpec(
          plaintextChars, saltBytes,
          iterations, SHA1_LENGTH * 8);
      KeySpec spec =
          new PBEKeySpec(plaintextChars, saltBytes, iterations, SHA1_LENGTH * 8);
      return factory.generateSecret(spec).getEncoded();
    }
    catch (Exception e)
    {
      logger.traceException(e);
      LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
          CLASS_NAME, getExceptionMessage(e));
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
          message, e);
      throw cannotEncodePassword(e);
    }
    finally
    {
@@ -368,12 +331,52 @@
    }
  }
  private static byte[] concatenateSaltPlusHash(byte[] saltBytes, byte[] digestBytes) {
    byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
  private boolean encodeAndMatch(ByteSequence plaintext, byte[] saltBytes,
      byte[] digestBytes, int iterations)
  {
    synchronized (factoryLock)
    {
      try
      {
        final byte[] userDigestBytes =
            encodeWithSalt(plaintext, saltBytes, iterations, factory);
        return Arrays.equals(digestBytes, userDigestBytes);
      }
      catch (Exception e)
      {
        return false;
      }
    }
  }
  private byte[] encodeWithRandomSalt(ByteSequence plaintext, byte[] saltBytes)
      throws DirectoryException
  {
    synchronized (factoryLock)
    {
      return encodeWithRandomSalt(plaintext, saltBytes, random, factory);
    }
  }
  private static byte[] encodeWithRandomSalt(ByteSequence plaintext, byte[] saltBytes,
      SecureRandom random, final SecretKeyFactory factory) throws DirectoryException
  {
    random.nextBytes(saltBytes);
    return encodeWithSalt(plaintext, saltBytes, iterations, factory);
  }
  private static DirectoryException cannotEncodePassword(Exception e)
  {
    logger.traceException(e);
    LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(CLASS_NAME, getExceptionMessage(e));
    return new DirectoryException(DirectoryServer.getServerErrorResultCode(), message, e);
  }
  private static byte[] concatenateSaltPlusHash(byte[] saltBytes, byte[] digestBytes) {
    final byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
    System.arraycopy(saltBytes, 0, hashPlusSalt, 0, NUM_SALT_BYTES);
    System.arraycopy(digestBytes, 0, hashPlusSalt, NUM_SALT_BYTES,
        digestBytes.length);
    System.arraycopy(digestBytes, 0, hashPlusSalt, NUM_SALT_BYTES, digestBytes.length);
    return hashPlusSalt;
  }
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/CryptPasswordStorageSchemeTestCase.java
@@ -27,43 +27,26 @@
 */
package org.opends.server.extensions;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.ArrayList;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.CryptPasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.CryptPasswordStorageSchemeCfg;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.PasswordPolicy;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.schema.AuthPasswordSyntax;
import org.opends.server.schema.UserPasswordSyntax;
import org.opends.server.types.Attributes;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.ResultCode;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.opends.server.extensions.PasswordStorageSchemeTestCase.*;
/**
 * A set of test cases for the crypt password storage scheme.
 */
@SuppressWarnings("javadoc")
public class CryptPasswordStorageSchemeTestCase
       extends ExtensionsTestCase
{
  // Names of all the crypt algorithms we want to test.
  private static final String[] names = { "unix", "md5", "sha256", "sha512" };
@@ -81,7 +64,7 @@
   * Ensures that the Directory Server is started before running any of these
   * tests.
   */
  @BeforeClass()
  @BeforeClass
  public void startServer() throws Exception
  {
    TestCaseUtils.startServer();
@@ -99,31 +82,7 @@
  @DataProvider(name = "testPasswords")
  public Object[][] getTestPasswords()
  {
    return new Object[][]
    {
      new Object[] { ByteString.empty() },
      new Object[] { ByteString.valueOf("") },
      new Object[] { ByteString.valueOf("\u0000") },
      new Object[] { ByteString.valueOf("\t") },
      new Object[] { ByteString.valueOf("\n") },
      new Object[] { ByteString.valueOf("\r\n") },
      new Object[] { ByteString.valueOf(" ") },
      new Object[] { ByteString.valueOf("Test1\tTest2\tTest3") },
      new Object[] { ByteString.valueOf("Test1\nTest2\nTest3") },
      new Object[] { ByteString.valueOf("Test1\r\nTest2\r\nTest3") },
      new Object[] { ByteString.valueOf("a") },
      new Object[] { ByteString.valueOf("ab") },
      new Object[] { ByteString.valueOf("abc") },
      new Object[] { ByteString.valueOf("abcd") },
      new Object[] { ByteString.valueOf("abcde") },
      new Object[] { ByteString.valueOf("abcdef") },
      new Object[] { ByteString.valueOf("abcdefg") },
      new Object[] { ByteString.valueOf("abcdefgh") },
      new Object[] { ByteString.valueOf("The Quick Brown Fox Jumps Over " +
                                         "The Lazy Dog") },
      new Object[] { ByteString.valueOf("\u00BFD\u00F3nde est\u00E1 el " +
                                         "ba\u00F1o?") }
    };
    return getTestPasswordsStatic();
  }
@@ -132,7 +91,6 @@
   * provided password, and ensures that the encoded value is correct.
   *
   * @param  plaintext  The plain-text version of the password to encode.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "testPasswords")
@@ -141,94 +99,15 @@
  {
    for (String name : names)
    {
      CryptPasswordStorageScheme scheme = getScheme(name);
      assertNotNull(scheme);
      assertNotNull(scheme.getStorageSchemeName());
      ByteString encodedPassword = scheme.encodePassword(plaintext);
      assertNotNull(encodedPassword);
      assertTrue(scheme.passwordMatches(plaintext, encodedPassword));
      assertFalse(scheme.passwordMatches(plaintext,
                                         ByteString.valueOf("garbage")));
      ByteString schemeEncodedPassword =
           scheme.encodePasswordWithScheme(plaintext);
      String[] pwComponents = UserPasswordSyntax.decodeUserPassword(
                                   schemeEncodedPassword.toString());
      assertNotNull(pwComponents);
      if (scheme.supportsAuthPasswordSyntax())
      {
        assertNotNull(scheme.getAuthPasswordSchemeName());
        ByteString encodedAuthPassword = scheme.encodeAuthPassword(plaintext);
        StringBuilder[] authPWComponents =
             AuthPasswordSyntax.decodeAuthPassword(
                  encodedAuthPassword.toString());
        assertTrue(scheme.authPasswordMatches(plaintext,
                                              authPWComponents[1].toString(),
                                              authPWComponents[2].toString()));
        assertFalse(scheme.authPasswordMatches(plaintext, ",", "foo"));
        assertFalse(scheme.authPasswordMatches(plaintext, "foo", ","));
      }
      else
      {
        try
        {
          scheme.encodeAuthPassword(plaintext);
          throw new Exception("Expected encodedAuthPassword to fail for scheme " +
                              scheme.getStorageSchemeName() +
                              " because it doesn't support auth passwords.");
        }
        catch (DirectoryException de)
        {
          // This was expected.
        }
        assertFalse(scheme.authPasswordMatches(plaintext, "foo", "bar"));
      }
      if (scheme.isReversible())
      {
        assertEquals(scheme.getPlaintextValue(encodedPassword), plaintext);
      }
      else
      {
        try
        {
          scheme.getPlaintextValue(encodedPassword);
          throw new Exception("Expected getPlaintextValue to fail for scheme " +
                              scheme.getStorageSchemeName() +
                              " because it is not reversible.");
        }
        catch (DirectoryException de)
        {
          // This was expected.
        }
      }
      scheme.isStorageSchemeSecure();
      testStorageScheme(plaintext, getScheme(name));
    }
  }
  @DataProvider
  public Object[][] passwordsForBinding()
  {
    return new Object[][]
    {
      // In the case of a clear-text password, these values will be shoved
      // un-excaped into an LDIF file, so make sure they don't include \n
      // or other characters that will cause LDIF parsing errors.
      // We really don't need many test cases here, since that functionality
      // is tested above.
      new Object[] { ByteString.valueOf("a") },
      new Object[] { ByteString.valueOf("abcdefgh") },
      new Object[] { ByteString.valueOf("abcdefghi") },
    };
    return PasswordStorageSchemeTestCase.passwordsForBinding();
  }
@@ -243,88 +122,10 @@
  {
    for (String name: names)
    {
      // Start/clear-out the memory backend
      TestCaseUtils.initializeTestBackend(true);
      setAllowPreencodedPasswords(true);
      CryptPasswordStorageScheme scheme = getScheme(name);
      ByteString schemeEncodedPassword =
          scheme.encodePasswordWithScheme(plainPassword);
      //
      // This code creates a user with the encoded password,
      // and then verifies that they can bind with the raw password.
      //
      Entry userEntry = TestCaseUtils.makeEntry(
          "dn: uid=test.user,o=test",
          "objectClass: top",
          "objectClass: person",
          "objectClass: organizationalPerson",
          "objectClass: inetOrgPerson",
          "uid: test.user",
          "givenName: Test",
          "sn: User",
          "cn: Test User",
          "ds-privilege-name: bypass-acl",
          "userPassword: " + schemeEncodedPassword.toString());
      // Add the entry
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=test.user,o=test",
          plainPassword.toString()),
          "Failed to bind when pre-encoded password = \"" +
              schemeEncodedPassword.toString() + "\" and " +
              "plaintext password = \"" +
              plainPassword.toString() + "\"");
      testSettingEncodedPassword(plainPassword, getScheme(name));
    }
  }
  /**
   * Sets whether or not to allow pre-encoded password values for the
   * current password storage scheme and returns the previous value so that
   * it can be restored.
   *
   * @param allowPreencoded whether or not to allow pre-encoded passwords
   * @return the previous value for the allow preencoded passwords
   */
  private boolean setAllowPreencodedPasswords(boolean allowPreencoded)
          throws Exception
  {
    // This code was borrowed from
    // PasswordPolicyTestCase.testAllowPreEncodedPasswordsAuth
    boolean previousValue = false;
    try {
      DN dn = DN.valueOf("cn=Default Password Policy,cn=Password Policies,cn=config");
      PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn);
      previousValue = p.isAllowPreEncodedPasswords();
      String attr  = "ds-cfg-allow-pre-encoded-passwords";
      ArrayList<Modification> mods = new ArrayList<Modification>();
      mods.add(new Modification(ModificationType.REPLACE,
          Attributes.create(attr, String.valueOf(allowPreencoded))));
      InternalClientConnection conn =
           InternalClientConnection.getRootConnection();
      ModifyOperation modifyOperation = conn.processModify(dn, mods);
      assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
      p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn);
      assertEquals(p.isAllowPreEncodedPasswords(), allowPreencoded);
    } catch (Exception e) {
      System.err.println("Failed to set ds-cfg-allow-pre-encoded-passwords " +
                         " to " + allowPreencoded);
      e.printStackTrace();
      throw e;
    }
    return previousValue;
  }
  /**
   * Retrieves a set of passwords (plain and variously hashed) that may
   * be used to test the different Unix "crypt" algorithms used by the Crypt
@@ -337,7 +138,6 @@
   *          may be used to test the different algorithms used by the Crypt
   *          password storage scheme.
   */
  @DataProvider(name = "testCryptPasswords")
  public Object[][] getTestCryptPasswords()
         throws Exception
@@ -361,38 +161,7 @@
          String plaintextPassword,
          String encodedPassword) throws Exception
  {
      // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try {
      Entry userEntry = TestCaseUtils.makeEntry(
       "dn: uid=testCrypt.user,o=test",
       "objectClass: top",
       "objectClass: person",
       "objectClass: organizationalPerson",
       "objectClass: inetOrgPerson",
       "uid: testCrypt.user",
       "givenName: TestCrypt",
       "sn: User",
       "cn: TestCrypt User",
       "userPassword: " + encodedPassword);
      // Add the entry
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=testCrypt.user,o=test",
                  plaintextPassword),
               "Failed to bind when pre-encoded password = \"" +
               encodedPassword + "\" and " +
               "plaintext password = \"" +
               plaintextPassword + "\"" );
    } finally {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
    testAuthPasswords("TestCrypt", plaintextPassword, encodedPassword);
  }
  /**
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PBKDF2PasswordStorageSchemeTestCase.java
@@ -29,11 +29,13 @@
import org.opends.server.admin.std.meta.PBKDF2PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.PBKDF2PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.DirectoryException;
import org.testng.annotations.DataProvider;
/**
 * A set of test cases for the PBKDF2 password storage scheme.
 */
@SuppressWarnings("javadoc")
public class PBKDF2PasswordStorageSchemeTestCase
       extends PasswordStorageSchemeTestCase
{
@@ -84,4 +86,9 @@
    return scheme;
  }
  @Override
  protected String encodeOffline(final byte[] plaintextBytes) throws DirectoryException
  {
    return PBKDF2PasswordStorageScheme.encodeOffline(plaintextBytes);
  }
}
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PKCS5S2PasswordStorageSchemeTestCase.java
@@ -25,17 +25,14 @@
 */
package org.opends.server.extensions;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.PKCS5S2PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.PKCS5S2PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.Entry;
import org.opends.server.types.DirectoryException;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
 * A set of test cases for the PKCS5S2 password storage scheme.
 */
@@ -138,34 +135,13 @@
          String plaintextPassword,
          String encodedPassword) throws Exception
  {
    // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    testAuthPasswords("TestPKCS5S2", plaintextPassword, encodedPassword);
  }
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try {
      Entry userEntry = TestCaseUtils.makeEntry(
       "dn: uid=testPKCS5S2.user,o=test",
       "objectClass: top",
       "objectClass: person",
       "objectClass: organizationalPerson",
       "objectClass: inetOrgPerson",
       "uid: testPKCS5S2.user",
       "givenName: TestPKCS5S2",
       "sn: User",
       "cn: TestPKCS5S2 User",
       "userPassword: " + encodedPassword);
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=testPKCS5S2.user,o=test", plaintextPassword),
               "Failed to bind when pre-encoded password = \"" +
               encodedPassword + "\" and " +
               "plaintext password = \"" +
               plaintextPassword + "\"" );
    } finally {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
  @Override
  protected String encodeOffline(final byte[] plaintextBytes) throws DirectoryException
  {
    return PKCS5S2PasswordStorageScheme.encodeOffline(plaintextBytes);
  }
}
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/PasswordStorageSchemeTestCase.java
@@ -26,10 +26,6 @@
 */
package org.opends.server.extensions;
import static org.testng.Assert.*;
import java.util.ArrayList;
import org.opends.server.TestCaseUtils;
@@ -53,18 +49,22 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
 * A set of generic test cases for password storage schemes.
 */
@SuppressWarnings("javadoc")
public abstract class PasswordStorageSchemeTestCase
       extends ExtensionsTestCase
{
  // The configuration entry for this password storage scheme.
  /** The configuration entry for this password storage scheme. */
  protected ConfigEntry configEntry;
  // The string representation of the DN of the configuration entry for this
  // password storage scheme.
  /**
   * The string representation of the DN of the configuration entry for this
   * password storage scheme.
   */
  private String configDNString;
@@ -91,9 +91,8 @@
   * Ensures that the Directory Server is started before running any of these
   * tests.
   */
  @BeforeClass()
  public void startServer()
         throws Exception
  @BeforeClass
  public void startServer() throws Exception
  {
    TestCaseUtils.startServer();
@@ -115,6 +114,11 @@
  @DataProvider(name = "testPasswords")
  public Object[][] getTestPasswords()
  {
    return getTestPasswordsStatic();
  }
  static Object[][] getTestPasswordsStatic()
  {
    return new Object[][]
    {
      new Object[] { ByteString.empty() },
@@ -149,14 +153,18 @@
   * provided password, and ensures that the encoded value is correct.
   *
   * @param  plaintext  The plain-text version of the password to encode.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "testPasswords")
  public void testStorageScheme(ByteString plaintext)
         throws Exception
  {
    PasswordStorageScheme scheme = getScheme();
    testStorageScheme(plaintext, getScheme());
  }
  static void testStorageScheme(ByteString plaintext,
      PasswordStorageScheme<?> scheme) throws Exception
  {
    assertNotNull(scheme);
    assertNotNull(scheme.getStorageSchemeName());
@@ -228,7 +236,7 @@
  @DataProvider
  public Object[][] passwordsForBinding()
  public static Object[][] passwordsForBinding()
  {
    return new Object[][]
    {
@@ -250,21 +258,23 @@
  @Test(dataProvider = "passwordsForBinding")
  public void testSettingEncodedPassword(ByteString plainPassword) throws Exception
  {
    testSettingEncodedPassword(plainPassword, getScheme());
  }
  static void testSettingEncodedPassword(ByteString plainPassword,
      PasswordStorageScheme<?> scheme) throws Exception, DirectoryException
  {
    // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try {
      PasswordStorageScheme scheme = getScheme();
      ByteString schemeEncodedPassword =
           scheme.encodePasswordWithScheme(plainPassword);
      //
      // This code creates a user with the encoded password,
      // and then verifies that they can bind with the raw password.
      //
      Entry userEntry = TestCaseUtils.makeEntry(
           "dn: uid=test.user,o=test",
           "objectClass: top",
@@ -276,17 +286,16 @@
           "sn: User",
           "cn: Test User",
           "ds-privilege-name: bypass-acl",
           "userPassword: " + schemeEncodedPassword.toString());
           "userPassword: " + schemeEncodedPassword);
      // Add the entry
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=test.user,o=test",
                 plainPassword.toString()),
                 "Failed to bind when pre-encoded password = \"" +
                         schemeEncodedPassword.toString() + "\" and " +
                         schemeEncodedPassword + "\" and " +
                         "plaintext password = \"" +
                         plainPassword.toString() + "\"");
                         plainPassword + "\"");
    } finally {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
@@ -301,7 +310,7 @@
   * @param allowPreencoded whether or not to allow pre-encoded passwords
   * @return the previous value for the allow preencoded passwords
   */
  protected boolean setAllowPreencodedPasswords(boolean allowPreencoded)
  protected static boolean setAllowPreencodedPasswords(boolean allowPreencoded)
          throws Exception
  {
    // This code was borrowed from
@@ -335,14 +344,86 @@
    return previousValue;
  }
  protected static void testAuthPasswords(final String upperName,
      String plaintextPassword, String encodedPassword) throws Exception
  {
    // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try
    {
      final String lowerName =
          Character.toLowerCase(upperName.charAt(0)) + upperName.substring(1);
      Entry userEntry = TestCaseUtils.makeEntry(
          "dn: uid=" + lowerName + ".user,o=test",
          "objectClass: top",
          "objectClass: person",
          "objectClass: organizationalPerson",
          "objectClass: inetOrgPerson",
          "uid: " + lowerName + ".user",
          "givenName: " + upperName,
          "sn: User",
          "cn: " + upperName + " User",
          "userPassword: " + encodedPassword);
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind(
          "uid=" + lowerName + ".user,o=test", plaintextPassword),
          "Failed to bind when pre-encoded password = \"" + encodedPassword
          + "\" and " + "plaintext password = \"" + plaintextPassword + "\"");
    }
    finally
    {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
  }
  /**
   * Tests the <CODE>encodeOffline</CODE> method.
   *
   * @param plaintext
   *          The plaintext password to use for the test.
   * @throws Exception
   *           If an unexpected problem occurs.
   */
  @Test(dataProvider = "testPasswords")
  public void testEncodeOffline(ByteString plaintext) throws Exception
  {
    PasswordStorageScheme<?> scheme = getScheme();
    String passwordString = encodeOffline(plaintext.toByteArray());
    if (passwordString != null)
    {
      String[] pwComps = UserPasswordSyntax.decodeUserPassword(passwordString);
      ByteString encodedPassword = ByteString.valueOf(pwComps[1]);
      assertTrue(scheme.passwordMatches(plaintext, encodedPassword));
    }
  }
  /**
   * 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.
   * @return An initialized instance of this password storage scheme.
   * @throws Exception
   *           If an unexpected problem occurs.
   */
  protected abstract PasswordStorageScheme getScheme()
         throws Exception;
  protected abstract PasswordStorageScheme<?> getScheme() throws Exception;
  /**
   * Encodes the provided plaintext password while offline.
   *
   * @param plaintextBytes
   *          The plaintext password in bytes to use for the test.
   * @throws DirectoryException
   *           If an unexpected problem occurs.
   */
  protected String encodeOffline(byte[] plaintextBytes) throws DirectoryException
  {
    return null;
  }
}
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageSchemeTestCase.java
@@ -26,20 +26,11 @@
 */
package org.opends.server.extensions;
import org.testng.annotations.Test;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.SaltedSHA1PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.SaltedSHA1PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.schema.UserPasswordSyntax;
import org.forgerock.opendj.ldap.ByteString;
import static org.testng.Assert.*;
import org.opends.server.types.DirectoryException;
/**
 * A set of test cases for the salted SHA-1 password storage scheme.
@@ -61,11 +52,10 @@
   * 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
  @Override
  protected PasswordStorageScheme<?> getScheme() throws Exception
  {
    SaltedSHA1PasswordStorageScheme scheme =
         new SaltedSHA1PasswordStorageScheme();
@@ -80,35 +70,11 @@
    return scheme;
  }
  /**
   * Tests the <CODE>encodeOffline</CODE> method.
   *
   * @param  plaintext  The plaintext password to use for the test.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(dataProvider = "testPasswords")
  public void testEncodeOffline(ByteString plaintext)
         throws Exception
  /** {@inheritDoc} */
  @Override
  protected String encodeOffline(final byte[] plaintextBytes) throws DirectoryException
  {
    SaltedSHA1PasswordStorageScheme scheme =
         new SaltedSHA1PasswordStorageScheme();
    SaltedSHA1PasswordStorageSchemeCfg configuration =
      AdminTestCaseUtils.getConfiguration(
          SaltedSHA1PasswordStorageSchemeCfgDefn.getInstance(),
          configEntry.getEntry()
          );
    scheme.initializePasswordStorageScheme(configuration);
    String passwordString = SaltedSHA1PasswordStorageScheme.encodeOffline(plaintext.toByteArray());
    String[] pwComps = UserPasswordSyntax.decodeUserPassword(passwordString);
    ByteString encodedPassword = ByteString.valueOf(pwComps[1]);
    assertTrue(scheme.passwordMatches(plaintext, encodedPassword));
    return SaltedSHA1PasswordStorageScheme.encodeOffline(plaintextBytes);
  }
}
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageSchemeTestCase.java
@@ -22,28 +22,21 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 *      Portions Copyright 2010-2014 ForgeRock AS.
 */
package org.opends.server.extensions;
import static org.testng.Assert.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.
            SaltedSHA256PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.meta.SaltedSHA256PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.SaltedSHA256PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.Entry;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * A set of test cases for the salted SHA-256 password storage scheme.
 */
@SuppressWarnings("javadoc")
public class SaltedSHA256PasswordStorageSchemeTestCase
       extends PasswordStorageSchemeTestCase
{
@@ -64,8 +57,8 @@
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  protected PasswordStorageScheme getScheme()
         throws Exception
  @Override
  protected PasswordStorageScheme<?> getScheme() throws Exception
  {
    SaltedSHA256PasswordStorageScheme scheme =
         new SaltedSHA256PasswordStorageScheme();
@@ -89,10 +82,8 @@
   * @return  A set of couple (cleartext, encrypted) passwords that
   *          may be used to test the SSHA256 password storage scheme
   */
  @DataProvider(name = "testSSHA256Passwords")
  public Object[][] getTestSSHA256Passwords()
         throws Exception
  public Object[][] getTestSSHA256Passwords() throws Exception
  {
    return new Object[][]
    {
@@ -105,38 +96,7 @@
          String plaintextPassword,
          String encodedPassword) throws Exception
  {
    // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try {
      Entry userEntry = TestCaseUtils.makeEntry(
       "dn: uid=testSSHA256.user,o=test",
       "objectClass: top",
       "objectClass: person",
       "objectClass: organizationalPerson",
       "objectClass: inetOrgPerson",
       "uid: testSSHA256.user",
       "givenName: TestSSHA256",
       "sn: User",
       "cn: TestSSHA256 User",
       "userPassword: " + encodedPassword);
      // Add the entry
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=testSSHA256.user,o=test",
                  plaintextPassword),
               "Failed to bind when pre-encoded password = \"" +
               encodedPassword + "\" and " +
               "plaintext password = \"" +
               plaintextPassword + "\"" );
    } finally {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
    testAuthPasswords("TestSSHA256", plaintextPassword, encodedPassword);
  }
}
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageSchemeTestCase.java
@@ -22,29 +22,21 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 *      Portions Copyright 2010-2014 ForgeRock AS.
 */
package org.opends.server.extensions;
import static org.testng.Assert.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.
            SaltedSHA384PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.meta.SaltedSHA384PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.SaltedSHA384PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.Entry;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * A set of test cases for the salted SHA-384 password storage scheme.
 */
@SuppressWarnings("javadoc")
public class SaltedSHA384PasswordStorageSchemeTestCase
       extends PasswordStorageSchemeTestCase
{
@@ -65,8 +57,8 @@
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  protected PasswordStorageScheme getScheme()
         throws Exception
  @Override
  protected PasswordStorageScheme<?> getScheme() throws Exception
  {
    SaltedSHA384PasswordStorageScheme scheme =
         new SaltedSHA384PasswordStorageScheme();
@@ -90,10 +82,8 @@
   * @return  A set of couple (cleartext, encrypted) passwords that
   *          may be used to test the SSHA384 password storage scheme
   */
  @DataProvider(name = "testSSHA384Passwords")
  public Object[][] getTestSSHA384Passwords()
         throws Exception
  public Object[][] getTestSSHA384Passwords() throws Exception
  {
    return new Object[][]
    {
@@ -108,38 +98,7 @@
          String plaintextPassword,
          String encodedPassword) throws Exception
  {
    // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try {
      Entry userEntry = TestCaseUtils.makeEntry(
       "dn: uid=testSSHA384.user,o=test",
       "objectClass: top",
       "objectClass: person",
       "objectClass: organizationalPerson",
       "objectClass: inetOrgPerson",
       "uid: testSSHA384.user",
       "givenName: TestSSHA384",
       "sn: User",
       "cn: TestSSHA384 User",
       "userPassword: " + encodedPassword);
      // Add the entry
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=testSSHA384.user,o=test",
                  plaintextPassword),
               "Failed to bind when pre-encoded password = \"" +
               encodedPassword + "\" and " +
               "plaintext password = \"" +
               plaintextPassword + "\"" );
    } finally {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
    testAuthPasswords("TestSSHA384", plaintextPassword, encodedPassword);
  }
}
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageSchemeTestCase.java
@@ -22,29 +22,22 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 *      Portions Copyright 2010-2014 ForgeRock AS.
 */
package org.opends.server.extensions;
import static org.testng.Assert.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.
            SaltedSHA512PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.meta.SaltedSHA512PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.SaltedSHA512PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.Entry;
import org.opends.server.types.DirectoryException;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * A set of test cases for the salted SHA-512 password storage scheme.
 */
@SuppressWarnings("javadoc")
public class SaltedSHA512PasswordStorageSchemeTestCase
       extends PasswordStorageSchemeTestCase
{
@@ -65,8 +58,8 @@
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  protected PasswordStorageScheme getScheme()
         throws Exception
  @Override
  protected PasswordStorageScheme<?> getScheme() throws Exception
  {
    SaltedSHA512PasswordStorageScheme scheme =
         new SaltedSHA512PasswordStorageScheme();
@@ -106,39 +99,13 @@
          String plaintextPassword,
          String encodedPassword) throws Exception
  {
    // Start/clear-out the memory backend
    TestCaseUtils.initializeTestBackend(true);
    boolean allowPreencodedDefault = setAllowPreencodedPasswords(true);
    try {
      Entry userEntry = TestCaseUtils.makeEntry(
       "dn: uid=testSSHA512.user,o=test",
       "objectClass: top",
       "objectClass: person",
       "objectClass: organizationalPerson",
       "objectClass: inetOrgPerson",
       "uid: testSSHA512.user",
       "givenName: TestSSHA512",
       "sn: User",
       "cn: TestSSHA512 User",
       "userPassword: " + encodedPassword);
      // Add the entry
      TestCaseUtils.addEntry(userEntry);
      assertTrue(TestCaseUtils.canBind("uid=testSSHA512.user,o=test",
                  plaintextPassword),
               "Failed to bind when pre-encoded password = \"" +
               encodedPassword + "\" and " +
               "plaintext password = \"" +
               plaintextPassword + "\"" );
    } finally {
      setAllowPreencodedPasswords(allowPreencodedDefault);
    }
    testAuthPasswords("TestSSHA512", plaintextPassword, encodedPassword);
  }
  /** {@inheritDoc} */
  @Override
  protected String encodeOffline(byte[] plaintextBytes) throws DirectoryException
  {
    return SaltedSHA512PasswordStorageScheme.encodeOffline(plaintextBytes);
  }
}