/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.dynamo.db;

import java.security.MessageDigest;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;

class DefaultHashAuthenticator implements Authenticator
{
  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  DefaultHashAuthenticator()
  { // do nothing
  } // end constructor

  /*--------------------------------------------------------------------------------
   * IMplementations from interface Authenticator
   *--------------------------------------------------------------------------------
   */

  public boolean authenticate(String stored_data, String input_data) throws AuthenticationException
  {
    return stored_data.equals(hashPassword(input_data));

  } // end authenticate

  public String processInputData(String input_data) throws AuthenticationException
  {
    return hashPassword(input_data);

  } // end processInputData

  /*--------------------------------------------------------------------------------
   * External static operations
   *--------------------------------------------------------------------------------
   */

  public static final String hashPassword(String password)
  {
    if ((password!=null) && (password.length()>0))
    { // hash the password and save the hash value
      MessageDigest hasher;

      try
      { // get a hasher implementing the Secure Hashing Algorithm
	hasher = MessageDigest.getInstance("SHA");

      } // end try
      catch (java.security.NoSuchAlgorithmException e)
      { // SHA should be a standard algorithm...if it isn't, we're h0sed
	throw new RuntimeException("HOSED JRE - SHA should be a standard algorithm");

      } // end catch

      try
      { // update the hasher with the UTF-8 bytes of the password
	hasher.update(password.getBytes("UTF8"));

      } // end try
      catch (java.io.UnsupportedEncodingException e)
      { // WTF? How can the JRE NOT know about UTF-8?  HOW?!?
	throw new RuntimeException("HOSED JRE - UTF-8 encoding should be supported");

      } // end catch

      // Retrieve the raw hash value (should be 160 bits, or 20 bytes)
      byte[] raw_hash = hasher.digest();

      // Convert the hash value to a hexadecimal string (40 chars in length)
      StringBuffer hash_buf = new StringBuffer(raw_hash.length * 2);
      StringBuffer tmp_buf = new StringBuffer();
      String tmp;
      for (int i=0; i<raw_hash.length; i++)
      { // N.B.: Integer.toHexString does not zero-pad on the left, so that's why this is
	// a little complex
	tmp_buf.setLength(0);
	tmp_buf.append("00").append(Integer.toHexString(raw_hash[i]).trim());
	tmp = tmp_buf.toString();
	hash_buf.append(tmp.substring(tmp.length()-2));

      } // end for

      // finally, save off the password hash value
      return hash_buf.toString().toUpperCase();

    } // end if
    else  // no password
      return "";

  } // end hashPassword

} // end class DefaultHashAuthenticator
