diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/kdb/ChangeLog | 28 | ||||
| -rw-r--r-- | src/lib/kdb/decrypt_key.c | 1 | ||||
| -rw-r--r-- | src/lib/kdb/kdb_cpw.c | 91 | ||||
| -rw-r--r-- | src/lib/kdb/kdb_xdr.c | 125 |
4 files changed, 205 insertions, 40 deletions
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index 8ef46b836..15bdd684b 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,31 @@ + +Fri Nov 03 04:49:58 1995 Chris Provenzano (proven@mit.edu) + + * decrypt_key.c (krb5_dbekd_decrypt_key_data()) : If key salt length + is 0 then set keysalt->data.data to NULL. + * kdb_cpw.c (add_key_rnd(), add_key_pwd()) : When creating new keys + for a new kvno and there are multiple enctypes that use a + common keytype, then set the enctype in the key to the first + specified enctype and skip all other enctypes that use + the same keytype. (This assumes the salt type is the same too.) + This way when the kdc needs to get the server key it doesn't + need to gues what enctypes the server supports. + * kdb_xdr.c (krb5_dbe_find_enctype()): Match keys that use common + keytypes but different enctypes. Eg. ENCTYPE_DES_CBC_MD5 + matches ENCTYPE_DES_CBC_CRC and vice versa. + * kdb_xdr.c krb5_dbe_find_enctype()): If kvno = 0 then determine + maxkvno for all the keys and then search keys for a key that + matches enctype salttype and has kvno == maxkvno. This + is different than when kvno = -1 which searches the keys + for THE key with the greatest kvno which also matches enctype + and salttype. + * kdb_kdr.c (krb5_dbe_find_enctype()): If kvno = ktype = stype = -1 + then set kvno = 0. The first doesn't make a lot of sense. + * kdb_xdr.c (krb5_dbe_encode_last_pwd_change(), + krb5_dbe_decode_last_pwd_change()) : Added. + * kdb_xdr.c (krb5_decode_princ_contents()) : Don't try to allocate + space for keys if n_key_data = 0. + Mon Sep 25 17:31:02 1995 Theodore Y. Ts'o <tytso@dcl> * Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c index 4f67d519e..32891098d 100644 --- a/src/lib/kdb/decrypt_key.c +++ b/src/lib/kdb/decrypt_key.c @@ -84,6 +84,7 @@ krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) keysalt->data.data = (char *) NULL; } else { keysalt->type = KRB5_KDB_SALTTYPE_NORMAL; + keysalt->data.data = (char *) NULL; keysalt->data.length = 0; } } diff --git a/src/lib/kdb/kdb_cpw.c b/src/lib/kdb/kdb_cpw.c index 4b6dcd4ba..b88a97478 100644 --- a/src/lib/kdb/kdb_cpw.c +++ b/src/lib/kdb/kdb_cpw.c @@ -76,15 +76,16 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) int kvno; { krb5_principal krbtgt_princ; - krb5_keyblock krbtgt_keyblock, * key; + krb5_keyblock krbtgt_key, * key; krb5_pointer krbtgt_seed; krb5_encrypt_block krbtgt_eblock; krb5_db_entry krbtgt_entry; + krb5_key_data * krbtgt_kdata; krb5_boolean more, found; int max_kvno, one, i, j; krb5_error_code retval; - memset(&krbtgt_keyblock, 0, sizeof(krbtgt_keyblock)); + memset(&krbtgt_key, 0, sizeof(krbtgt_key)); retval = krb5_build_principal_ext(context, &krbtgt_princ, db_entry->princ->realm.length, db_entry->princ->realm.data, @@ -117,14 +118,33 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) } for (i = 0; i < ks_tuple_count; i++) { + krb5_enctype new_enctype, old_enctype; + + switch (new_enctype = ks_tuple[i].ks_enctype) { + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + new_enctype = ENCTYPE_DES_CBC_CRC; + default: + break; + } + found = 0; + /* * We could use krb5_keysalt_iterate to replace this loop, or use * krb5_keysalt_is_present for the loop below, but we want to avoid * circular library dependencies. */ - found = 0; for (j = 0; j < i; j++) { - if (ks_tuple[j].ks_enctype == ks_tuple[i].ks_enctype) { + switch (old_enctype = ks_tuple[j].ks_enctype) { + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + old_enctype = ENCTYPE_DES_CBC_CRC; + default: + break; + } + if (old_enctype == new_enctype) { found = 1; break; } @@ -134,35 +154,26 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) if (retval = krb5_dbe_create_key_data(context, db_entry)) goto add_key_rnd_err; - for (j = 0; j < krbtgt_entry.n_key_data; j++) { - if ((krbtgt_entry.key_data[j].key_data_kvno == max_kvno) && - (krbtgt_entry.key_data[j].key_data_type[0] == - ks_tuple[i].ks_enctype)) { - break; - } - } - - if (j == krbtgt_entry.n_key_data) { - retval = KRB5_KDB_BAD_ENCTYPE; + if (retval = krb5_dbe_find_enctype(context, &krbtgt_entry, + ks_tuple[i].ks_enctype, + -1, 0, &krbtgt_kdata)) goto add_key_rnd_err; - } /* Decrypt key */ if (retval = krb5_dbekd_decrypt_key_data(context, master_eblock, - &krbtgt_entry.key_data[j], - &krbtgt_keyblock, NULL)) { + krbtgt_kdata,&krbtgt_key,NULL)) goto add_key_rnd_err; - } /* Init key */ + krbtgt_key.enctype = ks_tuple[i].ks_enctype; krb5_use_enctype(context, &krbtgt_eblock, ks_tuple[i].ks_enctype); - if (retval = krb5_process_key(context,&krbtgt_eblock,&krbtgt_keyblock)){ + if (retval = krb5_process_key(context, &krbtgt_eblock, &krbtgt_key)) { goto add_key_rnd_err; } /* Init random generator */ if (retval = krb5_init_random_key(context, &krbtgt_eblock, - &krbtgt_keyblock, &krbtgt_seed)) { + &krbtgt_key, &krbtgt_seed)) { krb5_finish_key(context, &krbtgt_eblock); goto add_key_rnd_err; } @@ -189,9 +200,9 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) add_key_rnd_err:; krb5_db_free_principal(context, &krbtgt_entry, one); - if (krbtgt_keyblock.contents && krbtgt_keyblock.length) { - memset(krbtgt_keyblock.contents, 0, krbtgt_keyblock.length); - krb5_xfree(krbtgt_keyblock.contents); + if (krbtgt_key.contents && krbtgt_key.length) { + memset(krbtgt_key.contents, 0, krbtgt_key.length); + krb5_xfree(krbtgt_key.contents); } return(retval); } @@ -308,17 +319,35 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, int i, j; for (i = 0; i < ks_tuple_count; i++) { + krb5_enctype new_enctype, old_enctype; + + switch (new_enctype = ks_tuple[i].ks_enctype) { + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + new_enctype = ENCTYPE_DES_CBC_CRC; + default: + break; + } /* * We could use krb5_keysalt_iterate to replace this loop, or use * krb5_keysalt_is_present for the loop below, but we want to avoid * circular library dependencies. */ - found = 0; - for (j = 0; j < i; j++) { - if ((ks_tuple[j].ks_enctype == ks_tuple[i].ks_enctype) && - (ks_tuple[j].ks_salttype == ks_tuple[i].ks_salttype)) { - found = 1; - break; + for (found = j = 0; j < i; j++) { + if (ks_tuple[j].ks_salttype == ks_tuple[i].ks_salttype) { + switch (old_enctype = ks_tuple[j].ks_enctype) { + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + old_enctype = ENCTYPE_DES_CBC_CRC; + default: + break; + } + if (old_enctype == new_enctype) { + found = 1; + break; + } } } if (found) @@ -360,8 +389,8 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, pwd.data = passwd; pwd.length = strlen(passwd); if (retval = krb5_string_to_key(context, &key_eblock, - ks_tuple[i].ks_enctype, &key, - &pwd, &key_salt.data)) + ks_tuple[i].ks_enctype, + &key, &pwd, &key_salt.data)) return(retval); if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock, &key, diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c index c91af0880..dee44db0c 100644 --- a/src/lib/kdb/kdb_xdr.c +++ b/src/lib/kdb/kdb_xdr.c @@ -48,6 +48,71 @@ krb5_dbe_create_key_data(context, entry) } krb5_error_code +krb5_dbe_encode_last_pwd_change(context, stamp, entry) + krb5_context context; + krb5_tl_last_change * stamp; + krb5_db_entry * entry; +{ + krb5_error_code retval; + krb5_tl_data ** tl_data; + krb5_octet * nextloc; + + /* Find any old versions and delete them. */ + for (tl_data = &(entry->tl_data); *tl_data; + tl_data = &((*tl_data)->tl_data_next)) { + if ((*tl_data)->tl_data_type == KRB5_TL_LAST_PWD_CHANGE) { + break; + } + } + + if ((*tl_data) || + /* Only zero data if it is freshly allocated */ + ((*tl_data) = (krb5_tl_data *)calloc(1, sizeof(krb5_tl_data)))) { + if (!(*tl_data)->tl_data_type) { + if ((nextloc = (*tl_data)->tl_data_contents = + (krb5_octet *)malloc(sizeof(krb5_timestamp))) == NULL) { + krb5_xfree(*tl_data); + (*tl_data) = NULL; + return ENOMEM; + } + (*tl_data)->tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + (*tl_data)->tl_data_length = sizeof(krb5_timestamp); + entry->n_tl_data++; + } + + *nextloc++ = (krb5_octet)(stamp->last_pwd_change & 0xff); + *nextloc++ = (krb5_octet)((stamp->last_pwd_change >> 8) & 0xff); + *nextloc++ = (krb5_octet)((stamp->last_pwd_change >> 16) & 0xff); + *nextloc++ = (krb5_octet)((stamp->last_pwd_change >> 24) & 0xff); + + return 0; + } + return ENOMEM; +} + +krb5_error_code +krb5_dbe_decode_last_pwd_change(context, entry, stamp) + krb5_context context; + krb5_db_entry * entry; + krb5_tl_last_change * stamp; +{ + krb5_tl_data * tl_data; + + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { + if (tl_data->tl_data_type == KRB5_TL_LAST_PWD_CHANGE) { + krb5_octet * nextloc = tl_data->tl_data_contents; + + stamp->last_pwd_change = *nextloc++; + stamp->last_pwd_change += (*nextloc++ << 8); + stamp->last_pwd_change += (*nextloc++ << 16); + stamp->last_pwd_change += (*nextloc++ << 24); + return 0; + } + } + stamp->last_pwd_change = 0; +} + +krb5_error_code krb5_dbe_encode_mod_princ_data(context, mod_princ, entry) krb5_context context; krb5_tl_mod_princ * mod_princ; @@ -527,8 +592,8 @@ krb5_decode_princ_contents(context, content, entry) } /* key_data is an array */ - if ((entry->key_data = (krb5_key_data *) - malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL) { + if (entry->n_key_data && ((entry->key_data = (krb5_key_data *) + malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL)) { retval = ENOMEM; goto error_out; } @@ -631,6 +696,8 @@ krb5_dbe_free_contents(context, entry) * most appropriate krb5_key_data entry of the database entry. * * If stype or kvno is negative, it is ignored. + * If kvno is 0 get the key which is maxkvno for the princ and matches + * the other attributes. */ krb5_error_code krb5_dbe_find_enctype(kcontext, dbentp, ktype, stype, kvno, kdatap) @@ -645,20 +712,60 @@ krb5_dbe_find_enctype(kcontext, dbentp, ktype, stype, kvno, kdatap) int maxkvno; krb5_key_data *datap; + if (kvno == stype == ktype == -1) + kvno = 0; + + if (kvno == 0) { + /* Get the max key version */ + for (i = 0; i < dbentp->n_key_data; i++) { + if (kvno < dbentp->key_data[i].key_data_kvno) { + kvno = dbentp->key_data[i].key_data_kvno; + } + } + } + + /* + * ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD4, ENCTYPE_DES_CBC_MD5, + * ENCTYPE_DES_CBC_RAW all use the same key. + */ + switch (ktype) { + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + ktype = ENCTYPE_DES_CBC_CRC; + break; + default: + break; + } + maxkvno = -1; datap = (krb5_key_data *) NULL; - for (i=0; i<dbentp->n_key_data; i++) { - if (((krb5_enctype) dbentp->key_data[i].key_data_type[0]) == ktype && - ((dbentp->key_data[i].key_data_type[1] == stype) || - (stype < 0))) { + for (i = 0; i < dbentp->n_key_data; i++) { + krb5_enctype db_ktype; + krb5_int32 db_stype; + + switch (db_ktype = dbentp->key_data[i].key_data_type[0]) { + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + db_ktype = ENCTYPE_DES_CBC_CRC; + defualt: + break; + } + if (dbentp->key_data[i].key_data_ver > 1) { + db_stype = dbentp->key_data[i].key_data_type[1]; + } else { + db_stype = KRB5_KDB_SALTTYPE_NORMAL; + } + if (((db_ktype == ktype) || (ktype < 0)) && + ((db_stype == stype) || (stype < 0))) { if (kvno >= 0) { if (kvno == dbentp->key_data[i].key_data_kvno) { - maxkvno = kvno; datap = &dbentp->key_data[i]; + maxkvno = kvno; break; } - } - else { + } else { if (dbentp->key_data[i].key_data_kvno > maxkvno) { maxkvno = dbentp->key_data[i].key_data_kvno; datap = &dbentp->key_data[i]; |
