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

import org.ietf.jgss.*;
import sun.security.jgss.spi.*;
import sun.security.util.ObjectIdentifier;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.sun.security.jgss.*;

/**
 * This class represents the JGSS security context and its associated
 * operations.  JGSS security contexts are established between
 * peers using locally established credentials.  Multiple contexts
 * may exist simultaneously between a pair of peers, using the same
 * or different set of credentials.  The JGSS is independent of
 * the underlying transport protocols and depends on its callers to
 * transport the tokens between peers.
 * <p>
 * The context object can be thought of as having 3 implicit states:
 * before it is established, during its context establishment, and
 * after a fully established context exists.
 * <p>
 * Before the context establishment phase is initiated, the context
 * initiator may request specific characteristics desired of the
 * established context. These can be set using the set methods. After the
 * context is established, the caller can check the actual characteristic
 * and services offered by the context using the query methods.
 * <p>
 * The context establishment phase begins with the first call to the
 * initSecContext method by the context initiator. During this phase the
 * initSecContext and acceptSecContext methods will produce GSS-API
 * authentication tokens which the calling application needs to send to its
 * peer. The initSecContext and acceptSecContext methods may
 * return a CONTINUE_NEEDED code which indicates that a token is needed
 * from its peer in order to continue the context establishment phase. A
 * return code of COMPLETE signals that the local end of the context is
 * established. This may still require that a token be sent to the peer,
 * depending if one is produced by GSS-API. The isEstablished method can
 * also be used to determine if the local end of the context has been
 * fully established. During the context establishment phase, the
 * isProtReady method may be called to determine if the context can be
 * used for the per-message operations. This allows implementation to
 * use per-message operations on contexts which aren't fully established.
 * <p>
 * After the context has been established or the isProtReady method
 * returns "true", the query routines can be invoked to determine the actual
 * characteristics and services of the established context. The
 * application can also start using the per-message methods of wrap and
 * getMIC to obtain cryptographic operations on application supplied data.
 * <p>
 * When the context is no longer needed, the application should call
 * dispose to release any system resources the context may be using.
 * <DL><DT><B>RFC 2078</b>
 *    <DD>This class corresponds to the context level calls together with
 * the per message calls of RFC 2078. The gss_init_sec_context and
 * gss_accept_sec_context calls have been made simpler by only taking
 * required parameters.  The context can have its properties set before
 * the first call to initSecContext. The supplementary status codes for the
 * per-message operations are returned in an instance of the MessageProp
 * class, which is used as an argument in these calls.</dl>
 */
class GSSContextImpl implements ExtendedGSSContext {

    private final GSSManagerImpl gssManager;
    private final boolean initiator;

    // private flags for the context state
    private static final int PRE_INIT = 1;
    private static final int IN_PROGRESS = 2;
    private static final int READY = 3;
    private static final int DELETED = 4;

    // instance variables
    private int currentState = PRE_INIT;

    private GSSContextSpi mechCtxt = null;
    private Oid mechOid = null;
    private ObjectIdentifier objId = null;

    private GSSCredentialImpl myCred = null;

    private GSSNameImpl srcName = null;
    private GSSNameImpl targName = null;

    private int reqLifetime = INDEFINITE_LIFETIME;
    private ChannelBinding channelBindings = null;

    private boolean reqConfState = true;
    private boolean reqIntegState = true;
    private boolean reqMutualAuthState = true;
    private boolean reqReplayDetState = true;
    private boolean reqSequenceDetState = true;
    private boolean reqCredDelegState = false;
    private boolean reqAnonState = false;
    private boolean reqDelegPolicyState = false;

    /**
     * Creates a GSSContextImp on the context initiator's side.
     */
    public GSSContextImpl(GSSManagerImpl gssManager, GSSName peer, Oid mech,
                          GSSCredential myCred, int lifetime)
        throws GSSException {
        if ((peer == null) || !(peer instanceof GSSNameImpl)) {
            throw new GSSException(GSSException.BAD_NAME);
        }
        if (mech == null) mech = ProviderList.DEFAULT_MECH_OID;

        this.gssManager = gssManager;
        this.myCred = (GSSCredentialImpl) myCred;  // XXX Check first
        reqLifetime = lifetime;
        targName = (GSSNameImpl)peer;
        this.mechOid = mech;
        initiator = true;
    }

    /**
     * Creates a GSSContextImpl on the context acceptor's side.
     */
    public GSSContextImpl(GSSManagerImpl gssManager, GSSCredential myCred)
        throws GSSException {
        this.gssManager = gssManager;
        this.myCred = (GSSCredentialImpl) myCred; // XXX Check first
        initiator = false;
    }

