1*ab9b2e15Sgtb /*
2*ab9b2e15Sgtb * lib/gssapi/krb5/set_allowable_enctypes.c
3*ab9b2e15Sgtb *
4*ab9b2e15Sgtb * Copyright 2004 by the Massachusetts Institute of Technology.
5*ab9b2e15Sgtb * All Rights Reserved.
6*ab9b2e15Sgtb *
7*ab9b2e15Sgtb * Export of this software from the United States of America may
8*ab9b2e15Sgtb * require a specific license from the United States Government.
9*ab9b2e15Sgtb * It is the responsibility of any person or organization contemplating
10*ab9b2e15Sgtb * export to obtain such a license before exporting.
11*ab9b2e15Sgtb *
12*ab9b2e15Sgtb * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*ab9b2e15Sgtb * distribute this software and its documentation for any purpose and
14*ab9b2e15Sgtb * without fee is hereby granted, provided that the above copyright
15*ab9b2e15Sgtb * notice appear in all copies and that both that copyright notice and
16*ab9b2e15Sgtb * this permission notice appear in supporting documentation, and that
17*ab9b2e15Sgtb * the name of M.I.T. not be used in advertising or publicity pertaining
18*ab9b2e15Sgtb * to distribution of the software without specific, written prior
19*ab9b2e15Sgtb * permission. Furthermore if you modify this software you must label
20*ab9b2e15Sgtb * your software as modified software and not distribute it in such a
21*ab9b2e15Sgtb * fashion that it might be confused with the original M.I.T. software.
22*ab9b2e15Sgtb * M.I.T. makes no representations about the suitability of
23*ab9b2e15Sgtb * this software for any purpose. It is provided "as is" without express
24*ab9b2e15Sgtb * or implied warranty.
25*ab9b2e15Sgtb *
26*ab9b2e15Sgtb * krb5_gss_set_allowable_enctypes()
27*ab9b2e15Sgtb */
28*ab9b2e15Sgtb
29*ab9b2e15Sgtb /*
30*ab9b2e15Sgtb * gss_krb5_set_allowable_enctypes
31*ab9b2e15Sgtb *
32*ab9b2e15Sgtb * This function may be called by a context initiator after calling
33*ab9b2e15Sgtb * gss_acquire_cred(), but before calling gss_init_sec_context(),
34*ab9b2e15Sgtb * to restrict the set of enctypes which will be negotiated during
35*ab9b2e15Sgtb * context establishment to those in the provided array.
36*ab9b2e15Sgtb *
37*ab9b2e15Sgtb * 'cred_handle' must be a valid credential handle obtained via
38*ab9b2e15Sgtb * gss_acquire_cred(). It may not be GSS_C_NO_CREDENTIAL.
39*ab9b2e15Sgtb * gss_acquire_cred() may be called with GSS_C_NO_CREDENTIAL
40*ab9b2e15Sgtb * to get a handle to the default credential.
41*ab9b2e15Sgtb *
42*ab9b2e15Sgtb * The purpose of this function is to limit the keys that may
43*ab9b2e15Sgtb * be exported via gss_krb5_export_lucid_sec_context(); thus it
44*ab9b2e15Sgtb * should limit the enctypes of all keys that will be needed
45*ab9b2e15Sgtb * after the security context has been established.
46*ab9b2e15Sgtb * (i.e. context establishment may use a session key with a
47*ab9b2e15Sgtb * stronger enctype than in the provided array, however a
48*ab9b2e15Sgtb * subkey must be established within the enctype limits
49*ab9b2e15Sgtb * established by this function.)
50*ab9b2e15Sgtb *
51*ab9b2e15Sgtb */
52*ab9b2e15Sgtb
53*ab9b2e15Sgtb #include "gssapiP_krb5.h"
54*ab9b2e15Sgtb #ifdef HAVE_STRING_H
55*ab9b2e15Sgtb #include <string.h>
56*ab9b2e15Sgtb #else
57*ab9b2e15Sgtb #include <strings.h>
58*ab9b2e15Sgtb #endif
59*ab9b2e15Sgtb #include "gssapi_krb5.h"
60*ab9b2e15Sgtb
61*ab9b2e15Sgtb OM_uint32 KRB5_CALLCONV
gss_krb5int_set_allowable_enctypes(OM_uint32 * minor_status,gss_cred_id_t cred_handle,OM_uint32 num_ktypes,krb5_enctype * ktypes)62*ab9b2e15Sgtb gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status,
63*ab9b2e15Sgtb gss_cred_id_t cred_handle,
64*ab9b2e15Sgtb OM_uint32 num_ktypes,
65*ab9b2e15Sgtb krb5_enctype *ktypes)
66*ab9b2e15Sgtb {
67*ab9b2e15Sgtb int i;
68*ab9b2e15Sgtb krb5_enctype * new_ktypes;
69*ab9b2e15Sgtb OM_uint32 major_status;
70*ab9b2e15Sgtb krb5_gss_cred_id_t cred;
71*ab9b2e15Sgtb krb5_error_code kerr = 0;
72*ab9b2e15Sgtb OM_uint32 temp_status;
73*ab9b2e15Sgtb
74*ab9b2e15Sgtb /* Assume a failure */
75*ab9b2e15Sgtb *minor_status = 0;
76*ab9b2e15Sgtb major_status = GSS_S_FAILURE;
77*ab9b2e15Sgtb
78*ab9b2e15Sgtb /* verify and valildate cred handle */
79*ab9b2e15Sgtb if (cred_handle == GSS_C_NO_CREDENTIAL) {
80*ab9b2e15Sgtb kerr = KRB5_NOCREDS_SUPPLIED;
81*ab9b2e15Sgtb goto error_out;
82*ab9b2e15Sgtb }
83*ab9b2e15Sgtb major_status = krb5_gss_validate_cred(&temp_status, cred_handle);
84*ab9b2e15Sgtb if (GSS_ERROR(major_status)) {
85*ab9b2e15Sgtb kerr = temp_status;
86*ab9b2e15Sgtb goto error_out;
87*ab9b2e15Sgtb }
88*ab9b2e15Sgtb cred = (krb5_gss_cred_id_t) cred_handle;
89*ab9b2e15Sgtb
90*ab9b2e15Sgtb if (ktypes) {
91*ab9b2e15Sgtb for (i = 0; i < num_ktypes && ktypes[i]; i++) {
92*ab9b2e15Sgtb if (!krb5_c_valid_enctype(ktypes[i])) {
93*ab9b2e15Sgtb kerr = KRB5_PROG_ETYPE_NOSUPP;
94*ab9b2e15Sgtb goto error_out;
95*ab9b2e15Sgtb }
96*ab9b2e15Sgtb }
97*ab9b2e15Sgtb } else {
98*ab9b2e15Sgtb kerr = k5_mutex_lock(&cred->lock);
99*ab9b2e15Sgtb if (kerr)
100*ab9b2e15Sgtb goto error_out;
101*ab9b2e15Sgtb if (cred->req_enctypes)
102*ab9b2e15Sgtb free(cred->req_enctypes);
103*ab9b2e15Sgtb cred->req_enctypes = NULL;
104*ab9b2e15Sgtb k5_mutex_unlock(&cred->lock);
105*ab9b2e15Sgtb return GSS_S_COMPLETE;
106*ab9b2e15Sgtb }
107*ab9b2e15Sgtb
108*ab9b2e15Sgtb /* Copy the requested ktypes into the cred structure */
109*ab9b2e15Sgtb if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * (i + 1)))) {
110*ab9b2e15Sgtb memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i);
111*ab9b2e15Sgtb new_ktypes[i] = 0; /* "null-terminate" the list */
112*ab9b2e15Sgtb }
113*ab9b2e15Sgtb else {
114*ab9b2e15Sgtb kerr = ENOMEM;
115*ab9b2e15Sgtb goto error_out;
116*ab9b2e15Sgtb }
117*ab9b2e15Sgtb kerr = k5_mutex_lock(&cred->lock);
118*ab9b2e15Sgtb if (kerr) {
119*ab9b2e15Sgtb free(new_ktypes);
120*ab9b2e15Sgtb goto error_out;
121*ab9b2e15Sgtb }
122*ab9b2e15Sgtb if (cred->req_enctypes)
123*ab9b2e15Sgtb free(cred->req_enctypes);
124*ab9b2e15Sgtb cred->req_enctypes = new_ktypes;
125*ab9b2e15Sgtb k5_mutex_unlock(&cred->lock);
126*ab9b2e15Sgtb
127*ab9b2e15Sgtb /* Success! */
128*ab9b2e15Sgtb return GSS_S_COMPLETE;
129*ab9b2e15Sgtb
130*ab9b2e15Sgtb error_out:
131*ab9b2e15Sgtb *minor_status = kerr;
132*ab9b2e15Sgtb return(major_status);
133*ab9b2e15Sgtb }
134