/*
 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.security.sasl.digest;

import java.util.Map;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.math.BigInteger;
import java.util.Random;
import java.security.Provider;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.io.IOException;

import java.security.MessageDigest;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.spec.KeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.InvalidAlgorithmParameterException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;

import javax.security.sasl.*;
import com.sun.security.sasl.util.AbstractSaslImpl;

import javax.security.auth.callback.CallbackHandler;

/**
 * Utility class for DIGEST-MD5 mechanism. Provides utility methods
 * and contains two inner classes which implement the SecurityCtx
 * interface. The inner classes provide the funtionality to allow
 * for quality-of-protection (QOP) with integrity checking and
 * privacy.
 *
 * @author Jonathan Bruce
 * @author Rosanna Lee
 */
abstract class DigestMD5Base extends AbstractSaslImpl {
    /* ------------------------- Constants ------------------------ */

    // Used for logging
    private static final String DI_CLASS_NAME = DigestIntegrity.class.getName();
    private static final String DP_CLASS_NAME = DigestPrivacy.class.getName();

    /* Constants - defined in RFC2831 */
    protected static final int MAX_CHALLENGE_LENGTH = 2048;
    protected static final int MAX_RESPONSE_LENGTH = 4096;
    protected static final int DEFAULT_MAXBUF = 65536;

    /* Supported ciphers for 'auth-conf' */
    protected static final int DES3 = 0;
    protected static final int RC4 = 1;
    protected static final int DES = 2;
    protected static final int RC4_56 = 3;
    protected static final int RC4_40 = 4;
    protected static final String[] CIPHER_TOKENS = { "3des",
                                                      "rc4",
                                                      "des",
                                                      "rc4-56",
                                                      "rc4-40" };
    private static final String[] JCE_CIPHER_NAME = {
        "DESede/CBC/NoPadding",
        "RC4",
        "DES/CBC/NoPadding",
    };

    /*
     * If QOP is set to 'auth-conf', a DIGEST-MD5 mechanism must have
     * support for the DES and Triple DES cipher algorithms (optionally,
     * support for RC4 [128/56/40 bit keys] ciphers) to provide for
     * confidentiality. See RFC 2831 for details. This implementation
     * provides support for DES, Triple DES and RC4 ciphers.
     *
     * The value of strength effects the strength of cipher used. The mappings
     * of 'high', 'medium', and 'low' give the following behaviour.
     *
     *  HIGH_STRENGTH   - Triple DES
     *                  - RC4 (128bit)
     *  MEDIUM_STRENGTH - DES
     *                  - RC4 (56bit)
     *  LOW_SRENGTH     - RC4 (40bit)
     */
    protected static final byte DES_3_STRENGTH = HIGH_STRENGTH;
    protected static final byte RC4_STRENGTH = HIGH_STRENGTH;
    protected static final byte DES_STRENGTH = MEDIUM_STRENGTH;
    protected static final byte RC4_56_STRENGTH = MEDIUM_STRENGTH;
    protected static final byte RC4_40_STRENGTH = LOW_STRENGTH;
    protected static final byte UNSET = (byte)0;
    protected static final byte[] CIPHER_MASKS = { DES_3_STRENGTH,
                                                   RC4_STRENGTH,
                                                   DES_STRENGTH,
                                                   RC4_56_STRENGTH,
                                                   RC4_40_STRENGTH };

    private static final String SECURITY_LAYER_MARKER =
        ":00000000000000000000000000000000";

    protected static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

    /* ------------------- Variable Fields ----------------------- */

    /* Used to track progress of authentication; step numbers from RFC 2831 */
    protected int step;

    /* Used to get username/password, choose realm for client */
    /* Used to obtain authorization, pw info, canonicalized authzid for server */
    protected CallbackHandler cbh;

    protected SecurityCtx secCtx;
    protected byte[] H_A1; // component of response-value

    protected byte[] nonce;         // server generated nonce

    /* Variables set when parsing directives in digest challenge/response. */
    protected String negotiatedStrength;
    protected String negotiatedCipher;
    protected String negotiatedQop;
    protected String negotiatedRealm;
    protected boolean useUTF8 = false;
    protected String encoding = "8859_1";  // default unless server specifies utf-8

    protected String digestUri;
    protected String authzid;       // authzid or canonicalized authzid

    /**
     * Constucts an instance of DigestMD5Base. Calls super constructor
     * to parse properties for mechanism.
     *
     * @param props A map of property/value pairs
     * @param className name of class to use for logging
     * @param firstStep number of first step in authentication state machine
     * @param digestUri digestUri used in authentication
     * @param cbh callback handler used to get info required for auth
     *
     * @throws SaslException If invalid value found in props.
     */
    protected DigestMD5Base(Map props, String className, int firstStep,
        String digestUri, CallbackHandler cbh) throws SaslException {
        super(props, className); // sets QOP, STENGTH and BUFFER_SIZE

        step = firstStep;
        this.digestUri = digestUri;
        this.cbh = cbh;
    }

    /**
     * Retrieves the SASL mechanism IANA name.
     *
     * @return The String "DIGEST-MD5"
     */
    public String getMechanismName() {
        return "DIGEST-MD5";
    }

    /**
     * Unwrap the incoming message using the wrap method of the secCtx object
     * instance.
     *
     * @param incoming The byte array containing the incoming bytes.
     * @param start The offset from which to read the byte array.
     * @param len The number of bytes to read from the offset.
     * @return The unwrapped message according to either the integrity or
     * privacy quality-of-protection specifications.
     * @throws SaslException if an error occurs when unwrapping the incoming
     * message
     */
    public byte[] unwrap(byte[] incoming, int start, int len) throws SaslException {
        if (!completed) {
            throw new IllegalStateException(
                "DIGEST-MD5 authentication not completed");
        }

        if (secCtx == null) {
            throw new IllegalStateException(
                "Neither integrity nor privacy was negotiated");
        }

        return (secCtx.unwrap(incoming, start, len));
    }

    /**
     * Wrap outgoing bytes using the wrap method of the secCtx object
     * instance.
     *
     * @param outgoing The byte array containing the outgoing bytes.
     * @param start The offset from which to read the byte array.
     * @param len The number of bytes to read from the offset.
     * @return The wrapped message according to either the integrity or
     * privacy quality-of-protection specifications.
     * @throws SaslException if an error occurs when wrapping the outgoing
     * message
     */
    public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException {
        if (!completed) {
            throw new IllegalStateException(
                "DIGEST-MD5 authentication not completed");
        }

        if (secCtx == null) {
            throw new IllegalStateException(
                "Neither integrity nor privacy was negotiated");
        }

        return (secCtx.wrap(outgoing, start, len));
    }

    public void dispose() throws SaslException {
        if (secCtx != null) {
            secCtx = null;
        }
    }

