OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / acme / types.go
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.
4
5 package acme
6
7 import (
8         "errors"
9         "fmt"
10         "net/http"
11         "strings"
12         "time"
13 )
14
15 // ACME server response statuses used to describe Authorization and Challenge states.
16 const (
17         StatusUnknown    = "unknown"
18         StatusPending    = "pending"
19         StatusProcessing = "processing"
20         StatusValid      = "valid"
21         StatusInvalid    = "invalid"
22         StatusRevoked    = "revoked"
23 )
24
25 // CRLReasonCode identifies the reason for a certificate revocation.
26 type CRLReasonCode int
27
28 // CRL reason codes as defined in RFC 5280.
29 const (
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
40 )
41
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")
44
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.
47 type Error struct {
48         // StatusCode is The HTTP status code generated by the origin server.
49         StatusCode int
50         // ProblemType is a URI reference that identifies the problem type,
51         // typically in a "urn:acme:error:xxx" form.
52         ProblemType string
53         // Detail is a human-readable explanation specific to this occurrence of the problem.
54         Detail string
55         // Header is the original server error response headers.
56         // It may be nil.
57         Header http.Header
58 }
59
60 func (e *Error) Error() string {
61         return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
62 }
63
64 // AuthorizationError indicates that an authorization for an identifier
65 // did not succeed.
66 // It contains all errors from Challenge items of the failed Authorization.
67 type AuthorizationError struct {
68         // URI uniquely identifies the failed Authorization.
69         URI string
70
71         // Identifier is an AuthzID.Value of the failed Authorization.
72         Identifier string
73
74         // Errors is a collection of non-nil error values of Challenge items
75         // of the failed Authorization.
76         Errors []error
77 }
78
79 func (a *AuthorizationError) Error() string {
80         e := make([]string, len(a.Errors))
81         for i, err := range a.Errors {
82                 e[i] = err.Error()
83         }
84         return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
85 }
86
87 // RateLimit reports whether err represents a rate limit error and
88 // any Retry-After duration returned by the server.
89 //
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) {
93         e, ok := err.(*Error)
94         if !ok {
95                 return 0, false
96         }
97         // Some CA implementations may return incorrect values.
98         // Use case-insensitive comparison.
99         if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
100                 return 0, false
101         }
102         if e.Header == nil {
103                 return 0, true
104         }
105         return retryAfter(e.Header.Get("Retry-After"), 0), true
106 }
107
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.
112         URI string
113
114         // Contact is a slice of contact info used during registration.
115         Contact []string
116
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.
120         AgreedTerms string
121
122         // Actual terms of a CA.
123         CurrentTerms string
124
125         // Authz is the authorization URL used to initiate a new authz flow.
126         Authz string
127
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
131
132         // Certificates is a URI from which a list of certificates
133         // issued for this account can be fetched via a GET request.
134         Certificates string
135 }
136
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.
141         RegURL string
142
143         // AuthzURL is used to initiate Identifier Authorization flow.
144         AuthzURL string
145
146         // CertURL is a new certificate issuance endpoint URL.
147         CertURL string
148
149         // RevokeURL is used to initiate a certificate revocation flow.
150         RevokeURL string
151
152         // Term is a URI identifying the current terms of service.
153         Terms string
154
155         // Website is an HTTP or HTTPS URL locating a website
156         // providing more information about the ACME server.
157         Website string
158
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.
162         CAA []string
163 }
164
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".
170         Type string
171
172         // URI is where a challenge response can be posted to.
173         URI string
174
175         // Token is a random value that uniquely identifies the challenge.
176         Token string
177
178         // Status identifies the status of this challenge.
179         Status string
180
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.
184         Error error
185 }
186
187 // Authorization encodes an authorization response.
188 type Authorization struct {
189         // URI uniquely identifies a authorization.
190         URI string
191
192         // Status identifies the status of an authorization.
193         Status string
194
195         // Identifier is what the account is authorized to represent.
196         Identifier AuthzID
197
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
202
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.
208         Combinations [][]int
209 }
210
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".
215 }
216
217 // wireAuthz is ACME JSON representation of Authorization objects.
218 type wireAuthz struct {
219         Status       string
220         Challenges   []wireChallenge
221         Combinations [][]int
222         Identifier   struct {
223                 Type  string
224                 Value string
225         }
226 }
227
228 func (z *wireAuthz) authorization(uri string) *Authorization {
229         a := &Authorization{
230                 URI:          uri,
231                 Status:       z.Status,
232                 Identifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
233                 Combinations: z.Combinations, // shallow copy
234                 Challenges:   make([]*Challenge, len(z.Challenges)),
235         }
236         for i, v := range z.Challenges {
237                 a.Challenges[i] = v.challenge()
238         }
239         return a
240 }
241
242 func (z *wireAuthz) error(uri string) *AuthorizationError {
243         err := &AuthorizationError{
244                 URI:        uri,
245                 Identifier: z.Identifier.Value,
246         }
247         for _, raw := range z.Challenges {
248                 if raw.Error != nil {
249                         err.Errors = append(err.Errors, raw.Error.error(nil))
250                 }
251         }
252         return err
253 }
254
255 // wireChallenge is ACME JSON challenge representation.
256 type wireChallenge struct {
257         URI    string `json:"uri"`
258         Type   string
259         Token  string
260         Status string
261         Error  *wireError
262 }
263
264 func (c *wireChallenge) challenge() *Challenge {
265         v := &Challenge{
266                 URI:    c.URI,
267                 Type:   c.Type,
268                 Token:  c.Token,
269                 Status: c.Status,
270         }
271         if v.Status == "" {
272                 v.Status = StatusPending
273         }
274         if c.Error != nil {
275                 v.Error = c.Error.error(nil)
276         }
277         return v
278 }
279
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 {
283         Status int
284         Type   string
285         Detail string
286 }
287
288 func (e *wireError) error(h http.Header) *Error {
289         return &Error{
290                 StatusCode:  e.Status,
291                 ProblemType: e.Type,
292                 Detail:      e.Detail,
293                 Header:      h,
294         }
295 }