/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.util.crypt;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/*

 Based on the work of Jonathan Abbey
 Adopted for Director by Thomas Aeby, 2004

 MD5Crypt.java

 Created: 3 November 1999
 Release: $Name:  $
 Version: $Revision: 1.1 $
 Last Mod Date: $Date: 2004/02/04 08:10:35 $
 Java Code By: Jonathan Abbey, jonabbey@arlut.utexas.edu
 Original C Version:
 ----------------------------------------------------------------------------
 "THE BEER-WARE LICENSE" (Revision 42):
 <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
 can do whatever you want with this stuff. If we meet some day, and you think
 this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 ----------------------------------------------------------------------------

 -----------------------------------------------------------------------

 Ganymede Directory Management System

 Copyright (C) 1996, 1997, 1998, 1999  The University of Texas at Austin.

 Contact information

 Author Email: ganymede_author@arlut.utexas.edu
 Email mailing list: ganymede@arlut.utexas.edu

 US Mail:

 Computer Science Division
 Applied Research Laboratories
 The University of Texas at Austin
 PO Box 8029, Austin TX 78713-8029

 Telephone: (512) 835-3200

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 */

/*------------------------------------------------------------------------------
 class
 MD5Crypt

 ------------------------------------------------------------------------------*/

/**
 * <p>
 * This class defines a method,
 * {@link MD5Crypt#crypt(java.lang.String, java.lang.String) crypt()}, which
 * takes a password and a salt string and generates an
 * OpenBSD/FreeBSD/Linux-compatible md5-encoded password entry.
 * </p>
 * 
 * <p>
 * Created: 3 November 1999
 * </p>
 * <p>
 * Release: $Name: $
 * </p>
 * <p>
 * Version: $Revision: 1.1 $
 * </p>
 * <p>
 * Last Mod Date: $Date: 2004/02/04 08:10:35 $
 * </p>
 * <p>
 * Java Code By: Jonathan Abbey, jonabbey@arlut.utexas.edu
 * </p>
 * <p>
 * Original C Version:
 * 
 * <pre>
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 * ----------------------------------------------------------------------------
 * </pre>
 * 
 * </p>
 */

public final class MD5Crypt {

	/**
	 * 
	 * Command line test rig.
	 * 
	 * @throws NoSuchAlgorithmException
	 * 
	 */

	static public void main(String argv[]) throws NoSuchAlgorithmException {
		if ((argv.length < 1) || (argv.length > 2)) {
			System.err.println("Usage: MD5Crypt password salt");
			System.exit(1);
		}

		if (argv.length == 2) {
			System.err.println(MD5Crypt.crypt(argv[0], argv[1]));
		} else {
			System.err.println(MD5Crypt.crypt(argv[0]));
		}

		System.exit(0);
	}

	static private final String SALTCHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

	static private final String itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

	static private final String to64(long v, int size) {
		StringBuffer result = new StringBuffer();

		while (--size >= 0) {
			result.append(itoa64.charAt((int) (v & 0x3f)));
			v >>>= 6;
		}

		return result.toString();
	}

	static private final void clearbits(byte bits[]) {
		for (int i = 0; i < bits.length; i++) {
			bits[i] = 0;
		}
	}

	/**
	 * convert an encoded unsigned byte value into a int with the unsigned
	 * value.
	 */

	@SuppressWarnings("cast")
	static private final int bytes2u(byte inp) {
		return ((int) inp) & 0xff;
	}

	/**
	 * <p>
	 * This method actually generates a OpenBSD/FreeBSD/Linux PAM compatible
	 * md5-encoded password hash from a plaintext password and a salt.
	 * </p>
	 * 
	 * <p>
	 * The resulting string will be in the form '$1$&lt;salt&gt;$&lt;hashed
	 * mess&gt;
	 * </p>
	 * 
	 * @param password
	 *            Plaintext password
	 * 
	 * @return An OpenBSD/FreeBSD/Linux-compatible md5-hashed password field.
	 * @throws NoSuchAlgorithmException
	 */

	static public final String crypt(String password)
			throws NoSuchAlgorithmException {
		StringBuffer salt = new StringBuffer();
		java.util.Random randgen = new java.util.Random();

		/* -- */

		while (salt.length() < 8) {
			int index = (int) (randgen.nextFloat() * SALTCHARS.length());
			salt.append(SALTCHARS.substring(index, index + 1));
		}

		return MD5Crypt.crypt(password, salt.toString());
	}

