xref: /freebsd/crypto/krb5/src/lib/gssapi/generic/gssapi_generic.c (revision b670c9bafc0e31c7609969bf374b2e80bdc00211)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright 1993 by OpenVision Technologies, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software
6  * and its documentation for any purpose is hereby granted without fee,
7  * provided that the above copyright notice appears in all copies and
8  * that both that copyright notice and this permission notice appear in
9  * supporting documentation, and that the name of OpenVision not be used
10  * in advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission. OpenVision makes no
12  * representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21  * PERFORMANCE OF THIS SOFTWARE.
22  */
23 
24 /*
25  * $Id$
26  */
27 
28 #include "gssapiP_generic.h"
29 
30 /*
31  * See krb5/gssapi_krb5.c for a description of the algorithm for
32  * encoding an object identifier.
33  */
34 
35 /* Reserved static storage for GSS_oids.  Comments are quotes from RFC 2744. */
36 
37 #define oids ((gss_OID_desc *)const_oids)
38 static const gss_OID_desc const_oids[] = {
39     /*
40      * The implementation must reserve static storage for a
41      * gss_OID_desc object containing the value */
42     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
43     /* corresponding to an object-identifier value of
44      * {iso(1) member-body(2) United States(840) mit(113554)
45      * infosys(1) gssapi(2) generic(1) user_name(1)}.  The constant
46      * GSS_C_NT_USER_NAME should be initialized to point
47      * to that gss_OID_desc.
48      */
49 
50     /*
51      * The implementation must reserve static storage for a
52      * gss_OID_desc object containing the value */
53     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
54     /* corresponding to an object-identifier value of
55      * {iso(1) member-body(2) United States(840) mit(113554)
56      * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
57      * The constant GSS_C_NT_MACHINE_UID_NAME should be
58      * initialized to point to that gss_OID_desc.
59      */
60 
61     /*
62      * The implementation must reserve static storage for a
63      * gss_OID_desc object containing the value */
64     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
65     /* corresponding to an object-identifier value of
66      * {iso(1) member-body(2) United States(840) mit(113554)
67      * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
68      * The constant GSS_C_NT_STRING_UID_NAME should be
69      * initialized to point to that gss_OID_desc.
70      */
71 
72     /*
73      * The implementation must reserve static storage for a
74      * gss_OID_desc object containing the value */
75     {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
76     /* corresponding to an object-identifier value of
77      * {iso(1) org(3) dod(6) internet(1) security(5)
78      * nametypes(6) gss-host-based-services(2)).  The constant
79      * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
80      * to that gss_OID_desc.  This is a deprecated OID value, and
81      * implementations wishing to support hostbased-service names
82      * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
83      * defined below, to identify such names;
84      * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
85      * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
86      * parameter, but should not be emitted by GSS-API
87      * implementations
88      */
89 
90     /*
91      * The implementation must reserve static storage for a
92      * gss_OID_desc object containing the value */
93     {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"},
94     /* corresponding to an object-identifier value of
95      * {iso(1) member-body(2) Unites States(840) mit(113554)
96      * infosys(1) gssapi(2) generic(1) service_name(4)}.
97      * The constant GSS_C_NT_HOSTBASED_SERVICE should be
98      * initialized to point to that gss_OID_desc.
99      */
100 
101     /*
102      * The implementation must reserve static storage for a
103      * gss_OID_desc object containing the value */
104     {6, (void *)"\x2b\x06\01\x05\x06\x03"},
105     /* corresponding to an object identifier value of
106      * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
107      * 6(nametypes), 3(gss-anonymous-name)}.  The constant
108      * and GSS_C_NT_ANONYMOUS should be initialized to point
109      * to that gss_OID_desc.
110      */
111 
112     /*
113      * The implementation must reserve static storage for a
114      * gss_OID_desc object containing the value */
115     {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
116     /* corresponding to an object-identifier value of
117      * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
118      * 6(nametypes), 4(gss-api-exported-name)}.  The constant
119      * GSS_C_NT_EXPORT_NAME should be initialized to point
120      * to that gss_OID_desc.
121      */
122     {6, (void *)"\x2b\x06\x01\x05\x06\x06"},
123     /* corresponding to an object-identifier value of
124      * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
125      * 6(nametypes), 6(gss-composite-export)}.  The constant
126      * GSS_C_NT_COMPOSITE_EXPORT should be initialized to point
127      * to that gss_OID_desc.
128      */
129     /* GSS_C_INQ_SSPI_SESSION_KEY 1.2.840.113554.1.2.2.5.5 */
130     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"},
131     /* GSS_C_INQ_NEGOEX_KEY 1.2.840.113554.1.2.2.5.16 */
132     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x10"},
133     /* GSS_C_INQ_NEGOEX_VERIFY_KEY 1.2.840.113554.1.2.2.5.17 */
134     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x11"},
135 
136     /* RFC 5587 attributes, see below */
137     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x01"},
138     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x02"},
139     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x03"},
140     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x04"},
141     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x05"},
142     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x06"},
143     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x07"},
144     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x08"},
145     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x09"},
146     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0a"},
147     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0b"},
148     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0c"},
149     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0d"},
150     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0e"},
151     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x0f"},
152     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x10"},
153     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x11"},
154     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x12"},
155     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x13"},
156     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x14"},
157     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x15"},
158     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x16"},
159     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x17"},
160     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x18"},
161     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"},
162     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"},
163     {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"},
164     /* GSS_C_MA_NEGOEX_AND_SPNEGO 1.2.840.113554.1.2.2.5.18 */
165     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x12"},
166 
167     /*
168      * GSS_SEC_CONTEXT_SASL_SSF_OID 1.2.840.113554.1.2.2.5.15
169      * iso(1) member-body(2) United States(840) mit(113554)
170      * infosys(1) gssapi(2) krb5(2) krb5-gssapi-ext(5) sasl-ssf(15)
171      */
172     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"},
173 
174     /*
175      * GSS_C_INQ_ODBC_SESSION_KEY 1.2.840.113554.1.2.2.5.19
176      * iso(1) member-body(2) United States(840) mit(113554)
177      * infosys(1) ssapi(2) krb5(2) krb5-gssapi-ext(5)
178      * inq-odbc-session-key(19)
179      */
180     {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05\13"},
181 };
182 
183 /* Here are the constants which point to the static structure above.
184  *
185  * Constants of the form GSS_C_NT_* are specified by rfc 2744.
186  *
187  * Constants of the form gss_nt_* are the original MIT krb5 names
188  * found in gssapi_generic.h.  They are provided for compatibility. */
189 
190 GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME           = oids+0;
191 GSS_DLLIMP gss_OID gss_nt_user_name             = oids+0;
192 
193 GSS_DLLIMP gss_OID GSS_C_NT_MACHINE_UID_NAME    = oids+1;
194 GSS_DLLIMP gss_OID gss_nt_machine_uid_name      = oids+1;
195 
196 GSS_DLLIMP gss_OID GSS_C_NT_STRING_UID_NAME     = oids+2;
197 GSS_DLLIMP gss_OID gss_nt_string_uid_name       = oids+2;
198 
199 GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = oids+3;
200 gss_OID gss_nt_service_name_v2                  = oids+3;
201 
202 GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE   = oids+4;
203 GSS_DLLIMP gss_OID gss_nt_service_name          = oids+4;
204 
205 GSS_DLLIMP gss_OID GSS_C_NT_ANONYMOUS           = oids+5;
206 
207 GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME         = oids+6;
208 gss_OID gss_nt_exported_name                    = oids+6;
209 
210 GSS_DLLIMP gss_OID GSS_C_NT_COMPOSITE_EXPORT    = oids+7;
211 GSS_DLLIMP gss_OID GSS_C_INQ_SSPI_SESSION_KEY   = oids+8;
212 GSS_DLLIMP gss_OID GSS_C_INQ_NEGOEX_KEY         = oids+9;
213 GSS_DLLIMP gss_OID GSS_C_INQ_NEGOEX_VERIFY_KEY  = oids+10;
214 
215 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_CONCRETE     = oids+11;
216 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_PSEUDO       = oids+12;
217 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_COMPOSITE    = oids+13;
218 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_NEGO         = oids+14;
219 GSS_DLLIMP gss_const_OID GSS_C_MA_MECH_GLUE         = oids+15;
220 GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_MECH          = oids+16;
221 GSS_DLLIMP gss_const_OID GSS_C_MA_DEPRECATED        = oids+17;
222 GSS_DLLIMP gss_const_OID GSS_C_MA_NOT_DFLT_MECH     = oids+18;
223 GSS_DLLIMP gss_const_OID GSS_C_MA_ITOK_FRAMED       = oids+19;
224 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT         = oids+20;
225 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG         = oids+21;
226 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_INIT    = oids+22;
227 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_INIT    = oids+23;
228 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_INIT_ANON    = oids+24;
229 GSS_DLLIMP gss_const_OID GSS_C_MA_AUTH_TARG_ANON    = oids+25;
230 GSS_DLLIMP gss_const_OID GSS_C_MA_DELEG_CRED        = oids+26;
231 GSS_DLLIMP gss_const_OID GSS_C_MA_INTEG_PROT        = oids+27;
232 GSS_DLLIMP gss_const_OID GSS_C_MA_CONF_PROT         = oids+28;
233 GSS_DLLIMP gss_const_OID GSS_C_MA_MIC               = oids+29;
234 GSS_DLLIMP gss_const_OID GSS_C_MA_WRAP              = oids+30;
235 GSS_DLLIMP gss_const_OID GSS_C_MA_PROT_READY        = oids+31;
236 GSS_DLLIMP gss_const_OID GSS_C_MA_REPLAY_DET        = oids+32;
237 GSS_DLLIMP gss_const_OID GSS_C_MA_OOS_DET           = oids+33;
238 GSS_DLLIMP gss_const_OID GSS_C_MA_CBINDINGS         = oids+34;
239 GSS_DLLIMP gss_const_OID GSS_C_MA_PFS               = oids+35;
240 GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS          = oids+36;
241 GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS         = oids+37;
242 GSS_DLLIMP gss_const_OID GSS_C_MA_NEGOEX_AND_SPNEGO = oids+38;
243 
244 GSS_DLLIMP gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = oids+39;
245 
246 GSS_DLLIMP gss_OID GSS_C_INQ_ODBC_SESSION_KEY = oids+40;
247 
248 static gss_OID_set_desc gss_ma_known_attrs_desc = { 28, oids+11 };
249 
250 gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc;
251 
252 static struct mech_attr_info_desc {
253     gss_OID mech_attr;
254     const char *name;
255     const char *short_desc;
256     const char *long_desc;
257 } mech_attr_info[] = {
258     {
259         oids+11,
260         "GSS_C_MA_MECH_CONCRETE",
261         "concrete-mech",
262         "Mechanism is neither a pseudo-mechanism nor a composite mechanism.",
263     },
264     {
265         oids+12,
266         "GSS_C_MA_MECH_PSEUDO",
267         "pseudo-mech",
268         "Mechanism is a pseudo-mechanism.",
269     },
270     {
271         oids+13,
272         "GSS_C_MA_MECH_COMPOSITE",
273         "composite-mech",
274         "Mechanism is a composite of other mechanisms.",
275     },
276     {
277         oids+14,
278         "GSS_C_MA_MECH_NEGO",
279         "mech-negotiation-mech",
280         "Mechanism negotiates other mechanisms.",
281     },
282     {
283         oids+15,
284         "GSS_C_MA_MECH_GLUE",
285         "mech-glue",
286         "OID is not a mechanism but the GSS-API itself.",
287     },
288     {
289         oids+16,
290         "GSS_C_MA_NOT_MECH",
291         "not-mech",
292         "Known OID but not a mechanism OID.",
293     },
294     {
295         oids+17,
296         "GSS_C_MA_DEPRECATED",
297         "mech-deprecated",
298         "Mechanism is deprecated.",
299     },
300     {
301         oids+18,
302         "GSS_C_MA_NOT_DFLT_MECH",
303         "mech-not-default",
304         "Mechanism must not be used as a default mechanism.",
305     },
306     {
307         oids+19,
308         "GSS_C_MA_ITOK_FRAMED",
309         "initial-is-framed",
310         "Mechanism's initial contexts are properly framed.",
311     },
312     {
313         oids+20,
314         "GSS_C_MA_AUTH_INIT",
315         "auth-init-princ",
316         "Mechanism supports authentication of initiator to acceptor.",
317     },
318     {
319         oids+21,
320         "GSS_C_MA_AUTH_TARG",
321         "auth-targ-princ",
322         "Mechanism supports authentication of acceptor to initiator.",
323     },
324     {
325         oids+22,
326         "GSS_C_MA_AUTH_INIT_INIT",
327         "auth-init-princ-initial",
328         "Mechanism supports authentication of initiator using "
329         "initial credentials.",
330     },
331     {
332         oids+23,
333         "GSS_C_MA_AUTH_TARG_INIT",
334         "auth-target-princ-initial",
335         "Mechanism supports authentication of acceptor using "
336         "initial credentials.",
337     },
338     {
339         oids+24,
340         "GSS_C_MA_AUTH_INIT_ANON",
341         "auth-init-princ-anon",
342         "Mechanism supports GSS_C_NT_ANONYMOUS as an initiator name.",
343     },
344     {
345         oids+25,
346         "GSS_C_MA_AUTH_TARG_ANON",
347         "auth-targ-princ-anon",
348         "Mechanism supports GSS_C_NT_ANONYMOUS as an acceptor name.",
349     },
350     {
351         oids+26,
352         "GSS_C_MA_DELEG_CRED",
353         "deleg-cred",
354         "Mechanism supports credential delegation.",
355     },
356     {
357         oids+27,
358         "GSS_C_MA_INTEG_PROT",
359         "integ-prot",
360         "Mechanism supports per-message integrity protection.",
361     },
362     {
363         oids+28,
364         "GSS_C_MA_CONF_PROT",
365         "conf-prot",
366         "Mechanism supports per-message confidentiality protection.",
367     },
368     {
369         oids+29,
370         "GSS_C_MA_MIC",
371         "mic",
372         "Mechanism supports Message Integrity Code (MIC) tokens.",
373     },
374     {
375         oids+30,
376         "GSS_C_MA_WRAP",
377         "wrap",
378         "Mechanism supports wrap tokens.",
379     },
380     {
381         oids+31,
382         "GSS_C_MA_PROT_READY",
383         "prot-ready",
384         "Mechanism supports per-message proteciton prior to "
385         "full context establishment.",
386     },
387     {
388         oids+32,
389         "GSS_C_MA_REPLAY_DET",
390         "replay-detection",
391         "Mechanism supports replay detection.",
392     },
393     {
394         oids+33,
395         "GSS_C_MA_OOS_DET",
396         "oos-detection",
397         "Mechanism supports out-of-sequence detection.",
398     },
399     {
400         oids+34,
401         "GSS_C_MA_CBINDINGS",
402         "channel-bindings",
403         "Mechanism supports channel bindings.",
404     },
405     {
406         oids+35,
407         "GSS_C_MA_PFS",
408         "pfs",
409         "Mechanism supports Perfect Forward Security.",
410     },
411     {
412         oids+36,
413         "GSS_C_MA_COMPRESS",
414         "compress",
415         "Mechanism supports compression of data inputs to gss_wrap().",
416     },
417     {
418         oids+37,
419         "GSS_C_MA_CTX_TRANS",
420         "context-transfer",
421         "Mechanism supports security context export/import.",
422     },
423     {
424         oids+38,
425         "GSS_C_MA_NEGOEX_AND_SPNEGO",
426         "negoex-only",
427         "NegoEx mechanism should also be negotiable through SPNEGO.",
428     },
429 };
430 
431 OM_uint32
432 generic_gss_display_mech_attr(
433     OM_uint32         *minor_status,
434     gss_const_OID      mech_attr,
435     gss_buffer_t       name,
436     gss_buffer_t       short_desc,
437     gss_buffer_t       long_desc)
438 {
439     size_t i;
440 
441     if (minor_status != NULL)
442         *minor_status = 0;
443     if (name != GSS_C_NO_BUFFER) {
444         name->length = 0;
445         name->value = NULL;
446     }
447     if (short_desc != GSS_C_NO_BUFFER) {
448         short_desc->length = 0;
449         short_desc->value = NULL;
450     }
451     if (long_desc != GSS_C_NO_BUFFER) {
452         long_desc->length = 0;
453         long_desc->value = NULL;
454     }
455     if (minor_status == NULL)
456         return GSS_S_CALL_INACCESSIBLE_WRITE;
457     for (i = 0; i < sizeof(mech_attr_info)/sizeof(mech_attr_info[0]); i++) {
458         struct mech_attr_info_desc *mai = &mech_attr_info[i];
459 
460         if (g_OID_equal(mech_attr, mai->mech_attr)) {
461             if (name != GSS_C_NO_BUFFER &&
462                 !g_make_string_buffer(mai->name, name)) {
463                 *minor_status = ENOMEM;
464                 return GSS_S_FAILURE;
465             }
466             if (short_desc != GSS_C_NO_BUFFER &&
467                 !g_make_string_buffer(mai->short_desc, short_desc)) {
468                 *minor_status = ENOMEM;
469                 return GSS_S_FAILURE;
470             }
471             if (long_desc != GSS_C_NO_BUFFER &&
472                 !g_make_string_buffer(mai->long_desc, long_desc)) {
473                 *minor_status = ENOMEM;
474                 return GSS_S_FAILURE;
475             }
476             return GSS_S_COMPLETE;
477         }
478     }
479 
480     return GSS_S_BAD_MECH_ATTR;
481 }
482 
483 static gss_buffer_desc const_attrs[] = {
484     { sizeof("local-login-user") - 1,
485       "local-login-user" },
486 };
487 
488 GSS_DLLIMP gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER = &const_attrs[0];
489