/*
 * Copyright (c) 2000, 2006, 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.GSSException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import sun.security.util.*;

/**
 * This class represents the mechanism independent part of a GSS-API
 * context establishment token. Some mechanisms may choose to encode
 * all subsequent tokens as well such that they start with an encoding
 * of an instance of this class. e.g., The Kerberos v5 GSS-API Mechanism
 * uses this header for all GSS-API tokens.
 * <p>
 * The format is specified in RFC 2743 section 3.1.
 *
 * @author Mayank Upadhyay
 */

/*
 * The RFC states that implementations should explicitly follow the
 * encoding scheme descibed in this section rather than use ASN.1
 * compilers. However, we should consider removing duplicate ASN.1
 * like code from here and depend on sun.security.util if possible.
 */

public class GSSHeader {

    private ObjectIdentifier mechOid = null;
    private byte[] mechOidBytes = null;
    private int mechTokenLength = 0;

    /**
     * The tag defined in the GSS-API mechanism independent token
     * format.
     */
    public static final int TOKEN_ID=0x60;

    /**
     * Creates a GSSHeader instance whose encoding can be used as the
     * prefix for a particular mechanism token.
     * @param mechOid the Oid of the mechanism which generated the token
     * @param mechTokenLength the length of the subsequent portion that
     * the mechanism will be adding.
     */
    public GSSHeader(ObjectIdentifier mechOid, int mechTokenLength)
        throws IOException {

        this.mechOid = mechOid;
        DerOutputStream temp = new DerOutputStream();
        temp.putOID(mechOid);
        mechOidBytes = temp.toByteArray();
        this.mechTokenLength = mechTokenLength;
    }

    /**
     * Reads in a GSSHeader from an InputStream. Typically this would be
     * used as part of reading the complete token from an InputStream
     * that is obtained from a socket.
     */
    public GSSHeader(InputStream is)
        throws IOException, GSSException {

        //      debug("Parsing GSS token: ");

        int tag = is.read();

        //      debug("tag=" + tag);

        if (tag != TOKEN_ID)
            throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
                                   "GSSHeader did not find the right tag");

        int length = getLength(is);

        DerValue temp = new DerValue(is);
        mechOidBytes = temp.toByteArray();
        mechOid = temp.getOID();
        //      debug (" oid=" + mechOid);

        //      debug (" len starting with oid=" + length);
        mechTokenLength = length - mechOidBytes.length;