    public Object getNegotiatedProperty(String propName) {
        if (completed) {
            if (propName.equals(Sasl.STRENGTH)) {
                return negotiatedStrength;
            } else {
                return super.getNegotiatedProperty(propName);
            }
        } else {
            throw new IllegalStateException(
                "DIGEST-MD5 authentication not completed");
        }
    }

    /* ----------------- Digest-MD5 utilities ---------------- */
    /**
     * Generate random-string used for digest-response.
     * This method uses Random to get random bytes and then
     * base64 encodes the bytes. Could also use binaryToHex() but this
     * is slightly faster and a more compact representation of the same info.
     * @return A non-null byte array containing the nonce value for the
     * digest challenge or response.
     * Could use SecureRandom to be more secure but it is very slow.
     */

    /** This array maps the characters to their 6 bit values */
    private final static char pem_array[] = {
        //       0   1   2   3   4   5   6   7
                'A','B','C','D','E','F','G','H', // 0
                'I','J','K','L','M','N','O','P', // 1
                'Q','R','S','T','U','V','W','X', // 2
                'Y','Z','a','b','c','d','e','f', // 3
                'g','h','i','j','k','l','m','n', // 4
                'o','p','q','r','s','t','u','v', // 5
                'w','x','y','z','0','1','2','3', // 6
                '4','5','6','7','8','9','+','/'  // 7
    };

    // Make sure that this is a multiple of 3
    private static final int RAW_NONCE_SIZE = 30;

    // Base 64 encoding turns each 3 bytes into 4
    private static final int ENCODED_NONCE_SIZE = RAW_NONCE_SIZE*4/3;

    protected static final byte[] generateNonce() {

        // SecureRandom random = new SecureRandom();
        Random random = new Random();
        byte[] randomData = new byte[RAW_NONCE_SIZE];
        random.nextBytes(randomData);

        byte[] nonce = new byte[ENCODED_NONCE_SIZE];

        // Base64-encode bytes
        byte a, b, c;
        int j = 0;
        for (int i = 0; i < randomData.length; i += 3) {
            a = randomData[i];
            b = randomData[i+1];
            c = randomData[i+2];
            nonce[j++] = (byte)(pem_array[(a >>> 2) & 0x3F]);
            nonce[j++] = (byte)(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
            nonce[j++] = (byte)(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
            nonce[j++] = (byte)(pem_array[c & 0x3F]);
        }

        return nonce;

        // %%% For testing using RFC 2831 example, uncomment the following 2 lines
        // System.out.println("!!!Using RFC 2831's cnonce for testing!!!");
        // return "OA6MHXh6VqTrRk".getBytes();
    }

    /**
     * Checks if a byte[] contains characters that must be quoted
     * and write the resulting, possibly escaped, characters to out.
     */
    protected static void writeQuotedStringValue(ByteArrayOutputStream out,
        byte[] buf) {

        int len = buf.length;
        byte ch;
        for (int i = 0; i < len; i++) {
            ch = buf[i];
            if (needEscape((char)ch)) {
                out.write('\\');
            }
            out.write(ch);
        }
    }

    // See Section 7.2 of RFC 2831; double-quote character is not allowed
    // unless escaped; also escape the escape character and CTL chars except LWS
    private static boolean needEscape(String str) {
        int len = str.length();
        for (int i = 0; i < len; i++) {
            if (needEscape(str.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    // Determines whether a character needs to be escaped in a quoted string
    private static boolean needEscape(char ch) {
        return ch == '"' ||  // escape char
            ch == '\\' ||    // quote
            ch == 127 ||     // DEL

            // 0 <= ch <= 31 except CR, HT and LF
            (ch >= 0 && ch <= 31 && ch != 13 && ch != 9 && ch != 10);
    }

    protected static String quotedStringValue(String str) {
        if (needEscape(str)) {
            int len = str.length();
            char[] buf = new char[len+len];
            int j = 0;
            char ch;
            for (int i = 0; i < len; i++) {
                ch = str.charAt(i);
                if (needEscape(ch)) {
                    buf[j++] =  '\\';
                }
                buf[j++] = ch;
            }
            return new String(buf, 0, j);
        } else {
            return str;
        }
    }

    /**
     * Convert a byte array to hexadecimal string.
     *
     * @param a non-null byte array
     * @return a non-null String contain the HEX value
     */
    protected byte[] binaryToHex(byte[] digest) throws
    UnsupportedEncodingException {

        StringBuffer digestString = new StringBuffer();

        for (int i = 0; i < digest.length; i ++) {
            if ((digest[i] & 0x000000ff) < 0x10) {
                digestString.append("0"+
                    Integer.toHexString(digest[i] & 0x000000ff));
            } else {
                digestString.append(
                    Integer.toHexString(digest[i] & 0x000000ff));
            }
        }
        return digestString.toString().getBytes(encoding);
    }

    /**
     * Used to convert username-value, passwd or realm to 8859_1 encoding
     * if all chars in string are within the 8859_1 (Latin 1) encoding range.
     *
     * @param a non-null String
     * @return a non-nuill byte array containing the correct character encoding
     * for username, paswd or realm.
     */
    protected byte[] stringToByte_8859_1(String str) throws SaslException {

        char[] buffer = str.toCharArray();

        try {
            if (useUTF8) {
                for( int i = 0; i< buffer.length; i++ ) {
                    if( buffer[i] > '\u00FF' ) {
                        return str.getBytes("UTF8");
                    }
                }
            }
            return str.getBytes("8859_1");
        } catch (UnsupportedEncodingException e) {
            throw new SaslException(
                "cannot encode string in UTF8 or 8859-1 (Latin-1)", e);
        }
    }

    protected static byte[] getPlatformCiphers() {
        byte[] ciphers = new byte[CIPHER_TOKENS.length];

        for (int i = 0; i < JCE_CIPHER_NAME.length; i++) {
            try {
                // Checking whether the transformation is available from the
                // current installed providers.
                Cipher.getInstance(JCE_CIPHER_NAME[i]);

                logger.log(Level.FINE, "DIGEST01:Platform supports {0}", JCE_CIPHER_NAME[i]);
                ciphers[i] |= CIPHER_MASKS[i];
            } catch (NoSuchAlgorithmException e) {
                // no implementation found for requested algorithm.
            } catch (NoSuchPaddingException e) {
                // no implementation found for requested algorithm.
            }
        }

        if (ciphers[RC4] != UNSET) {
            ciphers[RC4_56] |= CIPHER_MASKS[RC4_56];
            ciphers[RC4_40] |= CIPHER_MASKS[RC4_40];
        }

        return ciphers;
    }

    /**
     * Assembles response-value for digest-response.
     *
     * @param authMethod "AUTHENTICATE" for client-generated response;
     *        "" for server-generated response
     * @return A non-null byte array containing the repsonse-value.
     * @throws NoSuchAlgorithmException if the platform does not have MD5
     * digest support.
     * @throws UnsupportedEncodingException if a an error occurs
     * encoding a string into either Latin-1 or UTF-8.
     * @throws IOException if an error occurs writing to the output
     * byte array buffer.
     */
    protected byte[] generateResponseValue(
        String authMethod,
        String digestUriValue,
        String qopValue,
        String usernameValue,
        String realmValue,
        char[] passwdValue,
        byte[] nonceValue,
        byte[] cNonceValue,
        int nonceCount,
        byte[] authzidValue
        ) throws NoSuchAlgorithmException,
            UnsupportedEncodingException,
            IOException {

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] hexA1, hexA2;
        ByteArrayOutputStream A2, beginA1, A1, KD;

        // A2
        // --
        // A2 = { "AUTHENTICATE:", digest-uri-value,
        // [:00000000000000000000000000000000] }  // if auth-int or auth-conf
        //
        A2 = new ByteArrayOutputStream();
        A2.write((authMethod + ":" + digestUriValue).getBytes(encoding));
        if (qopValue.equals("auth-conf") ||
            qopValue.equals("auth-int")) {

            logger.log(Level.FINE, "DIGEST04:QOP: {0}", qopValue);

            A2.write(SECURITY_LAYER_MARKER.getBytes(encoding));
        }

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST05:A2: {0}", A2.toString());
        }

        md5.update(A2.toByteArray());
        byte[] digest = md5.digest();
        hexA2 = binaryToHex(digest);

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST06:HEX(H(A2)): {0}", new String(hexA2));
        }

        // A1
        // --
        // H(user-name : realm-value : passwd)
        //
        beginA1 = new ByteArrayOutputStream();
        beginA1.write(stringToByte_8859_1(usernameValue));
        beginA1.write(':');
        // if no realm, realm will be an empty string
        beginA1.write(stringToByte_8859_1(realmValue));
        beginA1.write(':');
        beginA1.write(stringToByte_8859_1(new String(passwdValue)));

        md5.update(beginA1.toByteArray());
        digest = md5.digest();

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST07:H({0}) = {1}",
                new Object[]{beginA1.toString(), new String(binaryToHex(digest))});
        }

        // A1
        // --
        // A1 = { H ( {user-name : realm-value : passwd } ),
        // : nonce-value, : cnonce-value : authzid-value
        //
        A1 = new ByteArrayOutputStream();
        A1.write(digest);
        A1.write(':');
        A1.write(nonceValue);
        A1.write(':');
        A1.write(cNonceValue);

        if (authzidValue != null) {
            A1.write(':');
            A1.write(authzidValue);
        }
        md5.update(A1.toByteArray());
        digest = md5.digest();
        H_A1 = digest; // Record H(A1). Use for integrity & privacy.
        hexA1 = binaryToHex(digest);

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST08:H(A1) = {0}", new String(hexA1));
        }

        //
        // H(k, : , s);
        //
        KD = new ByteArrayOutputStream();
        KD.write(hexA1);
        KD.write(':');
        KD.write(nonceValue);
        KD.write(':');
        KD.write(nonceCountToHex(nonceCount).getBytes(encoding));
        KD.write(':');
        KD.write(cNonceValue);
        KD.write(':');
        KD.write(qopValue.getBytes(encoding));
        KD.write(':');
        KD.write(hexA2);

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST09:KD: {0}", KD.toString());
        }

