/*
 * Copyright 2005-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 sun.security.jgss.spnego;

import java.io.*;
import java.security.Provider;
import java.util.List;
import java.util.ArrayList;
import org.ietf.jgss.*;
import sun.security.jgss.*;
import sun.security.jgss.spi.*;
import sun.security.util.*;

/**
 * Implements the mechanism specific context class for SPNEGO
 * GSS-API mechanism
 *
 * @author Seema Malkani
 * @since 1.6
 */
public class SpNegoContext implements GSSContextSpi {

    /*
     * The different states that this context can be in.
     */
    private static final int STATE_NEW = 1;
    private static final int STATE_IN_PROCESS = 2;
    private static final int STATE_DONE = 3;
    private static final int STATE_DELETED = 4;

    private int state = STATE_NEW;

    private static final int CHECKSUM_DELEG_FLAG    = 1;
    private static final int CHECKSUM_MUTUAL_FLAG   = 2;
    private static final int CHECKSUM_REPLAY_FLAG   = 4;
    private static final int CHECKSUM_SEQUENCE_FLAG = 8;
    private static final int CHECKSUM_CONF_FLAG     = 16;
    private static final int CHECKSUM_INTEG_FLAG    = 32;

    /*
     * Optional features that the application can set and their default
     * values.
     */
    private boolean credDelegState = false;
    private boolean mutualAuthState = true;
    private boolean replayDetState = true;
    private boolean sequenceDetState = true;
    private boolean confState = true;
    private boolean integState = true;

    private GSSNameSpi peerName = null;
    private GSSNameSpi myName = null;
    private SpNegoCredElement myCred = null;

    private GSSContext mechContext = null;
    private byte[] DER_mechTypes = null;

    private int lifetime;
    private ChannelBinding channelBinding;
    private boolean initiator;

    // the underlying negotiated mechanism
    private Oid internal_mech = null;

    // the SpNegoMechFactory that creates this context
    final private SpNegoMechFactory factory;

    // debug property
    static final boolean DEBUG =
        java.security.AccessController.doPrivileged(
            new sun.security.action.GetBooleanAction
            ("sun.security.spnego.debug")).booleanValue();

    /**
     * Constructor for SpNegoContext to be called on the context initiator's
     * side.
     */
    public SpNegoContext(SpNegoMechFactory factory, GSSNameSpi peerName,
                        GSSCredentialSpi myCred,
                        int lifetime) throws GSSException {

        if (peerName == null)
            throw new IllegalArgumentException("Cannot have null peer name");
        if ((myCred != null) && !(myCred instanceof SpNegoCredElement)) {
            throw new IllegalArgumentException("Wrong cred element type");
        }
        this.peerName = peerName;
        this.myCred = (SpNegoCredElement) myCred;
        this.lifetime = lifetime;
        this.initiator = true;
        this.factory = factory;
    }

    /**
     * Constructor for SpNegoContext to be called on the context acceptor's
     * side.
     */
    public SpNegoContext(SpNegoMechFactory factory, GSSCredentialSpi myCred)
            throws GSSException {
        if ((myCred != null) && !(myCred instanceof SpNegoCredElement)) {
            throw new IllegalArgumentException("Wrong cred element type");
        }
        this.myCred = (SpNegoCredElement) myCred;
        this.initiator = false;
        this.factory = factory;
    }

    /**
     * Constructor for SpNegoContext to import a previously exported context.
     */
    public SpNegoContext(SpNegoMechFactory factory, byte [] interProcessToken)
        throws GSSException {
        throw new GSSException(GSSException.UNAVAILABLE,
                               -1, "GSS Import Context not available");
    }

    /**
     * Requests that confidentiality be available.
     */
    public final void requestConf(boolean value) throws GSSException {
        if (state == STATE_NEW && isInitiator())
            confState  = value;
    }

    /**
     * Is confidentiality available?
     */
    public final boolean getConfState() {
        return confState;
    }

    /**
     * Requests that integrity be available.
     */
    public final void requestInteg(boolean value) throws GSSException {
        if (state == STATE_NEW && isInitiator())
            integState  = value;
    }

    /**
     * Is integrity available?
     */
    public final boolean getIntegState() {
        return integState;
    }

