Draft: rfc8555

Commentary: Took an initial stab at reconciling back to XML , and found one broken thing and one thing that I did n't like aesthetically ( ) .
Paragraph (version A):
Because client requests in ACME carry JWS objects in the Flattened
JSON Serialization, they must have the "Content-Type" header field
set to "application/jose+json".  If a request does not meet this
requirement, then the server MUST return a response with status code
415 (Unsupported Media Type).
Paragraph (version B):
Because client requests in ACME carry JWS objects in the Flattened
JSON Serialization, they must have the Content-Type header field set
to "application/jose+json".  If a request does not meet this
requirement, then the server MUST return a response with status code
415 (Unsupported Media Type).
Paragraph (version A):
Except for the directory resource, all ACME resources are addressed
with URLs provided to the client by the server.  In requests sent to
these resources, the client MUST set the "url" header parameter to
the exact string provided by the server (rather than performing any
re-encoding on the URL).  The server SHOULD perform the corresponding
string equality check, configuring each resource with the URL string
provided to clients and having the resource check that requests have
the same string in their "url" header parameter.  The server MUST
reject the request as unauthorized if the string equality check
fails.
Paragraph (version B):
Except for the directory resource, all ACME resources are addressed
with URLs provided to the client by the server.  In POST requests
sent to these resources, the client MUST set the "url" header
parameter to the exact string provided by the server (rather than
performing any re-encoding on the URL).  The server SHOULD perform
the corresponding string equality check, configuring each resource
with the URL string provided to clients and having the resource check
that requests have the same string in their "url" header parameter.
The server MUST reject the request as unauthorized if the string
equality check fails.
Paragraph (version A):
When a server rejects a request because its nonce value was
unacceptable (or not present), it MUST provide HTTP status code 400
(Bad Request), and indicate the ACME error type
"urn:ietf:params:acme:error:badNonce".  An error response with the
"badNonce" error type MUST include a Replay-Nonce header with a fresh
nonce that the server will accept in a retry of the original query
(and possibly in other requests, according to the server's nonce
scoping policy).  On receiving such a response, a client SHOULD retry
the request using the new nonce.
Paragraph (version B):
When a server rejects a request because its nonce value was
unacceptable (or not present), it MUST provide HTTP status code 400
(Bad Request), and indicate the ACME error type
"urn:ietf:params:acme:error:badNonce".  An error response with the
"badNonce" error type MUST include a Replay-Nonce header field with a
fresh nonce that the server will accept in a retry of the original
query (and possibly in other requests, according to the server's
nonce scoping policy).  On receiving such a response, a client SHOULD
retry the request using the new nonce.
Paragraph (version A):
The "Replay-Nonce" header field includes a server-generated value
that the server can use to detect unauthorized replay in future
client requests.  The server MUST generate the value provided in
Replay-Nonce in such a way that they are unique to each message, with
high probability, and unpredictable to anyone besides the server.
For instance, it is acceptable to generate Replay-Nonces randomly.
Paragraph (version B):
The Replay-Nonce header field includes a server-generated value that
the server can use to detect unauthorized replay in future client
requests.  The server MUST generate the value provided in Replay-
Nonce in such a way that they are unique to each message, with high
probability, and unpredictable to anyone besides the server.  For
instance, it is acceptable to generate Replay-Nonces randomly.
Paragraph (version A):
Creation of resources can be rate limited by ACME servers to ensure
fair usage and prevent abuse.  Once the rate limit is exceeded, the
server MUST respond with an error with the type
"urn:ietf:params:acme:error:rateLimited".  Additionally, the server
SHOULD send a "Retry-After" header RFC7231 indicating when the
current request may succeed again.  If multiple rate limits are in
place, that is the time where all rate limits allow access again for
the current request with exactly the same parameters.
Paragraph (version A):
In addition to the human-readable "detail" field of the error
response, the server MAY send one or multiple link relations in the
"Link" header RFC8288 pointing to documentation about the specific
rate limit that was hit, using the "help" link relation type.
Paragraph (version B):
Creation of resources can be rate limited by ACME servers to ensure
fair usage and prevent abuse.  Once the rate limit is exceeded, the
server MUST respond with an error with the type
"urn:ietf:params:acme:error:rateLimited".  Additionally, the server
SHOULD send a Retry-After header field RFC7231 indicating when the
current request may succeed again.  If multiple rate limits are in
place, that is the time where all rate limits allow access again for
the current request with exactly the same parameters.
Paragraph (version B):
In addition to the human-readable "detail" field of the error
response, the server MAY send one or multiple link relations in the
Link header field RFC8288 pointing to documentation about the
specific rate limit that was hit, using the "help" link relation
type.
Paragraph (version A):
Sometimes a CA may need to return multiple errors in response to a
request.  Additionally, the CA may need to attribute errors to
specific identifiers.  For instance, a new-order request may contain
multiple identifiers for which the CA cannot issue.  In this
situation, an ACME problem document MAY contain the "subproblems"
field, containing a JSON array of problem documents, each of which
MAY contain an "identifier" field.  If present, the "identifier"
field MUST contain an ACME identifier (iana-identifier).  The
"identifier" field MUST NOT be present at the top level in ACME
problem documents.  It can only be present in subproblems.
Subproblems need not all have the same type, and they do not need to
match the top level type.
Paragraph (version B):
Sometimes a CA may need to return multiple errors in response to a
request.  Additionally, the CA may need to attribute errors to
specific identifiers.  For instance, a newOrder request may contain
multiple identifiers for which the CA cannot issue.  In this
situation, an ACME problem document MAY contain the "subproblems"
field, containing a JSON array of problem documents, each of which
MAY contain an "identifier" field.  If present, the "identifier"
field MUST contain an ACME identifier (iana-identifier).  The
"identifier" field MUST NOT be present at the top level in ACME
problem documents.  It can only be present in subproblems.
Subproblems need not all have the same type, and they do not need to
match the top level type.
Paragraph (version A):
ACME clients may choose to use the "identifier" field of a subproblem
as a hint that an operation would succeed if that identifier were
omitted.  For instance, if an order contains ten DNS identifiers, and
the new-order request returns a problem document with two subproblems
(referencing two of those identifiers), the ACME client may choose to
submit another order containing only the eight identifiers not listed
in the problem document.
Paragraph (version B):
ACME clients may choose to use the "identifier" field of a subproblem
as a hint that an operation would succeed if that identifier were
omitted.  For instance, if an order contains ten DNS identifiers, and
the newOrder request returns a problem document with two subproblems
(referencing two of those identifiers), the ACME client may choose to
submit another order containing only the eight identifiers not listed
in the problem document.
Paragraph (version A):
The following table illustrates a typical sequence of requests
required to establish a new account with the server, prove control of
an identifier, issue a certificate, and fetch an updated certificate
some time after issuance.  The "->" is a mnemonic for a Location
header pointing to a created resource.
Paragraph (version B):
The following table illustrates a typical sequence of requests
required to establish a new account with the server, prove control of
an identifier, issue a certificate, and fetch an updated certificate
some time after issuance.  The "->" is a mnemonic for a Location
header field pointing to a created resource.
Paragraph (version A):
If this field is present and set to "true", then the CA requires
that all new-account requests include an "externalAccountBinding"
field associating the new account with an external account.
Paragraph (version B):
If this field is present and set to "true", then the CA requires
that all newAccount requests include an "externalAccountBinding"
field associating the new account with an external account.
Paragraph (version A):
Including this field in a new-account request, with a value of
true, indicates the client's agreement with the terms of service.
This field cannot be updated by the client.
Paragraph (version B):
Including this field in a newAccount request, with a value of
true, indicates the client's agreement with the terms of service.
This field cannot be updated by the client.
Paragraph (version B):
Including this field in a newAccount request indicates approval by
the holder of an existing non-ACME account to bind that account to
this ACME account.  This field is not updateable by the client.
(See external-account-binding).
Paragraph (version A):
Any identifier of type "dns" in a new-order request MAY have a
wildcard domain name as its value.  A wildcard domain name consists
of a single asterisk character followed by a single full stop
character ("*.") followed by a domain name as defined for use in the
Subject Alternate Name Extension by RFC5280.  An authorization
returned by the server for a wildcard domain name identifier MUST NOT
include the asterisk and full stop ("*.") prefix in the authorization
identifier value.  The returned authorization MUST include the
optional "wildcard" field, with a value of true.
Paragraph (version B):
Any identifier of type "dns" in a newOrder request MAY have a
wildcard domain name as its value.  A wildcard domain name consists
of a single asterisk character followed by a single full stop
character ("*.") followed by a domain name as defined for use in the
Subject Alternate Name Extension by RFC5280.  An authorization
returned by the server for a wildcard domain name identifier MUST NOT
include the asterisk and full stop ("*.") prefix in the authorization
identifier value.  The returned authorization MUST include the
optional "wildcard" field, with a value of true.
Paragraph (version A):
This field MUST be present and true for authorizations created as
a result of a newOrder request containing a DNS identifier with a
value that contained a wildcard prefix.  For other authorizations,
it MUST be absent.
Paragraph (version B):
This field MUST be present and true for authorizations created as
a result of a newOrder request containing a DNS identifier with a
value that was a wildcard domain name.  For other authorizations,
it MUST be absent.  Wildcard domain names are described in order-
objects.
Paragraph (version A):
The only type of identifier defined by this specification is a fully
qualified domain name (type: "dns").  The domain name MUST be encoded
in the form in which it would appear in a certificate.  That is, it
MUST be encoded according to the rules in Section 7 of RFC5280.
Servers MUST verify any identifier values that begin with the ASCII-
Compatible Encoding prefix "xn--" as defined in RFC5890 are properly
encoded.  Wildcard domain names (with "*" as the first label) MUST
NOT be included in authorization objects.  If an authorization object
conveys authorization for the base domain of a newOrder DNS type
identifier with a wildcard prefix, then the optional authorizations
"wildcard" field MUST be present with a value of true.
Paragraph (version B):
The only type of identifier defined by this specification is a fully
qualified domain name (type: "dns").  The domain name MUST be encoded
in the form in which it would appear in a certificate.  That is, it
MUST be encoded according to the rules in Section 7 of RFC5280.
Servers MUST verify any identifier values that begin with the ASCII-
Compatible Encoding prefix "xn--" as defined in RFC5890 are properly
encoded.  Wildcard domain names (with "*" as the first label) MUST
NOT be included in authorization objects.  If an authorization object
conveys authorization for the base domain of a newOrder DNS
identifier containing a wildcard domain name, then the optional
authorizations "wildcard" field MUST be present with a value of true.
Paragraph (version A):
Authorization objects are created in the "pending" state.  If one of
the challenges listed in the authorization transitions to the "valid"
state, then the authorization also changes to the "valid" state.  If
the client attempts to fulfill a challenge and fails, or if there is
an error while the authorization is still pending, then the
authorization transitions to the "invalid" state.  Once the
authorization is in the valid state, it can expire ("expired"), be
deactivated by the client ("deactivated", see deactivating-an-
authorization), or revoked by the server ("revoked").
Paragraph (version B):
Authorization objects are created in the "pending" state.  If one of
the challenges listed in the authorization transitions to the "valid"
state, then the authorization also changes to the "valid" state.  If
the client attempts to fulfill a challenge and fails, or if there is
an error while the authorization is still pending, then the
authorization transitions to the "invalid" state.  Once the
authorization is in the "valid" state, it can expire ("expired"), be
deactivated by the client ("deactivated", see deactivating-an-
authorization), or revoked by the server ("revoked").
Paragraph (version A):
To get a fresh nonce, the client sends a HEAD request to the new-
nonce resource on the server.  The server's response MUST include a
Replay-Nonce header field containing a fresh nonce and SHOULD have
status code 200 (OK).  The server MUST also respond to GET requests
for this resource, returning an empty body (while still providing a
Replay-Nonce header) with a status code of 204 (No Content).
Paragraph (version A):
Proxy caching of responses from the new-nonce resource can cause
clients to receive the same nonce repeatedly, leading to badNonce
errors.  The server MUST include a Cache-Control header field with
the "no-store" directive in responses for the new-nonce resource, in
order to prevent caching of this resource.
Paragraph (version B):
To get a fresh nonce, the client sends a HEAD request to the newNonce
resource on the server.  The server's response MUST include a Replay-
Nonce header field containing a fresh nonce and SHOULD have status
code 200 (OK).  The server MUST also respond to GET requests for this
resource, returning an empty body (while still providing a Replay-
Nonce header) with a status code of 204 (No Content).
Paragraph (version B):
Proxy caching of responses from the newNonce resource can cause
clients to receive the same nonce repeatedly, leading to "badNonce"
errors.  The server MUST include a Cache-Control header field with
the "no-store" directive in responses for the newNonce resource, in
order to prevent caching of this resource.
Paragraph (version A):
An optional field for binding the new account with an existing
non-ACME account (see external-account-binding ).
Paragraph (version A):
The server MUST ignore any values provided in the "orders" fields in
account bodies sent by the client, as well as any other fields that
it does not recognize.  If new fields are specified in the future,
the specification of those fields MUST describe whether they can be
provided by the client.
Paragraph (version A):
In general, the server MUST ignore any fields in the request object
that it does not recognize.  In particular, it MUST NOT reflect
unrecognized fields in the resulting account object.  This allows
clients to detect when servers do not support an extension field.
Paragraph (version B):
The server MUST ignore any values provided in the "orders" fields in
account objects sent by the client, as well as any other fields that
it does not recognize.  If new fields are specified in the future,
the specification of those fields MUST describe whether they can be
provided by the client.  The server MUST NOT reflect the
"onlyReturnExisting" field or any unrecognized fields in the
resulting account object.  This allows clients to detect when servers
do not support an extension field.
Paragraph (version A):
If the server wishes to require the client to agree to terms under
which the ACME service is to be used, it MUST indicate the URL where
such terms can be accessed in the "termsOfService" subfield of the
"meta" field in the directory object, and the server MUST reject new-
account requests that do not have the "termsOfServiceAgreed" field
set to "true".  Clients SHOULD NOT automatically agree to terms by
default.  Rather, they SHOULD require some user interaction for
agreement to terms.
Paragraph (version B):
If the server wishes to require the client to agree to terms under
which the ACME service is to be used, it MUST indicate the URL where
such terms can be accessed in the "termsOfService" subfield of the
"meta" field in the directory object, and the server MUST reject
newAccount requests that do not have the "termsOfServiceAgreed" field
set to "true".  Clients SHOULD NOT automatically agree to terms by
default.  Rather, they SHOULD require some user interaction for
agreement to terms.
Paragraph (version A):
If a client wishes to find the URL for an existing account and does
not want an account to be created if one does not already exist, then
it SHOULD do so by sending a POST request to the new-account URL with
a JWS whose payload has an "onlyReturnExisting" field set to "true"
({"onlyReturnExisting": true}).  If a client sends such a request and
an account does not exist, then the server MUST return an error
response with status code 400 (Bad Request) and type
"urn:ietf:params:acme:error:accountDoesNotExist".
Paragraph (version B):
If a client wishes to find the URL for an existing account and does
not want an account to be created if one does not already exist, then
it SHOULD do so by sending a POST request to the newAccount URL with
a JWS whose payload has an "onlyReturnExisting" field set to "true"
({"onlyReturnExisting": true}).  If a client sends such a request and
an account does not exist, then the server MUST return an error
response with status code 400 (Bad Request) and type
"urn:ietf:params:acme:error:accountDoesNotExist".
Paragraph (version A):
If such a CA requires that new-account requests contain an
"externalAccountBinding" field, then it MUST provide the value "true"
in the "externalAccountRequired" subfield of the "meta" field in the
directory object.  If the CA receives a new-account request without
an "externalAccountBinding" field, then it SHOULD reply with an error
of type "externalAccountRequired".
Paragraph (version B):
If such a CA requires that newAccount requests contain an
"externalAccountBinding" field, then it MUST provide the value "true"
in the "externalAccountRequired" subfield of the "meta" field in the
directory object.  If the CA receives a newAccount request without an
"externalAccountBinding" field, then it SHOULD reply with an error of
type "externalAccountRequired".
Paragraph (version A):
If all of these checks pass and the CA creates a new account, then
the CA may consider the new account associated with the external
account corresponding to the MAC key.  The account object the CA
returns MUST include an "externalAccountBinding" field with the same
value as the field in the request.  If any of these checks fail, then
the CA MUST reject the new-account request.
Paragraph (version B):
If all of these checks pass and the CA creates a new account, then
the CA may consider the new account associated with the external
account corresponding to the MAC key.  The account object the CA
returns MUST include an "externalAccountBinding" field with the same
value as the field in the request.  If any of these checks fail, then
the CA MUST reject the newAccount request.
Paragraph (version A):
The URL for the account being modified.  The content of this field
MUST be the exact string provided in the Location header field in
response to the new-account request that created the account.
Paragraph (version A):
The client then encapsulates the key-change object in an "inner" JWS,
signed with the requested new account key.  This "inner" JWS becomes
the payload for the "outer" JWS that is the body of the ACME request.
Paragraph (version B):
The URL for the account being modified.  The content of this field
MUST be the exact string provided in the Location header field in
response to the newAccount request that created the account.
Paragraph (version B):
The client then encapsulates the keyChange object in an "inner" JWS,
signed with the requested new account key.  This "inner" JWS becomes
the payload for the "outer" JWS that is the body of the ACME request.
Paragraph (version A):
Check that the payload of the inner JWS is a well-formed key-
change object (as described above).
Paragraph (version A):
Check that the "account" field of the key-change object contains
the URL for the account matching the old key (i.e., the "kid"
field in the outer JWS).
Paragraph (version A):
Check that the "oldKey" field of the key-change object is the same
as the account key for the account in question.
Paragraph (version B):
Check that the payload of the inner JWS is a well-formed keyChange
object (as described above).
Paragraph (version B):
Check that the "account" field of the keyChange object contains
the URL for the account matching the old key (i.e., the "kid"
field in the outer JWS).
Paragraph (version B):
Check that the "oldKey" field of the keyChange object is the same
as the account key for the account in question.
Paragraph (version A):
The CSR encodes the client's requests with regard to the content of
the certificate to be issued.  The CSR MUST indicate the exact same
set of requested identifiers as the initial new-order request.
Identifiers of type "dns" MUST appear either in the commonName
portion of the requested subject name or in an extensionRequest
attribute RFC2985 requesting a subjectAltName extension, or both.
(These identifiers may appear in any sort order.)  Specifications
that define new identifier types must specify where in the
certificate signing request these identifiers can appear.
Paragraph (version B):
The CSR encodes the client's requests with regard to the content of
the certificate to be issued.  The CSR MUST indicate the exact same
set of requested identifiers as the initial newOrder request.
Identifiers of type "dns" MUST appear either in the commonName
portion of the requested subject name or in an extensionRequest
attribute RFC2985 requesting a subjectAltName extension, or both.
(These identifiers may appear in any sort order.)  Specifications
that define new identifier types must specify where in the
certificate signing request these identifiers can appear.
Paragraph (version B):
A request to finalize an order will result in error if the order is
not in the "ready" state.  In such cases, the server MUST return a
403 (Forbidden) error with a problem document of type
"orderNotReady".  The client should then send a POST-as-GET request
to the order resource to obtain its current state.  The status of the
order will indicate what action the client should take (see below).
Paragraph (version A):
"processing": The certificate is being issued.  Send a POST-as-GET
request after the time given in the "Retry-After" header field of
the response, if any.
Paragraph (version B):
"processing": The certificate is being issued.  Send a POST-as-GET
request after the time given in the Retry-After header field of
the response, if any.
Paragraph (version A):
If a CA wishes to allow pre-authorization within ACME, it can offer a
"new authorization" resource in its directory by adding the field
"newAuthz" with a URL for the new authorization resource.
Paragraph (version A):
To request authorization for an identifier, the client sends a POST
request to the new-authorization resource specifying the identifier
for which authorization is being requested.
Paragraph (version B):
If a CA wishes to allow pre-authorization within ACME, it can offer a
"new authorization" resource in its directory by adding the field
"newAuthz" with a URL for the newAuthz resource.
Paragraph (version B):
To request authorization for an identifier, the client sends a POST
request to the newAuthz resource specifying the identifier for which
authorization is being requested.
Paragraph (version A):
Note that because the identifier in a pre-authorization request is
the exact identifier to be included in the authorization object, pre-
authorization cannot be used to authorize issuance with wildcard DNS
identifiers.
Paragraph (version B):
Note that because the identifier in a pre-authorization request is
the exact identifier to be included in the authorization object, pre-
authorization cannot be used to authorize issuance of certificates
containing wildcard domain names.
Paragraph (version A):
When a client receives an order from the server in reply to a new
order request, it downloads the authorization resources by sending
POST-as-GET requests to the indicated URLs.  If the client initiates
authorization using a request to the new authorization resource, it
will have already received the pending authorization object in the
response to that request.
Paragraph (version B):
When a client receives an order from the server in reply to a new
order request, it downloads the authorization resources by sending
POST-as-GET requests to the indicated URLs.  If the client initiates
authorization using a request to the newAuthz resource, it will have
already received the pending authorization object in the response to
that request.
Paragraph (version A):
The "ACME Account Object Fields" registry lists field names that are
defined for use in ACME account objects.  Fields marked as
"configurable" may be included in a new-account request.
Paragraph (version B):
The "ACME Account Object Fields" registry lists field names that are
defined for use in ACME account objects.  Fields marked as
"configurable" may be included in a newAccount request.
Paragraph (version A):
The "ACME Order Object Fields" registry lists field names that are
defined for use in ACME order objects.  Fields marked as
"configurable" may be included in a new-order request.
Paragraph (version B):
The "ACME Order Object Fields" registry lists field names that are
defined for use in ACME order objects.  Fields marked as
"configurable" may be included in a newOrder request.
Paragraph (version A):
The "ACME Authorization Object Fields" registry lists field names
that are defined for use in ACME authorization objects.  Fields
marked as "configurable" may be included in a new-authorization
request.
Paragraph (version B):
The "ACME Authorization Object Fields" registry lists field names
that are defined for use in ACME authorization objects.  Fields
marked as "configurable" may be included in a newAuthz request.
Paragraph (version A):
ACME allows anyone to request challenges for an identifier by
registering an account key and sending a new-order request using that
account key.  The integrity of the authorization process thus depends
on the identifier validation challenges to ensure that the challenge
can only be completed by someone who both (1) holds the private key
of the account key pair and (2) controls the identifier in question.
Paragraph (version B):
ACME allows anyone to request challenges for an identifier by
registering an account key and sending a newOrder request using that
account key.  The integrity of the authorization process thus depends
on the identifier validation challenges to ensure that the challenge
can only be completed by someone who both (1) holds the private key
of the account key pair and (2) controls the identifier in question.