/* * Copyright (C) 2006-2008 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.jlan.server.auth.spnego; import java.io.IOException; import org.alfresco.jlan.server.auth.asn.DERBuffer; import org.alfresco.jlan.server.auth.asn.DEREnumerated; import org.alfresco.jlan.server.auth.asn.DERObject; import org.alfresco.jlan.server.auth.asn.DEROctetString; import org.alfresco.jlan.server.auth.asn.DEROid; import org.alfresco.jlan.server.auth.asn.DERSequence; import org.ietf.jgss.GSSException; import org.ietf.jgss.Oid; /** * NegTokenTarg Class * * <p> * Contains the details of an SPNEGO NegTokenTarg blob for use with CIFS. * * @author gkspencer */ public class NegTokenTarg { // Result code private int m_result = -1; // Supported mechanism private Oid m_supportedMech; // Response token private byte[] m_responseToken; /** * Class constructor for decoding */ public NegTokenTarg() { } /** * Class constructor * * @param result int * @param mech Oid * @param response byte[] */ public NegTokenTarg(int result, Oid mech, byte[] response) { m_result = result; m_supportedMech = mech; m_responseToken = response; } /** * Return the result * * @return int */ public final int getResult() { return m_result; } /** * Return the supported mech type Oid * * @return Oid */ public final Oid getSupportedMech() { return m_supportedMech; } /** * Determine if there is a valid response token * * @return boolean */ public final boolean hasResponseToken() { return m_responseToken != null ? true : false; } /** * Return the response token * * @return byte[] */ public final byte[] getResponseToken() { return m_responseToken; } /** * Decode an SPNEGO NegTokenTarg blob * * @param buf byte[] * @param off int * @param len int * @exception IOException */ public void decode(byte[] buf, int off, int len) throws IOException { // Create a DER buffer to decode the blob DERBuffer derBuf = new DERBuffer(buf, off, len); // Get the first object from the blob DERObject derObj = derBuf.unpackObject(); if ( derObj instanceof DERSequence) { // Access the sequence DERSequence derSeq = (DERSequence) derObj; // Get the status derObj = derSeq.getTaggedObject( 0); if ( derObj != null) { if ( derObj instanceof DEREnumerated == false) throw new IOException( "Invalid status object"); DEREnumerated derEnum = (DEREnumerated) derObj; m_result = derEnum.getValue(); } // Get the supportedMech (optional) derObj = derSeq.getTaggedObject( 1); if ( derObj != null) { // Check the object type if ( derObj instanceof DEROid == false) throw new IOException( "Invalid supportedMech object"); DEROid derMech = (DEROid) derObj; try { m_supportedMech = new Oid( derMech.getOid()); } catch (GSSException ex) { throw new IOException( "Bad supportedMech OID"); } } else m_supportedMech = null; // Get the responseToken (optional) derObj = derSeq.getTaggedObject( 2); if ( derObj != null) { // Check the object type if ( derObj instanceof DEROctetString == false) throw new IOException( "Invalid responseToken object"); DEROctetString derResp = (DEROctetString) derObj; m_responseToken = derResp.getValue(); } else m_responseToken = null; // Get the mecListMIC (optional) derObj = derSeq.getTaggedObject( 3); if ( derObj != null) { // Check the object type if ( derObj instanceof DEROctetString == false) throw new IOException( "Invalid mecListMIC object"); DEROctetString derMec = (DEROctetString) derObj; } } else throw new IOException( "Bad format in security blob"); } /** * Encode an SPNEGO NegTokenTarg blob * * @return byte[] * @exception IOException */ public byte[] encode() throws IOException { // Build the sequence of tagged objects DERSequence derSeq = new DERSequence(); derSeq.setTagNo( 1); // Add the result DEREnumerated derEnum = new DEREnumerated( m_result); derEnum.setTagNo( 0); derSeq.addObject( derEnum); // Pack the supportedMech, if valid if ( m_supportedMech != null) { DEROid derOid = new DEROid( m_supportedMech.toString()); derOid.setTagNo( 1); derSeq.addObject( derOid); } // Pack the response token, if valid if ( m_responseToken != null) { DEROctetString derResp = new DEROctetString( m_responseToken); derResp.setTagNo( 2); derSeq.addObject( derResp); } // Pack the objects DERBuffer derBuf = new DERBuffer(); derBuf.packObject( derSeq); // Return the packed negTokenInit blob return derBuf.getBytes(); } /** * Return the NegtokenTarg object as a string * * @return String */ public String toString() { StringBuffer str = new StringBuffer(); str.append("[NegtokenTarg result="); str.append(SPNEGO.asResultString(getResult())); str.append(" oid="); str.append(getSupportedMech()); str.append(" response="); if (hasResponseToken()) { str.append(getResponseToken().length); str.append(" bytes"); } else str.append("null"); str.append("]"); return str.toString(); } }