    /**
     * Requests that credential delegation be done during context
     * establishment.
     */
    public final void requestCredDeleg(boolean value) throws GSSException {
        if (state == STATE_NEW && isInitiator())
            credDelegState  = value;
    }

    /**
     * Is credential delegation enabled?
     */
    public final boolean getCredDelegState() {
        if (mechContext != null &&
                (state == STATE_IN_PROCESS || state == STATE_DONE)) {
            return mechContext.getCredDelegState();
        } else {
            return credDelegState;
        }
    }

    /**
     * Requests that mutual authentication be done during context
     * establishment. Since this is fromm the client's perspective, it
     * essentially requests that the server be authenticated.
     */
    public final void requestMutualAuth(boolean value) throws GSSException {
        if (state == STATE_NEW && isInitiator()) {
            mutualAuthState  = value;
        }
    }

    /**
     * Is mutual authentication enabled? Since this is from the client's
     * perspective, it essentially meas that the server is being
     * authenticated.
     */
    public final boolean getMutualAuthState() {
        return mutualAuthState;
    }

    final void setCredDelegState(boolean state) {
        credDelegState = state;
    }

    final void setMutualAuthState(boolean state) {
        mutualAuthState = state;
    }

    final void setReplayDetState(boolean state) {
        replayDetState = state;
    }

    final void setSequenceDetState(boolean state) {
        sequenceDetState = state;
    }

    final void setConfState(boolean state) {
        confState = state;
    }

    final void setIntegState(boolean state) {
        integState = state;
    }

    /**
     * Returns the mechanism oid.
     *
     * @return the Oid of this context
     */
    public final Oid getMech() {
        if (isEstablished()) {
            return getNegotiatedMech();
        }
        return (SpNegoMechFactory.GSS_SPNEGO_MECH_OID);
    }

    public final Oid getNegotiatedMech() {
        return (internal_mech);
    }

    public final Provider getProvider() {
        return SpNegoMechFactory.PROVIDER;
    }

    public final void dispose() throws GSSException {
        mechContext = null;
        state = STATE_DELETED;
    }

    /**
     * Tests if this is the initiator side of the context.
     *
     * @return boolean indicating if this is initiator (true)
     *  or target (false)
     */
    public final boolean isInitiator() {
        return initiator;
    }

    /**
     * Tests if the context can be used for per-message service.
     * Context may allow the calls to the per-message service
     * functions before being fully established.
     *
     * @return boolean indicating if per-message methods can
     *  be called.
     */
    public final boolean isProtReady() {
        return (state == STATE_DONE);
    }