        md5.update(KD.toByteArray());
        digest = md5.digest();

        byte[] answer = binaryToHex(digest);

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "DIGEST10:response-value: {0}",
                new String(answer));
        }
        return (answer);
    }

    /**
     * Takes 'nonceCount' value and returns HEX value of the value.
     *
     * @return A non-null String representing the current NONCE-COUNT
     */
    protected static String nonceCountToHex(int count) {

        String str = Integer.toHexString(count);
        StringBuffer pad = new StringBuffer();

        if (str.length() < 8) {
            for (int i = 0; i < 8-str.length(); i ++) {
                pad.append("0");
            }
        }

        return pad.toString() + str;
    }

    /**
     * Parses digest-challenge string, extracting each token
     * and value(s)
     *
     * @param buf A non-null digest-challenge string.
     * @param multipleAllowed true if multiple qop or realm or QOP directives
     *  are allowed.
     * @throws SaslException if the buf cannot be parsed according to RFC 2831
     */
    protected static byte[][] parseDirectives(byte[] buf,
        String[]keyTable, List<byte[]> realmChoices, int realmIndex) throws SaslException {

        byte[][] valueTable = new byte[keyTable.length][];

        ByteArrayOutputStream key = new ByteArrayOutputStream(10);
        ByteArrayOutputStream value = new ByteArrayOutputStream(10);
        boolean gettingKey = true;
        boolean gettingQuotedValue = false;
        boolean expectSeparator = false;
        byte bch;

        int i = skipLws(buf, 0);
        while (i < buf.length) {
            bch = buf[i];

            if (gettingKey) {
                if (bch == ',') {
                    if (key.size() != 0) {
                        throw new SaslException("Directive key contains a ',':" +
                            key);
                    }
                    // Empty element, skip separator and lws
                    i = skipLws(buf, i+1);

                } else if (bch == '=') {
                    if (key.size() == 0) {
                        throw new SaslException("Empty directive key");
                    }
                    gettingKey = false;      // Termination of key
                    i = skipLws(buf, i+1);   // Skip to next nonwhitespace

                    // Check whether value is quoted
                    if (i < buf.length) {
                        if (buf[i] == '"') {
                            gettingQuotedValue = true;
                            ++i; // Skip quote
                        }
                    } else {
                        throw new SaslException(
                            "Valueless directive found: " + key.toString());
                    }
                } else if (isLws(bch)) {
                    // LWS that occurs after key
                    i = skipLws(buf, i+1);

                    // Expecting '='
                    if (i < buf.length) {
                        if (buf[i] != '=') {
                            throw new SaslException("'=' expected after key: " +
                                key.toString());
                        }
                    } else {
                        throw new SaslException(
                            "'=' expected after key: " + key.toString());
                    }
                } else {
                    key.write(bch);    // Append to key
                    ++i;               // Advance
                }
            } else if (gettingQuotedValue) {
                // Getting a quoted value
                if (bch == '\\') {
                    // quoted-pair = "\" CHAR  ==> CHAR
                    ++i;       // Skip escape
                    if (i < buf.length) {
                        value.write(buf[i]);
                        ++i;   // Advance
                    } else {
                        // Trailing escape in a quoted value
                        throw new SaslException(
                            "Unmatched quote found for directive: "
                            + key.toString() + " with value: " + value.toString());
                    }
                } else if (bch == '"') {
                    // closing quote
                    ++i;  // Skip closing quote
                    gettingQuotedValue = false;
                    expectSeparator = true;
                } else {
                    value.write(bch);
                    ++i;  // Advance
                }

            } else if (isLws(bch) || bch == ',') {
                //  Value terminated

                extractDirective(key.toString(), value.toByteArray(),
                    keyTable, valueTable, realmChoices, realmIndex);
                key.reset();
                value.reset();
                gettingKey = true;
                gettingQuotedValue = expectSeparator = false;
                i = skipLws(buf, i+1);   // Skip separator and LWS

            } else if (expectSeparator) {
                throw new SaslException(
                    "Expecting comma or linear whitespace after quoted string: \""
                        + value.toString() + "\"");
            } else {
                value.write(bch);   // Unquoted value
                ++i;                // Advance
            }
        }

        if (gettingQuotedValue) {
            throw new SaslException(
                "Unmatched quote found for directive: " + key.toString() +
                " with value: " + value.toString());
        }

        // Get last pair
        if (key.size() > 0) {
            extractDirective(key.toString(), value.toByteArray(),
                keyTable, valueTable, realmChoices, realmIndex);
        }

        return valueTable;
    }

    // Is character a linear white space?
    // LWS            = [CRLF] 1*( SP | HT )
    // %%% Note that we're checking individual bytes instead of CRLF
    private static boolean isLws(byte b) {
        switch (b) {
        case 13:   // US-ASCII CR, carriage return
        case 10:   // US-ASCII LF, linefeed
        case 32:   // US-ASCII SP, space
        case 9:    // US-ASCII HT, horizontal-tab
            return true;
        }
        return false;
    }

    // Skip all linear white spaces
    private static int skipLws(byte[] buf, int start) {
        int i;
        for (i = start; i < buf.length; i++) {
            if (!isLws(buf[i])) {
                return i;
            }
        }
        return i;
    }

    /**
     * Processes directive/value pairs from the digest-challenge and
     * fill out the challengeVal array.
     *
     * @param key A non-null String challenge token name.
     * @param value A non-null String token value.
     * @throws SaslException if a either the key or the value is null
     */
    private static void  extractDirective(String key, byte[] value,
        String[] keyTable, byte[][] valueTable,
        List<byte[]> realmChoices, int realmIndex) throws SaslException {

        for (int i = 0; i < keyTable.length; i++) {
            if (key.equalsIgnoreCase(keyTable[i])) {
                if (valueTable[i] == null) {
                    valueTable[i] = value;
                    if (logger.isLoggable(Level.FINE)) {
                        logger.log(Level.FINE, "DIGEST11:Directive {0} = {1}",
                            new Object[]{
                                keyTable[i],
                                new String(valueTable[i])});
                    }
                } else if (realmChoices != null && i == realmIndex) {
                    // > 1 realm specified
                    if (realmChoices.size() == 0) {
                        realmChoices.add(valueTable[i]); // add existing one
                    }
                    realmChoices.add(value);  // add new one
                } else {
                    throw new SaslException(
                        "DIGEST-MD5: peer sent more than one " +
                        key + " directive: " + new String(value));
                }

                break; // end search
            }
        }
     }


    /**
     * Implementation of the SecurityCtx interface allowing for messages
     * between the client and server to be integrity checked. After a
     * successful DIGEST-MD5 authentication, integtrity checking is invoked
     * if the SASL QOP (quality-of-protection) is set to 'auth-int'.
     * <p>
     * Further details on the integrity-protection mechanism can be found
     * at section 2.3 - Integrity protection in the
     * <a href="http://www.ietf.org/rfc/rfc2831.txt">RFC2831</a> definition.
     *
     * @author Jonathan Bruce
     */
    class DigestIntegrity implements SecurityCtx {
        /* Used for generating integrity keys - specified in RFC 2831*/
        static final private String CLIENT_INT_MAGIC = "Digest session key to " +
            "client-to-server signing key magic constant";
        static final private String SVR_INT_MAGIC = "Digest session key to " +
            "server-to-client signing key magic constant";

        /* Key pairs for integrity checking */
        protected byte[] myKi;     // == Kic for client; == Kis for server
        protected byte[] peerKi;   // == Kis for client; == Kic for server

        protected int mySeqNum = 0;
        protected int peerSeqNum = 0;

        // outgoing messageType and sequenceNum
        protected final byte[] messageType = new byte[2];
        protected final byte[] sequenceNum = new byte[4];

        /**
         * Initializes DigestIntegrity implementation of SecurityCtx to
         * enable DIGEST-MD5 integrity checking.
         *
         * @throws SaslException if an error is encountered generating the
         * key-pairs for integrity checking.
         */
        DigestIntegrity(boolean clientMode) throws SaslException {
            /* Initialize magic strings */

            try {
                generateIntegrityKeyPair(clientMode);

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

            } catch (IOException e) {
                throw new SaslException("DIGEST-MD5: Error accessing buffers " +
                    "required to create integrity key pairs", e);

            } catch (NoSuchAlgorithmException e) {
                throw new SaslException("DIGEST-MD5: Unsupported digest " +
                    "algorithm used to create integrity key pairs", e);
            }

            /* Message type is a fixed value */
            intToNetworkByteOrder(1, messageType, 0, 2);
        }

        /**
         * Generate client-server, server-client key pairs for DIGEST-MD5
         * integrity checking.
         *
         * @throws UnsupportedEncodingException if the UTF-8 encoding is not
         * supported on the platform.
         * @throws IOException if an error occurs when writing to or from the
         * byte array output buffers.
         * @throws NoSuchAlgorithmException if the MD5 message digest algorithm
         * cannot loaded.
         */
        private void generateIntegrityKeyPair(boolean clientMode)
            throws UnsupportedEncodingException, IOException,
                NoSuchAlgorithmException {

            byte[] cimagic = CLIENT_INT_MAGIC.getBytes(encoding);
            byte[] simagic = SVR_INT_MAGIC.getBytes(encoding);

            MessageDigest md5 = MessageDigest.getInstance("MD5");

            // Both client-magic-keys and server-magic-keys are the same length
            byte[] keyBuffer = new byte[H_A1.length + cimagic.length];

            // Kic: Key for protecting msgs from client to server.
            System.arraycopy(H_A1, 0, keyBuffer, 0, H_A1.length);
            System.arraycopy(cimagic, 0, keyBuffer, H_A1.length, cimagic.length);
            md5.update(keyBuffer);
            byte[] Kic = md5.digest();

            // Kis: Key for protecting msgs from server to client
            // No need to recopy H_A1
            System.arraycopy(simagic, 0, keyBuffer, H_A1.length, simagic.length);

            md5.update(keyBuffer);
            byte[] Kis = md5.digest();

            if (logger.isLoggable(Level.FINER)) {
                traceOutput(DI_CLASS_NAME, "generateIntegrityKeyPair",
                    "DIGEST12:Kic: ", Kic);
                traceOutput(DI_CLASS_NAME, "generateIntegrityKeyPair",
                    "DIGEST13:Kis: ", Kis);
            }

            if (clientMode) {
                myKi = Kic;
                peerKi = Kis;
            } else {
                myKi = Kis;
                peerKi = Kic;
            }
        }

        /**
         * Append MAC onto outgoing message.
         *
         * @param outgoing A non-null byte array containing the outgoing message.
         * @param start The offset from which to read the byte array.
         * @param len The non-zero number of bytes for be read from the offset.
         * @return The message including the integrity MAC
         * @throws SaslException if an error is encountered converting a string
         * into a UTF-8 byte encoding, or if the MD5 message digest algorithm
         * cannot be found or if there is an error writing to the byte array
         * output buffers.
         */
        public byte[] wrap(byte[] outgoing, int start, int len)
            throws SaslException {

            if (len == 0) {
                return EMPTY_BYTE_ARRAY;
            }

            /* wrapped = message, MAC, message type, sequence number */
            byte[] wrapped = new byte[len+10+2+4];

            /* Start with message itself */
            System.arraycopy(outgoing, start, wrapped, 0, len);

            incrementSeqNum();

            /* Calculate MAC */
            byte[] mac = getHMAC(myKi, sequenceNum, outgoing, start, len);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DI_CLASS_NAME, "wrap", "DIGEST14:outgoing: ",
                    outgoing, start, len);
                traceOutput(DI_CLASS_NAME, "wrap", "DIGEST15:seqNum: ",
                    sequenceNum);
                traceOutput(DI_CLASS_NAME, "wrap", "DIGEST16:MAC: ", mac);
            }

            /* Add MAC[0..9] to message */
            System.arraycopy(mac, 0, wrapped, len, 10);

            /* Add message type [0..1] */
            System.arraycopy(messageType, 0, wrapped, len+10, 2);

            /* Add sequence number [0..3] */
            System.arraycopy(sequenceNum, 0, wrapped, len+12, 4);
            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DI_CLASS_NAME, "wrap", "DIGEST17:wrapped: ", wrapped);
            }
            return wrapped;
        }

        /**
         * Return verified message without MAC - only if the received MAC
         * and re-generated MAC are the same.
         *
         * @param incoming A non-null byte array containing the incoming
         * message.
         * @param start The offset from which to read the byte array.
         * @param len The non-zero number of bytes to read from the offset
         * position.
         * @return The verified message or null if integrity checking fails.
         * @throws SaslException if an error is encountered converting a string
         * into a UTF-8 byte encoding, or if the MD5 message digest algorithm
         * cannot be found or if there is an error writing to the byte array
         * output buffers
         */
        public byte[] unwrap(byte[] incoming, int start, int len)
            throws SaslException {

            if (len == 0) {
                return EMPTY_BYTE_ARRAY;
            }

            // shave off last 16 bytes of message
            byte[] mac = new byte[10];
            byte[] msg = new byte[len - 16];
            byte[] msgType = new byte[2];
            byte[] seqNum = new byte[4];

            /* Get Msg, MAC, msgType, sequenceNum */
            System.arraycopy(incoming, start, msg, 0, msg.length);
            System.arraycopy(incoming, start+msg.length, mac, 0, 10);
            System.arraycopy(incoming, start+msg.length+10, msgType, 0, 2);
            System.arraycopy(incoming, start+msg.length+12, seqNum, 0, 4);

            /* Calculate MAC to ensure integrity */
            byte[] expectedMac = getHMAC(peerKi, seqNum, msg, 0, msg.length);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DI_CLASS_NAME, "unwrap", "DIGEST18:incoming: ",
                    msg);
                traceOutput(DI_CLASS_NAME, "unwrap", "DIGEST19:MAC: ",
                    mac);
                traceOutput(DI_CLASS_NAME, "unwrap", "DIGEST20:messageType: ",
                    msgType);
                traceOutput(DI_CLASS_NAME, "unwrap", "DIGEST21:sequenceNum: ",
                    seqNum);
                traceOutput(DI_CLASS_NAME, "unwrap", "DIGEST22:expectedMAC: ",
                    expectedMac);
            }

            /* First, compare MAC's before updating any of our state */
            if (!Arrays.equals(mac, expectedMac)) {
                //  Discard message and do not increment sequence number
                logger.log(Level.INFO, "DIGEST23:Unmatched MACs");
                return EMPTY_BYTE_ARRAY;
            }

            /* Ensure server-sequence numbers are correct */
            if (peerSeqNum != networkByteOrderToInt(seqNum, 0, 4)) {
                throw new SaslException("DIGEST-MD5: Out of order " +
                    "sequencing of messages from server. Got: " +
                    networkByteOrderToInt(seqNum, 0, 4) +
                    " Expected: " +     peerSeqNum);
            }

            if (!Arrays.equals(messageType, msgType)) {
                throw new SaslException("DIGEST-MD5: invalid message type: " +
                    networkByteOrderToInt(msgType, 0, 2));
            }

            // Increment sequence number and return message
            peerSeqNum++;
            return msg;
        }

        /**
         * Generates MAC to be appended onto out-going messages.
         *
         * @param Ki A non-null byte array containing the key for the digest
         * @param SeqNum A non-null byte array contain the sequence number
         * @param msg  The message to be digested
         * @param start The offset from which to read the msg byte array
         * @param len The non-zero number of bytes to be read from the offset
         * @return The MAC of a message.
         *
         * @throws SaslException if an error occurs when generating MAC.
         */
        protected byte[] getHMAC(byte[] Ki, byte[] seqnum, byte[] msg,
            int start, int len) throws SaslException {

            byte[] seqAndMsg = new byte[4+len];
            System.arraycopy(seqnum, 0, seqAndMsg, 0, 4);
            System.arraycopy(msg, start, seqAndMsg, 4, len);

            try {
                SecretKey keyKi = new SecretKeySpec(Ki, "HmacMD5");
                Mac m = Mac.getInstance("HmacMD5");
                m.init(keyKi);
                m.update(seqAndMsg);
                byte[] hMAC_MD5 = m.doFinal();

                /* First 10 bytes of HMAC_MD5 digest */
                byte macBuffer[] = new byte[10];
                System.arraycopy(hMAC_MD5, 0, macBuffer, 0, 10);

                return macBuffer;
            } catch (InvalidKeyException e) {
                throw new SaslException("DIGEST-MD5: Invalid bytes used for " +
                    "key of HMAC-MD5 hash.", e);
            } catch (NoSuchAlgorithmException e) {
                throw new SaslException("DIGEST-MD5: Error creating " +
                    "instance of MD5 digest algorithm", e);
            }
        }

        /**
         * Increment own sequence number and set answer in NBO sequenceNum field.
         */
        protected void incrementSeqNum() {
            intToNetworkByteOrder(mySeqNum++, sequenceNum, 0, 4);
        }
    }

    /**
     * Implementation of the SecurityCtx interface allowing for messages
     * between the client and server to be integrity checked and encrypted.
     * After a successful DIGEST-MD5 authentication, privacy is invoked if the
     * SASL QOP (quality-of-protection) is set to 'auth-conf'.
     * <p>
     * Further details on the integrity-protection mechanism can be found
     * at section 2.4 - Confidentiality protection in
     * <a href="http://www.ietf.org/rfc/rfc2831.txt">RFC2831</a> definition.
     *
     * @author Jonathan Bruce
     */
    final class DigestPrivacy extends DigestIntegrity implements SecurityCtx {
        /* Used for generating privacy keys - specified in RFC 2831 */
        static final private String CLIENT_CONF_MAGIC =
            "Digest H(A1) to client-to-server sealing key magic constant";
        static final private String SVR_CONF_MAGIC =
            "Digest H(A1) to server-to-client sealing key magic constant";

        private Cipher encCipher;
        private Cipher decCipher;

        /**
         * Initializes the cipher object instances for encryption and decryption.
         *
         * @throws SaslException if an error occurs with the Key
         * initialization, or a string cannot be encoded into a byte array
         * using the UTF-8 encoding, or an error occurs when writing to a
         * byte array output buffers or the mechanism cannot load the MD5
         * message digest algorithm or invalid initialization parameters are
         * passed to the cipher object instances.
         */
        DigestPrivacy(boolean clientMode) throws SaslException {

            super(clientMode); // generate Kic, Kis keys for integrity-checking.

            try {
                generatePrivacyKeyPair(clientMode);

            } catch (SaslException e) {
                throw e;

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

            } catch (IOException e) {
                throw new SaslException("DIGEST-MD5: Error accessing " +
                    "buffers required to generate cipher keys", e);
            } catch (NoSuchAlgorithmException e) {
                throw new SaslException("DIGEST-MD5: Error creating " +
                    "instance of required cipher or digest", e);
            }
        }

        /**
         * Generates client-server and server-client keys to encrypt and
         * decrypt messages. Also generates IVs for DES ciphers.
         *
         * @throws IOException if an error occurs when writing to or from the
         * byte array output buffers.
         * @throws NoSuchAlgorithmException if the MD5 message digest algorithm
         * cannot loaded.
         * @throws UnsupportedEncodingException if an UTF-8 encoding is not
         * supported on the platform.
         * @throw SaslException if an error occurs initializing the keys and
         * IVs for the chosen cipher.
         */
        private void generatePrivacyKeyPair(boolean clientMode)
            throws IOException, UnsupportedEncodingException,
            NoSuchAlgorithmException, SaslException {

            byte[] ccmagic = CLIENT_CONF_MAGIC.getBytes(encoding);
            byte[] scmagic = SVR_CONF_MAGIC.getBytes(encoding);

            /* Kcc = MD5{H(A1)[0..n], "Digest ... client-to-server"} */
            MessageDigest md5 = MessageDigest.getInstance("MD5");

            int n;
            if (negotiatedCipher.equals(CIPHER_TOKENS[RC4_40])) {
                n = 5;          /* H(A1)[0..5] */
            } else if (negotiatedCipher.equals(CIPHER_TOKENS[RC4_56])) {
                n = 7;          /* H(A1)[0..7] */
            } else { // des and 3des and rc4
                n = 16;         /* H(A1)[0..16] */
            }

            /* {H(A1)[0..n], "Digest ... client-to-server..."} */
            // Both client-magic-keys and server-magic-keys are the same length
            byte[] keyBuffer =  new byte[n + ccmagic.length];
            System.arraycopy(H_A1, 0, keyBuffer, 0, n);   // H(A1)[0..n]

            /* Kcc: Key for encrypting messages from client->server */
            System.arraycopy(ccmagic, 0, keyBuffer, n, ccmagic.length);
            md5.update(keyBuffer);
            byte[] Kcc = md5.digest();

            /* Kcs: Key for decrypting messages from server->client */
            // No need to copy H_A1 again since it hasn't changed
            System.arraycopy(scmagic, 0, keyBuffer, n, scmagic.length);
            md5.update(keyBuffer);
            byte[] Kcs = md5.digest();

            if (logger.isLoggable(Level.FINER)) {
                traceOutput(DP_CLASS_NAME, "generatePrivacyKeyPair",
                    "DIGEST24:Kcc: ", Kcc);
                traceOutput(DP_CLASS_NAME, "generatePrivacyKeyPair",
                    "DIGEST25:Kcs: ", Kcs);
            }

            byte[] myKc;
            byte[] peerKc;

            if (clientMode) {
                myKc = Kcc;
                peerKc = Kcs;
            } else {
                myKc = Kcs;
                peerKc = Kcc;
            }

            try {
                SecretKey encKey;
                SecretKey decKey;

                /* Initialize cipher objects */
                if (negotiatedCipher.indexOf(CIPHER_TOKENS[RC4]) > -1) {
                    encCipher = Cipher.getInstance("RC4");
                    decCipher = Cipher.getInstance("RC4");

                    encKey = new SecretKeySpec(myKc, "RC4");
                    decKey = new SecretKeySpec(peerKc, "RC4");

                    encCipher.init(Cipher.ENCRYPT_MODE, encKey);
                    decCipher.init(Cipher.DECRYPT_MODE, decKey);

                } else if ((negotiatedCipher.equals(CIPHER_TOKENS[DES])) ||
                    (negotiatedCipher.equals(CIPHER_TOKENS[DES3]))) {

                    // DES or 3DES
                    String cipherFullname, cipherShortname;

                        // Use "NoPadding" when specifying cipher names
                        // RFC 2831 already defines padding rules for producing
                        // 8-byte aligned blocks
                    if (negotiatedCipher.equals(CIPHER_TOKENS[DES])) {
                        cipherFullname = "DES/CBC/NoPadding";
                        cipherShortname = "des";
                    } else {
                        /* 3DES */
                        cipherFullname = "DESede/CBC/NoPadding";
                        cipherShortname = "desede";
                    }

                    encCipher = Cipher.getInstance(cipherFullname);
                    decCipher = Cipher.getInstance(cipherFullname);

                    encKey = makeDesKeys(myKc, cipherShortname);
                    decKey = makeDesKeys(peerKc, cipherShortname);

                    // Set up the DES IV, which is the last 8 bytes of Kcc/Kcs
                    IvParameterSpec encIv = new IvParameterSpec(myKc, 8, 8);
                    IvParameterSpec decIv = new IvParameterSpec(peerKc, 8, 8);

                    // Initialize cipher objects
                    encCipher.init(Cipher.ENCRYPT_MODE, encKey, encIv);
                    decCipher.init(Cipher.DECRYPT_MODE, decKey, decIv);

                    if (logger.isLoggable(Level.FINER)) {
                        traceOutput(DP_CLASS_NAME, "generatePrivacyKeyPair",
                            "DIGEST26:" + negotiatedCipher + " IVcc: ",
                            encIv.getIV());
                        traceOutput(DP_CLASS_NAME, "generatePrivacyKeyPair",
                            "DIGEST27:" + negotiatedCipher + " IVcs: ",
                            decIv.getIV());
                        traceOutput(DP_CLASS_NAME, "generatePrivacyKeyPair",
                            "DIGEST28:" + negotiatedCipher + " encryption key: ",
                            encKey.getEncoded());
                        traceOutput(DP_CLASS_NAME, "generatePrivacyKeyPair",
                            "DIGEST29:" + negotiatedCipher + " decryption key: ",
                            decKey.getEncoded());
                    }
                }
            } catch (InvalidKeySpecException e) {
                throw new SaslException("DIGEST-MD5: Unsupported key " +
                    "specification used.", e);
            } catch (InvalidAlgorithmParameterException e) {
                throw new SaslException("DIGEST-MD5: Invalid cipher " +
                    "algorithem parameter used to create cipher instance", e);
            } catch (NoSuchPaddingException e) {
                throw new SaslException("DIGEST-MD5: Unsupported " +
                    "padding used for chosen cipher", e);
            } catch (InvalidKeyException e) {
                throw new SaslException("DIGEST-MD5: Invalid data " +
                    "used to initialize keys", e);
            }
        }

        // -------------------------------------------------------------------

        /**
         * Encrypt out-going message.
         *
         * @param outgoing A non-null byte array containing the outgoing message.
         * @param start The offset from which to read the byte array.
         * @param len The non-zero number of bytes to be read from the offset.
         * @return The encrypted message.
         *
         * @throws SaslException if an error occurs when writing to or from the
         * byte array output buffers or if the MD5 message digest algorithm
         * cannot loaded or if an UTF-8 encoding is not supported on the
         * platform.
         */
        public byte[] wrap(byte[] outgoing, int start, int len)
            throws SaslException {

            if (len == 0) {
                return EMPTY_BYTE_ARRAY;
            }

            /* HMAC(Ki, {SeqNum, msg})[0..9] */
            incrementSeqNum();
            byte[] mac = getHMAC(myKi, sequenceNum, outgoing, start, len);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "wrap", "DIGEST30:Outgoing: ",
                    outgoing, start, len);
                traceOutput(DP_CLASS_NAME, "wrap", "seqNum: ",
                    sequenceNum);
                traceOutput(DP_CLASS_NAME, "wrap", "MAC: ", mac);
            }

            // Calculate padding
            int bs = encCipher.getBlockSize();
            byte[] padding;
            if (bs > 1 ) {
                int pad = bs - ((len + 10) % bs); // add 10 for HMAC[0..9]
                padding = new byte[pad];
                for (int i=0; i < pad; i++) {
                    padding[i] = (byte)pad;
                }
            } else {
                padding = EMPTY_BYTE_ARRAY;
            }

            byte[] toBeEncrypted = new byte[len+padding.length+10];

            /* {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])} */
            System.arraycopy(outgoing, start, toBeEncrypted, 0, len);
            System.arraycopy(padding, 0, toBeEncrypted, len, padding.length);
            System.arraycopy(mac, 0, toBeEncrypted, len+padding.length, 10);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "wrap",
                    "DIGEST31:{msg, pad, KicMAC}: ", toBeEncrypted);
            }

            /* CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])}) */
            byte[] cipherBlock;
            try {
                // Do CBC (chaining) across packets
                cipherBlock = encCipher.update(toBeEncrypted);

                if (cipherBlock == null) {
                    // update() can return null
                    throw new IllegalBlockSizeException(""+toBeEncrypted.length);
                }
            } catch (IllegalBlockSizeException e) {
                throw new SaslException(
                    "DIGEST-MD5: Invalid block size for cipher", e);
            }

            byte[] wrapped = new byte[cipherBlock.length+2+4];
            System.arraycopy(cipherBlock, 0, wrapped, 0, cipherBlock.length);
            System.arraycopy(messageType, 0, wrapped, cipherBlock.length, 2);
            System.arraycopy(sequenceNum, 0, wrapped, cipherBlock.length+2, 4);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "wrap", "DIGEST32:Wrapped: ", wrapped);
            }

            return wrapped;
        }

        /*
         * Decrypt incoming messages and verify their integrity.
         *
         * @param incoming A non-null byte array containing the incoming
         * encrypted message.
         * @param start The offset from which to read the byte array.
         * @param len The non-zero number of bytes to read from the offset
         * position.
         * @return The decrypted, verified message or null if integrity
         * checking
         * fails.
         * @throws SaslException if there are the SASL buffer is empty or if
         * if an error occurs reading the SASL buffer.
         */
        public byte[] unwrap(byte[] incoming, int start, int len)
            throws SaslException {

            if (len == 0) {
                return EMPTY_BYTE_ARRAY;
            }

            byte[] encryptedMsg = new byte[len - 6];
            byte[] msgType = new byte[2];
            byte[] seqNum = new byte[4];

            /* Get cipherMsg; msgType; sequenceNum */
            System.arraycopy(incoming, start,
                encryptedMsg, 0, encryptedMsg.length);
            System.arraycopy(incoming, start+encryptedMsg.length,
                msgType, 0, 2);
            System.arraycopy(incoming, start+encryptedMsg.length+2,
                seqNum, 0, 4);

            if (logger.isLoggable(Level.FINEST)) {
                logger.log(Level.FINEST,
                    "DIGEST33:Expecting sequence num: {0}",
                    new Integer(peerSeqNum));
                traceOutput(DP_CLASS_NAME, "unwrap", "DIGEST34:incoming: ",
                    encryptedMsg);
            }

            // Decrypt message
            /* CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])}) */
            byte[] decryptedMsg;

            try {
                // Do CBC (chaining) across packets
                decryptedMsg = decCipher.update(encryptedMsg);

                if (decryptedMsg == null) {
                    // update() can return null
                    throw new IllegalBlockSizeException(""+encryptedMsg.length);
                }
            } catch (IllegalBlockSizeException e) {
                throw new SaslException("DIGEST-MD5: Illegal block " +
                    "sizes used with chosen cipher", e);
            }

            byte[] msgWithPadding = new byte[decryptedMsg.length - 10];
            byte[] mac = new byte[10];

            System.arraycopy(decryptedMsg, 0,
                msgWithPadding, 0, msgWithPadding.length);
            System.arraycopy(decryptedMsg, msgWithPadding.length,
                mac, 0, 10);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "unwrap",
                    "DIGEST35:Unwrapped (w/padding): ", msgWithPadding);
                traceOutput(DP_CLASS_NAME, "unwrap", "DIGEST36:MAC: ", mac);
                traceOutput(DP_CLASS_NAME, "unwrap", "DIGEST37:messageType: ",
                    msgType);
                traceOutput(DP_CLASS_NAME, "unwrap", "DIGEST38:sequenceNum: ",
                    seqNum);
            }

            int msgLength = msgWithPadding.length;
            int blockSize = decCipher.getBlockSize();
            if (blockSize > 1) {
                // get value of last octet of the byte array
                msgLength -= (int)msgWithPadding[msgWithPadding.length - 1];
                if (msgLength < 0) {
                    //  Discard message and do not increment sequence number
                    if (logger.isLoggable(Level.INFO)) {
                        logger.log(Level.INFO,
                            "DIGEST39:Incorrect padding: {0}",
                            new Byte(msgWithPadding[msgWithPadding.length - 1]));
                    }
                    return EMPTY_BYTE_ARRAY;
                }
            }

            /* Re-calculate MAC to ensure integrity */
            byte[] expectedMac = getHMAC(peerKi, seqNum, msgWithPadding,
                0, msgLength);

            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "unwrap", "DIGEST40:KisMAC: ",
                    expectedMac);
            }

            // First, compare MACs before updating state
            if (!Arrays.equals(mac, expectedMac)) {
                //  Discard message and do not increment sequence number
                logger.log(Level.INFO, "DIGEST41:Unmatched MACs");
                return EMPTY_BYTE_ARRAY;
            }

            /* Ensure sequence number is correct */
            if (peerSeqNum != networkByteOrderToInt(seqNum, 0, 4)) {
                throw new SaslException("DIGEST-MD5: Out of order " +
                    "sequencing of messages from server. Got: " +
                    networkByteOrderToInt(seqNum, 0, 4) + " Expected: " +
                    peerSeqNum);
            }

            /* Check message type */
            if (!Arrays.equals(messageType, msgType)) {
                throw new SaslException("DIGEST-MD5: invalid message type: " +
                    networkByteOrderToInt(msgType, 0, 2));
            }

            // Increment sequence number and return message
            peerSeqNum++;

            if (msgLength == msgWithPadding.length) {
                return msgWithPadding; // no padding
            } else {
                // Get a copy of the message without padding
                byte[] clearMsg = new byte[msgLength];
                System.arraycopy(msgWithPadding, 0, clearMsg, 0, msgLength);
                return clearMsg;
            }
        }
    }

    // ---------------- DES and 3 DES key manipulation routines

    private static final BigInteger MASK = new BigInteger("7f", 16);

    /**
     * Sets the parity bit (0th bit) in each byte so that each byte
     * contains an odd number of 1's.
     */
    private static void setParityBit(byte[] key) {
        for (int i = 0; i < key.length; i++) {
            int b = key[i] & 0xfe;
            b |= (Integer.bitCount(b) & 1) ^ 1;
            key[i] = (byte) b;
        }
    }

    /**
     * Expands a 7-byte array into an 8-byte array that contains parity bits
     * The binary format of a cryptographic key is:
     *     (B1,B2,...,B7,P1,B8,...B14,P2,B15,...,B49,P7,B50,...,B56,P8)
     * where (B1,B2,...,B56) are the independent bits of a DES key and
     * (PI,P2,...,P8) are reserved for parity bits computed on the preceding
     * seven independent bits and set so that the parity of the octet is odd,
     * i.e., there is an odd number of "1" bits in the octet.
     */
    private static byte[] addDesParity(byte[] input, int offset, int len) {
        if (len != 7)
            throw new IllegalArgumentException(
                "Invalid length of DES Key Value:" + len);

        byte[] raw = new byte[7];
        System.arraycopy(input, offset, raw, 0, len);

        byte[] result = new byte[8];
        BigInteger in = new BigInteger(raw);

        // Shift 7 bits each time into a byte
        for (int i=result.length-1; i>=0; i--) {
            result[i] = in.and(MASK).toByteArray()[0];
            result[i] <<= 1;         // make room for parity bit
            in = in.shiftRight(7);
        }
        setParityBit(result);
        return result;
    }

    /**
     * Create parity-adjusted keys suitable for DES / DESede encryption.
     *
     * @param input A non-null byte array containing key material for
     * DES / DESede.
     * @param desStrength A string specifying eithe a DES or a DESede key.
     * @return SecretKey An instance of either DESKeySpec or DESedeKeySpec.
     *
     * @throws NoSuchAlgorithmException if the either the DES or DESede
     * algorithms cannote be lodaed by JCE.
     * @throws InvalidKeyException if an invalid array of bytes is used
     * as a key for DES or DESede.
     * @throws InvalidKeySpecException in an invalid parameter is passed
     * to either te DESKeySpec of the DESedeKeySpec constructors.
     */
    private static SecretKey makeDesKeys(byte[] input, String desStrength)
        throws NoSuchAlgorithmException, InvalidKeyException,
            InvalidKeySpecException {

        // Generate first subkey using first 7 bytes
        byte[] subkey1 = addDesParity(input, 0, 7);

        KeySpec spec = null;
        SecretKeyFactory desFactory =
            SecretKeyFactory.getInstance(desStrength);

        if (desStrength.equals("des")) {
            spec = new DESKeySpec(subkey1, 0);
            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "makeDesKeys",
                    "DIGEST42:DES key input: ", input);
                traceOutput(DP_CLASS_NAME, "makeDesKeys",
                    "DIGEST43:DES key parity-adjusted: ", subkey1);
                traceOutput(DP_CLASS_NAME, "makeDesKeys",
                    "DIGEST44:DES key material: ", ((DESKeySpec)spec).getKey());
                logger.log(Level.FINEST, "DIGEST45: is parity-adjusted? {0}",
                    Boolean.valueOf(DESKeySpec.isParityAdjusted(subkey1, 0)));
            }

        } else if (desStrength.equals("desede")) {

            // Generate second subkey using second 7 bytes
            byte[] subkey2 = addDesParity(input, 7, 7);

            // Construct 24-byte encryption-decryption-encryption sequence
            byte[] ede = new byte[subkey1.length*2+subkey2.length];
            System.arraycopy(subkey1, 0, ede, 0, subkey1.length);
            System.arraycopy(subkey2, 0, ede, subkey1.length, subkey2.length);
            System.arraycopy(subkey1, 0, ede, subkey1.length+subkey2.length,
                subkey1.length);

            spec = new DESedeKeySpec(ede, 0);
            if (logger.isLoggable(Level.FINEST)) {
                traceOutput(DP_CLASS_NAME, "makeDesKeys",
                    "DIGEST46:3DES key input: ", input);
                traceOutput(DP_CLASS_NAME, "makeDesKeys",
                    "DIGEST47:3DES key ede: ", ede);
                traceOutput(DP_CLASS_NAME, "makeDesKeys",
                    "DIGEST48:3DES key material: ",
                    ((DESedeKeySpec)spec).getKey());
                logger.log(Level.FINEST, "DIGEST49: is parity-adjusted? ",
                    Boolean.valueOf(DESedeKeySpec.isParityAdjusted(ede, 0)));
            }
        } else {
            throw new IllegalArgumentException("Invalid DES strength:" +
                desStrength);
        }
        return desFactory.generateSecret(spec);
    }
}
