/*
 * Copyright (c) 2000, 2010, 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 java.util.Set;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Arrays;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import sun.security.util.ObjectIdentifier;
import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;

/**
 * This is the implementation class for GSSName. Conceptually the
 * GSSName is a container with mechanism specific name elements. Each
 * name element is a representation of how that particular mechanism
 * would canonicalize this principal.
 *
 * Generally a GSSName is created by an application when it supplies
 * a sequence of bytes and a nametype that helps each mechanism
 * decide how to interpret those bytes.
 *
 * It is not necessary to create name elements for each available
 * mechanism at the time the application creates the GSSName. This
 * implementation does this lazily, as and when name elements for
 * mechanisms are required to be handed out. (Generally, other GSS
 * classes like GSSContext and GSSCredential request specific
 * elements depending on the mechanisms that they are dealing with.)
 * Assume that getting a mechanism to parse the applciation specified
 * bytes is an expensive call.
 *
 * When a GSSName is canonicalized wrt some mechanism, it is supposed
 * to discard all elements of other mechanisms and retain only the
 * element for this mechanism. In GSS terminology this is called a
 * Mechanism Name or MN. This implementation tries to retain the
 * application provided bytes and name type just in case the MN is
 * asked to produce an element for a mechanism that is different.
 *
 * When a GSSName is to be exported, the name element for the desired
 * mechanism is converted to a byte representation and written
 * out. It might happen that a name element for that mechanism cannot
 * be obtained. This happens when the mechanism is just not supported
 * in this GSS-API or when the mechanism is supported but bytes
 * corresponding to the nametypes that it understands are not
 * available in this GSSName.
 *
 * This class is safe for sharing. Each retrieval of a name element
 * from getElement() might potentially add a new element to the
 * hashmap of elements, but getElement() is synchronized.
 *
 * @author Mayank Upadhyay
 * @since 1.4
 */

public class GSSNameImpl implements GSSName {

    /**
     * The old Oid used in RFC 2853. Now supported as
     * input parameters in:
     *
     * 1. The four overloaded GSSManager.createName(*) methods
     * 2. GSSManager.getMechsForName(Oid)
     *
     * Note that even if a GSSName is created with this old Oid,
     * its internal name type and getStringNameType() output are
     * always the new value.
     */
    final static Oid oldHostbasedServiceName;

    static {
        Oid tmp = null;
        try {
            tmp = new Oid("1.3.6.1.5.6.2");
        } catch (Exception e) {
            // should never happen
        }
        oldHostbasedServiceName = tmp;
    }

    private GSSManagerImpl gssManager = null;

    /*
     * Store whatever the application passed in. We will use this to
     * get individual mechanisms to create name elements as and when
     * needed.
     * Store both the String and the byte[]. Leave I18N to the
     * mechanism by allowing it to extract bytes from the String!
     */

    private String appNameStr = null;
    private byte[] appNameBytes = null;
    private Oid appNameType = null;

    /*
     * When we figure out what the printable name would be, we store
     * both the name and its type.
     */

    private String printableName = null;
    private Oid printableNameType = null;

    private HashMap<Oid, GSSNameSpi> elements = null;
    private GSSNameSpi mechElement = null;

    static GSSNameImpl wrapElement(GSSManagerImpl gssManager,
        GSSNameSpi mechElement) throws GSSException {
        return (mechElement == null ?
            null : new GSSNameImpl(gssManager, mechElement));
    }

    GSSNameImpl(GSSManagerImpl gssManager, GSSNameSpi mechElement) {
        this.gssManager = gssManager;
        appNameStr = printableName = mechElement.toString();
        appNameType = printableNameType = mechElement.getStringNameType();
        this.mechElement = mechElement;
        elements = new HashMap<Oid, GSSNameSpi>(1);
        elements.put(mechElement.getMechanism(), this.mechElement);
    }

    GSSNameImpl(GSSManagerImpl gssManager,
                       Object appName,
                       Oid appNameType)
        throws GSSException {
        this(gssManager, appName, appNameType, null);
    }

    GSSNameImpl(GSSManagerImpl gssManager,
                        Object appName,
                        Oid appNameType,
                        Oid mech)
        throws GSSException {

        if (oldHostbasedServiceName.equals(appNameType)) {
            appNameType = GSSName.NT_HOSTBASED_SERVICE;
        }
        if (appName == null)
            throw new GSSExceptionImpl(GSSException.BAD_NAME,
                                   "Cannot import null name");
        if (mech == null) mech = ProviderList.DEFAULT_MECH_OID;
        if (NT_EXPORT_NAME.equals(appNameType)) {
            importName(gssManager, appName);
        } else {
            init(gssManager, appName, appNameType, mech);
        }
    }