        //      debug("  mechToken length=" + mechTokenLength);

    }

    /**
     * Used to obtain the Oid stored in this GSSHeader instance.
     * @return the Oid of the mechanism.
     */
    public ObjectIdentifier getOid() {
        return mechOid;
    }

    /**
     * Used to obtain the length of the mechanism specific token that
     * will follow the encoding of this GSSHeader instance.
     * @return the length of the mechanism specific token portion that
     * will follow this GSSHeader.
     */
    public int getMechTokenLength() {
        return mechTokenLength;
    }

    /**
     * Used to obtain the length of the encoding of this GSSHeader.
     * @return the lenght of the encoding of this GSSHeader instance.
     */
    public int getLength() {
        int lenField = mechOidBytes.length + mechTokenLength;
        return (1 + getLenFieldSize(lenField) + mechOidBytes.length);
    }

    /**
     * Used to determine what the maximum possible mechanism token
     * size is if the complete GSSToken returned to the application
     * (including a GSSHeader) is not to exceed some pre-determined
     * value in size.
     * @param mechOid the Oid of the mechanism that will generate
     * this GSS-API token
     * @param maxTotalSize the pre-determined value that serves as a
     * maximum size for the complete GSS-API token (including a
     * GSSHeader)
     * @return the maximum size of mechanism token that can be used
     * so as to not exceed maxTotalSize with the GSS-API token
     */
    public static int getMaxMechTokenSize(ObjectIdentifier mechOid,
                                          int maxTotalSize) {

        int mechOidBytesSize = 0;
        try {
            DerOutputStream temp = new DerOutputStream();
            temp.putOID(mechOid);
            mechOidBytesSize = temp.toByteArray().length;
        } catch (IOException e) {
        }

        // Subtract bytes needed for 0x60 tag and mechOidBytes
        maxTotalSize -= (1 + mechOidBytesSize);

        // Subtract maximum len bytes
        maxTotalSize -= 5;

        return maxTotalSize;

        /*
         * Len field and mechanism token must fit in remaining
         * space. The range of the len field that we allow is
         * 1 through 5.
         *

         int mechTokenSize = 0;
         for (int lenFieldSize = 1; lenFieldSize <= 5;
         lenFieldSize++) {
         mechTokenSize = maxTotalSize - lenFieldSize;
         if (getLenFieldSize(mechTokenSize + mechOidBytesSize +
         lenFieldSize) <= lenFieldSize)
         break;
         }

         return mechTokenSize;
        */


    }

    /**
     * Used to determine the number of bytes that will be need to encode
     * the length field of the GSSHeader.
     */
    private int getLenFieldSize(int len) {
        int retVal = 1;
        if (len < 128) {
            retVal=1;
        } else if (len < (1 << 8)) {
            retVal=2;
        } else if (len < (1 << 16)) {
            retVal=3;
        } else if (len < (1 << 24)) {
            retVal=4;
        } else {
            retVal=5; // See getMaxMechTokenSize
        }
        return retVal;
    }

    /**
     * Encodes this GSSHeader instance onto the provided OutputStream.
     * @param os the OutputStream to which the token should be written.
     * @return the number of bytes that are output as a result of this
     * encoding
     */
    public int encode(OutputStream os) throws IOException {
        int retVal = 1 + mechOidBytes.length;
        os.write(TOKEN_ID);
        int length = mechOidBytes.length + mechTokenLength;
        retVal += putLength(length, os);
        os.write(mechOidBytes);
        return retVal;
    }

    /**
     * Get a length from the input stream, allowing for at most 32 bits of
     * encoding to be used. (Not the same as getting a tagged integer!)
     *
     * @return the length or -1 if indefinite length found.
     * @exception IOException on parsing error or unsupported lengths.
     */
    // shameless lifted from sun.security.util.DerInputStream.
    private int getLength(InputStream in) throws IOException {
        return getLength(in.read(), in);
    }

    /**
     * Get a length from the input stream, allowing for at most 32 bits of
     * encoding to be used. (Not the same as getting a tagged integer!)
     *
     * @return the length or -1 if indefinite length found.
     * @exception IOException on parsing error or unsupported lengths.
     */
    // shameless lifted from sun.security.util.DerInputStream.
    private int getLength(int lenByte, InputStream in) throws IOException {
        int value, tmp;

        tmp = lenByte;
        if ((tmp & 0x080) == 0x00) { // short form, 1 byte datum
            value = tmp;
        } else {                                         // long form or indefinite
            tmp &= 0x07f;

            /*
             * NOTE:  tmp == 0 indicates indefinite length encoded data.
             * tmp > 4 indicates more than 4Gb of data.
             */
            if (tmp == 0)
                return -1;
            if (tmp < 0 || tmp > 4)
                throw new IOException("DerInputStream.getLength(): lengthTag="
                                      + tmp + ", "
                                      + ((tmp < 0) ? "incorrect DER encoding." : "too big."));

            for (value = 0; tmp > 0; tmp --) {
                value <<= 8;
                value += 0x0ff & in.read();
            }
        }
        return value;
    }

    /**
     * Put the encoding of the length in the specified stream.
     *
     * @params len the length of the attribute.
     * @param out the outputstream to write the length to
     * @return the number of bytes written
     * @exception IOException on writing errors.
     */
    // Shameless lifted from sun.security.util.DerOutputStream.
    private int putLength(int len, OutputStream out) throws IOException {
        int retVal = 0;
        if (len < 128) {
            out.write((byte)len);
            retVal=1;

        } else if (len < (1 << 8)) {
            out.write((byte)0x081);
            out.write((byte)len);
            retVal=2;

        } else if (len < (1 << 16)) {
            out.write((byte)0x082);
            out.write((byte)(len >> 8));
            out.write((byte)len);
            retVal=3;

        } else if (len < (1 << 24)) {
            out.write((byte)0x083);
            out.write((byte)(len >> 16));
            out.write((byte)(len >> 8));
            out.write((byte)len);
            retVal=4;

        } else {
            out.write((byte)0x084);
            out.write((byte)(len >> 24));
            out.write((byte)(len >> 16));
            out.write((byte)(len >> 8));
            out.write((byte)len);
            retVal=5;
        }

        return retVal;
    }

    // XXX Call these two in some central class
    private void debug(String str) {
        System.err.print(str);
    }

    private  String getHexBytes(byte[] bytes, int len)
        throws IOException {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < len; i++) {

            int b1 = (bytes[i]>>4) & 0x0f;
            int b2 = bytes[i] & 0x0f;

            sb.append(Integer.toHexString(b1));
            sb.append(Integer.toHexString(b2));
            sb.append(' ');
        }
        return sb.toString();
    }
}
