The FAST negotiation project builds on Projects/FAST. That project defines an interface that a client can use to make an armor ticket available to the library. Currently, that interface mandates the use of FAST; if a client supplies an armor ticket then the library requires the KDC to support FAST.
In many situations, it is desirable to use FAST when it is available but to fall back to not using FAST if FAST is unavailable. This project proposes to implement a secure mechanism for accomplishing that goal.
Larry Zhu proposed  a mechanism for negotiating FAST. The client includes a padata in its request indicating it supports the negotiation mechanism. If the KDC receives this padata, it returns a modified as-rep including a checksum of the client's as-req along with an indication of whether FAST is supported.
- A mechanism to request an armor ticket and during the process of requesting that armor ticket securely determine whether the KDC supports FAST.
- A mechanism to store the result of FAST negotiation
- Enhancements of the FAST API to require/use FAST only when it is supported
In addition, the following would be strongly desirable:
- A mechanism to use Anonymous pkinit to obtain an armor ticket for a given set of realms if no armor ticket is provided
Projects/Aliases added support for the encrypted padata field in MIT Kerberos. This field is currently a Microsoft extension introduced in Windows 2000. The KDC reply may contain a second set of padata encrypted in the reply key of the request. This field would not be useful for solving the same problems that FAST solves; among other reasons, the client must know the reply key before it can decrypt. However, this facility is sufficient for securely negotiating FAST.
Larry proposes to standardize this field and to standardize a mechanism for FAST negotiation. At the interop event, Larry's proposal was prototyped for MIT Kerberos. This included the necessary work to send the padata and to verify results.
Storing Negotiation results
Currently, armor tickets are stored in a credentials cache. In order to effectively use the negotiation mechanism, the client needs to be able to look at a given armor ticket and determine whether fast is available. [krbdev.mit.edu #6206] provides a way to store configuration information in a ticket cache. This API shall be used to store information on whether FAST is available.
The current approach is to store state based on what is returned from the AS request. The pre-authentication framework does permit a cross-realm armor ticket to be used; for example, if a host key is used to obtain an armor ticket and the client and host are registered in different realms, then a cross-realm armor ticket will be used. The assumption of this project is that whether FAST is used will be determined based on what the KDC against which the AS request to get the armor ticket supports. This can be expanded in the future to store more fine-grained negotiation state if needed. Options would include:
- Constructing configuration keys that include the realm name and using the negotiation procedure recursively
- Using the negotiation procedure recursively and storing per-realm state with some new mechanism--possibly associated with the TGT for that realm
Another complexity is handling of renewed and validated credentials. Currently, the APIs for handling renewal and credential validation take a ccache, but do not write credentials out to the ccache. Since there is no API documentation it's not clear what behavior changes are acceptable. For a program today that runs the renewal and then replaces the credentials in the cache, writing out the credentials would be a no-op. For a program that expects credentials unrelated to the renewal to remain in the cache and be undisturbed, that behavior change would be significant. Another approach might be to preserve set_config state across calls to krb5_cc_initialize. That should not affect existing code, although it would make it difficult to unset configuration state in a ccache.
Unexpected preauth handling
Prior to [krbdev.mit.edu #6480], included in Krb5 1.7, if the KDC received unknown padata it would return KDC_ERR_PREAUTH_FAILED rather than KDC_ERR_PREAUTH_REQUIRED. Also, prior to 1.7, the KDC did not include the set of pre-authentication types to try with the PREAUTH_FAILED error. The FAST negotiation code needs to handle this situation. The proposal is that if PREAUTH_FAILED is received as the first error and no pre-authentication types were forced, then try again without including the request for negotiation. If the KDC ends up supporting negotiation, the ticket flag will be set and we will correctly fail. When standardizing this we will need to require that KDCs implementing this negotiation ignore unknown padata and return PREAUTH_REQUIRED not PREAUTH_FAILED.
The current FAST API requires that if a client specifies a FAST armor ticket, then FAST will be required. However comments in the header file make it clear that this is not a guaranteed interface. the API contract is that the client is providing an armor ticket for the library. The library may either interpret this as "must use FAST," as it does today or "should use fast."
This project changes the behavior from "must use fast," to "should use fast." and provides an additional API to force FAST be required.
Ccache to krb5_get_init_creds
In order to store negotiation state in the ccache, krb5_get_init_creds needs to actually write the ticket to the ccache. To do that, a new API will be added to use the get_init_creds options structure to store the target ccache.