barometer: update DMA's vendoring packages
[barometer.git] / src / dma / vendor / golang.org / x / crypto / acme / acme.go
1 // Copyright 2015 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 provides an implementation of the
6 // Automatic Certificate Management Environment (ACME) spec.
7 // See https://tools.ietf.org/html/draft-ietf-acme-acme-02 for details.
8 //
9 // Most common scenarios will want to use autocert subdirectory instead,
10 // which provides automatic access to certificates from Let's Encrypt
11 // and any other ACME-based CA.
12 //
13 // This package is a work in progress and makes no API stability promises.
14 package acme
15
16 import (
17         "context"
18         "crypto"
19         "crypto/ecdsa"
20         "crypto/elliptic"
21         "crypto/rand"
22         "crypto/sha256"
23         "crypto/tls"
24         "crypto/x509"
25         "crypto/x509/pkix"
26         "encoding/asn1"
27         "encoding/base64"
28         "encoding/hex"
29         "encoding/json"
30         "encoding/pem"
31         "errors"
32         "fmt"
33         "io"
34         "io/ioutil"
35         "math/big"
36         "net/http"
37         "strings"
38         "sync"
39         "time"
40 )
41
42 const (
43         // LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
44         LetsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
45
46         // ALPNProto is the ALPN protocol name used by a CA server when validating
47         // tls-alpn-01 challenges.
48         //
49         // Package users must ensure their servers can negotiate the ACME ALPN in
50         // order for tls-alpn-01 challenge verifications to succeed.
51         // See the crypto/tls package's Config.NextProtos field.
52         ALPNProto = "acme-tls/1"
53 )
54
55 // idPeACMEIdentifierV1 is the OID for the ACME extension for the TLS-ALPN challenge.
56 var idPeACMEIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
57
58 const (
59         maxChainLen = 5       // max depth and breadth of a certificate chain
60         maxCertSize = 1 << 20 // max size of a certificate, in bytes
61
62         // Max number of collected nonces kept in memory.
63         // Expect usual peak of 1 or 2.
64         maxNonces = 100
65 )
66
67 // Client is an ACME client.
68 // The only required field is Key. An example of creating a client with a new key
69 // is as follows:
70 //
71 //      key, err := rsa.GenerateKey(rand.Reader, 2048)
72 //      if err != nil {
73 //              log.Fatal(err)
74 //      }
75 //      client := &Client{Key: key}
76 //
77 type Client struct {
78         // Key is the account key used to register with a CA and sign requests.
79         // Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
80         //
81         // The following algorithms are supported:
82         // RS256, ES256, ES384 and ES512.
83         // See RFC7518 for more details about the algorithms.
84         Key crypto.Signer
85
86         // HTTPClient optionally specifies an HTTP client to use
87         // instead of http.DefaultClient.
88         HTTPClient *http.Client
89
90         // DirectoryURL points to the CA directory endpoint.
91         // If empty, LetsEncryptURL is used.
92         // Mutating this value after a successful call of Client's Discover method
93         // will have no effect.
94         DirectoryURL string
95
96         // RetryBackoff computes the duration after which the nth retry of a failed request
97         // should occur. The value of n for the first call on failure is 1.
98         // The values of r and resp are the request and response of the last failed attempt.
99         // If the returned value is negative or zero, no more retries are done and an error
100         // is returned to the caller of the original method.
101         //
102         // Requests which result in a 4xx client error are not retried,
103         // except for 400 Bad Request due to "bad nonce" errors and 429 Too Many Requests.
104         //
105         // If RetryBackoff is nil, a truncated exponential backoff algorithm
106         // with the ceiling of 10 seconds is used, where each subsequent retry n
107         // is done after either ("Retry-After" + jitter) or (2^n seconds + jitter),
108         // preferring the former if "Retry-After" header is found in the resp.
109         // The jitter is a random value up to 1 second.
110         RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration
111
112         dirMu sync.Mutex // guards writes to dir
113         dir   *Directory // cached result of Client's Discover method
114
115         noncesMu sync.Mutex
116         nonces   map[string]struct{} // nonces collected from previous responses
117 }
118
119 // Discover performs ACME server discovery using c.DirectoryURL.
120 //
121 // It caches successful result. So, subsequent calls will not result in
122 // a network round-trip. This also means mutating c.DirectoryURL after successful call
123 // of this method will have no effect.
124 func (c *Client) Discover(ctx context.Context) (Directory, error) {
125         c.dirMu.Lock()
126         defer c.dirMu.Unlock()
127         if c.dir != nil {
128                 return *c.dir, nil
129         }
130
131         res, err := c.get(ctx, c.directoryURL(), wantStatus(http.StatusOK))
132         if err != nil {
133                 return Directory{}, err
134         }
135         defer res.Body.Close()
136         c.addNonce(res.Header)
137
138         var v struct {
139                 Reg    string `json:"new-reg"`
140                 Authz  string `json:"new-authz"`
141                 Cert   string `json:"new-cert"`
142                 Revoke string `json:"revoke-cert"`
143                 Meta   struct {
144                         Terms   string   `json:"terms-of-service"`
145                         Website string   `json:"website"`
146                         CAA     []string `json:"caa-identities"`
147                 }
148         }
149         if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
150                 return Directory{}, err
151         }
152         c.dir = &Directory{
153                 RegURL:    v.Reg,
154                 AuthzURL:  v.Authz,
155                 CertURL:   v.Cert,
156                 RevokeURL: v.Revoke,
157                 Terms:     v.Meta.Terms,
158                 Website:   v.Meta.Website,
159                 CAA:       v.Meta.CAA,
160         }
161         return *c.dir, nil
162 }
163
164 func (c *Client) directoryURL() string {
165         if c.DirectoryURL != "" {
166                 return c.DirectoryURL
167         }
168         return LetsEncryptURL
169 }
170
171 // CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format.
172 // The exp argument indicates the desired certificate validity duration. CA may issue a certificate
173 // with a different duration.
174 // If the bundle argument is true, the returned value will also contain the CA (issuer) certificate chain.
175 //
176 // In the case where CA server does not provide the issued certificate in the response,
177 // CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips.
178 // In such a scenario, the caller can cancel the polling with ctx.
179 //
180 // CreateCert returns an error if the CA's response or chain was unreasonably large.
181 // Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
182 func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {
183         if _, err := c.Discover(ctx); err != nil {
184                 return nil, "", err
185         }
186
187         req := struct {
188                 Resource  string `json:"resource"`
189                 CSR       string `json:"csr"`
190                 NotBefore string `json:"notBefore,omitempty"`
191                 NotAfter  string `json:"notAfter,omitempty"`
192         }{
193                 Resource: "new-cert",
194                 CSR:      base64.RawURLEncoding.EncodeToString(csr),
195         }
196         now := timeNow()
197         req.NotBefore = now.Format(time.RFC3339)
198         if exp > 0 {
199                 req.NotAfter = now.Add(exp).Format(time.RFC3339)
200         }
201
202         res, err := c.post(ctx, c.Key, c.dir.CertURL, req, wantStatus(http.StatusCreated))
203         if err != nil {
204                 return nil, "", err
205         }
206         defer res.Body.Close()
207
208         curl := res.Header.Get("Location") // cert permanent URL
209         if res.ContentLength == 0 {
210                 // no cert in the body; poll until we get it
211                 cert, err := c.FetchCert(ctx, curl, bundle)
212                 return cert, curl, err
213         }
214         // slurp issued cert and CA chain, if requested
215         cert, err := c.responseCert(ctx, res, bundle)
216         return cert, curl, err
217 }
218
219 // FetchCert retrieves already issued certificate from the given url, in DER format.
220 // It retries the request until the certificate is successfully retrieved,
221 // context is cancelled by the caller or an error response is received.
222 //
223 // The returned value will also contain the CA (issuer) certificate if the bundle argument is true.
224 //
225 // FetchCert returns an error if the CA's response or chain was unreasonably large.
226 // Callers are encouraged to parse the returned value to ensure the certificate is valid
227 // and has expected features.
228 func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
229         res, err := c.get(ctx, url, wantStatus(http.StatusOK))
230         if err != nil {
231                 return nil, err
232         }
233         return c.responseCert(ctx, res, bundle)
234 }
235
236 // RevokeCert revokes a previously issued certificate cert, provided in DER format.
237 //
238 // The key argument, used to sign the request, must be authorized
239 // to revoke the certificate. It's up to the CA to decide which keys are authorized.
240 // For instance, the key pair of the certificate may be authorized.
241 // If the key is nil, c.Key is used instead.
242 func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
243         if _, err := c.Discover(ctx); err != nil {
244                 return err
245         }
246
247         body := &struct {
248                 Resource string `json:"resource"`
249                 Cert     string `json:"certificate"`
250                 Reason   int    `json:"reason"`
251         }{
252                 Resource: "revoke-cert",
253                 Cert:     base64.RawURLEncoding.EncodeToString(cert),
254                 Reason:   int(reason),
255         }
256         if key == nil {
257                 key = c.Key
258         }
259         res, err := c.post(ctx, key, c.dir.RevokeURL, body, wantStatus(http.StatusOK))
260         if err != nil {
261                 return err
262         }
263         defer res.Body.Close()
264         return nil
265 }
266
267 // AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service
268 // during account registration. See Register method of Client for more details.
269 func AcceptTOS(tosURL string) bool { return true }
270
271 // Register creates a new account registration by following the "new-reg" flow.
272 // It returns the registered account. The account is not modified.
273 //
274 // The registration may require the caller to agree to the CA's Terms of Service (TOS).
275 // If so, and the account has not indicated the acceptance of the terms (see Account for details),
276 // Register calls prompt with a TOS URL provided by the CA. Prompt should report
277 // whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.
278 func (c *Client) Register(ctx context.Context, a *Account, prompt func(tosURL string) bool) (*Account, error) {
279         if _, err := c.Discover(ctx); err != nil {
280                 return nil, err
281         }
282
283         var err error
284         if a, err = c.doReg(ctx, c.dir.RegURL, "new-reg", a); err != nil {
285                 return nil, err
286         }
287         var accept bool
288         if a.CurrentTerms != "" && a.CurrentTerms != a.AgreedTerms {
289                 accept = prompt(a.CurrentTerms)
290         }
291         if accept {
292                 a.AgreedTerms = a.CurrentTerms
293                 a, err = c.UpdateReg(ctx, a)
294         }
295         return a, err
296 }
297
298 // GetReg retrieves an existing registration.
299 // The url argument is an Account URI.
300 func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
301         a, err := c.doReg(ctx, url, "reg", nil)
302         if err != nil {
303                 return nil, err
304         }
305         a.URI = url
306         return a, nil
307 }
308
309 // UpdateReg updates an existing registration.
310 // It returns an updated account copy. The provided account is not modified.
311 func (c *Client) UpdateReg(ctx context.Context, a *Account) (*Account, error) {
312         uri := a.URI
313         a, err := c.doReg(ctx, uri, "reg", a)
314         if err != nil {
315                 return nil, err
316         }
317         a.URI = uri
318         return a, nil
319 }
320
321 // Authorize performs the initial step in an authorization flow.
322 // The caller will then need to choose from and perform a set of returned
323 // challenges using c.Accept in order to successfully complete authorization.
324 //
325 // If an authorization has been previously granted, the CA may return
326 // a valid authorization (Authorization.Status is StatusValid). If so, the caller
327 // need not fulfill any challenge and can proceed to requesting a certificate.
328 func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {
329         return c.authorize(ctx, "dns", domain)
330 }
331
332 // AuthorizeIP is the same as Authorize but requests IP address authorization.
333 // Clients which successfully obtain such authorization may request to issue
334 // a certificate for IP addresses.
335 //
336 // See the ACME spec extension for more details about IP address identifiers:
337 // https://tools.ietf.org/html/draft-ietf-acme-ip.
338 func (c *Client) AuthorizeIP(ctx context.Context, ipaddr string) (*Authorization, error) {
339         return c.authorize(ctx, "ip", ipaddr)
340 }
341
342 func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization, error) {
343         if _, err := c.Discover(ctx); err != nil {
344                 return nil, err
345         }
346
347         type authzID struct {
348                 Type  string `json:"type"`
349                 Value string `json:"value"`
350         }
351         req := struct {
352                 Resource   string  `json:"resource"`
353                 Identifier authzID `json:"identifier"`
354         }{
355                 Resource:   "new-authz",
356                 Identifier: authzID{Type: typ, Value: val},
357         }
358         res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
359         if err != nil {
360                 return nil, err
361         }
362         defer res.Body.Close()
363
364         var v wireAuthz
365         if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
366                 return nil, fmt.Errorf("acme: invalid response: %v", err)
367         }
368         if v.Status != StatusPending && v.Status != StatusValid {
369                 return nil, fmt.Errorf("acme: unexpected status: %s", v.Status)
370         }
371         return v.authorization(res.Header.Get("Location")), nil
372 }
373
374 // GetAuthorization retrieves an authorization identified by the given URL.
375 //
376 // If a caller needs to poll an authorization until its status is final,
377 // see the WaitAuthorization method.
378 func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
379         res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
380         if err != nil {
381                 return nil, err
382         }
383         defer res.Body.Close()
384         var v wireAuthz
385         if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
386                 return nil, fmt.Errorf("acme: invalid response: %v", err)
387         }
388         return v.authorization(url), nil
389 }
390
391 // RevokeAuthorization relinquishes an existing authorization identified
392 // by the given URL.
393 // The url argument is an Authorization.URI value.
394 //
395 // If successful, the caller will be required to obtain a new authorization
396 // using the Authorize method before being able to request a new certificate
397 // for the domain associated with the authorization.
398 //
399 // It does not revoke existing certificates.
400 func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
401         req := struct {
402                 Resource string `json:"resource"`
403                 Status   string `json:"status"`
404                 Delete   bool   `json:"delete"`
405         }{
406                 Resource: "authz",
407                 Status:   "deactivated",
408                 Delete:   true,
409         }
410         res, err := c.post(ctx, c.Key, url, req, wantStatus(http.StatusOK))
411         if err != nil {
412                 return err
413         }
414         defer res.Body.Close()
415         return nil
416 }
417
418 // WaitAuthorization polls an authorization at the given URL
419 // until it is in one of the final states, StatusValid or StatusInvalid,
420 // the ACME CA responded with a 4xx error code, or the context is done.
421 //
422 // It returns a non-nil Authorization only if its Status is StatusValid.
423 // In all other cases WaitAuthorization returns an error.
424 // If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
425 func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
426         for {
427                 res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
428                 if err != nil {
429                         return nil, err
430                 }
431
432                 var raw wireAuthz
433                 err = json.NewDecoder(res.Body).Decode(&raw)
434                 res.Body.Close()
435                 switch {
436                 case err != nil:
437                         // Skip and retry.
438                 case raw.Status == StatusValid:
439                         return raw.authorization(url), nil
440                 case raw.Status == StatusInvalid:
441                         return nil, raw.error(url)
442                 }
443
444                 // Exponential backoff is implemented in c.get above.
445                 // This is just to prevent continuously hitting the CA
446                 // while waiting for a final authorization status.
447                 d := retryAfter(res.Header.Get("Retry-After"))
448                 if d == 0 {
449                         // Given that the fastest challenges TLS-SNI and HTTP-01
450                         // require a CA to make at least 1 network round trip
451                         // and most likely persist a challenge state,
452                         // this default delay seems reasonable.
453                         d = time.Second
454                 }
455                 t := time.NewTimer(d)
456                 select {
457                 case <-ctx.Done():
458                         t.Stop()
459                         return nil, ctx.Err()
460                 case <-t.C:
461                         // Retry.
462                 }
463         }
464 }
465
466 // GetChallenge retrieves the current status of an challenge.
467 //
468 // A client typically polls a challenge status using this method.
469 func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
470         res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
471         if err != nil {
472                 return nil, err
473         }
474         defer res.Body.Close()
475         v := wireChallenge{URI: url}
476         if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
477                 return nil, fmt.Errorf("acme: invalid response: %v", err)
478         }
479         return v.challenge(), nil
480 }
481
482 // Accept informs the server that the client accepts one of its challenges
483 // previously obtained with c.Authorize.
484 //
485 // The server will then perform the validation asynchronously.
486 func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
487         auth, err := keyAuth(c.Key.Public(), chal.Token)
488         if err != nil {
489                 return nil, err
490         }
491
492         req := struct {
493                 Resource string `json:"resource"`
494                 Type     string `json:"type"`
495                 Auth     string `json:"keyAuthorization"`
496         }{
497                 Resource: "challenge",
498                 Type:     chal.Type,
499                 Auth:     auth,
500         }
501         res, err := c.post(ctx, c.Key, chal.URI, req, wantStatus(
502                 http.StatusOK,       // according to the spec
503                 http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
504         ))
505         if err != nil {
506                 return nil, err
507         }
508         defer res.Body.Close()
509
510         var v wireChallenge
511         if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
512                 return nil, fmt.Errorf("acme: invalid response: %v", err)
513         }
514         return v.challenge(), nil
515 }
516
517 // DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response.
518 // A TXT record containing the returned value must be provisioned under
519 // "_acme-challenge" name of the domain being validated.
520 //
521 // The token argument is a Challenge.Token value.
522 func (c *Client) DNS01ChallengeRecord(token string) (string, error) {
523         ka, err := keyAuth(c.Key.Public(), token)
524         if err != nil {
525                 return "", err
526         }
527         b := sha256.Sum256([]byte(ka))
528         return base64.RawURLEncoding.EncodeToString(b[:]), nil
529 }
530
531 // HTTP01ChallengeResponse returns the response for an http-01 challenge.
532 // Servers should respond with the value to HTTP requests at the URL path
533 // provided by HTTP01ChallengePath to validate the challenge and prove control
534 // over a domain name.
535 //
536 // The token argument is a Challenge.Token value.
537 func (c *Client) HTTP01ChallengeResponse(token string) (string, error) {
538         return keyAuth(c.Key.Public(), token)
539 }
540
541 // HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge
542 // should be provided by the servers.
543 // The response value can be obtained with HTTP01ChallengeResponse.
544 //
545 // The token argument is a Challenge.Token value.
546 func (c *Client) HTTP01ChallengePath(token string) string {
547         return "/.well-known/acme-challenge/" + token
548 }
549
550 // TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
551 // Servers can present the certificate to validate the challenge and prove control
552 // over a domain name.
553 //
554 // The implementation is incomplete in that the returned value is a single certificate,
555 // computed only for Z0 of the key authorization. ACME CAs are expected to update
556 // their implementations to use the newer version, TLS-SNI-02.
557 // For more details on TLS-SNI-01 see https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-7.3.
558 //
559 // The token argument is a Challenge.Token value.
560 // If a WithKey option is provided, its private part signs the returned cert,
561 // and the public part is used to specify the signee.
562 // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
563 //
564 // The returned certificate is valid for the next 24 hours and must be presented only when
565 // the server name of the TLS ClientHello matches exactly the returned name value.
566 func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
567         ka, err := keyAuth(c.Key.Public(), token)
568         if err != nil {
569                 return tls.Certificate{}, "", err
570         }
571         b := sha256.Sum256([]byte(ka))
572         h := hex.EncodeToString(b[:])
573         name = fmt.Sprintf("%s.%s.acme.invalid", h[:32], h[32:])
574         cert, err = tlsChallengeCert([]string{name}, opt)
575         if err != nil {
576                 return tls.Certificate{}, "", err
577         }
578         return cert, name, nil
579 }
580
581 // TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
582 // Servers can present the certificate to validate the challenge and prove control
583 // over a domain name. For more details on TLS-SNI-02 see
584 // https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.3.
585 //
586 // The token argument is a Challenge.Token value.
587 // If a WithKey option is provided, its private part signs the returned cert,
588 // and the public part is used to specify the signee.
589 // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
590 //
591 // The returned certificate is valid for the next 24 hours and must be presented only when
592 // the server name in the TLS ClientHello matches exactly the returned name value.
593 func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
594         b := sha256.Sum256([]byte(token))
595         h := hex.EncodeToString(b[:])
596         sanA := fmt.Sprintf("%s.%s.token.acme.invalid", h[:32], h[32:])
597
598         ka, err := keyAuth(c.Key.Public(), token)
599         if err != nil {
600                 return tls.Certificate{}, "", err
601         }
602         b = sha256.Sum256([]byte(ka))
603         h = hex.EncodeToString(b[:])
604         sanB := fmt.Sprintf("%s.%s.ka.acme.invalid", h[:32], h[32:])
605
606         cert, err = tlsChallengeCert([]string{sanA, sanB}, opt)
607         if err != nil {
608                 return tls.Certificate{}, "", err
609         }
610         return cert, sanA, nil
611 }
612
613 // TLSALPN01ChallengeCert creates a certificate for TLS-ALPN-01 challenge response.
614 // Servers can present the certificate to validate the challenge and prove control
615 // over a domain name. For more details on TLS-ALPN-01 see
616 // https://tools.ietf.org/html/draft-shoemaker-acme-tls-alpn-00#section-3
617 //
618 // The token argument is a Challenge.Token value.
619 // If a WithKey option is provided, its private part signs the returned cert,
620 // and the public part is used to specify the signee.
621 // If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
622 //
623 // The returned certificate is valid for the next 24 hours and must be presented only when
624 // the server name in the TLS ClientHello matches the domain, and the special acme-tls/1 ALPN protocol
625 // has been specified.
626 func (c *Client) TLSALPN01ChallengeCert(token, domain string, opt ...CertOption) (cert tls.Certificate, err error) {
627         ka, err := keyAuth(c.Key.Public(), token)
628         if err != nil {
629                 return tls.Certificate{}, err
630         }
631         shasum := sha256.Sum256([]byte(ka))
632         extValue, err := asn1.Marshal(shasum[:])
633         if err != nil {
634                 return tls.Certificate{}, err
635         }
636         acmeExtension := pkix.Extension{
637                 Id:       idPeACMEIdentifierV1,
638                 Critical: true,
639                 Value:    extValue,
640         }
641
642         tmpl := defaultTLSChallengeCertTemplate()
643
644         var newOpt []CertOption
645         for _, o := range opt {
646                 switch o := o.(type) {
647                 case *certOptTemplate:
648                         t := *(*x509.Certificate)(o) // shallow copy is ok
649                         tmpl = &t
650                 default:
651                         newOpt = append(newOpt, o)
652                 }
653         }
654         tmpl.ExtraExtensions = append(tmpl.ExtraExtensions, acmeExtension)
655         newOpt = append(newOpt, WithTemplate(tmpl))
656         return tlsChallengeCert([]string{domain}, newOpt)
657 }
658
659 // doReg sends all types of registration requests.
660 // The type of request is identified by typ argument, which is a "resource"
661 // in the ACME spec terms.
662 //
663 // A non-nil acct argument indicates whether the intention is to mutate data
664 // of the Account. Only Contact and Agreement of its fields are used
665 // in such cases.
666 func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Account) (*Account, error) {
667         req := struct {
668                 Resource  string   `json:"resource"`
669                 Contact   []string `json:"contact,omitempty"`
670                 Agreement string   `json:"agreement,omitempty"`
671         }{
672                 Resource: typ,
673         }
674         if acct != nil {
675                 req.Contact = acct.Contact
676                 req.Agreement = acct.AgreedTerms
677         }
678         res, err := c.post(ctx, c.Key, url, req, wantStatus(
679                 http.StatusOK,       // updates and deletes
680                 http.StatusCreated,  // new account creation
681                 http.StatusAccepted, // Let's Encrypt divergent implementation
682         ))
683         if err != nil {
684                 return nil, err
685         }
686         defer res.Body.Close()
687
688         var v struct {
689                 Contact        []string
690                 Agreement      string
691                 Authorizations string
692                 Certificates   string
693         }
694         if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
695                 return nil, fmt.Errorf("acme: invalid response: %v", err)
696         }
697         var tos string
698         if v := linkHeader(res.Header, "terms-of-service"); len(v) > 0 {
699                 tos = v[0]
700         }
701         var authz string
702         if v := linkHeader(res.Header, "next"); len(v) > 0 {
703                 authz = v[0]
704         }
705         return &Account{
706                 URI:            res.Header.Get("Location"),
707                 Contact:        v.Contact,
708                 AgreedTerms:    v.Agreement,
709                 CurrentTerms:   tos,
710                 Authz:          authz,
711                 Authorizations: v.Authorizations,
712                 Certificates:   v.Certificates,
713         }, nil
714 }
715
716 // popNonce returns a nonce value previously stored with c.addNonce
717 // or fetches a fresh one from a URL by issuing a HEAD request.
718 // It first tries c.directoryURL() and then the provided url if the former fails.
719 func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
720         c.noncesMu.Lock()
721         defer c.noncesMu.Unlock()
722         if len(c.nonces) == 0 {
723                 dirURL := c.directoryURL()
724                 v, err := c.fetchNonce(ctx, dirURL)
725                 if err != nil && url != dirURL {
726                         v, err = c.fetchNonce(ctx, url)
727                 }
728                 return v, err
729         }
730         var nonce string
731         for nonce = range c.nonces {
732                 delete(c.nonces, nonce)
733                 break
734         }
735         return nonce, nil
736 }
737
738 // clearNonces clears any stored nonces
739 func (c *Client) clearNonces() {
740         c.noncesMu.Lock()
741         defer c.noncesMu.Unlock()
742         c.nonces = make(map[string]struct{})
743 }
744
745 // addNonce stores a nonce value found in h (if any) for future use.
746 func (c *Client) addNonce(h http.Header) {
747         v := nonceFromHeader(h)
748         if v == "" {
749                 return
750         }
751         c.noncesMu.Lock()
752         defer c.noncesMu.Unlock()
753         if len(c.nonces) >= maxNonces {
754                 return
755         }
756         if c.nonces == nil {
757                 c.nonces = make(map[string]struct{})
758         }
759         c.nonces[v] = struct{}{}
760 }
761
762 func (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {
763         r, err := http.NewRequest("HEAD", url, nil)
764         if err != nil {
765                 return "", err
766         }
767         resp, err := c.doNoRetry(ctx, r)
768         if err != nil {
769                 return "", err
770         }
771         defer resp.Body.Close()
772         nonce := nonceFromHeader(resp.Header)
773         if nonce == "" {
774                 if resp.StatusCode > 299 {
775                         return "", responseError(resp)
776                 }
777                 return "", errors.New("acme: nonce not found")
778         }
779         return nonce, nil
780 }
781
782 func nonceFromHeader(h http.Header) string {
783         return h.Get("Replay-Nonce")
784 }
785
786 func (c *Client) responseCert(ctx context.Context, res *http.Response, bundle bool) ([][]byte, error) {
787         b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
788         if err != nil {
789                 return nil, fmt.Errorf("acme: response stream: %v", err)
790         }
791         if len(b) > maxCertSize {
792                 return nil, errors.New("acme: certificate is too big")
793         }
794         cert := [][]byte{b}
795         if !bundle {
796                 return cert, nil
797         }
798
799         // Append CA chain cert(s).
800         // At least one is required according to the spec:
801         // https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-6.3.1
802         up := linkHeader(res.Header, "up")
803         if len(up) == 0 {
804                 return nil, errors.New("acme: rel=up link not found")
805         }
806         if len(up) > maxChainLen {
807                 return nil, errors.New("acme: rel=up link is too large")
808         }
809         for _, url := range up {
810                 cc, err := c.chainCert(ctx, url, 0)
811                 if err != nil {
812                         return nil, err
813                 }
814                 cert = append(cert, cc...)
815         }
816         return cert, nil
817 }
818
819 // chainCert fetches CA certificate chain recursively by following "up" links.
820 // Each recursive call increments the depth by 1, resulting in an error
821 // if the recursion level reaches maxChainLen.
822 //
823 // First chainCert call starts with depth of 0.
824 func (c *Client) chainCert(ctx context.Context, url string, depth int) ([][]byte, error) {
825         if depth >= maxChainLen {
826                 return nil, errors.New("acme: certificate chain is too deep")
827         }
828
829         res, err := c.get(ctx, url, wantStatus(http.StatusOK))
830         if err != nil {
831                 return nil, err
832         }
833         defer res.Body.Close()
834         b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
835         if err != nil {
836                 return nil, err
837         }
838         if len(b) > maxCertSize {
839                 return nil, errors.New("acme: certificate is too big")
840         }
841         chain := [][]byte{b}
842
843         uplink := linkHeader(res.Header, "up")
844         if len(uplink) > maxChainLen {
845                 return nil, errors.New("acme: certificate chain is too large")
846         }
847         for _, up := range uplink {
848                 cc, err := c.chainCert(ctx, up, depth+1)
849                 if err != nil {
850                         return nil, err
851                 }
852                 chain = append(chain, cc...)
853         }
854
855         return chain, nil
856 }
857
858 // linkHeader returns URI-Reference values of all Link headers
859 // with relation-type rel.
860 // See https://tools.ietf.org/html/rfc5988#section-5 for details.
861 func linkHeader(h http.Header, rel string) []string {
862         var links []string
863         for _, v := range h["Link"] {
864                 parts := strings.Split(v, ";")
865                 for _, p := range parts {
866                         p = strings.TrimSpace(p)
867                         if !strings.HasPrefix(p, "rel=") {
868                                 continue
869                         }
870                         if v := strings.Trim(p[4:], `"`); v == rel {
871                                 links = append(links, strings.Trim(parts[0], "<>"))
872                         }
873                 }
874         }
875         return links
876 }
877
878 // keyAuth generates a key authorization string for a given token.
879 func keyAuth(pub crypto.PublicKey, token string) (string, error) {
880         th, err := JWKThumbprint(pub)
881         if err != nil {
882                 return "", err
883         }
884         return fmt.Sprintf("%s.%s", token, th), nil
885 }
886
887 // defaultTLSChallengeCertTemplate is a template used to create challenge certs for TLS challenges.
888 func defaultTLSChallengeCertTemplate() *x509.Certificate {
889         return &x509.Certificate{
890                 SerialNumber:          big.NewInt(1),
891                 NotBefore:             time.Now(),
892                 NotAfter:              time.Now().Add(24 * time.Hour),
893                 BasicConstraintsValid: true,
894                 KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
895                 ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
896         }
897 }
898
899 // tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
900 // with the given SANs and auto-generated public/private key pair.
901 // The Subject Common Name is set to the first SAN to aid debugging.
902 // To create a cert with a custom key pair, specify WithKey option.
903 func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
904         var key crypto.Signer
905         tmpl := defaultTLSChallengeCertTemplate()
906         for _, o := range opt {
907                 switch o := o.(type) {
908                 case *certOptKey:
909                         if key != nil {
910                                 return tls.Certificate{}, errors.New("acme: duplicate key option")
911                         }
912                         key = o.key
913                 case *certOptTemplate:
914                         t := *(*x509.Certificate)(o) // shallow copy is ok
915                         tmpl = &t
916                 default:
917                         // package's fault, if we let this happen:
918                         panic(fmt.Sprintf("unsupported option type %T", o))
919                 }
920         }
921         if key == nil {
922                 var err error
923                 if key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {
924                         return tls.Certificate{}, err
925                 }
926         }
927         tmpl.DNSNames = san
928         if len(san) > 0 {
929                 tmpl.Subject.CommonName = san[0]
930         }
931
932         der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)
933         if err != nil {
934                 return tls.Certificate{}, err
935         }
936         return tls.Certificate{
937                 Certificate: [][]byte{der},
938                 PrivateKey:  key,
939         }, nil
940 }
941
942 // encodePEM returns b encoded as PEM with block of type typ.
943 func encodePEM(typ string, b []byte) []byte {
944         pb := &pem.Block{Type: typ, Bytes: b}
945         return pem.EncodeToMemory(pb)
946 }
947
948 // timeNow is useful for testing for fixed current time.
949 var timeNow = time.Now