set_keys.c revision 55682
1193323Sed/* 2193323Sed * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H�gskolan 3193323Sed * (Royal Institute of Technology, Stockholm, Sweden). 4193323Sed * All rights reserved. 5193323Sed * 6193323Sed * Redistribution and use in source and binary forms, with or without 7193323Sed * modification, are permitted provided that the following conditions 8193323Sed * are met: 9193323Sed * 10193323Sed * 1. Redistributions of source code must retain the above copyright 11193323Sed * notice, this list of conditions and the following disclaimer. 12203954Srdivacky * 13193323Sed * 2. Redistributions in binary form must reproduce the above copyright 14193323Sed * notice, this list of conditions and the following disclaimer in the 15193323Sed * documentation and/or other materials provided with the distribution. 16193323Sed * 17193323Sed * 3. Neither the name of the Institute nor the names of its contributors 18193323Sed * may be used to endorse or promote products derived from this software 19234353Sdim * without specific prior written permission. 20249423Sdim * 21239462Sdim * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22249423Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23249423Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24239462Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25243830Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29193323Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30239462Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31263508Sdim * SUCH DAMAGE. 32193323Sed */ 33193323Sed 34193323Sed#include "kadm5_locl.h" 35198090Srdivacky 36249423SdimRCSID("$Id: set_keys.c,v 1.18 1999/12/04 23:11:01 assar Exp $"); 37249423Sdim 38249423Sdim/* 39193323Sed * free all the memory used by (len, keys) 40193323Sed */ 41193323Sed 42226633Sdimstatic void 43226633Sdimfree_keys (kadm5_server_context *context, 44193323Sed int len, Key *keys) 45193323Sed{ 46193323Sed int i; 47193323Sed 48193323Sed for (i = 0; i < len; ++i) { 49193323Sed free (keys[i].mkvno); 50193323Sed keys[i].mkvno = NULL; 51218893Sdim if (keys[i].salt != NULL) { 52193323Sed free_Salt(keys[i].salt); 53193323Sed free(keys[i].salt); 54194612Sed keys[i].salt = NULL; 55193323Sed } 56193323Sed krb5_free_keyblock_contents(context->context, &keys[i].key); 57193323Sed } 58198892Srdivacky free (keys); 59193323Sed} 60193323Sed 61193323Sed/* 62193323Sed * null-ify `len', `keys' 63193323Sed */ 64193323Sed 65193323Sedstatic void 66193323Sedinit_keys (Key *keys, int len) 67193323Sed{ 68218893Sdim int i; 69218893Sdim 70218893Sdim for (i = 0; i < len; ++i) { 71218893Sdim keys[i].mkvno = NULL; 72193323Sed keys[i].salt = NULL; 73193323Sed keys[i].key.keyvalue.length = 0; 74218893Sdim keys[i].key.keyvalue.data = NULL; 75218893Sdim } 76218893Sdim} 77226633Sdim 78218893Sdim/* 79218893Sdim * the known and used DES enctypes 80218893Sdim */ 81249423Sdim 82249423Sdimstatic krb5_enctype des_types[] = { ETYPE_DES_CBC_CRC, 83249423Sdim ETYPE_DES_CBC_MD4, 84249423Sdim ETYPE_DES_CBC_MD5 }; 85249423Sdim 86249423Sdimstatic unsigned n_des_types = 3; 87249423Sdim 88194612Sed/* 89194612Sed * Set the keys of `ent' to the string-to-key of `password' 90249423Sdim */ 91249423Sdim 92249423Sdimkadm5_ret_t 93249423Sdim_kadm5_set_keys(kadm5_server_context *context, 94249423Sdim hdb_entry *ent, 95249423Sdim const char *password) 96249423Sdim{ 97249423Sdim kadm5_ret_t ret = 0; 98249423Sdim int i; 99193323Sed unsigned len; 100193323Sed Key *keys; 101193323Sed krb5_salt salt; 102193323Sed krb5_boolean v4_salt = FALSE; 103193323Sed 104218893Sdim len = n_des_types + 1; 105193323Sed keys = malloc (len * sizeof(*keys)); 106193323Sed if (keys == NULL) 107193323Sed return ENOMEM; 108193323Sed 109193323Sed init_keys (keys, len); 110193323Sed 111193323Sed salt.salttype = KRB5_PW_SALT; 112193323Sed salt.saltvalue.length = 0; 113193323Sed salt.saltvalue.data = NULL; 114193323Sed 115193323Sed if (krb5_config_get_bool (context->context, 116193323Sed NULL, "kadmin", "use_v4_salt", NULL)) { 117239462Sdim v4_salt = TRUE; 118239462Sdim } else { 119239462Sdim ret = krb5_get_pw_salt (context->context, ent->principal, &salt); 120239462Sdim if (ret) 121239462Sdim goto out; 122239462Sdim } 123239462Sdim 124239462Sdim for (i = 0; i < n_des_types; ++i) { 125239462Sdim ret = krb5_string_to_key_salt (context->context, 126239462Sdim des_types[i], 127239462Sdim password, 128239462Sdim salt, 129239462Sdim &keys[i].key); 130239462Sdim if (ret) 131239462Sdim goto out; 132239462Sdim if (v4_salt) { 133239462Sdim keys[i].salt = malloc (sizeof(*keys[i].salt)); 134239462Sdim if (keys[i].salt == NULL) { 135239462Sdim ret = ENOMEM; 136239462Sdim goto out; 137239462Sdim } 138243830Sdim keys[i].salt->type = salt.salttype; 139239462Sdim ret = copy_octet_string (&salt.saltvalue, &keys[i].salt->salt); 140239462Sdim if (ret) 141239462Sdim goto out; 142243830Sdim } 143239462Sdim } 144239462Sdim 145239462Sdim ret = krb5_string_to_key (context->context, 146239462Sdim ETYPE_DES3_CBC_SHA1, 147239462Sdim password, 148239462Sdim ent->principal, 149239462Sdim &keys[n_des_types].key); 150239462Sdim if (ret) 151239462Sdim goto out; 152239462Sdim 153239462Sdim free_keys (context, ent->keys.len, ent->keys.val); 154239462Sdim ent->keys.len = len; 155239462Sdim ent->keys.val = keys; 156239462Sdim ent->kvno++; 157239462Sdim return ret; 158239462Sdimout: 159239462Sdim krb5_data_free (&salt.saltvalue); 160239462Sdim free_keys (context, len, keys); 161239462Sdim return ret; 162239462Sdim} 163239462Sdim 164239462Sdim/* 165239462Sdim * Set the keys of `ent' to (`n_key_data', `key_data') 166239462Sdim */ 167239462Sdim 168239462Sdimkadm5_ret_t 169239462Sdim_kadm5_set_keys2(hdb_entry *ent, 170239462Sdim int16_t n_key_data, 171239462Sdim krb5_key_data *key_data) 172239462Sdim{ 173239462Sdim krb5_error_code ret; 174239462Sdim int i; 175239462Sdim 176239462Sdim ent->keys.len = n_key_data; 177239462Sdim ent->keys.val = malloc(ent->keys.len * sizeof(*ent->keys.val)); 178239462Sdim if(ent->keys.val == NULL) 179239462Sdim return ENOMEM; 180239462Sdim for(i = 0; i < n_key_data; i++) { 181239462Sdim ent->keys.val[i].mkvno = NULL; 182239462Sdim ent->keys.val[i].key.keytype = key_data[i].key_data_type[0]; 183243830Sdim ret = krb5_data_copy(&ent->keys.val[i].key.keyvalue, 184239462Sdim key_data[i].key_data_contents[0], 185239462Sdim key_data[i].key_data_length[0]); 186239462Sdim if(ret) 187239462Sdim return ret; 188239462Sdim if(key_data[i].key_data_ver == 2) { 189239462Sdim Salt *salt; 190239462Sdim salt = malloc(sizeof(*salt)); 191239462Sdim if(salt == NULL) 192239462Sdim return ENOMEM; 193239462Sdim ent->keys.val[i].salt = salt; 194239462Sdim salt->type = key_data[i].key_data_type[1]; 195239462Sdim krb5_data_copy(&salt->salt, 196243830Sdim key_data[i].key_data_contents[1], 197243830Sdim key_data[i].key_data_length[1]); 198239462Sdim } else 199239462Sdim ent->keys.val[i].salt = NULL; 200239462Sdim } 201239462Sdim ent->kvno++; 202239462Sdim return 0; 203239462Sdim} 204239462Sdim 205239462Sdim/* 206239462Sdim * Set the keys of `ent' to random keys and return them in `n_keys' 207239462Sdim * and `new_keys'. 208239462Sdim */ 209239462Sdim 210239462Sdimkadm5_ret_t 211218893Sdim_kadm5_set_keys_randomly (kadm5_server_context *context, 212218893Sdim hdb_entry *ent, 213243830Sdim krb5_keyblock **new_keys, 214239462Sdim int *n_keys) 215239462Sdim{ 216239462Sdim kadm5_ret_t ret = 0; 217243830Sdim int i; 218239462Sdim unsigned len; 219239462Sdim krb5_keyblock *keys; 220239462Sdim Key *hkeys; 221239462Sdim 222239462Sdim len = n_des_types + 1; 223239462Sdim keys = malloc (len * sizeof(*keys)); 224239462Sdim if (keys == NULL) 225239462Sdim return ENOMEM; 226239462Sdim 227239462Sdim for (i = 0; i < len; ++i) { 228239462Sdim keys[i].keyvalue.length = 0; 229239462Sdim keys[i].keyvalue.data = NULL; 230239462Sdim } 231239462Sdim 232239462Sdim hkeys = malloc (len * sizeof(*hkeys)); 233239462Sdim if (hkeys == NULL) { 234239462Sdim free (keys); 235239462Sdim return ENOMEM; 236239462Sdim } 237239462Sdim 238239462Sdim init_keys (hkeys, len); 239239462Sdim 240239462Sdim ret = krb5_generate_random_keyblock (context->context, 241239462Sdim des_types[0], 242239462Sdim &keys[0]); 243239462Sdim if (ret) 244239462Sdim goto out; 245239462Sdim 246239462Sdim ret = krb5_copy_keyblock_contents (context->context, 247239462Sdim &keys[0], 248239462Sdim &hkeys[0].key); 249239462Sdim if (ret) 250239462Sdim goto out; 251239462Sdim 252239462Sdim for (i = 1; i < n_des_types; ++i) { 253239462Sdim ret = krb5_copy_keyblock_contents (context->context, 254239462Sdim &keys[0], 255239462Sdim &keys[i]); 256239462Sdim if (ret) 257239462Sdim goto out; 258239462Sdim keys[i].keytype = des_types[i]; 259239462Sdim ret = krb5_copy_keyblock_contents (context->context, 260239462Sdim &keys[0], 261239462Sdim &hkeys[i].key); 262239462Sdim if (ret) 263239462Sdim goto out; 264239462Sdim hkeys[i].key.keytype = des_types[i]; 265221345Sdim } 266221345Sdim 267218893Sdim ret = krb5_generate_random_keyblock (context->context, 268263508Sdim ETYPE_DES3_CBC_SHA1, 269218893Sdim &keys[n_des_types]); 270218893Sdim if (ret) 271218893Sdim goto out; 272218893Sdim 273263508Sdim ret = krb5_copy_keyblock_contents (context->context, 274234353Sdim &keys[n_des_types], 275234353Sdim &hkeys[n_des_types].key); 276218893Sdim if (ret) 277218893Sdim goto out; 278218893Sdim 279263508Sdim free_keys (context, ent->keys.len, ent->keys.val); 280263508Sdim ent->keys.len = len; 281263508Sdim ent->keys.val = hkeys; 282263508Sdim ent->kvno++; 283263508Sdim *new_keys = keys; 284263508Sdim *n_keys = len; 285263508Sdim return ret; 286263508Sdimout: 287263508Sdim for (i = 0; i < len; ++i) 288263508Sdim krb5_free_keyblock_contents (context->context, &keys[i]); 289263508Sdim free (keys); 290263508Sdim free_keys (context, len, hkeys); 291263508Sdim return ret; 292263508Sdim} 293263508Sdim