/*
 * 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.geronimo.javamail.authentication;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.mail.MessagingException;

import org.apache.geronimo.mail.util.Hex;

public class CramMD5Authenticator implements ClientAuthenticator {

    // the user we're authenticating
    protected String username;

    // the user's password (the "shared secret")
    protected String password;

    // indicates whether we've gone through the entire challenge process.
    protected boolean complete = false;

    /**
     * Main constructor.
     *
     * @param username
     *            The login user name.
     * @param password
     *            The login password.
     */
    public CramMD5Authenticator(String username, String password) {
        this.username = username;
        this.password = password;
    }

    /**
     * Respond to the hasInitialResponse query. This mechanism does not have an
     * initial response.
     *
     * @return Always returns false.
     */
    public boolean hasInitialResponse() {
        return false;
    }

    /**
     * Indicate whether the challenge/response process is complete.
     *
     * @return True if the last challenge has been processed, false otherwise.
     */
    public boolean isComplete() {
        return complete;
    }

    /**
     * Retrieve the authenticator mechanism name.
     *
     * @return Always returns the string "CRAM-MD5"
     */
    public String getMechanismName() {
        return "CRAM-MD5";
    }

    /**
     * Evaluate a CRAM-MD5 login challenge, returning the a result string that
     * should satisfy the clallenge.
     *
     * @param challenge
     *            The decoded challenge data, as a byte array.
     *
     * @return A formatted challege response, as an array of bytes.
     * @exception MessagingException
     */
    public byte[] evaluateChallenge(byte[] challenge) throws MessagingException {
        // we create the challenge from the userid and password information (the
        // "shared secret").
        byte[] passBytes;

        try {
            // get the password in an UTF-8 encoding to create the token
            passBytes = password.getBytes("UTF-8");
            // compute the password digest using the key
            byte[] digest = computeCramDigest(passBytes, challenge);

            // create a unified string using the user name and the hex encoded
            // digest
            String responseString = username + " " + new String(Hex.encode(digest), "ISO8859-1");
            complete = true;
            return responseString.getBytes("ISO8859-1");
        } catch (UnsupportedEncodingException e) {
            // got an error, fail this
            throw new MessagingException("Invalid character encodings");
        }

    }

    /**
     * Compute a CRAM digest using the hmac_md5 algorithm. See the description
     * of RFC 2104 for algorithm details.
     *
     * @param key
     *            The key (K) for the calculation.
     * @param input
     *            The encrypted text value.
     *
     * @return The computed digest, as a byte array value.
     * @exception NoSuchAlgorithmException
     */
    protected byte[] computeCramDigest(byte[] key, byte[] input) throws MessagingException {
        // CRAM digests are computed using the MD5 algorithm.
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new MessagingException("Unable to access MD5 message digest", e);
        }

        // if the key is longer than 64 bytes, then we get a digest of the key
        // and use that instead.
        // this is required by RFC 2104.
        if (key.length > 64) {
            digest.update(key);
            key = digest.digest();
        }

        // now we create two 64 bit padding keys, initialized with the key
        // information.
        byte[] ipad = new byte[64];
        byte[] opad = new byte[64];

        System.arraycopy(key, 0, ipad, 0, key.length);
        System.arraycopy(key, 0, opad, 0, key.length);

        // and these versions are munged by XORing with "magic" values.

        for (int i = 0; i < 64; i++) {
            ipad[i] ^= 0x36;
            opad[i] ^= 0x5c;
        }

        // now there are a pair of MD5 operations performed, and inner and an
        // outer. The spec defines this as
        // H(K XOR opad, H(K XOR ipad, text)), where H is the MD5 operation.

        // inner operation
        digest.reset();
        digest.update(ipad);
        digest.update(input); // this appends the text to the pad
        byte[] md5digest = digest.digest();

        // outer operation
        digest.reset();
        digest.update(opad);
        digest.update(md5digest);
        return digest.digest(); // final result
    }
}
