Projects/SPAKE preauth prereqs
Contents
Background
draft-mccallum-kitten-krb-spake-preauth is a new pre-authentication mechanism which will better protect client passwords and will allow better integration of second factors. Although the details of the mechanism are still in development and will not be ready for the 1.14 release, it will have several prerequisites for the client and KDC implementations. By satisfying these prerequisites, we can allow the SPAKE preauth mechanism to be distributed as a loadable module which works with the 1.14 release.
KDC cookie
RFC 6113 defines a pa-data type containing a cookie which the client must echo back to the KDC. The SPAKE preauth mech will require the use of this cookie to remember the KDC private value and other information. As of the 1.13 release, the cookie value is always "MIT".
KDC cookie support is in pull request #314. The cookie value will be the four bytes "MIT1", followed by a four-byte big-endian kvno value, followed by the RFC 3961 encryption of the following ASN.1 sequence:
SecureCookie ::= SEQUENCE { time INTEGER, data SEQUENCE OF PA-DATA, ... }
An integer is used for the timestamp to save space. The cookie is encrypted in a derivative of the first local-realm krbtgt key of the specified kvno, using the PRF+ function with the string "COOKIE" followed by the unparsed client principal name as input. The encryption uses key usage 513, which is in the key usage range reserved for Kerberos implementations.
kdcpreauth modules will gain new callbacks to set cookie information for the reply and to retrieve cookie information from the request. The KDC will aggregate, encode, and encrypt cookie information when generating error replies, and will decrypt, verify, and decode cookie information received in requests.
KDC_ERR_PREAUTH_EXPIRED
Cookies older than the clock skew will be rejected by the KDC using the new error code KDC_ERR_PREAUTH_EXPIRED from RFC 6113. When the client receives this error code, it should discard its pre-authentication information (including the cookie) and retry the AS exchange. Support for KDC_ERR_PREAUTH_EXPIRED is implemented in the following commits:
9914d38658e5612db5b2847892b5ddce2b73c344 Simplify get_in_tkt.c restart handling d3e0af0774dd100f00fbc8895b99355d82d86bf1 Add KDC_ERR_PREAUTH_EXPIRED support
Single ETYPE-INFO2
The actual SPAKE exchange in the SPAKE preauth mech begins with the KDC's public value; therefore, the KDC must know what long-term key the client will use. To make this work, the KDC must supply only one ETYPE-INFO2 entry as suggested in RFC 6113 section 2.1. We also need a new kdcpreauth module callback to retrieve the single client key which the KDC has determined based on the client enctype list.
This change is implemented in the following commits:
385cd2d07983a89892dad1606e1a41a78066c6ec Only include one key in etype-info 5cf4a7e220141f10f51995ceae9b9e74232a31b7 Add tests for KDC etype-info behavior 7b12eb4757f8dd05b79c9b49d4289f0caf1f6eec Add client_keyblock kdcpreauth callback be20a5f5cee8d6c4072d1b81712520dbf9f6eefd Test client_keyblock kdcpreauth callback
KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
The SPAKE preauth mechanism is multi-hop, and therefore requires support for the KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error from RFC 6113. Initial support for this error is in the following commit:
95c3cab051aa1b8b4f7eb309bf135e8f51665baa Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
On the KDC side, we will need to amend this support to add a KDC cookie to the module-supplied pa-data. Also, if the client did not include a KDC cookie in its request, then it is performing optimistic preauth and has not yet received an ETYPE-INFO2 from the KDC. In this case, an ETYPE-INFO2 entry must be added to the pa-data so the client can compute the long-term key when continuing the SPAKE mechanism.
kdcpreauth module ordering
The KDC does not currently support any administrator control over pre-authentication module ordering in the PREAUTH_REQUIRED METHOD-DATA, nor does it allow modules to influence the ordering. Since SPAKE is intended to be a superior replacement to encrypted timestamp, the loadable module which implements it must be able to make the SPAKE preauth mech appear before encrypted timestamp in the METHOD-DATA.
Fortunately, no action is required. Although we formerly preferred built-in preauth mechs to loaded ones ([krbdev.mit.edu #6429]), this was changed 1.12 when plugin module ordering guarantees were implemented ([krbdev.mit.edu #7665]). Loaded kdcpreauth modules now appear before built-in mechanisms in the METHOD-DATA.
PRF+ API
The SPAKE preauth mech uses the PRF+ primitive from RFC 6113 in several places. A public API implementing this primitive would make it easier to perform this operation. The PRF+ API should be similar to krb5_c_random_make_octets(), with the addition of key and input-string parameters. We could also consider adding an API to derive a key from a key and an input string using PRF+.
This change is still in development. It is not critical that it be done for the 1.14 release; the mech implementation can always implement PRF+ internally using krb5_c_prf().