	/**
	 * <p>
	 * This method actually generates a OpenBSD/FreeBSD/Linux PAM compatible
	 * md5-encoded password hash from a plaintext password and a salt.
	 * </p>
	 * 
	 * <p>
	 * The resulting string will be in the form '$1$&lt;salt&gt;$&lt;hashed
	 * mess&gt;
	 * </p>
	 * 
	 * @param password
	 *            Plaintext password
	 * @param salt
	 *            A short string to use to randomize md5. May start with $1$,
	 *            which will be ignored. It is explicitly permitted to pass a
	 *            pre-existing MD5Crypt'ed password entry as the salt. crypt()
	 *            will strip the salt chars out properly.
	 * 
	 * @return An OpenBSD/FreeBSD/Linux-compatible md5-hashed password field.
	 * @throws NoSuchAlgorithmException
	 */

	static public final String crypt(String password, String salt)
			throws NoSuchAlgorithmException {
		/*
		 * This string is magic for this algorithm. Having it this way, we can
		 * get get better later on
		 */

		String magic = "$1$";
		byte finalState[];
		MessageDigest ctx, ctx1;
		long l;

		/* -- */

		/* Refine the Salt first */

		/* If it starts with the magic string, then skip that */

		if (salt.startsWith(magic)) {
			salt = salt.substring(magic.length());
		}

		/* It stops at the first '$', max 8 chars */

		if (salt.indexOf('$') != -1) {
			salt = salt.substring(0, salt.indexOf('$'));
		}

		if (salt.length() > 8) {
			salt = salt.substring(0, 8);
		}

		ctx = MessageDigest.getInstance("MD5");

		ctx.update(password.getBytes()); // The password first, since that is
											// what is most unknown
		ctx.update(magic.getBytes()); // Then our magic string
		ctx.update(salt.getBytes()); // Then the raw salt

		/* Then just as many characters of the MD5(pw,salt,pw) */

		ctx1 = MessageDigest.getInstance("MD5");
		ctx1.update(password.getBytes());
		ctx1.update(salt.getBytes());
		ctx1.update(password.getBytes());
		finalState = ctx1.digest();

		for (int pl = password.length(); pl > 0; pl -= 16) {
			for (int i = 0; i < (pl > 16 ? 16 : pl); i++)
				ctx.update(finalState[i]);
		}

		/*
		 * the original code claimed that finalState was being cleared to keep
		 * dangerous bits out of memory, but doing this is also required in
		 * order to get the right output.
		 */

		clearbits(finalState);

		/* Then something really weird... */

		for (int i = password.length(); i != 0; i >>>= 1) {
			if ((i & 1) != 0) {
				ctx.update(finalState[0]);
			} else {
				ctx.update(password.getBytes()[0]);
			}
		}

		finalState = ctx.digest();

		/*
		 * and now, just to make sure things don't run too fast On a 60 Mhz
		 * Pentium this takes 34 msec, so you would need 30 seconds to build a
		 * 1000 entry dictionary...
		 * 
		 * (The above timings from the C version)
		 */

		for (int i = 0; i < 1000; i++) {
			ctx1 = MessageDigest.getInstance("MD5");

			if ((i & 1) != 0) {
				ctx1.update(password.getBytes());
			} else {
				for (int c = 0; c < 16; c++)
					ctx1.update(finalState[c]);
			}

			if ((i % 3) != 0) {
				ctx1.update(salt.getBytes());
			}

			if ((i % 7) != 0) {
				ctx1.update(password.getBytes());
			}

			if ((i & 1) != 0) {
				for (int c = 0; c < 16; c++)
					ctx1.update(finalState[c]);
			} else {
				ctx1.update(password.getBytes());
			}

			finalState = ctx1.digest();
		}

		/* Now make the output string */

		StringBuffer result = new StringBuffer();

		result.append(magic);
		result.append(salt);
		result.append("$");

		l = (bytes2u(finalState[0]) << 16) | (bytes2u(finalState[6]) << 8)
				| bytes2u(finalState[12]);
		result.append(to64(l, 4));

		l = (bytes2u(finalState[1]) << 16) | (bytes2u(finalState[7]) << 8)
				| bytes2u(finalState[13]);
		result.append(to64(l, 4));

		l = (bytes2u(finalState[2]) << 16) | (bytes2u(finalState[8]) << 8)
				| bytes2u(finalState[14]);
		result.append(to64(l, 4));

		l = (bytes2u(finalState[3]) << 16) | (bytes2u(finalState[9]) << 8)
				| bytes2u(finalState[15]);
		result.append(to64(l, 4));

		l = (bytes2u(finalState[4]) << 16) | (bytes2u(finalState[10]) << 8)
				| bytes2u(finalState[5]);
		result.append(to64(l, 4));

		l = bytes2u(finalState[11]);
		result.append(to64(l, 2));

		/* Don't leave anything around in vm they could use. */
		clearbits(finalState);

		return result.toString();
	}
}
