RFC 8070

Public Key Cryptography for Initial Authentication in Kerberos (PKINIT) Freshness Extension

πŸ“… published February 2017, from ietf

RFC 8070 πŸ’– Part 1 of 2

okay bestie, this is RFC 8070, and it's giving freshness 🧚✨ The title is Public Key Cryptography for Initial Authentication in Kerberos (PKINIT) Freshness Extension. It's a Standards Track doc from the IETF, dated February 2017, with ISSN 2070-1721. The authors are M. Short (Ed.), S. Moore, and P. Miller, all from Microsoft Corporation πŸŽ€. The title block doesn't list anything it obsoletes or updates, so it's a fresh one πŸ’….


Abstract 🌸

okay so the TL;DR: this doc explains how to bolt another extension onto PKINIT (the one from RFC 4556) so it can carry an opaque data blob 🫢. A Key Distribution Center (KDC) can check that blob and confirm the client actually has the private key right now during a PKINIT Authentication Service (AS) exchange. no more "I had the key yesterday, trust me bro" πŸ’€


Status of This Memo πŸ“œ

this is an Internet Standards Track document πŸ”₯

it's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. it went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check Section 2 of RFC 7841 ✨

for the current status, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc8070 πŸ¦‹


Copyright (c) 2017 IETF Trust and the persons identified as the document authors. All rights reserved πŸ’œ

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stood on the publication date. please actually read those, bestie, they spell out your rights and restrictions for this doc πŸ™ˆ

if you pull Code Components out of this doc, they have to include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, same as that license says ⭐


Table of Contents πŸ“

   1. Introduction ....................................................2
      1.1. Kerberos Message Flow Using KRB_AS_REQ without
           Pre-authentication .........................................3
      1.2. Requirements Language ......................................3
   2. Message Exchanges ...............................................4
      2.1. Generation of KRB_AS_REQ Message ...........................4
      2.2. Generation of KRB_ERROR Message ............................4
      2.3. Generation of KRB_AS_REQ Message ...........................4
      2.4. Receipt of KRB_AS_REQ Message ..............................5
      2.5. Receipt of Second KRB_ERROR Message ........................5
   3. PreAuthentication Data Types ....................................5
   4. Extended PKAuthenticator ........................................6
   5. IANA Considerations .............................................6
   6. Security Considerations .........................................7
   7. Interoperability Considerations .................................7
   8. Normative References ............................................8
   Acknowledgements ...................................................8
   Authors' Addresses .................................................9

1. Introduction ✨

okay so the Kerberos PKINIT extension [RFC4556] gives you two ways to use asymmetric crypto in a Kerberos pre-authenticator πŸ”. one uses Diffie-Hellman key exchange and the other uses public key encryption. the public key encryption one is way less popular, and there are two reasons:

  • Elliptic Curve Cryptography (ECC) Support for PKINIT [RFC5349] only specified Elliptic Curve Diffie-Hellman (ECDH) key agreement, so it can't be used for public key encryption 😭
  • public key encryption needs certificates that carry an encryption key, and a lot of existing smart cards just don't have one πŸ’€

now the Diffie-Hellman exchange: the client uses its private key only to sign the AuthPack structure (from Section 3.2.1 of [RFC4556]), and it does that before any traffic goes to the KDC 🧚. so a client can build requests with future times in the PKAuthenticator and then send them at those future times. unless that time is outside the validity period of the client's certificate, the KDC will validate the PKAuthenticator and hand back a Ticket-Granting Ticket (TGT) the client can use without ever having the private key 😳

so here's the tea 🍡: a client doing PKINIT with Diffie-Hellman doesn't prove it currently has the private key. it only proves it used that key at some point. to prove current possession, the signed PKAuthenticator data has to include something the client couldn't have predicted πŸ™ˆ

1.1. Kerberos Message Flow Using KRB_AS_REQ without Pre-authentication πŸ¦‹

