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

Valery Kharseko
2 days ago 1bda529e3cf685d5108832ecac7f433c85acb6fd
opendj-server-legacy/src/main/java/org/opends/server/extensions/MD5PasswordStorageScheme.java
@@ -13,6 +13,7 @@
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions Copyright 2013-2016 ForgeRock AS.
 * Portions Copyright 2026 3A Systems, LLC.
 */
package org.opends.server.extensions;
@@ -53,11 +54,13 @@
  private static final String CLASS_NAME =
       "org.opends.server.extensions.MD5PasswordStorageScheme";
  /** The message digest that will actually be used to generate the MD5 hashes. */
  private MessageDigest messageDigest;
  /** The lock used to provide threadsafe access to the message digest. */
  private Object digestLock;
  /**
   * The message digests used to generate the MD5 hashes.
   * MessageDigest is not thread-safe, so a per-thread instance is used
   * instead of a shared instance guarded by a lock: hashing under a global
   * lock serializes all concurrent bind password verifications.
   */
  private ThreadLocal<MessageDigest> messageDigest;
  /**
   * Creates a new instance of this password storage scheme.  Note that no
@@ -76,7 +79,8 @@
  {
    try
    {
      messageDigest = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM_MD5);
      // Fail fast at initialization time if the algorithm is unavailable.
      MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM_MD5);
    }
    catch (Exception e)
    {
@@ -87,7 +91,16 @@
      throw new InitializationException(message, e);
    }
    digestLock = new Object();
    messageDigest = ThreadLocal.withInitial(() -> {
      try
      {
        return MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM_MD5);
      }
      catch (Exception e)
      {
        throw new IllegalStateException(e);
      }
    });
  }
  @Override
@@ -103,29 +116,26 @@
    byte[] digestBytes;
    byte[] plaintextBytes = null;
    synchronized (digestLock)
    try
    {
      try
      {
        // TODO: Can we avoid this copy?
        plaintextBytes = plaintext.toByteArray();
        digestBytes = messageDigest.digest(plaintextBytes);
      }
      catch (Exception e)
      {
        logger.traceException(e);
      // TODO: Can we avoid this copy?
      plaintextBytes = plaintext.toByteArray();
      digestBytes = messageDigest.get().digest(plaintextBytes);
    }
    catch (Exception e)
    {
      logger.traceException(e);
        LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
            CLASS_NAME, getExceptionMessage(e));
        throw new DirectoryException(DirectoryServer.getCoreConfigManager().getServerErrorResultCode(),
                                     message, e);
      }
      finally
      LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
          CLASS_NAME, getExceptionMessage(e));
      throw new DirectoryException(DirectoryServer.getCoreConfigManager().getServerErrorResultCode(),
                                   message, e);
    }
    finally
    {
      if (plaintextBytes != null)
      {
        if (plaintextBytes != null)
        {
          Arrays.fill(plaintextBytes, (byte) 0);
        }
        Arrays.fill(plaintextBytes, (byte) 0);
      }
    }
@@ -144,29 +154,26 @@
    byte[] plaintextBytes = null;
    byte[] digestBytes;
    synchronized (digestLock)
    try
    {
      try
      {
        // TODO: Can we avoid this copy?
        plaintextBytes = plaintext.toByteArray();
        digestBytes = messageDigest.digest(plaintextBytes);
      }
      catch (Exception e)
      {
        logger.traceException(e);
      // TODO: Can we avoid this copy?
      plaintextBytes = plaintext.toByteArray();
      digestBytes = messageDigest.get().digest(plaintextBytes);
    }
    catch (Exception e)
    {
      logger.traceException(e);
        LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
            CLASS_NAME, getExceptionMessage(e));
        throw new DirectoryException(DirectoryServer.getCoreConfigManager().getServerErrorResultCode(),
                                     message, e);
      }
      finally
      LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(
          CLASS_NAME, getExceptionMessage(e));
      throw new DirectoryException(DirectoryServer.getCoreConfigManager().getServerErrorResultCode(),
                                   message, e);
    }
    finally
    {
      if (plaintextBytes != null)
      {
        if (plaintextBytes != null)
        {
          Arrays.fill(plaintextBytes, (byte) 0);
        }
        Arrays.fill(plaintextBytes, (byte) 0);
      }
    }
@@ -182,27 +189,24 @@
    byte[] plaintextPasswordBytes = null;
    ByteString userPWDigestBytes;
    synchronized (digestLock)
    try
    {
      try
      {
        // TODO: Can we avoid this copy?
        plaintextPasswordBytes = plaintextPassword.toByteArray();
        userPWDigestBytes =
            ByteString.wrap(messageDigest.digest(plaintextPasswordBytes));
      }
      catch (Exception e)
      {
        logger.traceException(e);
      // TODO: Can we avoid this copy?
      plaintextPasswordBytes = plaintextPassword.toByteArray();
      userPWDigestBytes =
          ByteString.wrap(messageDigest.get().digest(plaintextPasswordBytes));
    }
    catch (Exception e)
    {
      logger.traceException(e);
        return false;
      }
      finally
      return false;
    }
    finally
    {
      if (plaintextPasswordBytes != null)
      {
        if (plaintextPasswordBytes != null)
        {
          Arrays.fill(plaintextPasswordBytes, (byte) 0);
        }
        Arrays.fill(plaintextPasswordBytes, (byte) 0);
      }
    }