/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.security.sasl.digest;

import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Arrays;

import java.util.logging.Logger;
import java.util.logging.Level;

import javax.security.sasl.*;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
  * An implementation of the DIGEST-MD5
  * (<a href="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>) SASL
  * (<a href="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</a>) mechanism.
  *
  * The DIGEST-MD5 SASL mechanism specifies two modes of authentication.
  * - Initial Authentication
  * - Subsequent Authentication - optional, (currently unsupported)
  *
  * Required callbacks:
  * - RealmChoiceCallback
  *    shows user list of realms server has offered; handler must choose one
  *    from list
  * - RealmCallback
  *    shows user the only realm server has offered or none; handler must
  *    enter realm to use
  * - NameCallback
  *    handler must enter username to use for authentication
  * - PasswordCallback
  *    handler must enter password for username to use for authentication
  *
  * Environment properties that affect behavior of implementation:
  *
  * javax.security.sasl.qop
  *    quality of protection; list of auth, auth-int, auth-conf; default is "auth"
  * javax.security.sasl.strength
  *    auth-conf strength; list of high, medium, low; default is highest
  *    available on platform ["high,medium,low"].
  *    high means des3 or rc4 (128); medium des or rc4-56; low is rc4-40;
  *    choice of cipher depends on its availablility on platform
  * javax.security.sasl.maxbuf
  *    max receive buffer size; default is 65536
  * javax.security.sasl.sendmaxbuffer
  *    max send buffer size; default is 65536; (min with server max recv size)
  *
  * com.sun.security.sasl.digest.cipher
  *    name a specific cipher to use; setting must be compatible with the
  *    setting of the javax.security.sasl.strength property.
  *
  * @see <a href="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</a>
  * - Simple Authentication and Security Layer (SASL)
  * @see <a href="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>
  * - Using Digest Authentication as a SASL Mechanism
  * @see <a href="http://java.sun.com/products/jce">Java(TM)
  * Cryptography Extension 1.2.1 (JCE)</a>
  * @see <a href="http://java.sun.com/products/jaas">Java(TM)
  * Authentication and Authorization Service (JAAS)</a>
  *
  * @author Jonathan Bruce
  * @author Rosanna Lee
  */
final class DigestMD5Client extends DigestMD5Base implements SaslClient {
    private static final String MY_CLASS_NAME = DigestMD5Client.class.getName();

    // Property for specifying cipher explicitly
    private static final String CIPHER_PROPERTY =
        "com.sun.security.sasl.digest.cipher";

    /* Directives encountered in challenges sent by the server. */
    private static final String[] DIRECTIVE_KEY = {
        "realm",      // >= 0 times
        "qop",        // atmost once; default is "auth"
        "algorithm",  // exactly once
        "nonce",      // exactly once
        "maxbuf",     // atmost once; default is 65536
        "charset",    // atmost once; default is ISO 8859-1
        "cipher",     // exactly once if qop is "auth-conf"
        "rspauth",    // exactly once in 2nd challenge
        "stale",      // atmost once for in subsequent auth (not supported)
    };

    /* Indices into DIRECTIVE_KEY */
    private static final int REALM = 0;
    private static final int QOP = 1;
    private static final int ALGORITHM = 2;
    private static final int NONCE = 3;
    private static final int MAXBUF = 4;
    private static final int CHARSET = 5;
    private static final int CIPHER = 6;
    private static final int RESPONSE_AUTH = 7;
    private static final int STALE = 8;

    private int nonceCount; // number of times nonce has been used/seen

    /* User-supplied/generated information */
    private String specifiedCipher;  // cipher explicitly requested by user
    private byte[] cnonce;        // client generated nonce
    private String username;
    private char[] passwd;
    private byte[] authzidBytes;  // byte repr of authzid

    /**
      * Constructor for DIGEST-MD5 mechanism.
      *
      * @param authzid A non-null String representing the principal
      * for which authorization is being granted..
      * @param digestURI A non-null String representing detailing the
      * combined protocol and host being used for authentication.
      * @param props The possibly null properties to be used by the SASL
      * mechanism to configure the authentication exchange.
      * @param cbh The non-null CallbackHanlder object for callbacks
      * @throws SaslException if no authentication ID or password is supplied
      */
    DigestMD5Client(String authzid, String protocol, String serverName,
        Map props, CallbackHandler cbh) throws SaslException {

        super(props, MY_CLASS_NAME, 2, protocol + "/" + serverName, cbh);

        // authzID can only be encoded in UTF8 - RFC 2222
        if (authzid != null) {
            this.authzid = authzid;
            try {
                authzidBytes = authzid.getBytes("UTF8");

            } catch (UnsupportedEncodingException e) {
                throw new SaslException(
                    "DIGEST-MD5: Error encoding authzid value into UTF-8", e);
            }
        }

        if (props != null) {
            specifiedCipher = (String)props.get(CIPHER_PROPERTY);

            logger.log(Level.FINE, "DIGEST60:Explicitly specified cipher: {0}",
                specifiedCipher);
        }
   }

    /**
     * DIGEST-MD5 has no initial response
     *
     * @return false
     */
    public boolean hasInitialResponse() {
        return false;
    }

    /**
     * Process the challenge data.
     *
     * The server sends a digest-challenge which the client must reply to
     * in a digest-response. When the authentication is complete, the
     * completed field is set to true.
     *
     * @param challengeData A non-null byte array containing the challenge
     * data from the server.
     * @return A possibly null byte array containing the response to
     * be sent to the server.
     *
     * @throws SaslException If the platform does not have MD5 digest support
     * or if the server sends an invalid challenge.
     */
    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {

        if (challengeData.length > MAX_CHALLENGE_LENGTH) {
            throw new SaslException(
                "DIGEST-MD5: Invalid digest-challenge length. Got:  " +
                challengeData.length + " Expected < " + MAX_CHALLENGE_LENGTH);
        }

        /* Extract and process digest-challenge */
        byte[][] challengeVal;

        switch (step) {
        case 2:
            /* Process server's first challenge (from Step 1) */
            /* Get realm, qop, maxbuf, charset, algorithm, cipher, nonce
               directives */
            List<byte[]> realmChoices = new ArrayList<byte[]>(3);
            challengeVal = parseDirectives(challengeData, DIRECTIVE_KEY,
                realmChoices, REALM);

            try {
                processChallenge(challengeVal, realmChoices);
                checkQopSupport(challengeVal[QOP], challengeVal[CIPHER]);
                ++step;
                return generateClientResponse(challengeVal[CHARSET]);
            } catch (SaslException e) {
                step = 0;
                clearPassword();
                throw e; // rethrow
            } catch (IOException e) {
                step = 0;
                clearPassword();
                throw new SaslException("DIGEST-MD5: Error generating " +
                    "digest response-value", e);
            }

        case 3:
            try {
                /* Process server's step 3 (server response to digest response) */
                /* Get rspauth directive */
                challengeVal = parseDirectives(challengeData, DIRECTIVE_KEY,
                    null, REALM);
                validateResponseValue(challengeVal[RESPONSE_AUTH]);


                /* Initialize SecurityCtx implementation */
                if (integrity && privacy) {
                    secCtx = new DigestPrivacy(true /* client */);
                } else if (integrity) {
                    secCtx = new DigestIntegrity(true /* client */);
                }

                return null; // Mechanism has completed.
            } finally {
                clearPassword();
                step = 0;  // Set to invalid state
                completed = true;
            }

        default:
            // No other possible state
            throw new SaslException("DIGEST-MD5: Client at illegal state");
        }
    }


   /**
    * Record information from the challengeVal array into variables/fields.
    * Check directive values that are multi-valued and ensure that mandatory
    * directives not missing from the digest-challenge.
    *
    * @throws SaslException if a sasl is a the mechanism cannot
    * correcly handle a callbacks or if a violation in the
    * digest challenge format is detected.
    */
    private void processChallenge(byte[][] challengeVal, List<byte[]> realmChoices)
        throws SaslException, UnsupportedEncodingException {

        /* CHARSET: optional atmost once */
        if (challengeVal[CHARSET] != null) {
            if (!"utf-8".equals(new String(challengeVal[CHARSET], encoding))) {
                throw new SaslException("DIGEST-MD5: digest-challenge format " +
                    "violation. Unrecognised charset value: " +
                    new String(challengeVal[CHARSET]));
            } else {
                encoding = "UTF8";
                useUTF8 = true;
            }
        }

        /* ALGORITHM: required exactly once */
        if (challengeVal[ALGORITHM] == null) {
            throw new SaslException("DIGEST-MD5: Digest-challenge format " +
                "violation: algorithm directive missing");
        } else if (!"md5-sess".equals(new String(challengeVal[ALGORITHM], encoding))) {
            throw new SaslException("DIGEST-MD5: Digest-challenge format " +
                "violation. Invalid value for 'algorithm' directive: " +
                challengeVal[ALGORITHM]);
        }

        /* NONCE: required exactly once */
        if (challengeVal[NONCE] == null) {
            throw new SaslException("DIGEST-MD5: Digest-challenge format " +
                "violation: nonce directive missing");
        } else {
            nonce = challengeVal[NONCE];
        }

        try {
            /* REALM: optional, if multiple, stored in realmChoices */
            String[] realmTokens = null;

            if (challengeVal[REALM] != null) {
                if (realmChoices == null || realmChoices.size() <= 1) {
                    // Only one realm specified
                    negotiatedRealm = new String(challengeVal[REALM], encoding);
                } else {
                    realmTokens = new String[realmChoices.size()];
                    for (int i = 0; i < realmTokens.length; i++) {
                        realmTokens[i] =
                            new String(realmChoices.get(i), encoding);
                    }
                }
            }

            NameCallback ncb = authzid == null ?
                new NameCallback("DIGEST-MD5 authentication ID: ") :
                new NameCallback("DIGEST-MD5 authentication ID: ", authzid);
            PasswordCallback pcb =
                new PasswordCallback("DIGEST-MD5 password: ", false);

            if (realmTokens == null) {
                // Server specified <= 1 realm
                // If 0, RFC 2831: the client SHOULD solicit a realm from the user.
                RealmCallback tcb =
                    (negotiatedRealm == null? new RealmCallback("DIGEST-MD5 realm: ") :
                        new RealmCallback("DIGEST-MD5 realm: ", negotiatedRealm));

                cbh.handle(new Callback[] {tcb, ncb, pcb});

                /* Acquire realm from RealmCallback */
                negotiatedRealm = tcb.getText();
                if (negotiatedRealm == null) {
                    negotiatedRealm = "";
                }
            } else {
                RealmChoiceCallback ccb = new RealmChoiceCallback(
                    "DIGEST-MD5 realm: ",
                    realmTokens,
                    0, false);
                cbh.handle(new Callback[] {ccb, ncb, pcb});

                /* Acquire realm from RealmChoiceCallback*/
                negotiatedRealm = realmTokens[ccb.getSelectedIndexes()[0]];
            }

            passwd = pcb.getPassword();
            pcb.clearPassword();
            username = ncb.getName();

        } catch (UnsupportedCallbackException e) {
            throw new SaslException("DIGEST-MD5: Cannot perform callback to " +
                "acquire realm, authentication ID or password", e);

        } catch (IOException e) {
            throw new SaslException(
                "DIGEST-MD5: Error acquiring realm, authentication ID or password", e);
        }

        if (username == null || passwd == null) {
            throw new SaslException(
                "DIGEST-MD5: authentication ID and password must be specified");
        }

        /* MAXBUF: optional atmost once */
        int srvMaxBufSize =
            (challengeVal[MAXBUF] == null) ? DEFAULT_MAXBUF
            : Integer.parseInt(new String(challengeVal[MAXBUF], encoding));
        sendMaxBufSize =
            (sendMaxBufSize == 0) ? srvMaxBufSize
            : Math.min(sendMaxBufSize, srvMaxBufSize);
    }

    /**
     * Parses the 'qop' directive. If 'auth-conf' is specified by
     * the client and offered as a QOP option by the server, then a check
     * is client-side supported ciphers is performed.
     *
     * @throws IOException
     */
    private void checkQopSupport(byte[] qopInChallenge, byte[] ciphersInChallenge)
        throws IOException {

        /* QOP: optional; if multiple, merged earlier */
        String qopOptions;

        if (qopInChallenge == null) {
            qopOptions = "auth";
        } else {
            qopOptions = new String(qopInChallenge, encoding);
        }

        // process
        String[] serverQopTokens = new String[3];
        byte[] serverQop = parseQop(qopOptions, serverQopTokens,
            true /* ignore unrecognized tokens */);
        byte serverAllQop = combineMasks(serverQop);

        switch (findPreferredMask(serverAllQop, qop)) {
        case 0:
            throw new SaslException("DIGEST-MD5: No common protection " +
                "layer between client and server");

        case NO_PROTECTION:
            negotiatedQop = "auth";
            // buffer sizes not applicable
            break;

        case INTEGRITY_ONLY_PROTECTION:
            negotiatedQop = "auth-int";
            integrity = true;
            rawSendSize = sendMaxBufSize - 16;
            break;

        case PRIVACY_PROTECTION:
            negotiatedQop = "auth-conf";
            privacy = integrity = true;
            rawSendSize = sendMaxBufSize - 26;
            checkStrengthSupport(ciphersInChallenge);
            break;
        }

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST61:Raw send size: {0}",
                new Integer(rawSendSize));
        }
     }

    /**
     * Processes the 'cipher' digest-challenge directive. This allows the
     * mechanism to check for client-side support against the list of
     * supported ciphers send by the server. If no match is found,
     * the mechanism aborts.
     *
     * @throws SaslException If an error is encountered in processing
     * the cipher digest-challenge directive or if no client-side
     * support is found.
     */
    private void checkStrengthSupport(byte[] ciphersInChallenge)
        throws IOException {

        /* CIPHER: required exactly once if qop=auth-conf */
        if (ciphersInChallenge == null) {
            throw new SaslException("DIGEST-MD5: server did not specify " +
                "cipher to use for 'auth-conf'");
        }

        // First determine ciphers that server supports
        String cipherOptions = new String(ciphersInChallenge, encoding);
        StringTokenizer parser = new StringTokenizer(cipherOptions, ", \t\n");
        int tokenCount = parser.countTokens();
        String token = null;
        byte[] serverCiphers = { UNSET,
                                 UNSET,
                                 UNSET,
                                 UNSET,
                                 UNSET };
        String[] serverCipherStrs = new String[serverCiphers.length];

        // Parse ciphers in challenge; mark each that server supports
        for (int i = 0; i < tokenCount; i++) {
            token = parser.nextToken();
            for (int j = 0; j < CIPHER_TOKENS.length; j++) {
                if (token.equals(CIPHER_TOKENS[j])) {
                    serverCiphers[j] |= CIPHER_MASKS[j];
                    serverCipherStrs[j] = token; // keep for replay to server
                    logger.log(Level.FINE, "DIGEST62:Server supports {0}", token);
                }
            }
        }

        // Determine which ciphers are available on client
        byte[] clntCiphers = getPlatformCiphers();

        // Take intersection of server and client supported ciphers
        byte inter = 0;
        for (int i = 0; i < serverCiphers.length; i++) {
            serverCiphers[i] &= clntCiphers[i];
            inter |= serverCiphers[i];
        }

        if (inter == UNSET) {
            throw new SaslException(
                "DIGEST-MD5: Client supports none of these cipher suites: " +
                cipherOptions);
        }

        // now have a clear picture of user / client; client / server
        // cipher options. Leverage strength array against what is
        // supported to choose a cipher.
        negotiatedCipher = findCipherAndStrength(serverCiphers, serverCipherStrs);

        if (negotiatedCipher == null) {
            throw new SaslException("DIGEST-MD5: Unable to negotiate " +
                "a strength level for 'auth-conf'");
        }
        logger.log(Level.FINE, "DIGEST63:Cipher suite: {0}", negotiatedCipher);
    }

    /**
     * Steps through the ordered 'strength' array, and compares it with
     * the 'supportedCiphers' array. The cipher returned represents
     * the best possible cipher based on the strength preference and the
     * available ciphers on both the server and client environments.
     *
     * @param tokens The array of cipher tokens sent by server
     * @return The agreed cipher.
     */
    private String findCipherAndStrength(byte[] supportedCiphers,
        String[] tokens) {
        byte s;
        for (int i = 0; i < strength.length; i++) {
            if ((s=strength[i]) != 0) {
                for (int j = 0; j < supportedCiphers.length; j++) {

                    // If user explicitly requested cipher, then it
                    // must be the one we choose

                    if (s == supportedCiphers[j] &&
                        (specifiedCipher == null ||
                            specifiedCipher.equals(tokens[j]))) {
                        switch (s) {
                        case HIGH_STRENGTH:
                            negotiatedStrength = "high";
                            break;
                        case MEDIUM_STRENGTH:
                            negotiatedStrength = "medium";
                            break;
                        case LOW_STRENGTH:
                            negotiatedStrength = "low";
                            break;
                        }

                        return tokens[j];
                    }
                }
            }
        }

        return null;  // none found
    }

    /**
     * Returns digest-response suitable for an initial authentication.
     *
     * The following are qdstr-val (quoted string values) as per RFC 2831,
     * which means that any embedded quotes must be escaped.
     *    realm-value
     *    nonce-value
     *    username-value
     *    cnonce-value
     *    authzid-value
     * @returns <tt>digest-response</tt> in a byte array
     * @throws SaslException if there is an error generating the
     * response value or the cnonce value.
     */
    private byte[] generateClientResponse(byte[] charset) throws IOException {

        ByteArrayOutputStream digestResp = new ByteArrayOutputStream();

        if (useUTF8) {
            digestResp.write("charset=".getBytes(encoding));
            digestResp.write(charset);
            digestResp.write(',');
        }

        digestResp.write(("username=\"" +
            quotedStringValue(username) + "\",").getBytes(encoding));

        if (negotiatedRealm.length() > 0) {
            digestResp.write(("realm=\"" +
                quotedStringValue(negotiatedRealm) + "\",").getBytes(encoding));
        }

        digestResp.write("nonce=\"".getBytes(encoding));
        writeQuotedStringValue(digestResp, nonce);
        digestResp.write('"');
        digestResp.write(',');

        nonceCount = getNonceCount(nonce);
        digestResp.write(("nc=" +
            nonceCountToHex(nonceCount) + ",").getBytes(encoding));

        cnonce = generateNonce();
        digestResp.write("cnonce=\"".getBytes(encoding));
        writeQuotedStringValue(digestResp, cnonce);
        digestResp.write("\",".getBytes(encoding));
        digestResp.write(("digest-uri=\"" + digestUri + "\",").getBytes(encoding));

        digestResp.write("maxbuf=".getBytes(encoding));
        digestResp.write(String.valueOf(recvMaxBufSize).getBytes(encoding));
        digestResp.write(',');

        try {
            digestResp.write("response=".getBytes(encoding));
            digestResp.write(generateResponseValue("AUTHENTICATE",
                digestUri, negotiatedQop, username,
                negotiatedRealm, passwd, nonce, cnonce,
                nonceCount, authzidBytes));
            digestResp.write(',');
        } catch (Exception e) {
            throw new SaslException(
                "DIGEST-MD5: Error generating response value", e);
        }

        digestResp.write(("qop=" + negotiatedQop).getBytes(encoding));

        if (negotiatedCipher != null) {
            digestResp.write((",cipher=\"" + negotiatedCipher + "\"").getBytes(encoding));
        }

        if (authzidBytes != null) {
            digestResp.write(",authzid=\"".getBytes(encoding));
            writeQuotedStringValue(digestResp, authzidBytes);
            digestResp.write("\"".getBytes(encoding));
        }

        if (digestResp.size() > MAX_RESPONSE_LENGTH) {
            throw new SaslException ("DIGEST-MD5: digest-response size too " +
                "large. Length: "  + digestResp.size());
        }
        return digestResp.toByteArray();
     }


    /**
     * From RFC 2831, Section 2.1.3: Step Three
     * [Server] sends a message formatted as follows:
     *     response-auth = "rspauth" "=" response-value
     * where response-value is calculated as above, using the values sent in
     * step two, except that if qop is "auth", then A2 is
     *
     *  A2 = { ":", digest-uri-value }
     *
     * And if qop is "auth-int" or "auth-conf" then A2 is
     *
     *  A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
     */
    private void validateResponseValue(byte[] fromServer) throws SaslException {
        if (fromServer == null) {
            throw new SaslException("DIGEST-MD5: Authenication failed. " +
                "Expecting 'rspauth' authentication success message");
        }

        try {
            byte[] expected = generateResponseValue("",
                digestUri, negotiatedQop, username, negotiatedRealm,
                passwd, nonce, cnonce,  nonceCount, authzidBytes);
            if (!Arrays.equals(expected, fromServer)) {
                /* Server's rspauth value does not match */
                throw new SaslException(
                    "Server's rspauth value does not match what client expects");
            }
        } catch (NoSuchAlgorithmException e) {
            throw new SaslException(
                "Problem generating response value for verification", e);
        } catch (IOException e) {
            throw new SaslException(
                "Problem generating response value for verification", e);
        }
    }

    /**
     * Returns the number of requests (including current request)
     * that the client has sent in response to nonceValue.
     * This is 1 the first time nonceValue is seen.
     *
     * We don't cache nonce values seen, and we don't support subsequent
     * authentication, so the value is always 1.
     */
    private static int getNonceCount(byte[] nonceValue) {
        return 1;
    }

    private void clearPassword() {
        if (passwd != null) {
            for (int i = 0; i < passwd.length; i++) {
                passwd[i] = 0;
            }
            passwd = null;
        }
    }
}
