1347 lines · 62.5 KB · Java
RawDownload
/* * 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 org.ietf.jgss; import sun.security.jgss.spi.*;import java.io.InputStream;import java.io.OutputStream; /** * This interface encapsulates the GSS-API security context and provides * the security services that are available over the context.  Security * contexts are established between peers using locally acquired * credentials.  Multiple contexts may exist simultaneously between a pair * of peers, using the same or different set of credentials.  GSS-API * functions in a manner independent of the underlying transport protocol * and depends on its calling application to transport the tokens that are * generated by the security context between the peers.<p> * * If the caller instantiates the context using the default * <code>GSSManager</code> instance, then the Kerberos v5 GSS-API mechanism * is guaranteed to be available for context establishment. This mechanism * is identified by the Oid "1.2.840.113554.1.2.2" and is defined in RFC * 1964.<p> * * Before the context establishment phase is initiated, the context * initiator may request specific characteristics desired of the * established context. Not all underlying mechanisms support all * characteristics that a caller might desire. After the context is * established, the caller can check the actual characteristics and services * offered by that context by means of various query methods. When using * the Kerberos v5 GSS-API mechanism offered by the default * <code>GSSManager</code> instance, all optional services will be * available locally. They are mutual authentication, credential * delegation, confidentiality and integrity protection, and per-message * replay detection and sequencing. Note that in the GSS-API, message integrity * is a prerequisite for message confidentiality.<p> * * The context establishment occurs in a loop where the * initiator calls {@link #initSecContext(byte[], int, int) initSecContext} * and the acceptor calls {@link #acceptSecContext(byte[], int, int) * acceptSecContext} until the context is established. While in this loop * the <code>initSecContext</code> and <code>acceptSecContext</code> * methods produce tokens that the application sends over to the peer. The * peer passes any such token as input to its <code>acceptSecContext</code> * or <code>initSecContext</code> as the case may be.<p> * * During the context establishment phase, the {@link * #isProtReady() isProtReady} method may be called to determine if the * context can be used for the per-message operations of {@link * #wrap(byte[], int, int, MessageProp) wrap} and {@link #getMIC(byte[], * int, int, MessageProp) getMIC}.  This allows applications to use * per-message operations on contexts which aren't yet fully * established.<p> * * After the context has been established or the <code>isProtReady</code> * method returns <code>true</code>, 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 {@link #wrap(byte[], int, int, MessageProp) wrap} and * {@link #getMIC(byte[], int, int, MessageProp) getMIC} to obtain * cryptographic operations on application supplied data.<p> * * When the context is no longer needed, the application should call * {@link #dispose() dispose} to release any system resources the context * may be using.<p> * * A security context typically maintains sequencing and replay detection * information about the tokens it processes. Therefore, the sequence in * which any tokens are presented to this context for processing can be * important. Also note that none of the methods in this interface are * synchronized. Therefore, it is not advisable to share a * <code>GSSContext</code> among several threads unless some application * level synchronization is in place.<p> * * Finally, different mechanism providers might place different security * restrictions on using GSS-API contexts. These will be documented by the * mechanism provider. The application will need to ensure that it has the * appropriate permissions if such checks are made in the mechanism layer.<p> * * The example code presented below demonstrates the usage of the * <code>GSSContext</code> interface for the initiating peer.  Different * operations on the <code>GSSContext</code> object are presented, * including: object instantiation, setting of desired flags, context * establishment, query of actual context flags, per-message operations on * application data, and finally context deletion.<p> * * <pre> *    // Create a context using default credentials *    // and the implementation specific default mechanism *    GSSManager manager ... *    GSSName targetName ... *    GSSContext context = manager.createContext(targetName, null, null, *                                           GSSContext.INDEFINITE_LIFETIME); * *    // set desired context options prior to context establishment *    context.requestConf(true); *    context.requestMutualAuth(true); *    context.requestReplayDet(true); *    context.requestSequenceDet(true); * *    // establish a context between peers * *    byte []inToken = new byte[0]; * *    // Loop while there still is a token to be processed * *    while (!context.isEstablished()) { * *        byte[] outToken *            = context.initSecContext(inToken, 0, inToken.length); * *        // send the output token if generated *        if (outToken != null) *            sendToken(outToken); * *        if (!context.isEstablished()) { *            inToken = readToken(); *    } * *     // display context information *     System.out.println("Remaining lifetime in seconds = " *                                          + context.getLifetime()); *     System.out.println("Context mechanism = " + context.getMech()); *     System.out.println("Initiator = " + context.getSrcName()); *     System.out.println("Acceptor = " + context.getTargName()); * *     if (context.getConfState()) *             System.out.println("Confidentiality (i.e., privacy) is available"); * *     if (context.getIntegState()) *             System.out.println("Integrity is available"); * *     // perform wrap on an application supplied message, appMsg, *     // using QOP = 0, and requesting privacy service *     byte [] appMsg ... * *     MessageProp mProp = new MessageProp(0, true); * *     byte []tok = context.wrap(appMsg, 0, appMsg.length, mProp); * *     sendToken(tok); * *     // release the local-end of the context *     context.dispose(); * * </pre> * * @author Mayank Upadhyay * @since 1.4 */public interface GSSContext {     /**     * A lifetime constant representing the default context lifetime.  This     * value is set to 0.     */    public static final int DEFAULT_LIFETIME = 0;     /**     * A lifetime constant representing indefinite context 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;     /**     * Called by the context initiator to start the context creation     * phase and process any tokens generated     * by the peer's <code>acceptSecContext</code> method.     * This method may return an output token which the application will need     * to send to the peer for processing by its <code>acceptSecContext</code>     * method. The application can call {@link #isEstablished()     * isEstablished} to determine if the context establishment phase is     * complete on this side of the context.  A return value of     * <code>false</code> from <code>isEstablished</code> indicates that     * more tokens are expected to be supplied to     * <code>initSecContext</code>.  Upon completion of the context     * establishment, the available context options may be queried through     * the get methods.<p>     *     * Note that it is possible that the <code>initSecContext</code> method     * return a token for the peer, and <code>isEstablished</code> return     * <code>true</code> also. This indicates that the token needs to be sent     * to the peer, but the local end of the context is now fully     * established.<p>     *     * Some mechanism providers might require that the caller be granted     * permission to initiate a security context. A failed permission check     * might cause a {@link java.lang.SecurityException SecurityException}     * to be thrown from this method.<p>     *     * @return a byte[] containing the token to be sent to the     * peer. <code>null</code> indicates that no token is generated.     * @param inputBuf token generated by the peer. This parameter is ignored     * on the first call since no token has been received from the peer.     * @param offset the offset within the inputBuf where the token begins.     * @param len the length of the token.     *     * @throws GSSException containing the following     * major error codes:     *   {@link GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN},     *   {@link GSSException#BAD_MIC GSSException.BAD_MIC},     *   {@link GSSException#NO_CRED GSSException.NO_CRED},     *   {@link GSSException#CREDENTIALS_EXPIRED     *                                  GSSException.CREDENTIALS_EXPIRED},     *   {@link GSSException#BAD_BINDINGS GSSException.BAD_BINDINGS},     *   {@link GSSException#OLD_TOKEN GSSException.OLD_TOKEN},     *   {@link GSSException#DUPLICATE_TOKEN GSSException.DUPLICATE_TOKEN},     *   {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH},     *   {@link GSSException#FAILURE GSSException.FAILURE}     */    public byte[] initSecContext(byte inputBuf[], int offset, int len)        throws GSSException;     /**     * Called by the context initiator to start the context creation     * phase and process any tokens generated     * by the peer's <code>acceptSecContext</code> method using     * streams. This method may write an output token to the     * <code>OutpuStream</code>, which the application will     * need to send to the peer for processing by its     * <code>acceptSecContext</code> call. Typically, the application would     * ensure this by calling the  {@link java.io.OutputStream#flush() flush}     * method on an <code>OutputStream</code> that encapsulates the     * connection between the two peers. The application can     * determine if a token is written to the OutputStream from the return     * value of this method. A return value of <code>0</code> indicates that     * no token was written. The application can call     * {@link #isEstablished() isEstablished} to determine if the context     * establishment phase is complete on this side of the context. A     * return  value of <code>false</code> from <code>isEstablished</code>     * indicates that more tokens are expected to be supplied to     * <code>initSecContext</code>.     * Upon completion of the context establishment, the available context     * options may be queried through the get methods.<p>     *     * Note that it is possible that the <code>initSecContext</code> method     * return a token for the peer, and <code>isEstablished</code> return     * <code>true</code> also. This indicates that the token needs to be sent     * to the peer, but the local end of the context is now fully     * established.<p>     *     * The GSS-API authentication tokens contain a definitive start and     * end. This method will attempt to read one of these tokens per     * invocation, and may block on the stream if only part of the token is     * available.  In all other respects this method is equivalent to the     * byte array based {@link #initSecContext(byte[], int, int)     * initSecContext}.<p>     *     * Some mechanism providers might require that the caller be granted     * permission to initiate a security context. A failed permission check     * might cause a {@link java.lang.SecurityException SecurityException}     * to be thrown from this method.<p>     *     * The following example code demonstrates how this method might be     * used:<p>     * <pre>     *     InputStream is ...     *     OutputStream os ...     *     GSSContext context ...     *     *     // Loop while there is still a token to be processed     *     *     while (!context.isEstablished()) {     *     *         context.initSecContext(is, os);     *     *         // send output token if generated     *         os.flush();     *     }     * </pre>     *     *     * @return the number of bytes written to the OutputStream as part of the     * token to be sent to the peer. A value of 0 indicates that no token     * needs to be sent.     * @param inStream an InputStream that contains the token generated by     * the peer. This parameter is ignored on the first call since no token     * has been or will be received from the peer at that point.     * @param outStream an OutputStream where the output token will be     * written. During the final stage of context establishment, there may be     * no bytes written.     *     * @throws GSSException containing the following     * major error codes:     *   {@link GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN},     *   {@link GSSException#BAD_MIC GSSException.BAD_MIC},     *   {@link GSSException#NO_CRED GSSException.NO_CRED},     *   {@link GSSException#CREDENTIALS_EXPIRED GSSException.CREDENTIALS_EXPIRED},     *   {@link GSSException#BAD_BINDINGS GSSException.BAD_BINDINGS},     *   {@link GSSException#OLD_TOKEN GSSException.OLD_TOKEN},     *   {@link GSSException#DUPLICATE_TOKEN GSSException.DUPLICATE_TOKEN},     *   {@link GSSException#BAD_NAMETYPE GSSException.BAD_NAMETYPE},     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH},     *   {@link GSSException#FAILURE GSSException.FAILURE}     */    public int initSecContext(InputStream inStream,                              OutputStream outStream) throws GSSException;     /**     * Called by the context acceptor upon receiving a token from the     * peer. This method may return an output token which the application     * will need to send to the peer for further processing by its     * <code>initSecContext</code> call.<p>     *     * The application can call {@link #isEstablished() isEstablished} to     * determine if the context establishment phase is complete for this     * peer.  A return value of <code>false</code> from     * <code>isEstablished</code> indicates that more tokens are expected to     * be supplied to this method.    Upon completion of the context     * establishment, the available context options may be queried through     * the get methods.<p>     *     * Note that it is possible that <code>acceptSecContext</code> return a     * token for the peer, and <code>isEstablished</code> return     * <code>true</code> also.  This indicates that the token needs to be     * sent to the peer, but the local end of the context is now fully     * established.<p>     *     * Some mechanism providers might require that the caller be granted     * permission to accept a security context. A failed permission check     * might cause a {@link java.lang.SecurityException SecurityException}     * to be thrown from this method.<p>     *     * The following example code demonstrates how this method might be     * used:<p>     * <pre>     *     byte[] inToken;     *     byte[] outToken;     *     GSSContext context ...     *     *     // Loop while there is still a token to be processed     *     *     while (!context.isEstablished()) {     *         inToken = readToken();     *         outToken = context.acceptSecContext(inToken, 0,     *                                             inToken.length);     *         // send output token if generated     *         if (outToken != null)     *             sendToken(outToken);     *     }     * </pre>     *     *     * @return a byte[] containing the token to be sent to the     * peer. <code>null</code> indicates that no token is generated.     * @param inToken token generated by the peer.     * @param offset the offset within the inToken where the token begins.     * @param len the length of the token.     *     * @throws GSSException containing the following     * major error codes:     *   {@link GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN},     *   {@link GSSException#BAD_MIC GSSException.BAD_MIC},     *   {@link GSSException#NO_CRED GSSException.NO_CRED},     *   {@link GSSException#CREDENTIALS_EXPIRED     *                               GSSException.CREDENTIALS_EXPIRED},     *   {@link GSSException#BAD_BINDINGS GSSException.BAD_BINDINGS},     *   {@link GSSException#OLD_TOKEN GSSException.OLD_TOKEN},     *   {@link GSSException#DUPLICATE_TOKEN GSSException.DUPLICATE_TOKEN},     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH},     *   {@link GSSException#FAILURE GSSException.FAILURE}     */    public byte[] acceptSecContext(byte inToken[], int offset, int len)        throws GSSException;     /**     * Called by the context acceptor to process a token from the peer using     * streams.   It may write an output token to the     * <code>OutputStream</code>, which the application     * will need to send to the peer for processing by its     * <code>initSecContext</code> method.  Typically, the application would     * ensure this by calling the  {@link java.io.OutputStream#flush() flush}     * method on an <code>OutputStream</code> that encapsulates the     * connection between the two peers. The application can call     * {@link #isEstablished() isEstablished} to determine if the context     * establishment phase is complete on this side of the context. A     * return  value of <code>false</code> from <code>isEstablished</code>     * indicates that more tokens are expected to be supplied to     * <code>acceptSecContext</code>.     * Upon completion of the context establishment, the available context     * options may be queried through the get methods.<p>     *     * Note that it is possible that <code>acceptSecContext</code> return a     * token for the peer, and <code>isEstablished</code> return     * <code>true</code> also.  This indicates that the token needs to be     * sent to the peer, but the local end of the context is now fully     * established.<p>     *     * The GSS-API authentication tokens contain a definitive start and     * end. This method will attempt to read one of these tokens per     * invocation, and may block on the stream if only part of the token is     * available. In all other respects this method is equivalent to the byte     * array based {@link #acceptSecContext(byte[], int, int)     * acceptSecContext}.<p>     *     * Some mechanism providers might require that the caller be granted     * permission to accept a security context. A failed permission check     * might cause a {@link java.lang.SecurityException SecurityException}     * to be thrown from this method.<p>     *     * The following example code demonstrates how this method might be     * used:<p>     * <pre>     *     InputStream is ...     *     OutputStream os ...     *     GSSContext context ...     *     *     // Loop while there is still a token to be processed     *     *     while (!context.isEstablished()) {     *     *         context.acceptSecContext(is, os);     *     *         // send output token if generated     *         os.flush();     *     }     * </pre>     *     *     * @param inStream an InputStream that contains the token generated by     * the peer.     * @param outStream an OutputStream where the output token will be     * written. During the final stage of context establishment, there may be     * no bytes written.     *     * @throws GSSException containing the following     * major error codes:     *   {@link GSSException#DEFECTIVE_TOKEN GSSException.DEFECTIVE_TOKEN},     *   {@link GSSException#BAD_MIC GSSException.BAD_MIC},     *   {@link GSSException#NO_CRED GSSException.NO_CRED},     *   {@link GSSException#CREDENTIALS_EXPIRED     *                           GSSException.CREDENTIALS_EXPIRED},     *   {@link GSSException#BAD_BINDINGS GSSException.BAD_BINDINGS},     *   {@link GSSException#OLD_TOKEN GSSException.OLD_TOKEN},     *   {@link GSSException#DUPLICATE_TOKEN GSSException.DUPLICATE_TOKEN},     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH},     *   {@link GSSException#FAILURE GSSException.FAILURE}     */    /* Missing return value in RFC. int should have been returned.     * -----------------------------------------------------------     *     * The application can determine if a token is written to the     * OutputStream from the return value of this method. A return value of     * <code>0</code> indicates that no token was written.     *     * @return <strong>the number of bytes written to the     * OutputStream as part of the token to be sent to the peer. A value of     * 0 indicates that no token  needs to be     * sent.</strong>     */    public void acceptSecContext(InputStream inStream,                                 OutputStream outStream) throws GSSException;     /**     * Used during context establishment to determine the state of the     * context.     *     * @return <code>true</code> if this is a fully established context on     * the caller's side and no more tokens are needed from the peer.     */    public boolean isEstablished();     /**     * Releases any system resources and cryptographic information stored in     * the context object and invalidates the context.     *     *     * @throws GSSException containing the following     * major error codes:     *   {@link GSSException#FAILURE GSSException.FAILURE}     */    public void dispose() throws GSSException;     /**     * Used to determine limits on the size of the message

Lines 1–500 of 1347.