    /**
     * Initiator context establishment call. This method may be
     * required to be called several times. A CONTINUE_NEEDED return
     * call indicates that more calls are needed after the next token
     * is received from the peer.
     *
     * @param is contains the token received from the peer. On the
     *        first call it will be ignored.
     * @return any token required to be sent to the peer
     * It is responsibility of the caller to send the token
     * to its peer for processing.
     * @exception GSSException
     */
    public final byte[] initSecContext(InputStream is, int mechTokenSize)
        throws GSSException {

        byte[] retVal = null;
        NegTokenInit initToken = null;
        byte[] mechToken = null;
        int errorCode = GSSException.FAILURE;

        if (DEBUG) {
            System.out.println("Entered SpNego.initSecContext with " +
                                "state=" + printState(state));
        }
        if (!isInitiator()) {
            throw new GSSException(GSSException.FAILURE, -1,
                "initSecContext on an acceptor GSSContext");
        }

        try {
            if (state == STATE_NEW) {
                state = STATE_IN_PROCESS;

                errorCode = GSSException.NO_CRED;

                // determine available mech set
                Oid[] mechList = getAvailableMechs();
                DER_mechTypes = getEncodedMechs(mechList);

                // pull out first mechanism
                internal_mech = mechList[0];

                // get the token for first mechanism
                mechToken = GSS_initSecContext(null);

                errorCode = GSSException.DEFECTIVE_TOKEN;
                byte[] micToken = null;
                if (!GSSUtil.useMSInterop()) {
                    // calculate MIC only in normal mode
                    micToken = generateMechListMIC(DER_mechTypes);
                }
                // generate SPNEGO token
                initToken = new NegTokenInit(DER_mechTypes, getContextFlags(),
                                        mechToken, micToken);
                if (DEBUG) {
                    System.out.println("SpNegoContext.initSecContext: " +
                                "sending token of type = " +
                                SpNegoToken.getTokenName(initToken.getType()));
                }
                // get the encoded token
                retVal = initToken.getEncoded();

            } else if (state == STATE_IN_PROCESS) {

                errorCode = GSSException.FAILURE;
                if (is == null) {
                    throw new GSSException(errorCode, -1,
                                "No token received from peer!");
                }

                errorCode = GSSException.DEFECTIVE_TOKEN;
                byte[] server_token = new byte[is.available()];
                SpNegoToken.readFully(is, server_token);
                if (DEBUG) {
                    System.out.println("SpNegoContext.initSecContext: " +
                                        "process received token = " +
                                        SpNegoToken.getHexBytes(server_token));
                }

                // read the SPNEGO token
                // token will be validated when parsing
                NegTokenTarg targToken = new NegTokenTarg(server_token);

                if (DEBUG) {
                    System.out.println("SpNegoContext.initSecContext: " +
                                "received token of type = " +
                                SpNegoToken.getTokenName(targToken.getType()));
                }

                // pull out mechanism
                internal_mech = targToken.getSupportedMech();
                if (internal_mech == null) {
                    // return wth failure
                    throw new GSSException(errorCode, -1,
                                "supported mechansim from server is null");
                }

                // get the negotiated result
                SpNegoToken.NegoResult negoResult = null;
                int result = targToken.getNegotiatedResult();
                switch (result) {
                    case 0:
                        negoResult = SpNegoToken.NegoResult.ACCEPT_COMPLETE;
                        state = STATE_DONE;
                        break;
                    case 1:
                        negoResult = SpNegoToken.NegoResult.ACCEPT_INCOMPLETE;
                        state = STATE_IN_PROCESS;
                        break;
                    case 2:
                        negoResult = SpNegoToken.NegoResult.REJECT;
                        state = STATE_DELETED;
                        break;
                    default:
                        state = STATE_DONE;
                        break;
                }

                errorCode = GSSException.BAD_MECH;

                if (negoResult == SpNegoToken.NegoResult.REJECT) {
                    throw new GSSException(errorCode, -1,
                                        internal_mech.toString());
                }

                errorCode = GSSException.DEFECTIVE_TOKEN;

                if ((negoResult == SpNegoToken.NegoResult.ACCEPT_COMPLETE) ||
                    (negoResult == SpNegoToken.NegoResult.ACCEPT_INCOMPLETE)) {

                    // pull out the mechanism token
                    byte[] accept_token = targToken.getResponseToken();
                    if (accept_token == null) {
                        // return wth failure
                        throw new GSSException(errorCode, -1,
                                        "mechansim token from server is null");
                    }

                    mechToken = GSS_initSecContext(accept_token);

                    // verify MIC
                    if (!GSSUtil.useMSInterop()) {
                        byte[] micToken = targToken.getMechListMIC();
                        if (!verifyMechListMIC(DER_mechTypes, micToken)) {
                            throw new GSSException(errorCode, -1,
                                "verification of MIC on MechList Failed!");
                        }
                    }

                    if (isMechContextEstablished()) {
                        state = STATE_DONE;
                        retVal = mechToken;
                        if (DEBUG) {
                            System.out.println("SPNEGO Negotiated Mechanism = "
                                + internal_mech + " " +
                                GSSUtil.getMechStr(internal_mech));
                        }
                    } else {
                        // generate SPNEGO token
                        initToken = new NegTokenInit(null, null,
                                                mechToken, null);
                        if (DEBUG) {
                            System.out.println("SpNegoContext.initSecContext:" +
                                " continue sending token of type = " +
                                SpNegoToken.getTokenName(initToken.getType()));
                        }
                        // get the encoded token
                        retVal = initToken.getEncoded();
                    }
                }

            } else {
                // XXX Use logging API
                if (DEBUG) {
                    System.out.println(state);
                }
            }
            if (DEBUG) {
                if (retVal != null) {
                    System.out.println("SNegoContext.initSecContext: " +
                        "sending token = " + SpNegoToken.getHexBytes(retVal));
                }
            }
        } catch (GSSException e) {
            GSSException gssException =
                        new GSSException(errorCode, -1, e.getMessage());
            gssException.initCause(e);
            throw gssException;
        } catch (IOException e) {
            GSSException gssException =
                new GSSException(GSSException.FAILURE, -1, e.getMessage());
            gssException.initCause(e);
            throw gssException;
        }

        return retVal;
    }


