set_keys.c revision 178825
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1997 - 2001, 2003 Kungliga Tekniska H�gskolan 31541Srgrimes * (Royal Institute of Technology, Stockholm, Sweden). 41541Srgrimes * All rights reserved. 51541Srgrimes * 61541Srgrimes * Redistribution and use in source and binary forms, with or without 71541Srgrimes * modification, are permitted provided that the following conditions 81541Srgrimes * are met: 91541Srgrimes * 101541Srgrimes * 1. Redistributions of source code must retain the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer. 121541Srgrimes * 131541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer in the 151541Srgrimes * documentation and/or other materials provided with the distribution. 161541Srgrimes * 171541Srgrimes * 3. Neither the name of the Institute nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes */ 331541Srgrimes 341541Srgrimes#include "kadm5_locl.h" 351541Srgrimes 361541SrgrimesRCSID("$Id: set_keys.c 15888 2005-08-11 13:40:35Z lha $"); 371541Srgrimes 3844510Swollman/* 3950477Speter * Set the keys of `ent' to the string-to-key of `password' 401541Srgrimes */ 411541Srgrimes 421541Srgrimeskadm5_ret_t 431541Srgrimes_kadm5_set_keys(kadm5_server_context *context, 4433392Sphk hdb_entry *ent, 451541Srgrimes const char *password) 4674914Sjhb{ 4768840Sjhb Key *keys; 481541Srgrimes size_t num_keys; 4933392Sphk kadm5_ret_t ret; 5033392Sphk 5133392Sphk ret = hdb_generate_key_set_password(context->context, 5233392Sphk ent->principal, 5333392Sphk password, &keys, &num_keys); 5433392Sphk if (ret) 5529680Sgibbs return ret; 5629680Sgibbs 5729680Sgibbs _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); 5829680Sgibbs ent->keys.val = keys; 5933392Sphk ent->keys.len = num_keys; 6068889Sjake 612112Swollman hdb_entry_set_pw_change_time(context->context, ent, 0); 6229680Sgibbs 631541Srgrimes if (krb5_config_get_bool_default(context->context, NULL, FALSE, 641541Srgrimes "kadmin", "save-password", NULL)) 6582127Sdillon { 6682127Sdillon ret = hdb_entry_set_password(context->context, context->db, 6782127Sdillon ent, password); 6882127Sdillon if (ret) 6982127Sdillon return ret; 7082127Sdillon } 7182127Sdillon 7282127Sdillon return 0; 7382127Sdillon} 7482127Sdillon 7582127Sdillon/* 7682127Sdillon * Set the keys of `ent' to (`n_key_data', `key_data') 7782127Sdillon */ 7882127Sdillon 7982127Sdillonkadm5_ret_t 8082127Sdillon_kadm5_set_keys2(kadm5_server_context *context, 8182127Sdillon hdb_entry *ent, 8282127Sdillon int16_t n_key_data, 8382127Sdillon krb5_key_data *key_data) 8482127Sdillon{ 8582127Sdillon krb5_error_code ret; 8682127Sdillon int i; 8782127Sdillon unsigned len; 8882127Sdillon Key *keys; 8982127Sdillon 9082127Sdillon len = n_key_data; 9182127Sdillon keys = malloc (len * sizeof(*keys)); 9282127Sdillon if (keys == NULL) 9382127Sdillon return ENOMEM; 9482127Sdillon 9582127Sdillon _kadm5_init_keys (keys, len); 9682127Sdillon 9782127Sdillon for(i = 0; i < n_key_data; i++) { 9882127Sdillon keys[i].mkvno = NULL; 9982127Sdillon keys[i].key.keytype = key_data[i].key_data_type[0]; 10082127Sdillon ret = krb5_data_copy(&keys[i].key.keyvalue, 10182127Sdillon key_data[i].key_data_contents[0], 10282127Sdillon key_data[i].key_data_length[0]); 10382127Sdillon if(ret) 10482127Sdillon goto out; 10582127Sdillon if(key_data[i].key_data_ver == 2) { 10682127Sdillon Salt *salt; 10782127Sdillon 10882127Sdillon salt = malloc(sizeof(*salt)); 10982127Sdillon if(salt == NULL) { 11093818Sjhb ret = ENOMEM; 11182127Sdillon goto out; 11282127Sdillon } 11382127Sdillon keys[i].salt = salt; 11429680Sgibbs salt->type = key_data[i].key_data_type[1]; 11529680Sgibbs krb5_data_copy(&salt->salt, 11629680Sgibbs key_data[i].key_data_contents[1], 11729680Sgibbs key_data[i].key_data_length[1]); 11829680Sgibbs } else 11929680Sgibbs keys[i].salt = NULL; 12029680Sgibbs } 12129680Sgibbs _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); 12229680Sgibbs ent->keys.len = len; 12329680Sgibbs ent->keys.val = keys; 12432388Sphk 12529680Sgibbs hdb_entry_set_pw_change_time(context->context, ent, 0); 1261541Srgrimes hdb_entry_clear_password(context->context, ent); 1271541Srgrimes 1281541Srgrimes return 0; 1291541Srgrimes out: 13067551Sjhb _kadm5_free_keys (context->context, len, keys); 1311541Srgrimes return ret; 132102936Sphk} 133102936Sphk 134102936Sphk/* 135102936Sphk * Set the keys of `ent' to `n_keys, keys' 136102936Sphk */ 137102936Sphk 138102936Sphkkadm5_ret_t 139102936Sphk_kadm5_set_keys3(kadm5_server_context *context, 140102936Sphk hdb_entry *ent, 1411541Srgrimes int n_keys, 14233392Sphk krb5_keyblock *keyblocks) 14333392Sphk{ 14433392Sphk krb5_error_code ret; 14529680Sgibbs int i; 14629680Sgibbs unsigned len; 14772200Sbmilekic Key *keys; 14829680Sgibbs 14929805Sgibbs len = n_keys; 15029805Sgibbs keys = malloc (len * sizeof(*keys)); 15129805Sgibbs if (keys == NULL) 15229805Sgibbs return ENOMEM; 15329805Sgibbs 15429805Sgibbs _kadm5_init_keys (keys, len); 15529805Sgibbs 15629805Sgibbs for(i = 0; i < n_keys; i++) { 15729680Sgibbs keys[i].mkvno = NULL; 15829805Sgibbs ret = krb5_copy_keyblock_contents (context->context, 15929680Sgibbs &keyblocks[i], 16029680Sgibbs &keys[i].key); 16129680Sgibbs if(ret) 16229680Sgibbs goto out; 16329805Sgibbs keys[i].salt = NULL; 16472200Sbmilekic } 16581370Sjhb _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); 16672200Sbmilekic ent->keys.len = len; 16729680Sgibbs ent->keys.val = keys; 16829680Sgibbs 16929680Sgibbs hdb_entry_set_pw_change_time(context->context, ent, 0); 17029680Sgibbs hdb_entry_clear_password(context->context, ent); 17129680Sgibbs 17229680Sgibbs return 0; 17368889Sjake out: 17429680Sgibbs _kadm5_free_keys (context->context, len, keys); 17529680Sgibbs return ret; 17629805Sgibbs} 17729680Sgibbs 17829680Sgibbs/* 17968889Sjake * 18029680Sgibbs */ 18144510Swollman 18244510Swollmanstatic int 18344510Swollmanis_des_key_p(int keytype) 18444510Swollman{ 18544510Swollman return keytype == ETYPE_DES_CBC_CRC || 18644510Swollman keytype == ETYPE_DES_CBC_MD4 || 18750673Sjlemon keytype == ETYPE_DES_CBC_MD5; 18844510Swollman} 18972200Sbmilekic 19068889Sjake 19172200Sbmilekic/* 192102936Sphk * Set the keys of `ent' to random keys and return them in `n_keys' 193102936Sphk * and `new_keys'. 194102936Sphk */ 19529680Sgibbs 196102936Sphkkadm5_ret_t 197102936Sphk_kadm5_set_keys_randomly (kadm5_server_context *context, 198102936Sphk hdb_entry *ent, 199102936Sphk krb5_keyblock **new_keys, 200102936Sphk int *n_keys) 201102936Sphk{ 202102936Sphk krb5_keyblock *kblock = NULL; 203102936Sphk kadm5_ret_t ret = 0; 204102936Sphk int i, des_keyblock; 205102936Sphk size_t num_keys; 206102936Sphk Key *keys; 20768889Sjake 20872200Sbmilekic ret = hdb_generate_key_set(context->context, ent->principal, 20972200Sbmilekic &keys, &num_keys, 1); 21029680Sgibbs if (ret) 21129680Sgibbs return ret; 21229680Sgibbs 21329680Sgibbs kblock = malloc(num_keys * sizeof(kblock[0])); 2141541Srgrimes if (kblock == NULL) { 21529680Sgibbs ret = ENOMEM; 21672200Sbmilekic _kadm5_free_keys (context->context, num_keys, keys); 2171541Srgrimes return ret; 2181541Srgrimes } 2191541Srgrimes memset(kblock, 0, num_keys * sizeof(kblock[0])); 2201541Srgrimes 2211541Srgrimes des_keyblock = -1; 2221541Srgrimes for (i = 0; i < num_keys; i++) { 2231541Srgrimes 2241541Srgrimes /* 2251541Srgrimes * To make sure all des keys are the the same we generate only 22629680Sgibbs * the first one and then copy key to all other des keys. 22729680Sgibbs */ 22829680Sgibbs 2291541Srgrimes if (des_keyblock != -1 && is_des_key_p(keys[i].key.keytype)) { 23029680Sgibbs ret = krb5_copy_keyblock_contents (context->context, 23129680Sgibbs &kblock[des_keyblock], 23229680Sgibbs &kblock[i]); 23329680Sgibbs if (ret) 2341541Srgrimes goto out; 23529680Sgibbs kblock[i].keytype = keys[i].key.keytype; 23629680Sgibbs } else { 23733824Sbde ret = krb5_generate_random_keyblock (context->context, 2381541Srgrimes keys[i].key.keytype, 23969147Sjlemon &kblock[i]); 2401541Srgrimes if (ret) 24129680Sgibbs goto out; 24229680Sgibbs 2431541Srgrimes if (is_des_key_p(keys[i].key.keytype)) 24472200Sbmilekic des_keyblock = i; 2451541Srgrimes } 2461541Srgrimes 24729680Sgibbs ret = krb5_copy_keyblock_contents (context->context, 24829680Sgibbs &kblock[i], 24929680Sgibbs &keys[i].key); 2501541Srgrimes if (ret) 25129680Sgibbs goto out; 25244510Swollman } 25344510Swollman 2541541Srgrimesout: 25544510Swollman if(ret) { 25672200Sbmilekic for (i = 0; i < num_keys; ++i) 25729680Sgibbs krb5_free_keyblock_contents (context->context, &kblock[i]); 2581541Srgrimes free(kblock); 2591541Srgrimes _kadm5_free_keys (context->context, num_keys, keys); 2601541Srgrimes return ret; 26129680Sgibbs } 26233824Sbde 2631541Srgrimes _kadm5_free_keys (context->context, ent->keys.len, ent->keys.val); 26429680Sgibbs ent->keys.val = keys; 2651541Srgrimes ent->keys.len = num_keys; 2661541Srgrimes *new_keys = kblock; 26729680Sgibbs *n_keys = num_keys; 26829680Sgibbs 26929680Sgibbs hdb_entry_set_pw_change_time(context->context, ent, 0); 27029680Sgibbs hdb_entry_clear_password(context->context, ent); 27129680Sgibbs 27229680Sgibbs return 0; 27329680Sgibbs} 27429680Sgibbs