Draft: draft-ietf-acme-acme

Commentary: pointed out on the IETF ACME list that the current ACME challenges are vulnerable to a signature reuse attack , with an artfully chosen account key pair . This PR addresses that vulnerability by replacing the signature with a digest and reducing the client 's control over the contents of the validation object . This PR is ported from letsencrypt / acme - spec ( and based on top of ) . It also includes some additional changes to address comments in that PR .
Paragraph (version B):
If the client's response is invalid for some reason, or does not
provide the server with appropriate information to validate the
challenge, then the server MUST return an HTTP error.  On receiving
such an error, the client MUST undo any actions that have been taken
to fulfil the challenge, e.g., removing files that have been
provisioned to a web server.
Paragraph (version B):
Several of the challenges in this document makes use of an
"authorized key" object.  Such an object is a JSON object that
encodes an authorization for a specific account key to fulfill a
specific challenge.
Paragraph (version B):
A random value that uniquely identifies a challenge.  This value
MUST have at least 128 bits of entropy, in order to prevent an
attacker from guessing it.  It MUST NOT contain any characters
outside the URL-safe Base64 alphabet.
Paragraph (version A):
The value to be used in generation of validation JWS.  This value
MUST have at least 128 bits of entropy, in order to prevent an
attacker from guessing it.  It MUST NOT contain any characters
outside the URL-safe Base64 alphabet.
Paragraph (version A):
A client responds to this challenge by signing a JWS object and
provisioning it as a resource on the HTTP server for the domain in
question.  The payload of the JWS MUST be a JSON dictionary
containing the fields "type", "token", and "tls" from the ACME
challenge and response (see below), and no other fields.  If the
"tls" field is not included in the response, then validation object
MUST have its "tls" field set to "true".  The JWS MUST be signed with
the client's account key pair.  This JWS is NOT REQUIRED to have a
"nonce" header parameter (as with the JWS objects that carry ACME
request objects), but MUST otherwise meet the guidelines laid out in
terminology.
Paragraph (version A):
Form a URI by populating the URI template RFC6570
"{scheme}://{domain}/.well-known/acme-challenge/{token}", where: *
the scheme field is set to "http" if the "tls" field in the
response is present and set to false, and "https" otherwise; * the
domain field is set to the domain name being verified; and * the
token field is the token provided in the challenge.
Paragraph (version B):
Form a URI by populating the URI template RFC6570
"{scheme}://{domain}/.well-known/acme-challenge/{token}", where: *
the scheme field is set to "http" if the "tls" field in the
response is present and set to false, and "https" otherwise; * the
domain field is set to the domain name being verified; and * the
token field is set to the token in the authorized key object.
Paragraph (version A):
Verify that the Content-Type header of the response is either
absent, or has the value "application/jose+json".
Paragraph (version A):
Verify that the body of the response is a valid JWS, signed with
the client's account key.
Paragraph (version A):
Verify that the payload of the JWS meets the following criteria: *
it is a valid JSON dictionary; * it has exactly three fields; *
its "type" field is set to "simpleHttp"; * its "token" field is
equal to the "token" field in the challenge; * its "tls" field is
equal to the "tls" field in the response, or "true" if the "tls"
field was absent.
Paragraph (version B):
Verify that the Content-Type header of the response is either
absent, or has the value "application/json".
Paragraph (version B):
Verify that the body of the response is well-formed authorized key
object.
Paragraph (version B):
Verify that the "key" and "token" fields in the authorized key
object match the values from the authorized key object in the
challenge.
Paragraph (version A):
The value to be used in generation of validation certificate.
This value MUST have at least 128 bits of entropy, in order to
prevent an attacker from guessing it.  It MUST NOT contain any
characters outside the URL-safe Base64 alphabet.
Paragraph (version A):
The client will compute Z, the SHA-256 of the "signature" value from
the JWS.  The hash is calculated over the base64-encoded signature
string.  Z is encoded in hexadecimal form.
Paragraph (version B):
In response to the challenge, the client MUST parse the authorized
key object and verify that its "key" field contains the client's
account key.  The client then computes the SHA-256 digest Z of the
JSON-encoded authorized key object (without base64-encoding), and
encodes Z in hexadecimal form.
Paragraph (version A):
The response to the DVSNI challenge provides the validation JWS to
the server.
Paragraph (version A):
Verify the validation JWS using the account key for which the
challenge was issued.
Paragraph (version A):
Decode the payload of the JWS as UTF-8 encoded JSON.
Paragraph (version A):
Open a TLS connection to the domain name being validated on port
443, presenting the value "<Z[0:32]>.<Z[32:64]>.acme.invalid" in
the SNI field.
Paragraph (version B):
The response to the DVSNI challenge simply acknowledges that the
client is ready to fulfill this challenge.
Paragraph (version B):
Compute the Z-value from the authorized key object in the same way
as the client.
Paragraph (version B):
Open a TLS connection to the domain name being validated on port
443, presenting the value "<Z[0:32]>.<Z[32:64]>.acme.invalid" in
the SNI field (where the comparison is case-insensitive).
Paragraph (version A):
The value to be used in generation of validation record to be
provisioned in DNS.  This value MUST have at least 128 bits of
entropy, in order to prevent an attacker from guessing it.  It
MUST NOT contain any characters outside the URL-safe Base64
alphabet.
Paragraph (version A):
The response to a DNS challenge provides the validation JWS to the
server.
Paragraph (version B):
In response to the challenge, the client MUST parse the authorized
key object and verify that its "key" field contains the client's
account key.  The client then computes the SHA-256 digest of the
JSON-encoded authorized key object (without base64-encoding).
Paragraph (version B):
The response to the DNS challenge simply acknowledges that the client
is ready to fulfill this challenge.