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