From fa06bc80b027fb99232dd16923721ad8ed649281 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Thu, 08 May 2014 13:15:39 +0000
Subject: [PATCH] Fix OPENDJ-1451: Match non-default salt sizes in SMD5 passwords The code changes were adapted from the SSHA1 class, which was previously updated to match against different size salts.
---
opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java | 31 ++++++++++-----
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageSchemeTestCase.java | 30 +++++++++++++++
2 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java
index a8db68e..4a635ab 100644
--- a/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
- * Portions Copyright 2013 ForgeRock AS
+ * Portions Copyright 2013-2014 ForgeRock AS
*/
package org.opends.server.extensions;
@@ -82,6 +82,8 @@
*/
private static final int NUM_SALT_BYTES = 8;
+ // The number of bytes MD5 algorithm produces
+ private static final int MD5_LENGTH = 16;
// The message digest that will actually be used to generate the MD5 hashes.
@@ -279,16 +281,25 @@
{
// Base64-decode the stored value and take the last 8 bytes as the salt.
byte[] saltBytes = new byte[NUM_SALT_BYTES];
- byte[] digestBytes;
+ byte[] digestBytes = new byte[MD5_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 - MD5_LENGTH;
+ if (saltLength <= 0)
+ {
+ Message message =
+ ERR_PWSCHEME_INVALID_BASE64_DECODED_STORED_PASSWORD.get(
+ storedPassword.toString());
+ ErrorLogger.logError(message);
+ return false;
+ }
+ saltBytes = new byte[saltLength];
+ System.arraycopy(decodedBytes, 0, digestBytes, 0, MD5_LENGTH);
+ System.arraycopy(decodedBytes, MD5_LENGTH, saltBytes, 0,
+ saltLength);
}
catch (Exception e)
{
@@ -306,10 +317,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);
+ System.arraycopy(saltBytes, 0, plainPlusSalt, plainBytesLength,
+ saltLength);
byte[] userDigestBytes;
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageSchemeTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageSchemeTestCase.java
index 2886ecf..441e8dd 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageSchemeTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageSchemeTestCase.java
@@ -22,6 +22,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions Copyright 2014 ForgeRock, AS
*/
package org.opends.server.extensions;
@@ -31,7 +32,11 @@
import org.opends.server.admin.std.meta.SaltedMD5PasswordStorageSchemeCfgDefn;
import org.opends.server.admin.std.server.SaltedMD5PasswordStorageSchemeCfg;
import org.opends.server.api.PasswordStorageScheme;
+import org.opends.server.schema.UserPasswordSyntax;
+import org.opends.server.types.ByteString;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
/**
@@ -72,5 +77,30 @@
scheme.initializePasswordStorageScheme(configuration);
return scheme;
}
+
+
+
+ /**
+ * Tests matching with a different salt size.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test
+ public void testDifferentSaltSize()
+ throws Exception {
+ SaltedMD5PasswordStorageScheme scheme =
+ new SaltedMD5PasswordStorageScheme();
+
+ SaltedMD5PasswordStorageSchemeCfg configuration =
+ AdminTestCaseUtils.getConfiguration(
+ SaltedMD5PasswordStorageSchemeCfgDefn.getInstance(),
+ configEntry.getEntry()
+ );
+
+ scheme.initializePasswordStorageScheme(configuration);
+ // The stored value has a 12 byte salt instead of the default 8
+ assertTrue(scheme.passwordMatches(ByteString.valueOf("password"),
+ ByteString.valueOf("so5s1vK3oEi4uL/oVY3bqs5LRlKjgMN+u4A4bw==")));
+ }
}
--
Gitblit v1.10.0