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