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.
17 // ACME server response statuses used to describe Authorization and Challenge states.
19 StatusUnknown = "unknown"
20 StatusPending = "pending"
21 StatusProcessing = "processing"
23 StatusInvalid = "invalid"
24 StatusRevoked = "revoked"
27 // CRLReasonCode identifies the reason for a certificate revocation.
28 type CRLReasonCode int
30 // CRL reason codes as defined in RFC 5280.
32 CRLReasonUnspecified CRLReasonCode = 0
33 CRLReasonKeyCompromise CRLReasonCode = 1
34 CRLReasonCACompromise CRLReasonCode = 2
35 CRLReasonAffiliationChanged CRLReasonCode = 3
36 CRLReasonSuperseded CRLReasonCode = 4
37 CRLReasonCessationOfOperation CRLReasonCode = 5
38 CRLReasonCertificateHold CRLReasonCode = 6
39 CRLReasonRemoveFromCRL CRLReasonCode = 8
40 CRLReasonPrivilegeWithdrawn CRLReasonCode = 9
41 CRLReasonAACompromise CRLReasonCode = 10
44 // ErrUnsupportedKey is returned when an unsupported key type is encountered.
45 var ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
47 // Error is an ACME error, defined in Problem Details for HTTP APIs doc
48 // http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
50 // StatusCode is The HTTP status code generated by the origin server.
52 // ProblemType is a URI reference that identifies the problem type,
53 // typically in a "urn:acme:error:xxx" form.
55 // Detail is a human-readable explanation specific to this occurrence of the problem.
57 // Header is the original server error response headers.
62 func (e *Error) Error() string {
63 return fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
66 // AuthorizationError indicates that an authorization for an identifier
68 // It contains all errors from Challenge items of the failed Authorization.
69 type AuthorizationError struct {
70 // URI uniquely identifies the failed Authorization.
73 // Identifier is an AuthzID.Value of the failed Authorization.
76 // Errors is a collection of non-nil error values of Challenge items
77 // of the failed Authorization.
81 func (a *AuthorizationError) Error() string {
82 e := make([]string, len(a.Errors))
83 for i, err := range a.Errors {
86 return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
89 // RateLimit reports whether err represents a rate limit error and
90 // any Retry-After duration returned by the server.
92 // See the following for more details on rate limiting:
93 // https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
94 func RateLimit(err error) (time.Duration, bool) {
99 // Some CA implementations may return incorrect values.
100 // Use case-insensitive comparison.
101 if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
107 return retryAfter(e.Header.Get("Retry-After")), true
110 // Account is a user account. It is associated with a private key.
111 type Account struct {
112 // URI is the account unique ID, which is also a URL used to retrieve
113 // account data from the CA.
116 // Contact is a slice of contact info used during registration.
119 // The terms user has agreed to.
120 // A value not matching CurrentTerms indicates that the user hasn't agreed
121 // to the actual Terms of Service of the CA.
124 // Actual terms of a CA.
127 // Authz is the authorization URL used to initiate a new authz flow.
130 // Authorizations is a URI from which a list of authorizations
131 // granted to this account can be fetched via a GET request.
132 Authorizations string
134 // Certificates is a URI from which a list of certificates
135 // issued for this account can be fetched via a GET request.
139 // Directory is ACME server discovery data.
140 type Directory struct {
141 // RegURL is an account endpoint URL, allowing for creating new
142 // and modifying existing accounts.
145 // AuthzURL is used to initiate Identifier Authorization flow.
148 // CertURL is a new certificate issuance endpoint URL.
151 // RevokeURL is used to initiate a certificate revocation flow.
154 // Term is a URI identifying the current terms of service.
157 // Website is an HTTP or HTTPS URL locating a website
158 // providing more information about the ACME server.
161 // CAA consists of lowercase hostname elements, which the ACME server
162 // recognises as referring to itself for the purposes of CAA record validation
163 // as defined in RFC6844.
167 // Challenge encodes a returned CA challenge.
168 // Its Error field may be non-nil if the challenge is part of an Authorization
169 // with StatusInvalid.
170 type Challenge struct {
171 // Type is the challenge type, e.g. "http-01", "tls-sni-02", "dns-01".
174 // URI is where a challenge response can be posted to.
177 // Token is a random value that uniquely identifies the challenge.
180 // Status identifies the status of this challenge.
183 // Error indicates the reason for an authorization failure
184 // when this challenge was used.
185 // The type of a non-nil value is *Error.
189 // Authorization encodes an authorization response.
190 type Authorization struct {
191 // URI uniquely identifies a authorization.
194 // Status identifies the status of an authorization.
197 // Identifier is what the account is authorized to represent.
200 // Challenges that the client needs to fulfill in order to prove possession
201 // of the identifier (for pending authorizations).
202 // For final authorizations, the challenges that were used.
203 Challenges []*Challenge
205 // A collection of sets of challenges, each of which would be sufficient
206 // to prove possession of the identifier.
207 // Clients must complete a set of challenges that covers at least one set.
208 // Challenges are identified by their indices in the challenges array.
209 // If this field is empty, the client needs to complete all challenges.
213 // AuthzID is an identifier that an account is authorized to represent.
214 type AuthzID struct {
215 Type string // The type of identifier, e.g. "dns".
216 Value string // The identifier itself, e.g. "example.org".
219 // wireAuthz is ACME JSON representation of Authorization objects.
220 type wireAuthz struct {
222 Challenges []wireChallenge
230 func (z *wireAuthz) authorization(uri string) *Authorization {
234 Identifier: AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
235 Combinations: z.Combinations, // shallow copy
236 Challenges: make([]*Challenge, len(z.Challenges)),
238 for i, v := range z.Challenges {
239 a.Challenges[i] = v.challenge()
244 func (z *wireAuthz) error(uri string) *AuthorizationError {
245 err := &AuthorizationError{
247 Identifier: z.Identifier.Value,
249 for _, raw := range z.Challenges {
250 if raw.Error != nil {
251 err.Errors = append(err.Errors, raw.Error.error(nil))
257 // wireChallenge is ACME JSON challenge representation.
258 type wireChallenge struct {
259 URI string `json:"uri"`
266 func (c *wireChallenge) challenge() *Challenge {
274 v.Status = StatusPending
277 v.Error = c.Error.error(nil)
282 // wireError is a subset of fields of the Problem Details object
283 // as described in https://tools.ietf.org/html/rfc7807#section-3.1.
284 type wireError struct {
290 func (e *wireError) error(h http.Header) *Error {
292 StatusCode: e.Status,
299 // CertOption is an optional argument type for the TLS ChallengeCert methods for
300 // customizing a temporary certificate for TLS-based challenges.
301 type CertOption interface {
305 // WithKey creates an option holding a private/public key pair.
306 // The private part signs a certificate, and the public part represents the signee.
307 func WithKey(key crypto.Signer) CertOption {
308 return &certOptKey{key}
311 type certOptKey struct {
315 func (*certOptKey) privateCertOpt() {}
317 // WithTemplate creates an option for specifying a certificate template.
318 // See x509.CreateCertificate for template usage details.
320 // In TLS ChallengeCert methods, the template is also used as parent,
321 // resulting in a self-signed certificate.
322 // The DNSNames field of t is always overwritten for tls-sni challenge certs.
323 func WithTemplate(t *x509.Certificate) CertOption {
324 return (*certOptTemplate)(t)
327 type certOptTemplate x509.Certificate
329 func (*certOptTemplate) privateCertOpt() {}