1*4bff34e3Sthurlow // Copyright (C) 2002 Microsoft Corporation 2*4bff34e3Sthurlow // All rights reserved. 3*4bff34e3Sthurlow // 4*4bff34e3Sthurlow // THIS CODE AND INFORMATION IS PROVIDED "AS IS" 5*4bff34e3Sthurlow // WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 6*4bff34e3Sthurlow // OR IMPLIED, INCLUDING BUT NOT LIMITED 7*4bff34e3Sthurlow // TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY 8*4bff34e3Sthurlow // AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9*4bff34e3Sthurlow // 10*4bff34e3Sthurlow // Date - 10/08/2002 11*4bff34e3Sthurlow // Author - Sanj Surati 12*4bff34e3Sthurlow 13*4bff34e3Sthurlow ///////////////////////////////////////////////////////////// 14*4bff34e3Sthurlow // 15*4bff34e3Sthurlow // SPNEGO.C 16*4bff34e3Sthurlow // 17*4bff34e3Sthurlow // SPNEGO Token Handler Source File 18*4bff34e3Sthurlow // 19*4bff34e3Sthurlow // Contains implementation of SPNEGO Token Handling API 20*4bff34e3Sthurlow // as defined in SPNEGO.H. 21*4bff34e3Sthurlow // 22*4bff34e3Sthurlow ///////////////////////////////////////////////////////////// 23*4bff34e3Sthurlow 24*4bff34e3Sthurlow #pragma ident "%Z%%M% %I% %E% SMI" 25*4bff34e3Sthurlow 26*4bff34e3Sthurlow #include <stdlib.h> 27*4bff34e3Sthurlow #include <stdio.h> 28*4bff34e3Sthurlow #include <memory.h> 29*4bff34e3Sthurlow #include "spnego.h" 30*4bff34e3Sthurlow #include "derparse.h" 31*4bff34e3Sthurlow #include "spnegoparse.h" 32*4bff34e3Sthurlow 33*4bff34e3Sthurlow // 34*4bff34e3Sthurlow // Defined in DERPARSE.C 35*4bff34e3Sthurlow // 36*4bff34e3Sthurlow 37*4bff34e3Sthurlow extern MECH_OID g_stcMechOIDList []; 38*4bff34e3Sthurlow 39*4bff34e3Sthurlow 40*4bff34e3Sthurlow /**********************************************************************/ 41*4bff34e3Sthurlow /** **/ 42*4bff34e3Sthurlow /** **/ 43*4bff34e3Sthurlow /** **/ 44*4bff34e3Sthurlow /** **/ 45*4bff34e3Sthurlow /** SPNEGO Token Handler API implementation **/ 46*4bff34e3Sthurlow /** **/ 47*4bff34e3Sthurlow /** **/ 48*4bff34e3Sthurlow /** **/ 49*4bff34e3Sthurlow /** **/ 50*4bff34e3Sthurlow /**********************************************************************/ 51*4bff34e3Sthurlow 52*4bff34e3Sthurlow 53*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 54*4bff34e3Sthurlow // 55*4bff34e3Sthurlow // Function: 56*4bff34e3Sthurlow // spnegoInitFromBinary 57*4bff34e3Sthurlow // 58*4bff34e3Sthurlow // Parameters: 59*4bff34e3Sthurlow // [in] pbTokenData - Binary Token Data 60*4bff34e3Sthurlow // [in] ulLength - Length of binary Token Data 61*4bff34e3Sthurlow // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 62*4bff34e3Sthurlow // 63*4bff34e3Sthurlow // Returns: 64*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 65*4bff34e3Sthurlow // Failure - SPNEGO API Error code 66*4bff34e3Sthurlow // 67*4bff34e3Sthurlow // Comments : 68*4bff34e3Sthurlow // Initializes a SPNEGO_TOKEN_HANDLE from the supplied 69*4bff34e3Sthurlow // binary data. Data is copied locally. Returned data structure 70*4bff34e3Sthurlow // must be freed by calling spnegoFreeData(). 71*4bff34e3Sthurlow // 72*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 73*4bff34e3Sthurlow 74*4bff34e3Sthurlow int spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 75*4bff34e3Sthurlow { 76*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 77*4bff34e3Sthurlow SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 78*4bff34e3Sthurlow 79*4bff34e3Sthurlow // Pass off to a handler function that allows tighter control over how the token structure 80*4bff34e3Sthurlow // is handled. In this case, we want the token data copied and we want the associated buffer 81*4bff34e3Sthurlow // freed. 82*4bff34e3Sthurlow nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYDATA, 83*4bff34e3Sthurlow SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData, 84*4bff34e3Sthurlow ulLength, ppSpnegoToken ); 85*4bff34e3Sthurlow 86*4bff34e3Sthurlow return nReturn; 87*4bff34e3Sthurlow } 88*4bff34e3Sthurlow 89*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 90*4bff34e3Sthurlow // 91*4bff34e3Sthurlow // Function: 92*4bff34e3Sthurlow // spnegoCreateNegTokenInit 93*4bff34e3Sthurlow // 94*4bff34e3Sthurlow // Parameters: 95*4bff34e3Sthurlow // [in] MechType - MechType to specify in MechTypeList element 96*4bff34e3Sthurlow // [in] ucContextFlags - Context Flags element value 97*4bff34e3Sthurlow // [in] pbMechToken - Pointer to binary MechToken Data 98*4bff34e3Sthurlow // [in] ulMechTokenLen - Length of MechToken Data 99*4bff34e3Sthurlow // [in] pbMechListMIC - Pointer to binary MechListMIC Data 100*4bff34e3Sthurlow // [in] ulMechListMICLen - Length of MechListMIC Data 101*4bff34e3Sthurlow // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 102*4bff34e3Sthurlow // 103*4bff34e3Sthurlow // Returns: 104*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 105*4bff34e3Sthurlow // Failure - SPNEGO API Error code 106*4bff34e3Sthurlow // 107*4bff34e3Sthurlow // Comments : 108*4bff34e3Sthurlow // Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenInit type 109*4bff34e3Sthurlow // from the supplied parameters. ucContextFlags may be 0 or must be 110*4bff34e3Sthurlow // a valid flag combination. MechToken data can be NULL - if not, it 111*4bff34e3Sthurlow // must correspond to the MechType. MechListMIC can also be NULL. 112*4bff34e3Sthurlow // Returned data structure must be freed by calling spnegoFreeData(). 113*4bff34e3Sthurlow // 114*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 115*4bff34e3Sthurlow 116*4bff34e3Sthurlow int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType, 117*4bff34e3Sthurlow unsigned char ucContextFlags, unsigned char* pbMechToken, 118*4bff34e3Sthurlow unsigned long ulMechTokenLen, unsigned char* pbMechListMIC, 119*4bff34e3Sthurlow unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 120*4bff34e3Sthurlow { 121*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 122*4bff34e3Sthurlow long nTokenLength = 0L; 123*4bff34e3Sthurlow long nInternalTokenLength = 0L; 124*4bff34e3Sthurlow unsigned char* pbTokenData = NULL; 125*4bff34e3Sthurlow SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 126*4bff34e3Sthurlow 127*4bff34e3Sthurlow if ( NULL != ppSpnegoToken && 128*4bff34e3Sthurlow IsValidMechOid( MechType ) && 129*4bff34e3Sthurlow IsValidContextFlags( ucContextFlags ) ) 130*4bff34e3Sthurlow { 131*4bff34e3Sthurlow // Get the actual token size 132*4bff34e3Sthurlow 133*4bff34e3Sthurlow if ( ( nReturn = CalculateMinSpnegoInitTokenSize( ulMechTokenLen, ulMechListMICLen, 134*4bff34e3Sthurlow MechType, ( ucContextFlags != 0L ), 135*4bff34e3Sthurlow &nTokenLength, &nInternalTokenLength ) ) 136*4bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 137*4bff34e3Sthurlow { 138*4bff34e3Sthurlow // Allocate a buffer to hold the data. 139*4bff34e3Sthurlow pbTokenData = calloc( 1, nTokenLength ); 140*4bff34e3Sthurlow 141*4bff34e3Sthurlow if ( NULL != pbTokenData ) 142*4bff34e3Sthurlow { 143*4bff34e3Sthurlow 144*4bff34e3Sthurlow // Now write the token 145*4bff34e3Sthurlow if ( ( nReturn = CreateSpnegoInitToken( MechType, 146*4bff34e3Sthurlow ucContextFlags, pbMechToken, 147*4bff34e3Sthurlow ulMechTokenLen, pbMechListMIC, 148*4bff34e3Sthurlow ulMechListMICLen, pbTokenData, 149*4bff34e3Sthurlow nTokenLength, nInternalTokenLength ) ) 150*4bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 151*4bff34e3Sthurlow { 152*4bff34e3Sthurlow 153*4bff34e3Sthurlow // This will copy our allocated pointer, and ensure that the sructure cleans 154*4bff34e3Sthurlow // up the data later 155*4bff34e3Sthurlow nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR, 156*4bff34e3Sthurlow SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, 157*4bff34e3Sthurlow pbTokenData, nTokenLength, ppSpnegoToken ); 158*4bff34e3Sthurlow 159*4bff34e3Sthurlow } 160*4bff34e3Sthurlow 161*4bff34e3Sthurlow // Cleanup on failure 162*4bff34e3Sthurlow if ( SPNEGO_E_SUCCESS != nReturn ) 163*4bff34e3Sthurlow { 164*4bff34e3Sthurlow free( pbTokenData ); 165*4bff34e3Sthurlow } 166*4bff34e3Sthurlow 167*4bff34e3Sthurlow } // IF alloc succeeded 168*4bff34e3Sthurlow else 169*4bff34e3Sthurlow { 170*4bff34e3Sthurlow nReturn = SPNEGO_E_OUT_OF_MEMORY; 171*4bff34e3Sthurlow } 172*4bff34e3Sthurlow 173*4bff34e3Sthurlow } // If calculated token size 174*4bff34e3Sthurlow 175*4bff34e3Sthurlow } // IF Valid Parameters 176*4bff34e3Sthurlow 177*4bff34e3Sthurlow return nReturn; 178*4bff34e3Sthurlow } 179*4bff34e3Sthurlow 180*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 181*4bff34e3Sthurlow // 182*4bff34e3Sthurlow // Function: 183*4bff34e3Sthurlow // spnegoCreateNegTokenTarg 184*4bff34e3Sthurlow // 185*4bff34e3Sthurlow // Parameters: 186*4bff34e3Sthurlow // [in] MechType - MechType to specify in supported MechType element 187*4bff34e3Sthurlow // [in] spnegoNegResult - NegResult value 188*4bff34e3Sthurlow // [in] pbMechToken - Pointer to response MechToken Data 189*4bff34e3Sthurlow // [in] ulMechTokenLen - Length of MechToken Data 190*4bff34e3Sthurlow // [in] pbMechListMIC - Pointer to binary MechListMIC Data 191*4bff34e3Sthurlow // [in] ulMechListMICLen - Length of MechListMIC Data 192*4bff34e3Sthurlow // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 193*4bff34e3Sthurlow // 194*4bff34e3Sthurlow // Returns: 195*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 196*4bff34e3Sthurlow // Failure - SPNEGO API Error code 197*4bff34e3Sthurlow // 198*4bff34e3Sthurlow // Comments : 199*4bff34e3Sthurlow // Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenTarg type 200*4bff34e3Sthurlow // from the supplied parameters. MechToken data can be NULL - if not, 201*4bff34e3Sthurlow // it must correspond to the MechType. MechListMIC can also be NULL. 202*4bff34e3Sthurlow // Returned data structure must be freed by calling spnegoFreeData(). 203*4bff34e3Sthurlow // 204*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 205*4bff34e3Sthurlow 206*4bff34e3Sthurlow int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType, 207*4bff34e3Sthurlow SPNEGO_NEGRESULT spnegoNegResult, unsigned char* pbMechToken, 208*4bff34e3Sthurlow unsigned long ulMechTokenLen, unsigned char* pbMechListMIC, 209*4bff34e3Sthurlow unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 210*4bff34e3Sthurlow { 211*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 212*4bff34e3Sthurlow long nTokenLength = 0L; 213*4bff34e3Sthurlow long nInternalTokenLength = 0L; 214*4bff34e3Sthurlow unsigned char* pbTokenData = NULL; 215*4bff34e3Sthurlow SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 216*4bff34e3Sthurlow 217*4bff34e3Sthurlow // 218*4bff34e3Sthurlow // spnego_mech_oid_NotUsed and spnego_negresult_NotUsed 219*4bff34e3Sthurlow // are okay here, however a valid MechOid is required 220*4bff34e3Sthurlow // if spnego_negresult_success or spnego_negresult_incomplete 221*4bff34e3Sthurlow // is specified. 222*4bff34e3Sthurlow // 223*4bff34e3Sthurlow 224*4bff34e3Sthurlow if ( NULL != ppSpnegoToken && 225*4bff34e3Sthurlow 226*4bff34e3Sthurlow ( IsValidMechOid( MechType ) || 227*4bff34e3Sthurlow spnego_mech_oid_NotUsed == MechType ) && 228*4bff34e3Sthurlow 229*4bff34e3Sthurlow ( IsValidNegResult( spnegoNegResult ) || 230*4bff34e3Sthurlow spnego_negresult_NotUsed == spnegoNegResult ) && 231*4bff34e3Sthurlow 232*4bff34e3Sthurlow !( !IsValidMechOid( MechType ) && 233*4bff34e3Sthurlow ( spnego_negresult_success == spnegoNegResult || 234*4bff34e3Sthurlow spnego_negresult_incomplete == spnegoNegResult ) ) ) 235*4bff34e3Sthurlow { 236*4bff34e3Sthurlow 237*4bff34e3Sthurlow // Get the actual token size 238*4bff34e3Sthurlow 239*4bff34e3Sthurlow if ( ( nReturn = CalculateMinSpnegoTargTokenSize( MechType, spnegoNegResult, ulMechTokenLen, 240*4bff34e3Sthurlow ulMechListMICLen, &nTokenLength, 241*4bff34e3Sthurlow &nInternalTokenLength ) ) 242*4bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 243*4bff34e3Sthurlow { 244*4bff34e3Sthurlow // Allocate a buffer to hold the data. 245*4bff34e3Sthurlow pbTokenData = calloc( 1, nTokenLength ); 246*4bff34e3Sthurlow 247*4bff34e3Sthurlow if ( NULL != pbTokenData ) 248*4bff34e3Sthurlow { 249*4bff34e3Sthurlow 250*4bff34e3Sthurlow // Now write the token 251*4bff34e3Sthurlow if ( ( nReturn = CreateSpnegoTargToken( MechType, 252*4bff34e3Sthurlow spnegoNegResult, pbMechToken, 253*4bff34e3Sthurlow ulMechTokenLen, pbMechListMIC, 254*4bff34e3Sthurlow ulMechListMICLen, pbTokenData, 255*4bff34e3Sthurlow nTokenLength, nInternalTokenLength ) ) 256*4bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 257*4bff34e3Sthurlow { 258*4bff34e3Sthurlow 259*4bff34e3Sthurlow // This will copy our allocated pointer, and ensure that the sructure cleans 260*4bff34e3Sthurlow // up the data later 261*4bff34e3Sthurlow nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR, 262*4bff34e3Sthurlow SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, 263*4bff34e3Sthurlow pbTokenData, nTokenLength, ppSpnegoToken ); 264*4bff34e3Sthurlow 265*4bff34e3Sthurlow } 266*4bff34e3Sthurlow 267*4bff34e3Sthurlow // Cleanup on failure 268*4bff34e3Sthurlow if ( SPNEGO_E_SUCCESS != nReturn ) 269*4bff34e3Sthurlow { 270*4bff34e3Sthurlow free( pbTokenData ); 271*4bff34e3Sthurlow } 272*4bff34e3Sthurlow 273*4bff34e3Sthurlow } // IF alloc succeeded 274*4bff34e3Sthurlow else 275*4bff34e3Sthurlow { 276*4bff34e3Sthurlow nReturn = SPNEGO_E_OUT_OF_MEMORY; 277*4bff34e3Sthurlow } 278*4bff34e3Sthurlow 279*4bff34e3Sthurlow } // If calculated token size 280*4bff34e3Sthurlow 281*4bff34e3Sthurlow } // IF Valid Parameters 282*4bff34e3Sthurlow 283*4bff34e3Sthurlow return nReturn; 284*4bff34e3Sthurlow } 285*4bff34e3Sthurlow 286*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 287*4bff34e3Sthurlow // 288*4bff34e3Sthurlow // Function: 289*4bff34e3Sthurlow // spnegoTokenGetBinary 290*4bff34e3Sthurlow // 291*4bff34e3Sthurlow // Parameters: 292*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 293*4bff34e3Sthurlow // [out] pbTokenData - Buffer to copy token into 294*4bff34e3Sthurlow // [in/out] pulDataLen - Length of pbTokenData buffer, filled out 295*4bff34e3Sthurlow // with actual size used upon function return. 296*4bff34e3Sthurlow // 297*4bff34e3Sthurlow // Returns: 298*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 299*4bff34e3Sthurlow // Failure - SPNEGO API Error code 300*4bff34e3Sthurlow // 301*4bff34e3Sthurlow // Comments : 302*4bff34e3Sthurlow // Copies binary SPNEGO token data from hSpnegoToken into the user 303*4bff34e3Sthurlow // supplied buffer. If pbTokenData is NULL, or the value in pulDataLen 304*4bff34e3Sthurlow // is too small, the function will return SPNEGO_E_BUFFER_TOO_SMALL and 305*4bff34e3Sthurlow // fill out pulDataLen with the minimum required buffer size. 306*4bff34e3Sthurlow // 307*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 308*4bff34e3Sthurlow 309*4bff34e3Sthurlow int spnegoTokenGetBinary( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, 310*4bff34e3Sthurlow unsigned long * pulDataLen ) 311*4bff34e3Sthurlow { 312*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 313*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 314*4bff34e3Sthurlow 315*4bff34e3Sthurlow // Check parameters - pbTokenData is optional 316*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 317*4bff34e3Sthurlow NULL != pulDataLen ) 318*4bff34e3Sthurlow { 319*4bff34e3Sthurlow 320*4bff34e3Sthurlow // Check for Buffer too small conditions 321*4bff34e3Sthurlow if ( NULL == pbTokenData || 322*4bff34e3Sthurlow pSpnegoToken->ulBinaryDataLen > *pulDataLen ) 323*4bff34e3Sthurlow { 324*4bff34e3Sthurlow *pulDataLen = pSpnegoToken->ulBinaryDataLen; 325*4bff34e3Sthurlow nReturn = SPNEGO_E_BUFFER_TOO_SMALL; 326*4bff34e3Sthurlow } 327*4bff34e3Sthurlow else 328*4bff34e3Sthurlow { 329*4bff34e3Sthurlow memcpy( pbTokenData, pSpnegoToken->pbBinaryData, pSpnegoToken->ulBinaryDataLen ); 330*4bff34e3Sthurlow *pulDataLen = pSpnegoToken->ulBinaryDataLen; 331*4bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 332*4bff34e3Sthurlow } 333*4bff34e3Sthurlow 334*4bff34e3Sthurlow } // IF parameters OK 335*4bff34e3Sthurlow 336*4bff34e3Sthurlow return nReturn;; 337*4bff34e3Sthurlow } 338*4bff34e3Sthurlow 339*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 340*4bff34e3Sthurlow // 341*4bff34e3Sthurlow // Function: 342*4bff34e3Sthurlow // spnegoFreeData 343*4bff34e3Sthurlow // 344*4bff34e3Sthurlow // Parameters: 345*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 346*4bff34e3Sthurlow // 347*4bff34e3Sthurlow // Returns: 348*4bff34e3Sthurlow // void 349*4bff34e3Sthurlow // 350*4bff34e3Sthurlow // Comments : 351*4bff34e3Sthurlow // Frees up resources consumed by hSpnegoToken. The supplied data 352*4bff34e3Sthurlow // pointer is invalidated by this function. 353*4bff34e3Sthurlow // 354*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 355*4bff34e3Sthurlow 356*4bff34e3Sthurlow void spnegoFreeData( SPNEGO_TOKEN_HANDLE hSpnegoToken ) 357*4bff34e3Sthurlow { 358*4bff34e3Sthurlow FreeSpnegoToken( (SPNEGO_TOKEN*) hSpnegoToken); 359*4bff34e3Sthurlow return; 360*4bff34e3Sthurlow } 361*4bff34e3Sthurlow 362*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 363*4bff34e3Sthurlow // 364*4bff34e3Sthurlow // Function: 365*4bff34e3Sthurlow // spnegoGetTokenType 366*4bff34e3Sthurlow // 367*4bff34e3Sthurlow // Parameters: 368*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 369*4bff34e3Sthurlow // [out] piTokenType - Filled out with token type value. 370*4bff34e3Sthurlow // 371*4bff34e3Sthurlow // Returns: 372*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 373*4bff34e3Sthurlow // Failure - SPNEGO API Error code 374*4bff34e3Sthurlow // 375*4bff34e3Sthurlow // Comments : 376*4bff34e3Sthurlow // The function will analyze hSpnegoToken and return the appropriate 377*4bff34e3Sthurlow // type in piTokenType. 378*4bff34e3Sthurlow // 379*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 380*4bff34e3Sthurlow 381*4bff34e3Sthurlow int spnegoGetTokenType( SPNEGO_TOKEN_HANDLE hSpnegoToken, int * piTokenType ) 382*4bff34e3Sthurlow { 383*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 384*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 385*4bff34e3Sthurlow 386*4bff34e3Sthurlow // Check parameters 387*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 388*4bff34e3Sthurlow NULL != piTokenType && 389*4bff34e3Sthurlow pSpnegoToken) 390*4bff34e3Sthurlow { 391*4bff34e3Sthurlow 392*4bff34e3Sthurlow // Check that the type in the structure makes sense 393*4bff34e3Sthurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType || 394*4bff34e3Sthurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) 395*4bff34e3Sthurlow { 396*4bff34e3Sthurlow *piTokenType = pSpnegoToken->ucTokenType; 397*4bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 398*4bff34e3Sthurlow } 399*4bff34e3Sthurlow 400*4bff34e3Sthurlow } // IF parameters OK 401*4bff34e3Sthurlow 402*4bff34e3Sthurlow return nReturn; 403*4bff34e3Sthurlow } 404*4bff34e3Sthurlow 405*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 406*4bff34e3Sthurlow // 407*4bff34e3Sthurlow // Function: 408*4bff34e3Sthurlow // spnegoIsMechTypeAvailable 409*4bff34e3Sthurlow // 410*4bff34e3Sthurlow // Parameters: 411*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 412*4bff34e3Sthurlow // [in] MechOID - MechOID to search MechTypeList for 413*4bff34e3Sthurlow // [out] piMechTypeIndex - Filled out with index in MechTypeList 414*4bff34e3Sthurlow // element if MechOID is found. 415*4bff34e3Sthurlow // 416*4bff34e3Sthurlow // Returns: 417*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 418*4bff34e3Sthurlow // Failure - SPNEGO API Error code 419*4bff34e3Sthurlow // 420*4bff34e3Sthurlow // Comments : 421*4bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenInit. The 422*4bff34e3Sthurlow // function will search the MechTypeList element for an OID corresponding 423*4bff34e3Sthurlow // to the specified MechOID. If one is found, the index (0 based) will 424*4bff34e3Sthurlow // be passed into the piMechTypeIndex parameter. 425*4bff34e3Sthurlow // 426*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 427*4bff34e3Sthurlow 428*4bff34e3Sthurlow // Returns the Initial Mech Type in the MechList element in the NegInitToken. 429*4bff34e3Sthurlow int spnegoIsMechTypeAvailable( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID MechOID, int * piMechTypeIndex ) 430*4bff34e3Sthurlow { 431*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 432*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 433*4bff34e3Sthurlow 434*4bff34e3Sthurlow // Check parameters 435*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 436*4bff34e3Sthurlow NULL != piMechTypeIndex && 437*4bff34e3Sthurlow IsValidMechOid( MechOID ) && 438*4bff34e3Sthurlow SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 439*4bff34e3Sthurlow { 440*4bff34e3Sthurlow 441*4bff34e3Sthurlow // Check if MechList is available 442*4bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].iElementPresent 443*4bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 444*4bff34e3Sthurlow { 445*4bff34e3Sthurlow // Locate the MechOID in the list element 446*4bff34e3Sthurlow nReturn = FindMechOIDInMechList( 447*4bff34e3Sthurlow &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT], 448*4bff34e3Sthurlow MechOID, piMechTypeIndex ); 449*4bff34e3Sthurlow } 450*4bff34e3Sthurlow else 451*4bff34e3Sthurlow { 452*4bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 453*4bff34e3Sthurlow } 454*4bff34e3Sthurlow 455*4bff34e3Sthurlow } // IF parameters OK 456*4bff34e3Sthurlow 457*4bff34e3Sthurlow return nReturn;; 458*4bff34e3Sthurlow } 459*4bff34e3Sthurlow 460*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 461*4bff34e3Sthurlow // 462*4bff34e3Sthurlow // Function: 463*4bff34e3Sthurlow // spnegoGetContextFlags 464*4bff34e3Sthurlow // 465*4bff34e3Sthurlow // Parameters: 466*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 467*4bff34e3Sthurlow // [out] pucContextFlags - Filled out with ContextFlags value. 468*4bff34e3Sthurlow // 469*4bff34e3Sthurlow // Returns: 470*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 471*4bff34e3Sthurlow // Failure - SPNEGO API Error code 472*4bff34e3Sthurlow // 473*4bff34e3Sthurlow // Comments : 474*4bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenInit. The 475*4bff34e3Sthurlow // function will copy data from the ContextFlags element into the 476*4bff34e3Sthurlow // location pucContextFlags points to. Note that the function will 477*4bff34e3Sthurlow // fail if the actual ContextFlags data appears invalid. 478*4bff34e3Sthurlow // 479*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 480*4bff34e3Sthurlow 481*4bff34e3Sthurlow int spnegoGetContextFlags( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucContextFlags ) 482*4bff34e3Sthurlow { 483*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 484*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 485*4bff34e3Sthurlow 486*4bff34e3Sthurlow // Check parameters 487*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 488*4bff34e3Sthurlow NULL != pucContextFlags && 489*4bff34e3Sthurlow SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 490*4bff34e3Sthurlow { 491*4bff34e3Sthurlow 492*4bff34e3Sthurlow // Check if ContextFlags is available 493*4bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].iElementPresent 494*4bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 495*4bff34e3Sthurlow { 496*4bff34e3Sthurlow // The length should be two, the value should show a 1 bit difference in the difference byte, and 497*4bff34e3Sthurlow // the value must be valid 498*4bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS && 499*4bff34e3Sthurlow pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF && 500*4bff34e3Sthurlow IsValidContextFlags( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1] ) ) 501*4bff34e3Sthurlow { 502*4bff34e3Sthurlow *pucContextFlags = pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1]; 503*4bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 504*4bff34e3Sthurlow } 505*4bff34e3Sthurlow else 506*4bff34e3Sthurlow { 507*4bff34e3Sthurlow nReturn = SPNEGO_E_INVALID_ELEMENT; 508*4bff34e3Sthurlow } 509*4bff34e3Sthurlow 510*4bff34e3Sthurlow } 511*4bff34e3Sthurlow else 512*4bff34e3Sthurlow { 513*4bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 514*4bff34e3Sthurlow } 515*4bff34e3Sthurlow 516*4bff34e3Sthurlow } // IF parameters OK 517*4bff34e3Sthurlow 518*4bff34e3Sthurlow return nReturn;; 519*4bff34e3Sthurlow } 520*4bff34e3Sthurlow 521*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 522*4bff34e3Sthurlow // 523*4bff34e3Sthurlow // Function: 524*4bff34e3Sthurlow // spnegoGetNegotiationResult 525*4bff34e3Sthurlow // 526*4bff34e3Sthurlow // Parameters: 527*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 528*4bff34e3Sthurlow // [out] pnegResult - Filled out with NegResult value. 529*4bff34e3Sthurlow // 530*4bff34e3Sthurlow // Returns: 531*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 532*4bff34e3Sthurlow // Failure - SPNEGO API Error code 533*4bff34e3Sthurlow // 534*4bff34e3Sthurlow // Comments : 535*4bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenTarg. The 536*4bff34e3Sthurlow // function will copy data from the NegResult element into the 537*4bff34e3Sthurlow // location pointed to by pnegResult. Note that the function will 538*4bff34e3Sthurlow // fail if the actual NegResult data appears invalid. 539*4bff34e3Sthurlow // 540*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 541*4bff34e3Sthurlow 542*4bff34e3Sthurlow int spnegoGetNegotiationResult( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESULT* pnegResult ) 543*4bff34e3Sthurlow { 544*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 545*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 546*4bff34e3Sthurlow 547*4bff34e3Sthurlow // Check parameters 548*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 549*4bff34e3Sthurlow NULL != pnegResult && 550*4bff34e3Sthurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) 551*4bff34e3Sthurlow { 552*4bff34e3Sthurlow 553*4bff34e3Sthurlow // Check if NegResult is available 554*4bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].iElementPresent 555*4bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 556*4bff34e3Sthurlow { 557*4bff34e3Sthurlow // Must be 1 byte long and a valid value 558*4bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT && 559*4bff34e3Sthurlow IsValidNegResult( *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData ) ) 560*4bff34e3Sthurlow { 561*4bff34e3Sthurlow *pnegResult = *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData; 562*4bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 563*4bff34e3Sthurlow } 564*4bff34e3Sthurlow else 565*4bff34e3Sthurlow { 566*4bff34e3Sthurlow nReturn = SPNEGO_E_INVALID_ELEMENT; 567*4bff34e3Sthurlow } 568*4bff34e3Sthurlow } 569*4bff34e3Sthurlow else 570*4bff34e3Sthurlow { 571*4bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 572*4bff34e3Sthurlow } 573*4bff34e3Sthurlow 574*4bff34e3Sthurlow } // IF parameters OK 575*4bff34e3Sthurlow 576*4bff34e3Sthurlow return nReturn;; 577*4bff34e3Sthurlow } 578*4bff34e3Sthurlow 579*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 580*4bff34e3Sthurlow // 581*4bff34e3Sthurlow // Function: 582*4bff34e3Sthurlow // spnegoGetSupportedMechType 583*4bff34e3Sthurlow // 584*4bff34e3Sthurlow // Parameters: 585*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 586*4bff34e3Sthurlow // [out] pMechOID - Filled out with Supported MechType value. 587*4bff34e3Sthurlow // 588*4bff34e3Sthurlow // Returns: 589*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 590*4bff34e3Sthurlow // Failure - SPNEGO API Error code 591*4bff34e3Sthurlow // 592*4bff34e3Sthurlow // Comments : 593*4bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenTarg. The 594*4bff34e3Sthurlow // function will check the Supported MechType element, and if it 595*4bff34e3Sthurlow // corresponds to a supported MechType ( spnego_mech_oid_Kerberos_V5_Legacy 596*4bff34e3Sthurlow // or spnego_mech_oid_Kerberos_V5 ), will set the location pointed 597*4bff34e3Sthurlow // to by pMechOID equal to the appropriate value. 598*4bff34e3Sthurlow // 599*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 600*4bff34e3Sthurlow 601*4bff34e3Sthurlow int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID ) 602*4bff34e3Sthurlow { 603*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 604*4bff34e3Sthurlow int nCtr = 0L; 605*4bff34e3Sthurlow long nLength = 0L; 606*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 607*4bff34e3Sthurlow 608*4bff34e3Sthurlow // Check parameters 609*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 610*4bff34e3Sthurlow NULL != pMechOID && 611*4bff34e3Sthurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) 612*4bff34e3Sthurlow { 613*4bff34e3Sthurlow 614*4bff34e3Sthurlow // Check if MechList is available 615*4bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].iElementPresent 616*4bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 617*4bff34e3Sthurlow { 618*4bff34e3Sthurlow 619*4bff34e3Sthurlow for ( nCtr = 0; 620*4bff34e3Sthurlow nReturn != SPNEGO_E_SUCCESS && 621*4bff34e3Sthurlow g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed; 622*4bff34e3Sthurlow nCtr++ ) 623*4bff34e3Sthurlow { 624*4bff34e3Sthurlow 625*4bff34e3Sthurlow if ( ( nReturn = ASNDerCheckOID( 626*4bff34e3Sthurlow pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData, 627*4bff34e3Sthurlow nCtr, 628*4bff34e3Sthurlow pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].nDatalength, 629*4bff34e3Sthurlow &nLength ) ) == SPNEGO_E_SUCCESS ) 630*4bff34e3Sthurlow { 631*4bff34e3Sthurlow *pMechOID = nCtr; 632*4bff34e3Sthurlow } 633*4bff34e3Sthurlow 634*4bff34e3Sthurlow } // For enum MechOIDs 635*4bff34e3Sthurlow 636*4bff34e3Sthurlow 637*4bff34e3Sthurlow } 638*4bff34e3Sthurlow else 639*4bff34e3Sthurlow { 640*4bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 641*4bff34e3Sthurlow } 642*4bff34e3Sthurlow 643*4bff34e3Sthurlow } // IF parameters OK 644*4bff34e3Sthurlow 645*4bff34e3Sthurlow return nReturn;; 646*4bff34e3Sthurlow } 647*4bff34e3Sthurlow 648*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 649*4bff34e3Sthurlow // 650*4bff34e3Sthurlow // Function: 651*4bff34e3Sthurlow // spnegoTokenGetMechToken 652*4bff34e3Sthurlow // 653*4bff34e3Sthurlow // Parameters: 654*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 655*4bff34e3Sthurlow // [out] pbTokenData - Buffer to copy MechToken into 656*4bff34e3Sthurlow // [in/out] pulDataLen - Length of pbTokenData buffer, filled out 657*4bff34e3Sthurlow // with actual size used upon function return. 658*4bff34e3Sthurlow // 659*4bff34e3Sthurlow // Returns: 660*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 661*4bff34e3Sthurlow // Failure - SPNEGO API Error code 662*4bff34e3Sthurlow // 663*4bff34e3Sthurlow // Comments : 664*4bff34e3Sthurlow // hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token. 665*4bff34e3Sthurlow // The function will copy the MechToken (the initial MechToken if 666*4bff34e3Sthurlow // NegTokenInit, the response MechToken if NegTokenTarg) from the 667*4bff34e3Sthurlow // underlying token into the buffer pointed to by pbTokenData. If 668*4bff34e3Sthurlow // pbTokenData is NULL, or the value in pulDataLen is too small, the 669*4bff34e3Sthurlow // function will return SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen 670*4bff34e3Sthurlow // with the minimum required buffer size. The token can then be passed 671*4bff34e3Sthurlow // to a GSS-API function for processing. 672*4bff34e3Sthurlow // 673*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 674*4bff34e3Sthurlow 675*4bff34e3Sthurlow int spnegoGetMechToken( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, unsigned long* pulDataLen ) 676*4bff34e3Sthurlow { 677*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 678*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 679*4bff34e3Sthurlow SPNEGO_ELEMENT* pSpnegoElement = NULL; 680*4bff34e3Sthurlow 681*4bff34e3Sthurlow // Check parameters 682*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 683*4bff34e3Sthurlow NULL != pulDataLen ) 684*4bff34e3Sthurlow { 685*4bff34e3Sthurlow 686*4bff34e3Sthurlow // Point at the proper Element 687*4bff34e3Sthurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 688*4bff34e3Sthurlow { 689*4bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT]; 690*4bff34e3Sthurlow } 691*4bff34e3Sthurlow else 692*4bff34e3Sthurlow { 693*4bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT]; 694*4bff34e3Sthurlow } 695*4bff34e3Sthurlow 696*4bff34e3Sthurlow // Check if MechType is available 697*4bff34e3Sthurlow if ( SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent ) 698*4bff34e3Sthurlow { 699*4bff34e3Sthurlow // Check for Buffer too small conditions 700*4bff34e3Sthurlow if ( NULL == pbTokenData || 701*4bff34e3Sthurlow pSpnegoElement->nDatalength > *pulDataLen ) 702*4bff34e3Sthurlow { 703*4bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 704*4bff34e3Sthurlow nReturn = SPNEGO_E_BUFFER_TOO_SMALL; 705*4bff34e3Sthurlow } 706*4bff34e3Sthurlow else 707*4bff34e3Sthurlow { 708*4bff34e3Sthurlow // Copy Memory 709*4bff34e3Sthurlow memcpy( pbTokenData, pSpnegoElement->pbData, pSpnegoElement->nDatalength ); 710*4bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 711*4bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 712*4bff34e3Sthurlow } 713*4bff34e3Sthurlow } 714*4bff34e3Sthurlow else 715*4bff34e3Sthurlow { 716*4bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 717*4bff34e3Sthurlow } 718*4bff34e3Sthurlow 719*4bff34e3Sthurlow } // IF parameters OK 720*4bff34e3Sthurlow 721*4bff34e3Sthurlow return nReturn;; 722*4bff34e3Sthurlow } 723*4bff34e3Sthurlow 724*4bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 725*4bff34e3Sthurlow // 726*4bff34e3Sthurlow // Function: 727*4bff34e3Sthurlow // spnegoTokenGetMechListMIC 728*4bff34e3Sthurlow // 729*4bff34e3Sthurlow // Parameters: 730*4bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 731*4bff34e3Sthurlow // [out] pbTokenData - Buffer to copy MechListMIC data into 732*4bff34e3Sthurlow // [in/out] pulDataLen - Length of pbTokenData buffer, filled out 733*4bff34e3Sthurlow // with actual size used upon function return. 734*4bff34e3Sthurlow // 735*4bff34e3Sthurlow // Returns: 736*4bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 737*4bff34e3Sthurlow // Failure - SPNEGO API Error code 738*4bff34e3Sthurlow // 739*4bff34e3Sthurlow // Comments : 740*4bff34e3Sthurlow // hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token. 741*4bff34e3Sthurlow // The function will copy the MechListMIC data from the underlying token 742*4bff34e3Sthurlow // into the buffer pointed to by pbTokenData. If pbTokenData is NULL, 743*4bff34e3Sthurlow // or the value in pulDataLen is too small, the function will return 744*4bff34e3Sthurlow // SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen with the minimum 745*4bff34e3Sthurlow // required buffer size. 746*4bff34e3Sthurlow // 747*4bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 748*4bff34e3Sthurlow 749*4bff34e3Sthurlow int spnegoGetMechListMIC( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned long* pulDataLen ) 750*4bff34e3Sthurlow { 751*4bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 752*4bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 753*4bff34e3Sthurlow SPNEGO_ELEMENT* pSpnegoElement = NULL; 754*4bff34e3Sthurlow 755*4bff34e3Sthurlow // Check parameters 756*4bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 757*4bff34e3Sthurlow NULL != pulDataLen ) 758*4bff34e3Sthurlow { 759*4bff34e3Sthurlow 760*4bff34e3Sthurlow // Point at the proper Element 761*4bff34e3Sthurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 762*4bff34e3Sthurlow { 763*4bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT]; 764*4bff34e3Sthurlow } 765*4bff34e3Sthurlow else 766*4bff34e3Sthurlow { 767*4bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT]; 768*4bff34e3Sthurlow } 769*4bff34e3Sthurlow 770*4bff34e3Sthurlow // Check if MechType is available 771*4bff34e3Sthurlow if ( SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent ) 772*4bff34e3Sthurlow { 773*4bff34e3Sthurlow // Check for Buffer too small conditions 774*4bff34e3Sthurlow if ( NULL == pbMICData || 775*4bff34e3Sthurlow pSpnegoElement->nDatalength > *pulDataLen ) 776*4bff34e3Sthurlow { 777*4bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 778*4bff34e3Sthurlow nReturn = SPNEGO_E_BUFFER_TOO_SMALL; 779*4bff34e3Sthurlow } 780*4bff34e3Sthurlow else 781*4bff34e3Sthurlow { 782*4bff34e3Sthurlow // Copy Memory 783*4bff34e3Sthurlow memcpy( pbMICData, pSpnegoElement->pbData, pSpnegoElement->nDatalength ); 784*4bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 785*4bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 786*4bff34e3Sthurlow } 787*4bff34e3Sthurlow } 788*4bff34e3Sthurlow else 789*4bff34e3Sthurlow { 790*4bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 791*4bff34e3Sthurlow } 792*4bff34e3Sthurlow 793*4bff34e3Sthurlow } // IF parameters OK 794*4bff34e3Sthurlow 795*4bff34e3Sthurlow return nReturn;; 796*4bff34e3Sthurlow } 797*4bff34e3Sthurlow 798