Initial support for filtering out "dead" historical keys.

This commit is contained in:
Nicolas Williams
2011-07-15 19:13:10 -05:00
committed by Nicolas Williams
parent 7e0a801e28
commit 308e53a4a8
3 changed files with 26 additions and 13 deletions

View File

@@ -164,7 +164,7 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
return ret;
}
/* Decrypt the key history too */
ret = hdb_unseal_keys_kvno(context, db, 0, &entry->entry);
ret = hdb_unseal_keys_kvno(context, db, 0, flags, &entry->entry);
if (ret) {
hdb_free_entry(context, entry);
return ret;
@@ -182,7 +182,7 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
* Find and decrypt the keys from the history that we want,
* and swap them with the current keys
*/
ret = hdb_unseal_keys_kvno(context, db, 0, &entry->entry);
ret = hdb_unseal_keys_kvno(context, db, 0, flags, &entry->entry);
if (ret) {
hdb_free_entry(context, entry);
return ret;
@@ -190,7 +190,7 @@ _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
}
if ((flags & HDB_F_ALL_KVNOS)) {
/* Decrypt the history, post current/requested switcheroo */
ret = hdb_unseal_keys_kvno(context, db, 0, &entry->entry);
ret = hdb_unseal_keys_kvno(context, db, 0, flags, &entry->entry);
if (ret) {
hdb_free_entry(context, entry);
return ret;

View File

@@ -58,7 +58,9 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
#define HDB_F_ADMIN_DATA 64 /* want data that kdc don't use */
#define HDB_F_KVNO_SPECIFIED 128 /* we want a particular KVNO */
#define HDB_F_CURRENT_KVNO 256 /* we want the current KVNO */
#define HDB_F_ALL_KVNOS 512 /* we want all the keys */
#define HDB_F_LIVE_CLNT_KVNOS 512 /* we want all live keys for pre-auth */
#define HDB_F_LIVE_SVC_KVNOS 1024 /* we want all live keys for tix */
#define HDB_F_ALL_KVNOS 2048 /* we want all the keys, live or not */
/* hdb_capability_flags */
#define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1

View File

@@ -482,7 +482,7 @@ hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent)
krb5_error_code
hdb_unseal_keys_kvno(krb5_context context, HDB *db, krb5_kvno kvno,
hdb_entry *ent)
unsigned flags, hdb_entry *ent)
{
krb5_error_code ret = KRB5KRB_AP_ERR_NOKEY; /* XXX need a better code? */
HDB_extension *ext;
@@ -492,6 +492,13 @@ hdb_unseal_keys_kvno(krb5_context context, HDB *db, krb5_kvno kvno,
unsigned int tmp_len;
krb5_kvno tmp_kvno;
int i, k;
int exclude_dead = 0;
KerberosTime now = 0;
if ((flags & HDB_F_LIVE_CLNT_KVNOS) || (flags & HDB_F_LIVE_SVC_KVNOS)) {
exclude_dead = 1;
now = time(NULL);
}
assert(kvno == 0 || kvno < ent->kvno);
@@ -509,6 +516,15 @@ hdb_unseal_keys_kvno(krb5_context context, HDB *db, krb5_kvno kvno,
if (kvno != 0 && hist_keys->val[i].kvno != kvno)
continue;
if (exclude_dead && ent->max_life != NULL &&
hist_keys->val[i].set_time < (now - (*ent->max_life)))
/*
* The KDC may want to to check for this keyset's set_time
* is within the TGS principal's max_life, say. But we stop
* here.
*/
continue;
/* Either the keys we want, or all the keys */
for (k = 0; k < hist_keys->val[i].keys.len; k++) {
ret = hdb_unseal_key_mkey(context,
@@ -518,14 +534,9 @@ hdb_unseal_keys_kvno(krb5_context context, HDB *db, krb5_kvno kvno,
* If kvno == 0 we might not want to bail here! E.g., if we
* no longer have the right master key, so just ignore this.
*
* Might we want to filter out keys that we can't decrypt
* because of HDB_ERR_NO_MKEY? Probably. If nothing else
* so we don't leave turds behind. But also in case of old
* master keys derived from passwords -- we don't want to
* help kadmin clients with fetch authorization be able to
* mount dictionary attacks on old master keys. Also,
* mayber we're misconfigured and simply can't find a live
* master key.
* We could filter out keys that we can't decrypt here
* because of HDB_ERR_NO_MKEY. However, it seems safest to
* filter them out only where necessary, say, in kadm5.
*/
if (ret != HDB_ERR_NO_MKEY)
return (ret);