1*12b65585SGordon Ross // Copyright 2012 Nexenta Systems, Inc. All rights reserved. 24bff34e3Sthurlow // Copyright (C) 2002 Microsoft Corporation 34bff34e3Sthurlow // All rights reserved. 44bff34e3Sthurlow // 54bff34e3Sthurlow // THIS CODE AND INFORMATION IS PROVIDED "AS IS" 64bff34e3Sthurlow // WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 74bff34e3Sthurlow // OR IMPLIED, INCLUDING BUT NOT LIMITED 84bff34e3Sthurlow // TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY 94bff34e3Sthurlow // AND/OR FITNESS FOR A PARTICULAR PURPOSE. 104bff34e3Sthurlow // 114bff34e3Sthurlow // Date - 10/08/2002 124bff34e3Sthurlow // Author - Sanj Surati 134bff34e3Sthurlow 144bff34e3Sthurlow ///////////////////////////////////////////////////////////// 154bff34e3Sthurlow // 164bff34e3Sthurlow // SPNEGO.C 174bff34e3Sthurlow // 184bff34e3Sthurlow // SPNEGO Token Handler Source File 194bff34e3Sthurlow // 204bff34e3Sthurlow // Contains implementation of SPNEGO Token Handling API 214bff34e3Sthurlow // as defined in SPNEGO.H. 224bff34e3Sthurlow // 234bff34e3Sthurlow ///////////////////////////////////////////////////////////// 244bff34e3Sthurlow 254bff34e3Sthurlow #include <stdlib.h> 264bff34e3Sthurlow #include <stdio.h> 27*12b65585SGordon Ross #include <string.h> 284bff34e3Sthurlow #include <memory.h> 294bff34e3Sthurlow #include "spnego.h" 304bff34e3Sthurlow #include "derparse.h" 314bff34e3Sthurlow #include "spnegoparse.h" 324bff34e3Sthurlow 334bff34e3Sthurlow // 344bff34e3Sthurlow // Defined in DERPARSE.C 354bff34e3Sthurlow // 364bff34e3Sthurlow 374bff34e3Sthurlow extern MECH_OID g_stcMechOIDList []; 384bff34e3Sthurlow 394bff34e3Sthurlow 404bff34e3Sthurlow /**********************************************************************/ 414bff34e3Sthurlow /** **/ 424bff34e3Sthurlow /** **/ 434bff34e3Sthurlow /** **/ 444bff34e3Sthurlow /** **/ 454bff34e3Sthurlow /** SPNEGO Token Handler API implementation **/ 464bff34e3Sthurlow /** **/ 474bff34e3Sthurlow /** **/ 484bff34e3Sthurlow /** **/ 494bff34e3Sthurlow /** **/ 504bff34e3Sthurlow /**********************************************************************/ 514bff34e3Sthurlow 524bff34e3Sthurlow 534bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 544bff34e3Sthurlow // 554bff34e3Sthurlow // Function: 564bff34e3Sthurlow // spnegoInitFromBinary 574bff34e3Sthurlow // 584bff34e3Sthurlow // Parameters: 594bff34e3Sthurlow // [in] pbTokenData - Binary Token Data 604bff34e3Sthurlow // [in] ulLength - Length of binary Token Data 614bff34e3Sthurlow // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 624bff34e3Sthurlow // 634bff34e3Sthurlow // Returns: 644bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 654bff34e3Sthurlow // Failure - SPNEGO API Error code 664bff34e3Sthurlow // 674bff34e3Sthurlow // Comments : 684bff34e3Sthurlow // Initializes a SPNEGO_TOKEN_HANDLE from the supplied 694bff34e3Sthurlow // binary data. Data is copied locally. Returned data structure 704bff34e3Sthurlow // must be freed by calling spnegoFreeData(). 714bff34e3Sthurlow // 724bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 734bff34e3Sthurlow 744bff34e3Sthurlow int spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 754bff34e3Sthurlow { 764bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 774bff34e3Sthurlow SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 784bff34e3Sthurlow 794bff34e3Sthurlow // Pass off to a handler function that allows tighter control over how the token structure 804bff34e3Sthurlow // is handled. In this case, we want the token data copied and we want the associated buffer 814bff34e3Sthurlow // freed. 824bff34e3Sthurlow nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYDATA, 834bff34e3Sthurlow SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData, 844bff34e3Sthurlow ulLength, ppSpnegoToken ); 854bff34e3Sthurlow 864bff34e3Sthurlow return nReturn; 874bff34e3Sthurlow } 884bff34e3Sthurlow 894bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 904bff34e3Sthurlow // 914bff34e3Sthurlow // Function: 92*12b65585SGordon Ross // spnegoCreateNegTokenHint 93*12b65585SGordon Ross // 94*12b65585SGordon Ross // Parameters: 95*12b65585SGordon Ross // [in] pMechTypeList - List of MechTypes (OIDs) to include 96*12b65585SGordon Ross // [in] MechTypeCnt - Length of MechTypes array 97*12b65585SGordon Ross // [in] pbPrincipal - Principal name for MechListMIC 98*12b65585SGordon Ross // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 99*12b65585SGordon Ross // 100*12b65585SGordon Ross // Returns: 101*12b65585SGordon Ross // int Success - SPNEGO_E_SUCCESS 102*12b65585SGordon Ross // Failure - SPNEGO API Error code 103*12b65585SGordon Ross // 104*12b65585SGordon Ross // Comments : 105*12b65585SGordon Ross // Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenInit type token 106*12b65585SGordon Ross // from the supplied parameters. The token created is the "hint" 107*12b65585SGordon Ross // used (for example) in the response to an SMB negotiate protocol. 108*12b65585SGordon Ross // Returned data structure must be freed by calling spnegoFreeData(). 109*12b65585SGordon Ross // 110*12b65585SGordon Ross // The "hint" tells the client what authentication methods this 111*12b65585SGordon Ross // server supports (the ones in the MechTypeList). The Principal 112*12b65585SGordon Ross // name historically was the server's own SPN, but recent versions 113*12b65585SGordon Ross // of windows only supply: "not_defined_in_RFC4178@please_ignore" 114*12b65585SGordon Ross // So if you want to be nice to your clients, provide the host SPN, 115*12b65585SGordon Ross // otherwise provide the bogus SPN string like recent windows. 116*12b65585SGordon Ross // 117*12b65585SGordon Ross //////////////////////////////////////////////////////////////////////////// 118*12b65585SGordon Ross 119*12b65585SGordon Ross int spnegoCreateNegTokenHint( SPNEGO_MECH_OID *pMechTypeList, int MechTypeCnt, 120*12b65585SGordon Ross unsigned char *pbPrincipal, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 121*12b65585SGordon Ross { 122*12b65585SGordon Ross int nReturn; 123*12b65585SGordon Ross long nTokenLength = 0L; 124*12b65585SGordon Ross long nInternalTokenLength = 0L; 125*12b65585SGordon Ross unsigned long ulPrincipalLen; 126*12b65585SGordon Ross unsigned char* pbMechListMIC; 127*12b65585SGordon Ross unsigned long ulMechListMICLen; 128*12b65585SGordon Ross unsigned char* pbTokenData = NULL; 129*12b65585SGordon Ross SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 130*12b65585SGordon Ross 131*12b65585SGordon Ross if ( NULL == ppSpnegoToken || NULL == pbPrincipal ) 132*12b65585SGordon Ross return (SPNEGO_E_INVALID_PARAMETER); 133*12b65585SGordon Ross 134*12b65585SGordon Ross /* 135*12b65585SGordon Ross * Get the actual token size 136*12b65585SGordon Ross */ 137*12b65585SGordon Ross ulPrincipalLen = strlen((char *)pbPrincipal); 138*12b65585SGordon Ross ulMechListMICLen = ASNDerCalcElementLength( ulPrincipalLen, NULL ); 139*12b65585SGordon Ross nReturn = CalculateMinSpnegoInitTokenSize( 140*12b65585SGordon Ross 0, /* ulMechTokenLen */ 141*12b65585SGordon Ross ulMechListMICLen, 142*12b65585SGordon Ross pMechTypeList, 143*12b65585SGordon Ross MechTypeCnt, 144*12b65585SGordon Ross 0, /* nReqFlagsAvailable */ 145*12b65585SGordon Ross &nTokenLength, 146*12b65585SGordon Ross &nInternalTokenLength ); 147*12b65585SGordon Ross if ( nReturn != SPNEGO_E_SUCCESS ) 148*12b65585SGordon Ross return (nReturn); 149*12b65585SGordon Ross 150*12b65585SGordon Ross // Allocate a buffer to hold the data. 151*12b65585SGordon Ross pbTokenData = calloc( 1, nTokenLength ); 152*12b65585SGordon Ross 153*12b65585SGordon Ross if ( NULL == pbTokenData ) 154*12b65585SGordon Ross return ( SPNEGO_E_OUT_OF_MEMORY ); 155*12b65585SGordon Ross 156*12b65585SGordon Ross /* 157*12b65585SGordon Ross * Construct the MechListMIC 158*12b65585SGordon Ross */ 159*12b65585SGordon Ross pbMechListMIC = pbTokenData + (nTokenLength - ulMechListMICLen); 160*12b65585SGordon Ross (void) ASNDerWriteElement( pbMechListMIC, SPNEGO_NEGINIT_ELEMENT_MECHTYPES, 161*12b65585SGordon Ross GENERALSTR, pbPrincipal, ulPrincipalLen ); 162*12b65585SGordon Ross 163*12b65585SGordon Ross // Now write the token 164*12b65585SGordon Ross nReturn = CreateSpnegoInitToken( 165*12b65585SGordon Ross pMechTypeList, 166*12b65585SGordon Ross MechTypeCnt, 167*12b65585SGordon Ross 0, /* ContextFlags */ 168*12b65585SGordon Ross NULL, 0, /* MechToken, len */ 169*12b65585SGordon Ross pbMechListMIC, 170*12b65585SGordon Ross ulMechListMICLen, 171*12b65585SGordon Ross pbTokenData, 172*12b65585SGordon Ross nTokenLength, 173*12b65585SGordon Ross nInternalTokenLength ); 174*12b65585SGordon Ross if ( nReturn != SPNEGO_E_SUCCESS ) { 175*12b65585SGordon Ross free( pbTokenData ); 176*12b65585SGordon Ross return (nReturn); 177*12b65585SGordon Ross } 178*12b65585SGordon Ross 179*12b65585SGordon Ross // This will copy our allocated pointer, and ensure that the sructure cleans 180*12b65585SGordon Ross // up the data later 181*12b65585SGordon Ross nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR, 182*12b65585SGordon Ross SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, 183*12b65585SGordon Ross pbTokenData, nTokenLength, ppSpnegoToken ); 184*12b65585SGordon Ross 185*12b65585SGordon Ross // Cleanup on failure 186*12b65585SGordon Ross if ( nReturn != SPNEGO_E_SUCCESS ) { 187*12b65585SGordon Ross free( pbTokenData ); 188*12b65585SGordon Ross return (nReturn); 189*12b65585SGordon Ross } 190*12b65585SGordon Ross 191*12b65585SGordon Ross return (SPNEGO_E_SUCCESS); 192*12b65585SGordon Ross } 193*12b65585SGordon Ross 194*12b65585SGordon Ross ///////////////////////////////////////////////////////////////////////////// 195*12b65585SGordon Ross // 196*12b65585SGordon Ross // Function: 1974bff34e3Sthurlow // spnegoCreateNegTokenInit 1984bff34e3Sthurlow // 1994bff34e3Sthurlow // Parameters: 2004bff34e3Sthurlow // [in] MechType - MechType to specify in MechTypeList element 2014bff34e3Sthurlow // [in] ucContextFlags - Context Flags element value 2024bff34e3Sthurlow // [in] pbMechToken - Pointer to binary MechToken Data 2034bff34e3Sthurlow // [in] ulMechTokenLen - Length of MechToken Data 2044bff34e3Sthurlow // [in] pbMechListMIC - Pointer to binary MechListMIC Data 2054bff34e3Sthurlow // [in] ulMechListMICLen - Length of MechListMIC Data 2064bff34e3Sthurlow // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 2074bff34e3Sthurlow // 2084bff34e3Sthurlow // Returns: 2094bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 2104bff34e3Sthurlow // Failure - SPNEGO API Error code 2114bff34e3Sthurlow // 2124bff34e3Sthurlow // Comments : 2134bff34e3Sthurlow // Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenInit type 2144bff34e3Sthurlow // from the supplied parameters. ucContextFlags may be 0 or must be 2154bff34e3Sthurlow // a valid flag combination. MechToken data can be NULL - if not, it 2164bff34e3Sthurlow // must correspond to the MechType. MechListMIC can also be NULL. 2174bff34e3Sthurlow // Returned data structure must be freed by calling spnegoFreeData(). 2184bff34e3Sthurlow // 2194bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 2204bff34e3Sthurlow 2214bff34e3Sthurlow int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType, 2224bff34e3Sthurlow unsigned char ucContextFlags, unsigned char* pbMechToken, 2234bff34e3Sthurlow unsigned long ulMechTokenLen, unsigned char* pbMechListMIC, 2244bff34e3Sthurlow unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 2254bff34e3Sthurlow { 2264bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 2274bff34e3Sthurlow long nTokenLength = 0L; 2284bff34e3Sthurlow long nInternalTokenLength = 0L; 2294bff34e3Sthurlow unsigned char* pbTokenData = NULL; 2304bff34e3Sthurlow SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 2314bff34e3Sthurlow 2324bff34e3Sthurlow if ( NULL != ppSpnegoToken && 2334bff34e3Sthurlow IsValidMechOid( MechType ) && 2344bff34e3Sthurlow IsValidContextFlags( ucContextFlags ) ) 2354bff34e3Sthurlow { 2364bff34e3Sthurlow // Get the actual token size 2374bff34e3Sthurlow 2384bff34e3Sthurlow if ( ( nReturn = CalculateMinSpnegoInitTokenSize( ulMechTokenLen, ulMechListMICLen, 239*12b65585SGordon Ross &MechType, 1, ( ucContextFlags != 0L ), 2404bff34e3Sthurlow &nTokenLength, &nInternalTokenLength ) ) 2414bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 2424bff34e3Sthurlow { 2434bff34e3Sthurlow // Allocate a buffer to hold the data. 2444bff34e3Sthurlow pbTokenData = calloc( 1, nTokenLength ); 2454bff34e3Sthurlow 2464bff34e3Sthurlow if ( NULL != pbTokenData ) 2474bff34e3Sthurlow { 2484bff34e3Sthurlow 2494bff34e3Sthurlow // Now write the token 250*12b65585SGordon Ross if ( ( nReturn = CreateSpnegoInitToken( &MechType, 1, 2514bff34e3Sthurlow ucContextFlags, pbMechToken, 2524bff34e3Sthurlow ulMechTokenLen, pbMechListMIC, 2534bff34e3Sthurlow ulMechListMICLen, pbTokenData, 2544bff34e3Sthurlow nTokenLength, nInternalTokenLength ) ) 2554bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 2564bff34e3Sthurlow { 2574bff34e3Sthurlow 2584bff34e3Sthurlow // This will copy our allocated pointer, and ensure that the sructure cleans 2594bff34e3Sthurlow // up the data later 2604bff34e3Sthurlow nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR, 2614bff34e3Sthurlow SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, 2624bff34e3Sthurlow pbTokenData, nTokenLength, ppSpnegoToken ); 2634bff34e3Sthurlow 2644bff34e3Sthurlow } 2654bff34e3Sthurlow 2664bff34e3Sthurlow // Cleanup on failure 2674bff34e3Sthurlow if ( SPNEGO_E_SUCCESS != nReturn ) 2684bff34e3Sthurlow { 2694bff34e3Sthurlow free( pbTokenData ); 2704bff34e3Sthurlow } 2714bff34e3Sthurlow 2724bff34e3Sthurlow } // IF alloc succeeded 2734bff34e3Sthurlow else 2744bff34e3Sthurlow { 2754bff34e3Sthurlow nReturn = SPNEGO_E_OUT_OF_MEMORY; 2764bff34e3Sthurlow } 2774bff34e3Sthurlow 2784bff34e3Sthurlow } // If calculated token size 2794bff34e3Sthurlow 2804bff34e3Sthurlow } // IF Valid Parameters 2814bff34e3Sthurlow 2824bff34e3Sthurlow return nReturn; 2834bff34e3Sthurlow } 2844bff34e3Sthurlow 2854bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 2864bff34e3Sthurlow // 2874bff34e3Sthurlow // Function: 2884bff34e3Sthurlow // spnegoCreateNegTokenTarg 2894bff34e3Sthurlow // 2904bff34e3Sthurlow // Parameters: 2914bff34e3Sthurlow // [in] MechType - MechType to specify in supported MechType element 2924bff34e3Sthurlow // [in] spnegoNegResult - NegResult value 2934bff34e3Sthurlow // [in] pbMechToken - Pointer to response MechToken Data 2944bff34e3Sthurlow // [in] ulMechTokenLen - Length of MechToken Data 2954bff34e3Sthurlow // [in] pbMechListMIC - Pointer to binary MechListMIC Data 2964bff34e3Sthurlow // [in] ulMechListMICLen - Length of MechListMIC Data 2974bff34e3Sthurlow // [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer 2984bff34e3Sthurlow // 2994bff34e3Sthurlow // Returns: 3004bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 3014bff34e3Sthurlow // Failure - SPNEGO API Error code 3024bff34e3Sthurlow // 3034bff34e3Sthurlow // Comments : 3044bff34e3Sthurlow // Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenTarg type 3054bff34e3Sthurlow // from the supplied parameters. MechToken data can be NULL - if not, 3064bff34e3Sthurlow // it must correspond to the MechType. MechListMIC can also be NULL. 3074bff34e3Sthurlow // Returned data structure must be freed by calling spnegoFreeData(). 3084bff34e3Sthurlow // 3094bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 3104bff34e3Sthurlow 3114bff34e3Sthurlow int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType, 3124bff34e3Sthurlow SPNEGO_NEGRESULT spnegoNegResult, unsigned char* pbMechToken, 3134bff34e3Sthurlow unsigned long ulMechTokenLen, unsigned char* pbMechListMIC, 3144bff34e3Sthurlow unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken ) 3154bff34e3Sthurlow { 3164bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 3174bff34e3Sthurlow long nTokenLength = 0L; 3184bff34e3Sthurlow long nInternalTokenLength = 0L; 3194bff34e3Sthurlow unsigned char* pbTokenData = NULL; 3204bff34e3Sthurlow SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken; 3214bff34e3Sthurlow 3224bff34e3Sthurlow // 3234bff34e3Sthurlow // spnego_mech_oid_NotUsed and spnego_negresult_NotUsed 3244bff34e3Sthurlow // are okay here, however a valid MechOid is required 3254bff34e3Sthurlow // if spnego_negresult_success or spnego_negresult_incomplete 3264bff34e3Sthurlow // is specified. 3274bff34e3Sthurlow // 3284bff34e3Sthurlow 3294bff34e3Sthurlow if ( NULL != ppSpnegoToken && 3304bff34e3Sthurlow 3314bff34e3Sthurlow ( IsValidMechOid( MechType ) || 3324bff34e3Sthurlow spnego_mech_oid_NotUsed == MechType ) && 3334bff34e3Sthurlow 3344bff34e3Sthurlow ( IsValidNegResult( spnegoNegResult ) || 335*12b65585SGordon Ross spnego_negresult_NotUsed == spnegoNegResult ) ) 3364bff34e3Sthurlow { 3374bff34e3Sthurlow 3384bff34e3Sthurlow // Get the actual token size 3394bff34e3Sthurlow 3404bff34e3Sthurlow if ( ( nReturn = CalculateMinSpnegoTargTokenSize( MechType, spnegoNegResult, ulMechTokenLen, 3414bff34e3Sthurlow ulMechListMICLen, &nTokenLength, 3424bff34e3Sthurlow &nInternalTokenLength ) ) 3434bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 3444bff34e3Sthurlow { 3454bff34e3Sthurlow // Allocate a buffer to hold the data. 3464bff34e3Sthurlow pbTokenData = calloc( 1, nTokenLength ); 3474bff34e3Sthurlow 3484bff34e3Sthurlow if ( NULL != pbTokenData ) 3494bff34e3Sthurlow { 3504bff34e3Sthurlow 3514bff34e3Sthurlow // Now write the token 3524bff34e3Sthurlow if ( ( nReturn = CreateSpnegoTargToken( MechType, 3534bff34e3Sthurlow spnegoNegResult, pbMechToken, 3544bff34e3Sthurlow ulMechTokenLen, pbMechListMIC, 3554bff34e3Sthurlow ulMechListMICLen, pbTokenData, 3564bff34e3Sthurlow nTokenLength, nInternalTokenLength ) ) 3574bff34e3Sthurlow == SPNEGO_E_SUCCESS ) 3584bff34e3Sthurlow { 3594bff34e3Sthurlow 3604bff34e3Sthurlow // This will copy our allocated pointer, and ensure that the sructure cleans 3614bff34e3Sthurlow // up the data later 3624bff34e3Sthurlow nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR, 3634bff34e3Sthurlow SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, 3644bff34e3Sthurlow pbTokenData, nTokenLength, ppSpnegoToken ); 3654bff34e3Sthurlow 3664bff34e3Sthurlow } 3674bff34e3Sthurlow 3684bff34e3Sthurlow // Cleanup on failure 3694bff34e3Sthurlow if ( SPNEGO_E_SUCCESS != nReturn ) 3704bff34e3Sthurlow { 3714bff34e3Sthurlow free( pbTokenData ); 3724bff34e3Sthurlow } 3734bff34e3Sthurlow 3744bff34e3Sthurlow } // IF alloc succeeded 3754bff34e3Sthurlow else 3764bff34e3Sthurlow { 3774bff34e3Sthurlow nReturn = SPNEGO_E_OUT_OF_MEMORY; 3784bff34e3Sthurlow } 3794bff34e3Sthurlow 3804bff34e3Sthurlow } // If calculated token size 3814bff34e3Sthurlow 3824bff34e3Sthurlow } // IF Valid Parameters 3834bff34e3Sthurlow 3844bff34e3Sthurlow return nReturn; 3854bff34e3Sthurlow } 3864bff34e3Sthurlow 3874bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 3884bff34e3Sthurlow // 3894bff34e3Sthurlow // Function: 3904bff34e3Sthurlow // spnegoTokenGetBinary 3914bff34e3Sthurlow // 3924bff34e3Sthurlow // Parameters: 3934bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 3944bff34e3Sthurlow // [out] pbTokenData - Buffer to copy token into 3954bff34e3Sthurlow // [in/out] pulDataLen - Length of pbTokenData buffer, filled out 3964bff34e3Sthurlow // with actual size used upon function return. 3974bff34e3Sthurlow // 3984bff34e3Sthurlow // Returns: 3994bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 4004bff34e3Sthurlow // Failure - SPNEGO API Error code 4014bff34e3Sthurlow // 4024bff34e3Sthurlow // Comments : 4034bff34e3Sthurlow // Copies binary SPNEGO token data from hSpnegoToken into the user 4044bff34e3Sthurlow // supplied buffer. If pbTokenData is NULL, or the value in pulDataLen 4054bff34e3Sthurlow // is too small, the function will return SPNEGO_E_BUFFER_TOO_SMALL and 4064bff34e3Sthurlow // fill out pulDataLen with the minimum required buffer size. 4074bff34e3Sthurlow // 4084bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 4094bff34e3Sthurlow 4104bff34e3Sthurlow int spnegoTokenGetBinary( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, 4114bff34e3Sthurlow unsigned long * pulDataLen ) 4124bff34e3Sthurlow { 4134bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 4144bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 4154bff34e3Sthurlow 4164bff34e3Sthurlow // Check parameters - pbTokenData is optional 4174bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 4184bff34e3Sthurlow NULL != pulDataLen ) 4194bff34e3Sthurlow { 4204bff34e3Sthurlow 4214bff34e3Sthurlow // Check for Buffer too small conditions 4224bff34e3Sthurlow if ( NULL == pbTokenData || 4234bff34e3Sthurlow pSpnegoToken->ulBinaryDataLen > *pulDataLen ) 4244bff34e3Sthurlow { 4254bff34e3Sthurlow *pulDataLen = pSpnegoToken->ulBinaryDataLen; 4264bff34e3Sthurlow nReturn = SPNEGO_E_BUFFER_TOO_SMALL; 4274bff34e3Sthurlow } 4284bff34e3Sthurlow else 4294bff34e3Sthurlow { 4304bff34e3Sthurlow memcpy( pbTokenData, pSpnegoToken->pbBinaryData, pSpnegoToken->ulBinaryDataLen ); 4314bff34e3Sthurlow *pulDataLen = pSpnegoToken->ulBinaryDataLen; 4324bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 4334bff34e3Sthurlow } 4344bff34e3Sthurlow 4354bff34e3Sthurlow } // IF parameters OK 4364bff34e3Sthurlow 4374bff34e3Sthurlow return nReturn;; 4384bff34e3Sthurlow } 4394bff34e3Sthurlow 4404bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 4414bff34e3Sthurlow // 4424bff34e3Sthurlow // Function: 4434bff34e3Sthurlow // spnegoFreeData 4444bff34e3Sthurlow // 4454bff34e3Sthurlow // Parameters: 4464bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 4474bff34e3Sthurlow // 4484bff34e3Sthurlow // Returns: 4494bff34e3Sthurlow // void 4504bff34e3Sthurlow // 4514bff34e3Sthurlow // Comments : 4524bff34e3Sthurlow // Frees up resources consumed by hSpnegoToken. The supplied data 4534bff34e3Sthurlow // pointer is invalidated by this function. 4544bff34e3Sthurlow // 4554bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 4564bff34e3Sthurlow 4574bff34e3Sthurlow void spnegoFreeData( SPNEGO_TOKEN_HANDLE hSpnegoToken ) 4584bff34e3Sthurlow { 4594bff34e3Sthurlow FreeSpnegoToken( (SPNEGO_TOKEN*) hSpnegoToken); 4604bff34e3Sthurlow return; 4614bff34e3Sthurlow } 4624bff34e3Sthurlow 4634bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 4644bff34e3Sthurlow // 4654bff34e3Sthurlow // Function: 4664bff34e3Sthurlow // spnegoGetTokenType 4674bff34e3Sthurlow // 4684bff34e3Sthurlow // Parameters: 4694bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 4704bff34e3Sthurlow // [out] piTokenType - Filled out with token type value. 4714bff34e3Sthurlow // 4724bff34e3Sthurlow // Returns: 4734bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 4744bff34e3Sthurlow // Failure - SPNEGO API Error code 4754bff34e3Sthurlow // 4764bff34e3Sthurlow // Comments : 4774bff34e3Sthurlow // The function will analyze hSpnegoToken and return the appropriate 4784bff34e3Sthurlow // type in piTokenType. 4794bff34e3Sthurlow // 4804bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 4814bff34e3Sthurlow 4824bff34e3Sthurlow int spnegoGetTokenType( SPNEGO_TOKEN_HANDLE hSpnegoToken, int * piTokenType ) 4834bff34e3Sthurlow { 4844bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 4854bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 4864bff34e3Sthurlow 4874bff34e3Sthurlow // Check parameters 4884bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 4894bff34e3Sthurlow NULL != piTokenType && 4904bff34e3Sthurlow pSpnegoToken) 4914bff34e3Sthurlow { 4924bff34e3Sthurlow 4934bff34e3Sthurlow // Check that the type in the structure makes sense 4944bff34e3Sthurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType || 4954bff34e3Sthurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) 4964bff34e3Sthurlow { 4974bff34e3Sthurlow *piTokenType = pSpnegoToken->ucTokenType; 4984bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 4994bff34e3Sthurlow } 5004bff34e3Sthurlow 5014bff34e3Sthurlow } // IF parameters OK 5024bff34e3Sthurlow 5034bff34e3Sthurlow return nReturn; 5044bff34e3Sthurlow } 5054bff34e3Sthurlow 5064bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 5074bff34e3Sthurlow // 5084bff34e3Sthurlow // Function: 5094bff34e3Sthurlow // spnegoIsMechTypeAvailable 5104bff34e3Sthurlow // 5114bff34e3Sthurlow // Parameters: 5124bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 5134bff34e3Sthurlow // [in] MechOID - MechOID to search MechTypeList for 5144bff34e3Sthurlow // [out] piMechTypeIndex - Filled out with index in MechTypeList 5154bff34e3Sthurlow // element if MechOID is found. 5164bff34e3Sthurlow // 5174bff34e3Sthurlow // Returns: 5184bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 5194bff34e3Sthurlow // Failure - SPNEGO API Error code 5204bff34e3Sthurlow // 5214bff34e3Sthurlow // Comments : 5224bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenInit. The 5234bff34e3Sthurlow // function will search the MechTypeList element for an OID corresponding 5244bff34e3Sthurlow // to the specified MechOID. If one is found, the index (0 based) will 5254bff34e3Sthurlow // be passed into the piMechTypeIndex parameter. 5264bff34e3Sthurlow // 5274bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 5284bff34e3Sthurlow 5294bff34e3Sthurlow // Returns the Initial Mech Type in the MechList element in the NegInitToken. 5304bff34e3Sthurlow int spnegoIsMechTypeAvailable( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID MechOID, int * piMechTypeIndex ) 5314bff34e3Sthurlow { 5324bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 5334bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 5344bff34e3Sthurlow 5354bff34e3Sthurlow // Check parameters 5364bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 5374bff34e3Sthurlow NULL != piMechTypeIndex && 5384bff34e3Sthurlow IsValidMechOid( MechOID ) && 5394bff34e3Sthurlow SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 5404bff34e3Sthurlow { 5414bff34e3Sthurlow 5424bff34e3Sthurlow // Check if MechList is available 5434bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].iElementPresent 5444bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 5454bff34e3Sthurlow { 5464bff34e3Sthurlow // Locate the MechOID in the list element 5474bff34e3Sthurlow nReturn = FindMechOIDInMechList( 5484bff34e3Sthurlow &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT], 5494bff34e3Sthurlow MechOID, piMechTypeIndex ); 5504bff34e3Sthurlow } 5514bff34e3Sthurlow else 5524bff34e3Sthurlow { 5534bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 5544bff34e3Sthurlow } 5554bff34e3Sthurlow 5564bff34e3Sthurlow } // IF parameters OK 5574bff34e3Sthurlow 5584bff34e3Sthurlow return nReturn;; 5594bff34e3Sthurlow } 5604bff34e3Sthurlow 5614bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 5624bff34e3Sthurlow // 5634bff34e3Sthurlow // Function: 5644bff34e3Sthurlow // spnegoGetContextFlags 5654bff34e3Sthurlow // 5664bff34e3Sthurlow // Parameters: 5674bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 5684bff34e3Sthurlow // [out] pucContextFlags - Filled out with ContextFlags value. 5694bff34e3Sthurlow // 5704bff34e3Sthurlow // Returns: 5714bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 5724bff34e3Sthurlow // Failure - SPNEGO API Error code 5734bff34e3Sthurlow // 5744bff34e3Sthurlow // Comments : 5754bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenInit. The 5764bff34e3Sthurlow // function will copy data from the ContextFlags element into the 5774bff34e3Sthurlow // location pucContextFlags points to. Note that the function will 5784bff34e3Sthurlow // fail if the actual ContextFlags data appears invalid. 5794bff34e3Sthurlow // 5804bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 5814bff34e3Sthurlow 5824bff34e3Sthurlow int spnegoGetContextFlags( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucContextFlags ) 5834bff34e3Sthurlow { 5844bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 5854bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 5864bff34e3Sthurlow 5874bff34e3Sthurlow // Check parameters 5884bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 5894bff34e3Sthurlow NULL != pucContextFlags && 5904bff34e3Sthurlow SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 5914bff34e3Sthurlow { 5924bff34e3Sthurlow 5934bff34e3Sthurlow // Check if ContextFlags is available 5944bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].iElementPresent 5954bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 5964bff34e3Sthurlow { 5974bff34e3Sthurlow // The length should be two, the value should show a 1 bit difference in the difference byte, and 5984bff34e3Sthurlow // the value must be valid 5994bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS && 6004bff34e3Sthurlow pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF && 6014bff34e3Sthurlow IsValidContextFlags( pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1] ) ) 6024bff34e3Sthurlow { 6034bff34e3Sthurlow *pucContextFlags = pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1]; 6044bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 6054bff34e3Sthurlow } 6064bff34e3Sthurlow else 6074bff34e3Sthurlow { 6084bff34e3Sthurlow nReturn = SPNEGO_E_INVALID_ELEMENT; 6094bff34e3Sthurlow } 6104bff34e3Sthurlow 6114bff34e3Sthurlow } 6124bff34e3Sthurlow else 6134bff34e3Sthurlow { 6144bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 6154bff34e3Sthurlow } 6164bff34e3Sthurlow 6174bff34e3Sthurlow } // IF parameters OK 6184bff34e3Sthurlow 6194bff34e3Sthurlow return nReturn;; 6204bff34e3Sthurlow } 6214bff34e3Sthurlow 6224bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 6234bff34e3Sthurlow // 6244bff34e3Sthurlow // Function: 6254bff34e3Sthurlow // spnegoGetNegotiationResult 6264bff34e3Sthurlow // 6274bff34e3Sthurlow // Parameters: 6284bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 6294bff34e3Sthurlow // [out] pnegResult - Filled out with NegResult value. 6304bff34e3Sthurlow // 6314bff34e3Sthurlow // Returns: 6324bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 6334bff34e3Sthurlow // Failure - SPNEGO API Error code 6344bff34e3Sthurlow // 6354bff34e3Sthurlow // Comments : 6364bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenTarg. The 6374bff34e3Sthurlow // function will copy data from the NegResult element into the 6384bff34e3Sthurlow // location pointed to by pnegResult. Note that the function will 6394bff34e3Sthurlow // fail if the actual NegResult data appears invalid. 6404bff34e3Sthurlow // 6414bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 6424bff34e3Sthurlow 6434bff34e3Sthurlow int spnegoGetNegotiationResult( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESULT* pnegResult ) 6444bff34e3Sthurlow { 6454bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 6464bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 6474bff34e3Sthurlow 6484bff34e3Sthurlow // Check parameters 6494bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 6504bff34e3Sthurlow NULL != pnegResult && 6514bff34e3Sthurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) 6524bff34e3Sthurlow { 6534bff34e3Sthurlow 6544bff34e3Sthurlow // Check if NegResult is available 6554bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].iElementPresent 6564bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 6574bff34e3Sthurlow { 6584bff34e3Sthurlow // Must be 1 byte long and a valid value 6594bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT && 6604bff34e3Sthurlow IsValidNegResult( *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData ) ) 6614bff34e3Sthurlow { 6624bff34e3Sthurlow *pnegResult = *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData; 6634bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 6644bff34e3Sthurlow } 6654bff34e3Sthurlow else 6664bff34e3Sthurlow { 6674bff34e3Sthurlow nReturn = SPNEGO_E_INVALID_ELEMENT; 6684bff34e3Sthurlow } 6694bff34e3Sthurlow } 6704bff34e3Sthurlow else 6714bff34e3Sthurlow { 6724bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 6734bff34e3Sthurlow } 6744bff34e3Sthurlow 6754bff34e3Sthurlow } // IF parameters OK 6764bff34e3Sthurlow 6774bff34e3Sthurlow return nReturn;; 6784bff34e3Sthurlow } 6794bff34e3Sthurlow 6804bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 6814bff34e3Sthurlow // 6824bff34e3Sthurlow // Function: 6834bff34e3Sthurlow // spnegoGetSupportedMechType 6844bff34e3Sthurlow // 6854bff34e3Sthurlow // Parameters: 6864bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 6874bff34e3Sthurlow // [out] pMechOID - Filled out with Supported MechType value. 6884bff34e3Sthurlow // 6894bff34e3Sthurlow // Returns: 6904bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 6914bff34e3Sthurlow // Failure - SPNEGO API Error code 6924bff34e3Sthurlow // 6934bff34e3Sthurlow // Comments : 6944bff34e3Sthurlow // hSpnegoToken must reference a token of type NegTokenTarg. The 6954bff34e3Sthurlow // function will check the Supported MechType element, and if it 6964bff34e3Sthurlow // corresponds to a supported MechType ( spnego_mech_oid_Kerberos_V5_Legacy 6974bff34e3Sthurlow // or spnego_mech_oid_Kerberos_V5 ), will set the location pointed 6984bff34e3Sthurlow // to by pMechOID equal to the appropriate value. 6994bff34e3Sthurlow // 7004bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 7014bff34e3Sthurlow 7024bff34e3Sthurlow int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID ) 7034bff34e3Sthurlow { 7044bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 7054bff34e3Sthurlow int nCtr = 0L; 7064bff34e3Sthurlow long nLength = 0L; 7074bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 7084bff34e3Sthurlow 7094bff34e3Sthurlow // Check parameters 7104bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 7114bff34e3Sthurlow NULL != pMechOID && 7124bff34e3Sthurlow SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType ) 7134bff34e3Sthurlow { 7144bff34e3Sthurlow 7154bff34e3Sthurlow // Check if MechList is available 7164bff34e3Sthurlow if ( pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].iElementPresent 7174bff34e3Sthurlow == SPNEGO_TOKEN_ELEMENT_AVAILABLE ) 7184bff34e3Sthurlow { 7194bff34e3Sthurlow 7204bff34e3Sthurlow for ( nCtr = 0; 7214bff34e3Sthurlow nReturn != SPNEGO_E_SUCCESS && 7224bff34e3Sthurlow g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed; 7234bff34e3Sthurlow nCtr++ ) 7244bff34e3Sthurlow { 7254bff34e3Sthurlow 7264bff34e3Sthurlow if ( ( nReturn = ASNDerCheckOID( 7274bff34e3Sthurlow pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData, 7284bff34e3Sthurlow nCtr, 7294bff34e3Sthurlow pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].nDatalength, 7304bff34e3Sthurlow &nLength ) ) == SPNEGO_E_SUCCESS ) 7314bff34e3Sthurlow { 7324bff34e3Sthurlow *pMechOID = nCtr; 7334bff34e3Sthurlow } 7344bff34e3Sthurlow 7354bff34e3Sthurlow } // For enum MechOIDs 7364bff34e3Sthurlow 7374bff34e3Sthurlow 7384bff34e3Sthurlow } 7394bff34e3Sthurlow else 7404bff34e3Sthurlow { 7414bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 7424bff34e3Sthurlow } 7434bff34e3Sthurlow 7444bff34e3Sthurlow } // IF parameters OK 7454bff34e3Sthurlow 7464bff34e3Sthurlow return nReturn;; 7474bff34e3Sthurlow } 7484bff34e3Sthurlow 7494bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 7504bff34e3Sthurlow // 7514bff34e3Sthurlow // Function: 7524bff34e3Sthurlow // spnegoTokenGetMechToken 7534bff34e3Sthurlow // 7544bff34e3Sthurlow // Parameters: 7554bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 7564bff34e3Sthurlow // [out] pbTokenData - Buffer to copy MechToken into 7574bff34e3Sthurlow // [in/out] pulDataLen - Length of pbTokenData buffer, filled out 7584bff34e3Sthurlow // with actual size used upon function return. 7594bff34e3Sthurlow // 7604bff34e3Sthurlow // Returns: 7614bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 7624bff34e3Sthurlow // Failure - SPNEGO API Error code 7634bff34e3Sthurlow // 7644bff34e3Sthurlow // Comments : 7654bff34e3Sthurlow // hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token. 7664bff34e3Sthurlow // The function will copy the MechToken (the initial MechToken if 7674bff34e3Sthurlow // NegTokenInit, the response MechToken if NegTokenTarg) from the 7684bff34e3Sthurlow // underlying token into the buffer pointed to by pbTokenData. If 7694bff34e3Sthurlow // pbTokenData is NULL, or the value in pulDataLen is too small, the 7704bff34e3Sthurlow // function will return SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen 7714bff34e3Sthurlow // with the minimum required buffer size. The token can then be passed 7724bff34e3Sthurlow // to a GSS-API function for processing. 7734bff34e3Sthurlow // 7744bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 7754bff34e3Sthurlow 7764bff34e3Sthurlow int spnegoGetMechToken( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, unsigned long* pulDataLen ) 7774bff34e3Sthurlow { 7784bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 7794bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 7804bff34e3Sthurlow SPNEGO_ELEMENT* pSpnegoElement = NULL; 7814bff34e3Sthurlow 7824bff34e3Sthurlow // Check parameters 7834bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 7844bff34e3Sthurlow NULL != pulDataLen ) 7854bff34e3Sthurlow { 7864bff34e3Sthurlow 7874bff34e3Sthurlow // Point at the proper Element 7884bff34e3Sthurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 7894bff34e3Sthurlow { 7904bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT]; 7914bff34e3Sthurlow } 7924bff34e3Sthurlow else 7934bff34e3Sthurlow { 7944bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT]; 7954bff34e3Sthurlow } 7964bff34e3Sthurlow 7974bff34e3Sthurlow // Check if MechType is available 7984bff34e3Sthurlow if ( SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent ) 7994bff34e3Sthurlow { 8004bff34e3Sthurlow // Check for Buffer too small conditions 8014bff34e3Sthurlow if ( NULL == pbTokenData || 8024bff34e3Sthurlow pSpnegoElement->nDatalength > *pulDataLen ) 8034bff34e3Sthurlow { 8044bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 8054bff34e3Sthurlow nReturn = SPNEGO_E_BUFFER_TOO_SMALL; 8064bff34e3Sthurlow } 8074bff34e3Sthurlow else 8084bff34e3Sthurlow { 8094bff34e3Sthurlow // Copy Memory 8104bff34e3Sthurlow memcpy( pbTokenData, pSpnegoElement->pbData, pSpnegoElement->nDatalength ); 8114bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 8124bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 8134bff34e3Sthurlow } 8144bff34e3Sthurlow } 8154bff34e3Sthurlow else 8164bff34e3Sthurlow { 8174bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 8184bff34e3Sthurlow } 8194bff34e3Sthurlow 8204bff34e3Sthurlow } // IF parameters OK 8214bff34e3Sthurlow 8224bff34e3Sthurlow return nReturn;; 8234bff34e3Sthurlow } 8244bff34e3Sthurlow 8254bff34e3Sthurlow ///////////////////////////////////////////////////////////////////////////// 8264bff34e3Sthurlow // 8274bff34e3Sthurlow // Function: 8284bff34e3Sthurlow // spnegoTokenGetMechListMIC 8294bff34e3Sthurlow // 8304bff34e3Sthurlow // Parameters: 8314bff34e3Sthurlow // [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE 8324bff34e3Sthurlow // [out] pbTokenData - Buffer to copy MechListMIC data into 8334bff34e3Sthurlow // [in/out] pulDataLen - Length of pbTokenData buffer, filled out 8344bff34e3Sthurlow // with actual size used upon function return. 8354bff34e3Sthurlow // 8364bff34e3Sthurlow // Returns: 8374bff34e3Sthurlow // int Success - SPNEGO_E_SUCCESS 8384bff34e3Sthurlow // Failure - SPNEGO API Error code 8394bff34e3Sthurlow // 8404bff34e3Sthurlow // Comments : 8414bff34e3Sthurlow // hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token. 8424bff34e3Sthurlow // The function will copy the MechListMIC data from the underlying token 8434bff34e3Sthurlow // into the buffer pointed to by pbTokenData. If pbTokenData is NULL, 8444bff34e3Sthurlow // or the value in pulDataLen is too small, the function will return 8454bff34e3Sthurlow // SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen with the minimum 8464bff34e3Sthurlow // required buffer size. 8474bff34e3Sthurlow // 8484bff34e3Sthurlow //////////////////////////////////////////////////////////////////////////// 8494bff34e3Sthurlow 8504bff34e3Sthurlow int spnegoGetMechListMIC( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned long* pulDataLen ) 8514bff34e3Sthurlow { 8524bff34e3Sthurlow int nReturn = SPNEGO_E_INVALID_PARAMETER; 8534bff34e3Sthurlow SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) hSpnegoToken; 8544bff34e3Sthurlow SPNEGO_ELEMENT* pSpnegoElement = NULL; 8554bff34e3Sthurlow 8564bff34e3Sthurlow // Check parameters 8574bff34e3Sthurlow if ( IsValidSpnegoToken( pSpnegoToken ) && 8584bff34e3Sthurlow NULL != pulDataLen ) 8594bff34e3Sthurlow { 8604bff34e3Sthurlow 8614bff34e3Sthurlow // Point at the proper Element 8624bff34e3Sthurlow if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ) 8634bff34e3Sthurlow { 8644bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT]; 8654bff34e3Sthurlow } 8664bff34e3Sthurlow else 8674bff34e3Sthurlow { 8684bff34e3Sthurlow pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT]; 8694bff34e3Sthurlow } 8704bff34e3Sthurlow 8714bff34e3Sthurlow // Check if MechType is available 8724bff34e3Sthurlow if ( SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent ) 8734bff34e3Sthurlow { 8744bff34e3Sthurlow // Check for Buffer too small conditions 8754bff34e3Sthurlow if ( NULL == pbMICData || 8764bff34e3Sthurlow pSpnegoElement->nDatalength > *pulDataLen ) 8774bff34e3Sthurlow { 8784bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 8794bff34e3Sthurlow nReturn = SPNEGO_E_BUFFER_TOO_SMALL; 8804bff34e3Sthurlow } 8814bff34e3Sthurlow else 8824bff34e3Sthurlow { 8834bff34e3Sthurlow // Copy Memory 8844bff34e3Sthurlow memcpy( pbMICData, pSpnegoElement->pbData, pSpnegoElement->nDatalength ); 8854bff34e3Sthurlow *pulDataLen = pSpnegoElement->nDatalength; 8864bff34e3Sthurlow nReturn = SPNEGO_E_SUCCESS; 8874bff34e3Sthurlow } 8884bff34e3Sthurlow } 8894bff34e3Sthurlow else 8904bff34e3Sthurlow { 8914bff34e3Sthurlow nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE; 8924bff34e3Sthurlow } 8934bff34e3Sthurlow 8944bff34e3Sthurlow } // IF parameters OK 8954bff34e3Sthurlow 8964bff34e3Sthurlow return nReturn;; 8974bff34e3Sthurlow } 8984bff34e3Sthurlow 899