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
spnegoInitFromBinary(unsigned char * pbTokenData,unsigned long ulLength,SPNEGO_TOKEN_HANDLE * phSpnegoToken)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
spnegoCreateNegTokenHint(SPNEGO_MECH_OID * pMechTypeList,int MechTypeCnt,unsigned char * pbPrincipal,SPNEGO_TOKEN_HANDLE * phSpnegoToken)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
spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,unsigned char ucContextFlags,unsigned char * pbMechToken,unsigned long ulMechTokenLen,unsigned char * pbMechListMIC,unsigned long ulMechListMICLen,SPNEGO_TOKEN_HANDLE * phSpnegoToken)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
spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,SPNEGO_NEGRESULT spnegoNegResult,unsigned char * pbMechToken,unsigned long ulMechTokenLen,unsigned char * pbMechListMIC,unsigned long ulMechListMICLen,SPNEGO_TOKEN_HANDLE * phSpnegoToken)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
spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,unsigned char * pbTokenData,unsigned long * pulDataLen)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
spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken)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
spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken,int * piTokenType)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.
spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,SPNEGO_MECH_OID MechOID,int * piMechTypeIndex)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
spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,unsigned char * pucContextFlags)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
spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,SPNEGO_NEGRESULT * pnegResult)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
spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,SPNEGO_MECH_OID * pMechOID)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
spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken,unsigned char * pbTokenData,unsigned long * pulDataLen)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
spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken,unsigned char * pbMICData,unsigned long * pulDataLen)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