12b65585e720714b31036daaa2b30eb76014048eGordon Ross// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Copyright (C) 2002 Microsoft Corporation
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// OR IMPLIED, INCLUDING BUT NOT LIMITED
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Date - 10/08/2002
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Author - Sanj Surati
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// SPNEGOPARSE.C
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// SPNEGO Token Handler Source File
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Contains implementation of SPNEGO Token parsing functions.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdlib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdio.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <memory.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include "spnego.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include "derparse.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include "spnegoparse.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Defined in DERPARSE.C
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowextern MECH_OID g_stcMechOIDList [];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/**********************************************************************/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** Local SPNEGO Helper definitions **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/** **/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/**********************************************************************/
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// CalculateMinSpnegoInitTokenSize
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nMechTokenLength - Length of the MechToken Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nMechListMICLength - Length of the MechListMIC Element
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// (or negHints, if no MechToken)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] mechOID - OID for MechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nReqFlagsAvailable - Is ContextFlags element available
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnTokenSize - Filled out with total size of token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnInternalTokenLength - Filled out with length minus length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// for initial token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Calculates the required length for a SPNEGO NegTokenInit token based
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// on the supplied variable length values and which elements are present.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Note that because the lengths can be represented by an arbitrary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// number of bytes in DER encodings, we actually calculate the lengths
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// backwards, so we always know how many bytes we will potentially be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// writing out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint CalculateMinSpnegoInitTokenSize( long nMechTokenLength,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long nMechListMICLength, SPNEGO_MECH_OID *mechOidLst, int mechOidCnt,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReqFlagsAvailable, long* pnTokenSize,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long* pnInternalTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Start at 0.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTotalLength = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTempLength= 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We will calculate this by walking the token backwards
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Start with MIC Element (or negHints)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nMechListMICLength > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( nMechListMICLength, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nMechListMICLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the MechToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nMechTokenLength > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcElementLength( nMechTokenLength, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the ReqFlags
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nReqFlagsAvailable )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the MechList - This is REQUIRED
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTempLength += ASNDerCalcMechListLength( mechOidLst, mechOidCnt, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Following four fields are the basic header tokens
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Neg Token Identifier Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // SPNEGO OID Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // App Constructed Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenInitLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The internal length doesn't include the number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // for the initial token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnInternalTokenLength = nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We're done
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnTokenSize = nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowxEndTokenInitLength:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// CreateSpnegoInitToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// [in] pMechTypeList - OID array
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// [in] MechTypeCnt - OID array length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucContextFlags - ContextFlags value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbMechToken - Mech Token Binary Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulMechTokenLen - Length of Mech Token
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// [in] pbMechListMIC - MechListMIC Binary Data (or negHints)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulMechListMICn - Length of MechListMIC
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbTokenData - Buffer to write token into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nTokenLength - Length of pbTokenData buffer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nInternalTokenLength - Length of full token without leading
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// token bytes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Uses DER to fill out pbTokenData with a SPNEGO NegTokenInit Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Note that because the lengths can be represented by an arbitrary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// number of bytes in DER encodings, we actually calculate the lengths
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// backwards, so we always know how many bytes we will potentially be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// writing out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// This function is also used to create an SPNEGO "hint", as described in
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// [MS-SPNG] sec. 2.2.1 negTokenInit2. The "hint" looks almost identical
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// to a NegTokenInit, but has a "negHints" field inserted before the MIC.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// A normal SPNEGO negTokenInit2 contains only the mech list and the
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// negHints. To avoid a giant copy/paste of this function, we pass the
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// negHints as the MIC arg, and pass NULL as the MechToken to indicate
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// that we're creating a Hint rather than an Init, and use the correct
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// type when writing out the MIC (or negHints) element.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Rossint CreateSpnegoInitToken( SPNEGO_MECH_OID *pMechTypeList, long MechTypeCnt,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char ucContextFlags, unsigned char* pbMechToken,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned long ulMechListMICLen, unsigned char* pbTokenData,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTokenLength, long nInternalTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Start at 0.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTempLength= 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTotalBytesWritten = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nInternalLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbWriteTokenData = pbTokenData + nTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Temporary buffer to hold the REQ Flags as BIT String Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char abTempReqFlags[SPNEGO_NEGINIT_MAXLEN_REQFLAGS];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We will write the token out backwards to properly handle the cases
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // where the length bytes become adjustable
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Start with MIC Element (or negHints)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ulMechListMICLen > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross unsigned char ucType;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Decrease the pbWriteTokenData, now we know the length and write it out.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Note: When MechTokenLen == 0, we're writing a negTokenInit2 and the
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // MIC arg is really negHints, written as a constructed sequence.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Otherwise we're writing a negTokenInit, and the MIC is an OCTETSTRING.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross ucType = (ulMechTokenLen == 0) ?
12b65585e720714b31036daaa2b30eb76014048eGordon Ross SPNEGO_CONSTRUCTED_SEQUENCE : OCTETSTRING;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross ucType, pbMechListMIC, ulMechListMICLen );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF MechListMIC is present
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the MechToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ulMechTokenLen > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHTOKEN,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow OCTETSTRING, pbMechToken, ulMechTokenLen );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF MechToken Length is present
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the ReqFlags
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ucContextFlags > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We need a byte that indicates how many bits difference between the number
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // of bits used in final octet (we only have one) and the max (8)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow abTempReqFlags[1] = ucContextFlags;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow BITSTRING, abTempReqFlags, SPNEGO_NEGINIT_MAXLEN_REQFLAGS );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF ContextFlags
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the MechList - This is REQUIRED
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTempLength = ASNDerCalcMechListLength( pMechTypeList, MechTypeCnt, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTempLength = ASNDerWriteMechList( pbWriteTokenData, pMechTypeList, MechTypeCnt );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next tokens we're writing out reflect the total number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // we have actually written out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL, nTotalBytesWritten );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Neg Init Token Identifier Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL, nTotalBytesWritten );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // SPNEGO OID Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteOID( pbWriteTokenData, spnego_mech_oid_Spnego );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenInit;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // App Constructed Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL, nTotalBytesWritten );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Don't adjust the internal token length here, it doesn't account
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // the initial bytes written out (we really don't need to keep
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // a running count here, but for debugging, it helps to be able
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // to see the total number of bytes written out as well as the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // number of bytes left to write).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData == pbTokenData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowxEndWriteNegTokenInit:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// CalculateMinSpnegoTargTokenSize
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] MechType - Supported MechType
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] spnegoNegResult - Neg Result
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nMechTokenLength - Length of the MechToken Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nMechListMICLength - Length of the MechListMIC Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnTokenSize - Filled out with total size of token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnInternalTokenLength - Filled out with length minus length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// for initial token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Calculates the required length for a SPNEGO NegTokenTarg token based
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// on the supplied variable length values and which elements are present.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Note that because the lengths can be represented by an arbitrary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// number of bytes in DER encodings, we actually calculate the lengths
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// backwards, so we always know how many bytes we will potentially be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// writing out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nMechListMICLen, long* pnTokenSize,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long* pnInternalTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Start at 0.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTotalLength = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTempLength= 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We will calculate this by walking the token backwards
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Start with MIC Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nMechListMICLen > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( nMechListMICLen, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nMechListMICLen )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenTargLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the MechToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nMechTokenLen > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcElementLength( nMechTokenLen, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenTargLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Supported MechType
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( spnego_mech_oid_NotUsed != MechType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Supported MechOID element - we use the token function since
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // we already know the size of the OID token and value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenTargLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF MechType is available
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // NegResult Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( spnego_negresult_NotUsed != spnegoNegResult )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenTargLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF negResult is available
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Following two fields are the basic header tokens
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenTargLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Neg Token Identifier Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for rollover error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTempLength < nTotalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndTokenTargLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The internal length doesn't include the number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // for the initial token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnInternalTokenLength = nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength = nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We're done
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnTokenSize = nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowxEndTokenTargLength:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// CreateSpnegoTargToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] MechType - Supported MechType
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] eNegResult - NegResult value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbMechToken - Mech Token Binary Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulMechTokenLen - Length of Mech Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbMechListMIC - MechListMIC Binary Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulMechListMICn - Length of MechListMIC
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbTokenData - Buffer to write token into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nTokenLength - Length of pbTokenData buffer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nInternalTokenLength - Length of full token without leading
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// token bytes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Uses DER to fill out pbTokenData with a SPNEGO NegTokenTarg Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Note that because the lengths can be represented by an arbitrary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// number of bytes in DER encodings, we actually calculate the lengths
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// backwards, so we always know how many bytes we will potentially be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// writing out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint CreateSpnegoTargToken( SPNEGO_MECH_OID MechType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_NEGRESULT eNegResult, unsigned char* pbMechToken,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned long ulMechListMICLen, unsigned char* pbTokenData,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTokenLength, long nInternalTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Start at 0.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTempLength= 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTotalBytesWritten = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nInternalLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char ucTemp = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We will write the token out backwards to properly handle the cases
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // where the length bytes become adjustable, so the write location
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // is initialized to point *just* past the end of the buffer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbWriteTokenData = pbTokenData + nTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Start with MIC Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ulMechListMICLen > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow OCTETSTRING, pbMechListMIC, ulMechListMICLen );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenTarg;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF MechListMIC is present
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next is the MechToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ulMechTokenLen > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow OCTETSTRING, pbMechToken, ulMechTokenLen );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenTarg;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF MechToken Length is present
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Supported Mech Type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( spnego_mech_oid_NotUsed != MechType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow g_stcMechOIDList[MechType].ucOid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow g_stcMechOIDList[MechType].iLen );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenTarg;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF MechType is present
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Neg Result
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // NegResult Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( spnego_negresult_NotUsed != eNegResult )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ucTemp = (unsigned char) eNegResult;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ENUMERATED, &ucTemp, SPNEGO_NEGTARG_MAXLEN_NEGRESULT );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenTarg;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // If eNegResult is available
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next tokens we're writing out reflect the total number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // we have actually written out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL, nTotalBytesWritten );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nInternalTokenLength -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow goto xEndWriteNegTokenTarg;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Neg Targ Token Identifier Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Decrease the pbWriteTokenData, now we know the length and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // write it out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData -= nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL, nTotalBytesWritten );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust Values and sanity check
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWritten += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Don't adjust the internal token length here, it doesn't account
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // the initial bytes written out (we really don't need to keep
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // a running count here, but for debugging, it helps to be able
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // to see the total number of bytes written out as well as the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // number of bytes left to write).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbWriteTokenData == pbTokenData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowxEndWriteNegTokenTarg:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// AllocEmptySpnegoToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucCopyData - Flag to copy data or pointer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulFlags - Flags for SPNEGO_TOKEN data member.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Binary token data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulTokenSize - Size of pbTokenData.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// SPNEGO_TOKEN* Success - Pointer to initialized SPNEGO_TOKEN struct
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - NULL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Allocates a SPNEGO_TOKEN data structure and initializes it. Based on
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// the value of ucCopyData, if non-zero, we copy the data into a buffer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// we allocate in this function, otherwise, we copy the data pointer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// direcly.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowSPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulFlags,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char * pbTokenData, unsigned long ulTokenSize )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) calloc( 1, sizeof(SPNEGO_TOKEN) );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Set the token size
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the element array
4bff34e37def8a90f9194d81bc345c52ba20086athurlow InitSpnegoTokenElementArray( pSpnegoToken );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Assign the flags value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->ulFlags = ulFlags;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Otherwise, we will just copy the pointer and the length. This is so we
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // can cut out additional allocations for performance reasons
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Alloc the internal buffer. Cleanup on failure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->pbBinaryData = (unsigned char*) calloc( ulTokenSize, sizeof(unsigned char) );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pSpnegoToken->pbBinaryData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We must ALWAYS free this buffer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Copy the data locally
4bff34e37def8a90f9194d81bc345c52ba20086athurlow memcpy( pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->ulBinaryDataLen = ulTokenSize;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free( pSpnegoToken );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF ucCopyData
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Copy the pointer and the length directly - ulFlags will control whether or not
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // we are allowed to free the value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->pbBinaryData = pbTokenData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->ulBinaryDataLen = ulTokenSize;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return pSpnegoToken;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// FreeSpnegoToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN to free.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// void
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// If non-NULL, interprets pSpnegoToken, freeing any internal allocations
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// and finally the actual structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Cleanup internal allocation per the flags
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL != pSpnegoToken->pbBinaryData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free( pSpnegoToken->pbBinaryData );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->pbBinaryData = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free ( pSpnegoToken );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// InitSpnegoTokenElementArray
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// void
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Initializes the element array data member of a SPNEGO_TOKEN data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nCtr;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Set the number of elemnts
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->nNumElements = MAX_NUM_TOKEN_ELEMENTS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initially, all elements are unavailable
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow for ( nCtr = 0; nCtr < MAX_NUM_TOKEN_ELEMENTS; nCtr++ )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Set the element size as well
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->aElementArray[ nCtr ].nStructSize = SPNEGO_ELEMENT_SIZE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->aElementArray[ nCtr ].iElementPresent = SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// InitSpnegoTokenType
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnTokenLength - Filled out with total token length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnRemainingTokenLength - Filled out with remaining length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// after header is parsed
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] ppbFirstElement - Filled out with pointer to first
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// element after header info.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Walks the underlying binary data for a SPNEGO_TOKEN data structure
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// and determines the type of the underlying token based on token header
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// information.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long* pnRemainingTokenLength, unsigned char** ppbFirstElement )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_TOKEN;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nActualTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nBoundaryLength = pSpnegoToken->ulBinaryDataLen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbTokenData = pSpnegoToken->pbBinaryData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // First byte MUST be either an APP_CONSTRUCT or the NEGTARG_TOKEN_TARG
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_NEGINIT_APP_CONSTRUCT == *pbTokenData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Validate the above token - this will tell us the actual length of the token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // per the encoding (minus the actual token bytes)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L, nBoundaryLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pnTokenLength, &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the remaining token length value. This will be used
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // to tell the caller how much token there is left once we've parsed
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // the header (they could calculate it from the other values, but this
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // is a bit friendlier)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength = *pnTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make adjustments to next token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nBoundaryLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next token should be an OID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckOID( pbTokenData, spnego_mech_oid_Spnego, nBoundaryLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nActualTokenLength ) ) == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make adjustments to next token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nBoundaryLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next token should specify the NegTokenInit
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make adjustments to next token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nBoundaryLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next token should specify the start of a sequence
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // NegTokenInit header is now checked out!
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make adjustments to next token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Store pointer to first element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *ppbFirstElement = pbTokenData + nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Check Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Check NegTokenInit token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Check for SPNEGO OID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF check app construct token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else if ( SPNEGO_NEGTARG_TOKEN_IDENTIFIER == *pbTokenData )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next token should specify the NegTokenInit
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the remaining token length value. This will be used
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // to tell the caller how much token there is left once we've parsed
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // the header (they could calculate it from the other values, but this
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // is a bit friendlier)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength = *pnTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make adjustments to next token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nBoundaryLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The next token should specify the start of a sequence
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // NegTokenInit header is now checked out!
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make adjustments to next token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnRemainingTokenLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Store pointer to first element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *ppbFirstElement = pbTokenData + nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Check Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Check NegTokenInit token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // ELSE IF it's a NegTokenTarg
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// GetSpnegoInitTokenMechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Points to binary MechList element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// in NegTokenInit.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nMechListLength - Length of the MechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pSpnegoElement - Filled out with MechList Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks that pbTokenData is pointing at something that at least
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// *looks* like a MechList and then fills out the supplied
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// SPNEGO_ELEMENT structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_ELEMENT* pSpnegoElement )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_TOKEN;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nActualTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Actual MechList is prepended by a Constructed Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nMechListLength, nMechListLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nLength, &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust for this token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nMechListLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Perform simple validation of the actual MechList (i.e. ensure that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // the OIDs in the MechList are reasonable).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ValidateMechList( pbTokenData, nLength ) ) == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the element now
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->eElementType = spnego_init_mechtypes;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->nDatalength = nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->pbData = pbTokenData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Check Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// InitSpnegoTokenElementFromBasicType
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Points to binary element data in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// a SPNEGO token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nElementLength - Length of the element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucExpectedType - Expected DER type.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] spnegoElementType - Which element is this?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pSpnegoElement - Filled out with element data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks that pbTokenData is pointing at the specified DER type. If so,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// then we verify that lengths are proper and then fill out the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// SPNEGO_ELEMENT data structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char ucExpectedType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_ELEMENT_TYPE spnegoElementType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_ELEMENT* pSpnegoElement )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nActualTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The type BYTE must match our token data or something is badly wrong
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( *pbTokenData == ucExpectedType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check that we are pointing at the specified type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, ucExpectedType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nElementLength, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nLength, &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust for this token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nElementLength -= nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the element now
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->eElementType = spnegoElementType;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->type = ucExpectedType;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->nDatalength = nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->pbData = pbTokenData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF type makes sense
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// InitSpnegoTokenElementFromOID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Points to binary element data in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// a SPNEGO token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nElementLength - Length of the element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] spnegoElementType - Which element is this?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pSpnegoElement - Filled out with element data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Initializes a SpnegoElement from an OID - normally, this would have
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// used the Basic Type function above, but since we do binary compares
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// on the OIDs against the DER information as well as the OID, we need
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// to account for that.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_ELEMENT_TYPE spnegoElementType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_ELEMENT* pSpnegoElement )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nActualTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The type BYTE must match our token data or something is badly wrong
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( *pbTokenData == OID )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check that we are pointing at an OID type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, OID,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nElementLength, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nLength, &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Don't adjust any values for this function
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the element now
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->eElementType = spnegoElementType;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->type = OID;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->nDatalength = nElementLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoElement->pbData = pbTokenData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF type makes sense
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// InitSpnegoTokenElements
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN struct
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Points to initial binary element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// data in a SPNEGO token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nRemainingTokenLength - Length remaining past header
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Interprets the data at pbTokenData based on the TokenType in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// pSpnegoToken. Since some elements are optional (technically all are
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// but the token becomes quite useless if this is so), we check if
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// an element exists before filling out the element in the array.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenData,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nRemainingTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The following arrays contain the token identifiers for the elements
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // comprising the actual token. All values are optional, and there are
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // no defaults.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow static unsigned char abNegTokenInitElements[] =
4bff34e37def8a90f9194d81bc345c52ba20086athurlow { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC };
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow static unsigned char abNegTokenTargElements[] =
4bff34e37def8a90f9194d81bc345c52ba20086athurlow { SPNEGO_NEGTARG_ELEMENT_NEGRESULT, SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC };
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nCtr = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nElementLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nActualTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbElements = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Point to the correct array
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch( pSpnegoToken->ucTokenType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_TOKEN_INIT:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbElements = abNegTokenInitElements;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_TOKEN_TARG:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbElements = abNegTokenTargElements;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // SWITCH tokentype
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Enumerate the element arrays and look for the tokens at our current location
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow for ( nCtr = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_E_SUCCESS == nReturn &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nCtr < MAX_NUM_TOKEN_ELEMENTS &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nRemainingTokenLength > 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nCtr++ )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check if the token exists
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, pbElements[nCtr],
4bff34e37def8a90f9194d81bc345c52ba20086athurlow 0L, nRemainingTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nElementLength, &nActualTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Token data should skip over the sequence token and then
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // call the appropriate function to initialize the element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nActualTokenLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Lengths in the elements should NOT go beyond the element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Different tokens mean different elements
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Handle each element as appropriate
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch( pbElements[nCtr] )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGINIT_ELEMENT_MECHTYPES:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // This is a Mech List that specifies which OIDs the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // originator of the Init Token supports.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = GetSpnegoInitTokenMechList( pbTokenData, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &pSpnegoToken->aElementArray[nCtr] );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGINIT_ELEMENT_REQFLAGS:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // This is a BITSTRING which specifies the flags that the receiver
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // pass to the gss_accept_sec_context() function.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow BITSTRING, spnego_init_reqFlags,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &pSpnegoToken->aElementArray[nCtr] );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // This is an OCTETSTRING which contains a GSSAPI token corresponding
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // to the first OID in the MechList.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow OCTETSTRING, spnego_init_mechToken,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &pSpnegoToken->aElementArray[nCtr] );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC: // xA3
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Don't yet know if this is a negTokenInit, or negTokenInit2.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Unfortunately, both have the same type: SPNEGO_TOKEN_INIT
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // If it's negTokenInit, this element should be an OCTETSTRING
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // containing the MIC. If it's a negTokenInit2, this element
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // should be an SPNEGO_CONSTRUCTED_SEQUENCE containing the
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // negHints (GENERALSTR, ignored)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross OCTETSTRING, spnego_init_mechListMIC,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross &pSpnegoToken->aElementArray[nCtr] );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if (nReturn == SPNEGO_E_UNEXPECTED_TYPE) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // This is really a negHints element. Check the type and length,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // but otherwise just ignore it.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long elen, tlen;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nElementLength, nElementLength,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross &elen, &tlen );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // SWITCH Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross /* pSpnegoToken->ucTokenType == SPNEGO_TOKEN_TARG */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch( pbElements[nCtr] )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGTARG_ELEMENT_NEGRESULT:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // This is an ENUMERATION which specifies result of the last GSS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // token negotiation call.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ENUMERATED, spnego_targ_negResult,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &pSpnegoToken->aElementArray[nCtr] );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // This is an OID which specifies a supported mechanism.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromOID( pbTokenData, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow spnego_targ_mechListMIC,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &pSpnegoToken->aElementArray[nCtr] );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // This is an OCTETSTRING which specifies results of the last GSS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // token negotiation call.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow OCTETSTRING, spnego_targ_responseToken,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &pSpnegoToken->aElementArray[nCtr] );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // This is an OCTETSTRING, typically 16 bytes,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // which contains a message integrity BLOB.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross OCTETSTRING, spnego_targ_mechListMIC,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross &pSpnegoToken->aElementArray[nCtr] );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // SWITCH Element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // ELSE !NegTokenInit
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Account for the entire token and following data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nRemainingTokenLength -= ( nActualTokenLength + nElementLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Token data should skip past the element length now
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData += nElementLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Token found
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else if ( SPNEGO_E_TOKEN_NOT_FOUND == nReturn )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // For now, this is a benign error (remember, all elements are optional, so
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // if we don't find one, it's okay).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // FOR enum elements
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We should always run down to 0 remaining bytes in the token. If not, we've got
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // a bad token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_E_SUCCESS == nReturn && nRemainingTokenLength != 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_INVALID_TOKEN;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// FindMechOIDInMechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoElement - SPNEGO_ELEMENT for MechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] MechOID - OID we're looking for.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] piMechTypeIndex - Index in the list where OID was
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// found
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Walks the MechList for MechOID. When it is found, the index in the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// list is written to piMechTypeIndex.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechOID,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int * piMechTypeIndex )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_NOT_FOUND;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nCtr = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nBoundaryLength = pSpnegoElement->nDatalength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbMechListData = pSpnegoElement->pbData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while( SPNEGO_E_SUCCESS != nReturn && nBoundaryLength > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Use the helper function to check the OID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckOID( pbMechListData, MechOID, nBoundaryLength, &nLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *piMechTypeIndex = nCtr;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust for the current OID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbMechListData += nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nBoundaryLength -= nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nCtr++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // WHILE enuming OIDs
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ValidateMechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbMechListData - Pointer to binary MechList data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nBoundaryLength - Length we must not exceed
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks the data at pbMechListData to see if it looks like a MechList.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// As part of this, we walk the list and ensure that none of the OIDs
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// have a length that takes us outside of nBoundaryLength.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while( SPNEGO_E_SUCCESS == nReturn && nBoundaryLength > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Verify that we have something that at least *looks* like an OID - in other
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // words it has an OID identifier and specifies a length that doesn't go beyond
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // the size of the list.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = ASNDerCheckToken( pbMechListData, OID, 0L, nBoundaryLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nLength, &nTokenLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust for the current OID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbMechListData += ( nLength + nTokenLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nBoundaryLength -= ( nLength + nTokenLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // WHILE enuming OIDs
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// IsValidMechOid
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] mechOid - mechOID id enumeration
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - 1
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - 0
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks for a valid mechOid value.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint IsValidMechOid( SPNEGO_MECH_OID mechOid )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return ( mechOid >= spnego_mech_oid_Kerberos_V5_Legacy &&
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mechOid <= spnego_mech_oid_NTLMSSP );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// IsValidContextFlags
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucContextFlags - ContextFlags value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - 1
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - 0
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks for a valid ContextFlags value.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint IsValidContextFlags( unsigned char ucContextFlags )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Mask out our valid bits. If there is anything leftover, this
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // is not a valid value for Context Flags
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return ( ( ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK ) == 0 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// IsValidNegResult
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] negResult - NegResult value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - 1
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - 0
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks for a valid NegResult value.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint IsValidNegResult( SPNEGO_NEGRESULT negResult )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return ( negResult >= spnego_negresult_success &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow negResult <= spnego_negresult_rejected );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// IsValidSpnegoToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - 1
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - 0
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Performs simple heuristic on location pointed to by pSpnegoToken.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Parameter should be non-NULL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Length should be at least the size defined in the header
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Number of elements should be >= our maximum - if it's greater, that's
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for proper token type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF struct size makes sense
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF non-NULL spnego Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// IsValidSpnegoElement
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] spnegoElement - spnegoElement Type from enumeration
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - 1
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - 0
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks that spnegoElement has a valid value and is appropriate for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// the SPNEGO token encapsulated by pSpnegoToken.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check boundaries
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( spnegoElement > spnego_element_min &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow spnegoElement < spnego_element_max )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check for appropriateness to token type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = ( spnegoElement >= spnego_init_mechtypes &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow spnegoElement <= spnego_init_mechListMIC );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = ( spnegoElement >= spnego_targ_negResult &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow spnegoElement <= spnego_targ_mechListMIC );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF boundary conditions are met
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// CalculateElementArrayIndex
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] spnegoElement - spnegoElement Type from enumeration
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int index in the SPNEGO_TOKEN element array that the element can
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// can be found
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Based on the Token Type, calculates the index in the element array
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// at which the specified element can be found.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Offset is difference between value and initial element identifier
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // (these differ based on ucTokenType)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = spnegoElement - spnego_init_mechtypes;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = spnegoElement - spnego_targ_negResult;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// InitTokenFromBinary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucCopyData - Flag indicating if data should be copied
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulFlags - Flags value for structure
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pnTokenData - Binary Token Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ulLength - Length of the data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] ppSpnegoToken - Pointer to call allocated SPNEGO Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// data structure
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Allocates a SPNEGO_TOKEN data structure and fills it out as
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// appropriate based in the flags passed into the function.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Initializes SPNEGO_TOKEN structure from DER encoded binary data
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint InitTokenFromBinary( unsigned char ucCopyData, unsigned long ulFlags,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbTokenData, unsigned long ulLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_TOKEN** ppSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_PARAMETER;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SPNEGO_TOKEN* pSpnegoToken = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbFirstElement = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nRemainingTokenLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Basic Parameter Validation
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pbTokenData &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL != ppSpnegoToken &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow 0L != ulLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Allocate the empty token, then initialize the data structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow //
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pSpnegoToken = AllocEmptySpnegoToken( ucCopyData, ulFlags, pbTokenData, ulLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pSpnegoToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Copy the binary data locally
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the token type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = InitSpnegoTokenType( pSpnegoToken, &nTokenLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nRemainingTokenLength, &pbFirstElement ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Initialize the element array
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = InitSpnegoTokenElements( pSpnegoToken, pbFirstElement,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nRemainingTokenLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *ppSpnegoToken = pSpnegoToken;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Init Token Type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Cleanup on error condition
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_E_SUCCESS != nReturn )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow spnegoFreeData( pSpnegoToken );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_OUT_OF_MEMORY;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Valid parameters
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}