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
;
546 hdb_principal2key(context
, principal
, &key
);
548 if ((flags
& HDB_F_PRECHECK
)) {
550 * We don't check that we can delete the aliases because we
551 * assume that the DB is consistent. If we did check for alias
552 * consistency we'd also have to provide a way to fsck the DB,
553 * otherwise admins would have no way to recover -- papering
554 * over this here is less work, but we really ought to provide
557 code
= db
->hdb__get(context
, db
, key
, &value
);
558 krb5_data_free(&key
);
560 krb5_data_free(&value
);
566 code
= hdb_remove_aliases(context
, db
, &key
);
568 krb5_data_free(&key
);
571 code
= db
->hdb__del(context
, db
, key
);
572 krb5_data_free(&key
);
576 /* PRF+(K_base, pad, keylen(etype)) */
577 static krb5_error_code
578 derive_Key1(krb5_context context
,
585 krb5_crypto crypto
= NULL
;
592 ret
= krb5_enctype_keysize(context
, base
->keytype
, &len
);
594 ret
= krb5_crypto_init(context
, base
, 0, &crypto
);
596 ret
= krb5_crypto_prfplus(context
, crypto
, pad
, len
, &out
);
598 krb5_crypto_destroy(context
, crypto
);
600 ret
= krb5_random_to_key(context
, etype
, out
.data
, out
.length
, nk
);
601 krb5_data_free(&out
);
605 /* PRF+(PRF+(K_base, princ, keylen(etype)), kvno, keylen(etype)) */
606 /* XXX Make it PRF+(PRF+(K_base, princ, keylen(K_base.etype)), and lift it, kvno, keylen(etype)) */
607 static krb5_error_code
608 derive_Key(krb5_context context
,
615 krb5_error_code ret
= 0;
616 EncryptionKey intermediate
;
622 nk
->key
.keyvalue
.data
= 0;
623 nk
->key
.keyvalue
.length
= 0;
625 intermediate
.keytype
= 0;
626 intermediate
.keyvalue
.data
= 0;
627 intermediate
.keyvalue
.length
= 0;
629 /* Derive intermediate key for the given principal */
630 /* XXX Lift to optimize? */
631 pad
.data
= (void *)(uintptr_t)princ
;
632 pad
.length
= strlen(princ
);
633 ret
= derive_Key1(context
, &pad
, base
, etype
, &intermediate
);
635 base
= &intermediate
;
636 } /* else `base' is already an intermediate key for the desired princ */
638 /* Derive final key for `kvno' from intermediate key */
641 pad
.length
= sizeof(kvno
);
643 ret
= derive_Key1(context
, &pad
, base
, etype
, &nk
->key
);
644 free_EncryptionKey(&intermediate
);
649 * PRF+(PRF+(K_base, princ, keylen(etype)), kvno, keylen(etype)) for one
652 static krb5_error_code
653 derive_Keys(krb5_context context
,
661 krb5_error_code ret
= 0;
669 * The enctypes of the base keys is the list of enctypes to derive keys
670 * for. Still, we derive all keys from the first base key.
672 for (i
= 0; ret
== 0 && i
< base
->len
; i
++) {
673 if (etype
!= KRB5_ENCTYPE_NULL
&& etype
!= base
->val
[i
].key
.keytype
)
675 ret
= derive_Key(context
, princ
, kvno
, &base
->val
[0].key
,
676 base
->val
[i
].key
.keytype
, &nk
);
679 ret
= add_Keys(dk
, &nk
);
682 * FIXME We need to finish kdc/kadm5/kadmin support for the `etypes' so
683 * we can reduce the number of keys in keytabs to just those in current
684 * use and only of *one* enctype.
686 * What we could do is derive *one* key and for the others output a
687 * one-byte key of the intended enctype (which will never work).
689 * We'll never need any keys but the first one...
698 /* Helper for derive_keys_for_kr() */
699 static krb5_error_code
700 derive_keyset(krb5_context context
,
701 const Keys
*base_keys
,
705 KerberosTime set_time
, /* "now" */
710 dks
->set_time
= malloc(sizeof(dks
->set_time
));
711 if (dks
->set_time
== NULL
)
712 return krb5_enomem(context
);
713 *dks
->set_time
= set_time
;
714 return derive_Keys(context
, princ
, kvno
, etype
, base_keys
, &dks
->keys
);
717 /* Possibly derive and install in `h' a keyset identified by `t' */
718 static krb5_error_code
719 derive_keys_for_kr(krb5_context context
,
721 HDB_Ext_KeySet
*base_keys
,
722 int is_current_keyset
,
723 int rotation_period_offset
,
726 krb5uint32 kvno_wanted
,
728 struct KeyRotation
*krp
)
732 KerberosTime set_time
, n
;
736 if (rotation_period_offset
< -1 || rotation_period_offset
> 1)
737 return EINVAL
; /* wat */
740 * Compute `kvno' and `set_time' given `t' and `krp'.
742 * There be signed 32-bit time_t dragons here.
744 * (t - krp->epoch < 0) is better than (krp->epoch < t), making us more
745 * tolerant of signed 32-bit time_t here near 2038. Of course, we have
746 * signed 32-bit time_t dragons elsewhere.
748 if (t
- krp
->epoch
< 0)
749 return 0; /* This KR is not relevant yet */
750 n
= (t
- krp
->epoch
) / krp
->period
;
751 n
+= rotation_period_offset
;
752 set_time
= krp
->epoch
+ krp
->period
* n
;
753 kvno
= krp
->base_kvno
+ n
;
757 * Do not waste cycles computing keys not wanted or needed.
758 * A past kvno is too old if its set_time + rotation period is in the past
759 * by more than half a rotation period, since then no service ticket
760 * encrypted with keys of that kvno can still be extant.
762 * A future kvno is not coming up soon enough if we're more than a quarter
763 * of the rotation period away from it.
765 * Recall: the assumption for virtually-keyed principals is that services
766 * fetch their future keys frequently enough that they'll never miss having
767 * the keys they need.
769 if (!is_current_keyset
|| rotation_period_offset
!= 0) {
770 if ((kvno_wanted
&& kvno
!= kvno_wanted
) ||
771 t
- (set_time
+ krp
->period
+ (krp
->period
>> 1)) > 0 ||
772 (set_time
- t
> 0 && (set_time
- t
) > (krp
->period
>> 2)))
776 for (i
= 0; i
< base_keys
->len
; i
++) {
777 if (base_keys
->val
[i
].kvno
== krp
->base_key_kvno
)
780 if (i
== base_keys
->len
) {
781 /* Base key not found! */
782 if (kvno_wanted
|| is_current_keyset
) {
783 krb5_set_error_message(context
, ret
= HDB_ERR_KVNO_NOT_FOUND
,
784 "Base key version %u not found for %s",
785 krp
->base_key_kvno
, princ
);
791 ret
= derive_keyset(context
, &base_keys
->val
[i
].keys
, princ
, etype
, kvno
,
794 ret
= hdb_install_keyset(context
, &h
->entry
, is_current_keyset
, &dks
);
796 free_HDB_keyset(&dks
);
800 /* Derive and install current keys, and possibly preceding or next keys */
801 static krb5_error_code
802 derive_keys_for_current_kr(krb5_context context
,
804 HDB_Ext_KeySet
*base_keys
,
808 krb5uint32 kvno_wanted
,
810 struct KeyRotation
*krp
,
811 KerberosTime future_epoch
)
815 /* derive_keys_for_kr() for current kvno and install as the current keys */
816 ret
= derive_keys_for_kr(context
, h
, base_keys
, 1, 0, princ
, etype
,
817 kvno_wanted
, t
, krp
);
818 if (!(flags
& HDB_F_ALL_KVNOS
))
825 * derive_keys_for_kr() for prev kvno if still needed -- it can only be
826 * needed if the prev kvno's start time is within this KR's epoch.
828 * Note that derive_keys_for_kr() can return without doing anything if this
829 * is isn't the current keyset. So these conditions need not be
830 * sufficiently narrow.
832 if (ret
== 0 && t
- krp
->epoch
>= krp
->period
)
833 ret
= derive_keys_for_kr(context
, h
, base_keys
, 0, -1, princ
, etype
,
834 kvno_wanted
, t
, krp
);
836 * derive_keys_for_kr() for next kvno if near enough, but only if it
837 * doesn't start after the next KR's epoch.
840 t
- krp
->epoch
>= 0 /* We know! Hint to the compiler */) {
841 KerberosTime next_kvno_start
, n
;
843 n
= (t
- krp
->epoch
) / krp
->period
;
844 next_kvno_start
= krp
->epoch
+ krp
->period
* (n
+ 1);
845 if (future_epoch
- next_kvno_start
<= 0)
849 ret
= derive_keys_for_kr(context
, h
, base_keys
, 0, 1, princ
, etype
,
850 kvno_wanted
, t
, krp
);
855 * Derive and install all keysets in `h' that `princ' needs at time `now'.
857 * This mutates the entry `h' to
859 * a) not have base keys,
860 * b) have keys derived from the base keys according to
861 * c) the key rotation periods for the base principal (possibly the same
862 * principal if it's a concrete principal with virtual keys), and the
863 * requested time, enctype, and kvno (all of which are optional, with zero
864 * implying some default).
868 * - `flags' is the flags passed to `hdb_fetch_kvno()'
869 * - `princ' is the name of the principal we'll end up with in `h->entry'
870 * - `h_is_namespace' indicates whether `h' is for a namespace or a concrete
871 * principal (that might nonetheless have virtual/derived keys)
872 * - `t' is the time such that the derived keys are for kvnos needed at `t'
873 * - `etype' indicates what enctype to derive keys for (0 for all enctypes in
875 * - `kvno' requests a particular kvno, or all if zero
877 * The caller doesn't know if the principal needs key derivation -- we make
878 * that determination in this function.
880 * Note that this function is fully deterministic for any given set of
881 * arguments and HDB contents.
885 * - A keyset is a set of keys for a single kvno.
886 * - A keyset is relevant IFF:
887 * - it is the keyset for a time period identified by `t' in a
889 * - it is a keyset for a past time period for which there may be extant,
890 * not-yet-expired tickets that a service may need to decrypt
891 * - it is a keyset for an upcoming time period that a service will need to
892 * fetch before that time period becomes current, that way the service
893 * can have keytab entries for those keys in time for when the KDC starts
894 * encrypting service tickets to those keys
896 * This function derives the keyset(s) for the current KR first. The idea is
897 * to optimize the order of resulting keytabs so that the most likely keys to
898 * be used come first.
902 * - KR metadata is sane because sanity is checked for when storing HDB
904 * - KRs are sorted by epoch in descending order; KR #0's epoch is the most
906 * - KR periods are non-zero (we divide by period)
907 * - kvnos are numerically ordered and correspond to time periods
908 * - within each KR, the kvnos for larger times are larger than (or equal
909 * to) the kvnos of earlier times
910 * - at KR boundaries, the first kvno of the newer boundary is larger than
911 * the kvno of the last time period of the previous KR
912 * - the time `t' must fall into exactly one KR period
913 * - the time `t' must fall into exactly one period within a KR period
914 * - at most two kvnos will be relevant from the KR that `t' falls into
915 * (the current kvno for `t', and possibly either the preceding, or the
917 * - at most one kvno from non-current KRs will be derived: possibly one for a
918 * preceding KR, and possibly one from an upcoming KR
922 * - no KR extension (not a namespace principal, and no virtual keys)
923 * - 1, 2, or 3 KRs (see above)
924 * - the newest KR may have the `deleted' flag, meaning "does not exist after
927 * Note that the last time period in any older KR can be partial.
931 * .......|--+--+...+--|---+---+---+...+--|----+...
932 * T20 T10 T11 RT12 T1n T01
934 * | | | T22 T2n | | ^
936 * princ | | epoch of | epoch of
937 * did | | middle KR | newest epoch
939 * exist! | start of Note that T1n
940 * | second kvno is shown as shorter
941 * | in 1st epoch than preceding periods
948 * Tmn == the start of the Mth KR's Nth time period.
949 * (higher M -> older KR; lower M -> newer KR)
950 * (N is the reverse: lower N -> older time period in KR)
951 * T20 == start of oldest KR -- no keys before this time will be derived.
952 * T2n == last time period in oldest KR
953 * T10 == start of middle KR
954 * T1n == last time period in middle KR
955 * T00 == start of newest KR
956 * T0n == current time period in newest KR for wall clock time
958 static krb5_error_code
959 derive_keys(krb5_context context
,
961 krb5_const_principal princ
,
968 HDB_Ext_KeyRotation kr
;
969 HDB_Ext_KeySet base_keys
;
970 krb5_error_code ret
= 0;
971 size_t current_kr
, future_kr
, past_kr
, i
;
975 if (!h_is_namespace
&& !h
->entry
.flags
.virtual_keys
)
977 h
->entry
.flags
.virtual = 1;
978 if (h_is_namespace
) {
979 /* Set the entry's principal name */
980 free_Principal(h
->entry
.principal
);
981 ret
= copy_Principal(princ
, h
->entry
.principal
);
987 const HDB_Ext_KeyRotation
*ckr
;
989 /* Installing keys invalidates `ckr', so we copy it */
990 ret
= hdb_entry_get_key_rotation(context
, &h
->entry
, &ckr
);
992 ret
= copy_HDB_Ext_KeyRotation(ckr
, &kr
);
995 /* Get the base keys from the entry, and remove them */
999 ret
= hdb_remove_base_keys(context
, &h
->entry
, &base_keys
);
1001 /* Make sure we have h->entry.etypes */
1002 if (ret
== 0 && !h
->entry
.etypes
)
1003 ret
= hdb_derive_etypes(context
, &h
->entry
, &base_keys
);
1005 /* Keys not desired? Don't derive them! */
1006 if (ret
|| !(flags
& HDB_F_DECRYPT
)) {
1007 free_HDB_Ext_KeyRotation(&kr
);
1008 free_HDB_Ext_KeySet(&base_keys
);
1012 /* The principal name will be used in key derivation and error messages */
1013 if (ret
== 0 && h_is_namespace
)
1014 ret
= krb5_unparse_name(context
, princ
, &p
);
1016 /* Sanity check key rotations, determine current & last kr */
1017 if (ret
== 0 && kr
.len
< 1)
1018 krb5_set_error_message(context
, ret
= HDB_ERR_NOENTRY
,
1019 "no key rotation periods for %s", p
);
1021 current_kr
= future_kr
= past_kr
= kr
.len
;
1023 current_kr
= future_kr
= past_kr
= 1;
1026 * Identify a current, next, and previous KRs if there are any.
1028 * There can be up to three KRs, ordered by epoch, descending, making up a
1031 * ...|---------|--------|------>
1034 * | | | Newest KR (kr.val[0])
1035 * | | Middle KR (kr.val[1])
1036 * | Oldest (last) KR (kr.val[2])
1038 * Before the begging of time for this namespace
1040 * We step through these from future towards past looking for the best
1041 * future, current, and past KRs. The best current KR is one that has its
1042 * epoch nearest to `t' but in the past of `t'.
1044 * We validate KRs before storing HDB entries with the KR extension, so we
1045 * can assume they are valid here. However, we do some validity checking,
1046 * and if they're not valid, we pick the best current KR and ignore the
1049 * In principle there cannot be two future KRs, but this function is
1050 * deterministic and takes a time value, so it should not enforce this just
1051 * so we can test. Enforcement of such rules should be done at store time.
1053 for (i
= 0; ret
== 0 && i
< kr
.len
; i
++) {
1054 /* Minimal validation: order and period */
1055 if (i
&& kr
.val
[i
- 1].epoch
- kr
.val
[i
].epoch
<= 0) {
1056 future_kr
= past_kr
= kr
.len
;
1059 if (!kr
.val
[i
].period
) {
1060 future_kr
= past_kr
= kr
.len
;
1064 if (t
- kr
.val
[i
].epoch
>= 0) {
1066 * `t' is in the future of this KR's epoch, so it's a candidate for
1067 * either current or past KR.
1069 if (current_kr
== kr
.len
)
1070 current_kr
= i
; /* First curr KR candidate; should be best */
1071 else if (kr
.val
[current_kr
].epoch
- kr
.val
[i
].epoch
< 0)
1072 current_kr
= i
; /* Invalid KRs, but better curr KR cand. */
1073 else if (valid
&& past_kr
== kr
.len
)
1076 /* This KR is in the future of `t', a candidate for next KR */
1080 if (ret
== 0 && current_kr
== kr
.len
)
1081 /* No current KR -> too soon */
1082 krb5_set_error_message(context
, ret
= HDB_ERR_NOENTRY
,
1083 "Too soon for virtual principal to exist");
1085 /* Check that the principal has not been marked deleted */
1086 if (ret
== 0 && current_kr
< kr
.len
&& kr
.val
[current_kr
].flags
.deleted
)
1087 krb5_set_error_message(context
, ret
= HDB_ERR_NOENTRY
,
1088 "virtual principal %s does not exist "
1089 "because last key rotation period "
1090 "marks deletion", p
);
1093 * Derive and set in `h' its current kvno and current keys.
1095 * This will set h->entry.kvno as well.
1097 * This may set up to TWO keysets for the current key rotation period:
1098 * - current keys (h->entry.keys and h->entry.kvno)
1099 * - possibly one future
1101 * possibly one past keyset in hist_keys for the current_kr
1103 if (ret
== 0 && current_kr
< kr
.len
)
1104 ret
= derive_keys_for_current_kr(context
, h
, &base_keys
, p
, flags
,
1105 etype
, kvno
, t
, &kr
.val
[current_kr
],
1106 current_kr
? kr
.val
[0].epoch
: 0);
1109 * Derive and set in `h' its future keys for next KR if it is soon to be
1112 * We want to derive keys for the first kvno of the next (future) KR if
1113 * it's sufficiently close to `t', meaning within 1 period of the current
1114 * KR, but we want these keys to be available sooner, so 1.5 of the current
1117 if (ret
== 0 && future_kr
< kr
.len
&& (flags
& HDB_F_ALL_KVNOS
))
1118 ret
= derive_keys_for_kr(context
, h
, &base_keys
, 0, 0, p
, etype
, kvno
,
1119 kr
.val
[future_kr
].epoch
, &kr
.val
[future_kr
]);
1122 * Derive and set in `h' its past keys for the previous KR if its last time
1123 * period could still have extant, unexpired service tickets encrypted in
1126 if (ret
== 0 && past_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
[current_kr
].epoch
- 1, &kr
.val
[past_kr
]);
1131 * Impose a bound on h->entry.max_life so that [when the KDC is the caller]
1132 * the KDC won't issue tickets longer lived than this.
1134 if (ret
== 0 && !h
->entry
.max_life
&&
1135 (h
->entry
.max_life
= malloc(sizeof(h
->entry
.max_life
[0]))) == NULL
)
1136 ret
= krb5_enomem(context
);
1137 if (ret
== 0 && *h
->entry
.max_life
> kr
.val
[current_kr
].period
>> 1)
1138 *h
->entry
.max_life
= kr
.val
[current_kr
].period
>> 1;
1140 free_HDB_Ext_KeyRotation(&kr
);
1141 free_HDB_Ext_KeySet(&base_keys
);
1147 * In order for disparate keytab provisioning systems such as OSKT and our own
1148 * kadmin ext_keytab and httpkadmind's get-keys to coexist, we need to be able
1149 * to force keys set by the former to not become current keys until users of
1150 * the latter have had a chance to fetch those keys into their keytabs. To do
1151 * this we have to search the list of keys in the entry looking for the newest
1152 * keys older than `now - db->new_service_key_delay'.
1154 * The context is that OSKT's krb5_keytab is very happy to change keys in a way
1155 * that requires all members of a cluster to rekey together. If one also
1156 * wishes to have cluster members that opt out of this and just fetch current,
1157 * past, and future keys periodically, then the keys set by OSKT need to not
1158 * come into effect until all the opt-out members have had a chance to fetch
1161 * The assumption is that services will fetch new keys periodically, say, every
1162 * four hours. Then one can set `[hdb] new_service_key_delay = 8h' in the
1163 * configuration and new keys set by OSKT will not be used until 8h after they
1166 * Naturally, this applies only to concrete principals with concrete keys.
1168 static krb5_error_code
1169 fix_keys(krb5_context context
,
1177 HDB_Ext_KeySet keys
;
1183 * If we want a specific kvno, or if the caller doesn't want new keys
1184 * delayed, or if there's no new-key delay configured, or we're not
1185 * fetching for use as a service principal, then we're out.
1187 if (!(flags
& HDB_F_DELAY_NEW_KEYS
) || kvno
|| h
->entry
.flags
.virtual ||
1188 h
->entry
.flags
.virtual_keys
|| db
->new_service_key_delay
<= 0)
1191 /* No history -> current keyset is the only one and therefore the best */
1192 ext
= hdb_find_extension(&h
->entry
, choice_HDB_extension_data_hist_keys
);
1196 /* Assume the current keyset is the best to start with */
1197 (void) hdb_entry_get_pw_change_time(&h
->entry
, ¤t
);
1198 if (current
== 0 && h
->entry
.modified_by
)
1199 current
= h
->entry
.modified_by
->time
;
1201 current
= h
->entry
.created_by
.time
;
1203 /* Current keyset starts out as best */
1205 kvno
= h
->entry
.kvno
;
1207 /* Look for a better keyset in the history */
1208 keys
= ext
->data
.u
.hist_keys
;
1209 for (i
= 0; i
< keys
.len
; i
++) {
1210 /* No set_time? Ignore. Too new? Ignore */
1211 if (!keys
.val
[i
].set_time
||
1212 keys
.val
[i
].set_time
[0] + db
->new_service_key_delay
> now
)
1216 * Ignore the keyset with kvno 1 when the entry has better kvnos
1217 * because kadmin's `ank -r' command immediately changes the keys.
1219 if (kvno
> 1 && keys
.val
[i
].kvno
== 1)
1223 * This keyset's set_time older than the previous best? Ignore.
1224 * However, if the current best is the entry's current and that one
1225 * is too new, then don't ignore this one.
1227 if (keys
.val
[i
].set_time
[0] < best
&&
1228 (best
!= current
|| current
+ db
->new_service_key_delay
< now
))
1232 * If two good enough keysets have the same set_time, take the keyset
1233 * with the highest kvno.
1235 if (keys
.val
[i
].set_time
[0] == best
&& keys
.val
[i
].kvno
<= kvno
)
1239 * This keyset is clearly more current than the previous best keyset
1240 * but still old enough to use for encrypting tickets with.
1242 best
= keys
.val
[i
].set_time
[0];
1243 kvno
= keys
.val
[i
].kvno
;
1245 return hdb_change_kvno(context
, kvno
, &h
->entry
);
1249 * Make a WELLKNOWN/HOSTBASED-NAMESPACE/${svc}/${hostname} or
1250 * WELLKNOWN/HOSTBASED-NAMESPACE/${svc}/${hostname}/${domainname} principal
1251 * object, with the service and hostname components take from `wanted', but if
1252 * the service name is not in the list `db->virtual_hostbased_princ_svcs[]'
1253 * then use "_" (wildcard) instead. This way we can have different attributes
1254 * for different services in the same namespaces.
1256 * For example, virtual hostbased service names for the "host" service might
1257 * have ok-as-delegate set, but ones for the "HTTP" service might not.
1259 static krb5_error_code
1260 make_namespace_princ(krb5_context context
,
1262 krb5_const_principal wanted
,
1263 krb5_principal
*namespace)
1265 krb5_error_code ret
= 0;
1266 const char *realm
= krb5_principal_get_realm(context
, wanted
);
1267 const char *comp0
= krb5_principal_get_comp_string(context
, wanted
, 0);
1268 const char *comp1
= krb5_principal_get_comp_string(context
, wanted
, 1);
1269 const char *comp2
= krb5_principal_get_comp_string(context
, wanted
, 2);
1270 char * const *svcs
= db
->virtual_hostbased_princ_svcs
;
1274 if (comp0
== NULL
|| comp1
== NULL
)
1276 if (strcmp(comp0
, "krbtgt") == 0)
1279 for (i
= 0; svcs
&& svcs
[i
]; i
++) {
1280 if (strcmp(comp0
, svcs
[i
]) == 0) {
1285 if (!svcs
|| !svcs
[i
])
1288 /* First go around, need a namespace princ. Make it! */
1289 ret
= krb5_build_principal(context
, namespace, strlen(realm
),
1291 HDB_WK_NAMESPACE
, comp0
, NULL
);
1293 ret
= krb5_principal_set_comp_string(context
, *namespace, 3, comp1
);
1294 if (ret
== 0 && comp2
)
1295 /* Support domain-based names */
1296 ret
= krb5_principal_set_comp_string(context
, *namespace, 4, comp2
);
1297 /* Caller frees `*namespace' on error */
1301 /* Wrapper around db->hdb_fetch_kvno() that implements virtual princs/keys */
1302 static krb5_error_code
1303 fetch_it(krb5_context context
,
1305 krb5_const_principal princ
,
1312 krb5_const_principal tmpprinc
= princ
;
1313 krb5_principal baseprinc
= NULL
;
1314 krb5_error_code ret
= 0;
1315 const char *comp0
= krb5_principal_get_comp_string(context
, princ
, 0);
1316 const char *comp1
= krb5_principal_get_comp_string(context
, princ
, 1);
1318 size_t mindots
= db
->virtual_hostbased_princ_ndots
;
1319 size_t maxdots
= db
->virtual_hostbased_princ_maxdots
;
1324 if (db
->enable_virtual_hostbased_princs
&& comp1
&&
1325 strcmp("krbtgt", comp0
) != 0 && strcmp("WELLKNOWN", comp0
) != 0) {
1328 if ((host
= strdup(comp1
)) == NULL
)
1329 return krb5_enomem(context
);
1331 /* Strip out any :port */
1332 htmp
= strchr(host
, ':');
1334 if (strchr(htmp
+ 1, ':')) {
1335 /* Extra ':'s? No virtualization for you! */
1343 /* Count dots in `host' */
1344 for (hdots
= 0, htmp
= host
; htmp
&& *htmp
; htmp
++)
1351 tmp
= host
? host
: comp1
;
1352 for (ret
= HDB_ERR_NOENTRY
; ret
== HDB_ERR_NOENTRY
; tmpprinc
= baseprinc
) {
1353 krb5_error_code ret2
= 0;
1356 * We break out of this loop with ret == 0 only if we found the HDB
1357 * entry we were looking for or the HDB entry for a matching namespace.
1359 * Otherwise we break out with ret != 0, typically HDB_ERR_NOENTRY.
1361 * First time through we lookup the principal as given.
1363 * Next we lookup a namespace principal, stripping off hostname labels
1364 * from the left until we find one or get tired of looking or run out
1367 ret
= db
->hdb_fetch_kvno(context
, db
, tmpprinc
, flags
, kvno
, ent
);
1368 if (ret
!= HDB_ERR_NOENTRY
|| hdots
== 0 || hdots
< mindots
|| !tmp
||
1375 * - if we found a concrete principal, but it's been marked
1376 * as now-virtual, then we must keep going
1378 * But this will be coded in the future.
1380 * Maybe we can take attributes from the concrete principal...
1384 * The namespace's hostname will not have more labels than maxdots + 1.
1385 * Thus we truncate immediately down to maxdots + 1 if we haven't yet.
1387 * Example: with maxdots == 3,
1388 * foo.bar.baz.app.blah.example -> baz.app.blah.example
1390 while (maxdots
&& hdots
> maxdots
&& tmp
) {
1391 tmp
= strchr(tmp
, '.');
1392 /* tmp != NULL because maxdots > 0 */
1397 if (baseprinc
== NULL
)
1398 /* First go around, need a namespace princ. Make it! */
1399 ret2
= make_namespace_princ(context
, db
, tmpprinc
, &baseprinc
);
1400 /* Update the hostname component */
1402 ret2
= krb5_principal_set_comp_string(context
, baseprinc
, 3, tmp
);
1407 /* Strip off left-most label for the next go-around */
1408 if ((tmp
= strchr(tmp
, '.')))
1411 } /* else we'll break out after the next db->hdb_fetch_kvno() call */
1415 * If unencrypted keys were requested, derive them. There may not be any
1416 * key derivation to do, but that's decided in derive_keys().
1419 ret
= derive_keys(context
, flags
, princ
, !!baseprinc
, t
, etype
, kvno
,
1422 ret
= fix_keys(context
, db
, flags
, t
, kvno
, ent
);
1424 hdb_free_entry(context
, ent
);
1426 krb5_free_principal(context
, baseprinc
);
1432 * Fetch a principal's HDB entry, possibly generating virtual keys from base
1433 * keys according to strict key rotation schedules. If a time is given, other
1434 * than HDB I/O, this function is pure, thus usable for testing.
1436 * HDB writers should use `db->hdb_fetch_kvno()' to avoid materializing virtual
1439 * HDB readers should use this function rather than `db->hdb_fetch_kvno()'
1440 * unless they only want to see concrete principals and not bother generating
1443 * @param context Context
1445 * @param principal Principal name
1446 * @param flags Fetch flags
1447 * @param t For virtual keys, use this as the point in time (use zero to mean "now")
1448 * @param etype Key enctype (use KRB5_ENCTYPE_NULL to mean "preferred")
1449 * @param kvno Key version number (use zero to mean "current")
1450 * @param h Output HDB entry
1452 * @return Zero on success, an error code otherwise.
1455 hdb_fetch_kvno(krb5_context context
,
1457 krb5_const_principal principal
,
1464 krb5_error_code ret
= HDB_ERR_NOENTRY
;
1466 flags
|= kvno
? HDB_F_KVNO_SPECIFIED
: 0; /* XXX is this needed */
1468 krb5_timeofday(context
, &t
);
1469 ret
= fetch_it(context
, db
, principal
, flags
, t
, etype
, kvno
, h
);
1470 if (ret
== HDB_ERR_NOENTRY
)
1471 krb5_set_error_message(context
, ret
, "no such entry found in hdb");
1476 length_hdb_keyset(HDB_keyset
*data
)
1478 return length_HDB_keyset(data
);
1482 length_hdb_entry(HDB_entry
*data
)
1484 return length_HDB_entry(data
);
1488 length_hdb_entry_alias(HDB_entry_alias
*data
)
1490 return length_HDB_entry_alias(data
);
1494 free_hdb_keyset(HDB_keyset
*data
)
1496 free_HDB_keyset(data
);
1500 free_hdb_entry(HDB_entry
*data
)
1502 free_HDB_entry(data
);
1506 free_hdb_entry_alias(HDB_entry_alias
*data
)
1508 free_HDB_entry_alias(data
);
1512 copy_hdb_keyset(const HDB_keyset
*from
, HDB_keyset
*to
)
1514 return copy_HDB_keyset(from
, to
);
1518 copy_hdb_entry(const HDB_entry
*from
, HDB_entry
*to
)
1520 return copy_HDB_entry(from
, to
);
1524 copy_hdb_entry_alias(const HDB_entry_alias
*from
, HDB_entry_alias
*to
)
1526 return copy_HDB_entry_alias(from
, to
);
1530 decode_hdb_keyset(const unsigned char *p
,
1535 return decode_HDB_keyset(p
, len
, data
, size
);
1539 decode_hdb_entry(const unsigned char *p
,
1544 return decode_HDB_entry(p
, len
, data
, size
);
1548 decode_hdb_entry_alias(const unsigned char *p
,
1550 HDB_entry_alias
*data
,
1553 return decode_HDB_entry_alias(p
, len
, data
, size
);
1557 encode_hdb_keyset(unsigned char *p
,
1559 const HDB_keyset
*data
,
1562 return encode_HDB_keyset(p
, len
, data
, size
);
1566 encode_hdb_entry(unsigned char *p
,
1568 const HDB_entry
*data
,
1571 return encode_HDB_entry(p
, len
, data
, size
);
1575 encode_hdb_entry_alias(unsigned char *p
,
1577 const HDB_entry_alias
*data
,
1580 return encode_HDB_entry_alias(p
, len
, data
, size
);