/*
 * Copyright 2003-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.Provider;
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.Random;
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.*;

/**
  * An implementation of the DIGEST-MD5 server SASL mechanism.
  * (<a href="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>)
  * <p>
  * The DIGEST-MD5 SASL mechanism specifies two modes of authentication.
  * <ul><li>Initial Authentication
  * <li>Subsequent Authentication - optional, (currently not supported)
  * </ul>
  *
  * Required callbacks:
  * - RealmCallback
  *      used as key by handler to fetch password
  * - NameCallback
  *      used as key by handler to fetch password
  * - PasswordCallback
  *      handler must enter password for username/realm supplied
  * - AuthorizeCallback
  *      handler must verify that authid/authzids are allowed and set
  *      authorized ID to be the canonicalized authzid (if applicable).
  *
  * Environment properties that affect the implementation:
  * javax.security.sasl.qop:
  *    specifies list of qops; default is "auth"; typically, caller should set
  *    this to "auth, auth-int, auth-conf".
  * javax.security.sasl.strength
  *    specifies low/medium/high strength of encryption; default is all available
  *    ciphers [high,medium,low]; high means des3 or rc4 (128); medium des or
  *    rc4-56; low is rc4-40.
  * javax.security.sasl.maxbuf
  *    specifies max receive buf size; default is 65536
  * javax.security.sasl.sendmaxbuffer
  *    specifies max send buf size; default is 65536 (min of this and client's max
  *    recv size)
  *
  * com.sun.security.sasl.digest.utf8:
  *    "true" means to use UTF-8 charset; "false" to use ISO-8859-1 encoding;
  *    default is "true".
  * com.sun.security.sasl.digest.realm:
  *    space-separated list of realms; default is server name (fqdn parameter)
  *
  * @author Rosanna Lee
  */

final class DigestMD5Server extends DigestMD5Base implements SaslServer {
    private static final String MY_CLASS_NAME = DigestMD5Server.class.getName();

    private static final String UTF8_DIRECTIVE = "charset=utf-8,";
    private static final String ALGORITHM_DIRECTIVE = "algorithm=md5-sess";

    /*
     * Always expect nonce count value to be 1 because we support only
     * initial authentication.
     */
    private static final int NONCE_COUNT_VALUE = 1;

    /* "true" means use UTF8; "false" ISO 8859-1; default is "true" */
    private static final String UTF8_PROPERTY =
        "com.sun.security.sasl.digest.utf8";

    /* List of space-separated realms used for authentication */
    private static final String REALM_PROPERTY =
        "com.sun.security.sasl.digest.realm";

    /* Directives encountered in responses sent by the client. */
    private static final String[] DIRECTIVE_KEY = {
        "username",    // exactly once
        "realm",       // exactly once if sent by server
        "nonce",       // exactly once
        "cnonce",      // exactly once
        "nonce-count", // atmost once; default is 00000001
        "qop",         // atmost once; default is "auth"
        "digest-uri",  // atmost once; (default?)
        "response",    // exactly once
        "maxbuf",      // atmost once; default is 65536
        "charset",     // atmost once; default is ISO-8859-1
        "cipher",      // exactly once if qop is "auth-conf"
        "authzid",     // atmost once; default is none
        "auth-param",  // >= 0 times (ignored)
    };

    /* Indices into DIRECTIVE_KEY */
    private static final int USERNAME = 0;
    private static final int REALM = 1;
    private static final int NONCE = 2;
    private static final int CNONCE = 3;
    private static final int NONCE_COUNT = 4;
    private static final int QOP = 5;
    private static final int DIGEST_URI = 6;
    private static final int RESPONSE = 7;
    private static final int MAXBUF = 8;
    private static final int CHARSET = 9;
    private static final int CIPHER = 10;
    private static final int AUTHZID = 11;
    private static final int AUTH_PARAM = 12;

    /* Server-generated/supplied information */
    private String specifiedQops;
    private byte[] myCiphers;
    private List<String> serverRealms;

