From 46824550ba084705c3fbb1475b200da1f84b471a Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Thu, 14 Mar 2013 16:20:30 +0000
Subject: [PATCH] CR-1406 Fix OPENDJ-120 Enhancement: Support BSD Crypt SHA256/512 in binding

---
 opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java |   84 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java
index 348a945..fdfa06e 100644
--- a/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java
@@ -23,7 +23,8 @@
  *
  *
  *      Copyright 2008 Sun Microsystems, Inc.
- *      Portions Copyright 2010 ForgeRock AS
+ *      Portions Copyright 2010-2013 ForgeRock AS
+ *      Portions Copyright 2012 Dariusz Janny <dariusz.janny@gmail.com>
  *
  */
 
@@ -34,6 +35,7 @@
 import java.util.ArrayList;
 import java.util.Random;
 
+
 import org.opends.messages.Message;
 import org.opends.server.admin.server.ConfigurationChangeListener;
 import org.opends.server.admin.std.server.PasswordStorageSchemeCfg;
@@ -50,7 +52,6 @@
 import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
 
 
-
 /**
  * This class defines a Directory Server password storage scheme based on the
  * UNIX Crypt algorithm.  This is a legacy one-way digest algorithm
@@ -63,6 +64,7 @@
        extends PasswordStorageScheme<CryptPasswordStorageSchemeCfg>
        implements ConfigurationChangeListener<CryptPasswordStorageSchemeCfg>
 {
+
   /**
    * The fully-qualified name of this class for debugging purposes.
    */
@@ -185,6 +187,40 @@
     return ByteString.valueOf(output);
   }
 
+  private ByteString sha256CryptEncodePassword(ByteSequence plaintext)
+      throws DirectoryException {
+    String output;
+    try
+    {
+      output = Sha2Crypt.sha256Crypt(plaintext.toByteArray());
+    }
+    catch (Exception e)
+    {
+      Message message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
+          CLASS_NAME, stackTraceToSingleLineString(e));
+      throw new DirectoryException(
+          DirectoryServer.getServerErrorResultCode(), message, e);
+    }
+    return ByteString.valueOf(output);
+  }
+
+  private ByteString sha512CryptEncodePassword(ByteSequence plaintext)
+      throws DirectoryException {
+    String output;
+    try
+    {
+      output = Sha2Crypt.sha512Crypt(plaintext.toByteArray());
+    }
+    catch (Exception e)
+    {
+      Message message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
+          CLASS_NAME, stackTraceToSingleLineString(e));
+      throw new DirectoryException(
+          DirectoryServer.getServerErrorResultCode(), message, e);
+    }
+    return ByteString.valueOf(output);
+  }
+
   /**
    * {@inheritDoc}
    */
@@ -201,6 +237,12 @@
       case MD5:
         bytes = md5CryptEncodePassword(plaintext);
         break;
+      case SHA256:
+        bytes = sha256CryptEncodePassword(plaintext);
+        break;
+      case SHA512:
+        bytes = sha512CryptEncodePassword(plaintext);
+        break;
     }
     return bytes;
   }
@@ -267,6 +309,36 @@
     }
   }
 
+  private boolean sha256CryptPasswordMatches(ByteSequence plaintextPassword,
+      ByteSequence storedPassword) {
+    String storedString = storedPassword.toString();
+    try
+    {
+      String userString = Sha2Crypt.sha256Crypt(
+          plaintextPassword.toByteArray(), storedString);
+      return userString.equals(storedString);
+    }
+    catch (Exception e)
+    {
+      return false;
+    }
+  }
+
+  private boolean sha512CryptPasswordMatches(ByteSequence plaintextPassword,
+      ByteSequence storedPassword) {
+    String storedString = storedPassword.toString();
+    try
+    {
+      String userString = Sha2Crypt.sha512Crypt(
+          plaintextPassword.toByteArray(), storedString);
+      return userString.equals(storedString);
+    }
+    catch (Exception e)
+    {
+      return false;
+    }
+  }
+
   /**
    * {@inheritDoc}
    */
@@ -279,6 +351,14 @@
     {
       return md5CryptPasswordMatches(plaintextPassword, storedPassword);
     }
+    else if (storedString.startsWith(Sha2Crypt.getMagicSHA256Prefix()))
+    {
+      return sha256CryptPasswordMatches(plaintextPassword, storedPassword);
+    }
+    else if (storedString.startsWith(Sha2Crypt.getMagicSHA512Prefix()))
+    {
+      return sha512CryptPasswordMatches(plaintextPassword, storedPassword);
+    }
     else
     {
       return unixCryptPasswordMatches(plaintextPassword, storedPassword);

--
Gitblit v1.10.0