From bcb182fbd407f8e107207244eff5149b9145bdb9 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Mon, 22 Jul 2013 13:10:15 +0000
Subject: [PATCH] CR-2009 Fix OPENDJ-1036 Cleanup passwords in memory?

---
 opends/src/server/org/opends/server/util/BSDMD5Crypt.java |   48 +++++++++++++++++++++++-------------------------
 1 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/opends/src/server/org/opends/server/util/BSDMD5Crypt.java b/opends/src/server/org/opends/server/util/BSDMD5Crypt.java
index a0582f9..c262ddb 100644
--- a/opends/src/server/org/opends/server/util/BSDMD5Crypt.java
+++ b/opends/src/server/org/opends/server/util/BSDMD5Crypt.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- * Copyright 2010 ForgeRock AS
+ * Copyright 2010-2013 ForgeRock AS
  *
  * BSD-compatible md5 password crypt
  * Ported to Java from C based on crypt-md5.c by Poul-Henning Kamp,
@@ -36,9 +36,13 @@
  */
 package org.opends.server.util;
 
+import org.opends.server.types.ByteSequence;
+import org.opends.server.types.ByteString;
+
 import java.security.MessageDigest;
 import java.security.SecureRandom;
 import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
 
 /**
  * BSD MD5 Crypt algorithm, ported from C.
@@ -62,19 +66,10 @@
       value >>= 6;
     }
 
-    return (output.toString());
+    return output.toString();
   }
 
-  /* Clear bytes, equivalent of memset */
-  static private void clearBytes(byte bytes[])
-  {
-    for (int i = 0; i < bytes.length; i++)
-    {
-      bytes[i] = 0;
-    }
-  }
-
-  /**
+    /**
    * Encode the supplied password in BSD MD5 crypt form, using
    * a random salt.
    *
@@ -85,7 +80,7 @@
    * @throws NoSuchAlgorithmException If the MD5 algorithm is not supported.
    *
    */
-  static public String crypt(String password)
+  static public String crypt(ByteSequence password)
           throws NoSuchAlgorithmException
   {
     SecureRandom randomGenerator = new SecureRandom();
@@ -115,11 +110,12 @@
    * @throws NoSuchAlgorithmException If the MD5 algorithm is not supported.
    *
    */
-  static public String crypt(String password, String salt)
+  static public String crypt(ByteSequence password, String salt)
           throws NoSuchAlgorithmException
   {
     MessageDigest ctx, ctx1;
     byte digest1[], digest[];
+    byte[] plaintextBytes = password.toByteArray();
 
     /* First skip the magic string */
     if (salt.startsWith(magic))
@@ -142,7 +138,7 @@
     ctx = MessageDigest.getInstance("MD5");
 
     /* The password first, since that is what is most unknown */
-    ctx.update(password.getBytes());
+    ctx.update(plaintextBytes);
 
     /* Then our magic string */
     ctx.update(magic.getBytes());
@@ -152,9 +148,9 @@
 
     /* Then just as many characters of the MD5(password,salt,password) */
     ctx1 = MessageDigest.getInstance("MD5");
-    ctx1.update(password.getBytes());
+    ctx1.update(plaintextBytes);
     ctx1.update(salt.getBytes());
-    ctx1.update(password.getBytes());
+    ctx1.update(plaintextBytes);
     digest1 = ctx1.digest();
 
 
@@ -164,7 +160,7 @@
     }
 
     /* Don't leave anything around in vm they could use. */
-    clearBytes(digest1);
+    Arrays.fill(digest1, (byte) 0);
 
     /* Then something really weird... */
     for (int i = password.length(); i != 0; i >>= 1)
@@ -174,7 +170,7 @@
         ctx.update(digest1[0]);
       } else
       {
-        ctx.update(password.getBytes()[0]);
+        ctx.update(plaintextBytes[0]);
       }
     }
 
@@ -197,7 +193,7 @@
 
       if ((i & 1) != 0)
       {
-        ctx1.update(password.getBytes());
+        ctx1.update(plaintextBytes);
       } else
       {
         ctx1.update(digest);
@@ -208,14 +204,14 @@
       }
       if ((i % 7) != 0)
       {
-        ctx1.update(password.getBytes());
+        ctx1.update(plaintextBytes);
       }
       if ((i & 1) != 0)
       {
         ctx1.update(digest);
       } else
       {
-        ctx1.update(password.getBytes());
+        ctx1.update(plaintextBytes);
       }
       digest = ctx1.digest();
     }
@@ -241,7 +237,8 @@
     output.append(intTo64(l, 2));
 
     /* Don't leave anything around in vm they could use. */
-    clearBytes(digest);
+    Arrays.fill(digest, (byte) 0);
+    Arrays.fill(plaintextBytes, (byte) 0);
     ctx = null;
     ctx1 = null;
 
@@ -276,10 +273,11 @@
     {
       if (argv.length == 2)
       {
-        System.out.println(BSDMD5Crypt.crypt(argv[0], argv[1]));
+        System.out.println(BSDMD5Crypt.crypt(ByteString.valueOf(argv[0]),
+                argv[1]));
       } else
       {
-        System.out.println(BSDMD5Crypt.crypt(argv[0]));
+        System.out.println(BSDMD5Crypt.crypt(ByteString.valueOf(argv[0])));
       }
     } catch (Exception e)
     {

--
Gitblit v1.10.0