Public Key Cryptography for Initial Authentication in Kerberos (PKINIT) Freshness Extension
Extracted elements (19)
In PKINIT Diffie-Hellman exchanges, the client signs the AuthPack before any traffic is sent to the KDC, making it possible to pre-generate requests with future timestamps and send them later without possessing the private key at that time. This means DH-based PKINIT proves only prior use of the private key, not current possession.
Standardizing the internal contents of the freshness token is explicitly not a concern for interoperability, since freshness tokens are validated only by KDCs within the same realm and are opaque to clients. This allows realm-specific implementations.
The freshness token is intentionally opaque to the client so that KDC implementers can add additional functionality (such as signing or binding to context) without impacting existing clients, as long as the tokens expire to preserve the freshness guarantee.
To ensure current possession of the private key, the signed PKAuthenticator must include information the client could not have predicted. A KDC-provided freshness token—included in the signed portion of the KRB_AS_REQ—serves this purpose by introducing unpredictable data.
Because the client treats the KDC-provided freshness token as an opaque blob, the KDC can change the token's internal structure without impacting existing clients, making extensions to the freshness token backward compatible.
Clients SHOULD NOT reuse freshness tokens across multiple exchanges, as there is no guarantee a KDC will accept a previously valid token again; clients that reuse tokens may fail to interoperate with certain KDC implementations.
During deployment, implementers may allow both freshness-token-based and legacy (pre-generated PKAuthenticator) exchanges. Until freshness tokens are required by the realm, the existing risks of pre-generated PKAuthenticators remain.
After receiving the KRB_ERROR with a freshness token, the client SHALL add the PA_AS_FRESHNESS padata-value as an opaque blob in the freshnessToken field of the PKAuthenticator, ensuring it is covered by the client's signature.
If a client receives a KDC_ERR_PREAUTH_EXPIRED KRB_ERROR that includes a freshness token, it SHOULD retry the AS exchange using the new freshness token.
If the freshness token present in PA_PK_AS_REQ is not valid, the KDC MUST return a KRB_ERROR with error-code KDC_ERR_PREAUTH_EXPIRED (RFC 6113), and the e-data field MUST contain a METHOD-DATA object specifying a valid PA_AS_FRESHNESS padata-value.
If the realm requires freshness and the PA_PK_AS_REQ does not contain a freshness token, the KDC MUST return a KRB_ERROR with error-code KDC_ERR_PREAUTH_FAILED and include a valid PA_AS_FRESHNESS padata-value.
The client indicates support for freshness tokens by adding a padata element with padata-type PA_AS_FRESHNESS and padata-value of an empty octet string in its initial KRB_AS_REQ.
The KDC responds to a freshness token request with a KRB_ERROR carrying error-code KDC_ERR_PREAUTH_REQUIRED and includes a padata element with padata-type PA_AS_FRESHNESS and padata-value containing the freshness token in the METHOD-DATA object.
PA_AS_FRESHNESS is a new padata type with padata-type value 150. Clients include it with an empty octet string to signal support; the KDC includes it with the actual freshness token value in KRB_ERROR responses.
The extended PKAuthenticator retains the original fields (cusec [0], ctime [1], nonce [2], paChecksum [3]) and adds freshnessToken [4] OCTET STRING OPTIONAL. The freshnessToken covers the KDC-provided opaque blob and is included in the signed portion of the KRB_AS_REQ.
RFC 8070 registers PA_AS_FRESHNESS with type value 150 in the 'Pre-authentication and Typed Data' subregistry of the 'Kerberos Parameters' IANA registry.
The freshness token SHOULD include signing, encrypting, or sealing of KDC data to determine authenticity and prevent tampering. Freshness tokens are not required to be single-use or bound to specific AS exchanges, but they must expire to preserve the freshness guarantee.
The protocol follows a five-step flow: (1) client sends KRB_AS_REQ with PA_AS_FRESHNESS but no PA_PK_AS_REQ; (2) KDC returns KRB_ERROR with freshness token; (3) client sends KRB_AS_REQ with the freshness token embedded in the signed PKAuthenticator; (4) KDC validates the request and freshness token; (5) KDC and client continue per RFC 4120/4556.
The PKAuthenticator ASN.1 SEQUENCE (from RFC 4556 Section 3.2.1) is extended with an optional freshnessToken field tagged [4] OCTET STRING OPTIONAL. This field MUST be present if the KDC sent a freshness token; it carries the opaque PA_AS_FRESHNESS padata-value verbatim.