draft-ietf-acme-acme-15.txt   draft-ietf-acme-acme-16.txt 
ACME Working Group R. Barnes ACME Working Group R. Barnes
Internet-Draft Cisco Internet-Draft Cisco
Intended status: Standards Track J. Hoffman-Andrews Intended status: Standards Track J. Hoffman-Andrews
Expires: March 29, 2019 EFF Expires: April 15, 2019 EFF
D. McCarney D. McCarney
Let's Encrypt Let's Encrypt
J. Kasten J. Kasten
University of Michigan University of Michigan
September 25, 2018 October 12, 2018
Automatic Certificate Management Environment (ACME) Automatic Certificate Management Environment (ACME)
draft-ietf-acme-acme-15 draft-ietf-acme-acme-16
Abstract Abstract
Public Key Infrastructure X.509 (PKIX) certificates are used for a Public Key Infrastructure X.509 (PKIX) certificates are used for a
number of purposes, the most significant of which is the number of purposes, the most significant of which is the
authentication of domain names. Thus, certification authorities authentication of domain names. Thus, certification authorities
(CAs) in the Web PKI are trusted to verify that an applicant for a (CAs) in the Web PKI are trusted to verify that an applicant for a
certificate legitimately represents the domain name(s) in the certificate legitimately represents the domain name(s) in the
certificate. Today, this verification is done through a collection certificate. Today, this verification is done through a collection
of ad hoc mechanisms. This document describes a protocol that a CA of ad hoc mechanisms. This document describes a protocol that a CA
skipping to change at page 2, line 7 skipping to change at page 2, line 7
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on March 29, 2019. This Internet-Draft will expire on April 15, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2018 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 38 skipping to change at page 2, line 38
3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7
4. Protocol Overview . . . . . . . . . . . . . . . . . . . . . . 7 4. Protocol Overview . . . . . . . . . . . . . . . . . . . . . . 7
5. Character Encoding . . . . . . . . . . . . . . . . . . . . . 10 5. Character Encoding . . . . . . . . . . . . . . . . . . . . . 10
6. Message Transport . . . . . . . . . . . . . . . . . . . . . . 10 6. Message Transport . . . . . . . . . . . . . . . . . . . . . . 10
6.1. HTTPS Requests . . . . . . . . . . . . . . . . . . . . . 10 6.1. HTTPS Requests . . . . . . . . . . . . . . . . . . . . . 10
6.2. Request Authentication . . . . . . . . . . . . . . . . . 11 6.2. Request Authentication . . . . . . . . . . . . . . . . . 11
6.3. GET and POST-as-GET Requests . . . . . . . . . . . . . . 12 6.3. GET and POST-as-GET Requests . . . . . . . . . . . . . . 12
6.4. Request URL Integrity . . . . . . . . . . . . . . . . . . 13 6.4. Request URL Integrity . . . . . . . . . . . . . . . . . . 13
6.4.1. "url" (URL) JWS Header Parameter . . . . . . . . . . 14 6.4.1. "url" (URL) JWS Header Parameter . . . . . . . . . . 14
6.5. Replay protection . . . . . . . . . . . . . . . . . . . . 14 6.5. Replay protection . . . . . . . . . . . . . . . . . . . . 14
6.5.1. Replay-Nonce . . . . . . . . . . . . . . . . . . . . 15 6.5.1. Replay-Nonce . . . . . . . . . . . . . . . . . . . . 14
6.5.2. "nonce" (Nonce) JWS Header Parameter . . . . . . . . 15 6.5.2. "nonce" (Nonce) JWS Header Parameter . . . . . . . . 15
6.6. Rate Limits . . . . . . . . . . . . . . . . . . . . . . . 15 6.6. Rate Limits . . . . . . . . . . . . . . . . . . . . . . . 15
6.7. Errors . . . . . . . . . . . . . . . . . . . . . . . . . 16 6.7. Errors . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.7.1. Subproblems . . . . . . . . . . . . . . . . . . . . . 18 6.7.1. Subproblems . . . . . . . . . . . . . . . . . . . . . 17
7. Certificate Management . . . . . . . . . . . . . . . . . . . 19 7. Certificate Management . . . . . . . . . . . . . . . . . . . 18
7.1. Resources . . . . . . . . . . . . . . . . . . . . . . . . 19 7.1. Resources . . . . . . . . . . . . . . . . . . . . . . . . 19
7.1.1. Directory . . . . . . . . . . . . . . . . . . . . . . 21 7.1.1. Directory . . . . . . . . . . . . . . . . . . . . . . 21
7.1.2. Account Objects . . . . . . . . . . . . . . . . . . . 23 7.1.2. Account Objects . . . . . . . . . . . . . . . . . . . 23
7.1.3. Order Objects . . . . . . . . . . . . . . . . . . . . 24 7.1.3. Order Objects . . . . . . . . . . . . . . . . . . . . 24
7.1.4. Authorization Objects . . . . . . . . . . . . . . . . 27 7.1.4. Authorization Objects . . . . . . . . . . . . . . . . 27
7.1.5. Challenge Objects . . . . . . . . . . . . . . . . . . 29 7.1.5. Challenge Objects . . . . . . . . . . . . . . . . . . 29
7.1.6. Status Changes . . . . . . . . . . . . . . . . . . . 29 7.1.6. Status Changes . . . . . . . . . . . . . . . . . . . 29
7.2. Getting a Nonce . . . . . . . . . . . . . . . . . . . . . 31 7.2. Getting a Nonce . . . . . . . . . . . . . . . . . . . . . 31
7.3. Account Creation . . . . . . . . . . . . . . . . . . . . 32 7.3. Account Creation . . . . . . . . . . . . . . . . . . . . 32
7.3.1. Finding an Account URL Given a Key . . . . . . . . . 34 7.3.1. Finding an Account URL Given a Key . . . . . . . . . 34
7.3.2. Account Update . . . . . . . . . . . . . . . . . . . 35 7.3.2. Account Update . . . . . . . . . . . . . . . . . . . 35
7.3.3. Changes of Terms of Service . . . . . . . . . . . . . 35 7.3.3. Changes of Terms of Service . . . . . . . . . . . . . 35
7.3.4. External Account Binding . . . . . . . . . . . . . . 36 7.3.4. External Account Binding . . . . . . . . . . . . . . 36
7.3.5. Account Key Roll-over . . . . . . . . . . . . . . . . 38 7.3.5. Account Key Roll-over . . . . . . . . . . . . . . . . 38
7.3.6. Account Deactivation . . . . . . . . . . . . . . . . 41 7.3.6. Account Deactivation . . . . . . . . . . . . . . . . 41
7.4. Applying for Certificate Issuance . . . . . . . . . . . . 42 7.4. Applying for Certificate Issuance . . . . . . . . . . . . 42
7.4.1. Pre-Authorization . . . . . . . . . . . . . . . . . . 46 7.4.1. Pre-Authorization . . . . . . . . . . . . . . . . . . 46
7.4.2. Downloading the Certificate . . . . . . . . . . . . . 48 7.4.2. Downloading the Certificate . . . . . . . . . . . . . 48
7.5. Identifier Authorization . . . . . . . . . . . . . . . . 49 7.5. Identifier Authorization . . . . . . . . . . . . . . . . 50
7.5.1. Responding to Challenges . . . . . . . . . . . . . . 51 7.5.1. Responding to Challenges . . . . . . . . . . . . . . 52
7.5.2. Deactivating an Authorization . . . . . . . . . . . . 53 7.5.2. Deactivating an Authorization . . . . . . . . . . . . 54
7.6. Certificate Revocation . . . . . . . . . . . . . . . . . 54 7.6. Certificate Revocation . . . . . . . . . . . . . . . . . 55
8. Identifier Validation Challenges . . . . . . . . . . . . . . 56 8. Identifier Validation Challenges . . . . . . . . . . . . . . 57
8.1. Key Authorizations . . . . . . . . . . . . . . . . . . . 58 8.1. Key Authorizations . . . . . . . . . . . . . . . . . . . 59
8.2. Retrying Challenges . . . . . . . . . . . . . . . . . . . 58 8.2. Retrying Challenges . . . . . . . . . . . . . . . . . . . 59
8.3. HTTP Challenge . . . . . . . . . . . . . . . . . . . . . 59 8.3. HTTP Challenge . . . . . . . . . . . . . . . . . . . . . 60
8.4. DNS Challenge . . . . . . . . . . . . . . . . . . . . . . 61 8.4. DNS Challenge . . . . . . . . . . . . . . . . . . . . . . 62
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 63 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 64
9.1. MIME Type: application/pem-certificate-chain . . . . . . 63 9.1. MIME Type: application/pem-certificate-chain . . . . . . 64
9.2. Well-Known URI for the HTTP Challenge . . . . . . . . . . 64 9.2. Well-Known URI for the HTTP Challenge . . . . . . . . . . 65
9.3. Replay-Nonce HTTP Header . . . . . . . . . . . . . . . . 65 9.3. Replay-Nonce HTTP Header . . . . . . . . . . . . . . . . 66
9.4. "url" JWS Header Parameter . . . . . . . . . . . . . . . 65 9.4. "url" JWS Header Parameter . . . . . . . . . . . . . . . 66
9.5. "nonce" JWS Header Parameter . . . . . . . . . . . . . . 65 9.5. "nonce" JWS Header Parameter . . . . . . . . . . . . . . 66
9.6. URN Sub-namespace for ACME (urn:ietf:params:acme) . . . . 66 9.6. URN Sub-namespace for ACME (urn:ietf:params:acme) . . . . 67
9.7. New Registries . . . . . . . . . . . . . . . . . . . . . 66 9.7. New Registries . . . . . . . . . . . . . . . . . . . . . 67
9.7.1. Fields in Account Objects . . . . . . . . . . . . . . 67 9.7.1. Fields in Account Objects . . . . . . . . . . . . . . 68
9.7.2. Fields in Order Objects . . . . . . . . . . . . . . . 67 9.7.2. Fields in Order Objects . . . . . . . . . . . . . . . 68
9.7.3. Fields in Authorization Objects . . . . . . . . . . . 68 9.7.3. Fields in Authorization Objects . . . . . . . . . . . 69
9.7.4. Error Types . . . . . . . . . . . . . . . . . . . . . 69 9.7.4. Error Types . . . . . . . . . . . . . . . . . . . . . 70
9.7.5. Resource Types . . . . . . . . . . . . . . . . . . . 70 9.7.5. Resource Types . . . . . . . . . . . . . . . . . . . 71
9.7.6. Fields in the "meta" Object within a Directory Object 70 9.7.6. Fields in the "meta" Object within a Directory Object 71
9.7.7. Identifier Types . . . . . . . . . . . . . . . . . . 71 9.7.7. Identifier Types . . . . . . . . . . . . . . . . . . 72
9.7.8. Validation Methods . . . . . . . . . . . . . . . . . 72 9.7.8. Validation Methods . . . . . . . . . . . . . . . . . 73
10. Security Considerations . . . . . . . . . . . . . . . . . . . 73 10. Security Considerations . . . . . . . . . . . . . . . . . . . 74
10.1. Threat Model . . . . . . . . . . . . . . . . . . . . . . 73 10.1. Threat Model . . . . . . . . . . . . . . . . . . . . . . 74
10.2. Integrity of Authorizations . . . . . . . . . . . . . . 75 10.2. Integrity of Authorizations . . . . . . . . . . . . . . 76
10.3. Denial-of-Service Considerations . . . . . . . . . . . . 78 10.3. Denial-of-Service Considerations . . . . . . . . . . . . 79
10.4. Server-Side Request Forgery . . . . . . . . . . . . . . 79 10.4. Server-Side Request Forgery . . . . . . . . . . . . . . 80
10.5. CA Policy Considerations . . . . . . . . . . . . . . . . 79 10.5. CA Policy Considerations . . . . . . . . . . . . . . . . 80
11. Operational Considerations . . . . . . . . . . . . . . . . . 81 11. Operational Considerations . . . . . . . . . . . . . . . . . 82
11.1. Key Selection . . . . . . . . . . . . . . . . . . . . . 81 11.1. Key Selection . . . . . . . . . . . . . . . . . . . . . 82
11.2. DNS security . . . . . . . . . . . . . . . . . . . . . . 82 11.2. DNS security . . . . . . . . . . . . . . . . . . . . . . 83
11.3. Token Entropy . . . . . . . . . . . . . . . . . . . . . 82 11.3. Token Entropy . . . . . . . . . . . . . . . . . . . . . 83
11.4. Malformed Certificate Chains . . . . . . . . . . . . . . 83 11.4. Malformed Certificate Chains . . . . . . . . . . . . . . 83
12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 83 12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 84
13. References . . . . . . . . . . . . . . . . . . . . . . . . . 84 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 84
13.1. Normative References . . . . . . . . . . . . . . . . . . 84 13.1. Normative References . . . . . . . . . . . . . . . . . . 85
13.2. Informative References . . . . . . . . . . . . . . . . . 87 13.2. Informative References . . . . . . . . . . . . . . . . . 88
13.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 89 13.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 89 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 89
1. Introduction 1. Introduction
Certificates [RFC5280] in the Web PKI are most commonly used to Certificates [RFC5280] in the Web PKI are most commonly used to
authenticate domain names. Thus, certification authorities (CAs) in authenticate domain names. Thus, certification authorities (CAs) in
the Web PKI are trusted to verify that an applicant for a certificate the Web PKI are trusted to verify that an applicant for a certificate
legitimately represents the domain name(s) in the certificate. legitimately represents the domain name(s) in the certificate.
skipping to change at page 12, line 43 skipping to change at page 12, line 43
set to "application/jose+json". If a request does not meet this set to "application/jose+json". If a request does not meet this
requirement, then the server MUST return a response with status code requirement, then the server MUST return a response with status code
415 (Unsupported Media Type). 415 (Unsupported Media Type).
6.3. GET and POST-as-GET Requests 6.3. GET and POST-as-GET Requests
Note that authentication via signed JWS request bodies implies that Note that authentication via signed JWS request bodies implies that
requests without an entity body are not authenticated, in particular requests without an entity body are not authenticated, in particular
GET requests. Except for the cases described in this section, if the GET requests. Except for the cases described in this section, if the
server receives a GET request, it MUST return an error with status server receives a GET request, it MUST return an error with status
code 405 "Method Not Allowed" and type "malformedRequest". code 405 "Method Not Allowed" and type "malformed".
If a client wishes to fetch a resource from the server (which would If a client wishes to fetch a resource from the server (which would
otherwise be done with a GET), then it MUST send a POST request with otherwise be done with a GET), then it MUST send a POST request with
a JWS body as described above, where the payload of the JWS is a a JWS body as described above, where the payload of the JWS is a
zero-length octet string. In other words, the "payload" field of the zero-length octet string. In other words, the "payload" field of the
JWS object MUST be present and set to the empty string (""). JWS object MUST be present and set to the empty string ("").
We will refer to these as "POST-as-GET" requests. On receiving a We will refer to these as "POST-as-GET" requests. On receiving a
request with a zero-length (and thus non-JSON) payload, the server request with a zero-length (and thus non-JSON) payload, the server
MUST authenticate the sender and verify any access control rules. MUST authenticate the sender and verify any access control rules.
Otherwise, the server MUST treat this request as having the same Otherwise, the server MUST treat this request as having the same
semantics as a GET request for the same resource. semantics as a GET request for the same resource.
The server MUST allow GET requests for the directory and newNonce The server MUST allow GET requests for the directory and newNonce
resources (see Section 7.1), in addition to POST-as-GET requests for resources (see Section 7.1), in addition to POST-as-GET requests for
these resources. This enables clients to bootstrap into the ACME these resources. This enables clients to bootstrap into the ACME
authentication system. authentication system.
The server MAY allow GET requests for certificate resources in order
to allow certificates to be fetched by a lower-privileged process,
e.g., the web server that will use the referenced certificate chain.
(See [I-D.ietf-acme-star] for more advanced cases.) A server that
allows GET requests for certificate resources can still provide a
degree of access control by assigning them capability URLs
[W3C.WD-capability-urls-20140218]. As above, if the server does not
allow GET requests for a given resource, it MUST return an error with
status code 405 "Method Not Allowed" and type "malformedRequest".
6.4. Request URL Integrity 6.4. Request URL Integrity
It is common in deployment for the entity terminating TLS for HTTPS It is common in deployment for the entity terminating TLS for HTTPS
to be different from the entity operating the logical HTTPS server, to be different from the entity operating the logical HTTPS server,
with a "request routing" layer in the middle. For example, an ACME with a "request routing" layer in the middle. For example, an ACME
CA might have a content delivery network terminate TLS connections CA might have a content delivery network terminate TLS connections
from clients so that it can inspect client requests for denial-of- from clients so that it can inspect client requests for denial-of-
service protection. service protection.
These intermediaries can also change values in the request that are These intermediaries can also change values in the request that are
skipping to change at page 24, line 18 skipping to change at page 24, line 18
submitted by this account can be fetched via a POST-as-GET submitted by this account can be fetched via a POST-as-GET
request, as described in Section 7.1.2.1. request, as described in Section 7.1.2.1.
{ {
"status": "valid", "status": "valid",
"contact": [ "contact": [
"mailto:cert-admin@example.com", "mailto:cert-admin@example.com",
"mailto:admin@example.com" "mailto:admin@example.com"
], ],
"termsOfServiceAgreed": true, "termsOfServiceAgreed": true,
"orders": "https://example.com/acme/acct/1/orders" "orders": "https://example.com/acme/acct/evOfKhNU60wg/orders"
} }
7.1.2.1. Orders List 7.1.2.1. Orders List
Each account object includes an "orders" URL from which a list of Each account object includes an "orders" URL from which a list of
orders created by the account can be fetched via POST-as-GET request. orders created by the account can be fetched via POST-as-GET request.
The result of the request MUST be a JSON object whose "orders" field The result of the request MUST be a JSON object whose "orders" field
is an array of URLs, each identifying an order belonging to the is an array of URLs, each identifying an order belonging to the
account. The server SHOULD include pending orders, and SHOULD NOT account. The server SHOULD include pending orders, and SHOULD NOT
include orders that are invalid in the array of URLs. The server MAY include orders that are invalid in the array of URLs. The server MAY
return an incomplete list, along with a Link header field with a return an incomplete list, along with a Link header field with a
"next" link relation indicating where further entries can be "next" link relation indicating where further entries can be
acquired. acquired.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Link: <https://example.com/acme/acct/1/orders?cursor=2>;rel="next" Link: <https://example.com/acme/acct/evOfKhNU60wg/orders?cursor=2>;rel="next"
{ {
"orders": [ "orders": [
"https://example.com/acme/acct/1/order/1", "https://example.com/acme/order/TOlocE8rfgo",
"https://example.com/acme/acct/1/order/2", "https://example.com/acme/order/4E16bbL5iSw",
/* 47 more URLs not shown for example brevity */ /* more URLs not shown for example brevity */
"https://example.com/acme/acct/1/order/50" "https://example.com/acme/order/neBHYLfw0mg"
] ]
} }
7.1.3. Order Objects 7.1.3. Order Objects
An ACME order object represents a client's request for a certificate An ACME order object represents a client's request for a certificate
and is used to track the progress of that order through to issuance. and is used to track the progress of that order through to issuance.
Thus, the object contains information about the requested Thus, the object contains information about the requested
certificate, the authorizations that the server requires the client certificate, the authorizations that the server requires the client
to complete, and any certificates that have resulted from this order. to complete, and any certificates that have resulted from this order.
status (required, string): The status of this order. Possible status (required, string): The status of this order. Possible
skipping to change at page 26, line 21 skipping to change at page 26, line 21
"identifiers": [ "identifiers": [
{ "type": "dns", "value": "example.com" }, { "type": "dns", "value": "example.com" },
{ "type": "dns", "value": "www.example.com" } { "type": "dns", "value": "www.example.com" }
], ],
"notBefore": "2016-01-01T00:00:00Z", "notBefore": "2016-01-01T00:00:00Z",
"notAfter": "2016-01-08T00:00:00Z", "notAfter": "2016-01-08T00:00:00Z",
"authorizations": [ "authorizations": [
"https://example.com/acme/authz/1234", "https://example.com/acme/authz/PAniVnsZcis",
"https://example.com/acme/authz/2345" "https://example.com/acme/authz/r4HqLzrSrpI"
], ],
"finalize": "https://example.com/acme/acct/1/order/1/finalize", "finalize": "https://example.com/acme/order/TOlocE8rfgo/finalize",
"certificate": "https://example.com/acme/cert/1234" "certificate": "https://example.com/acme/cert/jWCdfHVGY2M"
} }
Any identifier of type "dns" in a new-order request MAY have 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 wildcard domain name as its value. A wildcard domain name consists
of a single asterisk character followed by a single full stop of a single asterisk character followed by a single full stop
character ("*.") followed by a domain name as defined for use in the character ("*.") followed by a domain name as defined for use in the
Subject Alternate Name Extension by RFC 5280 [RFC5280]. An Subject Alternate Name Extension by RFC 5280 [RFC5280]. An
authorization returned by the server for a wildcard domain name authorization returned by the server for a wildcard domain name
identifier MUST NOT include the asterisk and full stop ("*.") prefix identifier MUST NOT include the asterisk and full stop ("*.") prefix
in the authorization identifier value. The returned authorization in the authorization identifier value. The returned authorization
skipping to change at page 28, line 17 skipping to change at page 28, line 17
server should consider any one of the challenges sufficient to server should consider any one of the challenges sufficient to
make the authorization valid. make the authorization valid.
wildcard (optional, boolean): For authorizations created as a result wildcard (optional, boolean): For authorizations created as a result
of a newOrder request containing a DNS identifier with a value of a newOrder request containing a DNS identifier with a value
that contained a wildcard prefix this field MUST be present, and that contained a wildcard prefix this field MUST be present, and
true. true.
The only type of identifier defined by this specification is a fully- The only type of identifier defined by this specification is a fully-
qualified domain name (type: "dns"). The domain name MUST be encoded qualified domain name (type: "dns"). The domain name MUST be encoded
in the form in which it would apper in a certificate. That is, it 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]. MUST be encoded according to the rules in Section 7 of [RFC5280].
Servers MUST verify any identifier values that begin with the ASCII Servers MUST verify any identifier values that begin with the ASCII
Compatible Encoding prefix "xn--" as defined in [RFC5890] are Compatible Encoding prefix "xn--" as defined in [RFC5890] are
properly encoded. Wildcard domain names (with "*" as the first properly encoded. Wildcard domain names (with "*" as the first
label) MUST NOT be included in authorization objects. If an label) MUST NOT be included in authorization objects. If an
authorization object conveys authorization for the base domain of a authorization object conveys authorization for the base domain of a
newOrder DNS type identifier with a wildcard prefix then the optional newOrder DNS type identifier with a wildcard prefix then the optional
authorizations "wildcard" field MUST be present with a value of true. authorizations "wildcard" field MUST be present with a value of true.
Section 8 describes a set of challenges for domain name validation. Section 8 describes a set of challenges for domain name validation.
skipping to change at page 28, line 40 skipping to change at page 28, line 40
"status": "valid", "status": "valid",
"expires": "2015-03-01T14:09:07.99Z", "expires": "2015-03-01T14:09:07.99Z",
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.org" "value": "example.org"
}, },
"challenges": [ "challenges": [
{ {
"url": "https://example.com/acme/authz/1234/0", "url": "https://example.com/acme/chall/prV_B7yEyA4",
"type": "http-01", "type": "http-01",
"status": "valid", "status": "valid",
"token": "DGyRejmCefe7v4NfDGDKfA", "token": "DGyRejmCefe7v4NfDGDKfA",
"validated": "2014-12-01T12:05:58.16Z" "validated": "2014-12-01T12:05:58.16Z"
} }
], ],
"wildcard": false "wildcard": false
} }
skipping to change at page 34, line 25 skipping to change at page 34, line 25
verify the JWS (i.e., the "jwk" element of the JWS header) to verify the JWS (i.e., the "jwk" element of the JWS header) to
authenticate future requests from the account. The server returns authenticate future requests from the account. The server returns
this account object in a 201 (Created) response, with the account URL 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" in a Location header field. The account URL is used as the "kid"
value in the JWS authenticating subsequent requests by this account value in the JWS authenticating subsequent requests by this account
(See Section 6.2). (See Section 6.2).
HTTP/1.1 201 Created HTTP/1.1 201 Created
Content-Type: application/json Content-Type: application/json
Replay-Nonce: D8s4D2mLs8Vn-goWuPQeKA Replay-Nonce: D8s4D2mLs8Vn-goWuPQeKA
Location: https://example.com/acme/acct/1 Location: https://example.com/acme/acct/evOfKhNU60wg
Link: <https://example.com/acme/some-directory>;rel="index" Link: <https://example.com/acme/some-directory>;rel="index"
{ {
"status": "valid", "status": "valid",
"contact": [ "contact": [
"mailto:cert-admin@example.com", "mailto:cert-admin@example.com",
"mailto:admin@example.com" "mailto:admin@example.com"
], ],
"orders": "https://example.com/acme/acct/1/orders" "orders": "https://example.com/acme/acct/evOfKhNU60wg/orders"
} }
7.3.1. Finding an Account URL Given a Key 7.3.1. Finding an Account URL Given a Key
If the server receives a newAccount request signed with a key for If the server receives a newAccount request signed with a key for
which it already has an account registered with the provided account which it already has an account registered with the provided account
key, then it MUST return a response with a 200 (OK) status code and key, then it MUST return a response with a 200 (OK) status code and
provide the URL of that account in the Location header field. The provide the URL of that account in the Location header field. The
body of this response represents the account object as it existed on body of this response represents the account object as it existed on
the server before this request; any fields in the request object MUST the server before this request; any fields in the request object MUST
skipping to change at page 35, line 24 skipping to change at page 35, line 24
The server MUST ignore any updates to the "orders" field, The server MUST ignore any updates to the "orders" field,
"termsOfServiceAgreed" field (see Section 7.3.3), the "status" field "termsOfServiceAgreed" field (see Section 7.3.3), the "status" field
(except as allowed by Section 7.3.6), or any other fields it does not (except as allowed by Section 7.3.6), or any other fields it does not
recognize. If the server accepts the update, it MUST return a recognize. If the server accepts the update, it MUST return a
response with a 200 (OK) status code and the resulting account response with a 200 (OK) status code and the resulting account
object. object.
For example, to update the contact information in the above account, For example, to update the contact information in the above account,
the client could send the following request: the client could send the following request:
POST /acme/acct/1 HTTP/1.1 POST /acme/acct/evOfKhNU60wg HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "ax5RnthDqp_Yf4_HZnFLmA", "nonce": "ax5RnthDqp_Yf4_HZnFLmA",
"url": "https://example.com/acme/acct/1" "url": "https://example.com/acme/acct/evOfKhNU60wg"
}), }),
"payload": base64url({ "payload": base64url({
"contact": [ "contact": [
"mailto:certificates@example.com", "mailto:certificates@example.com",
"mailto:admin@example.com" "mailto:admin@example.com"
] ]
}), }),
"signature": "hDXzvcj8T6fbFbmn...rDzXzzvzpRy64N0o" "signature": "hDXzvcj8T6fbFbmn...rDzXzzvzpRy64N0o"
} }
skipping to change at page 39, line 15 skipping to change at page 39, line 15
The outer JWS MUST meet the normal requirements for an ACME JWS (see The outer JWS MUST meet the normal requirements for an ACME JWS (see
Section 6.2). The inner JWS MUST meet the normal requirements, with Section 6.2). The inner JWS MUST meet the normal requirements, with
the following differences: the following differences:
o The inner JWS MUST have a "jwk" header parameter, containing the o The inner JWS MUST have a "jwk" header parameter, containing the
public key of the new key pair. public key of the new key pair.
o The inner JWS MUST have the same "url" header parameter as the o The inner JWS MUST have the same "url" header parameter as the
outer JWS. outer JWS.
o The inner JWS MAY omit the "nonce" header parameter. The server o The inner JWS MUST omit the "nonce" header parameter.
MUST ignore any value provided for the "nonce" header parameter.
This transaction has signatures from both the old and new keys so This transaction has signatures from both the old and new keys so
that the server can verify that the holders of the two keys both that the server can verify that the holders of the two keys both
agree to the change. The signatures are nested to preserve the agree to the change. The signatures are nested to preserve the
property that all signatures on POST messages are signed by exactly property that all signatures on POST messages are signed by exactly
one key. The "inner" JWS effectively represents a request by the one key. The "inner" JWS effectively represents a request by the
holder of the new key to take over the account form the holder of the holder of the new key to take over the account form the holder of the
old key. The "outer" JWS represents the current account holder's old key. The "outer" JWS represents the current account holder's
assent to this request. assent to this request.
POST /acme/key-change HTTP/1.1 POST /acme/key-change HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "S9XaOcxP5McpnTcWPIhYuB", "nonce": "S9XaOcxP5McpnTcWPIhYuB",
"url": "https://example.com/acme/key-change" "url": "https://example.com/acme/key-change"
}), }),
"payload": base64url({ "payload": base64url({
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"jwk": /* new key */, "jwk": /* new key */,
"url": "https://example.com/acme/key-change" "url": "https://example.com/acme/key-change"
}), }),
"payload": base64url({ "payload": base64url({
"account": "https://example.com/acme/acct/1", "account": "https://example.com/acme/acct/evOfKhNU60wg",
"oldKey": /* old key */ "oldKey": /* old key */
}), }),
"signature": "Xe8B94RD30Azj2ea...8BmZIRtcSKPSd8gU" "signature": "Xe8B94RD30Azj2ea...8BmZIRtcSKPSd8gU"
}), }),
"signature": "5TWiqIYQfIDfALQv...x9C2mg8JGPxl5bI4" "signature": "5TWiqIYQfIDfALQv...x9C2mg8JGPxl5bI4"
} }
On receiving key-change request, the server MUST perform the On receiving key-change request, the server MUST perform the
following steps in addition to the typical JWS validation: following steps in addition to the typical JWS validation:
1. Validate the POST request belongs to a currently active account, 1. Validate the POST request belongs to a currently active account,
skipping to change at page 41, line 17 skipping to change at page 41, line 17
A client can deactivate an account by posting a signed update to the A client can deactivate an account by posting a signed update to the
account URL with a status field of "deactivated." Clients may wish account URL with a status field of "deactivated." Clients may wish
to do this when the account key is compromised or decommissioned. A to do this when the account key is compromised or decommissioned. A
deactivated account can no longer request certificate issuance or deactivated account can no longer request certificate issuance or
access resources related to the account, such as orders or access resources related to the account, such as orders or
authorizations. If a server receives a POST or POST-as-GET from a authorizations. If a server receives a POST or POST-as-GET from a
deactivated account, it MUST return an error response with status deactivated account, it MUST return an error response with status
code 401 (Unauthorized) and type code 401 (Unauthorized) and type
"urn:ietf:params:acme:error:unauthorized". "urn:ietf:params:acme:error:unauthorized".
POST /acme/acct/1 HTTP/1.1 POST /acme/acct/evOfKhNU60wg HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "ntuJWWSic4WVNSqeUmshgg", "nonce": "ntuJWWSic4WVNSqeUmshgg",
"url": "https://example.com/acme/acct/1" "url": "https://example.com/acme/acct/evOfKhNU60wg"
}), }),
"payload": base64url({ "payload": base64url({
"status": "deactivated" "status": "deactivated"
}), }),
"signature": "earzVLd3m5M4xJzR...bVTqn7R08AKOVf3Y" "signature": "earzVLd3m5M4xJzR...bVTqn7R08AKOVf3Y"
} }
The server MUST verify that the request is signed by the account key. The server MUST verify that the request is signed by the account key.
If the server accepts the deactivation request, it replies with a 200 If the server accepts the deactivation request, it replies with a 200
(OK) status code and the current contents of the account object. (OK) status code and the current contents of the account object.
skipping to change at page 42, line 33 skipping to change at page 42, line 33
notAfter (optional, string): The requested value of the notAfter notAfter (optional, string): The requested value of the notAfter
field in the certificate, in the date format defined in [RFC3339]. field in the certificate, in the date format defined in [RFC3339].
POST /acme/new-order HTTP/1.1 POST /acme/new-order HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "5XJ1L3lEkMG7tR6pA00clA", "nonce": "5XJ1L3lEkMG7tR6pA00clA",
"url": "https://example.com/acme/new-order" "url": "https://example.com/acme/new-order"
}), }),
"payload": base64url({ "payload": base64url({
"identifiers": [ "identifiers": [
{ "type": "dns", "value": "example.com" } { "type": "dns", "value": "example.com" }
], ],
"notBefore": "2016-01-01T00:04:00+04:00", "notBefore": "2016-01-01T00:04:00+04:00",
"notAfter": "2016-01-08T00:04:00+04:00" "notAfter": "2016-01-08T00:04:00+04:00"
}), }),
skipping to change at page 43, line 13 skipping to change at page 43, line 13
appropriate error type and description. appropriate error type and description.
If the server is willing to issue the requested certificate, it If the server is willing to issue the requested certificate, it
responds with a 201 (Created) response. The body of this response is responds with a 201 (Created) response. The body of this response is
an order object reflecting the client's request and any an order object reflecting the client's request and any
authorizations the client must complete before the certificate will authorizations the client must complete before the certificate will
be issued. be issued.
HTTP/1.1 201 Created HTTP/1.1 201 Created
Replay-Nonce: MYAuvOpaoIiywTezizk5vw Replay-Nonce: MYAuvOpaoIiywTezizk5vw
Location: https://example.com/acme/order/asdf Location: https://example.com/acme/order/TOlocE8rfgo
{ {
"status": "pending", "status": "pending",
"expires": "2016-01-01T00:00:00Z", "expires": "2016-01-01T00:00:00Z",
"notBefore": "2016-01-01T00:00:00Z", "notBefore": "2016-01-01T00:00:00Z",
"notAfter": "2016-01-08T00:00:00Z", "notAfter": "2016-01-08T00:00:00Z",
"identifiers": [ "identifiers": [
{ "type": "dns", "value": "example.com" }, { "type": "dns", "value": "example.com" },
], ],
"authorizations": [ "authorizations": [
"https://example.com/acme/authz/1234", "https://example.com/acme/authz/PAniVnsZcis",
], ],
"finalize": "https://example.com/acme/order/asdf/finalize" "finalize": "https://example.com/acme/order/TOlocE8rfgo/finalize"
} }
The order object returned by the server represents a promise that if The order object returned by the server represents a promise that if
the client fulfills the server's requirements before the "expires" the client fulfills the server's requirements before the "expires"
time, then the server will be willing to finalize the order upon time, then the server will be willing to finalize the order upon
request and issue the requested certificate. In the order object, request and issue the requested certificate. In the order object,
any authorization referenced in the "authorizations" array whose any authorization referenced in the "authorizations" array whose
status is "pending" represents an authorization transaction that the status is "pending" represents an authorization transaction that the
client must complete before the server will issue the certificate client must complete before the server will issue the certificate
(see Section 7.5). If the client fails to complete the required (see Section 7.5). If the client fails to complete the required
skipping to change at page 44, line 8 skipping to change at page 44, line 8
Once the client believes it has fulfilled the server's requirements, Once the client believes it has fulfilled the server's requirements,
it should send a POST request to the order resource's finalize URL. it should send a POST request to the order resource's finalize URL.
The POST body MUST include a CSR: The POST body MUST include a CSR:
csr (required, string): A CSR encoding the parameters for the csr (required, string): A CSR encoding the parameters for the
certificate being requested [RFC2986]. The CSR is sent in the certificate being requested [RFC2986]. The CSR is sent in the
base64url-encoded version of the DER format. (Note: Because this base64url-encoded version of the DER format. (Note: Because this
field uses base64url, and does not include headers, it is field uses base64url, and does not include headers, it is
different from PEM.). different from PEM.).
POST /acme/order/asdf/finalize HTTP/1.1 POST /acme/order/TOlocE8rfgo/finalize HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "MSF2j2nawWHPxxkE3ZJtKQ", "nonce": "MSF2j2nawWHPxxkE3ZJtKQ",
"url": "https://example.com/acme/order/asdf/finalize" "url": "https://example.com/acme/order/TOlocE8rfgo/finalize"
}), }),
"payload": base64url({ "payload": base64url({
"csr": "MIIBPTCBxAIBADBFMQ...FS6aKdZeGsysoCo4H9P", "csr": "MIIBPTCBxAIBADBFMQ...FS6aKdZeGsysoCo4H9P",
}), }),
"signature": "uOrUfIIk5RyQ...nw62Ay1cl6AB" "signature": "uOrUfIIk5RyQ...nw62Ay1cl6AB"
} }
The CSR encodes the client's requests with regard to the content of 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 the certificate to be issued. The CSR MUST indicate the exact same
set of requested identifiers as the initial new-order request. set of requested identifiers as the initial new-order request.
skipping to change at page 46, line 7 skipping to change at page 46, line 7
o "processing": The certificate is being issued. Send a POST-as-GET o "processing": The certificate is being issued. Send a POST-as-GET
request after the time given in the "Retry-After" header field of request after the time given in the "Retry-After" header field of
the response, if any. the response, if any.
o "valid": The server has issued the certificate and provisioned its o "valid": The server has issued the certificate and provisioned its
URL to the "certificate" field of the order. Download the URL to the "certificate" field of the order. Download the
certificate. certificate.
HTTP/1.1 200 OK HTTP/1.1 200 OK
Replay-Nonce: CGf81JWBsq8QyIgPCi9Q9X Replay-Nonce: CGf81JWBsq8QyIgPCi9Q9X
Location: https://example.com/acme/order/asdf Location: https://example.com/acme/order/TOlocE8rfgo
{ {
"status": "valid", "status": "valid",
"expires": "2015-12-31T00:17:00.00-09:00", "expires": "2015-12-31T00:17:00.00-09:00",
"notBefore": "2015-12-31T00:17:00.00-09:00", "notBefore": "2015-12-31T00:17:00.00-09:00",
"notAfter": "2015-12-31T00:17:00.00-09:00", "notAfter": "2015-12-31T00:17:00.00-09:00",
"identifiers": [ "identifiers": [
{ "type": "dns", "value": "example.com" }, { "type": "dns", "value": "example.com" },
{ "type": "dns", "value": "www.example.com" } { "type": "dns", "value": "www.example.com" }
], ],
"authorizations": [ "authorizations": [
"https://example.com/acme/authz/1234", "https://example.com/acme/authz/PAniVnsZcis",
"https://example.com/acme/authz/2345" "https://example.com/acme/authz/r4HqLzrSrpI"
], ],
"finalize": "https://example.com/acme/order/asdf/finalize", "finalize": "https://example.com/acme/order/TOlocE8rfgo/finalize",
"certificate": "https://example.com/acme/cert/asdf" "certificate": "https://example.com/acme/cert/mAt3xBGaobw"
} }
7.4.1. Pre-Authorization 7.4.1. Pre-Authorization
The order process described above presumes that authorization objects The order process described above presumes that authorization objects
are created reactively, in response to a certificate order. Some are created reactively, in response to a certificate order. Some
servers may also wish to enable clients to obtain authorization for servers may also wish to enable clients to obtain authorization for
an identifier proactively, outside of the context of a specific an identifier proactively, outside of the context of a specific
issuance. For example, a client hosting virtual servers for a issuance. For example, a client hosting virtual servers for a
collection of names might wish to obtain authorization before any collection of names might wish to obtain authorization before any
skipping to change at page 47, line 23 skipping to change at page 47, line 23
value (required, string): The identifier itself. value (required, string): The identifier itself.
POST /acme/new-authz HTTP/1.1 POST /acme/new-authz HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "uQpSjlRb4vQVCjVYAyyUWg", "nonce": "uQpSjlRb4vQVCjVYAyyUWg",
"url": "https://example.com/acme/new-authz" "url": "https://example.com/acme/new-authz"
}), }),
"payload": base64url({ "payload": base64url({
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.net" "value": "example.net"
} }
}), }),
"signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps" "signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps"
skipping to change at page 48, line 34 skipping to change at page 49, line 5
The default format of the certificate is application/pem-certificate- The default format of the certificate is application/pem-certificate-
chain (see Section 9). chain (see Section 9).
The server MAY provide one or more link relation header fields The server MAY provide one or more link relation header fields
[RFC5988] with relation "alternate". Each such field SHOULD express [RFC5988] with relation "alternate". Each such field SHOULD express
an alternative certificate chain starting with the same end-entity an alternative certificate chain starting with the same end-entity
certificate. This can be used to express paths to various trust certificate. This can be used to express paths to various trust
anchors. Clients can fetch these alternates and use their own anchors. Clients can fetch these alternates and use their own
heuristics to decide which is optimal. heuristics to decide which is optimal.
GET /acme/cert/asdf HTTP/1.1 POST /acme/cert/mAt3xBGaobw HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json
Accept: application/pem-certificate-chain Accept: application/pem-certificate-chain
{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "uQpSjlRb4vQVCjVYAyyUWg",
"url": "https://example.com/acme/cert/mAt3xBGaobw"
}),
"payload": "",
"signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps"
}
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/pem-certificate-chain Content-Type: application/pem-certificate-chain
Link: <https://example.com/acme/some-directory>;rel="index" Link: <https://example.com/acme/some-directory>;rel="index"
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
[End-entity certificate contents] [End-entity certificate contents]
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
[Issuer certificate contents] [Issuer certificate contents]
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
[Other certificate contents] [Other certificate contents]
-----END CERTIFICATE----- -----END CERTIFICATE-----
An ACME client MAY attempt to fetch the certificate with a GET
request. If the server does not allow GET requests for certificate
resources, then it will return an error as described in Section 6.3.
On receiving such an error, the client SHOULD fall back to a POST-as-
GET request.
A certificate resource represents a single, immutable certificate. A certificate resource represents a single, immutable certificate.
If the client wishes to obtain a renewed certificate, the client If the client wishes to obtain a renewed certificate, the client
initiates a new order process to request one. initiates a new order process to request one.
Because certificate resources are immutable once issuance is Because certificate resources are immutable once issuance is
complete, the server MAY enable the caching of the resource by adding complete, the server MAY enable the caching of the resource by adding
Expires and Cache-Control header fields specifying a point in time in Expires and Cache-Control header fields specifying a point in time in
the distant future. These header fields have no relation to the the distant future. These header fields have no relation to the
certificate's period of validity. certificate's period of validity.
skipping to change at page 50, line 5 skipping to change at page 51, line 5
these requests. The authorization object is implicitly tied to the these requests. The authorization object is implicitly tied to the
account key used to sign the request. account key used to sign the request.
When a client receives an order from the server in reply to a new When a client receives an order from the server in reply to a new
order request, it downloads the authorization resources by sending order request, it downloads the authorization resources by sending
POST-as-GET requests to the indicated URLs. If the client initiates POST-as-GET requests to the indicated URLs. If the client initiates
authorization using a request to the new authorization resource, it authorization using a request to the new authorization resource, it
will have already received the pending authorization object in the will have already received the pending authorization object in the
response to that request. response to that request.
POST /acme/authz/1234 HTTP/1.1 POST /acme/authz/PAniVnsZcis HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
Accept: application/pkix-cert
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "uQpSjlRb4vQVCjVYAyyUWg", "nonce": "uQpSjlRb4vQVCjVYAyyUWg",
"url": "https://example.com/acme/authz/1234", "url": "https://example.com/acme/authz/1234"
}), }),
"payload": "", "payload": "",
"signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps" "signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps"
} }
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Link: <https://example.com/acme/some-directory>;rel="index" Link: <https://example.com/acme/some-directory>;rel="index"
{ {
skipping to change at page 50, line 37 skipping to change at page 51, line 36
"expires": "2018-03-03T14:09:30Z", "expires": "2018-03-03T14:09:30Z",
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.org" "value": "example.org"
}, },
"challenges": [ "challenges": [
{ {
"type": "http-01", "type": "http-01",
"url": "https://example.com/acme/authz/1234/0", "url": "https://example.com/acme/chall/prV_B7yEyA4",
"token": "DGyRejmCefe7v4NfDGDKfA" "token": "DGyRejmCefe7v4NfDGDKfA"
}, },
{ {
"type": "dns-01", "type": "dns-01",
"url": "https://example.com/acme/authz/1234/2", "url": "https://example.com/acme/chall/Rg5dV14Gh1Q",
"token": "DGyRejmCefe7v4NfDGDKfA" "token": "DGyRejmCefe7v4NfDGDKfA"
} }
], ],
"wildcard": false "wildcard": false
} }
7.5.1. Responding to Challenges 7.5.1. Responding to Challenges
To prove control of the identifier and receive authorization, the To prove control of the identifier and receive authorization, the
skipping to change at page 51, line 19 skipping to change at page 52, line 19
the challenge type and indicate to the server that it is ready for the challenge type and indicate to the server that it is ready for
the challenge validation to be attempted. the challenge validation to be attempted.
The client indicates to the server it is ready for the challenge The client indicates to the server it is ready for the challenge
validation by sending an empty JSON body ("{}"), carried in a POST validation by sending an empty JSON body ("{}"), carried in a POST
request to the challenge URL (not authorization URL). request to the challenge URL (not authorization URL).
For example, if the client were to respond to the "http-01" challenge For example, if the client were to respond to the "http-01" challenge
in the above authorization, it would send the following request: in the above authorization, it would send the following request:
POST /acme/authz/1234/0 HTTP/1.1 POST /acme/chall/prV_B7yEyA4 HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "Q_s3MWoqT05TrdkM2MTDcw", "nonce": "Q_s3MWoqT05TrdkM2MTDcw",
"url": "https://example.com/acme/authz/1234/0" "url": "https://example.com/acme/chall/prV_B7yEyA4"
}), }),
"payload": base64url({}), "payload": base64url({}),
"signature": "9cbg5JO1Gf5YLjjz...SpkUfcdPai9uVYYQ" "signature": "9cbg5JO1Gf5YLjjz...SpkUfcdPai9uVYYQ"
} }
The server updates the authorization document by updating its The server updates the authorization document by updating its
representation of the challenge with the response object provided by representation of the challenge with the response object provided by
the client. The server MUST ignore any fields in the response object the client. The server MUST ignore any fields in the response object
that are not specified as response fields for this type of challenge. that are not specified as response fields for this type of challenge.
The server provides a 200 (OK) response with the updated challenge The server provides a 200 (OK) response with the updated challenge
skipping to change at page 53, line 5 skipping to change at page 54, line 5
from the server), the client SHOULD NOT begin polling until it has from the server), the client SHOULD NOT begin polling until it has
seen the validation request from the server. seen the validation request from the server.
To check on the status of an authorization, the client sends a POST- To check on the status of an authorization, the client sends a POST-
as-GET request to the authorization URL, and the server responds with as-GET request to the authorization URL, and the server responds with
the current authorization object. In responding to poll requests the current authorization object. In responding to poll requests
while the validation is still in progress, the server MUST return a while the validation is still in progress, the server MUST return a
200 (OK) response and MAY include a Retry-After header field to 200 (OK) response and MAY include a Retry-After header field to
suggest a polling interval to the client. suggest a polling interval to the client.
POST /acme/authz/1234 HTTP/1.1 POST /acme/authz/PAniVnsZcis HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
Accept: application/pkix-cert
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "uQpSjlRb4vQVCjVYAyyUWg", "nonce": "uQpSjlRb4vQVCjVYAyyUWg",
"url": "https://example.com/acme/authz/1234", "url": "https://example.com/acme/authz/PAniVnsZcis"
}), }),
"payload": "", "payload": "",
"signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps" "signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps"
} }
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
{ {
"status": "valid", "status": "valid",
"expires": "2018-09-09T14:09:01.13Z", "expires": "2018-09-09T14:09:01.13Z",
"identifier": { "identifier": {
"type": "dns", "type": "dns",
"value": "example.org" "value": "example.org"
}, },
"challenges": [ "challenges": [
{ {
"type": "http-01", "type": "http-01",
"url": "https://example.com/acme/authz/1234/0", "url": "https://example.com/acme/chall/prV_B7yEyA4",
"status": "valid", "status": "valid",
"validated": "2014-12-01T12:05:13.72Z", "validated": "2014-12-01T12:05:13.72Z",
"token": "IlirfxKKXAsHtmzK29Pj8A" "token": "IlirfxKKXAsHtmzK29Pj8A"
} }
], ],
"wildcard": false "wildcard": false
} }
7.5.2. Deactivating an Authorization 7.5.2. Deactivating an Authorization
If a client wishes to relinquish its authorization to issue If a client wishes to relinquish its authorization to issue
certificates for an identifier, then it may request that the server certificates for an identifier, then it may request that the server
deactivates each authorization associated with it by sending POST deactivates each authorization associated with it by sending POST
requests with the static object {"status": "deactivated"} to each requests with the static object {"status": "deactivated"} to each
authorization URL. authorization URL.
POST /acme/authz/1234 HTTP/1.1 POST /acme/authz/PAniVnsZcis HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "xWCM9lGbIyCgue8di6ueWQ", "nonce": "xWCM9lGbIyCgue8di6ueWQ",
"url": "https://example.com/acme/authz/1234" "url": "https://example.com/acme/authz/PAniVnsZcis"
}), }),
"payload": base64url({ "payload": base64url({
"status": "deactivated" "status": "deactivated"
}), }),
"signature": "srX9Ji7Le9bjszhu...WTFdtujObzMtZcx4" "signature": "srX9Ji7Le9bjszhu...WTFdtujObzMtZcx4"
} }
The server MUST verify that the request is signed by the account key The server MUST verify that the request is signed by the account key
corresponding to the account that owns the authorization. If the corresponding to the account that owns the authorization. If the
server accepts the deactivation, it should reply with a 200 (OK) server accepts the deactivation, it should reply with a 200 (OK)
skipping to change at page 55, line 18 skipping to change at page 56, line 18
Example using an account key pair for the signature: Example using an account key pair for the signature:
POST /acme/revoke-cert HTTP/1.1 POST /acme/revoke-cert HTTP/1.1
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "JHb54aT_KTXBWQOzGYkt9A", "nonce": "JHb54aT_KTXBWQOzGYkt9A",
"url": "https://example.com/acme/revoke-cert" "url": "https://example.com/acme/revoke-cert"
}), }),
"payload": base64url({ "payload": base64url({
"certificate": "MIIEDTCCAvegAwIBAgIRAP8...", "certificate": "MIIEDTCCAvegAwIBAgIRAP8...",
"reason": 4 "reason": 4
}), }),
"signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4" "signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4"
} }
skipping to change at page 60, line 7 skipping to change at page 61, line 7
type (required, string): The string "http-01" type (required, string): The string "http-01"
token (required, string): A random value that uniquely identifies token (required, string): A random value that uniquely identifies
the challenge. This value MUST have at least 128 bits of entropy. the challenge. This value MUST have at least 128 bits of entropy.
It MUST NOT contain any characters outside the base64url alphabet, It MUST NOT contain any characters outside the base64url alphabet,
and MUST NOT include base64 padding characters ("="). See and MUST NOT include base64 padding characters ("="). See
[RFC4086] for additional information on randomness requirements. [RFC4086] for additional information on randomness requirements.
{ {
"type": "http-01", "type": "http-01",
"url": "https://example.com/acme/authz/0", "url": "https://example.com/acme/chall/prV_B7yEyA4",
"status": "pending", "status": "pending",
"token": "LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0" "token": "LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0"
} }
A client fulfills this challenge by constructing a key authorization A client fulfills this challenge by constructing a key authorization
from the "token" value provided in the challenge and the client's from the "token" value provided in the challenge and the client's
account key. The client then provisions the key authorization as a account key. The client then provisions the key authorization as a
resource on the HTTP server for the domain in question. resource on the HTTP server for the domain in question.
The path at which the resource is provisioned is comprised of the The path at which the resource is provisioned is comprised of the
skipping to change at page 60, line 36 skipping to change at page 61, line 36
Content-Type: application/octet-stream Content-Type: application/octet-stream
LoqXcYV8...jxAjEuX0.9jg46WB3...fm21mqTI LoqXcYV8...jxAjEuX0.9jg46WB3...fm21mqTI
(In the above, "..." indicates that the token and the JWK thumbprint (In the above, "..." indicates that the token and the JWK thumbprint
in the key authorization have been truncated to fit on the page.) in the key authorization have been truncated to fit on the page.)
A client responds with an empty object ({}) to acknowledge that the A client responds with an empty object ({}) to acknowledge that the
challenge can be validated by the server. challenge can be validated by the server.
POST /acme/authz/1234/0 POST /acme/authz/PAniVnsZcis/0
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "UQI1PoRi5OuXzxuX7V7wL0", "nonce": "UQI1PoRi5OuXzxuX7V7wL0",
"url": "https://example.com/acme/authz/1234/0" "url": "https://example.com/acme/chall/prV_B7yEyA4"
}), }),
"payload": base64url({}), "payload": base64url({}),
"signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4" "signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4"
} }
On receiving a response, the server constructs and stores the key On receiving a response, the server constructs and stores the key
authorization from the challenge "token" value and the current client authorization from the challenge "token" value and the current client
account key. account key.
Given a challenge/response pair, the server verifies the client's Given a challenge/response pair, the server verifies the client's
control of the domain by verifying that the resource was provisioned control of the domain by verifying that the resource was provisioned
skipping to change at page 62, line 12 skipping to change at page 63, line 12
type (required, string): The string "dns-01" type (required, string): The string "dns-01"
token (required, string): A random value that uniquely identifies token (required, string): A random value that uniquely identifies
the challenge. This value MUST have at least 128 bits of entropy. the challenge. This value MUST have at least 128 bits of entropy.
It MUST NOT contain any characters outside the base64url alphabet, It MUST NOT contain any characters outside the base64url alphabet,
including padding characters ("="). See [RFC4086] for additional including padding characters ("="). See [RFC4086] for additional
information on randomness requirements. information on randomness requirements.
{ {
"type": "dns-01", "type": "dns-01",
"url": "https://example.com/acme/authz/1234/2", "url": "https://example.com/acme/chall/Rg5dV14Gh1Q",
"status": "pending", "status": "pending",
"token": "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA" "token": "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
} }
A client fulfills this challenge by constructing a key authorization A client fulfills this challenge by constructing a key authorization
from the "token" value provided in the challenge and the client's from the "token" value provided in the challenge and the client's
account key. The client then computes the SHA-256 digest [FIPS180-4] account key. The client then computes the SHA-256 digest [FIPS180-4]
of the key authorization. of the key authorization.
The record provisioned to the DNS contains the base64url encoding of The record provisioned to the DNS contains the base64url encoding of
skipping to change at page 62, line 35 skipping to change at page 63, line 35
validated, then provisions a TXT record with the digest value under validated, then provisions a TXT record with the digest value under
that name. For example, if the domain name being validated is that name. For example, if the domain name being validated is
"example.org", then the client would provision the following DNS "example.org", then the client would provision the following DNS
record: record:
_acme-challenge.example.org. 300 IN TXT "gfj9Xq...Rg85nM" _acme-challenge.example.org. 300 IN TXT "gfj9Xq...Rg85nM"
A client responds with an empty object ({}) to acknowledge that the A client responds with an empty object ({}) to acknowledge that the
challenge can be validated by the server. challenge can be validated by the server.
POST /acme/authz/1234/2 POST /acme/chall/Rg5dV14Gh1Q
Host: example.com Host: example.com
Content-Type: application/jose+json Content-Type: application/jose+json
{ {
"protected": base64url({ "protected": base64url({
"alg": "ES256", "alg": "ES256",
"kid": "https://example.com/acme/acct/1", "kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "SS2sSl1PtspvFZ08kNtzKd", "nonce": "SS2sSl1PtspvFZ08kNtzKd",
"url": "https://example.com/acme/authz/1234/2" "url": "https://example.com/acme/chall/Rg5dV14Gh1Q"
}), }),
"payload": base64url({}), "payload": base64url({}),
"signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4" "signature": "Q1bURgJoEslbD1c5...3pYdSMLio57mQNN4"
} }
On receiving a response, the server constructs and stores the key On receiving a response, the server constructs and stores the key
authorization from the challenge "token" value and the current client authorization from the challenge "token" value and the current client
account key. account key.
To validate a DNS challenge, the server performs the following steps: To validate a DNS challenge, the server performs the following steps:
skipping to change at page 71, line 11 skipping to change at page 72, line 11
o Field name: The string to be used as a field name in the JSON o Field name: The string to be used as a field name in the JSON
object object
o Field type: The type of value to be provided, e.g., string, o Field type: The type of value to be provided, e.g., string,
boolean, array of string boolean, array of string
o Reference: Where this field is defined o Reference: Where this field is defined
Initial contents: The fields and descriptions defined in Initial contents: The fields and descriptions defined in
Section 7.1.2. Section 7.1.1.
+-------------------------+-----------------+-----------+ +-------------------------+-----------------+-----------+
| Field Name | Field Type | Reference | | Field Name | Field Type | Reference |
+-------------------------+-----------------+-----------+ +-------------------------+-----------------+-----------+
| termsOfService | string | RFC XXXX | | termsOfService | string | RFC XXXX |
| | | | | | | |
| website | string | RFC XXXX | | website | string | RFC XXXX |
| | | | | | | |
| caaIdentities | array of string | RFC XXXX | | caaIdentities | array of string | RFC XXXX |
| | | | | | | |
skipping to change at page 80, line 29 skipping to change at page 81, line 29
keep in mind that ACME clients can automate this agreement, possibly keep in mind that ACME clients can automate this agreement, possibly
not involving a human user. not involving a human user.
ACME does not specify how the server constructs the URLs that it uses ACME does not specify how the server constructs the URLs that it uses
to address resources. If the server operator uses URLs that are to address resources. If the server operator uses URLs that are
predictable to third parties, this can leak information about what predictable to third parties, this can leak information about what
URLs exist on the server, since an attacker can probe for whether URLs exist on the server, since an attacker can probe for whether
POST-as-GET request to the URL returns "Not Found" or "Unauthorized". POST-as-GET request to the URL returns "Not Found" or "Unauthorized".
For example, suppose that the CA uses highly structured URLs with For example, suppose that the CA uses highly structured URLs with
several low-entropy fields: guessable fields:
o Accounts: https://example.com/:accountID o Accounts: https://example.com/:accountID
o Orders: https://example.com/:accountID/:orderID o Orders: https://example.com/:accountID/:domainName
o Authorizations: https://example.com/:accountID/:authorizationID
o Certificates: https://example.com/:accountID/:certID o Authorizations: https://example.com/:accountID/:domainName
If the ID fields have low entropy, then an attacker can find out how o Certificates: https://example.com/:accountID/:domainName
many users a CA has, how many authorizations each account has, etc.
In order to avoid leaking these correlations, servers SHOULD assign Under that scheme, an attacker could probe for which domain names are
capability URLs for dynamically-created resources associated with which accounts, which may allow correlation of
[W3C.WD-capability-urls-20140218]. These URLs incorporate large ownership between domain names, if the CA does not otherwise permit
unpredictable components to prevent third parties from guessing them. it.
These URLs SHOULD NOT have a structure that would enable a third
party to infer correlations between resources.
For example, a CA might assign URLs for each resource type from an To avoid leaking these correlations, CAs SHOULD assign URLs with an
independent namespace, using unpredictable IDs for each resource: unpredictable component. For example, a CA might assign URLs for
each resource type from an independent namespace, using unpredictable
IDs for each resource:
o Accounts: https://example.com/acct/:accountID o Accounts: https://example.com/acct/:accountID
o Orders: https://example.com/order/:orderID o Orders: https://example.com/order/:orderID
o Authorizations: https://example.com/authz/:authorizationID o Authorizations: https://example.com/authz/:authorizationID
o Certificates: https://example.com/cert/:certID o Certificates: https://example.com/cert/:certID
Such a scheme would leak only the type of resource, hiding the Such a scheme would leak only the type of resource, hiding the
additional correlations revealed in the example above. additional correlations revealed in the example above.
11. Operational Considerations 11. Operational Considerations
There are certain factors that arise in operational reality that There are certain factors that arise in operational reality that
skipping to change at page 87, line 42 skipping to change at page 88, line 37
[I-D.ietf-acme-caa] [I-D.ietf-acme-caa]
Landau, H., "CAA Record Extensions for Account URI and Landau, H., "CAA Record Extensions for Account URI and
ACME Method Binding", draft-ietf-acme-caa-05 (work in ACME Method Binding", draft-ietf-acme-caa-05 (work in
progress), June 2018. progress), June 2018.
[I-D.ietf-acme-ip] [I-D.ietf-acme-ip]
Shoemaker, R., "ACME IP Identifier Validation Extension", Shoemaker, R., "ACME IP Identifier Validation Extension",
draft-ietf-acme-ip-04 (work in progress), July 2018. draft-ietf-acme-ip-04 (work in progress), July 2018.
[I-D.ietf-acme-star]
Sheffer, Y., Lopez, D., Dios, O., Pastor, A., and T.
Fossati, "Support for Short-Term, Automatically-Renewed
(STAR) Certificates in Automated Certificate Management
Environment (ACME)", draft-ietf-acme-star-03 (work in
progress), March 2018.
[I-D.ietf-acme-telephone] [I-D.ietf-acme-telephone]
Peterson, J. and R. Barnes, "ACME Identifiers and Peterson, J. and R. Barnes, "ACME Identifiers and
Challenges for Telephone Numbers", draft-ietf-acme- Challenges for Telephone Numbers", draft-ietf-acme-
telephone-01 (work in progress), October 2017. telephone-01 (work in progress), October 2017.
[I-D.vixie-dnsext-dns0x20] [I-D.vixie-dnsext-dns0x20]
Vixie, P. and D. Dagon, "Use of Bit 0x20 in DNS Labels to Vixie, P. and D. Dagon, "Use of Bit 0x20 in DNS Labels to
Improve Transaction Identity", draft-vixie-dnsext- Improve Transaction Identity", draft-vixie-dnsext-
dns0x20-00 (work in progress), March 2008. dns0x20-00 (work in progress), March 2008.
skipping to change at page 88, line 45 skipping to change at page 89, line 35
"Recommendations for Secure Use of Transport Layer "Recommendations for Secure Use of Transport Layer
Security (TLS) and Datagram Transport Layer Security Security (TLS) and Datagram Transport Layer Security
(DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May (DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May
2015, <https://www.rfc-editor.org/info/rfc7525>. 2015, <https://www.rfc-editor.org/info/rfc7525>.
[W3C.REC-cors-20140116] [W3C.REC-cors-20140116]
Kesteren, A., "Cross-Origin Resource Sharing", World Wide Kesteren, A., "Cross-Origin Resource Sharing", World Wide
Web Consortium Recommendation REC-cors-20140116, January Web Consortium Recommendation REC-cors-20140116, January
2014, <http://www.w3.org/TR/2014/REC-cors-20140116>. 2014, <http://www.w3.org/TR/2014/REC-cors-20140116>.
[W3C.WD-capability-urls-20140218]
Tennison, J., "Good Practices for Capability URLs", World
Wide Web Consortium WD WD-capability-urls-20140218,
February 2014,
<http://www.w3.org/TR/2014/WD-capability-urls-20140218>.
13.3. URIs 13.3. URIs
[1] https://github.com/ietf-wg-acme/acme [1] https://github.com/ietf-wg-acme/acme
[2] mailto:iesg@ietf.org [2] mailto:iesg@ietf.org
Authors' Addresses Authors' Addresses
Richard Barnes Richard Barnes
Cisco Cisco
 End of changes. 82 change blocks. 
157 lines changed or deleted 146 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/