    private void init(GSSManagerImpl gssManager,
                      Object appName, Oid appNameType,
                      Oid mech)
        throws GSSException {

        this.gssManager = gssManager;
        this.elements =
                new HashMap<Oid, GSSNameSpi>(gssManager.getMechs().length);

        if (appName instanceof String) {
            this.appNameStr = (String) appName;
            /*
             * If appNameType is null, then the nametype for this printable
             * string is determined only by interrogating the
             * mechanism. Thus, defer the setting of printableName and
             * printableNameType till later.
             */
            if (appNameType != null) {
                printableName = appNameStr;
                printableNameType = appNameType;
            }
        } else {
            this.appNameBytes = (byte[]) appName;
        }

        this.appNameType = appNameType;

        mechElement = getElement(mech);

        /*
         * printableName will be null if appName was in a byte[] or if
         * appName was in a String but appNameType was null.
         */
        if (printableName == null) {
            printableName = mechElement.toString();
            printableNameType = mechElement.getStringNameType();
        }

        /*
         *  At this point the GSSNameImpl has the following set:
         *   appNameStr or appNameBytes
         *   appNameType (could be null)
         *   printableName
         *   printableNameType
         *   mechElement (which also exists in the hashmap of elements)
         */
    }

    private void importName(GSSManagerImpl gssManager,
                            Object appName)
        throws GSSException {

        int pos = 0;
        byte[] bytes = null;

        if (appName instanceof String) {
            try {
                bytes = ((String) appName).getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                // Won't happen
            }
        } else
            bytes = (byte[]) appName;

        if ((bytes[pos++] != 0x04) ||
            (bytes[pos++] != 0x01))
            throw new GSSExceptionImpl(GSSException.BAD_NAME,
                                   "Exported name token id is corrupted!");

        int oidLen  = (((0xFF & bytes[pos++]) << 8) |
                       (0xFF & bytes[pos++]));
        ObjectIdentifier temp = null;
        try {
            DerInputStream din = new DerInputStream(bytes, pos,
                                                    oidLen);
            temp = new ObjectIdentifier(din);
        } catch (IOException e) {
            throw new GSSExceptionImpl(GSSException.BAD_NAME,
                       "Exported name Object identifier is corrupted!");
        }
        Oid oid = new Oid(temp.toString());
        pos += oidLen;
        int mechPortionLen = (((0xFF & bytes[pos++]) << 24) |
                              ((0xFF & bytes[pos++]) << 16) |
                              ((0xFF & bytes[pos++]) << 8) |
                              (0xFF & bytes[pos++]));
        if (mechPortionLen < 0 || pos > bytes.length - mechPortionLen) {
             throw new GSSExceptionImpl(GSSException.BAD_NAME,
                     "Exported name mech name is corrupted!");
         }
        byte[] mechPortion = new byte[mechPortionLen];
        System.arraycopy(bytes, pos, mechPortion, 0, mechPortionLen);

        init(gssManager, mechPortion, NT_EXPORT_NAME, oid);
    }

    public GSSName canonicalize(Oid mech) throws GSSException {
        if (mech == null) mech = ProviderList.DEFAULT_MECH_OID;

        return wrapElement(gssManager, getElement(mech));
    }

    /**
     * This method may return false negatives. But if it says two
     * names are equals, then there is some mechanism that
     * authenticates them as the same principal.
     */
    public boolean equals(GSSName other) throws GSSException {

        if (this.isAnonymous() || other.isAnonymous())
            return false;

        if (other == this)
            return true;

        if (! (other instanceof GSSNameImpl))
            return equals(gssManager.createName(other.toString(),
                                                other.getStringNameType()));

        /*
         * XXX Do a comparison of the appNameStr/appNameBytes if
         * available. If that fails, then proceed with this test.
         */

        GSSNameImpl that = (GSSNameImpl) other;

        GSSNameSpi myElement = this.mechElement;
        GSSNameSpi element = that.mechElement;

        /*
         * XXX If they are not of the same mechanism type, convert both to
         * Kerberos since it is guaranteed to be present.
         */
        if ((myElement == null) && (element != null)) {
            myElement = this.getElement(element.getMechanism());
        } else if ((myElement != null) && (element == null)) {
            element = that.getElement(myElement.getMechanism());
        }

        if (myElement != null && element != null) {
            return myElement.equals(element);
        }

        if ((this.appNameType != null) &&
            (that.appNameType != null)) {
            if (!this.appNameType.equals(that.appNameType)) {
                return false;
            }
            byte[] myBytes = null;
            byte[] bytes = null;
            try {
                myBytes =
                    (this.appNameStr != null ?
                     this.appNameStr.getBytes("UTF-8") :
                     this.appNameBytes);
                bytes =
                    (that.appNameStr != null ?
                     that.appNameStr.getBytes("UTF-8") :
                     that.appNameBytes);
            } catch (UnsupportedEncodingException e) {
                // Won't happen
            }

            return Arrays.equals(myBytes, bytes);
        }

        return false;

    }

