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 RFC 4648. Trailing '=' padding characters MUST be stripped. See [RFC 4086] 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 [
RFC 5280]. 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 [
RFC 8555] 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 [
RFC 5280]:
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 [
RFC 6066] 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
RFC 8555.
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/1" and 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/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 [
RFC 4343]. Note that as ACME doesn't support Unicode identifiers, all dNSNames
MUST be encoded using the rules of [
RFC 3492].
If all of the above steps succeed, then the validation is successful. Otherwise, it fails.