    /**
     * Creates a GSSContextImpl out of a previously exported
     * GSSContext.
     *
     * @see #isTransferable
     */
    public GSSContextImpl(GSSManagerImpl gssManager, byte[] interProcessToken)
        throws GSSException {
        this.gssManager = gssManager;
        mechCtxt = gssManager.getMechanismContext(interProcessToken);
        initiator = mechCtxt.isInitiator();
        this.mechOid = mechCtxt.getMech();
    }

    public byte[] initSecContext(byte inputBuf[], int offset, int len)
        throws GSSException {
        /*
         * Size of ByteArrayOutputStream will double each time that extra
         * bytes are to be written. Usually, without delegation, a GSS
         * initial token containing the Kerberos AP-REQ is between 400 and
         * 600 bytes.
         */
        ByteArrayOutputStream bos = new ByteArrayOutputStream(600);
        ByteArrayInputStream bin =
            new ByteArrayInputStream(inputBuf, offset, len);
        int size = initSecContext(bin, bos);
        return (size == 0? null : bos.toByteArray());
    }

    public int initSecContext(InputStream inStream,
                              OutputStream outStream) throws GSSException {

        if (mechCtxt != null && currentState != IN_PROGRESS) {
            throw new GSSExceptionImpl(GSSException.FAILURE,
                                   "Illegal call to initSecContext");
        }

        GSSHeader gssHeader = null;
        int inTokenLen = -1;
        GSSCredentialSpi credElement = null;
        boolean firstToken = false;

        try {
            if (mechCtxt == null) {
                if (myCred != null) {
                    try {
                        credElement = myCred.getElement(mechOid, true);
                    } catch (GSSException ge) {
                        if (GSSUtil.isSpNegoMech(mechOid) &&
                            ge.getMajor() == GSSException.NO_CRED) {
                            credElement = myCred.getElement
                                (myCred.getMechs()[0], true);
                        } else {
                            throw ge;
                        }
                    }
                }
                GSSNameSpi nameElement = targName.getElement(mechOid);
                mechCtxt = gssManager.getMechanismContext(nameElement,
                                                          credElement,
                                                          reqLifetime,
                                                          mechOid);
                mechCtxt.requestConf(reqConfState);
                mechCtxt.requestInteg(reqIntegState);
                mechCtxt.requestCredDeleg(reqCredDelegState);
                mechCtxt.requestMutualAuth(reqMutualAuthState);
                mechCtxt.requestReplayDet(reqReplayDetState);
                mechCtxt.requestSequenceDet(reqSequenceDetState);
                mechCtxt.requestAnonymity(reqAnonState);
                mechCtxt.setChannelBinding(channelBindings);
                mechCtxt.requestDelegPolicy(reqDelegPolicyState);

                objId = new ObjectIdentifier(mechOid.toString());

                currentState = IN_PROGRESS;
                firstToken = true;
            } else {
                if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
                    GSSUtil.isSpNegoMech(mechOid)) {
                    // do not parse GSS header for native provider or SPNEGO
                    // mech
                } else {
                    // parse GSS header
                    gssHeader = new GSSHeader(inStream);
                    if (!gssHeader.getOid().equals((Object) objId))
                        throw new GSSExceptionImpl
                            (GSSException.DEFECTIVE_TOKEN,
                             "Mechanism not equal to " +
                             mechOid.toString() +
                             " in initSecContext token");
                    inTokenLen = gssHeader.getMechTokenLength();
                }
            }

            byte[] obuf = mechCtxt.initSecContext(inStream, inTokenLen);

            int retVal = 0;

            if (obuf != null) {
                retVal = obuf.length;
                if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
                    (!firstToken && GSSUtil.isSpNegoMech(mechOid))) {
                    // do not add GSS header for native provider or SPNEGO
                    // except for the first SPNEGO token
                } else {
                    // add GSS header
                    gssHeader = new GSSHeader(objId, obuf.length);
                    retVal += gssHeader.encode(outStream);
                }
                outStream.write(obuf);
            }

            if (mechCtxt.isEstablished())
                currentState = READY;