    DigestMD5Server(String protocol, String serverName, Map props,
        CallbackHandler cbh) throws SaslException {
        super(props, MY_CLASS_NAME, 1, protocol + "/" + serverName, cbh);

        serverRealms = new ArrayList<String>();

        useUTF8 = true;  // default

        if (props != null) {
            specifiedQops = (String) props.get(Sasl.QOP);
            if ("false".equals((String) props.get(UTF8_PROPERTY))) {
                useUTF8 = false;
                logger.log(Level.FINE, "DIGEST80:Server supports ISO-Latin-1");
            }

            String realms = (String) props.get(REALM_PROPERTY);
            if (realms != null) {
                StringTokenizer parser = new StringTokenizer(realms, ", \t\n");
                int tokenCount = parser.countTokens();
                String token = null;
                for (int i = 0; i < tokenCount; i++) {
                    token = parser.nextToken();
                    logger.log(Level.FINE, "DIGEST81:Server supports realm {0}",
                        token);
                    serverRealms.add(token);
                }
            }
        }

        encoding = (useUTF8 ? "UTF8" : "8859_1");

        // By default, use server name as realm
        if (serverRealms.size() == 0) {
            serverRealms.add(serverName);
        }
    }

    public  byte[] evaluateResponse(byte[] response) throws SaslException {
        if (response.length > MAX_RESPONSE_LENGTH) {
            throw new SaslException(
                "DIGEST-MD5: Invalid digest response length. Got:  " +
                response.length + " Expected < " + MAX_RESPONSE_LENGTH);
        }

        byte[] challenge;
        switch (step) {
        case 1:
            if (response.length != 0) {
                throw new SaslException(
                    "DIGEST-MD5 must not have an initial response");
            }

            /* Generate first challenge */
            String supportedCiphers = null;
            if ((allQop&PRIVACY_PROTECTION) != 0) {
                myCiphers = getPlatformCiphers();
                StringBuffer buf = new StringBuffer();

                // myCipher[i] is a byte that indicates whether CIPHER_TOKENS[i]
                // is supported
                for (int i = 0; i < CIPHER_TOKENS.length; i++) {
                    if (myCiphers[i] != 0) {
                        if (buf.length() > 0) {
                            buf.append(',');
                        }
                        buf.append(CIPHER_TOKENS[i]);
                    }
                }
                supportedCiphers = buf.toString();
            }

            try {
                challenge = generateChallenge(serverRealms, specifiedQops,
                    supportedCiphers);

                step = 3;
                return challenge;
            } catch (UnsupportedEncodingException e) {
                throw new SaslException(
                    "DIGEST-MD5: Error encoding challenge", e);
            } catch (IOException e) {
                throw new SaslException(
                    "DIGEST-MD5: Error generating challenge", e);
            }

            // Step 2 is performed by client

        case 3:
            /* Validates client's response and generate challenge:
             *    response-auth = "rspauth" "=" response-value
             */
            try {
                byte[][] responseVal = parseDirectives(response, DIRECTIVE_KEY,
                    null, REALM);
                challenge = validateClientResponse(responseVal);
            } catch (SaslException e) {
                throw e;
            } catch (UnsupportedEncodingException e) {
                throw new SaslException(
                    "DIGEST-MD5: Error validating client response", e);
            } finally {
                step = 0;  // Set to invalid state
            }

            completed = true;

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

            return challenge;

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

    /**
     * Generates challenge to be sent to client.
     *  digest-challenge  =
     *    1#( realm | nonce | qop-options | stale | maxbuf | charset
     *               algorithm | cipher-opts | auth-param )
     *
     *        realm             = "realm" "=" <"> realm-value <">
     *        realm-value       = qdstr-val
     *        nonce             = "nonce" "=" <"> nonce-value <">
     *        nonce-value       = qdstr-val
     *        qop-options       = "qop" "=" <"> qop-list <">
     *        qop-list          = 1#qop-value
     *        qop-value         = "auth" | "auth-int" | "auth-conf" |
     *                             token
     *        stale             = "stale" "=" "true"
     *        maxbuf            = "maxbuf" "=" maxbuf-value
     *        maxbuf-value      = 1*DIGIT
     *        charset           = "charset" "=" "utf-8"
     *        algorithm         = "algorithm" "=" "md5-sess"
     *        cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
     *        cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
     *                            "rc4-56" | token
     *        auth-param        = token "=" ( token | quoted-string )
     */
    private byte[] generateChallenge(List<String> realms, String qopStr,
        String cipherStr) throws UnsupportedEncodingException, IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // Realms (>= 0)
        for (int i = 0; realms != null && i < realms.size(); i++) {
            out.write("realm=\"".getBytes(encoding));
            writeQuotedStringValue(out, realms.get(i).getBytes(encoding));
            out.write('"');
            out.write(',');
        }

        // Nonce - required (1)
        out.write(("nonce=\"").getBytes(encoding));
        nonce = generateNonce();
        writeQuotedStringValue(out, nonce);
        out.write('"');
        out.write(',');

        // QOP - optional (1) [default: auth]
        // qop="auth,auth-conf,auth-int"
        if (qopStr != null) {
            out.write(("qop=\"").getBytes(encoding));
            // Check for quotes in case of non-standard qop options
            writeQuotedStringValue(out, qopStr.getBytes(encoding));
            out.write('"');
            out.write(',');
        }

        // maxbuf - optional (1) [default: 65536]
        if (recvMaxBufSize != DEFAULT_MAXBUF) {
            out.write(("maxbuf=\"" + recvMaxBufSize + "\",").getBytes(encoding));
        }

        // charset - optional (1) [default: ISO 8859_1]
        if (useUTF8) {
            out.write(UTF8_DIRECTIVE.getBytes(encoding));
        }

        if (cipherStr != null) {
            out.write("cipher=\"".getBytes(encoding));
            // Check for quotes in case of custom ciphers
            writeQuotedStringValue(out, cipherStr.getBytes(encoding));
            out.write('"');
            out.write(',');
        }

        // algorithm - required (1)
        out.write(ALGORITHM_DIRECTIVE.getBytes(encoding));

        return out.toByteArray();
    }

    /**
     * Validates client's response.
     *   digest-response  = 1#( username | realm | nonce | cnonce |
     *                          nonce-count | qop | digest-uri | response |
     *                          maxbuf | charset | cipher | authzid |
     *                          auth-param )
     *
     *       username         = "username" "=" <"> username-value <">
     *       username-value   = qdstr-val
     *       cnonce           = "cnonce" "=" <"> cnonce-value <">
     *       cnonce-value     = qdstr-val
     *       nonce-count      = "nc" "=" nc-value
     *       nc-value         = 8LHEX
     *       qop              = "qop" "=" qop-value
     *       digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
     *       digest-uri-value  = serv-type "/" host [ "/" serv-name ]
     *       serv-type        = 1*ALPHA
     *       host             = 1*( ALPHA | DIGIT | "-" | "." )
     *       serv-name        = host
     *       response         = "response" "=" response-value
     *       response-value   = 32LHEX
     *       LHEX             = "0" | "1" | "2" | "3" |
     *                          "4" | "5" | "6" | "7" |
     *                          "8" | "9" | "a" | "b" |
     *                          "c" | "d" | "e" | "f"
     *       cipher           = "cipher" "=" cipher-value
     *       authzid          = "authzid" "=" <"> authzid-value <">
     *       authzid-value    = qdstr-val
     * sets:
     *   negotiatedQop
     *   negotiatedCipher
     *   negotiatedRealm
     *   negotiatedStrength
     *   digestUri (checked and set to clients to account for case diffs)
     *   sendMaxBufSize
     *   authzid (gotten from callback)
     * @return response-value ('rspauth') for client to validate
     */
    private byte[] validateClientResponse(byte[][] responseVal)
        throws SaslException, UnsupportedEncodingException {

        /* CHARSET: optional atmost once */
        if (responseVal[CHARSET] != null) {
            // The client should send this directive only if the server has
            // indicated it supports UTF-8.
            if (!useUTF8 ||
                !"utf-8".equals(new String(responseVal[CHARSET], encoding))) {
                throw new SaslException("DIGEST-MD5: digest response format " +
                    "violation. Incompatible charset value: " +
                    new String(responseVal[CHARSET]));
            }
        }

        // maxbuf: atmost once
        int clntMaxBufSize =
            (responseVal[MAXBUF] == null) ? DEFAULT_MAXBUF
            : Integer.parseInt(new String(responseVal[MAXBUF], encoding));

        // Max send buf size is min of client's max recv buf size and
        // server's max send buf size
        sendMaxBufSize = ((sendMaxBufSize == 0) ? clntMaxBufSize :
            Math.min(sendMaxBufSize, clntMaxBufSize));

        /* username: exactly once */
        String username;
        if (responseVal[USERNAME] != null) {
            username = new String(responseVal[USERNAME], encoding);
            logger.log(Level.FINE, "DIGEST82:Username: {0}", username);
        } else {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Missing username.");
        }

        /* realm: exactly once if sent by server */
        negotiatedRealm = ((responseVal[REALM] != null) ?
            new String(responseVal[REALM], encoding) : "");
        logger.log(Level.FINE, "DIGEST83:Client negotiated realm: {0}",
            negotiatedRealm);

        if (!serverRealms.contains(negotiatedRealm)) {
            // Server had sent at least one realm
            // Check that response is one of these
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Nonexistent realm: " + negotiatedRealm);
        }
        // Else, client specified realm was one of server's or server had none

        /* nonce: exactly once */
        if (responseVal[NONCE] == null) {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Missing nonce.");
        }
        byte[] nonceFromClient = responseVal[NONCE];
        if (!Arrays.equals(nonceFromClient, nonce)) {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Mismatched nonce.");
        }

        /* cnonce: exactly once */
        if (responseVal[CNONCE] == null) {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Missing cnonce.");
        }
        byte[] cnonce = responseVal[CNONCE];

        /* nonce-count: atmost once */
        if (responseVal[NONCE_COUNT] != null &&
            NONCE_COUNT_VALUE != Integer.parseInt(
                new String(responseVal[NONCE_COUNT], encoding), 16)) {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Nonce count does not match: " +
                new String(responseVal[NONCE_COUNT]));
        }

        /* qop: atmost once; default is "auth" */
        negotiatedQop = ((responseVal[QOP] != null) ?
            new String(responseVal[QOP], encoding) : "auth");

        logger.log(Level.FINE, "DIGEST84:Client negotiated qop: {0}",
            negotiatedQop);

        // Check that QOP is one sent by server
        byte cQop;
        if (negotiatedQop.equals("auth")) {
            cQop = NO_PROTECTION;
        } else if (negotiatedQop.equals("auth-int")) {
            cQop = INTEGRITY_ONLY_PROTECTION;
            integrity = true;
            rawSendSize = sendMaxBufSize - 16;
        } else if (negotiatedQop.equals("auth-conf")) {
            cQop = PRIVACY_PROTECTION;
            integrity = privacy = true;
            rawSendSize = sendMaxBufSize - 26;
        } else {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Invalid QOP: " + negotiatedQop);
        }
        if ((cQop&allQop) == 0) {
            throw new SaslException("DIGEST-MD5: server does not support " +
                " qop: " + negotiatedQop);
        }

        if (privacy) {
            negotiatedCipher = ((responseVal[CIPHER] != null) ?
                new String(responseVal[CIPHER], encoding) : null);
            if (negotiatedCipher == null) {
                throw new SaslException("DIGEST-MD5: digest response format " +
                    "violation. No cipher specified.");
            }

            int foundCipher = -1;
            logger.log(Level.FINE, "DIGEST85:Client negotiated cipher: {0}",
                negotiatedCipher);

            // Check that cipher is one that we offered
            for (int j = 0; j < CIPHER_TOKENS.length; j++) {
                if (negotiatedCipher.equals(CIPHER_TOKENS[j]) &&
                    myCiphers[j] != 0) {
                    foundCipher = j;
                    break;
                }
            }
            if (foundCipher == -1) {
                throw new SaslException("DIGEST-MD5: server does not " +
                    "support cipher: " + negotiatedCipher);
            }
            // Set negotiatedStrength
            if ((CIPHER_MASKS[foundCipher]&HIGH_STRENGTH) != 0) {
                negotiatedStrength = "high";
            } else if ((CIPHER_MASKS[foundCipher]&MEDIUM_STRENGTH) != 0) {
                negotiatedStrength = "medium";
            } else {
                // assume default low
                negotiatedStrength = "low";
            }

            logger.log(Level.FINE, "DIGEST86:Negotiated strength: {0}",
                negotiatedStrength);
        }

        // atmost once
        String digestUriFromResponse = ((responseVal[DIGEST_URI]) != null ?
            new String(responseVal[DIGEST_URI], encoding) : null);

        if (digestUriFromResponse != null) {
            logger.log(Level.FINE, "DIGEST87:digest URI: {0}",
                digestUriFromResponse);
        }

        // serv-type "/" host [ "/" serv-name ]
        // e.g.: smtp/mail3.example.com/example.com
        // e.g.: ftp/ftp.example.com
        // e.g.: ldap/ldapserver.example.com

        // host should match one of service's configured service names
        // Check against digest URI that mech was created with

        if (digestUri.equalsIgnoreCase(digestUriFromResponse)) {
            digestUri = digestUriFromResponse; // account for case-sensitive diffs
        } else {
            throw new SaslException("DIGEST-MD5: digest response format " +
                "violation. Mismatched URI: " + digestUriFromResponse +
                "; expecting: " + digestUri);
        }

        // response: exactly once
        byte[] responseFromClient = responseVal[RESPONSE];
        if (responseFromClient == null) {
            throw new SaslException("DIGEST-MD5: digest response format " +
                " violation. Missing response.");
        }

        // authzid: atmost once
        byte[] authzidBytes;
        String authzidFromClient = ((authzidBytes=responseVal[AUTHZID]) != null?
            new String(authzidBytes, encoding) : username);

        if (authzidBytes != null) {
            logger.log(Level.FINE, "DIGEST88:Authzid: {0}",
                new String(authzidBytes));
        }

        // Ignore auth-param

        // Get password need to generate verifying response
        char[] passwd;
        try {
            // Realm and Name callbacks are used to provide info
            RealmCallback rcb = new RealmCallback("DIGEST-MD5 realm: ",
                negotiatedRealm);
            NameCallback ncb = new NameCallback("DIGEST-MD5 authentication ID: ",
                username);

            // PasswordCallback is used to collect info
            PasswordCallback pcb =
                new PasswordCallback("DIGEST-MD5 password: ", false);

            cbh.handle(new Callback[] {rcb, ncb, pcb});
            passwd = pcb.getPassword();
            pcb.clearPassword();

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

        } catch (IOException e) {
            throw new SaslException(
                "DIGEST-MD5: IO error acquiring password", e);
        }

        if (passwd == null) {
            throw new SaslException(
                "DIGEST-MD5: cannot acquire password for " + username +
                " in realm : " + negotiatedRealm);
        }

        try {
            // Validate response value sent by client
            byte[] expectedResponse;

            try {
                expectedResponse = generateResponseValue("AUTHENTICATE",
                    digestUri, negotiatedQop, username, negotiatedRealm,
                    passwd, nonce /* use own nonce */,
                    cnonce, NONCE_COUNT_VALUE, authzidBytes);

            } catch (NoSuchAlgorithmException e) {
                throw new SaslException(
                    "DIGEST-MD5: problem duplicating client response", e);
            } catch (IOException e) {
                throw new SaslException(
                    "DIGEST-MD5: problem duplicating client response", e);
            }

            if (!Arrays.equals(responseFromClient, expectedResponse)) {
                throw new SaslException("DIGEST-MD5: digest response format " +
                    "violation. Mismatched response.");
            }

            // Ensure that authzid mapping is OK
            try {
                AuthorizeCallback acb =
                    new AuthorizeCallback(username, authzidFromClient);
                cbh.handle(new Callback[]{acb});

                if (acb.isAuthorized()) {
                    authzid = acb.getAuthorizedID();
                } else {
                    throw new SaslException("DIGEST-MD5: " + username +
                        " is not authorized to act as " + authzidFromClient);
                }
            } catch (SaslException e) {
                throw e;
            } catch (UnsupportedCallbackException e) {
                throw new SaslException(
                    "DIGEST-MD5: Cannot perform callback to check authzid", e);
            } catch (IOException e) {
                throw new SaslException(
                    "DIGEST-MD5: IO error checking authzid", e);
            }

            return generateResponseAuth(username, passwd, cnonce,
                NONCE_COUNT_VALUE, authzidBytes);
        } finally {
            // Clear password
            for (int i = 0; i < passwd.length; i++) {
                passwd[i] = 0;
            }
        }
    }

    /**
     * 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" }
     *
     * Clears password afterwards.
     */
    private byte[] generateResponseAuth(String username, char[] passwd,
        byte[] cnonce, int nonceCount, byte[] authzidBytes) throws SaslException {

        // Construct response value

        try {
            byte[] responseValue = generateResponseValue("",
                digestUri, negotiatedQop, username, negotiatedRealm,
                passwd, nonce, cnonce, nonceCount, authzidBytes);

            byte[] challenge = new byte[responseValue.length + 8];
            System.arraycopy("rspauth=".getBytes(encoding), 0, challenge, 0, 8);
            System.arraycopy(responseValue, 0, challenge, 8,
                responseValue.length );

            return challenge;

        } catch (NoSuchAlgorithmException e) {
            throw new SaslException("DIGEST-MD5: problem generating response", e);
        } catch (IOException e) {
            throw new SaslException("DIGEST-MD5: problem generating response", e);
        }
    }

    public String getAuthorizationID() {
        if (completed) {
            return authzid;
        } else {
            throw new IllegalStateException(
                "DIGEST-MD5 server negotiation not complete");
        }
    }
}
