Kerberos Ticket Granting Service (TGS) requests are one of the most complicated areas of processing in MIT krb5, in both the client and the KDC. Here are some notes on the different kind of TGS requests and what considerations must be made when processing them.
Like an AS request, a TGS request contains a KDC-REQ-BODY sequence and a sequence of PA-DATA. One of the pa-data elements will have type PA-TGS-REQ; its value will contain an AP-REQ, the same protocol structure a client would use to authenticate to an application server. The ticket in the AP-REQ is called the "header ticket" within the MIT KDC source code, because RFC 4120 uses the term "authentication header" to refer to the AP-REQ.
The authenticator in the AP-REQ contains a checksum over the encoding of the body. This checksum need not be keyed, as it is contained within an encrypted payload, but with modern encryption types it is usually a keyed checksum anyway. There is no intrinsic cryptographic binding between other padata elements and the PA-TGS-REQ or the body.
The authenticator in the AP-REQ may contain a subkey, in which case the TGS response should be encrypted in the subkey. Otherwise it should be encrypted in the session key of the header ticket. There are four historical interoperability bugs affecting the use of subkeys in TGS requests, as described here:
https://mailarchive.ietf.org/arch/msg/krb-wg/DD8CFMuWiHJhkkoHGbjx0Z1dpKo https://mailarchive.ietf.org/arch/msg/krb-wg/4qhYxn7iovCnfsHL8wmim7-8Tq0 https://mailarchive.ietf.org/arch/msg/krb-wg/hl6PvUz94IQMFadSybnjGYeBCCE
TGS requests may use FAST implicit armor (RFC 6113 section 5.4). In this case one of the pa-data elements will have type PA-FX-FAST and its value will contain a second copy of the TGS request encrypted in a key derived from the subkey (which must be present) and the ticket session key.
Types of TGS requests
- Ticket modification: if the RENEW, VALIDATE, or PROXY option is requested, the header ticket server need not be a TGT (and must not be a TGT for PROXY), but the requested server must match the header ticket server. The RENEW option is frequently used in practice, while the VALIDATE and PROXY options are not.
- User-to-user: if the ENC-TKT-IN-SKEY option is requested, the request body must contain an additional ticket, whose client must match the requested server and whose server must be the local TGS (krbtgt/THIS.REALM@THIS.REALM). The issued ticket will be encrypted in the session key of the second ticket, not in the long-term key of the service principal.
- S4U2Self (aka "protocol transition"): if the request pa-data contains an element of type PA-FOR-USER or PA_S4U_X509_USER or both, it is a request to issue a ticket from a named user to the requesting service. S4U2Self is specified in [MS-SFU].
- S4U2Proxy (aka "constrained delegation"): if the CNAME-IN-ADDL-TICKET option is requested, the request body must contain an additional ticket (called the "evidence ticket") from a user to the requesting service--or, for a cross-realm request, a cross-TGT containing a PAC or equivalent authorization data for a user. If delegation is allowed to the requested server, the KDC issues a ticket from the evidence ticket client (or the client named in the PAC) to the requested server. S4U2Proxy is specified in the same document as S4U2Self.
Normal TGS requests
For the purposes of this article, a TGS request is considered "normal" if it:
- does not have any of the forwarded, proxy, renew, validate, enc-tkt-in-skey, or cname-in-addl-tkt options
- does not contain PA-FOR-USER or PA_S4U_X509_USER pa-data.
The header ticket for a normal TGS request server must be a TGT, meaning its sname field is krbtgt/THIS.REALM. If it is a cross-realm TGT (the srealm field is some OTHER.REALM different from THIS.REALM), the ticket's crealm must also be different from THIS.REALM; this is called the "lineage check", and ensures that foreign realms cannot issue tickets for local users. The KDC also (unless requested not to) checks the transited list in the ticket to ensure that OTHER.REALM has the authority to issue tickets for the realm of the header ticket client, and adds OTHER.REALM to the transited list of the issued ticket if it does not match the realm of the header ticket client.
If the requested server is a TGS principal for a different realm, the KDC may issue a ticket to an alternative TGS principal for an intermediate realm instead. If the requested server is not a TGS server but the request has the "canonicalize" KDC option set (RFC 6803 section 3), the KDC may issue a ticket to an outgoing TGS principal; this is called a "referral".
For local clients, some KDC implementations look up the client DB entry and apply the entry's policy in case it has changed (e.g. the account has been revoked). The MIT krb5 KDC does not currently do this.
It is possible for an otherwise normal TGS request to be part of a cross-realm Resource-Based Constrained Delegation (RBCD) operation transiting through this realm. In this case, the header ticket will be a cross-realm TGT, the request server will be a cross-realm TGS, the header ticket PAC will contain an S4U_DELEGATION_INFO buffer giving the ticket client as the last transited service, and the PAC_CLIENT_INFO buffer will contain a realm part in the name. These requests can be processed the same way as a normal TGS request, but when issuing a PAC for the resulting TGT the KDC must copy the PAC_CLIENT_INFO values from the header ticket rather than issuing one for the ticket client.