/* | 
|
 * Copyright (c) 2005, 2011, 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.spnego;  | 
|
import java.io.*;  | 
|
import java.util.*;  | 
|
import org.ietf.jgss.*;  | 
|
import sun.security.util.*;  | 
|
import sun.security.jgss.*;  | 
|
/**  | 
|
* Astract class for SPNEGO tokens.  | 
|
* Implementation is based on RFC 2478  | 
|
*  | 
|
 * NegotiationToken ::= CHOICE { | 
|
* negTokenInit [0] NegTokenInit,  | 
|
* negTokenTarg [1] NegTokenTarg }  | 
|
*  | 
|
*  | 
|
* @author Seema Malkani  | 
|
* @since 1.6  | 
|
*/  | 
|
abstract class SpNegoToken extends GSSToken {  | 
|
static final int NEG_TOKEN_INIT_ID = 0x00;  | 
|
static final int NEG_TOKEN_TARG_ID = 0x01;  | 
|
    static enum NegoResult { | 
|
ACCEPT_COMPLETE,  | 
|
ACCEPT_INCOMPLETE,  | 
|
REJECT,  | 
|
};  | 
|
private int tokenType;  | 
|
    // property | 
|
static final boolean DEBUG = SpNegoContext.DEBUG;  | 
|
    /** | 
|
     * The object identifier corresponding to the SPNEGO GSS-API | 
|
     * mechanism. | 
|
*/  | 
|
public static ObjectIdentifier OID;  | 
|
    static { | 
|
        try { | 
|
OID = new ObjectIdentifier(SpNegoMechFactory.  | 
|
GSS_SPNEGO_MECH_OID.toString());  | 
|
} catch (IOException ioe) {  | 
|
// should not happen  | 
|
}  | 
|
}  | 
|
    /** | 
|
     * Creates SPNEGO token of the specified type. | 
|
*/  | 
|
    protected SpNegoToken(int tokenType) { | 
|
this.tokenType = tokenType;  | 
|
}  | 
|
    /** | 
|
     * Returns the individual encoded SPNEGO token | 
|
     * | 
|
     * @return the encoded token | 
|
     * @exception GSSException | 
|
*/  | 
|
abstract byte[] encode() throws GSSException;  | 
|
    /** | 
|
     * Returns the encoded SPNEGO token | 
|
     * Note: inserts the required CHOICE tags | 
|
     * | 
|
     * @return the encoded token | 
|
     * @exception GSSException | 
|
*/  | 
|
byte[] getEncoded() throws IOException, GSSException {  | 
|
        // get the token encoded value | 
|
DerOutputStream token = new DerOutputStream();  | 
|
token.write(encode());  | 
|
        // now insert the CHOICE | 
|
switch (tokenType) {  | 
|
case NEG_TOKEN_INIT_ID:  | 
|
                // Insert CHOICE of Negotiation Token | 
|
DerOutputStream initToken = new DerOutputStream();  | 
|
initToken.write(DerValue.createTag(DerValue.TAG_CONTEXT,  | 
|
true, (byte) NEG_TOKEN_INIT_ID), token);  | 
|
return initToken.toByteArray();  | 
|
case NEG_TOKEN_TARG_ID:  | 
|
                // Insert CHOICE of Negotiation Token | 
|
DerOutputStream targToken = new DerOutputStream();  | 
|
targToken.write(DerValue.createTag(DerValue.TAG_CONTEXT,  | 
|
true, (byte) NEG_TOKEN_TARG_ID), token);  | 
|
return targToken.toByteArray();  | 
|
default:  | 
|
return token.toByteArray();  | 
|
}  | 
|
}  | 
|
    /** | 
|
     * Returns the SPNEGO token type | 
|
     * | 
|
     * @return the token type | 
|
*/  | 
|
    final int getType() { | 
|
return tokenType;  | 
|
}  | 
|
    /** | 
|
     * Returns a string representing the token type. | 
|
     * | 
|
     * @param tokenType the token type for which a string name is desired | 
|
     * @return the String name of this token type | 
|
*/  | 
|
static String getTokenName(int type) {  | 
|
switch (type) {  | 
|
case NEG_TOKEN_INIT_ID:  | 
|
                return "SPNEGO NegTokenInit"; | 
|
case NEG_TOKEN_TARG_ID:  | 
|
                return "SPNEGO NegTokenTarg"; | 
|
default:  | 
|
                return "SPNEGO Mechanism Token"; | 
|
}  | 
|
}  | 
|
    /** | 
|
     * Returns the enumerated type of the Negotiation result. | 
|
     * | 
|
     * @param result the negotiated result represented by integer | 
|
     * @return the enumerated type of Negotiated result | 
|
*/  | 
|
    static NegoResult getNegoResultType(int result) { | 
|
switch (result) {  | 
|
case 0:  | 
|
return NegoResult.ACCEPT_COMPLETE;  | 
|
case 1:  | 
|
return NegoResult.ACCEPT_INCOMPLETE;  | 
|
case 2:  | 
|
return NegoResult.REJECT;  | 
|
default:  | 
|
                // unknown - return optimistic result | 
|
return NegoResult.ACCEPT_COMPLETE;  | 
|
}  | 
|
}  | 
|
    /** | 
|
     * Returns a string representing the negotiation result. | 
|
     * | 
|
     * @param result the negotiated result | 
|
     * @return the String message of this negotiated result | 
|
*/  | 
|
static String getNegoResultString(int result) {  | 
|
switch (result) {  | 
|
case 0:  | 
|
                return "Accept Complete"; | 
|
case 1:  | 
|
                return "Accept InComplete"; | 
|
case 2:  | 
|
                return "Reject"; | 
|
default:  | 
|
return ("Unknown Negotiated Result: " + result);  | 
|
}  | 
|
}  | 
|
    /** | 
|
     * Checks if the context tag in a sequence is in correct order. The "last" | 
|
     * value must be smaller than "current". | 
|
     * @param last the last tag seen | 
|
     * @param current the current tag | 
|
     * @return the current tag, used as the next value for last | 
|
     * @throws GSSException if there's a wrong order | 
|
*/  | 
|
static int checkNextField(int last, int current) throws GSSException {  | 
|
if (last < current) {  | 
|
return current;  | 
|
        } else { | 
|
throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,  | 
|
                "Invalid SpNegoToken token : wrong order"); | 
|
}  | 
|
}  | 
|
}  |