2 * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "krb5_locl.h"
38 hdb_principal2key(krb5_context context, krb5_const_principal p, krb5_data *key)
44 ret = copy_Principal(p, &new);
47 new.name.name_type = 0;
49 ASN1_MALLOC_ENCODE(Principal, key->data, key->length, &new, &len, ret);
50 if (ret == 0 && key->length != len)
51 krb5_abortx(context, "internal asn.1 encoder error");
57 hdb_key2principal(krb5_context context, krb5_data *key, krb5_principal p)
59 return decode_Principal(key->data, key->length, p, NULL);
63 hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value)
68 ASN1_MALLOC_ENCODE(HDB_entry, value->data, value->length, ent, &len, ret);
69 if (ret == 0 && value->length != len)
70 krb5_abortx(context, "internal asn.1 encoder error");
75 hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent)
77 return decode_HDB_entry(value->data, value->length, ent, NULL);
81 hdb_entry_alias2value(krb5_context context,
82 const hdb_entry_alias *alias,
88 ASN1_MALLOC_ENCODE(HDB_entry_alias, value->data, value->length,
90 if (ret == 0 && value->length != len)
91 krb5_abortx(context, "internal asn.1 encoder error");
96 hdb_value2entry_alias(krb5_context context, krb5_data *value,
99 return decode_HDB_entry_alias(value->data, value->length, ent, NULL);
103 * Some old databases may not have stored the salt with each key, which will
104 * break clients when aliases or canonicalization are used. Generate a
105 * default salt based on the real principal name in the entry to handle
108 static krb5_error_code
109 add_default_salts(krb5_context context, HDB *db, hdb_entry *entry)
115 ret = krb5_get_pw_salt(context, entry->principal, &pwsalt);
119 for (i = 0; i < entry->keys.len; i++) {
120 Key *key = &entry->keys.val[i];
122 if (key->salt != NULL ||
123 _krb5_enctype_requires_random_salt(context, key->key.keytype))
126 key->salt = calloc(1, sizeof(*key->salt));
127 if (key->salt == NULL) {
128 ret = krb5_enomem(context);
132 key->salt->type = KRB5_PADATA_PW_SALT;
134 ret = krb5_data_copy(&key->salt->salt,
135 pwsalt.saltvalue.data,
136 pwsalt.saltvalue.length);
141 krb5_free_salt(context, pwsalt);
146 static krb5_error_code
147 fetch_entry_or_alias(krb5_context context,
149 krb5_const_principal principal,
153 HDB_EntryOrAlias eoa;
154 krb5_principal enterprise_principal = NULL;
155 krb5_data key, value;
162 if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
163 if (principal->name.name_string.len != 1) {
164 ret = KRB5_PARSE_MALFORMED;
165 krb5_set_error_message(context, ret, "malformed principal: "
166 "enterprise name with %d name components",
167 principal->name.name_string.len);
170 ret = krb5_parse_name(context, principal->name.name_string.val[0],
171 &enterprise_principal);
174 principal = enterprise_principal;
177 ret = hdb_principal2key(context, principal, &key);
179 ret = db->hdb__get(context, db, key, &value);
181 ret = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL);
182 if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_entry) {
183 entry->entry = eoa.u.entry;
184 } else if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias) {
185 krb5_data_free(&key);
186 ret = hdb_principal2key(context, eoa.u.alias.principal, &key);
188 krb5_data_free(&value);
189 ret = db->hdb__get(context, db, key, &value);
192 /* No alias chaining */
193 ret = hdb_value2entry(context, &value, &entry->entry);
194 krb5_free_principal(context, eoa.u.alias.principal);
197 if (ret == 0 && enterprise_principal) {
199 * Whilst Windows does not canonicalize enterprise principal names if
200 * the canonicalize flag is unset, the original specification in
201 * draft-ietf-krb-wg-kerberos-referrals-03.txt says we should.
203 entry->entry.flags.force_canonicalize = 1;
206 /* HDB_F_GET_ANY indicates request originated from KDC (not kadmin) */
207 if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias &&
208 (flags & (HDB_F_CANON|HDB_F_GET_ANY)) == 0) {
210 /* `principal' was alias but canon not req'd */
211 free_HDB_entry(&entry->entry);
212 ret = HDB_ERR_NOENTRY;
215 krb5_free_principal(context, enterprise_principal);
216 krb5_data_free(&value);
217 krb5_data_free(&key);
218 principal = enterprise_principal = NULL;
223 _hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal,
224 unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry)
228 ret = fetch_entry_or_alias(context, db, principal, flags, entry);
232 if ((flags & HDB_F_DECRYPT) && (flags & HDB_F_ALL_KVNOS)) {
233 /* Decrypt the current keys */
234 ret = hdb_unseal_keys(context, db, &entry->entry);
236 hdb_free_entry(context, entry);
239 /* Decrypt the key history too */
240 ret = hdb_unseal_keys_kvno(context, db, 0, flags, &entry->entry);
242 hdb_free_entry(context, entry);
245 } else if ((flags & HDB_F_DECRYPT)) {
246 if ((flags & HDB_F_KVNO_SPECIFIED) == 0 || kvno == entry->entry.kvno) {
247 /* Decrypt the current keys */
248 ret = hdb_unseal_keys(context, db, &entry->entry);
250 hdb_free_entry(context, entry);
254 if ((flags & HDB_F_ALL_KVNOS))
257 * Find and decrypt the keys from the history that we want,
258 * and swap them with the current keys
260 ret = hdb_unseal_keys_kvno(context, db, kvno, flags, &entry->entry);
262 hdb_free_entry(context, entry);
267 if ((flags & HDB_F_FOR_AS_REQ) && (flags & HDB_F_GET_CLIENT)) {
269 * Generate default salt for any principals missing one; note such
270 * principals could include those for which a random (non-password)
271 * key was generated, but given the salt will be ignored by a keytab
272 * client it doesn't hurt to include the default salt.
274 ret = add_default_salts(context, db, &entry->entry);
276 hdb_free_entry(context, entry);
284 static krb5_error_code
285 hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key)
287 const HDB_Ext_Aliases *aliases;
288 krb5_error_code code;
293 code = db->hdb__get(context, db, *key, &value);
294 if (code == HDB_ERR_NOENTRY)
299 code = hdb_value2entry(context, &value, &oldentry);
300 krb5_data_free(&value);
304 code = hdb_entry_get_aliases(&oldentry, &aliases);
305 if (code || aliases == NULL) {
306 free_HDB_entry(&oldentry);
309 for (i = 0; i < aliases->aliases.len; i++) {
312 code = hdb_principal2key(context, &aliases->aliases.val[i], &akey);
314 code = db->hdb__del(context, db, akey);
315 krb5_data_free(&akey);
318 free_HDB_entry(&oldentry);
322 free_HDB_entry(&oldentry);
326 static krb5_error_code
327 hdb_add_aliases(krb5_context context, HDB *db,
328 unsigned flags, hdb_entry_ex *entry)
330 const HDB_Ext_Aliases *aliases;
331 krb5_error_code code;
332 krb5_data key, value;
335 code = hdb_entry_get_aliases(&entry->entry, &aliases);
336 if (code || aliases == NULL)
339 for (i = 0; i < aliases->aliases.len; i++) {
340 hdb_entry_alias entryalias;
341 entryalias.principal = entry->entry.principal;
343 code = hdb_entry_alias2value(context, &entryalias, &value);
347 code = hdb_principal2key(context, &aliases->aliases.val[i], &key);
349 code = db->hdb__put(context, db, flags, key, value);
350 krb5_data_free(&key);
352 krb5_data_free(&value);
359 /* Check if new aliases are already used for other entries */
360 static krb5_error_code
361 hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry)
363 const HDB_Ext_Aliases *aliases = NULL;
364 HDB_EntryOrAlias eoa;
365 krb5_data akey, value;
369 memset(&eoa, 0, sizeof(eoa));
370 krb5_data_zero(&value);
373 ret = hdb_entry_get_aliases(&entry->entry, &aliases);
374 for (i = 0; ret == 0 && aliases && i < aliases->aliases.len; i++) {
375 ret = hdb_principal2key(context, &aliases->aliases.val[i], &akey);
377 ret = db->hdb__get(context, db, akey, &value);
379 ret = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL);
380 if (ret == 0 && eoa.element != choice_HDB_EntryOrAlias_entry &&
381 eoa.element != choice_HDB_EntryOrAlias_alias)
383 if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_entry)
384 /* New alias names an existing non-alias entry in the HDB */
385 ret = HDB_ERR_EXISTS;
386 if (ret == 0 && eoa.element == choice_HDB_EntryOrAlias_alias &&
387 !krb5_principal_compare(context, eoa.u.alias.principal,
388 entry->entry.principal))
389 /* New alias names an existing alias of a different entry */
390 ret = HDB_ERR_EXISTS;
391 if (ret == HDB_ERR_NOENTRY) /* from db->hdb__get */
392 /* New alias is a name that doesn't exist in the HDB */
395 free_HDB_EntryOrAlias(&eoa);
396 krb5_data_free(&value);
397 krb5_data_free(&akey);
403 * Many HDB entries don't have `etypes' setup. Historically we use the
404 * enctypes of the selected keyset as the entry's supported enctypes, but that
405 * is problematic. By doing this at store time and, if need be, at fetch time,
406 * we can make sure to stop deriving supported etypes from keys in the long
407 * run. We also need kadm5/kadmin support for etypes. We'll use this function
408 * there to derive etypes when using a kadm5_principal_ent_t that lacks the new
409 * TL data for etypes.
412 hdb_derive_etypes(krb5_context context, hdb_entry *e, HDB_Ext_KeySet *base_keys)
414 krb5_error_code ret = 0;
415 size_t i, k, netypes;
419 (ext = hdb_find_extension(e, choice_HDB_extension_data_hist_keys)))
420 base_keys = &ext->data.u.hist_keys;
422 netypes = e->keys.len;
423 if (netypes == 0 && base_keys) {
424 /* There's no way that base_keys->val[i].keys.len == 0, but hey */
425 for (i = 0; netypes == 0 && i < base_keys->len; i++)
426 netypes = base_keys->val[i].keys.len;
432 if (e->etypes != NULL) {
433 free(e->etypes->val);
438 if (e->etypes == NULL &&
439 (e->etypes = malloc(sizeof(e->etypes[0]))) == NULL)
440 ret = krb5_enomem(context);
446 (e->etypes->val = calloc(netypes, sizeof(e->etypes->val[0]))) == NULL)
447 ret = krb5_enomem(context);
453 e->etypes->len = netypes;
454 for (i = 0; i < e->keys.len && i < netypes; i++)
455 e->etypes->val[i] = e->keys.val[i].key.keytype;
458 for (k = 0; i == 0 && k < base_keys->len; k++) {
459 if (!base_keys->val[k].keys.len)
461 for (; i < base_keys->val[k].keys.len; i++)
462 e->etypes->val[i] = base_keys->val[k].keys.val[i].key.keytype;
468 _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
470 krb5_data key, value;
473 if (entry->entry.flags.do_not_store ||
474 entry->entry.flags.force_canonicalize)
475 return HDB_ERR_MISUSE;
476 /* check if new aliases already is used */
477 code = hdb_check_aliases(context, db, entry);
481 if ((flags & HDB_F_PRECHECK) && (flags & HDB_F_REPLACE))
484 if ((flags & HDB_F_PRECHECK)) {
485 code = hdb_principal2key(context, entry->entry.principal, &key);
488 code = db->hdb__get(context, db, key, &value);
489 krb5_data_free(&key);
491 krb5_data_free(&value);
492 if (code == HDB_ERR_NOENTRY)
494 return code ? code : HDB_ERR_EXISTS;
497 if ((entry->entry.etypes == NULL || entry->entry.etypes->len == 0) &&
498 (code = hdb_derive_etypes(context, &entry->entry, NULL)))
501 if (entry->entry.generation == NULL) {
503 entry->entry.generation = malloc(sizeof(*entry->entry.generation));
504 if(entry->entry.generation == NULL) {
505 krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
508 gettimeofday(&t, NULL);
509 entry->entry.generation->time = t.tv_sec;
510 entry->entry.generation->usec = t.tv_usec;
511 entry->entry.generation->gen = 0;
513 entry->entry.generation->gen++;
515 code = hdb_seal_keys(context, db, &entry->entry);
519 hdb_principal2key(context, entry->entry.principal, &key);
522 code = hdb_remove_aliases(context, db, &key);
524 krb5_data_free(&key);
527 hdb_entry2value(context, &entry->entry, &value);
528 code = db->hdb__put(context, db, flags & HDB_F_REPLACE, key, value);
529 krb5_data_free(&value);
530 krb5_data_free(&key);
534 code = hdb_add_aliases(context, db, flags, entry);
540 _hdb_remove(krb5_context context, HDB *db,
541 unsigned flags, krb5_const_principal principal)
543 krb5_data key, value;
544 HDB_EntryOrAlias eoa;
549 * We only allow deletion of entries by canonical name. To remove an
550 * alias use kadm5_modify_principal().
552 * We need to determine if this is an alias. We decode as a
553 * HDB_EntryOrAlias, which is expensive -- we could decode as a
554 * HDB_entry_alias instead and assume it's an entry if decoding fails...
557 hdb_principal2key(context, principal, &key);
558 code = db->hdb__get(context, db, key, &value);
560 code = decode_HDB_EntryOrAlias(value.data, value.length, &eoa, NULL);
561 krb5_data_free(&value);
564 is_alias = eoa.element == choice_HDB_EntryOrAlias_entry ? 0 : 1;
565 free_HDB_EntryOrAlias(&eoa);
568 if ((flags & HDB_F_PRECHECK)) {
569 if (code == 0 && is_alias)
570 krb5_set_error_message(context, code = HDB_ERR_NOENTRY,
571 "Cannot delete alias of principal");
572 krb5_data_free(&key);
576 code = hdb_remove_aliases(context, db, &key);
578 code = db->hdb__del(context, db, key);
579 krb5_data_free(&key);
583 /* PRF+(K_base, pad, keylen(etype)) */
584 static krb5_error_code
585 derive_Key1(krb5_context context,
592 krb5_crypto crypto = NULL;
599 ret = krb5_enctype_keysize(context, base->keytype, &len);
601 ret = krb5_crypto_init(context, base, 0, &crypto);
603 ret = krb5_crypto_prfplus(context, crypto, pad, len, &out);
605 krb5_crypto_destroy(context, crypto);
607 ret = krb5_random_to_key(context, etype, out.data, out.length, nk);
608 krb5_data_free(&out);
612 /* PRF+(PRF+(K_base, princ, keylen(etype)), kvno, keylen(etype)) */
613 /* XXX Make it PRF+(PRF+(K_base, princ, keylen(K_base.etype)), and lift it, kvno, keylen(etype)) */
614 static krb5_error_code
615 derive_Key(krb5_context context,
622 krb5_error_code ret = 0;
623 EncryptionKey intermediate;
629 nk->key.keyvalue.data = 0;
630 nk->key.keyvalue.length = 0;
632 intermediate.keytype = 0;
633 intermediate.keyvalue.data = 0;
634 intermediate.keyvalue.length = 0;
636 /* Derive intermediate key for the given principal */
637 /* XXX Lift to optimize? */
638 pad.data = (void *)(uintptr_t)princ;
639 pad.length = strlen(princ);
640 ret = derive_Key1(context, &pad, base, etype, &intermediate);
642 base = &intermediate;
643 } /* else `base' is already an intermediate key for the desired princ */
645 /* Derive final key for `kvno' from intermediate key */
648 pad.length = sizeof(kvno);
650 ret = derive_Key1(context, &pad, base, etype, &nk->key);
651 free_EncryptionKey(&intermediate);
656 * PRF+(PRF+(K_base, princ, keylen(etype)), kvno, keylen(etype)) for one
659 static krb5_error_code
660 derive_Keys(krb5_context context,
668 krb5_error_code ret = 0;
676 * The enctypes of the base keys is the list of enctypes to derive keys
677 * for. Still, we derive all keys from the first base key.
679 for (i = 0; ret == 0 && i < base->len; i++) {
680 if (etype != KRB5_ENCTYPE_NULL && etype != base->val[i].key.keytype)
682 ret = derive_Key(context, princ, kvno, &base->val[0].key,
683 base->val[i].key.keytype, &nk);
686 ret = add_Keys(dk, &nk);
689 * FIXME We need to finish kdc/kadm5/kadmin support for the `etypes' so
690 * we can reduce the number of keys in keytabs to just those in current
691 * use and only of *one* enctype.
693 * What we could do is derive *one* key and for the others output a
694 * one-byte key of the intended enctype (which will never work).
696 * We'll never need any keys but the first one...
705 /* Helper for derive_keys_for_kr() */
706 static krb5_error_code
707 derive_keyset(krb5_context context,
708 const Keys *base_keys,
712 KerberosTime set_time, /* "now" */
717 dks->set_time = malloc(sizeof(*dks->set_time));
718 if (dks->set_time == NULL)
719 return krb5_enomem(context);
720 *dks->set_time = set_time;
721 return derive_Keys(context, princ, kvno, etype, base_keys, &dks->keys);
724 /* Possibly derive and install in `h' a keyset identified by `t' */
725 static krb5_error_code
726 derive_keys_for_kr(krb5_context context,
728 HDB_Ext_KeySet *base_keys,
729 int is_current_keyset,
730 int rotation_period_offset,
733 krb5uint32 kvno_wanted,
735 struct KeyRotation *krp)
739 KerberosTime set_time, n;
743 if (rotation_period_offset < -1 || rotation_period_offset > 1)
744 return EINVAL; /* wat */
747 * Compute `kvno' and `set_time' given `t' and `krp'.
749 * There be signed 32-bit time_t dragons here.
751 * (t - krp->epoch < 0) is better than (krp->epoch < t), making us more
752 * tolerant of signed 32-bit time_t here near 2038. Of course, we have
753 * signed 32-bit time_t dragons elsewhere.
755 if (t - krp->epoch < 0)
756 return 0; /* This KR is not relevant yet */
757 n = (t - krp->epoch) / krp->period;
758 n += rotation_period_offset;
759 set_time = krp->epoch + krp->period * n;
760 kvno = krp->base_kvno + n;
764 * Do not waste cycles computing keys not wanted or needed.
765 * A past kvno is too old if its set_time + rotation period is in the past
766 * by more than half a rotation period, since then no service ticket
767 * encrypted with keys of that kvno can still be extant.
769 * A future kvno is not coming up soon enough if we're more than a quarter
770 * of the rotation period away from it.
772 * Recall: the assumption for virtually-keyed principals is that services
773 * fetch their future keys frequently enough that they'll never miss having
774 * the keys they need.
776 if (!is_current_keyset || rotation_period_offset != 0) {
777 if ((kvno_wanted && kvno != kvno_wanted) ||
778 t - (set_time + krp->period + (krp->period >> 1)) > 0 ||
779 (set_time - t > 0 && (set_time - t) > (krp->period >> 2)))
783 for (i = 0; i < base_keys->len; i++) {
784 if (base_keys->val[i].kvno == krp->base_key_kvno)
787 if (i == base_keys->len) {
788 /* Base key not found! */
789 if (kvno_wanted || is_current_keyset) {
790 krb5_set_error_message(context, ret = HDB_ERR_KVNO_NOT_FOUND,
791 "Base key version %u not found for %s",
792 krp->base_key_kvno, princ);
798 ret = derive_keyset(context, &base_keys->val[i].keys, princ, etype, kvno,
801 ret = hdb_install_keyset(context, &h->entry, is_current_keyset, &dks);
803 free_HDB_keyset(&dks);
807 /* Derive and install current keys, and possibly preceding or next keys */
808 static krb5_error_code
809 derive_keys_for_current_kr(krb5_context context,
811 HDB_Ext_KeySet *base_keys,
815 krb5uint32 kvno_wanted,
817 struct KeyRotation *krp,
818 KerberosTime future_epoch)
822 /* derive_keys_for_kr() for current kvno and install as the current keys */
823 ret = derive_keys_for_kr(context, h, base_keys, 1, 0, princ, etype,
824 kvno_wanted, t, krp);
825 if (!(flags & HDB_F_ALL_KVNOS))
832 * derive_keys_for_kr() for prev kvno if still needed -- it can only be
833 * needed if the prev kvno's start time is within this KR's epoch.
835 * Note that derive_keys_for_kr() can return without doing anything if this
836 * is isn't the current keyset. So these conditions need not be
837 * sufficiently narrow.
839 if (ret == 0 && t - krp->epoch >= krp->period)
840 ret = derive_keys_for_kr(context, h, base_keys, 0, -1, princ, etype,
841 kvno_wanted, t, krp);
843 * derive_keys_for_kr() for next kvno if near enough, but only if it
844 * doesn't start after the next KR's epoch.
847 t - krp->epoch >= 0 /* We know! Hint to the compiler */) {
848 KerberosTime next_kvno_start, n;
850 n = (t - krp->epoch) / krp->period;
851 next_kvno_start = krp->epoch + krp->period * (n + 1);
852 if (future_epoch - next_kvno_start <= 0)
856 ret = derive_keys_for_kr(context, h, base_keys, 0, 1, princ, etype,
857 kvno_wanted, t, krp);
862 * Derive and install all keysets in `h' that `princ' needs at time `now'.
864 * This mutates the entry `h' to
866 * a) not have base keys,
867 * b) have keys derived from the base keys according to
868 * c) the key rotation periods for the base principal (possibly the same
869 * principal if it's a concrete principal with virtual keys), and the
870 * requested time, enctype, and kvno (all of which are optional, with zero
871 * implying some default).
875 * - `flags' is the flags passed to `hdb_fetch_kvno()'
876 * - `princ' is the name of the principal we'll end up with in `h->entry'
877 * - `h_is_namespace' indicates whether `h' is for a namespace or a concrete
878 * principal (that might nonetheless have virtual/derived keys)
879 * - `t' is the time such that the derived keys are for kvnos needed at `t'
880 * - `etype' indicates what enctype to derive keys for (0 for all enctypes in
882 * - `kvno' requests a particular kvno, or all if zero
884 * The caller doesn't know if the principal needs key derivation -- we make
885 * that determination in this function.
887 * Note that this function is fully deterministic for any given set of
888 * arguments and HDB contents.
892 * - A keyset is a set of keys for a single kvno.
893 * - A keyset is relevant IFF:
894 * - it is the keyset for a time period identified by `t' in a
896 * - it is a keyset for a past time period for which there may be extant,
897 * not-yet-expired tickets that a service may need to decrypt
898 * - it is a keyset for an upcoming time period that a service will need to
899 * fetch before that time period becomes current, that way the service
900 * can have keytab entries for those keys in time for when the KDC starts
901 * encrypting service tickets to those keys
903 * This function derives the keyset(s) for the current KR first. The idea is
904 * to optimize the order of resulting keytabs so that the most likely keys to
905 * be used come first.
909 * - KR metadata is sane because sanity is checked for when storing HDB
911 * - KRs are sorted by epoch in descending order; KR #0's epoch is the most
913 * - KR periods are non-zero (we divide by period)
914 * - kvnos are numerically ordered and correspond to time periods
915 * - within each KR, the kvnos for larger times are larger than (or equal
916 * to) the kvnos of earlier times
917 * - at KR boundaries, the first kvno of the newer boundary is larger than
918 * the kvno of the last time period of the previous KR
919 * - the time `t' must fall into exactly one KR period
920 * - the time `t' must fall into exactly one period within a KR period
921 * - at most two kvnos will be relevant from the KR that `t' falls into
922 * (the current kvno for `t', and possibly either the preceding, or the
924 * - at most one kvno from non-current KRs will be derived: possibly one for a
925 * preceding KR, and possibly one from an upcoming KR
929 * - no KR extension (not a namespace principal, and no virtual keys)
930 * - 1, 2, or 3 KRs (see above)
931 * - the newest KR may have the `deleted' flag, meaning "does not exist after
934 * Note that the last time period in any older KR can be partial.
938 * .......|--+--+...+--|---+---+---+...+--|----+...
939 * T20 T10 T11 RT12 T1n T01
941 * | | | T22 T2n | | ^
943 * princ | | epoch of | epoch of
944 * did | | middle KR | newest epoch
946 * exist! | start of Note that T1n
947 * | second kvno is shown as shorter
948 * | in 1st epoch than preceding periods
955 * Tmn == the start of the Mth KR's Nth time period.
956 * (higher M -> older KR; lower M -> newer KR)
957 * (N is the reverse: lower N -> older time period in KR)
958 * T20 == start of oldest KR -- no keys before this time will be derived.
959 * T2n == last time period in oldest KR
960 * T10 == start of middle KR
961 * T1n == last time period in middle KR
962 * T00 == start of newest KR
963 * T0n == current time period in newest KR for wall clock time
965 static krb5_error_code
966 derive_keys(krb5_context context,
968 krb5_const_principal princ,
975 HDB_Ext_KeyRotation kr;
976 HDB_Ext_KeySet base_keys;
977 krb5_error_code ret = 0;
978 size_t current_kr, future_kr, past_kr, i;
982 if (!h_is_namespace && !h->entry.flags.virtual_keys)
984 h->entry.flags.virtual = 1;
985 if (h_is_namespace) {
986 /* Set the entry's principal name */
987 free_Principal(h->entry.principal);
988 ret = copy_Principal(princ, h->entry.principal);
994 const HDB_Ext_KeyRotation *ckr;
996 /* Installing keys invalidates `ckr', so we copy it */
997 ret = hdb_entry_get_key_rotation(context, &h->entry, &ckr);
1001 ret = copy_HDB_Ext_KeyRotation(ckr, &kr);
1004 /* Get the base keys from the entry, and remove them */
1008 ret = hdb_remove_base_keys(context, &h->entry, &base_keys);
1010 /* Make sure we have h->entry.etypes */
1011 if (ret == 0 && !h->entry.etypes)
1012 ret = hdb_derive_etypes(context, &h->entry, &base_keys);
1014 /* Keys not desired? Don't derive them! */
1015 if (ret || !(flags & HDB_F_DECRYPT)) {
1016 free_HDB_Ext_KeyRotation(&kr);
1017 free_HDB_Ext_KeySet(&base_keys);
1021 /* The principal name will be used in key derivation and error messages */
1022 if (ret == 0 && h_is_namespace)
1023 ret = krb5_unparse_name(context, princ, &p);
1025 /* Sanity check key rotations, determine current & last kr */
1026 if (ret == 0 && kr.len < 1)
1027 krb5_set_error_message(context, ret = HDB_ERR_NOENTRY,
1028 "no key rotation periods for %s", p);
1030 current_kr = future_kr = past_kr = kr.len;
1032 current_kr = future_kr = past_kr = 1;
1035 * Identify a current, next, and previous KRs if there are any.
1037 * There can be up to three KRs, ordered by epoch, descending, making up a
1040 * ...|---------|--------|------>
1043 * | | | Newest KR (kr.val[0])
1044 * | | Middle KR (kr.val[1])
1045 * | Oldest (last) KR (kr.val[2])
1047 * Before the begging of time for this namespace
1049 * We step through these from future towards past looking for the best
1050 * future, current, and past KRs. The best current KR is one that has its
1051 * epoch nearest to `t' but in the past of `t'.
1053 * We validate KRs before storing HDB entries with the KR extension, so we
1054 * can assume they are valid here. However, we do some validity checking,
1055 * and if they're not valid, we pick the best current KR and ignore the
1058 * In principle there cannot be two future KRs, but this function is
1059 * deterministic and takes a time value, so it should not enforce this just
1060 * so we can test. Enforcement of such rules should be done at store time.
1062 for (i = 0; ret == 0 && i < kr.len; i++) {
1063 /* Minimal validation: order and period */
1064 if (i && kr.val[i - 1].epoch - kr.val[i].epoch <= 0) {
1065 future_kr = past_kr = kr.len;
1068 if (!kr.val[i].period) {
1069 future_kr = past_kr = kr.len;
1073 if (t - kr.val[i].epoch >= 0) {
1075 * `t' is in the future of this KR's epoch, so it's a candidate for
1076 * either current or past KR.
1078 if (current_kr == kr.len)
1079 current_kr = i; /* First curr KR candidate; should be best */
1080 else if (kr.val[current_kr].epoch - kr.val[i].epoch < 0)
1081 current_kr = i; /* Invalid KRs, but better curr KR cand. */
1082 else if (valid && past_kr == kr.len)
1085 /* This KR is in the future of `t', a candidate for next KR */
1089 if (ret == 0 && current_kr == kr.len)
1090 /* No current KR -> too soon */
1091 krb5_set_error_message(context, ret = HDB_ERR_NOENTRY,
1092 "Too soon for virtual principal to exist");
1094 /* Check that the principal has not been marked deleted */
1095 if (ret == 0 && current_kr < kr.len && kr.val[current_kr].flags.deleted)
1096 krb5_set_error_message(context, ret = HDB_ERR_NOENTRY,
1097 "virtual principal %s does not exist "
1098 "because last key rotation period "
1099 "marks deletion", p);
1102 * Derive and set in `h' its current kvno and current keys.
1104 * This will set h->entry.kvno as well.
1106 * This may set up to TWO keysets for the current key rotation period:
1107 * - current keys (h->entry.keys and h->entry.kvno)
1108 * - possibly one future
1110 * possibly one past keyset in hist_keys for the current_kr
1112 if (ret == 0 && current_kr < kr.len)
1113 ret = derive_keys_for_current_kr(context, h, &base_keys, p, flags,
1114 etype, kvno, t, &kr.val[current_kr],
1115 current_kr ? kr.val[0].epoch : 0);
1118 * Derive and set in `h' its future keys for next KR if it is soon to be
1121 * We want to derive keys for the first kvno of the next (future) KR if
1122 * it's sufficiently close to `t', meaning within 1 period of the current
1123 * KR, but we want these keys to be available sooner, so 1.5 of the current
1126 if (ret == 0 && future_kr < kr.len && (flags & HDB_F_ALL_KVNOS))
1127 ret = derive_keys_for_kr(context, h, &base_keys, 0, 0, p, etype, kvno,
1128 kr.val[future_kr].epoch, &kr.val[future_kr]);
1131 * Derive and set in `h' its past keys for the previous KR if its last time
1132 * period could still have extant, unexpired service tickets encrypted in
1135 if (ret == 0 && past_kr < kr.len && (flags & HDB_F_ALL_KVNOS))
1136 ret = derive_keys_for_kr(context, h, &base_keys, 0, 0, p, etype, kvno,
1137 kr.val[current_kr].epoch - 1, &kr.val[past_kr]);
1140 * Impose a bound on h->entry.max_life so that [when the KDC is the caller]
1141 * the KDC won't issue tickets longer lived than this.
1143 if (ret == 0 && !h->entry.max_life &&
1144 (h->entry.max_life = malloc(sizeof(h->entry.max_life[0]))) == NULL)
1145 ret = krb5_enomem(context);
1146 if (ret == 0 && *h->entry.max_life > kr.val[current_kr].period >> 1)
1147 *h->entry.max_life = kr.val[current_kr].period >> 1;
1149 free_HDB_Ext_KeyRotation(&kr);
1150 free_HDB_Ext_KeySet(&base_keys);
1156 * In order for disparate keytab provisioning systems such as OSKT and our own
1157 * kadmin ext_keytab and httpkadmind's get-keys to coexist, we need to be able
1158 * to force keys set by the former to not become current keys until users of
1159 * the latter have had a chance to fetch those keys into their keytabs. To do
1160 * this we have to search the list of keys in the entry looking for the newest
1161 * keys older than `now - db->new_service_key_delay'.
1163 * The context is that OSKT's krb5_keytab is very happy to change keys in a way
1164 * that requires all members of a cluster to rekey together. If one also
1165 * wishes to have cluster members that opt out of this and just fetch current,
1166 * past, and future keys periodically, then the keys set by OSKT need to not
1167 * come into effect until all the opt-out members have had a chance to fetch
1170 * The assumption is that services will fetch new keys periodically, say, every
1171 * four hours. Then one can set `[hdb] new_service_key_delay = 8h' in the
1172 * configuration and new keys set by OSKT will not be used until 8h after they
1175 * Naturally, this applies only to concrete principals with concrete keys.
1177 static krb5_error_code
1178 fix_keys(krb5_context context,
1186 HDB_Ext_KeySet keys;
1192 * If we want a specific kvno, or if the caller doesn't want new keys
1193 * delayed, or if there's no new-key delay configured, or we're not
1194 * fetching for use as a service principal, then we're out.
1196 if (!(flags & HDB_F_DELAY_NEW_KEYS) || kvno || h->entry.flags.virtual ||
1197 h->entry.flags.virtual_keys || db->new_service_key_delay <= 0)
1200 /* No history -> current keyset is the only one and therefore the best */
1201 ext = hdb_find_extension(&h->entry, choice_HDB_extension_data_hist_keys);
1205 /* Assume the current keyset is the best to start with */
1206 (void) hdb_entry_get_pw_change_time(&h->entry, ¤t);
1207 if (current == 0 && h->entry.modified_by)
1208 current = h->entry.modified_by->time;
1210 current = h->entry.created_by.time;
1212 /* Current keyset starts out as best */
1214 kvno = h->entry.kvno;
1216 /* Look for a better keyset in the history */
1217 keys = ext->data.u.hist_keys;
1218 for (i = 0; i < keys.len; i++) {
1219 /* No set_time? Ignore. Too new? Ignore */
1220 if (!keys.val[i].set_time ||
1221 keys.val[i].set_time[0] + db->new_service_key_delay > now)
1225 * Ignore the keyset with kvno 1 when the entry has better kvnos
1226 * because kadmin's `ank -r' command immediately changes the keys.
1228 if (kvno > 1 && keys.val[i].kvno == 1)
1232 * This keyset's set_time older than the previous best? Ignore.
1233 * However, if the current best is the entry's current and that one
1234 * is too new, then don't ignore this one.
1236 if (keys.val[i].set_time[0] < best &&
1237 (best != current || current + db->new_service_key_delay < now))
1241 * If two good enough keysets have the same set_time, take the keyset
1242 * with the highest kvno.
1244 if (keys.val[i].set_time[0] == best && keys.val[i].kvno <= kvno)
1248 * This keyset is clearly more current than the previous best keyset
1249 * but still old enough to use for encrypting tickets with.
1251 best = keys.val[i].set_time[0];
1252 kvno = keys.val[i].kvno;
1254 return hdb_change_kvno(context, kvno, &h->entry);
1258 * Make a WELLKNOWN/HOSTBASED-NAMESPACE/${svc}/${hostname} or
1259 * WELLKNOWN/HOSTBASED-NAMESPACE/${svc}/${hostname}/${domainname} principal
1260 * object, with the service and hostname components take from `wanted', but if
1261 * the service name is not in the list `db->virtual_hostbased_princ_svcs[]'
1262 * then use "_" (wildcard) instead. This way we can have different attributes
1263 * for different services in the same namespaces.
1265 * For example, virtual hostbased service names for the "host" service might
1266 * have ok-as-delegate set, but ones for the "HTTP" service might not.
1268 static krb5_error_code
1269 make_namespace_princ(krb5_context context,
1271 krb5_const_principal wanted,
1272 krb5_principal *namespace)
1274 krb5_error_code ret = 0;
1275 const char *realm = krb5_principal_get_realm(context, wanted);
1276 const char *comp0 = krb5_principal_get_comp_string(context, wanted, 0);
1277 const char *comp1 = krb5_principal_get_comp_string(context, wanted, 1);
1278 const char *comp2 = krb5_principal_get_comp_string(context, wanted, 2);
1279 char * const *svcs = db->virtual_hostbased_princ_svcs;
1283 if (comp0 == NULL || comp1 == NULL)
1285 if (strcmp(comp0, "krbtgt") == 0)
1288 for (i = 0; svcs && svcs[i]; i++) {
1289 if (strcmp(comp0, svcs[i]) == 0) {
1294 if (!svcs || !svcs[i])
1297 /* First go around, need a namespace princ. Make it! */
1298 ret = krb5_build_principal(context, namespace, strlen(realm),
1300 HDB_WK_NAMESPACE, comp0, NULL);
1302 ret = krb5_principal_set_comp_string(context, *namespace, 3, comp1);
1303 if (ret == 0 && comp2)
1304 /* Support domain-based names */
1305 ret = krb5_principal_set_comp_string(context, *namespace, 4, comp2);
1306 /* Caller frees `*namespace' on error */
1310 /* Wrapper around db->hdb_fetch_kvno() that implements virtual princs/keys */
1311 static krb5_error_code
1312 fetch_it(krb5_context context,
1314 krb5_const_principal princ,
1321 krb5_const_principal tmpprinc = princ;
1322 krb5_principal baseprinc = NULL;
1323 krb5_error_code ret = 0;
1324 const char *comp0 = krb5_principal_get_comp_string(context, princ, 0);
1325 const char *comp1 = krb5_principal_get_comp_string(context, princ, 1);
1327 size_t mindots = db->virtual_hostbased_princ_ndots;
1328 size_t maxdots = db->virtual_hostbased_princ_maxdots;
1333 if (db->enable_virtual_hostbased_princs && comp1 &&
1334 strcmp("krbtgt", comp0) != 0 && strcmp("WELLKNOWN", comp0) != 0) {
1337 if ((host = strdup(comp1)) == NULL)
1338 return krb5_enomem(context);
1340 /* Strip out any :port */
1341 htmp = strchr(host, ':');
1343 if (strchr(htmp + 1, ':')) {
1344 /* Extra ':'s? No virtualization for you! */
1352 /* Count dots in `host' */
1353 for (hdots = 0, htmp = host; htmp && *htmp; htmp++)
1360 tmp = host ? host : comp1;
1361 for (ret = HDB_ERR_NOENTRY; ret == HDB_ERR_NOENTRY; tmpprinc = baseprinc) {
1362 krb5_error_code ret2 = 0;
1365 * We break out of this loop with ret == 0 only if we found the HDB
1366 * entry we were looking for or the HDB entry for a matching namespace.
1368 * Otherwise we break out with ret != 0, typically HDB_ERR_NOENTRY.
1370 * First time through we lookup the principal as given.
1372 * Next we lookup a namespace principal, stripping off hostname labels
1373 * from the left until we find one or get tired of looking or run out
1376 ret = db->hdb_fetch_kvno(context, db, tmpprinc, flags, kvno, ent);
1377 if (ret != HDB_ERR_NOENTRY || hdots == 0 || hdots < mindots || !tmp ||
1384 * - if we found a concrete principal, but it's been marked
1385 * as now-virtual, then we must keep going
1387 * But this will be coded in the future.
1389 * Maybe we can take attributes from the concrete principal...
1393 * The namespace's hostname will not have more labels than maxdots + 1.
1394 * Thus we truncate immediately down to maxdots + 1 if we haven't yet.
1396 * Example: with maxdots == 3,
1397 * foo.bar.baz.app.blah.example -> baz.app.blah.example
1399 while (maxdots && hdots > maxdots && tmp) {
1400 tmp = strchr(tmp, '.');
1401 /* tmp != NULL because maxdots > 0 */
1406 if (baseprinc == NULL)
1407 /* First go around, need a namespace princ. Make it! */
1408 ret2 = make_namespace_princ(context, db, tmpprinc, &baseprinc);
1409 /* Update the hostname component */
1411 ret2 = krb5_principal_set_comp_string(context, baseprinc, 3, tmp);
1416 /* Strip off left-most label for the next go-around */
1417 if ((tmp = strchr(tmp, '.')))
1420 } /* else we'll break out after the next db->hdb_fetch_kvno() call */
1424 * If unencrypted keys were requested, derive them. There may not be any
1425 * key derivation to do, but that's decided in derive_keys().
1428 ret = derive_keys(context, flags, princ, !!baseprinc, t, etype, kvno,
1431 ret = fix_keys(context, db, flags, t, kvno, ent);
1433 hdb_free_entry(context, ent);
1435 krb5_free_principal(context, baseprinc);
1441 * Fetch a principal's HDB entry, possibly generating virtual keys from base
1442 * keys according to strict key rotation schedules. If a time is given, other
1443 * than HDB I/O, this function is pure, thus usable for testing.
1445 * HDB writers should use `db->hdb_fetch_kvno()' to avoid materializing virtual
1448 * HDB readers should use this function rather than `db->hdb_fetch_kvno()'
1449 * unless they only want to see concrete principals and not bother generating
1452 * @param context Context
1454 * @param principal Principal name
1455 * @param flags Fetch flags
1456 * @param t For virtual keys, use this as the point in time (use zero to mean "now")
1457 * @param etype Key enctype (use KRB5_ENCTYPE_NULL to mean "preferred")
1458 * @param kvno Key version number (use zero to mean "current")
1459 * @param h Output HDB entry
1461 * @return Zero on success, an error code otherwise.
1464 hdb_fetch_kvno(krb5_context context,
1466 krb5_const_principal principal,
1473 krb5_error_code ret = HDB_ERR_NOENTRY;
1475 flags |= kvno ? HDB_F_KVNO_SPECIFIED : 0; /* XXX is this needed */
1477 krb5_timeofday(context, &t);
1478 ret = fetch_it(context, db, principal, flags, t, etype, kvno, h);
1479 if (ret == HDB_ERR_NOENTRY)
1480 krb5_set_error_message(context, ret, "no such entry found in hdb");
1483 * This check is to support aliases in HDB; the force_canonicalize
1484 * check is to allow HDB backends to support realm name canon
1485 * independently of principal aliases (used by Samba).
1487 if (ret == 0 && !(flags & HDB_F_ADMIN_DATA) &&
1488 !h->entry.flags.force_canonicalize &&
1489 !krb5_realm_compare(context, principal, h->entry.principal))
1490 ret = HDB_ERR_WRONG_REALM;
1495 length_hdb_keyset(HDB_keyset *data)
1497 return length_HDB_keyset(data);
1501 length_hdb_entry(HDB_entry *data)
1503 return length_HDB_entry(data);
1507 length_hdb_entry_alias(HDB_entry_alias *data)
1509 return length_HDB_entry_alias(data);
1513 free_hdb_keyset(HDB_keyset *data)
1515 free_HDB_keyset(data);
1519 free_hdb_entry(HDB_entry *data)
1521 free_HDB_entry(data);
1525 free_hdb_entry_alias(HDB_entry_alias *data)
1527 free_HDB_entry_alias(data);
1531 copy_hdb_keyset(const HDB_keyset *from, HDB_keyset *to)
1533 return copy_HDB_keyset(from, to);
1537 copy_hdb_entry(const HDB_entry *from, HDB_entry *to)
1539 return copy_HDB_entry(from, to);
1543 copy_hdb_entry_alias(const HDB_entry_alias *from, HDB_entry_alias *to)
1545 return copy_HDB_entry_alias(from, to);
1549 decode_hdb_keyset(const unsigned char *p,
1554 return decode_HDB_keyset(p, len, data, size);
1558 decode_hdb_entry(const unsigned char *p,
1563 return decode_HDB_entry(p, len, data, size);
1567 decode_hdb_entry_alias(const unsigned char *p,
1569 HDB_entry_alias *data,
1572 return decode_HDB_entry_alias(p, len, data, size);
1576 encode_hdb_keyset(unsigned char *p,
1578 const HDB_keyset *data,
1581 return encode_HDB_keyset(p, len, data, size);
1585 encode_hdb_entry(unsigned char *p,
1587 const HDB_entry *data,
1590 return encode_HDB_entry(p, len, data, size);
1594 encode_hdb_entry_alias(unsigned char *p,
1596 const HDB_entry_alias *data,
1599 return encode_HDB_entry_alias(p, len, data, size);