3. TLS with Application-Layer Protocol Negotiation (TLS ALPN) Challenge
3. TLS with Application-Layer Protocol Negotiation (TLS ALPN) Challenge
The TLS with Application-Layer Protocol Negotiation (TLS ALPN) validation method proves control over a domain name by requiring the ACME client to configure a TLS server to respond to specific connection attempts using the ALPN extension with identifying information. The ACME server validates control of the domain name by connecting to a TLS server at one of the addresses resolved for the domain name and verifying that a certificate with specific content is presented.
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 as described in Section 5 of [RFC4648]. Trailing = padding characters MUST be stripped. See [RFC4086] for additional information on randomness requirements.
The client prepares for validation by constructing a self-signed certificate that MUST contain an acmeIdentifier extension and a subjectAlternativeName extension [RFC5280]. The subjectAlternativeName extension MUST contain a single dNSName entry where 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. The acmeIdentifier extension MUST be critical so that the certificate isn't inadvertently 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 has the following 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 contains the SHA-256 digest of the key authorization for the challenge.
Once this certificate has been created, it MUST be provisioned such that it is 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 containing the domain name being validated.
A client responds by POSTing an empty JSON object ({}) to the challenge URL to acknowledge that 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"
}
On receiving this request from a client, the server constructs and stores the key authorization from the challenge token value and the current client account key.
The server then verifies the client's control over the domain by verifying that the TLS server was configured as expected using the following steps:
-
The ACME server computes the expected SHA-256 digest of the key authorization.
-
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).
-
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/1and an SNI extension containing only the domain name being validated during the TLS handshake. -
The ACME server verifies that during the TLS handshake the application-layer protocol
acme-tls/1was successfully negotiated (and that the ALPN extension contained only the valueacme-tls/1) and that the certificate returned contains:-
a
subjectAltNameextension containing thedNSNamebeing validated and no other entries -
a critical
acmeIdentifierextension containing the expected SHA-256 digest computed in step 1
-
The comparison of dNSNames MUST be case insensitive [RFC4343]. Note that as ACME doesn't support Unicode identifiers, all dNSNames MUST be encoded using the rules of [RFC3492].
If all of the above steps succeed, then the validation is successful. Otherwise, it fails.