1 /*
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  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
17  * Copyright 2022 RackTop Systems, Inc.
18  */
19 
20 /*
21  * spnego.h
22  *
23  * SPNEGO Token Handler Header File
24  *
25  * Contains the definitions required to interpret and create
26  * SPNEGO tokens so that Kerberos GSS tokens can be
27  * Unpackaged/packaged.
28  */
29 
30 #ifndef _SPNEGO_H
31 #define	_SPNEGO_H
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * Type Definitions
39  */
40 
41 /*
42  * Users of SPNEGO Token Handler API will request
43  * these as well as free them,
44  */
45 typedef void*  SPNEGO_TOKEN_HANDLE;
46 
47 /*
48  * Defines the element types that are found
49  * in each of the tokens.
50  */
51 
52 typedef enum spnego_element_type
53 {
54 	spnego_element_min,  /* Lower bound */
55 
56 	/* Init token elements */
57 	spnego_init_mechtypes,
58 	spnego_init_reqFlags,
59 	spnego_init_mechToken,
60 	spnego_init_mechListMIC,
61 
62 	/* Targ token elements */
63 	spnego_targ_negResult,
64 	spnego_targ_supportedMech,
65 	spnego_targ_responseToken,
66 	spnego_targ_mechListMIC,
67 
68 	spnego_element_max   /* Upper bound */
69 
70 } SPNEGO_ELEMENT_TYPE;
71 
72 /*
73  * Token Element Availability.  Elements in both
74  * token types are optional.  Since there are only
75  * 4 elements in each Token, we will allocate space
76  * to hold the information, but we need a way to
77  * indicate whether or not an element is available
78  */
79 
80 #define	SPNEGO_TOKEN_ELEMENT_UNAVAILABLE 0
81 #define	SPNEGO_TOKEN_ELEMENT_AVAILABLE 1
82 
83 /*
84  * Token type values.  SPNEGO has 2 token types:
85  * NegTokenInit and NegTokenTarg
86  */
87 
88 #define	SPNEGO_TOKEN_INIT 0
89 #define	SPNEGO_TOKEN_TARG 1
90 
91 /*
92  * GSS Mechanism OID enumeration.  We only really handle
93  * 3 different OIDs.  These are stored in an array structure
94  * defined in the parsing code.
95  */
96 
97 typedef enum spnego_mech_oid
98 {
99 	/* Init token elements */
100 	spnego_mech_oid_Kerberos_V5_Legacy, /* Really V5, but OID off by 1 */
101 	spnego_mech_oid_Kerberos_V5,
102 	spnego_mech_oid_Spnego,
103 	spnego_mech_oid_NTLMSSP,
104 	spnego_mech_oid_NotUsed = -1
105 
106 } SPNEGO_MECH_OID;
107 
108 /*
109  * Defines the negResult values.
110  */
111 
112 typedef enum spnego_negResult
113 {
114 	spnego_negresult_success,
115 	spnego_negresult_incomplete,
116 	spnego_negresult_rejected,
117 	spnego_negresult_request_mic,
118 	spnego_negresult_NotUsed = -1
119 } SPNEGO_NEGRESULT;
120 
121 /*
122  * Context Flags in NegTokenInit
123  */
124 
125 /*
126  * ContextFlags values MUST be zero or a combination
127  * of the below
128  */
129 
130 #define	SPNEGO_NEGINIT_CONTEXT_DELEG_FLAG	0x80
131 #define	SPNEGO_NEGINIT_CONTEXT_MUTUAL_FLAG	0x40
132 #define	SPNEGO_NEGINIT_CONTEXT_REPLAY_FLAG	0x20
133 #define	SPNEGO_NEGINIT_CONTEXT_SEQUENCE_FLAG	0x10
134 #define	SPNEGO_NEGINIT_CONTEXT_ANON_FLAG	0x8
135 #define	SPNEGO_NEGINIT_CONTEXT_CONF_FLAG	0x4
136 #define	SPNEGO_NEGINIT_CONTEXT_INTEG_FLAG	0x2
137 
138 /*
139  * Mask to retrieve valid values.
140  */
141 
142 #define	SPNEGO_NEGINIT_CONTEXT_MASK	0xFE
143 
144 /*
145  * SPNEGO API return codes.
146  */
147 
148 /* API function was successful */
149 #define	SPNEGO_E_SUCCESS		0
150 
151 /* The supplied Token was invalid */
152 #define	SPNEGO_E_INVALID_TOKEN		-1
153 
154 /* An invalid length was encountered */
155 #define	SPNEGO_E_INVALID_LENGTH		-2
156 
157 /* The Token Parse failed */
158 #define	SPNEGO_E_PARSE_FAILED		-3
159 
160 /* The requested value was not found */
161 #define	SPNEGO_E_NOT_FOUND		-4
162 
163 /* The requested element is not available */
164 #define	SPNEGO_E_ELEMENT_UNAVAILABLE	-5
165 
166 /* Out of Memory */
167 #define	SPNEGO_E_OUT_OF_MEMORY		-6
168 
169 /* Not Implemented */
170 #define	SPNEGO_E_NOT_IMPLEMENTED	-7
171 
172 /* Invalid Parameter */
173 #define	SPNEGO_E_INVALID_PARAMETER	-8
174 
175 /* Token Handler encountered an unexpected OID */
176 #define	SPNEGO_E_UNEXPECTED_OID		-9
177 
178 /* The requested token was not found */
179 #define	SPNEGO_E_TOKEN_NOT_FOUND	-10
180 
181 /* An unexpected type was encountered in the encoding */
182 #define	SPNEGO_E_UNEXPECTED_TYPE	-11
183 
184 /* The buffer was too small */
185 #define	SPNEGO_E_BUFFER_TOO_SMALL	-12
186 
187 /* A Token Element was invalid (e.g. improper length or value) */
188 #define	SPNEGO_E_INVALID_ELEMENT	-13
189 
190 /* Miscelaneous API Functions */
191 
192 /* Frees opaque data */
193 void spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken);
194 
195 /* Initializes SPNEGO_TOKEN structure from DER encoded binary data */
196 int spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
197 	SPNEGO_TOKEN_HANDLE* phSpnegoToken);
198 
199 /* Initializes SPNEGO_TOKEN structure for a NegTokenInit type */
200 int spnegoCreateNegTokenHint(SPNEGO_MECH_OID *pMechTypeList, int MechTypeCnt,
201 	unsigned char *pbPrincipal, SPNEGO_TOKEN_HANDLE* phSpnegoToken);
202 
203 /* Initializes SPNEGO_TOKEN structure for a NegTokenInit type */
204 int spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
205 	unsigned char ucContextFlags, unsigned char *pbMechToken,
206 	unsigned long ulMechTokenLen, unsigned char *pbMechTokenMIC,
207 	unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE *phSpnegoToken);
208 
209 /* Initializes SPNEGO_TOKEN structure for a NegTokenTarg type */
210 int spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
211 	SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
212 	unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
213 	unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken);
214 
215 /* Copies binary representation of SPNEGO Data into user supplied buffer */
216 int spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
217 	unsigned char *pbTokenData, unsigned long *pulDataLen);
218 
219 /* Returns SPNEGO Token Type */
220 int spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int *piTokenType);
221 
222 /* Reading an Init Token */
223 
224 /* Returns the Initial Mech Type in the MechList element in the NegInitToken. */
225 int spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
226 	SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
227 
228 /* Returns the value from the context flags element in the NegInitToken */
229 int spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
230 	unsigned char *pucContextFlags);
231 
232 /* Reading a Response Token */
233 
234 /*
235  * Returns the value from the negResult element
236  * (Status code of GSS call - 0,1,2)
237  */
238 int spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
239 	SPNEGO_NEGRESULT* pnegResult);
240 
241 /* Returns the Supported Mech Type from the NegTokenTarg. */
242 int spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
243 	SPNEGO_MECH_OID* pMechOID);
244 
245 /* Reading either Token Type */
246 
247 /*
248  * Returns the actual Mechanism data from the token
249  * (this is what is passed into GSS-API functions
250  */
251 int spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken,
252 	unsigned char *pbTokenData, unsigned long *pulDataLen);
253 
254 /* Returns the Message Integrity BLOB in the token */
255 int spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken,
256 	unsigned char *pbMICData, unsigned long *pulDataLen);
257 
258 #ifdef __cplusplus
259 }
260 #endif
261 
262 #endif /* _SPNEGO_H */
263