/* * 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"); } } }