From ac786258cfb4e59e00ac531a3dde1761624021ff Mon Sep 17 00:00:00 2001 From: Will Fiveash Date: Tue, 20 Jan 2009 22:52:29 +0000 Subject: [PATCH] More bug fixes. There were several bugs in the existing new commands. At this point the add_mkey, use_mkey and list_mkeys commands appear to work generally. I've noticed however that specifying a non-default enctype when using add_mkey and stashing the result (add_mkey -e aes128-cts-hmac-sha1-96 -s) causes problems when the new mkey is fetched from the stash file. I'll fix this in another commit. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/mkey_migrate@21765 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kadmin/dbutil/kdb5_mkey.c | 211 +++++++++++++++++++----------- src/kadmin/dbutil/kdb5_util.c | 15 ++- src/lib/kadm5/srv/svr_principal.c | 7 +- src/lib/kdb/kdb5.c | 40 ++++-- src/lib/kdb/kdb_default.c | 153 +++++++++++----------- 5 files changed, 255 insertions(+), 171 deletions(-) diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c index 981259f8b0..fa5dd9b32c 100644 --- a/src/kadmin/dbutil/kdb5_mkey.c +++ b/src/kadmin/dbutil/kdb5_mkey.c @@ -43,28 +43,28 @@ kdb5_add_mkey(int argc, char *argv[]) char *pw_str = 0; unsigned int pw_size = 0; int do_stash = 0, nentries = 0; - int old_key_data_count, i, j; + int old_key_data_count, i; krb5_boolean more = 0; krb5_data pwd; krb5_kvno old_kvno, new_mkey_kvno; krb5_keyblock new_master_keyblock; - krb5_keyblock plainkey; - krb5_key_data tmp_key_data, *old_key_data, *key_data; + krb5_key_data tmp_key_data, *old_key_data; krb5_enctype new_master_enctype = DEFAULT_KDC_ENCTYPE; char *new_mkey_password; krb5_db_entry master_entry; krb5_timestamp now; krb5_mkey_aux_node *mkey_aux_data_head, **mkey_aux_data, *cur_mkey_aux_data, *next_mkey_aux_data; + krb5_keylist_node *keylist_node; /* * The command table entry for this command causes open_db_and_mkey() to be * called first to open the KDB and get the current mkey. */ - while ((optchar = getopt(argc, argv, "k:s")) != -1) { + while ((optchar = getopt(argc, argv, "e:s")) != -1) { switch(optchar) { - case 'k': + case 'e': if (krb5_string_to_enctype(optarg, &new_master_enctype)) { com_err(progname, EINVAL, ": %s is an invalid enctype", optarg); exit_status++; @@ -116,7 +116,7 @@ kdb5_add_mkey(int argc, char *argv[]) } retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2, - pw_str, &pw_size); + pw_str, &pw_size); if (retval) { com_err(progname, retval, "while reading new master key from keyboard"); exit_status++; @@ -134,7 +134,7 @@ kdb5_add_mkey(int argc, char *argv[]) } retval = krb5_c_string_to_key(util_context, new_master_enctype, - &pwd, &master_salt, &new_master_keyblock); + &pwd, &master_salt, &new_master_keyblock); if (retval) { com_err(progname, retval, "while transforming master key from password"); exit_status++; @@ -143,7 +143,7 @@ kdb5_add_mkey(int argc, char *argv[]) /* First save the old keydata */ old_kvno = get_key_data_kvno(util_context, master_entry.n_key_data, - master_entry.key_data); + master_entry.key_data); old_key_data_count = master_entry.n_key_data; old_key_data = master_entry.key_data; @@ -160,7 +160,8 @@ kdb5_add_mkey(int argc, char *argv[]) exit_status++; return; } - memset((char *) master_entry.key_data, 0, sizeof(krb5_key_data) * (old_key_data_count + 1)); + memset((char *) master_entry.key_data, 0, + sizeof(krb5_key_data) * (old_key_data_count + 1)); master_entry.n_key_data = old_key_data_count + 1; new_mkey_kvno = old_kvno + 1; @@ -181,7 +182,10 @@ kdb5_add_mkey(int argc, char *argv[]) /* * Need to decrypt old keys with the current mkey which is in the global - * master_keyblock and encrypt those keys with the latest mkey. + * master_keyblock and encrypt those keys with the latest mkey. And while + * the old keys are being decrypted, use those to create the + * KRB5_TL_MKEY_AUX entries which store the latest mkey encrypted by one of + * the older mkeys. * * The new mkey is followed by existing keys. * @@ -197,10 +201,15 @@ kdb5_add_mkey(int argc, char *argv[]) memset(mkey_aux_data_head, 0, sizeof(krb5_mkey_aux_node)); mkey_aux_data = &mkey_aux_data_head; + /* XXX WAF: old, remove before final commit */ +#if 0 /************** Begin IFDEF'ed OUT *******************************/ for (i = 0; i < old_key_data_count; i++) { key_data = &old_key_data[i]; - retval = krb5_dbekd_decrypt_key_data(util_context, &master_keyblock, + /* decrypt the old key */ + /* XXX WAF: don't need to do this, use the master_keylist instead. */ + memset(&plainkey, 0, sizeof(plainkey)); + retval = krb5_dbekd_decrypt_key_data(util_context, &master_keylist->keyblock, key_data, &plainkey, NULL); if (retval) { com_err(progname, retval, "while decrypting master keys"); @@ -217,7 +226,7 @@ kdb5_add_mkey(int argc, char *argv[]) if (*mkey_aux_data == NULL) { /* *mkey_aux_data points to next field of previous node */ *mkey_aux_data = (krb5_mkey_aux_node *) malloc(sizeof(krb5_mkey_aux_node)); - if (mkey_aux_data == NULL) { + if (*mkey_aux_data == NULL) { com_err(progname, ENOMEM, "while creating mkey_aux_data"); exit_status++; return; @@ -225,12 +234,13 @@ kdb5_add_mkey(int argc, char *argv[]) memset(*mkey_aux_data, 0, sizeof(krb5_mkey_aux_node)); } + memset(&tmp_key_data, 0, sizeof(tmp_key_data)); /* encrypt the new mkey with the older mkey */ retval = krb5_dbekd_encrypt_key_data(util_context, &plainkey, - &new_master_keyblock, - NULL, /* no keysalt */ - (int) key_data->key_data_kvno, - &tmp_key_data); + &new_master_keyblock, + NULL, /* no keysalt */ + (int) new_mkey_kvno, + &tmp_key_data); if (retval) { com_err(progname, retval, "while encrypting master keys"); exit_status++; @@ -242,7 +252,10 @@ kdb5_add_mkey(int argc, char *argv[]) mkey_aux_data = &((*mkey_aux_data)->next); - /* Store old key in master_entry keydata, + 1 to skip the first key_data entry */ + /* + * Store old key in master_entry keydata, + 1 to avoid overwritting the + * first key_data entry + */ retval = krb5_dbekd_encrypt_key_data(util_context, &new_master_keyblock, &plainkey, NULL, /* no keysalt */ @@ -262,8 +275,63 @@ kdb5_add_mkey(int argc, char *argv[]) free(key_data->key_data_contents[j]); } } + } /* end for (i = 0; i < old_key_data_count; i++) */ +#endif /**************** END IFDEF'ed OUT *******************************/ + + for (keylist_node = master_keylist, i = 1; keylist_node != NULL; + keylist_node = keylist_node->next, i++) { + + /* + * Create a list of krb5_mkey_aux_node nodes. One node contains the new + * mkey encrypted by an old mkey and the old mkey's kvno (one node per + * old mkey). + */ + if (*mkey_aux_data == NULL) { + /* *mkey_aux_data points to next field of previous node */ + *mkey_aux_data = (krb5_mkey_aux_node *) malloc(sizeof(krb5_mkey_aux_node)); + if (*mkey_aux_data == NULL) { + com_err(progname, ENOMEM, "while creating mkey_aux_data"); + exit_status++; + return; + } + memset(*mkey_aux_data, 0, sizeof(krb5_mkey_aux_node)); + } + + memset(&tmp_key_data, 0, sizeof(tmp_key_data)); + /* encrypt the new mkey with the older mkey */ + retval = krb5_dbekd_encrypt_key_data(util_context, &keylist_node->keyblock, + &new_master_keyblock, + NULL, /* no keysalt */ + (int) new_mkey_kvno, + &tmp_key_data); + if (retval) { + com_err(progname, retval, "while encrypting master keys"); + exit_status++; + return; + } + + (*mkey_aux_data)->latest_mkey = tmp_key_data; + (*mkey_aux_data)->mkey_kvno = keylist_node->kvno; + mkey_aux_data = &((*mkey_aux_data)->next); + + /* + * Store old key in master_entry keydata past the new mkey + */ + retval = krb5_dbekd_encrypt_key_data(util_context, &new_master_keyblock, + &keylist_node->keyblock, + NULL, /* no keysalt */ + (int) keylist_node->kvno, + &master_entry.key_data[i]); + if (retval) { + com_err(progname, retval, "while encrypting master keys"); + exit_status++; + return; + } } + printf("i = %d old_key_data_count = %d\n", i, old_key_data_count); + assert(i == old_key_data_count + 1); + if ((retval = krb5_dbe_update_mkey_aux(util_context, &master_entry, mkey_aux_data_head))) { com_err(progname, retval, "while updating mkey aux data"); @@ -278,7 +346,7 @@ kdb5_add_mkey(int argc, char *argv[]) } if ((retval = krb5_dbe_update_mod_princ_data(util_context, &master_entry, - now, master_princ))) { + now, master_princ))) { com_err(progname, retval, "while updating the master key principal modification time"); exit_status++; return; @@ -338,12 +406,13 @@ kdb5_use_mkey(int argc, char *argv[]) int nentries = 0; krb5_boolean more = 0; - if (argc < 1 || argc > 2) { + if (argc < 2 || argc > 3) { /* usage calls exit */ usage(); } - use_kvno = (int) strtol(argv[0], (char **)NULL, 10); + /* use_kvno = (int) strtol(argv[0], (char **)NULL, 10); */ + use_kvno = atoi(argv[1]); if (use_kvno == 0) { com_err(progname, EINVAL, ": 0 is an invalid KVNO value."); exit_status++; @@ -356,8 +425,8 @@ kdb5_use_mkey(int argc, char *argv[]) return; } - if (argc == 2) { - start_time = (krb5_timestamp) get_date(argv[0]); + if (argc == 3) { + start_time = (krb5_timestamp) get_date(argv[2]); } else { start_time = now; } @@ -411,62 +480,52 @@ kdb5_use_mkey(int argc, char *argv[]) exit_status++; return; } + memset(new_actkvno, 0, sizeof(krb5_actkvno_node)); new_actkvno->act_kvno = use_kvno; new_actkvno->act_time = start_time; - if (actkvno_list == NULL || new_actkvno->act_time < actkvno_list->act_time) { - /* insert new actkvno at head of list and link rest following */ - new_actkvno->next = actkvno_list; + if (actkvno_list == NULL) { + /* new actkvno is the list */ new_actkvno_list_head = new_actkvno; } else { - for (new_actkvno_list_head = prev_actkvno = cur_actkvno = actkvno_list; + krb5_boolean inserted = FALSE, trimed = FALSE; + + for (prev_actkvno = NULL, cur_actkvno = actkvno_list; cur_actkvno != NULL; prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) { - if (cur_actkvno->act_time <= now) { + if (!inserted) { if (new_actkvno->act_time < cur_actkvno->act_time) { - /* - * This is a problem as the new actkvno would be skipped and - * not added to the entries for the mkey princ. - */ - com_err(progname, EINVAL, - "Activation time %s is less than a existing currently " - "active kvno %d (activation time %s)", - strdate(new_actkvno->act_time), cur_actkvno->act_kvno, - strdate(cur_actkvno->act_time)); - exit_status++; - return; + if (prev_actkvno) { + prev_actkvno->next = new_actkvno; + new_actkvno->next = cur_actkvno; + } else { + new_actkvno->next = actkvno_list; + actkvno_list = new_actkvno; + } + inserted = TRUE; + } else if (cur_actkvno->next == NULL) { + /* end of line, just add new node to end of list */ + cur_actkvno->next = new_actkvno; + inserted = TRUE; } - /* - * New list head should point to the most current valid node in - * order to trim out of date entries. - */ - new_actkvno_list_head = cur_actkvno; } - - if (new_actkvno->act_time < cur_actkvno->act_time) { - if (new_actkvno_list_head == cur_actkvno) { - /* - * XXX WAF: trying to minimize race condition issue here, - * maybe there is a better way to do this? - */ - com_err(progname, EINVAL, - "Activation time %s is less than an existing currently " - "active kvno %d (activation time %s)", - strdate(new_actkvno->act_time), cur_actkvno->act_kvno, - strdate(cur_actkvno->act_time)); - exit_status++; - return; + if (!trimed) { + if (cur_actkvno->act_time > now) { + if (prev_actkvno) { + new_actkvno_list_head = prev_actkvno; + } else { + new_actkvno_list_head = actkvno_list; + } + trimed = TRUE; + } else if (cur_actkvno->next == NULL) { + new_actkvno_list_head = cur_actkvno; + trimed = TRUE; } - prev_actkvno->next = new_actkvno; - new_actkvno->next = cur_actkvno; - break; - } else if (cur_actkvno->next == NULL) { - /* end of line, just add new node to end of list */ - cur_actkvno->next = new_actkvno; - break; } + if (trimed && inserted) + break; } /* end for (new_actkvno_list_head = prev_actkvno = ... */ } @@ -517,6 +576,12 @@ kdb5_list_mkeys(int argc, char *argv[]) krb5_keylist_node *cur_kb_node; krb5_keyblock *act_mkey; + if (master_keylist == NULL) { + com_err(progname, retval, "master keylist not initialized"); + exit_status++; + return; + } + /* assemble & parse the master key name */ if ((retval = krb5_db_setup_mkey_name(util_context, global_params.mkey_name, @@ -541,12 +606,6 @@ kdb5_list_mkeys(int argc, char *argv[]) exit_status++; return; } - /* XXX WAF: debug code, remove before commit */ - if (master_keylist == NULL) { - com_err(progname, retval, "master_keylist == NULL this is a problem"); - exit_status++; - return; - } if (actkvno_list == NULL) { act_kvno = master_entry.key_data[0].key_data_kvno; @@ -573,6 +632,7 @@ kdb5_list_mkeys(int argc, char *argv[]) } if (actkvno_list != NULL) { + act_time = 0; for (cur_actkvno = actkvno_list; cur_actkvno != NULL; cur_actkvno = cur_actkvno->next) { if (cur_actkvno->act_kvno == cur_kb_node->kvno) { @@ -596,11 +656,16 @@ kdb5_list_mkeys(int argc, char *argv[]) asprintf(&output_str, "KNVO: %d, Enctype: %s, Active on: %s *\n", cur_kb_node->kvno, enctype, strdate(act_time)); } else { - asprintf(&output_str, "KNVO: %d, Enctype: %s, Active on: %s\n", - cur_kb_node->kvno, enctype, strdate(act_time)); + if (act_time) { + asprintf(&output_str, "KNVO: %d, Enctype: %s, Active on: %s\n", + cur_kb_node->kvno, enctype, strdate(act_time)); + } else { + asprintf(&output_str, "KNVO: %d, Enctype: %s, Not activated\n", + cur_kb_node->kvno, enctype); + } } + printf("%s", output_str); } - printf("%s", output_str); /* clean up */ (void) krb5_db_fini(util_context); diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c index 7a8df47684..aadf04ac85 100644 --- a/src/kadmin/dbutil/kdb5_util.c +++ b/src/kadmin/dbutil/kdb5_util.c @@ -90,6 +90,8 @@ void usage() "\t [-rev] [-recurse] [filename [princs...]]\n" "\tload [-old] [-ov] [-b6] [-verbose] [-update] filename\n" "\tark [-e etype_list] principal\n" + "\tadd_mkey [-e etype] [-s]\n" + "\tuse_mkey kvno [time]\n" "\tlist_mkeys\n"); /* avoid a string length compiler warning */ fprintf(stderr, @@ -434,7 +436,8 @@ static int open_db_and_mkey() if (global_params.mask & KADM5_CONFIG_KVNO) kvno = global_params.kvno; /* user specified */ else - kvno = (krb5_kvno) master_entry.key_data->key_data_kvno; + kvno = IGNORE_VNO; + /* kvno = (krb5_kvno) master_entry.key_data->key_data_kvno; */ krb5_db_free_principal(util_context, &master_entry, nentries); @@ -481,7 +484,8 @@ static int open_db_and_mkey() exit_status++; return(0); } - +#if 0 /************** Begin IFDEF'ed OUT *******************************/ + /* krb5_db_fetch_mkey_list will verify the mkey */ if ((retval = krb5_db_verify_master_key(util_context, master_princ, kvno, &master_keyblock))) { com_err(progname, retval, "while verifying master key"); @@ -489,13 +493,10 @@ static int open_db_and_mkey() krb5_free_keyblock_contents(util_context, &master_keyblock); return(1); } +#endif /**************** END IFDEF'ed OUT *******************************/ - /* - * I think I need to get the mkey list here so the ark command will - * work properly. - */ if ((retval = krb5_db_fetch_mkey_list(util_context, master_princ, - &master_keyblock, kvno, &master_keylist))) { + &master_keyblock, kvno, &master_keylist))) { com_err(progname, retval, "while getting master key list"); com_err(progname, 0, "Warning: proceeding without master key list"); exit_status++; diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index 5930d79d12..9833a2bb49 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -1332,6 +1332,7 @@ kadm5_chpass_principal_3(void *server_handle, kadm5_server_handle_t handle = server_handle; osa_pw_hist_ent hist; krb5_keyblock *act_mkey; + krb5_kvno act_kvno; CHECK_HANDLE(server_handle); @@ -1366,7 +1367,7 @@ kadm5_chpass_principal_3(void *server_handle, goto done; ret = krb5_dbe_find_act_mkey(handle->context, master_keylist, - active_mkey_list, NULL, &act_mkey); + active_mkey_list, &act_kvno, &act_mkey); if (ret) goto done; @@ -1378,6 +1379,10 @@ kadm5_chpass_principal_3(void *server_handle, if (ret) goto done; + ret = krb5_dbe_update_mkvno(handle->context, &kdb, act_kvno); + if (ret) + goto done; + kdb.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; ret = krb5_timeofday(handle->context, &now); diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index cebbb181e2..07c76abb32 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -1930,9 +1930,9 @@ krb5_dbe_fetch_act_mkey_list(krb5_context context, if (tmp_actkvno == NULL) return (ENOMEM); + memset(tmp_actkvno, 0, sizeof(krb5_actkvno_node)); tmp_actkvno->act_time = now; tmp_actkvno->act_kvno = master_entry.key_data[0].key_data_kvno; - tmp_actkvno->next = NULL; *act_mkey_list = tmp_actkvno; } @@ -2373,14 +2373,15 @@ krb5_dbe_lookup_mkey_aux(krb5_context context, /* curloc points to first tuple entry in the tl_data_contents */ curloc = tl_data.tl_data_contents + sizeof(version); - while (curloc != (tl_data.tl_data_contents + tl_data.tl_data_length)) { - assert(curloc < tl_data.tl_data_contents + tl_data.tl_data_length); + while (curloc < (tl_data.tl_data_contents + tl_data.tl_data_length)) { new_data = (krb5_mkey_aux_node *) malloc(sizeof(krb5_mkey_aux_node)); if (new_data == NULL) { krb5_free_mkey_aux_list(context, head_data); return (ENOMEM); } + memset(new_data, 0, sizeof(krb5_mkey_aux_node)); + krb5_kdb_decode_int16(curloc, new_data->mkey_kvno); curloc += sizeof(krb5_ui_2); krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_kvno); @@ -2399,6 +2400,10 @@ krb5_dbe_lookup_mkey_aux(krb5_context context, } memcpy(new_data->latest_mkey.key_data_contents[0], curloc, new_data->latest_mkey.key_data_length[0]); + curloc += new_data->latest_mkey.key_data_length[0]; + + /* always using key data ver 1 for mkeys */ + new_data->latest_mkey.key_data_ver = 1; new_data->next = NULL; if (prev_data != NULL) @@ -2425,23 +2430,25 @@ krb5_dbe_update_mkey_aux(krb5_context context, { krb5_tl_data tl_data; krb5_int16 version, tmp_kvno; - /* krb5_octet *nextloc; */ unsigned char *nextloc; krb5_mkey_aux_node *aux_data_entry; + memset(&tl_data, 0, sizeof(tl_data)); tl_data.tl_data_type = KRB5_TL_MKEY_AUX; /* - * determine out how much space to allocate + * determine out how much space to allocate. Note key_data_ver not stored + * as this is hard coded to one and is accounted for in + * krb5_dbe_lookup_mkey_aux. */ tl_data.tl_data_length = sizeof(version); /* version */ for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL; aux_data_entry = aux_data_entry->next) { - tl_data.tl_data_length += sizeof(krb5_ui_2); /* mkey_kvno */ - tl_data.tl_data_length += sizeof(krb5_ui_2); /* latest_mkey kvno */ - tl_data.tl_data_length += sizeof(krb5_ui_2); /* latest_mkey enctype */ - tl_data.tl_data_length += sizeof(krb5_ui_2); /* latest_mkey length */ - tl_data.tl_data_length += - aux_data_entry->latest_mkey.key_data_length[0]; /* mkey data */ + + tl_data.tl_data_length += (sizeof(krb5_ui_2) + /* mkey_kvno */ + sizeof(krb5_ui_2) + /* latest_mkey kvno */ + sizeof(krb5_ui_2) + /* latest_mkey enctype */ + sizeof(krb5_ui_2) + /* latest_mkey length */ + aux_data_entry->latest_mkey.key_data_length[0]); } tl_data.tl_data_contents = (krb5_octet *) malloc(tl_data.tl_data_length); @@ -2460,19 +2467,22 @@ krb5_dbe_update_mkey_aux(krb5_context context, tmp_kvno = (krb5_int16) aux_data_entry->mkey_kvno; krb5_kdb_encode_int16(tmp_kvno, nextloc); nextloc += sizeof(krb5_ui_2); + krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_kvno, nextloc); nextloc += sizeof(krb5_ui_2); + krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_type[0], nextloc); nextloc += sizeof(krb5_ui_2); + krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_length[0], nextloc); nextloc += sizeof(krb5_ui_2); if (aux_data_entry->latest_mkey.key_data_length[0] > 0) { memcpy(nextloc, aux_data_entry->latest_mkey.key_data_contents[0], - aux_data_entry->latest_mkey.key_data_length[0]); + aux_data_entry->latest_mkey.key_data_length[0]); nextloc += aux_data_entry->latest_mkey.key_data_length[0]; } } @@ -2518,7 +2528,8 @@ krb5_dbe_lookup_actkvno(krb5_context context, * Find number of tuple entries, remembering to account for version * field. */ - num_actkvno = (tl_data.tl_data_length - sizeof(version)) / ACTKVNO_TUPLE_SIZE; + num_actkvno = (tl_data.tl_data_length - sizeof(version)) / + ACTKVNO_TUPLE_SIZE; prev_data = NULL; /* next_tuple points to first tuple entry in the tl_data_contents */ next_tuple = tl_data.tl_data_contents + sizeof(version); @@ -2528,12 +2539,13 @@ krb5_dbe_lookup_actkvno(krb5_context context, krb5_free_actkvno_list(context, head_data); return (ENOMEM); } + memset(new_data, 0, sizeof(krb5_actkvno_node)); + /* using tmp_kvno to avoid type mismatch */ krb5_kdb_decode_int16(act_kvno(next_tuple), tmp_kvno); new_data->act_kvno = (krb5_kvno) tmp_kvno; krb5_kdb_decode_int32(act_time(next_tuple), new_data->act_time); - new_data->next = NULL; if (prev_data != NULL) prev_data->next = new_data; else diff --git a/src/lib/kdb/kdb_default.c b/src/lib/kdb/kdb_default.c index a5c8ea444b..5a711ab49a 100644 --- a/src/lib/kdb/kdb_default.c +++ b/src/lib/kdb/kdb_default.c @@ -501,22 +501,22 @@ krb5_def_fetch_mkey_list(krb5_context context, int i; if (mkeys_list == NULL) - return (EINVAL); + return (EINVAL); memset(&tmp_clearkey, 0, sizeof(tmp_clearkey)); nprinc = 1; if ((retval = krb5_db_get_principal(context, mprinc, - &master_entry, &nprinc, &more))) - return (retval); - + &master_entry, &nprinc, &more))) + return (retval); + if (nprinc != 1) { - if (nprinc) - krb5_db_free_principal(context, &master_entry, nprinc); - return(KRB5_KDB_NOMASTERKEY); + if (nprinc) + krb5_db_free_principal(context, &master_entry, nprinc); + return(KRB5_KDB_NOMASTERKEY); } else if (more) { - krb5_db_free_principal(context, &master_entry, nprinc); - return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); + krb5_db_free_principal(context, &master_entry, nprinc); + return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); } /* @@ -524,46 +524,46 @@ krb5_def_fetch_mkey_list(krb5_context context, * latest mkey. */ if ((retval = krb5_dbekd_decrypt_key_data(context, mkey, - &master_entry.key_data[0], - &tmp_clearkey, NULL)) != 0) { - /* - * Note the mkvno may provide a hint as to which mkey_aux tuple to - * decrypt. - */ - if ((retval = krb5_dbe_lookup_mkey_aux(context, &master_entry, &mkey_aux_data_list))) - goto clean_n_exit; - - /* for performance sake, try decrypting with matching kvno */ - for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL; - aux_data_entry = aux_data_entry->next) { - - if (aux_data_entry->mkey_kvno == mkvno) { - if (krb5_dbekd_decrypt_key_data(context, mkey, &aux_data_entry->latest_mkey, - &tmp_clearkey, NULL) == 0) { - found_key = TRUE; - break; - } - } - } - if (found_key != TRUE) { - /* given the importance of acquiring the latest mkey, try brute force */ - for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL; - aux_data_entry = aux_data_entry->next) { - - if (krb5_dbekd_decrypt_key_data(context, mkey, &aux_data_entry->latest_mkey, - &tmp_clearkey, NULL) == 0) { - found_key = TRUE; - /* XXX WAF: should I issue warning about kvno not matching? */ - break; - } - } - if (found_key != TRUE) { - krb5_set_error_message (context, KRB5_KDB_BADMASTERKEY, - "Unable to decrypt latest master key with the provided master key\n"); - retval = KRB5_KDB_BADMASTERKEY; - goto clean_n_exit; - } - } + &master_entry.key_data[0], + &tmp_clearkey, NULL)) != 0) { + /* + * Note the mkvno may provide a hint as to which mkey_aux tuple to + * decrypt. + */ + if ((retval = krb5_dbe_lookup_mkey_aux(context, &master_entry, &mkey_aux_data_list))) + goto clean_n_exit; + + /* for performance sake, try decrypting with matching kvno */ + for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL; + aux_data_entry = aux_data_entry->next) { + + if (aux_data_entry->mkey_kvno == mkvno) { + if (krb5_dbekd_decrypt_key_data(context, mkey, &aux_data_entry->latest_mkey, + &tmp_clearkey, NULL) == 0) { + found_key = TRUE; + break; + } + } + } + if (found_key != TRUE) { + /* given the importance of acquiring the latest mkey, try brute force */ + for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL; + aux_data_entry = aux_data_entry->next) { + + if (krb5_dbekd_decrypt_key_data(context, mkey, &aux_data_entry->latest_mkey, + &tmp_clearkey, NULL) == 0) { + found_key = TRUE; + /* XXX WAF: should I issue warning about kvno not matching? */ + break; + } + } + if (found_key != TRUE) { + krb5_set_error_message (context, KRB5_KDB_BADMASTERKEY, + "Unable to decrypt latest master key with the provided master key\n"); + retval = KRB5_KDB_BADMASTERKEY; + goto clean_n_exit; + } + } current_mkey = &tmp_clearkey; } else { current_mkey = mkey; @@ -576,8 +576,8 @@ krb5_def_fetch_mkey_list(krb5_context context, mkey_list_head = (krb5_keylist_node *) malloc(sizeof(krb5_keylist_node)); if (mkey_list_head == NULL) { - retval = ENOMEM; - goto clean_n_exit; + retval = ENOMEM; + goto clean_n_exit; } memset(mkey_list_head, 0, sizeof(krb5_keylist_node)); @@ -587,24 +587,25 @@ krb5_def_fetch_mkey_list(krb5_context context, * if there are any others then do for loop below. */ for (i = 0; i < master_entry.n_key_data; i++) { - if (*mkey_list_node == NULL) { - /* *mkey_list_node points to next field of previous node */ - *mkey_list_node = (krb5_keylist_node *) malloc(sizeof(krb5_keylist_node)); - if (*mkey_list_node == NULL) { - retval = ENOMEM; - goto clean_n_exit; - } - memset(*mkey_list_node, 0, sizeof(krb5_keylist_node)); - } - key_data = &master_entry.key_data[i]; - retval = krb5_dbekd_decrypt_key_data(context, current_mkey, - key_data, &((*mkey_list_node)->keyblock), - NULL); - if (retval) - goto clean_n_exit; + if (*mkey_list_node == NULL) { + /* *mkey_list_node points to next field of previous node */ + *mkey_list_node = (krb5_keylist_node *) malloc(sizeof(krb5_keylist_node)); + if (*mkey_list_node == NULL) { + retval = ENOMEM; + goto clean_n_exit; + } + memset(*mkey_list_node, 0, sizeof(krb5_keylist_node)); + } + key_data = &master_entry.key_data[i]; + retval = krb5_dbekd_decrypt_key_data(context, current_mkey, + key_data, + &((*mkey_list_node)->keyblock), + NULL); + if (retval) + goto clean_n_exit; (*mkey_list_node)->kvno = key_data->key_data_kvno; - mkey_list_node = &((*mkey_list_node)->next); + mkey_list_node = &((*mkey_list_node)->next); } *mkeys_list = mkey_list_head; @@ -612,21 +613,21 @@ krb5_def_fetch_mkey_list(krb5_context context, clean_n_exit: if (tmp_clearkey.contents) { - memset(tmp_clearkey.contents, 0, tmp_clearkey.length); - krb5_db_free(context, tmp_clearkey.contents); + memset(tmp_clearkey.contents, 0, tmp_clearkey.length); + krb5_db_free(context, tmp_clearkey.contents); } krb5_db_free_principal(context, &master_entry, nprinc); if (retval != 0) { - krb5_keylist_node *cur_node, *next_node; + krb5_keylist_node *cur_node, *next_node; - for (cur_node = mkey_list_head; cur_node != NULL; cur_node = next_node) { - next_node = cur_node->next; - krb5_free_keyblock(context, &(cur_node->keyblock)); - krb5_xfree(cur_node); - } + for (cur_node = mkey_list_head; cur_node != NULL; cur_node = next_node) { + next_node = cur_node->next; + krb5_free_keyblock(context, &(cur_node->keyblock)); + krb5_xfree(cur_node); + } } - + return retval; } -- 2.47.2