Skip Menu |
 

Subject: etype-info conflated for initial, final reply key enctype
Download (untitled) / with headers
text/plain 3.2KiB
etype-info (PA-ETYPE-INFO and its successor PA-ETYPE-INFO2) may
appear in a preauth error (PREAUTH_REQUIRED,
MORE_PREAUTH_DATA_REQUIRED, or PREAUTH_FAILED). RFC 4120 sections
5.2.7.4 and 5.2.7.5 only talk about etype-info as it pertains to
encrypted timestamp. RFC 6113 section 2.1 indicates that the client
uses etype-info to produce the initial reply key (or a set of them).

etype-info may also appear in an AS-REP. RFC 4120 only talks about
this usage as it pertains to string-to-key operations used to compute
the AS-REP enc-part decryption key. RFC 4120 restricts AS-REP etype-
info to at most one entry which must match the enc-part of the AS-
REP. RFC 6113 does not discuss this usage of etype-info. The most
reasonable interpretation of the two specs is that AS-REP etype-info
pertains the final reply key.

The initial and final reply keys differ when a preauth mech replaces
the reply key. PKINIT is one such mechanism. As PKINIT makes no use
of the initial reply key, the final reply key may have a different
enctype from the initial reply key, or there might not even be an
initial reply key if the client principal entry has no keys. Our
PKINIT server code picks the first valid enctype in the client's
request list for the final reply key.

There are several concerning behaviors here:

1. The KDC may or may not include etype-info with a PKINIT AS-REP.
If it does, it includes salt information for the client's long-term
key (chosen according to the request enctype list as filtered by the
KDC's permitted_enctypes list), but the enctype of the final reply
key. This is clearly a nonsensical combination, although the
mismatched salt information is harmless as the client will not
perform any string-to-key operation. If the client has no long-term
keys (or none which match the request and permitted_enctype list),
the KDC will send no etype-info. Sending no etype-info would
probably be the ideal behavior for a PKINIT AS-REP whether or not the
client has long-term keys, except for #3 below.

2. Each time the client reads a padata list, whether in a preauth
error or an AS-REP, it looks for etype-info and extracts an enctype,
salt, and s2kparams into the init_creds context; those values are
used those for the clpreauth get_as_key() or get_etype() callbacks.
If a hypothetical future preauth mech first needs access to the
initial reply key or its enctype when processing the AS-REP, it could
erroneously use etype-info describing the final reply key.

3. The PKINIT client code uses the get_etype() callback to determine
the enctype of the final reply key, as clpreauth modules have no
access to the enctype of the AS-REP enc-part. If the KDC sent etype-
info in the AS-REP, that ought to work, assuming the KDC conforms to
RFC 4120 in the content of that element. If the KDC sent no etype-
info in the AS-REP but did send etype-info in the PREAUTH_REQUIRED
error, get_etype() will return the enctype from the earlier etype-
info, which is for the client's long-term key and could easily be
wrong. If the KDC never sent etype-info at all (such as when the
client principal has no long-term key), get_etype() will return the
first requested enctype, which is probably correct but isn't
guaranteed to be.
Download (untitled) / with headers
text/plain 1.1KiB
It looks like I was wrong about #3. get_in_tkt.c resets ctx->etype
to the AS-REP enctype before processing the final padata list,
although it can then be changed by etype-info in the AS-REP. The
PKINIT client will use the correct enctype unless the KDC sends
etype-info with a different enctype (which would be in violation of
RFC 4120). For robustness it would be better to use the AS-REP
enctype, but there's no immediate bug, and KDCs can omit etype-info
in PKINIT AS-REPs.

The get_etype() callback has some history to it. In release 1.6 when
it was first added (in the form of a get_data_proc request), it
always yielded the AS-REP enctype, or failed with ENOENT if there was
no AS-REP yet. The implementation of FAST in 1.7 (ticket 6436)
changed the callback to the current behavior and used it in encrypted
challenge. Ticket 6976 added the get_as_key() callback and stopped
using get_etype() in encrypted challenge, so only PKINIT currently
uses the callback. But the callback is now documented as returning
the enctype from etype-info before the AS-REP, so we shouldn't
completely revert to the 1.6 behavior.
From: ghudson@mit.edu
Subject: git commit

Always use AS-REP enctype in PKINIT client

The get_etype() callback originally only returned the AS-REP enctype
for PKINIT, but was changed for encrypted challenge to sometimes
return the enctype from etype-info. (Encrypted challenge no longer
uses the callback; PKINIT is currently the only known consumer.) Make
sure to always return the AS-REP enctype if an AS-REP has been
received, so that the PKINIT clpreauth module uses the correct enctype
even if the KDC sends a different enctype in etype-info in violation
of RFC 4120.

https://github.com/krb5/krb5/commit/0a9bd34b97ebf794b6ddbeb17c274623b445cca4
Author: Greg Hudson <ghudson@mit.edu>
Commit: 0a9bd34b97ebf794b6ddbeb17c274623b445cca4
Branch: master
src/include/krb5/clpreauth_plugin.h | 7 +++----
src/lib/krb5/krb/preauth2.c | 6 +++++-
2 files changed, 8 insertions(+), 5 deletions(-)
From: ghudson@mit.edu
Subject: git commit

Omit AS-REP etype-info for replaced reply keys

etype-info in AS-REP is currently only useful when no
pre-authentication took place. Don't send it if a preauth mech
replaced the reply key, as we can't send something consistently
meaningful (the enctype must match the replaced reply key per RFC
4120, but the salt from the client key data corresponds to the initial
reply key).

https://github.com/krb5/krb5/commit/9dadcd682c1a9c47bbea8182d82faa89ede3daaf
Author: Greg Hudson <ghudson@mit.edu>
Commit: 9dadcd682c1a9c47bbea8182d82faa89ede3daaf
Branch: master
src/kdc/kdc_preauth.c | 51 ++++++++++++++++++++++++++++++++----------------
1 files changed, 34 insertions(+), 17 deletions(-)