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