Skip Menu |
 

Subject: still not ready for kvnos over 255
kadmin's ktadd, klist -k, and ktutil wrap the displayed kvno at 8 bits. kadmin's getprinc shows
the correct value.

For extra fun, kadmin ktremove old picks the wrong entry of the "current kvno" to remove, at
least sometimes.
[kaduk@MIT.EDU - Fri Jan 4 20:30:46 2013]:

Show quoted text
> kadmin's ktadd, klist -k, and ktutil wrap the displayed kvno at 8
> bits. kadmin's getprinc shows
> the correct value.
>
> For extra fun, kadmin ktremove old picks the wrong entry of the
> "current kvno" to remove, at
> least sometimes.

I guess at least some of this is because the on-disk format stores the kvno in a krb5_octet.
From: Ian Crowther <i.crowther@gmail.com>
Date: Sat, 5 Jan 2013 01:09:53 +0000
Subject: klist/ktutil wrapping kvno field
To: krb5-bugs@mit.edu
Download (untitled) / with headers
text/plain 2.2KiB
When ktadmin is used to put a principal with kvno 320 into a file,
klist and kutil both show that the file has a kvno of 64.

Kaduk states "It is almost certain that klist is assuming the kvno is
an 8-bit field, so 320 wraps around to 64. (In krb4, the kvno field
actually was 8 bits.)" which would be consistent with both getprinc
and klist's kvno incrementing 'independently'

Sample log:

kadmin.local: getprinc cfengine-policyhost/admin@EXAMPLE.COM
Principal: cfengine-policyhost/admin@EXAMPLE.COM
Expiration date: [never]
Last password change: Sat Jan 05 00:46:15 GMT 2013
Password expiration date: [none]
Maximum ticket life: 0 days 10:00:00
Maximum renewable life: 7 days 00:00:00
Last modified: Sat Jan 05 00:46:15 GMT 2013 (root/admin@EXAMPLE.COM)
Last successful authentication: Sat Jan 05 00:16:01 GMT 2013
Last failed authentication: Sat Jan 05 00:14:55 GMT 2013
Failed password attempts: 0
Number of keys: 4
Key: vno 319, AES-256 CTS mode with 96-bit SHA-1 HMAC, no salt
Key: vno 319, ArcFour with HMAC/md5, no salt
Key: vno 319, Triple DES cbc mode with HMAC/sha1, no salt
Key: vno 319, DES cbc mode with CRC-32, no salt
MKey: vno 1
Attributes: REQUIRES_PRE_AUTH
Policy: service


kadmin.local: ktadd -k /tmp/newfile cfengine-policyhost/admin
Entry for principal cfengine-policyhost/admin with kvno 320,
encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to
keytab WRFILE:/tmp/newfile.
Entry for principal cfengine-policyhost/admin with kvno 320,
encryption type ArcFour with HMAC/md5 added to keytab
WRFILE:/tmp/newfile.
Entry for principal cfengine-policyhost/admin with kvno 320,
encryption type Triple DES cbc mode with HMAC/sha1 added to keytab
WRFILE:/tmp/newfile.
Entry for principal cfengine-policyhost/admin with kvno 320,
encryption type DES cbc mode with CRC-32 added to keytab
WRFILE:/tmp/newfile.
kadmin.local:


0 root@caffeine:/var/cfengine/inputs[2] klist -k /tmp/newfile
Keytab name: WRFILE:/tmp/newfile
KVNO Principal
---- --------------------------------------------------------------------------
64 cfengine-policyhost/admin@EXAMPLE.COM
64 cfengine-policyhost/admin@EXAMPLE.COM
64 cfengine-policyhost/admin@EXAMPLE.COM
64 cfengine-policyhost/admin@EXAMPLE.COM
0 root@caffeine:/var/cfengine/inputs[2]
My understanding is that the krb5 keytab format was based loosely on
Kerberos 4's srvtab format, and in an error of omission, the kvno field
was left at 8 bits.

We have several heuristics to work around this mistake.
krb5_ktfile_get_entry() tries to detect wraparound when looking up the
highest kvno in the keytab, for instance.

There is a path away from this mistake if we look at Heimdal and Shishi.
They both support a 32-bit kvno value located after the existing keytab
fields, overriding the 8-bit value. This is documented at:

http://www.gnu.org/software/shishi/manual/html_node/The-Keytab-Binary-
File-Format.html
Download (untitled) / with headers
text/plain 1.2KiB
It appears that the kadmin protocol also only supports kvnos up to
255. xdr_krb5_kvno() truncates the kvno to 8 bits and marshals it
using xdr_u_char().

It may be possible to fix this in a backwards-compatible fashion,
because xdr_u_char() still uses 32 bits to marshal the value and
doesn't do any bounds checking on decode. But of course even if we
do that, keytab code can't assume it's not interacting with an old
kadmind which truncates kvnos.

There are pivot heuristics in krb5_ktfile_get_entry() to make key
rotations continue to work across the 8-bit boundary. The heuristics
are:

* When getting the highest kvno, if we see any entries with kvno >
240, we start comparing kvno values with ((kvno + 128) % 256) so that
values from 1-127 are assumed to refer to 256+N instead.

