Problems with krb5_get_in_tkt()
bjaspan at MIT.EDU
Fri Nov 21 11:06:45 EST 2003
I have discovered an oddity or a bug in krb5_get_in_tkt(). The
behavior changed from 1.2.8 to 1.3.1, but I think both are wrong.
Suppose a program calls krb5_get_in_tkt_with_skey() with a
krb5_keyblock whose enctype is DES_CBC_CRC but with a ktypes parameter
of NULL. This call forwards to krb5_get_in_tkt() with keyproc as
skey_keyproc and keyseed as key.
krb5_get_in_tkt() sets up krb5_kdc_req request structure. In 1.3.1,
request.ktype is set to the HARD-CODED list get_in_tkt_enctypes which
includes five particular enctypes, starting with 3DES_CBC_SHA1. In
1.2.8, request.ktype is filled by krb5_get_default_in_tkt_ktypes()
which reads the default_tkt_enctypes variable from krb5.conf. Then,
*if* we had passed in a list of enctypes in the ktypes parameter,
request.ktype would be reordered to hold our requested ktypes first,
and requested ktypes not in request.ktype would be discarded. But we
passed NULL for ktypes, so we get the default.
krb5_get_in_tkt() next enters the send_to_kdc loop. It calls
krb5_obtain_padata(), passing it skey_keyproc, our key, and the
request data structure with request.ktypes filled in. In
krb5_obtain_padata(), the local enctype variable is set to
request->ktype, which in 1.3.1 is 3DES_CBC_SHA1. Finally,
skey_keyproc is called with enctype 3DES_CBC_SHA1 and our DES_CBC_CRC
key. skey_keyproc makes a copy of its input key, notices that the
copy's enctype is not equal to the input enctype, and fails with
As far as I can tell, this means that krb5_get_in_tkt_with_skey() will
*always* fail if passed a key whose enctype is not (in 1.3.1)
3DES_CBC_SHA1 or (in 1.2.8) the first type listed in
default_tkt_enctypes unless it is also passed an enctypes array whose
*first* entry is the enctype of the actual key passed in.
I see several problems or questions here:
- How is krb5_get_in_tkt_with_skey() supposed to behave? The api spec
seems out of date and does not address this topic. It seems pretty
intuitive to me that it ought to work if the key's enctype is either
listed anywhere in krb5.conf's default_tkt_enctypes or listed anywhere
in the passed-in ktypes array. Otherwise, why bother having a default
array instead of a single default value, and why bother accepting an
input array instead of a single input value?
- Why does 1.3.1 use a hard-coded array of enctypes instead of the
default_tkt_enctypes variable? With 1.2.8, you could at least make
applications that call _with_skey with a NULL ktypes work with
DES_CBC_CRC keys by setting default_tkt_enctypes = des-cbc-crc,
because then it would be the first enctype tried. With 1.3.1, that
doesn't work, so the applications must be fixed and recompiled.
- Why does krb5_obtain_padata() bail if the key_proc fails on
request->ktype? It has an array of enctypes; shouldn't it try them
all before giving up?
- It seems like 1.2.8's default_tkt_enctypes or 1.3.1's hard-coded
enctypes list is being used where permitted_enctypes ought to be used
instead. Passed-in enctypes not listed in the default list are
discarded; that means the enctype is "not permitted," not that it is
"not in the default list."
- skey_keyproc copies its input keyblock and then checks whether the
copy's enctype matches the requested enctype; if not, it frees the
copy and fails. I'm unaware of a reason for it not to check the
enctype match first and not copy the key at all if it does not match.
More information about the krbdev