1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
15 // ACME server response statuses used to describe Authorization and Challenge states.
17 StatusUnknown = "unknown"
18 StatusPending = "pending"
19 StatusProcessing = "processing"
21 StatusInvalid = "invalid"
22 StatusRevoked = "revoked"
25 // CRLReasonCode identifies the reason for a certificate revocation.
26 type CRLReasonCode int
28 // CRL reason codes as defined in RFC 5280.
30 CRLReasonUnspecified CRLReasonCode = 0
31 CRLReasonKeyCompromise CRLReasonCode = 1
32 CRLReasonCACompromise CRLReasonCode = 2
33 CRLReasonAffiliationChanged CRLReasonCode = 3
34 CRLReasonSuperseded CRLReasonCode = 4
35 CRLReasonCessationOfOperation CRLReasonCode = 5
36 CRLReasonCertificateHold CRLReasonCode = 6
37 CRLReasonRemoveFromCRL CRLReasonCode = 8
38 CRLReasonPrivilegeWithdrawn CRLReasonCode = 9
39 CRLReasonAACompromise CRLReasonCode = 10
42 // ErrUnsupportedKey is returned when an unsupported key type is encountered.
43 var ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
45 // Error is an ACME error, defined in Problem Details for HTTP APIs doc
46 // http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
48 // StatusCode is The HTTP status code generated by the origin server.
50 // ProblemType is a URI reference that identifies the problem type,
51 // typically in a "urn:acme:error:xxx" form.
53 // Detail is a human-readable explanation specific to this occurrence of the problem.
55 // Header is the original server error response headers.
60 func (e *Error) Error() string {
61 return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
64 // AuthorizationError indicates that an authorization for an identifier
66 // It contains all errors from Challenge items of the failed Authorization.
67 type AuthorizationError struct {
68 // URI uniquely identifies the failed Authorization.
71 // Identifier is an AuthzID.Value of the failed Authorization.
74 // Errors is a collection of non-nil error values of Challenge items
75 // of the failed Authorization.
79 func (a *AuthorizationError) Error() string {
80 e := make([]string, len(a.Errors))
81 for i, err := range a.Errors {
84 return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
87 // RateLimit reports whether err represents a rate limit error and
88 // any Retry-After duration returned by the server.
90 // See the following for more details on rate limiting:
91 // https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
92 func RateLimit(err error) (time.Duration, bool) {
97 // Some CA implementations may return incorrect values.
98 // Use case-insensitive comparison.
99 if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
105 return retryAfter(e.Header.Get("Retry-After"), 0), true
108 // Account is a user account. It is associated with a private key.
109 type Account struct {
110 // URI is the account unique ID, which is also a URL used to retrieve
111 // account data from the CA.
114 // Contact is a slice of contact info used during registration.
117 // The terms user has agreed to.
118 // A value not matching CurrentTerms indicates that the user hasn't agreed
119 // to the actual Terms of Service of the CA.
122 // Actual terms of a CA.
125 // Authz is the authorization URL used to initiate a new authz flow.
128 // Authorizations is a URI from which a list of authorizations
129 // granted to this account can be fetched via a GET request.
130 Authorizations string
132 // Certificates is a URI from which a list of certificates
133 // issued for this account can be fetched via a GET request.
137 // Directory is ACME server discovery data.
138 type Directory struct {
139 // RegURL is an account endpoint URL, allowing for creating new
140 // and modifying existing accounts.
143 // AuthzURL is used to initiate Identifier Authorization flow.
146 // CertURL is a new certificate issuance endpoint URL.
149 // RevokeURL is used to initiate a certificate revocation flow.
152 // Term is a URI identifying the current terms of service.
155 // Website is an HTTP or HTTPS URL locating a website
156 // providing more information about the ACME server.
159 // CAA consists of lowercase hostname elements, which the ACME server
160 // recognises as referring to itself for the purposes of CAA record validation
161 // as defined in RFC6844.
165 // Challenge encodes a returned CA challenge.
166 // Its Error field may be non-nil if the challenge is part of an Authorization
167 // with StatusInvalid.
168 type Challenge struct {
169 // Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01".
172 // URI is where a challenge response can be posted to.
175 // Token is a random value that uniquely identifies the challenge.
178 // Status identifies the status of this challenge.
181 // Error indicates the reason for an authorization failure
182 // when this challenge was used.
183 // The type of a non-nil value is *Error.
187 // Authorization encodes an authorization response.
188 type Authorization struct {
189 // URI uniquely identifies a authorization.
192 // Status identifies the status of an authorization.
195 // Identifier is what the account is authorized to represent.
198 // Challenges that the client needs to fulfill in order to prove possession
199 // of the identifier (for pending authorizations).
200 // For final authorizations, the challenges that were used.
201 Challenges []*Challenge
203 // A collection of sets of challenges, each of which would be sufficient
204 // to prove possession of the identifier.
205 // Clients must complete a set of challenges that covers at least one set.
206 // Challenges are identified by their indices in the challenges array.
207 // If this field is empty, the client needs to complete all challenges.
211 // AuthzID is an identifier that an account is authorized to represent.
212 type AuthzID struct {
213 Type string // The type of identifier, e.g. "dns".
214 Value string // The identifier itself, e.g. "example.org".
217 // wireAuthz is ACME JSON representation of Authorization objects.
218 type wireAuthz struct {
220 Challenges []wireChallenge
228 func (z *wireAuthz) authorization(uri string) *Authorization {
232 Identifier: AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
233 Combinations: z.Combinations, // shallow copy
234 Challenges: make([]*Challenge, len(z.Challenges)),
236 for i, v := range z.Challenges {
237 a.Challenges[i] = v.challenge()
242 func (z *wireAuthz) error(uri string) *AuthorizationError {
243 err := &AuthorizationError{
245 Identifier: z.Identifier.Value,
247 for _, raw := range z.Challenges {
248 if raw.Error != nil {
249 err.Errors = append(err.Errors, raw.Error.error(nil))
255 // wireChallenge is ACME JSON challenge representation.
256 type wireChallenge struct {
257 URI string `json:"uri"`
264 func (c *wireChallenge) challenge() *Challenge {
272 v.Status = StatusPending
275 v.Error = c.Error.error(nil)
280 // wireError is a subset of fields of the Problem Details object
281 // as described in https://tools.ietf.org/html/rfc7807#section-3.1.
282 type wireError struct {
288 func (e *wireError) error(h http.Header) *Error {
290 StatusCode: e.Status,