            return retVal;

        } catch (IOException e) {
            throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN,
                                   e.getMessage());
        }
    }

    public byte[] acceptSecContext(byte inTok[], int offset, int len)
        throws GSSException {

        /*
         * Usually initial GSS token containing a Kerberos AP-REP is less
         * than 100 bytes.
         */
        ByteArrayOutputStream bos = new ByteArrayOutputStream(100);
        acceptSecContext(new ByteArrayInputStream(inTok, offset, len),
                         bos);
        byte[] out = bos.toByteArray();
        return (out.length == 0) ? null : out;
    }

    public void acceptSecContext(InputStream inStream,
                                 OutputStream outStream) throws GSSException {

        if (mechCtxt != null && currentState != IN_PROGRESS) {
            throw new GSSExceptionImpl(GSSException.FAILURE,
                                       "Illegal call to acceptSecContext");
        }

        GSSHeader gssHeader = null;
        int inTokenLen = -1;
        GSSCredentialSpi credElement = null;

        try {
            if (mechCtxt == null) {
                // mechOid will be null for an acceptor's context
                gssHeader = new GSSHeader(inStream);
                inTokenLen = gssHeader.getMechTokenLength();

                /*
                 * Convert ObjectIdentifier to Oid
                 */
                objId = gssHeader.getOid();
                mechOid = new Oid(objId.toString());
                // System.out.println("Entered GSSContextImpl.acceptSecContext"
                //                      + " with mechanism = " + mechOid);
                if (myCred != null) {
                    credElement = myCred.getElement(mechOid, false);
                }

                mechCtxt = gssManager.getMechanismContext(credElement,
                                                          mechOid);
                mechCtxt.setChannelBinding(channelBindings);

                currentState = IN_PROGRESS;
            } else {
                if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
                    (GSSUtil.isSpNegoMech(mechOid))) {
                    // do not parse GSS header for native provider and SPNEGO
                } else {
                    // parse GSS Header
                    gssHeader = new GSSHeader(inStream);
                    if (!gssHeader.getOid().equals((Object) objId))
                        throw new GSSExceptionImpl
                            (GSSException.DEFECTIVE_TOKEN,
                             "Mechanism not equal to " +
                             mechOid.toString() +
                             " in acceptSecContext token");
                    inTokenLen = gssHeader.getMechTokenLength();
                }
            }

            byte[] obuf = mechCtxt.acceptSecContext(inStream, inTokenLen);

            if (obuf != null) {
                int retVal = obuf.length;
                if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
                    (GSSUtil.isSpNegoMech(mechOid))) {
                    // do not add GSS header for native provider and SPNEGO
                } else {
                    // add GSS header
                    gssHeader = new GSSHeader(objId, obuf.length);
                    retVal += gssHeader.encode(outStream);
                }
                outStream.write(obuf);
            }

            if (mechCtxt.isEstablished()) {
                currentState = READY;
            }
        } catch (IOException e) {
            throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN,
                                   e.getMessage());
        }
    }

    public boolean isEstablished() {
        if (mechCtxt == null)
            return false;
        else
            return (currentState == READY);
    }

    public int getWrapSizeLimit(int qop, boolean confReq,
                                int maxTokenSize) throws GSSException {
        if (mechCtxt != null)
            return mechCtxt.getWrapSizeLimit(qop, confReq, maxTokenSize);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public byte[] wrap(byte inBuf[], int offset, int len,
                       MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            return mechCtxt.wrap(inBuf, offset, len, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                   "No mechanism context yet!");
    }

    public void wrap(InputStream inStream, OutputStream outStream,
                     MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            mechCtxt.wrap(inStream, outStream, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public byte [] unwrap(byte[] inBuf, int offset, int len,
                          MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            return mechCtxt.unwrap(inBuf, offset, len, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public void unwrap(InputStream inStream, OutputStream outStream,
                       MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            mechCtxt.unwrap(inStream, outStream, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public byte[] getMIC(byte []inMsg, int offset, int len,
                         MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            return mechCtxt.getMIC(inMsg, offset, len, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public void getMIC(InputStream inStream, OutputStream outStream,
                       MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            mechCtxt.getMIC(inStream, outStream, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public void verifyMIC(byte[] inTok, int tokOffset, int tokLen,
                          byte[] inMsg, int msgOffset, int msgLen,
                          MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            mechCtxt.verifyMIC(inTok, tokOffset, tokLen,
                               inMsg, msgOffset, msgLen, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public void verifyMIC(InputStream tokStream, InputStream msgStream,
                          MessageProp msgProp) throws GSSException {
        if (mechCtxt != null)
            mechCtxt.verifyMIC(tokStream, msgStream, msgProp);
        else
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                  "No mechanism context yet!");
    }

    public byte[] export() throws GSSException {
        // Defaults to null to match old behavior
        byte[] result = null;
        // Only allow context export from native provider since JGSS
        // still has not defined its own interprocess token format
        if (mechCtxt.isTransferable() &&
            mechCtxt.getProvider().getName().equals("SunNativeGSS")) {
            result = mechCtxt.export();
        }
        return result;
    }

    public void requestMutualAuth(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqMutualAuthState = state;
    }

    public void requestReplayDet(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqReplayDetState = state;
    }

    public void requestSequenceDet(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqSequenceDetState = state;
    }

    public void requestCredDeleg(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqCredDelegState = state;
    }

    public void requestAnonymity(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqAnonState = state;
    }

    public void requestConf(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqConfState = state;
    }

    public void requestInteg(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqIntegState = state;
    }

    public void requestLifetime(int lifetime) throws GSSException {
        if (mechCtxt == null && initiator)
            reqLifetime = lifetime;
    }

    public void setChannelBinding(ChannelBinding channelBindings)
        throws GSSException {

        if (mechCtxt == null)
            this.channelBindings = channelBindings;

    }

    public boolean getCredDelegState() {
        if (mechCtxt != null)
            return mechCtxt.getCredDelegState();
        else
            return reqCredDelegState;
    }

    public boolean getMutualAuthState() {
        if (mechCtxt != null)
            return mechCtxt.getMutualAuthState();
        else
            return reqMutualAuthState;
    }

    public boolean getReplayDetState() {
        if (mechCtxt != null)
            return mechCtxt.getReplayDetState();
        else
            return reqReplayDetState;
    }

    public boolean getSequenceDetState() {
        if (mechCtxt != null)
            return mechCtxt.getSequenceDetState();
        else
            return reqSequenceDetState;
    }

    public boolean getAnonymityState() {
        if (mechCtxt != null)
            return mechCtxt.getAnonymityState();
        else
            return reqAnonState;
    }

    public boolean isTransferable() throws GSSException {
        if (mechCtxt != null)
            return mechCtxt.isTransferable();
        else
            return false;
    }

    public boolean isProtReady() {
        if (mechCtxt != null)
            return mechCtxt.isProtReady();
        else
            return false;
    }

    public boolean getConfState() {
        if (mechCtxt != null)
            return mechCtxt.getConfState();
        else
            return reqConfState;
    }

    public boolean getIntegState() {
        if (mechCtxt != null)
            return mechCtxt.getIntegState();
        else
            return reqIntegState;
    }

    public int getLifetime() {
        if (mechCtxt != null)
            return mechCtxt.getLifetime();
        else
            return reqLifetime;
    }

    public GSSName getSrcName() throws GSSException {
        if (srcName == null) {
            srcName = GSSNameImpl.wrapElement
                (gssManager, mechCtxt.getSrcName());
        }
        return srcName;
    }

    public GSSName getTargName() throws GSSException {
        if (targName == null) {
            targName = GSSNameImpl.wrapElement
                (gssManager, mechCtxt.getTargName());
        }
        return targName;
    }

    public Oid getMech() throws GSSException {
        if (mechCtxt != null) {
            return mechCtxt.getMech();
        }
        return mechOid;
    }

    public GSSCredential getDelegCred() throws GSSException {

        if (mechCtxt == null)
            throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
                                   "No mechanism context yet!");
        GSSCredentialSpi delCredElement = mechCtxt.getDelegCred();
        return (delCredElement == null ?
            null : new GSSCredentialImpl(gssManager, delCredElement));
    }

    public boolean isInitiator() throws GSSException {
        return initiator;
    }

    public void dispose() throws GSSException {
        currentState = DELETED;
        if (mechCtxt != null) {
            mechCtxt.dispose();
            mechCtxt = null;
        }
        myCred = null;
        srcName = null;
        targName = null;
    }

    // ExtendedGSSContext methods:

    @Override
    public Object inquireSecContext(InquireType type) throws GSSException {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new InquireSecContextPermission(type.toString()));
        }
        if (mechCtxt == null) {
            throw new GSSException(GSSException.NO_CONTEXT);
        }
        return mechCtxt.inquireSecContext(type);
    }

    @Override
    public void requestDelegPolicy(boolean state) throws GSSException {
        if (mechCtxt == null && initiator)
            reqDelegPolicyState = state;
    }

    @Override
    public boolean getDelegPolicyState() {
        if (mechCtxt != null)
            return mechCtxt.getDelegPolicyState();
        else
            return reqDelegPolicyState;
    }
}