today, password-based AS exchanges [RFC4120] usually start with the client sending a KRB_AS_REQ with no pre-authentication πŸ’…. if the principal needs pre-authentication, the KDC replies with a KRB_ERROR that has what's needed to finish the AS exchange, like the supported encryption types and salt values. here's how that flow looks:

   Client                                          KDC

   AS-REQ without pre-authentication     ---->
                                         <----     KRB-ERROR

   AS-REQ                                ---->
                                         <----     AS-REP

   TGS-REQ                               ---->
                                         <----     TGS-REP

                           Figure 1

we can run something similar with PKINIT 🌸. the KDC gives the client a token to include in its KRB_AS_REQ, which makes sure the PA_PK_AS_REQ [RFC4556] wasn't pre-generated. iconic, right? πŸ‘‘

1.2. Requirements Language πŸŽ€

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] πŸ“š


2. Message Exchanges 🧚

here's the summary of the message flow, with the extensions to [RFC4120] and [RFC4556] that you need to support a KDC-provided freshness token during the initial ticket request πŸ’–

  1. the client generates a KRB_AS_REQ, as specified in Section 2.9.3 of [RFC4120], that has no PA_PK_AS_REQ and includes a freshness token request ✨
  2. the KDC generates a KRB_ERROR, as specified in Section 3.1.4 of [RFC4120], that provides a freshness token 🫢
  3. the client gets the error, as specified in Section 3.1.5 of [RFC4120], pulls out the freshness token, and includes it in the KRB_AS_REQ as specified in [RFC4120] and [RFC4556] πŸ¦‹
  4. the KDC receives and validates the KRB_AS_REQ, as specified in Section 3.2.2 of [RFC4556], and then also validates the freshness token πŸ”₯
  5. the KDC and client carry on, as specified in [RFC4120] and [RFC4556] πŸ’œ

2.1. Generation of KRB_AS_REQ Message 🌈

the client shows it supports freshness tokens by adding a padata element with padata-type PA_AS_FRESHNESS and a padata-value of an empty octet string πŸ“

2.2. Generation of KRB_ERROR Message 🌸

the KDC responds with a KRB_ERROR [RFC4120] message that has the error-code KDC_ERR_PREAUTH_REQUIRED [RFC4120]. it adds a padata element with padata-type PA_AS_FRESHNESS and a padata-value of the freshness token to the METHOD-DATA object πŸŽ€

2.3. Generation of KRB_AS_REQ Message ✨

once the client gets the KRB-ERROR message with a freshness token, it pulls out the PA_AS_FRESHNESS padata-value field of the PA-DATA structure as an opaque data blob 🧚. the PA_AS_FRESHNESS padata-value field of the PA-DATA structure SHALL then be added as an opaque blob in the freshnessToken field when the client builds the PKAuthenticator from Section 4 for the PA_PK_AS_REQ message. that way, the freshness token value ends up inside the signed data portion of the KRB_AS_REQ value πŸ”

2.4. Receipt of KRB_AS_REQ Message πŸ’…

if the realm requires freshness and the PA_PK_AS_REQ message doesn't contain the freshness token, the KDC MUST return a KRB_ERROR [RFC4120] message with the error-code KDC_ERR_PREAUTH_FAILED [RFC4120]. that error carries a padata element with padata-type PA_AS_FRESHNESS and a padata-value of the freshness token, inside the METHOD-DATA object πŸ™ˆ

when the PA_PK_AS_REQ message does contain a freshness token, the KDC first validates the PA_PK_AS_REQ message normally. then it validates the freshnessToken value in the PKAuthenticator, in an implementation-specific way πŸ¦‹. if the freshness token isn't valid, the KDC MUST return a KRB_ERROR [RFC4120] message with the error-code KDC_ERR_PREAUTH_EXPIRED [RFC6113] πŸ’€. the e-data field of that error holds a METHOD-DATA object [RFC4120], which specifies a valid PA_AS_FRESHNESS padata-value. since the freshness tokens get validated by KDCs in the same realm, standardizing what's inside the freshness token isn't a concern for interoperability 🫢

2.5. Receipt of Second KRB_ERROR Message πŸ’–

if a client gets a KDC_ERR_PREAUTH_EXPIRED KRB_ERROR message that includes a freshness token, it SHOULD retry using the new freshness token πŸ”βœ¨


3. PreAuthentication Data Types 🌈

