Summary: Has enough positions to pass.
Thanks for the work on this; I'm happy to see it nearing completion. I have a few minor comments: *** Substantive *** §6.1: "The ACME server acts as an HTTP and HTTPS client when validating challenges via HTTP." Section 8.3 says that HTTP challenge validation cannot use HTTPS. Also, §6 says that all interactions between the client and server use HTTPS. I recognize challenge validation is not really an interaction between the client and server, but I suspect some readers may be confused. - "ACME servers SHOULD follow the recommendations of [RFC7525] when configuring their TLS implementations." Why not MUST? §7.3: "... and the server MUST reject new-account requests that do not have the "termsOfServiceAgreed" field set to "true". " The MUST seems overly strong there; is there no room for local policy? Would it be completely insane to offer optional ToS? (For example, maybe one gets some additional service for agreeing to terms, but still gets a cert either way.) - "Clients SHOULD NOT automatically agree to terms by default." Why not MUST NOT? §8.3: - Is there a lifetime after which a provisioned HTTP resource in response to a challenge should go away? *** Editorial and Nits *** §2, first paragraph: Is the "user" the person requesting services from the ACME server? §10.2: " It is RECOMMENDED that the server perform DNS queries and make HTTP connections from various network perspectives..." §7.3.6: " The inner JWS is NOT REQUIRED to have a "nonce" header parameter." "NOT REQUIRED" is not among the terms defined by 2119/8174. I suspect this is intended as a statement of fact, and should therefore not be capitalized. I'm not sure what that means. Given that this uses an upper-case RECOMMENDED, can it be stated more concretely? §13.3: Is this section also to be removed?
Thanks for addressing my Discuss and other points; as promised, I'm switching to Yes. (But I support Adam's discuss and look forward to seeing it come to a close as well.) This document was quite easy to read -- thank you for the clear prose and document structure! It did leave me with some questions as to whether there are missing clarifications, though, so there are a pile of notes in the section-by-section comments below. It seems natural to feel some unease when the concept of automated certificate issuance like this comes up. As far as I can tell, though, the only substantive difference between this flow and the flow it's replacing is that this one qualitatively feels like it weakens the "know your customer" aspect for the CA -- with current/legacy methods registering for an account can be slow and involves real-world information. Such can be spoofed/forged, of course, but ACME seems to be weakening some aspect by automating it. Given the spoofability, though, this weakening does not seem to be a particular concern with the document. I was going to suggest mentioning the potential for future work in doing time-delayed or periodic revalidation or other schemes to look at the stability of the way that identifiers/challenges were validated, but I see that discussion has already happened. It's probably worth going over the examples and checking whether nonce values are repeated in ways that are inconsistent with expected usage. For example, I see these three values appearing multiple times (but I did not cross-check if a nonce returned in the Replay-Nonce response header was then used in a JWS header attribute): 2 K60BWPrMQG9SDxBDS_xtSw 3 IXVHDyxIRGcTE0VSblhPzw 4 JHb54aT_KTXBWQOzGYkt9A Perhaps the examples could be offset by a description of what they are? (They would probably also benefit from a disclaimer that the whitespace in the JSON is for ease of reading only.) Section-by-section comments follow. Abstract (also Introduction) If I read "authentication of domain names" with no context, I would be more likely to think of the sort of challenge/authorization process that this document describes, than I would be to think of using an X.509 certificate to authenticate myself as being the owner of a given domain name. But it's unclear whether there's an alternative phrasing that would be better. Section 1 Different types of certificates reflect different kinds of CA verification of information about the certificate subject. "Domain Validation" (DV) certificates are by far the most common type. The only validation the CA is required to perform in the DV issuance process is to verify that the requester has effective control of the domain. Can we get an (informative) ref for the "required"/requirements? Section 6.1 W3C.CR-cors-2013-0129 shows up as "outdated" when I follow the link. Section 6.2 IMPORTANT: The JSON Web Signature and Encryption Algorithms registry does not appear to include an explicit indicator of whether an algorithm is MAC-based; do we need to include text on how to make such a determination? Section 6.3 For servers following the "SHOULD ... string equality check" and for requests where the equality check fails, does that fall into the "MUST reject the request as unauthorized" bucket? Section 6.4 In order to protect ACME resources from any possible replay attacks, ACME requests have a mandatory anti-replay mechanism. We don't seem to actually define what an "ACME request" is that I can see. From context, this requirement only applies to JWS POST bodies, and not to, say, newNonce, but I wonder if some clarification would be useful. IMPORTANT: How tightly are these nonces scoped? Are they only good on a specific TLS connection? Bound to an account key pair? Globally valid? (This is not a DISCUSS point because AFAICT there is no loss in security if the nonce space is global to the server.) Section 6.6 IMPORTANT: Providing an accountDoesNotExist error type probably means we need to give guidance that the server should choose account URLs in a non-guessable way, to avoid account enumeration attacks. [...] Servers MUST NOT use the ACME URN namespace Section 9.6 for errors other than the standard types. "standard" as determined by inclusion in this document, or in the IANA registry? Section 7.1 The "up" link relation for going from certificate to chain seems to only be needed for alternate content types that can only represent a single certificate. (Also, the "alternate" link relation is used to provide alternate certifciation chains.) Could this text be made more clear? Presumably this is just my confusion, but what does "GET order certificate" mean? Section 7.1.1 [...] It is a JSON object, whose field names are drawn from the following table and whose values are the corresponding URLs. Er, from the IANA registry, right? The following metadata items are defined, all of which are OPTIONAL: Maybe also refer to the registry? Section 7.1.2 IMPORTANT: I'm unclear if the "contact" is supposed to be a "talk to a human" thing or not. If there are supposed to be different URLs that are used for different purposes, wouldn't more metadata be needed about them? So it seems most likely that this is indeed "talk to a human", in which case that might be worth mentioning. (Are these always going to be mailto:?) Section 220.127.116.11 IMPORTANT: Am I reading this correctly that the GET to the orders URL does not require the client to be authenticated, in effect relying on security-through-obscurity (of the account URL) for indicating which account is trying to order certificates for which identifiers? Section 7.1.4 challenges (required, array of objects): For pending authorizations, the challenges that the client can fulfill in order to prove possession of the identifier. For final authorizations (in the "valid" or "invalid" state), the challenges that were used. Each array entry is an object with parameters required to validate the challenge. A client should attempt to fulfill one of these challenges, and a server should consider any one of the challenges sufficient to make the authorization valid. This leaves me slightly confused. A final authorization can have multiple challenges. But a client should only attempt to fulfill one, and a server should treat any one as sufficient. So I can only get to the case with multiple challenges present in a final order of both "should"s are violated? Is there a way for the server to express that multiple challenges are going to be required? Hmm, but Section 7.1.6's flow chart for Authorization objects says that a single challenge's transition to valid also makes the authorization transition to valid, which would seem to close the window? Section 7.5.1 has inline text that implicitly assumes that only one challenge will be completed/validated. wildcard (optional, boolean): For authorizations created as a result of a newOrder request containing a DNS identifier with a value that contained a wildcard prefix this field MUST be present, and true. Is there a difference between false and absent? Section 7.3 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. Given that we go on to describe those two and also the optional onlyReturnExisting and externalAccountBinding fields, does this list need expanding? IMPORTANT: How does the client know if a termsOfService in the directory is actually required or just optional? (There doesn't seem to be a dedicated error type for this?) The text as-is seems to only say that if the server requires it, the field must be present in the directory, but not the other way around. I guess Section 7.3.4 describes the procedure for a similar case; should the same thing happen for the original terms acceptance? IMPORTANT: The example response uses what appears to be a sequential counter for account ID in the returned account URL, which loses any sort of security-through-obscurity protections if those were desired. Should a more opaque URL component be present, maybe a UUID? (The "orders" field would need to be modified accordingly, of course, and this pattern appears in later examples, as well.) Section 7.3.2 It's a little unclear to me whether the fields the client can put in the POST are the ones listed from Section 7.3 or 7.1.2, or the full set from the registry. But presumably the server must ignore the "status" field, too, or at least some values should be disallowed! The IANA registry's "configurable" column may not quite be the right thing for this usage, especially given how account deactivation works. Section 7.3.5 The server MAY require a value for the "externalAccountBinding" field to be present in "newAccount" requests. All requests including queries for the current status and modification of existing accounts? Or just creation of new ones? To enable ACME account binding, the CA operating the ACME server needs to provide the ACME client with a MAC key and a key identifier, using some mechanism outside of ACME. This key needs to also be tied to the external account in question, right? One might even say that it is provided not to the ACME client, but to the external account holder, who is also running an ACME client. [...] The payload of this JWS is the account key being registered, in JWK form. This is presumably my fault and not the document's, but I had to read this a few time to bind it as the ACME account key, and not the external MAC key. If 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 [...] nit: maybe "If such a CA"? IMPORTANT: I don't think I understand why "nonce" MUST NOT be present in the external-binding JWS object, though I think I understand why one is not needed in order to bind the MAC to the current transaction. (That is, this is in effect a "triply nested" construct, where a standalone MAC that certifies an ACME account (public) key as being authorized by the external-account holder to act on behal of that external account. But this standalone MAC will only be accepted by the ACME server in the context of the outer JWS POST, that must be signed by the ACME account key, which is assumed to be kept secure by the ACME client, ensuring that both key-holding entities agree to the account linkage.) Proof of freshness of the commitment from the external account holder to authorize the ACME account key would only be needed if there was a scenario where the external account holder would revoke that association, which does not seem to be a workflow supported by this document. Any need to effectuate such a revocation seems like it would involve issuing a new MAC key for the external account (and invalidating the old one), and revoking/deactivating the ACME account, which is a somewhat heavy hammer but perhaps reasonable for such a scenario. Account key rollover just says that the nonce is NOT REQUIRED, and also uses some nicer (to me) language about "outer JWS" and "inner JWS". It might be nice to synchronize these two sections. Section 7.3.7 IMPORTANT: The "url" in this example looks like an account URL, not an account-deactivation url. If they are one and the same, please include some body text to this effect as is done for account update in Section 7.3.2. Section 7.4 Is Section 7.1.3 or the registry a better reference for the request payload's fields? Does the exact-match policy (e.g., on notBefore and notAfter) result in CA maximum lifetime policies needing to be hardcoded in client software (as opposed to being discoverable at runtime)? (I like the order url in the example, "[...]/order/asdf". Not much entropy though.) IMPORTANT: Why does the example response include an identifier of www.example.com that was not in the request? Is the "order's requested identifiers appear in commonName or subjectAltName" requirement an exclusive or? After a valid request to finalize has been issued, are "pending" or "ready" still valid statuses that could be returned for that order? Section 7.4.1 Elsewhere when we list "identifier (required, object)" in a JWS payload we also inline the "type" and "value" breakdown of the object. How is "expires" set for this pre-authorization object? We probably need a reference for "certificate chain as defined in TLS". Section 7.5 "When a client receives an order from the server" is a bit jarring without some additional context of "in a reply to a new-order request" or "an order object" or similar. Section 7.5.1 To do this, the client updates the authorization object received from the server by filling in any required information in the elements of the "challenges" dictionary. "challenges" looks like an array of objects, not directly a dictionary with elements within it. Section 8 IMPORTANT: What do I do if I get a challenge object that has status "valid" but also includes an "error" field? Section 8.1 [...] A key authorization is a string that expresses a domain holder's authorization for a specified key to satisfy a specified challenge, [...] I'm going to quibble with the language here and say that the keyAuthorization string as defined does not express a specific authorization for a specific challenge, since there is no signature involved, and the JWK thumbprint is separable and can be attached to some other token. (This may just be an editorial matter with no broader impact, depending on how it's used.) One could perhaps argue that the mere existence of the token constitutes an authorization for a specified key to satisfy the challenge, since the token only gets generated upon receipt of such an authorized request. Section 8.3 I'm not sure that 4086 is a great cite, here. For example, in RFC 8446 we say that "TLS requires a [CSPRNG]. In most case, the operating system provides an appropriate facility [...] Should these prove unsatisfactory, [RFC4086] provides guidance on the generation of random values." On the other hand, citing 4086 like this is not wrong, so use your judgment. 4. Verify that the body of the response is well-formed key authorization. The server SHOULD ignore whitespace characters at the end of the body. nit: "a well-formed" Can we get some justification for the "SHOULD follow redirects", given the security considerations surrounding doing so? Section 8.4 Should this "token" description include the same text about entropy as for the HTTP challenge? Section 9.7.1 There is perhaps some subtlety here, in that the "configurable" column applies only to the new-account request, but its description in the template does not reflect that restriction. In particular, "status" values from the client *are* accepted when posted to the account URL, e.g., for account deactivation. Section 10.1 Can there be overlap between the "validation server" function and the "ACME client" function? Section 10.2 [...] The key authorization reflects the account public key, is provided to the server in the validation response over the validation channel and signed afterwards by the corresponding private key in the challenge response over the ACME channel. I'm stumbling up around the comma trying to parse this sentence. (Maybe a serial comma or using "and is signed" would help?) IMPORTANT: Also, I don't see where the key authorization is signed in the challenge response -- the payload is just an empty object for both the HTTP and DNS challenges' responses. Some of this text sounds like we're implicitly placing requirements on all (HTTP|DNS) server operators (not just ones trying to use ACME) to mitgate the risks being described. In general this sort of behavior seems like an anti-design-pattern, though perhaps one could argue that the behaviors in question should be avoided in general, indepnedent of ACME. Section 10.4 Some server implementations include information from the validation server's response (in order to facilitate debugging). Such Disambiguating "ACME server implementations" may help, since we talk about other HTTP requests in the previous paragraph. Section 11.1 IMPORTANT: This may be an appropriate place to recommend against reuse of account keys, whether after an account gets deactivated or by cycling through keys in a sequence of key-change operations (or otherwise). I think there are some attack scenarios possible wherein (inner) JWS objects could be replayed against a different account, if such key reuse occurs. Section 11.3 The http-01, and dns-01 validation methods mandate the usage of a nit: spurious comma. [...] Secondly, the entropy requirement prevents ACME clients from implementing a "naive" validation server that automatically replies to challenges without participating in the creation of the initial authorization request. IMPORTANT: I'm not sure I see how this applies to the HTTP mechanism -- couldn't you write a script to reply to .well-known/acme-challenge/<foo> with <foo>.<key thumbprint> for a fixed key thumbprint? The validation server would ned to know about the ACME account in question, but not about any individual authorization request.
Thanks for the well-written doc and for addressing the TSV-ART comment(s) (and thanks Martin for the TSV-ART review)!
(Happy with the changes in -15) Thank you for this very important document. As you've addressed my comments, I am balloting "Yes". However I am looking forward to seeing resolution of Adam's DISCUSS. A few remaining comments: First mentions of JSON and HTTPS need references.
Thanks for all the work that everyone has put into this protocol, and especially for the work that went into addressing the privacy issue that I identified. I'm excited by what ACME been able to do for the certificate issuance sector as a whole, and truly appreciate all of the early implementors who have put both clients and servers into active production.