/*
 * Copyright 2005 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.wrapper;

import java.util.Hashtable;
import org.ietf.jgss.Oid;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.ChannelBinding;
import org.ietf.jgss.MessageProp;
import org.ietf.jgss.GSSException;
import sun.security.jgss.GSSUtil;

/**
 * This class is essentially a JNI calling stub for all wrapper classes.
 *
 * @author Valerie Peng
 * @since 1.6
 */

class GSSLibStub {

    private Oid mech;
    private long pMech;

    /**
     * Initialization routine to dynamically load function pointers.
     *
     * @param library name to dlopen
     * @return true if succeeded, false otherwise.
     */
    static native boolean init(String lib);
    private static native long getMechPtr(byte[] oidDerEncoding);

    // Miscellaneous routines
    static native Oid[] indicateMechs();
    native Oid[] inquireNamesForMech() throws GSSException;

    // Name related routines
    native void releaseName(long pName);
    native long importName(byte[] name, Oid type);
    native boolean compareName(long pName1, long pName2);
    native long canonicalizeName(long pName);
    native byte[] exportName(long pName) throws GSSException;
    native Object[] displayName(long pName) throws GSSException;

    // Credential related routines
    native long acquireCred(long pName, int lifetime, int usage)
                                        throws GSSException;
    native long releaseCred(long pCred);
    native long getCredName(long pCred);
    native int getCredTime(long pCred);
    native int getCredUsage(long pCred);

    // Context related routines
    native NativeGSSContext importContext(byte[] interProcToken);
    native byte[] initContext(long pCred, long targetName, ChannelBinding cb,
                              byte[] inToken, NativeGSSContext context);
    native byte[] acceptContext(long pCred, ChannelBinding cb,
                                byte[] inToken, NativeGSSContext context);
    native long[] inquireContext(long pContext);
    native Oid getContextMech(long pContext);
    native long getContextName(long pContext, boolean isSrc);
    native int getContextTime(long pContext);
    native long deleteContext(long pContext);
    native int wrapSizeLimit(long pContext, int flags, int qop, int outSize);
    native byte[] exportContext(long pContext);
    native byte[] getMic(long pContext, int qop, byte[] msg);
    native void verifyMic(long pContext, byte[] token, byte[] msg,
                          MessageProp prop) ;
    native byte[] wrap(long pContext, byte[] msg, MessageProp prop);
    native byte[] unwrap(long pContext, byte[] msgToken, MessageProp prop);

    private static Hashtable<Oid, GSSLibStub>
        table = new Hashtable<Oid, GSSLibStub>(5);

    static GSSLibStub getInstance(Oid mech) throws GSSException {
        GSSLibStub s = table.get(mech);
        if (s == null) {
            s = new GSSLibStub(mech);
            table.put(mech, s);
        }
        return s;
    }
    private GSSLibStub(Oid mech) throws GSSException {
        SunNativeProvider.debug("Created GSSLibStub for mech " + mech);
        this.mech = mech;
        this.pMech = getMechPtr(mech.getDER());
    }
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof GSSLibStub)) {
            return false;
        }
        return (mech.equals(((GSSLibStub) obj).getMech()));
    }
    public int hashCode() {
        return mech.hashCode();
    }
    Oid getMech() {
        return mech;
    }
}