these are the new PreAuthentication data types πŸ“

               +----------------------+-------------------+
               | Padata and Data Type | Padata-type Value |
               +----------------------+-------------------+
               |   PA_AS_FRESHNESS    |        150        |
               +----------------------+-------------------+

4. Extended PKAuthenticator πŸ‘‘

the PKAuthenticator structure from Section 3.2.1 of [RFC4556] gets extended with a new freshnessToken field, like this 🧚

   PKAuthenticator ::= SEQUENCE {
      cusec        [0] INTEGER (0..999999),
      ctime        [1] KerberosTime,
                -- cusec and ctime are used as in [RFC4120], for
                -- replay prevention.
      nonce        [2] INTEGER (0..4294967295),
                -- Chosen randomly;  this nonce does not need to
                -- match with the nonce in the KDC-REQ-BODY.
      paChecksum   [3] OCTET STRING OPTIONAL,
                -- MUST be present.
                -- Contains the SHA1 checksum, performed over
                -- KDC-REQ-BODY.
      ...,
      freshnessToken     [4] OCTET STRING OPTIONAL,
                -- PA_AS_FRESHNESS padata value as received from the
                -- KDC. MUST be present if sent by KDC
      ...
   }

5. IANA Considerations πŸ¦‹

IANA has assigned numbers for PA_AS_FRESHNESS. they're listed in a subregistry of the "Kerberos Parameters" registry, titled "Pre-authentication and Typed Data" πŸ’…

                  +------+-----------------+-----------+
                  | Type |      Value      | Reference |
                  +------+-----------------+-----------+
                  | 150  | PA_AS_FRESHNESS | [RFC8070] |
                  +------+-----------------+-----------+

to be continued in part 2 πŸ’œπŸŽ€

6. Security Considerations πŸ”

Okay bestie, security is where things get dramatic 😭 The freshness token SHOULD include signing, encrypting, or sealing the data from the KDC, so you can tell it's really from the KDC and nobody has been messing with it πŸ’…

Freshness tokens exist to prove the client actually had the key when it built the AS-REQ ✨ They don't have to be single-use, and they don't have to be tied to one specific AS exchange πŸ¦‹ The token is opaque on purpose, so KDC implementers get the freedom to add extra features 🧚 The one non-negotiable is that the tokens expire, because that's what keeps the "freshness" guarantee alive πŸ’€

7. Interoperability Considerations 🫢

Since the client treats the KDC-provided data blob as opaque, changing what's inside won't break existing clients πŸŽ€ So extensions to the freshness token don't hurt interoperability at all, which is iconic πŸ‘‘

Clients SHOULD NOT reuse freshness tokens across multiple exchanges πŸ™ˆ There's no guarantee that a KDC will accept a token it already accepted once, so clients that don't grab a new freshness token on retry might not play nicely with some KDCs, depending on how that KDC does its freshness validation. Not me being left on read πŸ’€

Upgrading clients takes time, so implementers can think about supporting both freshness-token exchanges and "legacy" exchanges that don't use freshness tokens 🌸 Just know that until the realm requires freshness tokens, the existing risks of pre-generated PKAuthenticators are still hanging around 😬

8. Normative References πŸ“š

Acknowledgements 🌈

Douglas E. Engert, Sam Hartman, Henry B. Hotz, Nikos Mavrogiannopoulos, Martin Rex, Nico Williams, and Tom Yu were the key contributors who discovered the freshness issue in PKINIT πŸ•΅οΈβ€β™€οΈβœ¨

Sam Hartman, Greg Hudson, Jeffrey Hutzelman, Nathan Ide, Benjamin Kaduk, Bryce Nordgren, Magnus Nystrom, Nico Williams, and Tom Yu reviewed the document and gave suggestions for improvements πŸ«ΆπŸ’œ

Authors' Addresses πŸ’Œ

Michiko Short (editor) Microsoft Corporation United States of America Email: michikos@microsoft.com


Seth Moore Microsoft Corporation United States of America Email: sethmo@microsoft.com


Paul Miller Microsoft Corporation United States of America Email: paumil@microsoft.com

πŸ“¦ where this page comes from