xref: /illumos-gate/usr/src/lib/libsmbfs/smb/spnego.c (revision 55fea89d)
112b65585SGordon 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>
2712b65585SGordon 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 
8912b65585SGordon Ross /////////////////////////////////////////////////////////////////////////////
9012b65585SGordon Ross //
9112b65585SGordon Ross // Function:
9212b65585SGordon Ross //    spnegoCreateNegTokenHint
9312b65585SGordon Ross //
9412b65585SGordon Ross // Parameters:
9512b65585SGordon Ross //    [in]  pMechTypeList     -  List of MechTypes (OIDs) to include
9612b65585SGordon Ross //    [in]  MechTypeCnt       -  Length of MechTypes array
9712b65585SGordon Ross //    [in]  pbPrincipal       -  Principal name for MechListMIC
9812b65585SGordon Ross //    [out] phSpnegoToken     -  SPNEGO_TOKEN_HANDLE pointer
9912b65585SGordon Ross //
10012b65585SGordon Ross // Returns:
10112b65585SGordon Ross //    int   Success - SPNEGO_E_SUCCESS
10212b65585SGordon Ross //          Failure - SPNEGO API Error code
10312b65585SGordon Ross //
10412b65585SGordon Ross // Comments :
10512b65585SGordon Ross //    Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenInit type token
10612b65585SGordon Ross //    from the supplied parameters.  The token created is the "hint"
10712b65585SGordon Ross //    used (for example) in the response to an SMB negotiate protocol.
10812b65585SGordon Ross //    Returned data structure must be freed by calling spnegoFreeData().
10912b65585SGordon Ross //
11012b65585SGordon Ross //    The "hint" tells the client what authentication methods this
11112b65585SGordon Ross //    server supports (the ones in the MechTypeList).  The Principal
11212b65585SGordon Ross //    name historically was the server's own SPN, but recent versions
11312b65585SGordon Ross //    of windows only supply: "not_defined_in_RFC4178@please_ignore"
11412b65585SGordon Ross //    So if you want to be nice to your clients, provide the host SPN,
11512b65585SGordon Ross //    otherwise provide the bogus SPN string like recent windows.
11612b65585SGordon Ross //
11712b65585SGordon Ross ////////////////////////////////////////////////////////////////////////////
11812b65585SGordon Ross 
spnegoCreateNegTokenHint(SPNEGO_MECH_OID * pMechTypeList,int MechTypeCnt,unsigned char * pbPrincipal,SPNEGO_TOKEN_HANDLE * phSpnegoToken)11912b65585SGordon Ross int spnegoCreateNegTokenHint( SPNEGO_MECH_OID *pMechTypeList, int MechTypeCnt,
12012b65585SGordon Ross 	unsigned char *pbPrincipal, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
12112b65585SGordon Ross {
12212b65585SGordon Ross 	int   nReturn;
12312b65585SGordon Ross 	long  nTokenLength = 0L;
12412b65585SGordon Ross 	long  nInternalTokenLength = 0L;
12512b65585SGordon Ross 	unsigned long ulPrincipalLen;
12612b65585SGordon Ross 	unsigned char* pbMechListMIC;
12712b65585SGordon Ross 	unsigned long ulMechListMICLen;
12812b65585SGordon Ross 	unsigned char* pbTokenData = NULL;
12912b65585SGordon Ross 	SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken;
13012b65585SGordon Ross 
13112b65585SGordon Ross 	if ( NULL == ppSpnegoToken || NULL == pbPrincipal )
13212b65585SGordon Ross 		return (SPNEGO_E_INVALID_PARAMETER);
13312b65585SGordon Ross 
13412b65585SGordon Ross 	/*
13512b65585SGordon Ross 	 * Get the actual token size
13612b65585SGordon Ross 	 */
13712b65585SGordon Ross 	ulPrincipalLen = strlen((char *)pbPrincipal);
13812b65585SGordon Ross 	ulMechListMICLen = ASNDerCalcElementLength( ulPrincipalLen, NULL );
13912b65585SGordon Ross 	nReturn = CalculateMinSpnegoInitTokenSize(
14012b65585SGordon Ross 		0, /* ulMechTokenLen */
14112b65585SGordon Ross 		ulMechListMICLen,
14212b65585SGordon Ross 		pMechTypeList,
14312b65585SGordon Ross 		MechTypeCnt,
14412b65585SGordon Ross 		0, /* nReqFlagsAvailable */
14512b65585SGordon Ross 		&nTokenLength,
14612b65585SGordon Ross 		&nInternalTokenLength );
14712b65585SGordon Ross 	if ( nReturn != SPNEGO_E_SUCCESS )
14812b65585SGordon Ross 		return (nReturn);
14912b65585SGordon Ross 
15012b65585SGordon Ross 	// Allocate a buffer to hold the data.
15112b65585SGordon Ross 	pbTokenData = calloc( 1, nTokenLength );
15212b65585SGordon Ross 
15312b65585SGordon Ross 	if ( NULL == pbTokenData )
15412b65585SGordon Ross 		return ( SPNEGO_E_OUT_OF_MEMORY );
15512b65585SGordon Ross 
15612b65585SGordon Ross 	/*
15712b65585SGordon Ross 	 * Construct the MechListMIC
15812b65585SGordon Ross 	 */
15912b65585SGordon Ross 	pbMechListMIC = pbTokenData + (nTokenLength - ulMechListMICLen);
16012b65585SGordon Ross 	(void) ASNDerWriteElement( pbMechListMIC, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
16112b65585SGordon Ross 				   GENERALSTR, pbPrincipal, ulPrincipalLen );
16212b65585SGordon Ross 
16312b65585SGordon Ross 	// Now write the token
16412b65585SGordon Ross 	nReturn = CreateSpnegoInitToken(
16512b65585SGordon Ross 		pMechTypeList,
16612b65585SGordon Ross 		MechTypeCnt,
16712b65585SGordon Ross 		0, /* ContextFlags */
16812b65585SGordon Ross 		NULL, 0, /* MechToken, len */
16912b65585SGordon Ross 		pbMechListMIC,
17012b65585SGordon Ross 		ulMechListMICLen,
17112b65585SGordon Ross 		pbTokenData,
17212b65585SGordon Ross 		nTokenLength,
17312b65585SGordon Ross 		nInternalTokenLength );
17412b65585SGordon Ross 	if ( nReturn != SPNEGO_E_SUCCESS ) {
17512b65585SGordon Ross 		free( pbTokenData );
17612b65585SGordon Ross 		return (nReturn);
17712b65585SGordon Ross 	}
17812b65585SGordon Ross 
17912b65585SGordon Ross 	// This will copy our allocated pointer, and ensure that the sructure cleans
18012b65585SGordon Ross 	// up the data later
18112b65585SGordon Ross 	nReturn = InitTokenFromBinary( SPNEGO_TOKEN_INTERNAL_COPYPTR,
18212b65585SGordon Ross 				       SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
18312b65585SGordon Ross 				       pbTokenData, nTokenLength, ppSpnegoToken );
18412b65585SGordon Ross 
18512b65585SGordon Ross 	// Cleanup on failure
18612b65585SGordon Ross 	if ( nReturn != SPNEGO_E_SUCCESS ) {
18712b65585SGordon Ross 		free( pbTokenData );
18812b65585SGordon Ross 		return (nReturn);
18912b65585SGordon Ross 	}
19012b65585SGordon Ross 
19112b65585SGordon Ross 	return (SPNEGO_E_SUCCESS);
19212b65585SGordon Ross }
19312b65585SGordon Ross 
1944bff34e3Sthurlow /////////////////////////////////////////////////////////////////////////////
1954bff34e3Sthurlow //
1964bff34e3Sthurlow // 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 
238*55fea89dSDan Cross       if ( ( nReturn = CalculateMinSpnegoInitTokenSize( ulMechTokenLen, ulMechListMICLen,
239*55fea89dSDan Cross 							&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
25012b65585SGordon 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)311*55fea89dSDan Cross 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 ) ||
33512b65585SGordon Ross             spnego_negresult_NotUsed == spnegoNegResult ) )
3364bff34e3Sthurlow    {
3374bff34e3Sthurlow 
3384bff34e3Sthurlow       // Get the actual token size
3394bff34e3Sthurlow 
3404bff34e3Sthurlow       if ( ( nReturn = CalculateMinSpnegoTargTokenSize( MechType, spnegoNegResult, ulMechTokenLen,
341*55fea89dSDan Cross                                                          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;
415*55fea89dSDan Cross 
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;
486*55fea89dSDan Cross 
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;
534*55fea89dSDan Cross 
5354bff34e3Sthurlow    // Check parameters
5364bff34e3Sthurlow    if (  IsValidSpnegoToken( pSpnegoToken ) &&
5374bff34e3Sthurlow          NULL != piMechTypeIndex &&
538*55fea89dSDan Cross          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;
586*55fea89dSDan Cross 
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;
647*55fea89dSDan Cross 
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;
708*55fea89dSDan Cross 
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       {
719*55fea89dSDan Cross 
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;
781*55fea89dSDan Cross 
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;
855*55fea89dSDan Cross 
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