PKCS5S2PasswordStorageScheme.java revision 754f0bca5bd3fd27daabfa5a0b187fea3218f737
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2014-2015 ForgeRock AS.
* Portions Copyright 2014 Emidio Stani & Andrea Stani
*/
/**
* This class defines a Directory Server password storage scheme based on the
* Atlassian PBKF2-base hash algorithm. This is a one-way digest algorithm
* so there is no way to retrieve the original clear-text version of the
* password from the hashed value (although this means that it is not suitable
* for things that need the clear-text password like DIGEST-MD5). Unlike
* the other PBKF2-base scheme, this implementation uses a fixed number of
* iterations.
*/
public class PKCS5S2PasswordStorageScheme
{
/** The fully-qualified name of this class. */
private static final String CLASS_NAME = "org.opends.server.extensions.PKCS5S2PasswordStorageScheme";
/** The number of bytes of random data to use as the salt when generating the hashes. */
private static final int NUM_SALT_BYTES = 16;
/** The number of bytes the SHA-1 algorithm produces. */
private static final int SHA1_LENGTH = 32;
/** Atlassian hardcoded the number of iterations to 10000. */
private static final int iterations = 10000;
/** The secure random number generator to use to generate the salt values. */
private SecureRandom random;
/**
* Creates a new instance of this password storage scheme. Note that no
* initialization should be performed here, as all initialization should be
* done in the <CODE>initializePasswordStorageScheme</CODE> method.
*/
public PKCS5S2PasswordStorageScheme()
{
super();
}
/** {@inheritDoc} */
throws InitializationException
{
try
{
// Just try to verify if the algorithm is supported
}
catch (NoSuchAlgorithmException e)
{
throw new InitializationException(null);
}
}
/** {@inheritDoc} */
public String getStorageSchemeName()
{
return STORAGE_SCHEME_NAME_PKCS5S2;
}
/** {@inheritDoc} */
throws DirectoryException
{
byte[] saltBytes = new byte[NUM_SALT_BYTES];
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
{
// Base64-decode the value and take the first 16 bytes as the salt.
try
{
{
return false;
}
final int saltLength = NUM_SALT_BYTES;
final byte[] digestBytes = new byte[SHA1_LENGTH];
final byte[] saltBytes = new byte[saltLength];
}
catch (Exception e)
{
logger.traceException(e);
logger.error(ERR_PWSCHEME_CANNOT_BASE64_DECODE_STORED_PASSWORD.get(storedPassword.toString(), String.valueOf(e)));
return false;
}
}
/** {@inheritDoc} */
public boolean supportsAuthPasswordSyntax()
{
return true;
}
/** {@inheritDoc} */
public String getAuthPasswordSchemeName()
{
}
/** {@inheritDoc} */
throws DirectoryException
{
byte[] saltBytes = new byte[NUM_SALT_BYTES];
// Encode and return the value.
}
/** {@inheritDoc} */
public boolean authPasswordMatches(ByteSequence plaintextPassword, String authInfo, String authValue)
{
try
{
if (pos == -1)
{
throw new Exception();
}
}
catch (Exception e)
{
logger.traceException(e);
return false;
}
}
/** {@inheritDoc} */
public boolean isReversible()
{
return false;
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
throws DirectoryException
{
}
/** {@inheritDoc} */
public boolean isStorageSchemeSecure()
{
return true;
}
/**
* Generates an encoded password string from the given clear-text password.
* This method is primarily intended for use when it is necessary to generate a password with the server
* offline (e.g., when setting the initial root user password).
*
* @param passwordBytes The bytes that make up the clear-text password.
* @return The encoded password string, including the scheme name in curly braces.
* @throws DirectoryException If a problem occurs during processing.
*/
throws DirectoryException
{
byte[] saltBytes = new byte[NUM_SALT_BYTES];
}
throws DirectoryException
{
try
{
}
catch (DirectoryException e)
{
throw e;
}
catch (Exception e)
{
throw cannotEncodePassword(e);
}
}
throws DirectoryException
{
try
{
}
catch (Exception e)
{
throw cannotEncodePassword(e);
}
finally
{
}
}
private boolean encodeAndMatch(ByteSequence plaintext, byte[] saltBytes, byte[] digestBytes, int iterations)
{
try
{
}
catch (Exception e)
{
return false;
}
}
private static byte[] encodeWithRandomSalt(ByteSequence plaintext, byte[] saltBytes, SecureRandom random)
throws DirectoryException
{
}
{
logger.traceException(e);
LocalizableMessage message = ERR_PWSCHEME_CANNOT_ENCODE_PASSWORD.get(CLASS_NAME, getExceptionMessage(e));
}
return hashPlusSalt;
}
}