?? spnegoparse.c
字號:
// Copyright (C) 2002 Microsoft Corporation// All rights reserved.//// THIS CODE AND INFORMATION IS PROVIDED "AS IS"// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED// OR IMPLIED, INCLUDING BUT NOT LIMITED// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY// AND/OR FITNESS FOR A PARTICULAR PURPOSE.//// Date - 10/08/2002// Author - Sanj Surati///////////////////////////////////////////////////////////////// SPNEGOPARSE.C//// SPNEGO Token Handler Source File//// Contains implementation of SPNEGO Token parsing functions.///////////////////////////////////////////////////////////////#include <stdlib.h>#include <stdio.h>#include <memory.h>#include "spnego.h"#include "derparse.h"#include "spnegoparse.h"//// Defined in DERPARSE.C//extern MECH_OID g_stcMechOIDList [];/**********************************************************************//** **//** **//** **//** **//** Local SPNEGO Helper definitions **//** **//** **//** **//** **//**********************************************************************////////////////////////////////////////////////////////////////////////////////// Function:// CalculateMinSpnegoInitTokenSize//// Parameters:// [in] nMechTokenLength - Length of the MechToken Element// [in] nMechListMICLength - Length of the MechListMIC Element// [in] mechOID - OID for MechList// [in] nReqFlagsAvailable - Is ContextFlags element available// [out] pnTokenSize - Filled out with total size of token// [out] pnInternalTokenLength - Filled out with length minus length// for initial token.//// Returns:// int Success - SPNEGO_E_SUCCESS// Failure - SPNEGO API Error code//// Comments :// Calculates the required length for a SPNEGO NegTokenInit token based// on the supplied variable length values and which elements are present.// Note that because the lengths can be represented by an arbitrary// number of bytes in DER encodings, we actually calculate the lengths// backwards, so we always know how many bytes we will potentially be// writing out.//////////////////////////////////////////////////////////////////////////////int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, long nMechListMICLength, SPNEGO_MECH_OID mechOid, int nReqFlagsAvailable, long* pnTokenSize, long* pnInternalTokenLength ){ int nReturn = SPNEGO_E_INVALID_LENGTH; // Start at 0. long nTotalLength = 0; long nTempLength= 0L; // We will calculate this by walking the token backwards // Start with MIC Element if ( nMechListMICLength > 0L ) { nTempLength = ASNDerCalcElementLength( nMechListMICLength, NULL ); // Check for rollover error if ( nTempLength < nMechListMICLength ) { goto xEndTokenInitLength; } nTotalLength += nTempLength; } // Next is the MechToken if ( nMechTokenLength > 0L ) { nTempLength += ASNDerCalcElementLength( nMechTokenLength, NULL ); // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } nTotalLength = nTempLength; } // Next is the ReqFlags if ( nReqFlagsAvailable ) { nTempLength += ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL ); // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } nTotalLength = nTempLength; } // Next is the MechList - This is REQUIRED nTempLength += ASNDerCalcMechListLength( mechOid, NULL ); // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } nTotalLength = nTempLength; // Following four fields are the basic header tokens // Sequence Token nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L ); // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } nTotalLength = nTempLength; // Neg Token Identifier Token nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L ); // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } nTotalLength = nTempLength; // SPNEGO OID Token nTempLength += g_stcMechOIDList[spnego_mech_oid_Spnego].iLen; // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } nTotalLength = nTempLength; // App Constructed Token nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L ); // Check for rollover error if ( nTempLength < nTotalLength ) { goto xEndTokenInitLength; } // The internal length doesn't include the number of bytes // for the initial token *pnInternalTokenLength = nTotalLength; nTotalLength = nTempLength; // We're done *pnTokenSize = nTotalLength; nReturn = SPNEGO_E_SUCCESS;xEndTokenInitLength: LOG(("CalculateMinSpnegoInitTokenSize returned %d\n",nReturn)); return nReturn;}///////////////////////////////////////////////////////////////////////////////// Function:// CreateSpnegoInitToken//// Parameters:// [in] MechType - OID in MechList// [in] ucContextFlags - ContextFlags value// [in] pbMechToken - Mech Token Binary Data// [in] ulMechTokenLen - Length of Mech Token// [in] pbMechListMIC - MechListMIC Binary Data// [in] ulMechListMICn - Length of MechListMIC// [out] pbTokenData - Buffer to write token into.// [in] nTokenLength - Length of pbTokenData buffer// [in] nInternalTokenLength - Length of full token without leading// token bytes.//// Returns:// int Success - SPNEGO_E_SUCCESS// Failure - SPNEGO API Error code//// Comments :// Uses DER to fill out pbTokenData with a SPNEGO NegTokenInit Token// Note that because the lengths can be represented by an arbitrary// number of bytes in DER encodings, we actually calculate the lengths// backwards, so we always know how many bytes we will potentially be// writing out.//////////////////////////////////////////////////////////////////////////////int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType, unsigned char ucContextFlags, unsigned char* pbMechToken, unsigned long ulMechTokenLen, unsigned char* pbMechListMIC, unsigned long ulMechListMICLen, unsigned char* pbTokenData, long nTokenLength, long nInternalTokenLength ){ int nReturn = SPNEGO_E_INVALID_LENGTH; // Start at 0. long nTempLength= 0L; long nTotalBytesWritten = 0L; long nInternalLength = 0L; unsigned char* pbWriteTokenData = pbTokenData + nTokenLength; // Temporary buffer to hold the REQ Flags as BIT String Data unsigned char abTempReqFlags[SPNEGO_NEGINIT_MAXLEN_REQFLAGS]; // We will write the token out backwards to properly handle the cases // where the length bytes become adjustable // Start with MIC Element if ( ulMechListMICLen > 0L ) { nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength ); // Decrease the pbWriteTokenData, now we know the length and // write it out. pbWriteTokenData -= nTempLength; nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC, ulMechListMICLen ); // Adjust Values and sanity check nTotalBytesWritten += nTempLength; nInternalTokenLength -= nTempLength; if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { goto xEndWriteNegTokenInit; } } // IF MechListMIC is present // Next is the MechToken if ( ulMechTokenLen > 0L ) { nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength ); // Decrease the pbWriteTokenData, now we know the length and // write it out. pbWriteTokenData -= nTempLength; nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, OCTETSTRING, pbMechToken, ulMechTokenLen ); // Adjust Values and sanity check nTotalBytesWritten += nTempLength; nInternalTokenLength -= nTempLength; if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { goto xEndWriteNegTokenInit; } } // IF MechToken Length is present // Next is the ReqFlags if ( ucContextFlags > 0L ) { nTempLength = ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, &nInternalLength ); // We need a byte that indicates how many bits difference between the number // of bits used in final octet (we only have one) and the max (8) abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF; abTempReqFlags[1] = ucContextFlags; // Decrease the pbWriteTokenData, now we know the length and // write it out. pbWriteTokenData -= nTempLength; nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_REQFLAGS, BITSTRING, abTempReqFlags, SPNEGO_NEGINIT_MAXLEN_REQFLAGS ); // Adjust Values and sanity check nTotalBytesWritten += nTempLength; nInternalTokenLength -= nTempLength; if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { goto xEndWriteNegTokenInit; } } // IF ContextFlags // Next is the MechList - This is REQUIRED nTempLength = ASNDerCalcMechListLength( MechType, &nInternalLength ); // Decrease the pbWriteTokenData, now we know the length and // write it out. pbWriteTokenData -= nTempLength; nTempLength = ASNDerWriteMechList( pbWriteTokenData, MechType ); // Adjust Values and sanity check nTotalBytesWritten += nTempLength; nInternalTokenLength -= nTempLength; if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { goto xEndWriteNegTokenInit; } // The next tokens we're writing out reflect the total number of bytes // we have actually written out. // Sequence Token nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L ); // Decrease the pbWriteTokenData, now we know the length and // write it out. pbWriteTokenData -= nTempLength; nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL, nTotalBytesWritten ); // Adjust Values and sanity check nTotalBytesWritten += nTempLength; nInternalTokenLength -= nTempLength; if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 ) { goto xEndWriteNegTokenInit; } // Neg Init Token Identifier Token nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L ); // Decrease the pbWriteTokenData, now we know the length and // write it out. pbWriteTokenData -= nTempLength; nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER, NULL, nTotalBytesWritten ); // Adjust Values and sanity check nTotalBytesWritten += nTempLength; nInternalTokenLength -= nTempLength;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -