gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

acme.go (27459B)


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