/*
 * Copyright 2000-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 org.ietf.jgss;

/**
 * This interface encapsulates the GSS-API credentials for an entity.  A
 * credential contains all the necessary cryptographic information to
 * enable the creation of a context on behalf of the entity that it
 * represents.  It may contain multiple, distinct, mechanism specific
 * credential elements, each containing information for a specific
 * security mechanism, but all referring to the same entity. A credential
 * may be used to perform context initiation, acceptance, or both.<p>
 *
 * Credentials are instantiated using one of the
 * <code>createCredential</code> methods in the {@link GSSManager
 * GSSManager} class. GSS-API credential creation is not
 * intended to provide a "login to the network" function, as such a
 * function would involve the creation of new credentials rather than
 * merely acquiring a handle to existing credentials. The
 * <a href=package-summary.html#useSubjectCredsOnly>section on credential
 * acquisition</a> in the package level description describes
 * how existing credentials are acquired in the Java platform. GSS-API
 * implementations must impose a local access-control policy on callers to
 * prevent unauthorized callers from acquiring credentials to which they
 * are not entitled. <p>
 *
 * Applications will create a credential object passing the desired
 * parameters.  The application can then use the query methods to obtain
 * specific information about the instantiated credential object.
 * When the credential is no longer needed, the application should call
 * the {@link #dispose() dispose} method to release any resources held by
 * the credential object and to destroy any cryptographically sensitive
 * information.<p>
 *
 * This example code demonstrates the creation of a GSSCredential
 * implementation for a specific entity, querying of its fields, and its
 * release when it is no longer needed:<p>
 * <pre>
 *    GSSManager manager = GSSManager.getInstance();
 *
 *    // start by creating a name object for the entity
 *    GSSName name = manager.createName("myusername", GSSName.NT_USER_NAME);
 *
 *    // now acquire credentials for the entity
 *    GSSCredential cred = manager.createCredential(name,
 *                    GSSCredential.ACCEPT_ONLY);
 *
 *    // display credential information - name, remaining lifetime,
 *    // and the mechanisms it has been acquired over
 *    System.out.println(cred.getName().toString());
 *    System.out.println(cred.getRemainingLifetime());
 *
 *    Oid [] mechs = cred.getMechs();
 *    if (mechs != null) {
 *            for (int i = 0; i < mechs.length; i++)
 *                    System.out.println(mechs[i].toString());
 *    }
 *
 *    // release system resources held by the credential
 *    cred.dispose();
 * </pre>
 *
 * @see GSSManager#createCredential(int)
 * @see GSSManager#createCredential(GSSName, int, Oid, int)
 * @see GSSManager#createCredential(GSSName, int, Oid[], int)
 * @see #dispose()
 *
 * @author Mayank Upadhyay
 * @since 1.4
 */
public interface GSSCredential extends Cloneable{

    /**
     * Credential usage flag requesting that it be usable
     * for both context initiation and acceptance.
     *
     */
    public static final int INITIATE_AND_ACCEPT = 0;


    /**
     * Credential usage flag requesting that it be usable
     * for context initiation only.
     *
     */
    public static final int INITIATE_ONLY = 1;


    /**
     * Credential usage flag requesting that it be usable
     * for context acceptance only.
     *
     */
    public static final int ACCEPT_ONLY = 2;


    /**
     * A lifetime constant representing the default credential lifetime. This
     * value it set to 0.
     */
    public static final int DEFAULT_LIFETIME = 0;

    /**
     * A lifetime constant representing indefinite credential lifetime.
     * This value must is set to the maximum integer value in Java -
     * {@link java.lang.Integer#MAX_VALUE Integer.MAX_VALUE}.
     */
    public static final int INDEFINITE_LIFETIME = Integer.MAX_VALUE;

