summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/kdb/ChangeLog28
-rw-r--r--src/lib/kdb/decrypt_key.c1
-rw-r--r--src/lib/kdb/kdb_cpw.c91
-rw-r--r--src/lib/kdb/kdb_xdr.c125
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];