From 7fc458b7be71111b4c4a6e91f7b3ed6642b104a1 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Tue, 16 Jul 2013 14:12:20 +0000
Subject: [PATCH] CR-2005 Fix OPENDJ-1036 Cleanup passwords in memory?
---
opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java | 30 +++
opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java | 19 ++
opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java | 29 +++
opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java | 58 +++++++-
opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java | 29 +++
opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java | 19 ++
opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java | 19 ++
opends/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java | 30 +++
opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java | 57 ++++++-
opends/src/server/org/opends/server/extensions/SHA1PasswordStorageScheme.java | 26 +++
opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java | 26 +++
opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java | 20 ++
opends/src/server/org/opends/server/extensions/MD5PasswordStorageScheme.java | 30 +++
13 files changed, 343 insertions(+), 49 deletions(-)
diff --git a/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
index 2a7326f..e07afbe 100644
--- a/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/AESPasswordStorageScheme.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock, AS
*/
package org.opends.server.extensions;
@@ -37,6 +38,8 @@
import org.opends.server.types.*;
import org.opends.server.util.Base64;
+import java.util.Arrays;
+
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -109,10 +112,11 @@
public ByteString encodePassword(ByteSequence plaintext)
throws DirectoryException
{
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_AES,
KEY_SIZE_AES,
plaintextBytes);
@@ -130,6 +134,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
@@ -145,11 +154,11 @@
buffer.append('{');
buffer.append(STORAGE_SCHEME_NAME_AES);
buffer.append('}');
-
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_AES,
KEY_SIZE_AES,
plaintextBytes);
@@ -167,6 +176,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.valueOf(buffer.toString());
}
diff --git a/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
index 889088f..4cfd38b 100644
--- a/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/BlowfishPasswordStorageScheme.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.extensions;
@@ -37,6 +38,8 @@
import org.opends.server.types.*;
import org.opends.server.util.Base64;
+import java.util.Arrays;
+
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -109,10 +112,11 @@
public ByteString encodePassword(ByteSequence plaintext)
throws DirectoryException
{
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes =
cryptoManager.encrypt(CIPHER_TRANSFORMATION_BLOWFISH,
KEY_SIZE_BLOWFISH, plaintextBytes);
@@ -130,6 +134,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
@@ -145,11 +154,12 @@
buffer.append('{');
buffer.append(STORAGE_SCHEME_NAME_BLOWFISH);
buffer.append('}');
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes =
cryptoManager.encrypt(CIPHER_TRANSFORMATION_BLOWFISH,
KEY_SIZE_BLOWFISH, plaintextBytes);
@@ -167,6 +177,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.valueOf(buffer.toString());
}
diff --git a/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java
index fdfa06e..e7e060c 100644
--- a/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/CryptPasswordStorageScheme.java
@@ -31,6 +31,7 @@
package org.opends.server.extensions;
+import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
@@ -131,13 +132,13 @@
private ByteString unixCryptEncodePassword(ByteSequence plaintext)
throws DirectoryException
{
-
+ byte[] plaintextBytes = null;
byte[] digestBytes;
try
{
- // TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ // TODO: can we avoid this copy?
+ plaintextBytes = plaintext.toByteArray();
digestBytes = crypt.crypt(plaintextBytes, randomSalt());
}
catch (Exception e)
@@ -147,6 +148,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.wrap(digestBytes);
}
@@ -190,9 +196,12 @@
private ByteString sha256CryptEncodePassword(ByteSequence plaintext)
throws DirectoryException {
String output;
+ byte[] plaintextBytes = null;
+
try
{
- output = Sha2Crypt.sha256Crypt(plaintext.toByteArray());
+ plaintextBytes = plaintext.toByteArray();
+ output = Sha2Crypt.sha256Crypt(plaintextBytes);
}
catch (Exception e)
{
@@ -201,15 +210,23 @@
throw new DirectoryException(
DirectoryServer.getServerErrorResultCode(), message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.valueOf(output);
}
private ByteString sha512CryptEncodePassword(ByteSequence plaintext)
throws DirectoryException {
String output;
+ byte[] plaintextBytes = null;
+
try
{
- output = Sha2Crypt.sha512Crypt(plaintext.toByteArray());
+ plaintextBytes = plaintext.toByteArray();
+ output = Sha2Crypt.sha512Crypt(plaintextBytes);
}
catch (Exception e)
{
@@ -218,6 +235,11 @@
throw new DirectoryException(
DirectoryServer.getServerErrorResultCode(), message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.valueOf(output);
}
@@ -273,11 +295,12 @@
ByteSequence storedPassword)
{
// TODO: Can we avoid this copy?
- byte[] plaintextPasswordBytes = plaintextPassword.toByteArray();
+ byte[] plaintextPasswordBytes = null;
ByteString userPWDigestBytes;
try
{
+ plaintextPasswordBytes = plaintextPassword.toByteArray();
// The salt is stored as the first two bytes of the storedPassword
// value, and crypt.crypt() only looks at the first two bytes, so
// we can pass it in directly.
@@ -289,6 +312,11 @@
{
return false;
}
+ finally
+ {
+ if (plaintextPasswordBytes != null)
+ Arrays.fill(plaintextPasswordBytes, (byte) 0);
+ }
return userPWDigestBytes.equals(storedPassword);
}
@@ -311,32 +339,46 @@
private boolean sha256CryptPasswordMatches(ByteSequence plaintextPassword,
ByteSequence storedPassword) {
+ byte[] plaintextPasswordBytes = null;
String storedString = storedPassword.toString();
try
{
+ plaintextPasswordBytes = plaintextPassword.toByteArray();
String userString = Sha2Crypt.sha256Crypt(
- plaintextPassword.toByteArray(), storedString);
+ plaintextPasswordBytes, storedString);
return userString.equals(storedString);
}
catch (Exception e)
{
return false;
}
+ finally
+ {
+ if (plaintextPasswordBytes != null)
+ Arrays.fill(plaintextPasswordBytes, (byte) 0);
+ }
}
private boolean sha512CryptPasswordMatches(ByteSequence plaintextPassword,
ByteSequence storedPassword) {
+ byte[] plaintextPasswordBytes = null;
String storedString = storedPassword.toString();
try
{
+ plaintextPasswordBytes = plaintextPassword.toByteArray();
String userString = Sha2Crypt.sha512Crypt(
- plaintextPassword.toByteArray(), storedString);
+ plaintextPasswordBytes, storedString);
return userString.equals(storedString);
}
catch (Exception e)
{
return false;
}
+ finally
+ {
+ if (plaintextPasswordBytes != null)
+ Arrays.fill(plaintextPasswordBytes, (byte) 0);
+ }
}
/**
diff --git a/opends/src/server/org/opends/server/extensions/MD5PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/MD5PasswordStorageScheme.java
index aae5497..0f37d1e 100644
--- a/opends/src/server/org/opends/server/extensions/MD5PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/MD5PasswordStorageScheme.java
@@ -23,12 +23,14 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.extensions;
import java.security.MessageDigest;
+import java.util.Arrays;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.MD5PasswordStorageSchemeCfg;
@@ -141,13 +143,14 @@
throws DirectoryException
{
byte[] digestBytes;
+ byte[] plaintextBytes = null;
synchronized (digestLock)
{
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
digestBytes = messageDigest.digest(plaintextBytes);
}
catch (Exception e)
@@ -162,6 +165,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
return ByteString.valueOf(Base64.encode(digestBytes));
@@ -181,14 +189,15 @@
buffer.append(STORAGE_SCHEME_NAME_MD5);
buffer.append('}');
- // TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ byte[] plaintextBytes = null;
byte[] digestBytes;
synchronized (digestLock)
{
try
{
+ // TODO: Can we avoid this copy?
+ plaintextBytes = plaintext.toByteArray();
digestBytes = messageDigest.digest(plaintextBytes);
}
catch (Exception e)
@@ -203,6 +212,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
buffer.append(Base64.encode(digestBytes));
@@ -220,14 +234,15 @@
public boolean passwordMatches(ByteSequence plaintextPassword,
ByteSequence storedPassword)
{
- // TODO: Can we avoid this copy?
- byte[] plaintextPasswordBytes = plaintextPassword.toByteArray();
+ byte[] plaintextPasswordBytes = null;
ByteString userPWDigestBytes;
synchronized (digestLock)
{
try
{
+ // TODO: Can we avoid this copy?
+ plaintextPasswordBytes = plaintextPassword.toByteArray();
userPWDigestBytes =
ByteString.wrap(messageDigest.digest(plaintextPasswordBytes));
}
@@ -240,6 +255,11 @@
return false;
}
+ finally
+ {
+ if (plaintextPasswordBytes != null)
+ Arrays.fill(plaintextPasswordBytes, (byte) 0);
+ }
}
ByteString storedPWDigestBytes;
diff --git a/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
index 37dbf7c..6c7b98a 100644
--- a/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/PBKDF2PasswordStorageScheme.java
@@ -177,9 +177,10 @@
public ByteString encodePassword(ByteSequence plaintext)
throws DirectoryException
{
- byte[] saltBytes = new byte[NUM_SALT_BYTES];
+ byte[] saltBytes = new byte[NUM_SALT_BYTES];
byte[] digestBytes;
- int iterations = config.getPBKDF2Iterations();
+ char[] plaintextChars = null;
+ int iterations = config.getPBKDF2Iterations();
synchronized(factoryLock)
{
@@ -187,7 +188,8 @@
{
random.nextBytes(saltBytes);
- KeySpec spec = new PBEKeySpec(plaintext.toString().toCharArray(),
+ plaintextChars = plaintext.toString().toCharArray();
+ KeySpec spec = new PBEKeySpec(plaintextChars,
saltBytes, iterations, SHA1_LENGTH * 8);
digestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -203,6 +205,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
@@ -304,13 +311,15 @@
saltLength);
byte[] userDigestBytes;
+ char[] plaintextChars = null;
synchronized (factoryLock)
{
try
{
+ plaintextChars = plaintextPassword.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- plaintextPassword.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
userDigestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -323,6 +332,11 @@
return false;
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -360,9 +374,10 @@
public ByteString encodeAuthPassword(ByteSequence plaintext)
throws DirectoryException
{
- byte[] saltBytes = new byte[NUM_SALT_BYTES];
+ byte[] saltBytes = new byte[NUM_SALT_BYTES];
byte[] digestBytes;
- int iterations = config.getPBKDF2Iterations();
+ char[] plaintextChars = null;
+ int iterations = config.getPBKDF2Iterations();
synchronized(factoryLock)
{
@@ -370,8 +385,9 @@
{
random.nextBytes(saltBytes);
+ plaintextChars = plaintext.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- plaintext.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
digestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -387,6 +403,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
// Encode and return the value.
StringBuilder authPWValue = new StringBuilder();
@@ -446,13 +467,15 @@
saltBytes.length);
byte[] userDigestBytes;
+ char[] plaintextChars = null;
synchronized (factoryLock)
{
try
{
+ plaintextChars = plaintextPassword.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- plaintextPassword.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
userDigestBytes = factory.generateSecret(spec).getEncoded();
}
@@ -465,6 +488,11 @@
return false;
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -540,16 +568,18 @@
public static String encodeOffline(byte[] passwordBytes)
throws DirectoryException
{
- byte[] saltBytes = new byte[NUM_SALT_BYTES];
+ byte[] saltBytes = new byte[NUM_SALT_BYTES];
byte[] digestBytes;
- int iterations = 10000;
+ char[] plaintextChars = null;
+ int iterations = 10000;
try
{
SecureRandom.getInstance(SECURE_PRNG_SHA1).nextBytes(saltBytes);
+ plaintextChars = passwordBytes.toString().toCharArray();
KeySpec spec = new PBEKeySpec(
- passwordBytes.toString().toCharArray(), saltBytes,
+ plaintextChars, saltBytes,
iterations, SHA1_LENGTH * 8);
digestBytes = SecretKeyFactory
.getInstance(MESSAGE_DIGEST_ALGORITHM_PBKDF2)
@@ -567,6 +597,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextChars != null)
+ Arrays.fill(plaintextChars, '0');
+ }
// Append the salt to the hashed value and base64-the whole thing.
byte[] hashPlusSalt = new byte[digestBytes.length + NUM_SALT_BYTES];
diff --git a/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
index 06f963c..6e513a0 100644
--- a/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/RC4PasswordStorageScheme.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.extensions;
@@ -37,6 +38,8 @@
import org.opends.server.types.*;
import org.opends.server.util.Base64;
+import java.util.Arrays;
+
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -108,10 +111,11 @@
public ByteString encodePassword(ByteSequence plaintext)
throws DirectoryException
{
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_RC4,
KEY_SIZE_RC4,
plaintextBytes);
@@ -129,6 +133,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
@@ -144,11 +153,12 @@
buffer.append('{');
buffer.append(STORAGE_SCHEME_NAME_RC4);
buffer.append('}');
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_RC4,
KEY_SIZE_RC4,
plaintextBytes);
@@ -166,6 +176,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.valueOf(buffer.toString());
}
diff --git a/opends/src/server/org/opends/server/extensions/SHA1PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SHA1PasswordStorageScheme.java
index 569c24d..69ec9c9 100644
--- a/opends/src/server/org/opends/server/extensions/SHA1PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SHA1PasswordStorageScheme.java
@@ -23,12 +23,14 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS.
*/
package org.opends.server.extensions;
import java.security.MessageDigest;
+import java.util.Arrays;
import org.opends.messages.Message;
import org.opends.server.admin.std.server.SHA1PasswordStorageSchemeCfg;
@@ -140,13 +142,14 @@
throws DirectoryException
{
byte[] digestBytes;
+ byte[] plaintextBytes = null;
synchronized (digestLock)
{
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
digestBytes = messageDigest.digest(plaintextBytes);
}
catch (Exception e)
@@ -161,6 +164,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
return ByteString.valueOf(Base64.encode(digestBytes));
@@ -181,13 +189,14 @@
buffer.append('}');
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ byte[] plaintextBytes = null;
byte[] digestBytes;
synchronized (digestLock)
{
try
{
+ plaintextBytes = plaintext.toByteArray();
digestBytes = messageDigest.digest(plaintextBytes);
}
catch (Exception e)
@@ -202,6 +211,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
buffer.append(Base64.encode(digestBytes));
@@ -219,13 +233,14 @@
ByteSequence storedPassword)
{
// TODO: Can we avoid this copy?
- byte[] plaintextPasswordBytes = plaintextPassword.toByteArray();
+ byte[] plaintextPasswordBytes = null;
ByteString userPWDigestBytes;
synchronized (digestLock)
{
try
{
+ plaintextPasswordBytes = plaintextPassword.toByteArray();
userPWDigestBytes =
ByteString.wrap(messageDigest.digest(plaintextPasswordBytes));
}
@@ -238,6 +253,11 @@
return false;
}
+ finally
+ {
+ if (plaintextPasswordBytes != null)
+ Arrays.fill(plaintextPasswordBytes, (byte) 0);
+ }
}
ByteString storedPWDigestBytes;
diff --git a/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java
index 38194f4..baafd41 100644
--- a/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SaltedMD5PasswordStorageScheme.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS
*/
package org.opends.server.extensions;
@@ -189,6 +190,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -247,6 +252,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -320,6 +329,10 @@
return false;
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -389,6 +402,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
@@ -438,8 +455,15 @@
synchronized (digestLock)
{
- return Arrays.equals(digestBytes,
+ try
+ {
+ return Arrays.equals(digestBytes,
messageDigest.digest(plainPlusSaltBytes));
+ }
+ finally
+ {
+ Arrays.fill(plainPlusSaltBytes, (byte) 0);
+ }
}
}
diff --git a/opends/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java
index 49bd575..d3278e1 100644
--- a/opends/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SaltedSHA1PasswordStorageScheme.java
@@ -23,7 +23,7 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
- * Portions Copyright 2010 ForgeRock AS.
+ * Portions Copyright 2010-2013 ForgeRock AS.
*/
package org.opends.server.extensions;
@@ -190,6 +190,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -248,6 +252,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -330,6 +338,10 @@
return false;
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -399,6 +411,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
@@ -448,8 +464,15 @@
synchronized (digestLock)
{
- return Arrays.equals(digestBytes,
- messageDigest.digest(plainPlusSaltBytes));
+ try
+ {
+ return Arrays.equals(digestBytes,
+ messageDigest.digest(plainPlusSaltBytes));
+ }
+ finally
+ {
+ Arrays.fill(plainPlusSaltBytes, (byte) 0);
+ }
}
}
@@ -550,6 +573,7 @@
System.arraycopy(digestBytes, 0, digestPlusSalt, 0, digestBytes.length);
System.arraycopy(saltBytes, 0, digestPlusSalt, digestBytes.length,
NUM_SALT_BYTES);
+ Arrays.fill(passwordPlusSalt, (byte) 0);
return "{" + STORAGE_SCHEME_NAME_SALTED_SHA_1 + "}" +
Base64.encode(digestPlusSalt);
diff --git a/opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java
index b51327d..385da73 100644
--- a/opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SaltedSHA256PasswordStorageScheme.java
@@ -23,7 +23,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
- * Portions Copyright 2010 ForgeRock AS.
+ * Portions Copyright 2010-2013 ForgeRock AS.
*/
package org.opends.server.extensions;
@@ -192,6 +192,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -250,6 +254,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -334,6 +342,10 @@
return false;
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -403,6 +415,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
@@ -452,8 +468,15 @@
synchronized (digestLock)
{
- return Arrays.equals(digestBytes,
- messageDigest.digest(plainPlusSaltBytes));
+ try
+ {
+ return Arrays.equals(digestBytes,
+ messageDigest.digest(plainPlusSaltBytes));
+ }
+ finally
+ {
+ Arrays.fill(plainPlusSaltBytes, (byte) 0);
+ }
}
}
diff --git a/opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java
index ebbb8bd..d854ae8 100644
--- a/opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SaltedSHA384PasswordStorageScheme.java
@@ -23,7 +23,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
- * Portions Copyright 2010 ForgeRock AS.
+ * Portions Copyright 2010-2013 ForgeRock AS.
*/
package org.opends.server.extensions;
@@ -193,6 +193,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -251,6 +255,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -335,6 +343,10 @@
return false;
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -404,6 +416,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
@@ -453,8 +469,15 @@
synchronized (digestLock)
{
- return Arrays.equals(digestBytes,
- messageDigest.digest(plainPlusSaltBytes));
+ try
+ {
+ return Arrays.equals(digestBytes,
+ messageDigest.digest(plainPlusSaltBytes));
+ }
+ finally
+ {
+ Arrays.fill(plainPlusSaltBytes, (byte) 0);
+ }
}
}
diff --git a/opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java
index 8e553a9..e3d5460 100644
--- a/opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/SaltedSHA512PasswordStorageScheme.java
@@ -23,7 +23,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
- * Portions Copyright 2010 ForgeRock AS.
+ * Portions Copyright 2010-2013 ForgeRock AS.
*/
package org.opends.server.extensions;
@@ -192,6 +192,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -250,6 +254,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
// Append the salt to the hashed value and base64-the whole thing.
@@ -334,6 +342,10 @@
return false;
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
return Arrays.equals(digestBytes, userDigestBytes);
@@ -403,6 +415,10 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
message, e);
}
+ finally
+ {
+ Arrays.fill(plainPlusSalt, (byte) 0);
+ }
}
@@ -452,8 +468,15 @@
synchronized (digestLock)
{
- return Arrays.equals(digestBytes,
- messageDigest.digest(plainPlusSaltBytes));
+ try
+ {
+ return Arrays.equals(digestBytes,
+ messageDigest.digest(plainPlusSaltBytes));
+ }
+ finally
+ {
+ Arrays.fill(plainPlusSaltBytes, (byte) 0);
+ }
}
}
@@ -555,6 +578,7 @@
System.arraycopy(digestBytes, 0, digestPlusSalt, 0, digestBytes.length);
System.arraycopy(saltBytes, 0, digestPlusSalt, digestBytes.length,
NUM_SALT_BYTES);
+ Arrays.fill(passwordPlusSalt, (byte) 0);
return "{" + STORAGE_SCHEME_NAME_SALTED_SHA_512 + "}" +
Base64.encode(digestPlusSalt);
diff --git a/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java b/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
index 61a94e4..bc85618 100644
--- a/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
+++ b/opends/src/server/org/opends/server/extensions/TripleDESPasswordStorageScheme.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2008 Sun Microsystems, Inc.
+ * Portions Copyright 2013 ForgeRock AS.
*/
package org.opends.server.extensions;
@@ -37,6 +38,8 @@
import org.opends.server.types.*;
import org.opends.server.util.Base64;
+import java.util.Arrays;
+
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.extensions.ExtensionsConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
@@ -109,10 +112,11 @@
public ByteString encodePassword(ByteSequence plaintext)
throws DirectoryException
{
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_3DES,
KEY_SIZE_3DES,
plaintextBytes);
@@ -130,6 +134,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
}
@@ -145,11 +154,12 @@
buffer.append('{');
buffer.append(STORAGE_SCHEME_NAME_3DES);
buffer.append('}');
+ byte[] plaintextBytes = null;
try
{
// TODO: Can we avoid this copy?
- byte[] plaintextBytes = plaintext.toByteArray();
+ plaintextBytes = plaintext.toByteArray();
byte[] encodedBytes = cryptoManager.encrypt(CIPHER_TRANSFORMATION_3DES,
KEY_SIZE_3DES,
plaintextBytes);
@@ -167,6 +177,11 @@
throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
m, e);
}
+ finally
+ {
+ if (plaintextBytes != null)
+ Arrays.fill(plaintextBytes, (byte) 0);
+ }
return ByteString.valueOf(buffer.toString());
}
--
Gitblit v1.10.0