* When getting a specific kvno, we compare only the low eight bits of
the kvno.

My original plan had been to get rid of these heuristics, believing
the kvno problem to be local to the FILE keytab code. In light of
the kadmin issue, we can't safely do that. At the same time, those
heuristics can yield the wrong result. We may need to make the
heuristics more clever--for example, by disabling them if we see any
kvno values > 255.
I created a project page describing key version limitations in more
detail:

http://k5wiki.kerberos.org/wiki/Projects/Larger_key_versions

In addition to the kadmin concern, there are also 16-bit limitations on
the KDC side. The proposed changes could risk making our behavior
worse at 16-bit wraparound than it is currently. Perhaps this isn't
worth worrying about; if you rotate a key once per day, you won't hit
version 32767 until almost 90 years have elapsed. Regardless, some
possible approaches are detailed there.
From: ghudson@mit.edu
Subject: git commit

Use unsigned 16-bit type for key data kvno

Change key_data_kvno from a signed 16-bit field to an unsigned 16-bit
field, since negative values are never meaningful. When adding new
keys, wrap from 65535 to 1 to avoid using the special value 0.

Don't bump the KDB binary version since this change is unlikely to
affect callers.

https://github.com/krb5/krb5/commit/1d4df2264684ab6731dedc8882a0cd6353af33da
Author: Greg Hudson <ghudson@mit.edu>
Commit: 1d4df2264684ab6731dedc8882a0cd6353af33da
Branch: master
src/include/k5-int.h | 2 +-
src/include/kdb.h | 2 +-
src/lib/kadm5/kadm_rpc_xdr.c | 2 +-
src/lib/kadm5/srv/adb_xdr.c | 2 +-
src/lib/kdb/kdb_convert.c | 2 +-
src/lib/kdb/kdb_cpw.c | 4 ++++
src/lib/krb5/asn.1/ldap_key_seq.c | 3 ++-
src/plugins/kdb/ldap/libkdb_ldap/princ_xdr.c | 2 +-
8 files changed, 12 insertions(+), 7 deletions(-)
From: ghudson@mit.edu
Subject: git commit

Expand kadmin protocol kvno range

Make xdr_krb5_kvno() use xdr_u_int() instead of xdr_u_char(), allowing
it to marshal kvno values up to 32 bits. This change is
backwards-compatible because XDR uses four bytes to marshal char
values and does no bounds checking of char values on decode.

https://github.com/krb5/krb5/commit/49b2c5e30edf980e0f99b5fe2cdf6ff5b2a8b032
Author: Greg Hudson <ghudson@mit.edu>
Commit: 49b2c5e30edf980e0f99b5fe2cdf6ff5b2a8b032
Branch: master
src/lib/kadm5/kadm_rpc_xdr.c | 15 +--------------
1 files changed, 1 insertions(+), 14 deletions(-)
From: ghudson@mit.edu
Subject: git commit

Implement 32-bit keytab kvno extension

Heimdal and Shishi support a 32-bit kvno at the end of a keytab entry,
overriding the 8-bit version if present. Implement this in the FILE
keytab type and document it in keytab_file_format.rst.

https://github.com/krb5/krb5/commit/54b4ccf510b67140caec76b12fff4b30462e7e50
Author: Greg Hudson <ghudson@mit.edu>
Commit: 54b4ccf510b67140caec76b12fff4b30462e7e50
Branch: master
doc/formats/keytab_file_format.rst | 10 +++++-----
src/lib/krb5/keytab/kt_file.c | 26 +++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 6 deletions(-)
From: ghudson@mit.edu
Subject: git commit

Adjust keytab kvno workarounds

In krb5_ktfile_get_entry(), change the pivot and fuzzy match
workarounds for kvnos to work with the 32-bit kvno extension. For the
pivot logic, try to recognize kvno wraparound at boundary by looking
at the relative timestamps and the size of the version difference.
For the fuzzy match logic, remember the first match against the low 8
bits of the desired kvno, but keep searching for an exact match.

https://github.com/krb5/krb5/commit/73bdca02cd4c0f908affeea32a1693535955a766
Author: Greg Hudson <ghudson@mit.edu>
Commit: 73bdca02cd4c0f908affeea32a1693535955a766
Branch: master
src/lib/krb5/keytab/kt_file.c | 72 ++++++++++++++++++++++-------------------
1 files changed, 39 insertions(+), 33 deletions(-)
From: ghudson@mit.edu
Subject: git commit

Add tests for key rotation and 32-bit keytab kvnos

In t_keytab.py, test that kvnos no longer wrap after 255 or 32767, that
they do wrap from 65535 to 1, and that kadmin ktrem preserves the more
recent key after a wraparound.

Also test edge cases of the 32-bit keytab kvno extension using
hand-crafted keytab entries.

https://github.com/krb5/krb5/commit/3c873481596653f5a35be1fffc268847867e89e7
Author: Greg Hudson <ghudson@mit.edu>
Commit: 3c873481596653f5a35be1fffc268847867e89e7
Branch: master
src/tests/t_keytab.py | 81 ++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 70 insertions(+), 11 deletions(-)