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