github.com/devops-filetransfer/sshego@v7.0.4+incompatible/_vendor/golang.org/x/crypto/acme/acme.go (about)

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