Skip Menu |
 

From: "Arlene Berry" <arlene.berry@certifiedsecuritysolutions.com>
To: <krb5-bugs@mit.edu>
Subject: bug in 1.3.1 krb5_get_init_creds_keytab()
Date: Fri, 16 Jan 2004 16:26:40 -0800
Download (untitled) / with headers
text/plain 3.4KiB
I've found a bug in krb5 1.3.1 in function krb5_get_init_creds_keytab().
I'm using MS Active Directory for my KDC. I created a service principal
account and I created a key table entry for it with a DEC-CBC-MD5 key type.
The AD account has a userAccountControl atribute which contains bit flags.
When the UF_USE_DES_KEY_ONLY bit is set, krb5_get_init_creds_keytab()
successfully gets a TGT using the key table entry. When the bit is not set,
the function returns the error "Key table entry not found". When I do the
same thing with 1.2.5 or 1.2.8, krb5_get_init_creds_keytab() gets a TGT no
matter how that bit is set. The reason it's an issue is that if an AD
account is created with the bit set, a key table entry is created, and then
later someone changes the UF_USE_DES_KEY_ONLY bit, the key table entry can
no longer be used to get a TGT even though it's still good.

I've done a lot of debugging. The basic sequence of events is that a
request is built without preauth and sent to the KDC, a reply requesting
preauth is received, and an attempt is made to satisfy the request for
preauth. Krb5_get_init_creds_keytab() calls krb5_get_init_creds() which
calls krb5_do_preauth(). What happens in krb5_do_preauth() is that it looks
at a list of etypes returned by the KDC, chooses one, and then tries to find
a key table entry with a similar key type. The code which chooses the etype
looks like this:

for (etype_found = 0, valid_etype_found = 0, k = 0;
!etype_found && k < request->nktypes; k++) {
for (l = 0; etype_info[l]; l++) {
if (etype_info[l]->etype == request->ktype[k]) {
etype_found++;
break;
}

The etype_info array comes from the KDC's reply. Request->ktype is provided
by krb5_get_init_creds(). Krb5_get_init_creds() creates request and sets
request->ktype to the results of krb5_get_default_in_tkt_ktypes() if not
overridden by the options parameter which is passed from the application to
krb5_get_init_creds() by krb5_get_init_creds_keytab().

With AD the etype_info[]->etype list of etypes is 3, 1 when
UF_USE_DES_KEY_ONLY is set and the list is 23, 3, 1 when UF_USE_DES_KEY_ONLY
is not set. The list provided by krb5_get_default_in_tkt_ktypes() is 18,
16, 23, 1, 3, 2. The type chosen is 1 when AD returns 3, 1 and it's 23 when
AD returns 23, 3, 1. The problem is nothing looked in the key table to see
what's actually available. The key table lookup happens after the type is
chosen. Since what's in the key table is 3 which is similar to 1, the key
table entry is used when UF_USE_DES_KEY_ONLY is set, and it's rejected when
UF_USE_DES_KEY_ONLY is not set.

The 1.2.8 preauth code simply uses the first entry in the etype_info array
which is always 3 which must be because 1.2.8 doesn't support 23 and doesn't
include it in its initial request.

The real problem is that the default ktypes list that krb5_get_init_creds()
uses in the initial request is not suitable when krb5_get_init_creds() is
called by krb5_get_init_creds_keytab(). It seems to me that the solution is
for krb5_get_init_creds_keytab() to examine the key table and set an etype
list in the options parameter before passing it through to
krb5_get_init_creds() if a list is not provided by the calling application.
If this change were made to krb5_get_init_creds_keytab(), it should solve
the problem as I simulated it by temporarily modifying the application to
set the options etype list to 3, 1 and got a TGT.

Arlene Berry
From: ghudson@mit.edu
Subject: SVN Commit
Use etypes from keytab in krb5_gic_keytab

When getting initial credentials with a keytab, filter the list of
request enctypes based on the keys in the keytab.

Based on a patch from Stef Walter.

https://github.com/krb5/krb5/commit/8230c4b7b7323cdef2a6c877deb710a15380f40f
Commit By: ghudson
Revision: 25818
Changed Files:
U trunk/src/include/k5-trace.h
U trunk/src/lib/krb5/krb/gic_keytab.c
U trunk/src/tests/t_keytab.py
This change had the unintended consequence of restricting the ticket
session key to the enctypes in the keytab. The change was amended by
#7190 to include all of the default_tkt_enctypes list in the request, but
sorted with the keytab's enctypes appearing first. That way the session
key enctype is not constrained, but the KDC is very likely to use a reply
key which exists in the keytab.

Nico has also suggested doing encrypted timestamp preauth with one of the
keytab keys, and having the KDC use the encrypted timestamp key as the
reply key. These are probably good ideas but the former may have some
edge cases given the current state of the client preauth code. See also:

http://mailman.mit.edu/pipermail/krbdev/2012-July/010998.html