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

Ludovic Poitou
10.57.2010 aba086d243c22f496db8bd8e4f689f6a43126f2e
opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 */
package org.opends.server.extensions;
@@ -82,7 +83,8 @@
   */
  private static final int NUM_SALT_BYTES = 8;
  // Size of the dgiest in bytes.
  private static final int SHA256_LENGTH = 256 / 8;
  // The message digest that will actually be used to generate the 256-bit SHA-2
  // hashes.
@@ -270,18 +272,21 @@
  public boolean passwordMatches(ByteSequence plaintextPassword,
                                 ByteSequence storedPassword)
  {
    // Base64-decode the stored value and take the last 8 bytes as the salt.
    byte[] saltBytes = new byte[NUM_SALT_BYTES];
    byte[] digestBytes;
    // Base64-decode the stored value and take the first 256 bits
    // (SHA256_LENGTH) as the digest.
    byte[] saltBytes;
    byte[] digestBytes = new byte[SHA256_LENGTH];
    int saltLength = 0;
    try
    {
      byte[] decodedBytes = Base64.decode(storedPassword.toString());
      int digestLength = decodedBytes.length - NUM_SALT_BYTES;
      digestBytes = new byte[digestLength];
      System.arraycopy(decodedBytes, 0, digestBytes, 0, digestLength);
      System.arraycopy(decodedBytes, digestLength, saltBytes, 0,
                       NUM_SALT_BYTES);
      saltLength = decodedBytes.length - SHA256_LENGTH;
      saltBytes = new byte[saltLength];
      System.arraycopy(decodedBytes, 0, digestBytes, 0, SHA256_LENGTH);
      System.arraycopy(decodedBytes, SHA256_LENGTH, saltBytes, 0,
                       saltLength);
    }
    catch (Exception e)
    {
@@ -299,10 +304,10 @@
    // Use the salt to generate a digest based on the provided plain-text value.
    int plainBytesLength = plaintextPassword.length();
    byte[] plainPlusSalt = new byte[plainBytesLength + NUM_SALT_BYTES];
    byte[] plainPlusSalt = new byte[plainBytesLength + saltLength];
    plaintextPassword.copyTo(plainPlusSalt);
    System.arraycopy(saltBytes, 0,plainPlusSalt, plainBytesLength,
                     NUM_SALT_BYTES);
                     saltLength);
    byte[] userDigestBytes;
opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 */
package org.opends.server.extensions;
@@ -83,6 +84,8 @@
  private static final int NUM_SALT_BYTES = 8;
  // The size of the digest in bytes.
  private static final int SHA384_LENGTH = 384 / 8;
  // The message digest that will actually be used to generate the 384-bit SHA-2
  // hashes.
@@ -270,18 +273,21 @@
  public boolean passwordMatches(ByteSequence plaintextPassword,
                                 ByteSequence storedPassword)
  {
    // Base64-decode the stored value and take the last 8 bytes as the salt.
    byte[] saltBytes = new byte[NUM_SALT_BYTES];
    byte[] digestBytes;
    // Base64-decode the stored value and take the first 384 bits
    // (SHA384_LENGTH) as the digest.
    byte[] saltBytes;
    byte[] digestBytes = new byte[SHA384_LENGTH];
    int saltLength = 0;
    try
    {
      byte[] decodedBytes = Base64.decode(storedPassword.toString());
      int digestLength = decodedBytes.length - NUM_SALT_BYTES;
      digestBytes = new byte[digestLength];
      System.arraycopy(decodedBytes, 0, digestBytes, 0, digestLength);
      System.arraycopy(decodedBytes, digestLength, saltBytes, 0,
                       NUM_SALT_BYTES);
      saltLength = decodedBytes.length - SHA384_LENGTH;
      saltBytes = new byte[saltLength];
      System.arraycopy(decodedBytes, 0, digestBytes, 0, SHA384_LENGTH);
      System.arraycopy(decodedBytes, SHA384_LENGTH, saltBytes, 0,
                       saltLength);
    }
    catch (Exception e)
    {
@@ -299,10 +305,10 @@
    // Use the salt to generate a digest based on the provided plain-text value.
    int plainBytesLength = plaintextPassword.length();
    byte[] plainPlusSalt = new byte[plainBytesLength + NUM_SALT_BYTES];
    byte[] plainPlusSalt = new byte[plainBytesLength + saltLength];
    plaintextPassword.copyTo(plainPlusSalt);
    System.arraycopy(saltBytes, 0,plainPlusSalt, plainBytesLength,
                     NUM_SALT_BYTES);
                     saltLength);
    byte[] userDigestBytes;
opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 */
package org.opends.server.extensions;
@@ -83,6 +84,8 @@
  private static final int NUM_SALT_BYTES = 8;
  // The size of the digest in bytes.
  private static final int SHA512_LENGTH = 512 / 8;
  // The message digest that will actually be used to generate the 512-bit SHA-2
  // hashes.
@@ -269,18 +272,21 @@
  public boolean passwordMatches(ByteSequence plaintextPassword,
                                 ByteSequence storedPassword)
  {
    // Base64-decode the stored value and take the last 8 bytes as the salt.
    byte[] saltBytes = new byte[NUM_SALT_BYTES];
    byte[] digestBytes;
    // Base64-decode the stored value and take the first 512 bits
    // (SHA512_LENGTH) as the digest.
    byte[] saltBytes;
    byte[] digestBytes = new byte[SHA512_LENGTH];
    int saltLength = 0;
    try
    {
      byte[] decodedBytes = Base64.decode(storedPassword.toString());
      int digestLength = decodedBytes.length - NUM_SALT_BYTES;
      digestBytes = new byte[digestLength];
      System.arraycopy(decodedBytes, 0, digestBytes, 0, digestLength);
      System.arraycopy(decodedBytes, digestLength, saltBytes, 0,
                       NUM_SALT_BYTES);
      saltLength = decodedBytes.length - SHA512_LENGTH;
      saltBytes = new byte[saltLength];
      System.arraycopy(decodedBytes, 0, digestBytes, 0, SHA512_LENGTH);
      System.arraycopy(decodedBytes, SHA512_LENGTH, saltBytes, 0,
                       saltLength);
    }
    catch (Exception e)
    {
@@ -298,10 +304,10 @@
    // Use the salt to generate a digest based on the provided plain-text value.
    int plainBytesLength = plaintextPassword.length();
    byte[] plainPlusSalt = new byte[plainBytesLength + NUM_SALT_BYTES];
    byte[] plainPlusSalt = new byte[plainBytesLength + saltLength];
    plaintextPassword.copyTo(plainPlusSalt);
    System.arraycopy(saltBytes, 0,plainPlusSalt, plainBytesLength,
                     NUM_SALT_BYTES);
                     saltLength);
    byte[] userDigestBytes;
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PasswordStorageSchemeTestCase.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 ForgeRock AS.
 */
package org.opends.server.extensions;
@@ -301,7 +302,7 @@
   * @param allowPreencoded whether or not to allow pre-encoded passwords
   * @return the previous value for the allow preencoded passwords
   */
  private boolean setAllowPreencodedPasswords(boolean allowPreencoded)
  protected boolean setAllowPreencodedPasswords(boolean allowPreencoded)
          throws Exception
  {
    // This code was borrowed from
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageSchemeTestCase.java
@@ -23,16 +23,22 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 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.server.SaltedSHA256PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.Entry;
@@ -74,5 +80,65 @@
    scheme.initializePasswordStorageScheme(configuration);
    return scheme;
  }
  /**
   * Retrieves a set of passwords (plain and SSHA256 encrypted) that may
   * be used to test the compatibility of SSHA256 passwords.
   * The encrypted versions have been provided by external tools or
   * users
   *
   * @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
  {
    return new Object[][]
    {
      new Object[] { "secret", "{SSHA256}xIar81hLva6DoMGVtk5WWfJTnBvkyAsYkj0phSdBBDW2DC1dXI79cw==" }
    };
}
  @Test(dataProvider = "testSSHA256Passwords")
  public void testAuthSSHA256Passwords(
          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);
    }
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageSchemeTestCase.java
@@ -23,16 +23,23 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2010 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.server.SaltedSHA512PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.types.Entry;
@@ -74,5 +81,65 @@
    scheme.initializePasswordStorageScheme(configuration);
    return scheme;
  }
  /**
   * Retrieves a set of passwords (plain and SSHA512 encrypted) that may
   * be used to test the compatibility of SSHA512 passwords.
   * The encrypted versions have been provided by external tools or
   * users
   *
   * @return  A set of couple (cleartext, encrypted) passwords that
   *          may be used to test the SSHA512 password storage scheme
   */
  @DataProvider(name = "testSSHA512Passwords")
  public Object[][] getTestSSHA512Passwords()
         throws Exception
  {
    return new Object[][]
    {
      new Object[] { "secret", "{SSHA512}8gRXO3lD2fGN3JIhbNJOsh31IRFKnWbDNl+cPH3HoJCkUpxZPG617TnN6Nvl2mVMSBLlzPu2eMpOhCDKoolNG6QCsYf2hppQTAVaqfx25PUJ1ngbuBiNDCpK6Xj5PYZiFwa+cpkY/Pzs77bLn3VMxmHhwa+vowfGhy5RRW+6npQ=" }
    };
}
  @Test(dataProvider = "testSSHA512Passwords")
  public void testAuthSSHA512Passwords(
          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);
    }
  }
}