1 // Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
2 // Copyright (C) 2002 Microsoft Corporation
3 // All rights reserved.
4 //
5 // THIS CODE AND INFORMATION IS PROVIDED "AS IS"
6 // WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
7 // OR IMPLIED, INCLUDING BUT NOT LIMITED
8 // TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
9 // AND/OR FITNESS FOR A PARTICULAR PURPOSE.
10 //
11 // Date    - 10/08/2002
12 // Author  - Sanj Surati
13 
14 /////////////////////////////////////////////////////////////
15 //
16 // SPNEGOPARSE.H
17 //
18 // SPNEGO Token Parser Header File
19 //
20 // Contains the definitions required to properly parse a
21 // SPNEGO token using ASN.1 DER helpers.
22 //
23 /////////////////////////////////////////////////////////////
24 
25 #ifndef __SPNEGOPARSE_H__
26 #define __SPNEGOPARSE_H__
27 
28 // C++ Specific
29 #if defined(__cplusplus)
30 extern "C"
31 {
32 #endif
33 
34 // Indicates if we copy data when creating a SPNEGO_TOKEN structure or not
35 #define SPNEGO_TOKEN_INTERNAL_COPYPTR           0
36 #define SPNEGO_TOKEN_INTERNAL_COPYDATA          0x1
37 
38 // Internal flag dictates whether or not we will free the binary data when
39 // the SPNEG_TOKEN structure is destroyed
40 #define  SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA   0x1
41 
42    //
43 // Each SPNEGO Token Type can be broken down into a
44 // maximum of 4 separate elements.
45 //
46 
47 #define  MAX_NUM_TOKEN_ELEMENTS  4
48 
49 //
50 // Element offsets in the array
51 //
52 
53 // INIT elements
54 #define  SPNEGO_INIT_MECHTYPES_ELEMENT    0
55 #define  SPNEGO_INIT_REQFLAGS_ELEMENT     1
56 #define  SPNEGO_INIT_MECHTOKEN_ELEMENT    2
57 #define  SPNEGO_INIT_MECHLISTMIC_ELEMENT  3
58 
59 // Response elements
60 #define  SPNEGO_TARG_NEGRESULT_ELEMENT    0
61 #define  SPNEGO_TARG_SUPPMECH_ELEMENT     1
62 #define  SPNEGO_TARG_RESPTOKEN_ELEMENT    2
63 #define  SPNEGO_TARG_MECHLISTMIC_ELEMENT  3
64 
65 //
66 // Defines an individual SPNEGO Token Element.
67 //
68 
69 typedef struct SpnegoElement
70 {
71    size_t                nStructSize;        // Size of the element structure
72    int                   iElementPresent;    // Is the field present?  Must be either
73                                              // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
74                                              // SPNEGO_TOKEN_ELEMENT_AVAILABLE
75 
76    SPNEGO_ELEMENT_TYPE   eElementType;       // The Element Type
77 
78    unsigned char         type;               // Data Type
79 
80    unsigned char*        pbData;             // Points to actual Data
81 
82    unsigned long         nDatalength;        // Actual Data Length
83 
84 } SPNEGO_ELEMENT;
85 
86 // Structure size in case we later choose to extend the structure
87 #define  SPNEGO_ELEMENT_SIZE sizeof(SPNEGO_ELEMENT)
88 
89 //
90 // Packages a SPNEGO Token Encoding.  There are two types of
91 // encodings: NegTokenInit and NegTokenTarg.  Each encoding can
92 // contain up to four distinct, optional elements.
93 //
94 
95 typedef struct SpnegoToken
96 {
97    size_t            nStructSize;                              // Size of the Token structure
98    unsigned long     ulFlags;                                  // Internal Structure Flags - Reserved!
99    int               ucTokenType;                              // Token Type - Must be
100                                                                // SPNEGO_TOKEN_INIT or
101                                                                // SPNEGO_TOKEN_TARG
102 
103    unsigned char*    pbBinaryData;                             // Points to binary token data
104 
105    unsigned long     ulBinaryDataLen;                          // Length of the actual binary data
106    int               nNumElements;                             // Number of elements
107    SPNEGO_ELEMENT    aElementArray [MAX_NUM_TOKEN_ELEMENTS];   // Holds the elements for the token
108 } SPNEGO_TOKEN;
109 
110 // Structure size in case we later choose to extend the structure
111 #define  SPNEGO_TOKEN_SIZE sizeof(SPNEGO_TOKEN)
112 
113 //
114 // Function definitions
115 //
116 
117 SPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulFlags,
118                                     unsigned char * pbTokenData, unsigned long ulTokenSize );
119 void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken );
120 void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken );
121 int InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength,
122                            long* pnRemainingTokenLength, unsigned char** ppbFirstElement );
123 int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenData,
124                            long nRemainingTokenLength  );
125 int GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength,
126                                  SPNEGO_ELEMENT* pSpnegoElement );
127 int InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElementLength,
128                                           unsigned char ucExpectedType,
129                                           SPNEGO_ELEMENT_TYPE spnegoElementType,
130                                           SPNEGO_ELEMENT* pSpnegoElement );
131 int InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLength,
132                                    SPNEGO_ELEMENT_TYPE spnegoElementType,
133                                    SPNEGO_ELEMENT* pSpnegoElement );
134 int FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechOID,
135                            int * piMechTypeIndex );
136 int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength );
137 int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, long nMechListMICLength,
138          SPNEGO_MECH_OID *mechOid, int mechOidCnt, int nReqFlagsAvailable,
139                                     long* plTokenSize, long* plInternalLength );
140 int CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType, SPNEGO_NEGRESULT spnegoNegResult,
141                                     long nMechTokenLen,
142                                     long nMechTokenMIC, long* pnTokenSize,
143                                     long* pnInternalTokenLength );
144 int CreateSpnegoInitToken( SPNEGO_MECH_OID *MechTypeList, long nMechTypes,
145           unsigned char ucContextFlags, unsigned char* pbMechToken,
146           unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
147           unsigned long ulMechListMICLen, unsigned char* pbTokenData,
148           long nTokenLength, long nInternalTokenLength );
149 int CreateSpnegoTargToken( SPNEGO_MECH_OID MechType,
150           SPNEGO_NEGRESULT eNegResult, unsigned char* pbMechToken,
151           unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
152           unsigned long ulMechListMICLen, unsigned char* pbTokenData,
153           long nTokenLength, long nInternalTokenLength );
154 int IsValidMechOid( SPNEGO_MECH_OID mechOid );
155 int IsValidContextFlags( unsigned char ucContextFlags );
156 int IsValidNegResult( SPNEGO_NEGRESULT negResult );
157 int IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken );
158 int IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement );
159 int CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement );
160 int InitTokenFromBinary( unsigned char ucCopyData, unsigned long ulFlags,
161                         unsigned char* pbTokenData, unsigned long ulLength,
162                         SPNEGO_TOKEN** ppSpnegoToken );
163 
164    // C++ Specific
165 #if defined(__cplusplus)
166 }
167 #endif
168 
169 #endif
170