    /**
     * Acceptor's context establishment call. This method may be
     * required to be called several times. A CONTINUE_NEEDED return
     * call indicates that more calls are needed after the next token
     * is received from the peer.
     *
     * @param is contains the token received from the peer.
     * @return any token required to be sent to the peer
     * It is responsibility of the caller to send the token
     * to its peer for processing.
     * @exception GSSException
     */
    public final byte[] acceptSecContext(InputStream is, int mechTokenSize)
        throws GSSException {

        byte[] retVal = null;
        SpNegoToken.NegoResult negoResult;
        boolean valid = true;

        if (DEBUG) {
            System.out.println("Entered SpNegoContext.acceptSecContext with " +
                               "state=" +  printState(state));
        }

        if (isInitiator()) {
            throw new GSSException(GSSException.FAILURE, -1,
                                   "acceptSecContext on an initiator " +
                                   "GSSContext");
        }
        try {
            if (state == STATE_NEW) {
                state = STATE_IN_PROCESS;

                // read data
                byte[] token = new byte[is.available()];
                SpNegoToken.readFully(is, token);
                if (DEBUG) {
                    System.out.println("SpNegoContext.acceptSecContext: " +
                                        "receiving token = " +
                                        SpNegoToken.getHexBytes(token));
                }

                // read the SPNEGO token
                // token will be validated when parsing
                NegTokenInit initToken = new NegTokenInit(token);

                if (DEBUG) {
                    System.out.println("SpNegoContext.acceptSecContext: " +
                                "received token of type = " +
                                SpNegoToken.getTokenName(initToken.getType()));
                }

                Oid[] mechList = initToken.getMechTypeList();
                DER_mechTypes = initToken.getMechTypes();
                if (DER_mechTypes == null) {
                    valid = false;
                }

                // get the mechanism token
                byte[] mechToken = initToken.getMechToken();

                /*
                 * Select the best match between the list of mechs
                 * that the initiator requested and the list that
                 * the acceptor will support.
                 */
                Oid[] supported_mechSet = getAvailableMechs();
                Oid mech_wanted =
                        negotiate_mech_type(supported_mechSet, mechList);
                if (mech_wanted == null) {
                    valid = false;
                }
                // save the desired mechansim
                internal_mech = mech_wanted;

                // get the token for mechanism
                byte[] accept_token = GSS_acceptSecContext(mechToken);
                if (accept_token == null) {
                    valid = false;
                }

                // verify MIC
                if (!GSSUtil.useMSInterop() && valid) {
                    valid = verifyMechListMIC(DER_mechTypes,
                                                initToken.getMechListMIC());
                }

                // determine negotiated result status
                if (valid) {
                    if (isMechContextEstablished()) {
                        negoResult = SpNegoToken.NegoResult.ACCEPT_COMPLETE;
                        state = STATE_DONE;
                        // now set the context flags for acceptor
                        setContextFlags();
                        // print the negotiated mech info
                        if (DEBUG) {
                            System.out.println("SPNEGO Negotiated Mechanism = "
                                + internal_mech + " " +
                                GSSUtil.getMechStr(internal_mech));
                        }
                    } else {
                        negoResult = SpNegoToken.NegoResult.ACCEPT_INCOMPLETE;
                        state = STATE_IN_PROCESS;
                    }
                } else {
                    negoResult = SpNegoToken.NegoResult.REJECT;
                    state = STATE_DONE;
                }

                if (DEBUG) {
                    System.out.println("SpNegoContext.acceptSecContext: " +
                                "mechanism wanted = " + mech_wanted);
                    System.out.println("SpNegoContext.acceptSecContext: " +
                                "negotiated result = " + negoResult);
                }

                // calculate MIC only in normal mode
                byte[] micToken = null;
                if (!GSSUtil.useMSInterop() && valid) {
                    micToken = generateMechListMIC(DER_mechTypes);
                }

                // generate SPNEGO token
                NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(),
                                mech_wanted, accept_token, micToken);
                if (DEBUG) {
                    System.out.println("SpNegoContext.acceptSecContext: " +
                                "sending token of type = " +
                                SpNegoToken.getTokenName(targToken.getType()));
                }
                // get the encoded token
                retVal = targToken.getEncoded();

            } else if (state == STATE_IN_PROCESS) {
                // read the token
                byte[] client_token = new byte[is.available()];
                SpNegoToken.readFully(is, client_token);
                byte[] accept_token = GSS_acceptSecContext(client_token);
                if (accept_token == null) {
                    valid = false;
                }

                // determine negotiated result status
                if (valid) {
                    if (isMechContextEstablished()) {
                        negoResult = SpNegoToken.NegoResult.ACCEPT_COMPLETE;
                        state = STATE_DONE;
                    } else {
                        negoResult = SpNegoToken.NegoResult.ACCEPT_INCOMPLETE;
                        state = STATE_IN_PROCESS;
                    }
                } else {
                    negoResult = SpNegoToken.NegoResult.REJECT;
                    state = STATE_DONE;
                }

                // generate SPNEGO token
                NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(),
                                null, accept_token, null);
                if (DEBUG) {
                    System.out.println("SpNegoContext.acceptSecContext: " +
                                "sending token of type = " +
                                SpNegoToken.getTokenName(targToken.getType()));
                }
                // get the encoded token
                retVal = targToken.getEncoded();

            } else {
                // XXX Use logging API
                if (DEBUG) {
                    System.out.println("AcceptSecContext: state = " + state);
                }
            }
            if (DEBUG) {
                    System.out.println("SpNegoContext.acceptSecContext: " +
                        "sending token = " + SpNegoToken.getHexBytes(retVal));
            }
        } catch (IOException e) {
            GSSException gssException =
                new GSSException(GSSException.FAILURE, -1, e.getMessage());
            gssException.initCause(e);
            throw gssException;
        }

        return retVal;
    }

    /**
     * obtain the available mechanisms
     */
    private Oid[] getAvailableMechs() {
        if (myCred != null) {
            Oid[] mechs = new Oid[1];
            mechs[0] = myCred.getInternalMech();
            return mechs;
        } else {
            return factory.availableMechs;
        }
    }

    /**
     * get ther DER encoded MechList
     */
    private byte[] getEncodedMechs(Oid[] mechSet)
        throws IOException, GSSException {

        DerOutputStream mech = new DerOutputStream();
        for (int i = 0; i < mechSet.length; i++) {
            byte[] mechType = mechSet[i].getDER();
            mech.write(mechType);
        }
        // insert in SEQUENCE
        DerOutputStream mechTypeList = new DerOutputStream();
        mechTypeList.write(DerValue.tag_Sequence, mech);
        byte[] encoded = mechTypeList.toByteArray();
        return encoded;
    }

    /**
     * get the context flags
     */
    private byte[] getContextFlags() {
        int flags = 0;

        if (getCredDelegState())
            flags |= CHECKSUM_DELEG_FLAG;
        if (getMutualAuthState())
            flags |= CHECKSUM_MUTUAL_FLAG;
        if (getReplayDetState())
            flags |= CHECKSUM_REPLAY_FLAG;
        if (getSequenceDetState())
            flags |= CHECKSUM_SEQUENCE_FLAG;
        if (getIntegState())
            flags |= CHECKSUM_INTEG_FLAG;
        if (getConfState())
            flags |= CHECKSUM_CONF_FLAG;

        byte[] temp = new byte[1];
        temp[0] = (byte)(flags & 0xff);
        return temp;
    }

    private void setContextFlags() {

        if (mechContext != null) {
            // default for cred delegation is false
            if (mechContext.getCredDelegState()) {
                setCredDelegState(true);
            }
            // default for the following are true
            if (!mechContext.getMutualAuthState()) {
                setMutualAuthState(false);
            }
            if (!mechContext.getReplayDetState()) {
                setReplayDetState(false);
            }
            if (!mechContext.getSequenceDetState()) {
                setSequenceDetState(false);
            }
            if (!mechContext.getIntegState()) {
                setIntegState(false);
            }
            if (!mechContext.getConfState()) {
                setConfState(false);
            }
        }
    }

    /**
     * generate MIC on mechList
     */
    private byte[] generateMechListMIC(byte[] mechTypes)
        throws GSSException {

        // sanity check the required input
        if (mechTypes == null) {
            if (DEBUG) {
                System.out.println("SpNegoContext: no MIC token included");
            }
            return null;
        }

        // check if mechansim supports integrity
        if (!mechContext.getIntegState()) {
            if (DEBUG) {
                System.out.println("SpNegoContext: no MIC token included" +
                        " - mechanism does not support integrity");
            }
            return null;
        }

        // compute MIC on DER encoded mechanism list
        byte[] mic = null;
        try {
            MessageProp prop = new MessageProp(0, true);
            mic = getMIC(mechTypes, 0, mechTypes.length, prop);
            if (DEBUG) {
                System.out.println("SpNegoContext: getMIC = " +
                                        SpNegoToken.getHexBytes(mic));
            }
        } catch (GSSException e) {
            mic = null;
            if (DEBUG) {
                System.out.println("SpNegoContext: no MIC token included" +
                        " - getMIC failed : " + e.getMessage());
            }
        }
        return mic;
    }

    /**
     * verify MIC on MechList
     */
    private boolean verifyMechListMIC(byte[] mechTypes, byte[] token)
        throws GSSException {

        // sanity check the input
        if (token == null) {
            if (DEBUG) {
                System.out.println("SpNegoContext: no MIC token validation");
            }
            return true;
        }

        // check if mechansim supports integrity
        if (!mechContext.getIntegState()) {
            if (DEBUG) {
                System.out.println("SpNegoContext: no MIC token validation" +
                        " - mechanism does not support integrity");
            }
            return true;
        }

        // now verify the token
        boolean valid = false;
        try {
            MessageProp prop = new MessageProp(0, true);
            verifyMIC(token, 0, token.length, mechTypes,
                        0, mechTypes.length, prop);
            valid = true;
        } catch (GSSException e) {
            valid = false;
            if (DEBUG) {
                System.out.println("SpNegoContext: MIC validation failed! " +
                                        e.getMessage());
            }
        }
        return valid;
    }

    /**
     * call gss_init_sec_context for the corresponding underlying mechanism
     */
    private byte[] GSS_initSecContext(byte[] token) throws GSSException {
        byte[] tok = null;

        if (mechContext == null) {
            // initialize mech context
            GSSName serverName =
                factory.manager.createName(peerName.toString(),
                    peerName.getStringNameType(), internal_mech);
            GSSCredential cred = null;
            if (myCred != null) {
                // create context with provided credential
                cred = new GSSCredentialImpl(factory.manager,
                    myCred.getInternalCred());
            }
            mechContext =
                factory.manager.createContext(serverName,
                    internal_mech, cred, GSSContext.DEFAULT_LIFETIME);
            mechContext.requestConf(confState);
            mechContext.requestInteg(integState);
            mechContext.requestCredDeleg(credDelegState);
            mechContext.requestMutualAuth(mutualAuthState);
            mechContext.requestReplayDet(replayDetState);
            mechContext.requestSequenceDet(sequenceDetState);
        }

        // pass token
        if (token != null) {
            tok = token;
        } else {
            tok = new byte[0];
        }

        // pass token to mechanism initSecContext
        byte[] init_token = mechContext.initSecContext(tok, 0, tok.length);

        return init_token;
    }

    /**
     * call gss_accept_sec_context for the corresponding underlying mechanism
     */
    private byte[] GSS_acceptSecContext(byte[] token) throws GSSException {

        if (mechContext == null) {
            // initialize mech context
            GSSCredential cred = null;
            if (myCred != null) {
                // create context with provided credential
                cred = new GSSCredentialImpl(factory.manager,
                myCred.getInternalCred());
            }
            mechContext =
                factory.manager.createContext(cred);
        }

        // pass token to mechanism acceptSecContext
        byte[] accept_token =
                mechContext.acceptSecContext(token, 0, token.length);

        return accept_token;
    }

    /**
     * This routine compares the recieved mechset to the mechset that
     * this server can support. It looks sequentially through the mechset
     * and the first one that matches what the server can support is
     * chosen as the negotiated mechanism. If one is found, negResult
     * is set to ACCEPT_COMPLETE, otherwise we return NULL and negResult
     * is set to REJECT.
     */
    private static Oid negotiate_mech_type(Oid[] supported_mechSet,
                                        Oid[] mechSet) {
        for (int i = 0; i < supported_mechSet.length; i++) {
            for (int j = 0; j < mechSet.length; j++) {
                if (mechSet[j].equals(supported_mechSet[i])) {
                    if (DEBUG) {
                        System.out.println("SpNegoContext: " +
                                "negotiated mechanism = " + mechSet[j]);
                    }
                    return (mechSet[j]);
                }
            }
        }
        return null;
    }

    public final boolean isEstablished() {
        return (state == STATE_DONE);
    }

    public final boolean isMechContextEstablished() {
        if (mechContext != null) {
            return mechContext.isEstablished();
        } else {
            if (DEBUG) {
                System.out.println("The underlying mechansim context has " +
                                        "not been initialized");
            }
            return false;
        }
    }

    public final byte [] export() throws GSSException {
        throw new GSSException(GSSException.UNAVAILABLE, -1,
                               "GSS Export Context not available");
    }

    /**
     * Sets the channel bindings to be used during context
     * establishment.
     */
    public final void setChannelBinding(ChannelBinding channelBinding)
        throws GSSException {
        this.channelBinding = channelBinding;
    }

    final ChannelBinding getChannelBinding() {
        return channelBinding;
    }

    /*
     * Anonymity is a little different in that after an application
     * requests anonymity it will want to know whether the mechanism
     * can support it or not, prior to sending any tokens across for
     * context establishment. Since this is from the initiator's
     * perspective, it essentially requests that the initiator be
     * anonymous.
     */
    public final void requestAnonymity(boolean value) throws GSSException {
        // Ignore silently. Application will check back with
        // getAnonymityState.
    }

    // RFC 2853 actually calls for this to be called after context
    // establishment to get the right answer, but that is
    // incorrect. The application may not want to send over any
    // tokens if anonymity is not available.
    public final boolean getAnonymityState() {
        return false;
    }

    /**
     * Requests the desired lifetime. Can only be used on the context
     * initiator's side.
     */
    public void requestLifetime(int lifetime) throws GSSException {
        if (state == STATE_NEW && isInitiator())
            this.lifetime = lifetime;
    }

    /**
     * The lifetime remaining for this context.
     */
    public final int getLifetime() {
        if (mechContext != null) {
            return mechContext.getLifetime();
        } else {
            return GSSContext.INDEFINITE_LIFETIME;
        }
    }

    public final boolean isTransferable() throws GSSException {
        return false;
    }

    /**
     * Requests that sequence checking be done on the GSS wrap and MIC
     * tokens.
     */
    public final void requestSequenceDet(boolean value) throws GSSException {
        if (state == STATE_NEW && isInitiator())
            sequenceDetState  = value;
    }

    /**
     * Is sequence checking enabled on the GSS Wrap and MIC tokens?
     * We enable sequence checking if replay detection is enabled.
     */
    public final boolean getSequenceDetState() {
        return sequenceDetState || replayDetState;
    }

    /**
     * Requests that replay detection be done on the GSS wrap and MIC
     * tokens.
     */
    public final void requestReplayDet(boolean value) throws GSSException {
        if (state == STATE_NEW && isInitiator())
            replayDetState  = value;
    }

    /**
     * Is replay detection enabled on the GSS wrap and MIC tokens?
     * We enable replay detection if sequence checking is enabled.
     */
    public final boolean getReplayDetState() {
        return replayDetState || sequenceDetState;
    }

    public final GSSNameSpi getTargName() throws GSSException {
        // fill-in the GSSName
        // get the peer name for the mechanism
        if (mechContext != null) {
            GSSNameImpl targName = (GSSNameImpl)mechContext.getTargName();
            peerName = (GSSNameSpi) targName.getElement(internal_mech);
            return peerName;
        } else {
            if (DEBUG) {
                System.out.println("The underlying mechansim context has " +
                                        "not been initialized");
            }
            return null;
        }
    }

    public final GSSNameSpi getSrcName() throws GSSException {
        // fill-in the GSSName
        // get the src name for the mechanism
        if (mechContext != null) {
            GSSNameImpl srcName = (GSSNameImpl)mechContext.getSrcName();
            myName = (GSSNameSpi) srcName.getElement(internal_mech);
            return myName;
        } else {
            if (DEBUG) {
                System.out.println("The underlying mechansim context has " +
                                        "not been initialized");
            }
            return null;
        }
    }

    /**
     * Returns the delegated credential for the context. This
     * is an optional feature of contexts which not all
     * mechanisms will support. A context can be requested to
     * support credential delegation by using the <b>CRED_DELEG</b>.
     * This is only valid on the acceptor side of the context.
     * @return GSSCredentialSpi object for the delegated credential
     * @exception GSSException
     * @see GSSContext#getDelegCredState
     */
    public final GSSCredentialSpi getDelegCred() throws GSSException {
        if (state != STATE_IN_PROCESS && state != STATE_DONE)
            throw new GSSException(GSSException.NO_CONTEXT);
        if (mechContext != null) {
            GSSCredentialImpl delegCred =
                        (GSSCredentialImpl)mechContext.getDelegCred();
            // determine delegated cred element usage
            boolean initiate = false;
            if (delegCred.getUsage() == GSSCredential.INITIATE_ONLY) {
                initiate = true;
            }
            GSSCredentialSpi mechCred = (GSSCredentialSpi)
                                delegCred.getElement(internal_mech, initiate);
            SpNegoCredElement cred = new SpNegoCredElement(mechCred);
            return cred.getInternalCred();
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "getDelegCred called in invalid state!");
        }
    }

    public final int getWrapSizeLimit(int qop, boolean confReq,
                                       int maxTokSize) throws GSSException {
        if (mechContext != null) {
            return mechContext.getWrapSizeLimit(qop, confReq, maxTokSize);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "getWrapSizeLimit called in invalid state!");
        }
    }

    public final byte[] wrap(byte inBuf[], int offset, int len,
                             MessageProp msgProp) throws GSSException {
        if (mechContext != null) {
            return mechContext.wrap(inBuf, offset, len, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "Wrap called in invalid state!");
        }
    }

    public final void wrap(InputStream is, OutputStream os,
                            MessageProp msgProp) throws GSSException {
        if (mechContext != null) {
            mechContext.wrap(is, os, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "Wrap called in invalid state!");
        }
    }

    public final byte[] unwrap(byte inBuf[], int offset, int len,
                               MessageProp msgProp)
        throws GSSException {
        if (mechContext != null) {
            return mechContext.unwrap(inBuf, offset, len, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "UnWrap called in invalid state!");
        }
    }

    public final void unwrap(InputStream is, OutputStream os,
                             MessageProp msgProp) throws GSSException {
        if (mechContext != null) {
            mechContext.unwrap(is, os, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "UnWrap called in invalid state!");
        }
    }

    public final byte[] getMIC(byte []inMsg, int offset, int len,
                               MessageProp msgProp)
        throws GSSException {
        if (mechContext != null) {
            return mechContext.getMIC(inMsg, offset, len, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "getMIC called in invalid state!");
        }
    }

    public final void getMIC(InputStream is, OutputStream os,
                              MessageProp msgProp) throws GSSException {
        if (mechContext != null) {
            mechContext.getMIC(is, os, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "getMIC called in invalid state!");
        }
    }

    public final void verifyMIC(byte []inTok, int tokOffset, int tokLen,
                                byte[] inMsg, int msgOffset, int msgLen,
                                MessageProp msgProp)
        throws GSSException {
        if (mechContext != null) {
            mechContext.verifyMIC(inTok, tokOffset, tokLen, inMsg, msgOffset,
                                msgLen,  msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "verifyMIC called in invalid state!");
        }
    }

    public final void verifyMIC(InputStream is, InputStream msgStr,
                                 MessageProp msgProp) throws GSSException {
        if (mechContext != null) {
            mechContext.verifyMIC(is, msgStr, msgProp);
        } else {
            throw new GSSException(GSSException.NO_CONTEXT, -1,
                                "verifyMIC called in invalid state!");
        }
    }

    private static String printState(int state) {
        switch (state) {
          case STATE_NEW:
                return ("STATE_NEW");
          case STATE_IN_PROCESS:
                return ("STATE_IN_PROCESS");
          case STATE_DONE:
                return ("STATE_DONE");
          case STATE_DELETED:
                return ("STATE_DELETED");
          default:
                return ("Unknown state " + state);
        }
    }
}
