RFC 8737

Automated Certificate Management Environment (ACME) TLS Application-Layer Protocol Negotiation (ALPN) Challenge Extension

πŸ“… published February 2020, from ietf

RFC 8737: ACME TLS ALPN Challenge Extension πŸŽ€

okay bestie, this one is RFC 8737, and it's giving "how do we prove we own a domain using just the TLS layer" πŸ”βœ¨. The title is Automated Certificate Management Environment (ACME) TLS Application-Layer Protocol Negotiation (ALPN) Challenge Extension. It was written by R.B. Shoemaker of ISRG and published in February 2020. It's a Standards Track doc, the ISSN is 2070-1721, and its header has no Obsoletes or Updates line, so it doesn't replace or change any other RFC. πŸ’–

Abstract

this doc adds a new challenge for the ACME protocol that lets you do domain control validation using TLS πŸ¦‹

Status of This Memo

this is an Internet Standards Track document 🌸

it's a product of the Internet Engineering Task Force (IETF) and it represents the consensus of the IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). more info on Internet Standards is in Section 2 of RFC 7841 πŸ“š

for the current status, any errata, and how to give feedback, check https://www.rfc-editor.org/info/rfc8737 πŸ”—

Copyright (c) 2020 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 (https://trustee.ietf.org/license-info) as they stand on the publication date. please actually read these, because they explain what you're allowed to do and what you aren't πŸ™ˆ. any Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty as described in the Simplified BSD License πŸ’œ

Table of Contents

1.  Introduction
2.  Terminology
3.  TLS with Application-Layer Protocol Negotiation (TLS ALPN)
        Challenge
4.  acme-tls/1 Protocol Definition
5.  Security Considerations
6.  IANA Considerations
  6.1.  SMI Security for PKIX Certificate Extension OID
  6.2.  ALPN Protocol ID
  6.3.  ACME Validation Method
7.  Normative References
Appendix A.  Design Rationale
Acknowledgments
Author's Address

1. Introduction ✨

okay so the Automatic Certificate Management Environment (ACME) [RFC8555] spec already explains how to validate control of domain names over HTTP and DNS. then deployments showed that it's also useful to validate domain control using the TLS layer alone πŸ₯Ή. this is especially good for hosting providers, Content Distribution Networks (CDNs), and TLS-terminating load balancers, because they can validate domain control without changing how their backends handle HTTP πŸ’…

this doc specifies a new TLS-based challenge type called tls-alpn-01. it needs you to negotiate a new application-layer protocol using the TLS Application-Layer Protocol Negotiation (ALPN) Extension [RFC7301] πŸ¦‹. since this protocol doesn't build on an existing deployment base, you can only complete tls-alpn-01 challenges if service providers make changes, so it's explicitly opt-in 🫢. and because providers have to deploy new code on purpose to support it, we can require stronger controls in that code, which makes it a stronger validation method πŸ‘‘

2. Terminology πŸ’…

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be read as described in BCP 14 [RFC2119] [RFC8174], but only when they're in ALL CAPS like shown here πŸŽ€. lowercase versions are just regular words, no cap 😭

3. TLS with Application-Layer Protocol Negotiation (TLS ALPN) Challenge πŸ”

okay this is the main event bestie πŸ’–. the TLS with Application-Layer Protocol Negotiation (TLS ALPN) validation method proves you control a domain name by making the ACME client set up a TLS server that responds to specific connection attempts using the ALPN extension with identifying info ✨. the ACME server checks control by connecting to a TLS server at one of the addresses resolved for the domain name, then verifying that a certificate with specific content comes back 🧚

the tls-alpn-01 ACME challenge object has the following format πŸ“‹:

  • type (required, string): the string "tls-alpn-01"
  • token (required, string): a random value that uniquely identifies the challenge. this value MUST have at least 128 bits of entropy 🎲. it MUST NOT contain any characters outside the base64url alphabet from Section 5 of [RFC4648] πŸ™…. trailing '=' padding characters MUST be stripped 🧹. for more on randomness requirements, see [RFC4086] πŸŒ€

the client gets ready for validation by building a self-signed certificate that MUST contain an acmeIdentifier extension and a subjectAlternativeName extension [RFC5280] πŸ“. the subjectAlternativeName extension MUST contain a single dNSName entry, and the value is the domain name being validated 🎯. the acmeIdentifier extension MUST contain the SHA-256 digest [FIPS180-4] of the key authorization [RFC8555] for the challenge πŸ’œ. and the acmeIdentifier extension MUST be critical, so the certificate doesn't get accidentally used by non-ACME software πŸ›‘

the acmeIdentifier extension is identified by the id-pe-acmeIdentifier object identifier (OID) in the id-pe arc [RFC5280] 🌈:

id-pe-acmeIdentifier OBJECT IDENTIFIER ::=  { id-pe 31 }

the extension uses this ASN.1 [X.680] format ✨:

Authorization ::= OCTET STRING (SIZE (32))

the extnValue of the id-pe-acmeIdentifier extension is the ASN.1 DER encoding [X.690] of the Authorization structure, which holds the SHA-256 digest of the key authorization for the challenge πŸ¦‹

once the certificate is created, it MUST be provisioned so it gets returned during a TLS handshake where the "acme-tls/1" application-layer protocol has been negotiated and a Server Name Indication (SNI) extension [RFC6066] has been provided with the domain name being validated 🫢

a client responds by POSTing an empty JSON object ({}) to the challenge URL to say the challenge is ready to be validated by the server πŸ’…. the base64url encoding of the protected headers and payload is described in Section 6.1 of [RFC8555] ✨

POST /acme/authz/1234/1
Host: example.com
Content-Type: application/jose+json

{
  "protected": base64url({
    "alg": "ES256",
    "kid": "https://example.com/acme/acct/1",
    "nonce": "JHb54aT_KTXBWQOzGYkt9A",
    "url": "https://example.com/acme/authz/1234/1"
  }),
  "payload": base64url({}),
  "signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4"
}

when the server gets this request, it builds and stores the key authorization from the challenge "token" value and the current client account key πŸ”‘

then the server verifies the client's control over the domain by checking that the TLS server was configured as expected, using these steps πŸ‘€:

  1. The ACME server computes the expected SHA-256 digest of the key authorization.
  2. The ACME server resolves the domain name being validated and chooses one of the IP addresses returned for validation (the server MAY validate against multiple addresses if more than one is returned) 🎲.
  3. The ACME server initiates a TLS connection to the chosen IP address. This connection MUST use TCP port 443. The ACME server MUST provide an ALPN extension with the single protocol name "acme-tls/1" and an SNI extension containing only the domain name being validated during the TLS handshake πŸ”Œ.
  4. The ACME server verifies that during the TLS handshake the application-layer protocol "acme-tls/1" was successfully negotiated (and that the ALPN extension contained only the value "acme-tls/1") and that the certificate returned contains:
    • a subjectAltName extension containing the dNSName being validated and no other entries
    • a critical acmeIdentifier extension containing the expected SHA-256 digest computed in step 1

the comparison of dNSNames MUST be case insensitive [RFC4343] πŸ”€. also, since ACME doesn't support Unicode identifiers, all dNSNames MUST be encoded using the rules of [RFC3492] 🌸

if every step above succeeds, the validation is successful πŸŽ‰. otherwise, it fails πŸ’€


okay that's the first half bestie 🫢. section 4 onward is next, so stay tuned for part 2 πŸ¦‹βœ¨

6.1. SMI Security for PKIX Certificate Extension OID πŸŽ€

Okay bestie, the IANA registry gets a new entry πŸ“‹ In the "Structure of Management Information (SMI) Numbers (MIB Module Registrations)" registry, a new row was added to the "SMI Security for PKIX Certificate Extension" (1.3.6.1.5.5.7.1) table. It's giving official paperwork energy πŸ’…

+---------+----------------------+------------+
| Decimal | Description          | References |
+=========+======================+============+
| 31      | id-pe-acmeIdentifier | RFC 8737   |
+---------+----------------------+------------+

                    Table 1

6.2. ALPN Protocol ID πŸ¦‹

Now the ALPN protocol ID! 🫢 Within the "Transport Layer Security (TLS) Extensions" registry, a new entry was added to the "TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs" table. The name is acme-tls/1, and its identification sequence is the bytes for that string, written out one by one in hex πŸ”₯

   +------------+------------------------------------+-----------+
   | Protocol   | Identification Sequence            | Reference |
   +============+====================================+===========+
   | acme-tls/1 | 0x61 0x63 0x6d 0x65 0x2d 0x74 0x6c | RFC 8737  |
   |            | 0x73 0x2f 0x31 ("acme-tls/1")      |           |
   +------------+------------------------------------+-----------+

                    Table 2

6.3. ACME Validation Method 🌸

Last one in IANA land, and it's a good one ✨ Within the "Automated Certificate Management Environment (ACME) Protocol" registry, a new entry was added to the "ACME Validation Methods" registry. The label is tls-alpn-01, the identifier type is dns, it's marked as ACME (Y), and it's defined by RFC 8737 🧚

        +-------------+-----------------+------+-----------+
        | Label       | Identifier Type | ACME | Reference |
        +=============+=================+======+===========+
        | tls-alpn-01 | dns             | Y    | RFC 8737  |
        +-------------+-----------------+------+-----------+

                    Table 3

7. Normative References πŸ“š

These are the docs this spec leans on, so you'd better know them too πŸ€“


Appendix A. Design Rationale 🧠

Okay, the story behind all of this is so good 😭 The TLS ALPN challenge exists to iterate on the TLS SNI challenge from the early ACME drafts. The SNI challenge was super convenient for two kinds of service providers: the ones running big TLS load balancers who wanted to do validation there, and the ones running servers that front tons of DNS names from a single host. Validation happened purely inside the TLS layer, which is why people loved it πŸ’– The value was considered big enough that this document was written to provide a new challenge type that dealt with the existing security concerns.

Now the drama πŸ’€ Frans Rosen discovered a security issue in the TLS SNI challenge. It let users of various service providers illegitimately validate control of other users' DNS names. The original assumption was that a user could only respond to TLS traffic via SNI for domain names they'd registered with a provider. Like, if a user registered a.example, they'd only be able to respond to SNI requests for a.example and not b.example. Turns out a bunch of big providers don't honor that property πŸ™ˆ

So here's how it went wrong. If User A and User B had registered Host A and Host B, respectively, User A could claim the constructed SNI challenge name for Host B. Then, when the validation connection was made, User A could answer it and prove "control" of Host B. The SNI name used was a subdomain of the domain being validated, not the domain itself, so it probably wasn't registered with the provider for traffic routing yet. That made a hijack way easier to pull off 😱 Not me being like "how did nobody catch this sooner"!


Acknowledgments 🫢

The author would like to thank everyone who provided design insights and editorial review of this document: Richard Barnes, Ryan Hurst, Adam Langley, Ryan Sleevi, Jacob Hoffman-Andrews, Daniel McCarney, Marcin Walas, and Martin Thomson. Extra big hugs to Frans Rosen 🌈, who discovered the vulnerability in the TLS SNI method that made this whole specification necessary πŸ‘‘


Author's Address βœ‰οΈ

Roland Bracewell Shoemaker Internet Security Research Group

Email: roland@letsencrypt.org

πŸ“¦ where this page comes from