    /**
     * Returns a hashcode value for this GSSName.
     *
     * @return a hashCode value
     */
    public int hashCode() {
        /*
         * XXX
         * In order to get this to work reliably and properly(!), obtain a
         * Kerberos name element for the name and then call hashCode on its
         * string representation. But this cannot be done if the nametype
         * is not one of those supported by the Kerberos provider and hence
         * this name cannot be imported by Kerberos. In that case return a
         * constant value!
         */

        return 1;
    }

    public boolean equals(Object another) {

        try {
            // XXX This can lead to an infinite loop. Extract info
            // and create a GSSNameImpl with it.

            if (another instanceof GSSName)
                return equals((GSSName) another);
        } catch (GSSException e) {
            // Squelch it and return false
        }

            return false;
    }

    /**
     * Returns a flat name representation for this object. The name
     * format is defined in RFC 2743:
     *<pre>
     * Length           Name          Description
     * 2               TOK_ID          Token Identifier
     *                                 For exported name objects, this
     *                                 must be hex 04 01.
     * 2               MECH_OID_LEN    Length of the Mechanism OID
     * MECH_OID_LEN    MECH_OID        Mechanism OID, in DER
     * 4               NAME_LEN        Length of name
     * NAME_LEN        NAME            Exported name; format defined in
     *                                 applicable mechanism draft.
     *</pre>
     *
     * Note that it is not required to canonicalize a name before
     * calling export(). i.e., the name need not be an MN. If it is
     * not an MN, an implementation defined algorithm can be used for
     * choosing the mechanism which should export this name.
     *
     * @return the flat name representation for this object
     * @exception GSSException with major codes NAME_NOT_MN, BAD_NAME,
     *  BAD_NAME, FAILURE.
     */
    public byte[] export() throws GSSException {

        if (mechElement == null) {
            /* Use default mech */
            mechElement = getElement(ProviderList.DEFAULT_MECH_OID);
        }

        byte[] mechPortion = mechElement.export();
        byte[] oidBytes = null;
        ObjectIdentifier oid = null;

        try {
            oid = new ObjectIdentifier
                (mechElement.getMechanism().toString());
        } catch (IOException e) {
            throw new GSSExceptionImpl(GSSException.FAILURE,
                                       "Invalid OID String ");
        }
        DerOutputStream dout = new DerOutputStream();
        try {
            dout.putOID(oid);
        } catch (IOException e) {
            throw new GSSExceptionImpl(GSSException.FAILURE,
                                   "Could not ASN.1 Encode "
                                   + oid.toString());
        }
        oidBytes = dout.toByteArray();

        byte[] retVal = new byte[2
                                + 2 + oidBytes.length
                                + 4 + mechPortion.length];
        int pos = 0;
        retVal[pos++] = 0x04;
        retVal[pos++] = 0x01;
        retVal[pos++] = (byte) (oidBytes.length>>>8);
        retVal[pos++] = (byte) oidBytes.length;
        System.arraycopy(oidBytes, 0, retVal, pos, oidBytes.length);
        pos += oidBytes.length;
        retVal[pos++] = (byte) (mechPortion.length>>>24);
        retVal[pos++] = (byte) (mechPortion.length>>>16);
        retVal[pos++] = (byte) (mechPortion.length>>>8);
        retVal[pos++] = (byte)  mechPortion.length;
        System.arraycopy(mechPortion, 0, retVal, pos, mechPortion.length);
        return retVal;
    }

    public String toString() {
         return printableName;

    }

    public Oid getStringNameType() throws GSSException {
        return printableNameType;
    }

    public boolean isAnonymous() {
        if (printableNameType == null) {
            return false;
        } else {
            return GSSName.NT_ANONYMOUS.equals(printableNameType);
        }
    }

    public boolean isMN() {
        return true; // Since always canonicalized for some mech
    }

    public synchronized GSSNameSpi getElement(Oid mechOid)
        throws GSSException {

        GSSNameSpi retVal = elements.get(mechOid);

        if (retVal == null) {
            if (appNameStr != null) {
                retVal = gssManager.getNameElement
                    (appNameStr, appNameType, mechOid);
            } else {
                retVal = gssManager.getNameElement
                    (appNameBytes, appNameType, mechOid);
            }
            elements.put(mechOid, retVal);
        }
        return retVal;
    }

    Set<GSSNameSpi> getElements() {
        return new HashSet<GSSNameSpi>(elements.values());
    }

    private static String getNameTypeStr(Oid nameTypeOid) {

        if (nameTypeOid == null)
            return "(NT is null)";

        if (nameTypeOid.equals(NT_USER_NAME))
            return "NT_USER_NAME";
        if (nameTypeOid.equals(NT_HOSTBASED_SERVICE))
            return "NT_HOSTBASED_SERVICE";
        if (nameTypeOid.equals(NT_EXPORT_NAME))
            return "NT_EXPORT_NAME";
        if (nameTypeOid.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL))
            return "NT_GSS_KRB5_PRINCIPAL";
        else
            return "Unknown";
    }
}
