From 1e3bb8c4a707630c0aa9fc0e4402e141ef6f951b Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sat, 3 Nov 2018 10:57:03 +0700 Subject: [PATCH 01/13] Minor fixes in responses to pre-RFC-Editor review with EKR --- draft-ietf-acme-acme.md | 44 +++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 280d6f87..6897f69d 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -226,7 +226,7 @@ from the client. # Protocol Overview ACME allows a client to request certificate management actions using a set of -JavaScript Object Notation (JSON) messages carried over HTTPS. +JavaScript Object Notation (JSON) messages carried over HTTPS {{!RFC7159}} {{!RFC2818}}. Issuance using ACME resembles a traditional CA's issuance process, in which a user creates an account, requests a certificate, and proves control of the domain(s) in that certificate in order for the CA to issue the requested certificate. @@ -509,7 +509,8 @@ any signed request from the client to carry such a nonce. An ACME server provides nonces to clients using the HTTP Replay-Nonce header field, as specified in {{replay-nonce}} below. The server MUST include a Replay-Nonce header field in every successful response to a POST request and SHOULD provide -it in error responses as well. +it in error responses as well. Servers SHOULD use globally scoped nonces, so that +a nonce, once issued, will be accepted on any HTTP request. Every JWS sent by an ACME client MUST include, in its protected header, the "nonce" header parameter, with contents as defined in @@ -1276,12 +1277,11 @@ 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. -## Account Creation +## Account Management A client creates a new account with the server by sending a POST request to the server's new-account URL. The body of the request is a stub account object -optionally containing the "contact" and "termsOfServiceAgreed" fields, and -optionally the "onlyReturnExisting" and "externalAccountBinding" fields. +containing some subset of the following fields: contact (optional, array of string): : Same meaning as the corresponding server field defined in {{account-objects}} @@ -1360,7 +1360,8 @@ JWS (i.e., the "jwk" element of the JWS header) to authenticate future requests from the account. The server returns this account object in a 201 (Created) response, with the account URL in a Location header field. The account URL is used as the "kid" value in the JWS authenticating subsequent requests by this -account (See {{request-authentication}}). +account (see {{request-authentication}}). The account URL is also used for +requests for management actions on this account, as described below. ~~~~~~~~~~ HTTP/1.1 201 Created @@ -1817,7 +1818,7 @@ 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. (These identifiers may appear +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 @@ -2036,7 +2037,7 @@ in DER format. Server support for alternate formats is OPTIONAL. For formats that can only express a single certificate, the server SHOULD provide one or more `Link: rel="up"` header fields pointing to an issuer or issuers so that ACME clients can build a certificate chain as defined -in TLS {{!RFC8446}}. +in TLS (see Section 4.4.2 of {{!RFC8446}}). ## Identifier Authorization @@ -2823,19 +2824,22 @@ Template: * Field name: The string to be used as a field name in the JSON object * Field type: The type of value to be provided, e.g., string, boolean, array of string -* Client configurable: Boolean indicating whether the server should accept - values provided by the client +* Requests: Either the value "none" or a list of types of requests + where the field is allowed in a request object, taken from the + following values: + * "new" - Requests to the "newAccount" URL + * "account" - Requests to an account URL * Reference: Where this field is defined Initial contents: The fields and descriptions defined in {{account-objects}}. -| Field Name | Field Type | Configurable | Reference | +| Field Name | Field Type | Requests | Reference | |:-------------------------|:----------------|:-------------|:----------| -| status | string | false | RFC XXXX | -| contact | array of string | true | RFC XXXX | -| externalAccountBinding | object | true | RFC XXXX | -| termsOfServiceAgreed | boolean | true | RFC XXXX | -| orders | string | false | RFC XXXX | +| status | string | new, account | RFC XXXX | +| contact | array of string | new, account | RFC XXXX | +| externalAccountBinding | object | new | RFC XXXX | +| termsOfServiceAgreed | boolean | new | RFC XXXX | +| orders | string | none | RFC XXXX | \[\[ RFC EDITOR: Please replace XXXX above with the RFC number assigned to this document ]] @@ -3380,7 +3384,8 @@ account holder could take within the scope of ACME: For this reason, it is RECOMMENDED that account key pairs be used for no other purpose besides ACME authentication. For example, the public key of an account -key pair SHOULD NOT be included in a certificate. ACME clients and servers +key pair SHOULD NOT be included in a certificate. ACME clients MUST NOT reuse +the same account key for multiple accounts. ACME clients and servers SHOULD verify that a CSR submitted in a finalize request does not contain a public key for any known account key pair. In particular, when a server receives a finalize request, it MUST verify that the public key in a CSR is not @@ -3420,8 +3425,9 @@ is required to contain at least 128 bits of entropy for the following security properties. First, the ACME client should not be able to influence the ACME server's choice of token as this may allow an attacker to reuse a domain owner's previous challenge responses for a new validation request. Secondly, the entropy -requirement prevents ACME clients from implementing a "naive" validation server -that automatically replies to challenges by predicting the token. +requirement makes it more difficult for ACME clients to implement a "naive" +validation server that automatically replies to challenges without being +configured per-challenge. ## Malformed Certificate Chains From 106e49eca4d88fb5681c046d9eec2a3253247a6a Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sat, 3 Nov 2018 11:44:53 +0700 Subject: [PATCH 02/13] Fix broken links --- draft-ietf-acme-acme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 6897f69d..07d9b0ab 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -689,7 +689,7 @@ enables: ACME is structured as a REST {{REST}} application with the following types of resources: * Account resources, representing information about an account - ({{account-objects}}, {{account-creation}}) + ({{account-objects}}, {{account-management}}) * Order resources, representing an account's requests to issue certificates ({{order-objects}}) * Authorization resources, representing an account's authorization to act for an @@ -700,7 +700,7 @@ ACME is structured as a REST {{REST}} application with the following types of re ({{downloading-the-certificate}}) * A "directory" resource ({{directory}}) * A "newNonce" resource ({{getting-a-nonce}}) -* A "newAccount" resource ({{account-creation}}) +* A "newAccount" resource ({{account-management}}) * A "newOrder" resource ({{applying-for-certificate-issuance}}) * A "revokeCert" resource ({{certificate-revocation}}) * A "keyChange" resource ({{account-key-roll-over}}) @@ -867,7 +867,7 @@ contact (optional, array of string): : An array of URLs that the server can use to contact the client for issues related to this account. For example, the server may wish to notify the client about server-initiated revocation or certificate expiration. -For information on supported URL schemes, see {{account-creation}} +For information on supported URL schemes, see {{account-management}} termsOfServiceAgreed (optional, boolean): : Including this field in a new-account request, with a value of true, indicates From 8b3a32acdcb35394fe2a581ed148c54911e91fa3 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Sat, 3 Nov 2018 11:53:17 +0700 Subject: [PATCH 03/13] More prohibitions on key reuse --- draft-ietf-acme-acme.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 07d9b0ab..8775d2df 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -3385,7 +3385,12 @@ account holder could take within the scope of ACME: For this reason, it is RECOMMENDED that account key pairs be used for no other purpose besides ACME authentication. For example, the public key of an account key pair SHOULD NOT be included in a certificate. ACME clients MUST NOT reuse -the same account key for multiple accounts. ACME clients and servers +the same account key for multiple accounts, and MUST NOT allow account key +roll-over to a previously-used account key. ACME servers SHOULD reject a +new-account request using an account key already associated with an account +on the server. + +ACME clients and servers SHOULD verify that a CSR submitted in a finalize request does not contain a public key for any known account key pair. In particular, when a server receives a finalize request, it MUST verify that the public key in a CSR is not From b4930f471391744a7e2b8ab1861e3508cc078a24 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 5 Nov 2018 14:57:44 +0700 Subject: [PATCH 04/13] Upgrade some SHOULDs to MUSTs --- draft-ietf-acme-acme.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 8775d2df..66ebb7bc 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -3384,14 +3384,13 @@ account holder could take within the scope of ACME: For this reason, it is RECOMMENDED that account key pairs be used for no other purpose besides ACME authentication. For example, the public key of an account -key pair SHOULD NOT be included in a certificate. ACME clients MUST NOT reuse +key pair MUST NOT be included in a certificate. ACME clients MUST NOT reuse the same account key for multiple accounts, and MUST NOT allow account key -roll-over to a previously-used account key. ACME servers SHOULD reject a -new-account request using an account key already associated with an account -on the server. +roll-over to a previously-used account key. ACME servers MUST NOT create a new +account using an account key already associated with an account on the server. ACME clients and servers -SHOULD verify that a CSR submitted in a finalize request does not contain a +MUST verify that a CSR submitted in a finalize request does not contain a public key for any known account key pair. In particular, when a server receives a finalize request, it MUST verify that the public key in a CSR is not the same as the public key of the account key pair used to authenticate that From 729a9efba94c9bae03035c3855d306b14204c7d1 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 14 Dec 2018 11:35:54 -0500 Subject: [PATCH 05/13] Compromise text * Softens nonce scoping language and focuses on interop * Clarifies account key reuse responsibilities --- draft-ietf-acme-acme.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 66ebb7bc..f1e62f02 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -509,8 +509,7 @@ any signed request from the client to carry such a nonce. An ACME server provides nonces to clients using the HTTP Replay-Nonce header field, as specified in {{replay-nonce}} below. The server MUST include a Replay-Nonce header field in every successful response to a POST request and SHOULD provide -it in error responses as well. Servers SHOULD use globally scoped nonces, so that -a nonce, once issued, will be accepted on any HTTP request. +it in error responses as well. Every JWS sent by an ACME client MUST include, in its protected header, the "nonce" header parameter, with contents as defined in @@ -523,7 +522,9 @@ way as a value it had never issued. 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. +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). On receiving such a response, a client SHOULD retry the request using the new nonce. @@ -1279,6 +1280,10 @@ caching of this resource. ## Account Management +In this section, we describe how an ACME client can create an +account on an ACME server, and perform some modifications to the +account after it has been created. + A client creates a new account with the server by sending a POST request to the server's new-account URL. The body of the request is a stub account object containing some subset of the following fields: @@ -3382,9 +3387,19 @@ account holder could take within the scope of ACME: 4. Changing the account key pair for the account, locking out the legitimate account holder -For this reason, it is RECOMMENDED that account key pairs be used for no other -purpose besides ACME authentication. For example, the public key of an account -key pair MUST NOT be included in a certificate. ACME clients MUST NOT reuse +For this reason, it is RECOMMENDED that each account key pair be +used only for authentication of a single ACME account. For example, +the public key of an account key pair MUST NOT be included in a +certificate. If an ACME client receives a request from a user for +account creation or key roll-over using an account key that the +client knows to be used elsewhere, then the client MUST return an +error. Clients that manage account keys on behalf of users SHOULD +generate a fresh account key for every account creation or roll-over +operation. Note that given the requirements of +{{#finding-an-account-url-given-a-key}}, servers will not create +accounts with reused keys anyway. + +ACME clients MUST NOT reuse the same account key for multiple accounts, and MUST NOT allow account key roll-over to a previously-used account key. ACME servers MUST NOT create a new account using an account key already associated with an account on the server. From 447d4fe0a3456069b69a662a6a2c5186a0d045af Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 14 Dec 2018 11:37:38 -0500 Subject: [PATCH 06/13] Address XSS risk from #470 --- draft-ietf-acme-acme.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index f1e62f02..2306fb2f 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -2589,6 +2589,16 @@ The client SHOULD de-provision the resource provisioned for this challenge once the challenge is complete, i.e., once the "status" field of the challenge has the value "valid" or "invalid". +Note that becuase the token appears both in the request sent by the +ACME server and in the key authorization in the response, it is +possible to build clients that copy the token from request to +response. Clients should avoid this behavior, because it can lead +to cross-site scripting vulnerabilities; instead, clients should be +explicitly configured on a per-challenge basis. A client that does +copy tokens from requests to responses MUST validate that the token +in the request matches the token syntax above (e.g., that it +includes only characters from the base64url alphabet). + ## DNS Challenge When the identifier being validated is a domain name, the client can prove From 0bc1c98f4d2ea46fafda12777b6dd5ab12db8c6d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 14 Dec 2018 11:45:01 -0500 Subject: [PATCH 07/13] Whitespace commit to re-trigger CI --- draft-ietf-acme-acme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 2306fb2f..cf6c7c91 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -3495,3 +3495,4 @@ inception. This document draws on many concepts established by Eric Rescorla's "Automated Certificate Issuance Protocol" draft. Martin Thomson provided helpful guidance in the use of HTTP. + From f08d5aea59faac540c77a35416fe9557c6f1b80d Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 14 Dec 2018 11:46:15 -0500 Subject: [PATCH 08/13] Remove outdated text --- draft-ietf-acme-acme.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index cf6c7c91..4584c24f 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -3409,11 +3409,6 @@ operation. Note that given the requirements of {{#finding-an-account-url-given-a-key}}, servers will not create accounts with reused keys anyway. -ACME clients MUST NOT reuse -the same account key for multiple accounts, and MUST NOT allow account key -roll-over to a previously-used account key. ACME servers MUST NOT create a new -account using an account key already associated with an account on the server. - ACME clients and servers MUST verify that a CSR submitted in a finalize request does not contain a public key for any known account key pair. In particular, when a server From bfbf23e6e35498614e1945f5e92d6b89c0b6043a Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 14 Dec 2018 14:59:38 -0500 Subject: [PATCH 09/13] Remove extra line breaks --- draft-ietf-acme-acme.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 4584c24f..515ea711 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -3409,8 +3409,7 @@ operation. Note that given the requirements of {{#finding-an-account-url-given-a-key}}, servers will not create accounts with reused keys anyway. -ACME clients and servers -MUST verify that a CSR submitted in a finalize request does not contain a +ACME clients and servers MUST verify that a CSR submitted in a finalize request does not contain a public key for any known account key pair. In particular, when a server receives a finalize request, it MUST verify that the public key in a CSR is not the same as the public key of the account key pair used to authenticate that @@ -3490,4 +3489,3 @@ inception. This document draws on many concepts established by Eric Rescorla's "Automated Certificate Issuance Protocol" draft. Martin Thomson provided helpful guidance in the use of HTTP. - From 46c277d33e253ddb24517022b46354fb73b4ddc4 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 14 Dec 2018 16:43:38 -0500 Subject: [PATCH 10/13] Fix reference error --- draft-ietf-acme-acme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 515ea711..4f63ac3d 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -3406,7 +3406,7 @@ client knows to be used elsewhere, then the client MUST return an error. Clients that manage account keys on behalf of users SHOULD generate a fresh account key for every account creation or roll-over operation. Note that given the requirements of -{{#finding-an-account-url-given-a-key}}, servers will not create +{{finding-an-account-url-given-a-key}}, servers will not create accounts with reused keys anyway. ACME clients and servers MUST verify that a CSR submitted in a finalize request does not contain a From 09d809151bf9a465f2e7bd8eb7763c655ed876ed Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 17 Dec 2018 16:07:25 -0500 Subject: [PATCH 11/13] Further clarification on nonce scoping --- draft-ietf-acme-acme.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 4f63ac3d..a7069607 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -532,6 +532,15 @@ The precise method used to generate and track nonces is up to the server. For example, the server could generate a random 128-bit value for each response, keep a list of issued nonces, and strike nonces from this list as they are used. +Other than the constraint above with regard to nonces issued in +"badNonce" responses, ACME does not constrain how servers +scope nonces. Clients MAY assume that nonces have broad scope, +e.g., by having a single pool of nonces used for all requests. +However, when retrying in response to a "badNonce" error, the client +MUST use the nonce provided in the error response. Obviously, +servers should scope nonces broadly enough that retries are not +needed very often. + ### Replay-Nonce The "Replay-Nonce" header field includes a server-generated value that the From 7069548463c48973cc562d3c78763597c941714c Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 17 Dec 2018 16:09:07 -0500 Subject: [PATCH 12/13] One more clarification --- draft-ietf-acme-acme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index a7069607..66085579 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -524,7 +524,8 @@ 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). +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. From 8e725f0fe8fc9712aa6a09567d071e9e746295e8 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Mon, 17 Dec 2018 16:25:44 -0500 Subject: [PATCH 13/13] #ObviouslyNotObviously --- draft-ietf-acme-acme.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/draft-ietf-acme-acme.md b/draft-ietf-acme-acme.md index 66085579..b01e25bb 100644 --- a/draft-ietf-acme-acme.md +++ b/draft-ietf-acme-acme.md @@ -538,9 +538,8 @@ Other than the constraint above with regard to nonces issued in scope nonces. Clients MAY assume that nonces have broad scope, e.g., by having a single pool of nonces used for all requests. However, when retrying in response to a "badNonce" error, the client -MUST use the nonce provided in the error response. Obviously, -servers should scope nonces broadly enough that retries are not -needed very often. +MUST use the nonce provided in the error response. Servers should +scope nonces broadly enough that retries are not needed very often. ### Replay-Nonce