    /**
     * Releases any sensitive information that the GSSCredential object may
     * be containing.  Applications should call this method as soon as the
     * credential is no longer needed to minimize the time any sensitive
     * information is maintained.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public void dispose() throws GSSException;

    /**
     *  Retrieves the name of the entity that the credential asserts.
     *
     * @return a GSSName representing the entity
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public GSSName getName() throws GSSException;

    /**
     * Retrieves a Mechanism Name of the entity that the credential
     * asserts. This is equivalent to calling {@link
     * GSSName#canonicalize(Oid) canonicalize} on the value returned by
     * the other form of {@link #getName() getName}.
     *
     * @param mech the Oid of the mechanism for which the Mechanism Name
     * should be returned.
     * @return a GSSName representing the entity canonicalized for the
     * desired mechanism
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#BAD_MECH GSSException.BAD_MECH},
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public GSSName getName(Oid mech) throws GSSException;

    /**
     * Returns the remaining lifetime in seconds for a credential.  The
     * remaining lifetime is the minimum lifetime amongst all of the underlying
     * mechanism specific credential elements.
     *
     * @return the minimum remaining lifetime in seconds for this
     * credential. A return value of {@link #INDEFINITE_LIFETIME
     * INDEFINITE_LIFETIME} indicates that the credential does
     * not expire. A return value of 0 indicates that the credential is
     * already expired.
     *
     * @see #getRemainingInitLifetime(Oid)
     * @see #getRemainingAcceptLifetime(Oid)
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public int getRemainingLifetime() throws GSSException;

    /**
     * Returns the lifetime in seconds for the credential to remain capable
     * of initiating security contexts using the specified mechanism. This
     * method queries the initiator credential element that belongs to the
     * specified mechanism.
     *
     * @return the number of seconds remaining in the life of this credential
     * element. A return value of {@link #INDEFINITE_LIFETIME
     * INDEFINITE_LIFETIME} indicates that the credential element does not
     * expire.  A return value of 0 indicates that the credential element is
     * already expired.
     *
     * @param mech the Oid of the mechanism whose intiator credential element
     * should be queried.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#BAD_MECH GSSException.BAD_MECH},
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public int getRemainingInitLifetime(Oid mech) throws GSSException;

    /**
     * Returns the lifetime in seconds for the credential to remain capable
     * of accepting security contexts using the specified mechanism. This
     * method queries the acceptor credential element that belongs to the
     * specified mechanism.
     *
     * @return the number of seconds remaining in the life of this credential
     * element. A return value of {@link #INDEFINITE_LIFETIME
     * INDEFINITE_LIFETIME} indicates that the credential element does not
     * expire.  A return value of 0 indicates that the credential element is
     * already expired.
     *
     * @param mech the Oid of the mechanism whose acceptor credential element
     * should be queried.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#BAD_MECH GSSException.BAD_MECH},
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public int getRemainingAcceptLifetime(Oid mech) throws GSSException;

    /**
     * Returns the credential usage mode. In other words, it
     * tells us if this credential can be used for initiating or accepting
     * security contexts. It does not tell us which mechanism(s) has to be
     * used in order to do so. It is expected that an application will allow
     * the GSS-API to pick a default mechanism after calling this method.
     *
     * @return The return value will be one of {@link #INITIATE_ONLY
     * INITIATE_ONLY}, {@link #ACCEPT_ONLY ACCEPT_ONLY}, and {@link
     * #INITIATE_AND_ACCEPT INITIATE_AND_ACCEPT}.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public int getUsage() throws GSSException;

    /**
     * Returns the credential usage mode for a specific mechanism. In other
     * words, it tells us if this credential can be used
     * for initiating or accepting security contexts with a given underlying
     * mechanism.
     *
     * @return The return value will be one of {@link #INITIATE_ONLY
     * INITIATE_ONLY}, {@link #ACCEPT_ONLY ACCEPT_ONLY}, and {@link
     * #INITIATE_AND_ACCEPT INITIATE_AND_ACCEPT}.
     * @param mech the Oid of the mechanism whose credentials usage mode is
     * to be determined.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#BAD_MECH GSSException.BAD_MECH},
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public int getUsage(Oid mech) throws GSSException;

    /**
     * Returns a list of mechanisms supported by this credential. It does
     * not tell us which ones can be used to initiate
     * contexts and which ones can be used to accept contexts. The
     * application must call the {@link #getUsage(Oid) getUsage} method with
     * each of the returned Oid's to determine the possible modes of
     * usage.
     *
     * @return an array of Oid's corresponding to the supported mechanisms.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public Oid[] getMechs() throws GSSException;

    /**
     * Adds a mechanism specific credential-element to an existing
     * credential.  This method allows the construction of credentials, one
     * mechanism at a time.<p>
     *
     * This routine is envisioned to be used mainly by context acceptors
     * during the creation of acceptor credentials which are to be used
     * with a variety of clients using different security mechanisms.<p>
     *
     * This routine adds the new credential element "in-place".  To add the
     * element in a new credential, first call <code>clone</code> to obtain a
     * copy of this credential, then call its <code>add</code> method.<p>
     *
     * As always, GSS-API implementations must impose a local access-control
     * policy on callers to prevent unauthorized callers from acquiring
     * credentials to which they are not entitled.
     *
     * Non-default values for initLifetime and acceptLifetime cannot always
     * be honored by the underlying mechanisms, thus callers should be
     * prepared to call {@link #getRemainingInitLifetime(Oid)
     * getRemainingInitLifetime} and {@link #getRemainingAcceptLifetime(Oid)
     * getRemainingAcceptLifetime} on the credential.
     *
     * @param name the name of the principal for whom this credential is to
     * be acquired.  Use <code>null</code> to specify the default
     * principal.
     * @param initLifetime the number of seconds that the credential element
     * should remain valid for initiating of security contexts. Use {@link
     * GSSCredential#INDEFINITE_LIFETIME GSSCredential.INDEFINITE_LIFETIME}
     * to request that the credentials have the maximum permitted lifetime
     * for this.  Use {@link GSSCredential#DEFAULT_LIFETIME
     * GSSCredential.DEFAULT_LIFETIME} to request default credential lifetime
     * for this.
     * @param acceptLifetime the number of seconds that the credential
     * element should remain valid for accepting security contexts. Use {@link
     * GSSCredential#INDEFINITE_LIFETIME GSSCredential.INDEFINITE_LIFETIME}
     * to request that the credentials have the maximum permitted lifetime
     * for this.  Use {@link GSSCredential#DEFAULT_LIFETIME
     * GSSCredential.DEFAULT_LIFETIME} to request default credential lifetime
     * for this.
     * @param mech the mechanism over which the credential is to be acquired.
     * @param usage the usage mode that this credential
     * element should add to the credential. The value
     * of this parameter must be one of:
     * {@link #INITIATE_AND_ACCEPT INITIATE_AND_ACCEPT},
     * {@link #ACCEPT_ONLY ACCEPT_ONLY}, and
     * {@link #INITIATE_ONLY INITIATE_ONLY}.
     *
     * @throws GSSException containing the following
     * major error codes:
     *         {@link GSSException#DUPLICATE_ELEMENT
     *                          GSSException.DUPLICATE_ELEMENT},
     *         {@link GSSException#BAD_MECH GSSException.BAD_MECH},
     *         {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},
     *         {@link GSSException#NO_CRED GSSException.NO_CRED},
     *         {@link GSSException#CREDENTIALS_EXPIRED
     *                                  GSSException.CREDENTIALS_EXPIRED},
     *         {@link GSSException#FAILURE GSSException.FAILURE}
     */
    public void add(GSSName name, int initLifetime, int acceptLifetime,
                    Oid mech, int usage) throws GSSException;

    /**
     * Tests if this GSSCredential asserts the same entity as the supplied
     * object.  The two credentials must be acquired over the same
     * mechanisms and must refer to the same principal.
     *
     * @return <code>true</code> if the two GSSCredentials assert the same
     * entity; <code>false</code> otherwise.
     * @param another another GSSCredential for comparison to this one
     */
    public boolean equals(Object another);

    /**
     * Returns a hashcode value for this GSSCredential.
     *
     * @return a hashCode value
     */
    public int hashCode();

}
