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".
The new secure 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.
Support for secure cookies is implemented in the following commits:
312b3bc29a0c52a0a82055f566241964532c2128 Add ASN.1 encoder and decoder for secure cookie 4e15c03b54464b661c6578f78de3bd348163fc07 Add secure cookie support 379239d98a05b271bbd6127f98bdb64646958b4c Add cookie tests 752574e288c8322001d1b4e62f5fd99c579a3403 Document secure cookie format and callbacks
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; this is done as part of cookie support in pull request #314. 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. This change is implemented in the following commits:
426d0bae0ebc8a4d4c6e44dd8953cde2196b5d82 Refactor finish_check_padata() in KDC 1b4bd4e388faa5685aa483fdc2bded02c95350bc Add etype-info2 to MORE_PREAUTH_DATA_REQUIRED
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 will 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 will also add an API to derive a key from a key and an input string using PRF+.
This change is implemented in the following commit:
35f288092f0df7f4aca92e1f51db3611a3b32ada Add krb5_c_prfplus() and krb5_c_derive_prfplus()
Release notes
Administrator experience:
- Transmit only one ETYPE-INFO and/or ETYPE-INFO2 entry from the KDC during pre-authentication, corresponding to the client's most preferred encryption type.
Developer experience:
- Add krb5_c_prfplus() and krb5_c_derive_prfplus() APIs, which implement the RFC 6113 PRF+ operation and key derivation using PRF+.
- Add support for pre-authentication mechanisms which use multiple round trips, using the the KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error code. Add get_cookie() and set_cookie() callbacks to the kdcpreauth interface; these callbacks can be used to save marshalled state information in an encrypted cookie for the next request.
- Add a client_key() callback to the kdcpreauth interface to retrieve the chosen client key, corresponding to the ETYPE-INFO2 entry sent by the KDC.