...

Source file src/golang.org/x/crypto/acme/autocert/autocert.go

Documentation: golang.org/x/crypto/acme/autocert

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package autocert provides automatic access to certificates from Let's Encrypt
     6  // and any other ACME-based CA.
     7  //
     8  // This package is a work in progress and makes no API stability promises.
     9  package autocert
    10  
    11  import (
    12  	"bytes"
    13  	"context"
    14  	"crypto"
    15  	"crypto/ecdsa"
    16  	"crypto/elliptic"
    17  	"crypto/rand"
    18  	"crypto/rsa"
    19  	"crypto/tls"
    20  	"crypto/x509"
    21  	"crypto/x509/pkix"
    22  	"encoding/pem"
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  	mathrand "math/rand"
    27  	"net"
    28  	"net/http"
    29  	"path"
    30  	"strings"
    31  	"sync"
    32  	"time"
    33  
    34  	"golang.org/x/crypto/acme"
    35  	"golang.org/x/net/idna"
    36  )
    37  
    38  // DefaultACMEDirectory is the default ACME Directory URL used when the Manager's Client is nil.
    39  const DefaultACMEDirectory = "https://acme-v02.api.letsencrypt.org/directory"
    40  
    41  // createCertRetryAfter is how much time to wait before removing a failed state
    42  // entry due to an unsuccessful createCert call.
    43  // This is a variable instead of a const for testing.
    44  // TODO: Consider making it configurable or an exp backoff?
    45  var createCertRetryAfter = time.Minute
    46  
    47  // pseudoRand is safe for concurrent use.
    48  var pseudoRand *lockedMathRand
    49  
    50  var errPreRFC = errors.New("autocert: ACME server doesn't support RFC 8555")
    51  
    52  func init() {
    53  	src := mathrand.NewSource(time.Now().UnixNano())
    54  	pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
    55  }
    56  
    57  // AcceptTOS is a Manager.Prompt function that always returns true to
    58  // indicate acceptance of the CA's Terms of Service during account
    59  // registration.
    60  func AcceptTOS(tosURL string) bool { return true }
    61  
    62  // HostPolicy specifies which host names the Manager is allowed to respond to.
    63  // It returns a non-nil error if the host should be rejected.
    64  // The returned error is accessible via tls.Conn.Handshake and its callers.
    65  // See Manager's HostPolicy field and GetCertificate method docs for more details.
    66  type HostPolicy func(ctx context.Context, host string) error
    67  
    68  // HostWhitelist returns a policy where only the specified host names are allowed.
    69  // Only exact matches are currently supported. Subdomains, regexp or wildcard
    70  // will not match.
    71  //
    72  // Note that all hosts will be converted to Punycode via idna.Lookup.ToASCII so that
    73  // Manager.GetCertificate can handle the Unicode IDN and mixedcase hosts correctly.
    74  // Invalid hosts will be silently ignored.
    75  func HostWhitelist(hosts ...string) HostPolicy {
    76  	whitelist := make(map[string]bool, len(hosts))
    77  	for _, h := range hosts {
    78  		if h, err := idna.Lookup.ToASCII(h); err == nil {
    79  			whitelist[h] = true
    80  		}
    81  	}
    82  	return func(_ context.Context, host string) error {
    83  		if !whitelist[host] {
    84  			return fmt.Errorf("acme/autocert: host %q not configured in HostWhitelist", host)
    85  		}
    86  		return nil
    87  	}
    88  }
    89  
    90  // defaultHostPolicy is used when Manager.HostPolicy is not set.
    91  func defaultHostPolicy(context.Context, string) error {
    92  	return nil
    93  }
    94  
    95  // Manager is a stateful certificate manager built on top of acme.Client.
    96  // It obtains and refreshes certificates automatically using "tls-alpn-01"
    97  // or "http-01" challenge types, as well as providing them to a TLS server
    98  // via tls.Config.
    99  //
   100  // You must specify a cache implementation, such as DirCache,
   101  // to reuse obtained certificates across program restarts.
   102  // Otherwise your server is very likely to exceed the certificate
   103  // issuer's request rate limits.
   104  type Manager struct {
   105  	// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
   106  	// The registration may require the caller to agree to the CA's TOS.
   107  	// If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
   108  	// whether the caller agrees to the terms.
   109  	//
   110  	// To always accept the terms, the callers can use AcceptTOS.
   111  	Prompt func(tosURL string) bool
   112  
   113  	// Cache optionally stores and retrieves previously-obtained certificates
   114  	// and other state. If nil, certs will only be cached for the lifetime of
   115  	// the Manager. Multiple Managers can share the same Cache.
   116  	//
   117  	// Using a persistent Cache, such as DirCache, is strongly recommended.
   118  	Cache Cache
   119  
   120  	// HostPolicy controls which domains the Manager will attempt
   121  	// to retrieve new certificates for. It does not affect cached certs.
   122  	//
   123  	// If non-nil, HostPolicy is called before requesting a new cert.
   124  	// If nil, all hosts are currently allowed. This is not recommended,
   125  	// as it opens a potential attack where clients connect to a server
   126  	// by IP address and pretend to be asking for an incorrect host name.
   127  	// Manager will attempt to obtain a certificate for that host, incorrectly,
   128  	// eventually reaching the CA's rate limit for certificate requests
   129  	// and making it impossible to obtain actual certificates.
   130  	//
   131  	// See GetCertificate for more details.
   132  	HostPolicy HostPolicy
   133  
   134  	// RenewBefore optionally specifies how early certificates should
   135  	// be renewed before they expire.
   136  	//
   137  	// If zero, they're renewed 30 days before expiration.
   138  	RenewBefore time.Duration
   139  
   140  	// Client is used to perform low-level operations, such as account registration
   141  	// and requesting new certificates.
   142  	//
   143  	// If Client is nil, a zero-value acme.Client is used with DefaultACMEDirectory
   144  	// as the directory endpoint.
   145  	// If the Client.Key is nil, a new ECDSA P-256 key is generated and,
   146  	// if Cache is not nil, stored in cache.
   147  	//
   148  	// Mutating the field after the first call of GetCertificate method will have no effect.
   149  	Client *acme.Client
   150  
   151  	// Email optionally specifies a contact email address.
   152  	// This is used by CAs, such as Let's Encrypt, to notify about problems
   153  	// with issued certificates.
   154  	//
   155  	// If the Client's account key is already registered, Email is not used.
   156  	Email string
   157  
   158  	// ForceRSA used to make the Manager generate RSA certificates. It is now ignored.
   159  	//
   160  	// Deprecated: the Manager will request the correct type of certificate based
   161  	// on what each client supports.
   162  	ForceRSA bool
   163  
   164  	// ExtraExtensions are used when generating a new CSR (Certificate Request),
   165  	// thus allowing customization of the resulting certificate.
   166  	// For instance, TLS Feature Extension (RFC 7633) can be used
   167  	// to prevent an OCSP downgrade attack.
   168  	//
   169  	// The field value is passed to crypto/x509.CreateCertificateRequest
   170  	// in the template's ExtraExtensions field as is.
   171  	ExtraExtensions []pkix.Extension
   172  
   173  	// ExternalAccountBinding optionally represents an arbitrary binding to an
   174  	// account of the CA to which the ACME server is tied.
   175  	// See RFC 8555, Section 7.3.4 for more details.
   176  	ExternalAccountBinding *acme.ExternalAccountBinding
   177  
   178  	clientMu sync.Mutex
   179  	client   *acme.Client // initialized by acmeClient method
   180  
   181  	stateMu sync.Mutex
   182  	state   map[certKey]*certState
   183  
   184  	// renewal tracks the set of domains currently running renewal timers.
   185  	renewalMu sync.Mutex
   186  	renewal   map[certKey]*domainRenewal
   187  
   188  	// challengeMu guards tryHTTP01, certTokens and httpTokens.
   189  	challengeMu sync.RWMutex
   190  	// tryHTTP01 indicates whether the Manager should try "http-01" challenge type
   191  	// during the authorization flow.
   192  	tryHTTP01 bool
   193  	// httpTokens contains response body values for http-01 challenges
   194  	// and is keyed by the URL path at which a challenge response is expected
   195  	// to be provisioned.
   196  	// The entries are stored for the duration of the authorization flow.
   197  	httpTokens map[string][]byte
   198  	// certTokens contains temporary certificates for tls-alpn-01 challenges
   199  	// and is keyed by the domain name which matches the ClientHello server name.
   200  	// The entries are stored for the duration of the authorization flow.
   201  	certTokens map[string]*tls.Certificate
   202  
   203  	// nowFunc, if not nil, returns the current time. This may be set for
   204  	// testing purposes.
   205  	nowFunc func() time.Time
   206  }
   207  
   208  // certKey is the key by which certificates are tracked in state, renewal and cache.
   209  type certKey struct {
   210  	domain  string // without trailing dot
   211  	isRSA   bool   // RSA cert for legacy clients (as opposed to default ECDSA)
   212  	isToken bool   // tls-based challenge token cert; key type is undefined regardless of isRSA
   213  }
   214  
   215  func (c certKey) String() string {
   216  	if c.isToken {
   217  		return c.domain + "+token"
   218  	}
   219  	if c.isRSA {
   220  		return c.domain + "+rsa"
   221  	}
   222  	return c.domain
   223  }
   224  
   225  // TLSConfig creates a new TLS config suitable for net/http.Server servers,
   226  // supporting HTTP/2 and the tls-alpn-01 ACME challenge type.
   227  func (m *Manager) TLSConfig() *tls.Config {
   228  	return &tls.Config{
   229  		GetCertificate: m.GetCertificate,
   230  		NextProtos: []string{
   231  			"h2", "http/1.1", // enable HTTP/2
   232  			acme.ALPNProto, // enable tls-alpn ACME challenges
   233  		},
   234  	}
   235  }
   236  
   237  // GetCertificate implements the tls.Config.GetCertificate hook.
   238  // It provides a TLS certificate for hello.ServerName host, including answering
   239  // tls-alpn-01 challenges.
   240  // All other fields of hello are ignored.
   241  //
   242  // If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
   243  // a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
   244  // The error is propagated back to the caller of GetCertificate and is user-visible.
   245  // This does not affect cached certs. See HostPolicy field description for more details.
   246  //
   247  // If GetCertificate is used directly, instead of via Manager.TLSConfig, package users will
   248  // also have to add acme.ALPNProto to NextProtos for tls-alpn-01, or use HTTPHandler for http-01.
   249  func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
   250  	if m.Prompt == nil {
   251  		return nil, errors.New("acme/autocert: Manager.Prompt not set")
   252  	}
   253  
   254  	name := hello.ServerName
   255  	if name == "" {
   256  		return nil, errors.New("acme/autocert: missing server name")
   257  	}
   258  	if !strings.Contains(strings.Trim(name, "."), ".") {
   259  		return nil, errors.New("acme/autocert: server name component count invalid")
   260  	}
   261  
   262  	// Note that this conversion is necessary because some server names in the handshakes
   263  	// started by some clients (such as cURL) are not converted to Punycode, which will
   264  	// prevent us from obtaining certificates for them. In addition, we should also treat
   265  	// example.com and EXAMPLE.COM as equivalent and return the same certificate for them.
   266  	// Fortunately, this conversion also helped us deal with this kind of mixedcase problems.
   267  	//
   268  	// Due to the "σςΣ" problem (see https://unicode.org/faq/idn.html#22), we can't use
   269  	// idna.Punycode.ToASCII (or just idna.ToASCII) here.
   270  	name, err := idna.Lookup.ToASCII(name)
   271  	if err != nil {
   272  		return nil, errors.New("acme/autocert: server name contains invalid character")
   273  	}
   274  
   275  	// In the worst-case scenario, the timeout needs to account for caching, host policy,
   276  	// domain ownership verification and certificate issuance.
   277  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
   278  	defer cancel()
   279  
   280  	// Check whether this is a token cert requested for TLS-ALPN challenge.
   281  	if wantsTokenCert(hello) {
   282  		m.challengeMu.RLock()
   283  		defer m.challengeMu.RUnlock()
   284  		if cert := m.certTokens[name]; cert != nil {
   285  			return cert, nil
   286  		}
   287  		if cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {
   288  			return cert, nil
   289  		}
   290  		// TODO: cache error results?
   291  		return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
   292  	}
   293  
   294  	// regular domain
   295  	ck := certKey{
   296  		domain: strings.TrimSuffix(name, "."), // golang.org/issue/18114
   297  		isRSA:  !supportsECDSA(hello),
   298  	}
   299  	cert, err := m.cert(ctx, ck)
   300  	if err == nil {
   301  		return cert, nil
   302  	}
   303  	if err != ErrCacheMiss {
   304  		return nil, err
   305  	}
   306  
   307  	// first-time
   308  	if err := m.hostPolicy()(ctx, name); err != nil {
   309  		return nil, err
   310  	}
   311  	cert, err = m.createCert(ctx, ck)
   312  	if err != nil {
   313  		return nil, err
   314  	}
   315  	m.cachePut(ctx, ck, cert)
   316  	return cert, nil
   317  }
   318  
   319  // wantsTokenCert reports whether a TLS request with SNI is made by a CA server
   320  // for a challenge verification.
   321  func wantsTokenCert(hello *tls.ClientHelloInfo) bool {
   322  	// tls-alpn-01
   323  	if len(hello.SupportedProtos) == 1 && hello.SupportedProtos[0] == acme.ALPNProto {
   324  		return true
   325  	}
   326  	return false
   327  }
   328  
   329  func supportsECDSA(hello *tls.ClientHelloInfo) bool {
   330  	// The "signature_algorithms" extension, if present, limits the key exchange
   331  	// algorithms allowed by the cipher suites. See RFC 5246, section 7.4.1.4.1.
   332  	if hello.SignatureSchemes != nil {
   333  		ecdsaOK := false
   334  	schemeLoop:
   335  		for _, scheme := range hello.SignatureSchemes {
   336  			const tlsECDSAWithSHA1 tls.SignatureScheme = 0x0203 // constant added in Go 1.10
   337  			switch scheme {
   338  			case tlsECDSAWithSHA1, tls.ECDSAWithP256AndSHA256,
   339  				tls.ECDSAWithP384AndSHA384, tls.ECDSAWithP521AndSHA512:
   340  				ecdsaOK = true
   341  				break schemeLoop
   342  			}
   343  		}
   344  		if !ecdsaOK {
   345  			return false
   346  		}
   347  	}
   348  	if hello.SupportedCurves != nil {
   349  		ecdsaOK := false
   350  		for _, curve := range hello.SupportedCurves {
   351  			if curve == tls.CurveP256 {
   352  				ecdsaOK = true
   353  				break
   354  			}
   355  		}
   356  		if !ecdsaOK {
   357  			return false
   358  		}
   359  	}
   360  	for _, suite := range hello.CipherSuites {
   361  		switch suite {
   362  		case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
   363  			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
   364  			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
   365  			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
   366  			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
   367  			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
   368  			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
   369  			return true
   370  		}
   371  	}
   372  	return false
   373  }
   374  
   375  // HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
   376  // It returns an http.Handler that responds to the challenges and must be
   377  // running on port 80. If it receives a request that is not an ACME challenge,
   378  // it delegates the request to the optional fallback handler.
   379  //
   380  // If fallback is nil, the returned handler redirects all GET and HEAD requests
   381  // to the default TLS port 443 with 302 Found status code, preserving the original
   382  // request path and query. It responds with 400 Bad Request to all other HTTP methods.
   383  // The fallback is not protected by the optional HostPolicy.
   384  //
   385  // Because the fallback handler is run with unencrypted port 80 requests,
   386  // the fallback should not serve TLS-only requests.
   387  //
   388  // If HTTPHandler is never called, the Manager will only use the "tls-alpn-01"
   389  // challenge for domain verification.
   390  func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
   391  	m.challengeMu.Lock()
   392  	defer m.challengeMu.Unlock()
   393  	m.tryHTTP01 = true
   394  
   395  	if fallback == nil {
   396  		fallback = http.HandlerFunc(handleHTTPRedirect)
   397  	}
   398  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   399  		if !strings.HasPrefix(r.URL.Path, "/.well-known/acme-challenge/") {
   400  			fallback.ServeHTTP(w, r)
   401  			return
   402  		}
   403  		// A reasonable context timeout for cache and host policy only,
   404  		// because we don't wait for a new certificate issuance here.
   405  		ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
   406  		defer cancel()
   407  		if err := m.hostPolicy()(ctx, r.Host); err != nil {
   408  			http.Error(w, err.Error(), http.StatusForbidden)
   409  			return
   410  		}
   411  		data, err := m.httpToken(ctx, r.URL.Path)
   412  		if err != nil {
   413  			http.Error(w, err.Error(), http.StatusNotFound)
   414  			return
   415  		}
   416  		w.Write(data)
   417  	})
   418  }
   419  
   420  func handleHTTPRedirect(w http.ResponseWriter, r *http.Request) {
   421  	if r.Method != "GET" && r.Method != "HEAD" {
   422  		http.Error(w, "Use HTTPS", http.StatusBadRequest)
   423  		return
   424  	}
   425  	target := "https://" + stripPort(r.Host) + r.URL.RequestURI()
   426  	http.Redirect(w, r, target, http.StatusFound)
   427  }
   428  
   429  func stripPort(hostport string) string {
   430  	host, _, err := net.SplitHostPort(hostport)
   431  	if err != nil {
   432  		return hostport
   433  	}
   434  	return net.JoinHostPort(host, "443")
   435  }
   436  
   437  // cert returns an existing certificate either from m.state or cache.
   438  // If a certificate is found in cache but not in m.state, the latter will be filled
   439  // with the cached value.
   440  func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
   441  	m.stateMu.Lock()
   442  	if s, ok := m.state[ck]; ok {
   443  		m.stateMu.Unlock()
   444  		s.RLock()
   445  		defer s.RUnlock()
   446  		return s.tlscert()
   447  	}
   448  	defer m.stateMu.Unlock()
   449  	cert, err := m.cacheGet(ctx, ck)
   450  	if err != nil {
   451  		return nil, err
   452  	}
   453  	signer, ok := cert.PrivateKey.(crypto.Signer)
   454  	if !ok {
   455  		return nil, errors.New("acme/autocert: private key cannot sign")
   456  	}
   457  	if m.state == nil {
   458  		m.state = make(map[certKey]*certState)
   459  	}
   460  	s := &certState{
   461  		key:  signer,
   462  		cert: cert.Certificate,
   463  		leaf: cert.Leaf,
   464  	}
   465  	m.state[ck] = s
   466  	m.startRenew(ck, s.key, s.leaf.NotAfter)
   467  	return cert, nil
   468  }
   469  
   470  // cacheGet always returns a valid certificate, or an error otherwise.
   471  // If a cached certificate exists but is not valid, ErrCacheMiss is returned.
   472  func (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, error) {
   473  	if m.Cache == nil {
   474  		return nil, ErrCacheMiss
   475  	}
   476  	data, err := m.Cache.Get(ctx, ck.String())
   477  	if err != nil {
   478  		return nil, err
   479  	}
   480  
   481  	// private
   482  	priv, pub := pem.Decode(data)
   483  	if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
   484  		return nil, ErrCacheMiss
   485  	}
   486  	privKey, err := parsePrivateKey(priv.Bytes)
   487  	if err != nil {
   488  		return nil, err
   489  	}
   490  
   491  	// public
   492  	var pubDER [][]byte
   493  	for len(pub) > 0 {
   494  		var b *pem.Block
   495  		b, pub = pem.Decode(pub)
   496  		if b == nil {
   497  			break
   498  		}
   499  		pubDER = append(pubDER, b.Bytes)
   500  	}
   501  	if len(pub) > 0 {
   502  		// Leftover content not consumed by pem.Decode. Corrupt. Ignore.
   503  		return nil, ErrCacheMiss
   504  	}
   505  
   506  	// verify and create TLS cert
   507  	leaf, err := validCert(ck, pubDER, privKey, m.now())
   508  	if err != nil {
   509  		return nil, ErrCacheMiss
   510  	}
   511  	tlscert := &tls.Certificate{
   512  		Certificate: pubDER,
   513  		PrivateKey:  privKey,
   514  		Leaf:        leaf,
   515  	}
   516  	return tlscert, nil
   517  }
   518  
   519  func (m *Manager) cachePut(ctx context.Context, ck certKey, tlscert *tls.Certificate) error {
   520  	if m.Cache == nil {
   521  		return nil
   522  	}
   523  
   524  	// contains PEM-encoded data
   525  	var buf bytes.Buffer
   526  
   527  	// private
   528  	switch key := tlscert.PrivateKey.(type) {
   529  	case *ecdsa.PrivateKey:
   530  		if err := encodeECDSAKey(&buf, key); err != nil {
   531  			return err
   532  		}
   533  	case *rsa.PrivateKey:
   534  		b := x509.MarshalPKCS1PrivateKey(key)
   535  		pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
   536  		if err := pem.Encode(&buf, pb); err != nil {
   537  			return err
   538  		}
   539  	default:
   540  		return errors.New("acme/autocert: unknown private key type")
   541  	}
   542  
   543  	// public
   544  	for _, b := range tlscert.Certificate {
   545  		pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
   546  		if err := pem.Encode(&buf, pb); err != nil {
   547  			return err
   548  		}
   549  	}
   550  
   551  	return m.Cache.Put(ctx, ck.String(), buf.Bytes())
   552  }
   553  
   554  func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
   555  	b, err := x509.MarshalECPrivateKey(key)
   556  	if err != nil {
   557  		return err
   558  	}
   559  	pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
   560  	return pem.Encode(w, pb)
   561  }
   562  
   563  // createCert starts the domain ownership verification and returns a certificate
   564  // for that domain upon success.
   565  //
   566  // If the domain is already being verified, it waits for the existing verification to complete.
   567  // Either way, createCert blocks for the duration of the whole process.
   568  func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
   569  	// TODO: maybe rewrite this whole piece using sync.Once
   570  	state, err := m.certState(ck)
   571  	if err != nil {
   572  		return nil, err
   573  	}
   574  	// state may exist if another goroutine is already working on it
   575  	// in which case just wait for it to finish
   576  	if !state.locked {
   577  		state.RLock()
   578  		defer state.RUnlock()
   579  		return state.tlscert()
   580  	}
   581  
   582  	// We are the first; state is locked.
   583  	// Unblock the readers when domain ownership is verified
   584  	// and we got the cert or the process failed.
   585  	defer state.Unlock()
   586  	state.locked = false
   587  
   588  	der, leaf, err := m.authorizedCert(ctx, state.key, ck)
   589  	if err != nil {
   590  		// Remove the failed state after some time,
   591  		// making the manager call createCert again on the following TLS hello.
   592  		didRemove := testDidRemoveState // The lifetime of this timer is untracked, so copy mutable local state to avoid races.
   593  		time.AfterFunc(createCertRetryAfter, func() {
   594  			defer didRemove(ck)
   595  			m.stateMu.Lock()
   596  			defer m.stateMu.Unlock()
   597  			// Verify the state hasn't changed and it's still invalid
   598  			// before deleting.
   599  			s, ok := m.state[ck]
   600  			if !ok {
   601  				return
   602  			}
   603  			if _, err := validCert(ck, s.cert, s.key, m.now()); err == nil {
   604  				return
   605  			}
   606  			delete(m.state, ck)
   607  		})
   608  		return nil, err
   609  	}
   610  	state.cert = der
   611  	state.leaf = leaf
   612  	m.startRenew(ck, state.key, state.leaf.NotAfter)
   613  	return state.tlscert()
   614  }
   615  
   616  // certState returns a new or existing certState.
   617  // If a new certState is returned, state.exist is false and the state is locked.
   618  // The returned error is non-nil only in the case where a new state could not be created.
   619  func (m *Manager) certState(ck certKey) (*certState, error) {
   620  	m.stateMu.Lock()
   621  	defer m.stateMu.Unlock()
   622  	if m.state == nil {
   623  		m.state = make(map[certKey]*certState)
   624  	}
   625  	// existing state
   626  	if state, ok := m.state[ck]; ok {
   627  		return state, nil
   628  	}
   629  
   630  	// new locked state
   631  	var (
   632  		err error
   633  		key crypto.Signer
   634  	)
   635  	if ck.isRSA {
   636  		key, err = rsa.GenerateKey(rand.Reader, 2048)
   637  	} else {
   638  		key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   639  	}
   640  	if err != nil {
   641  		return nil, err
   642  	}
   643  
   644  	state := &certState{
   645  		key:    key,
   646  		locked: true,
   647  	}
   648  	state.Lock() // will be unlocked by m.certState caller
   649  	m.state[ck] = state
   650  	return state, nil
   651  }
   652  
   653  // authorizedCert starts the domain ownership verification process and requests a new cert upon success.
   654  // The key argument is the certificate private key.
   655  func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck certKey) (der [][]byte, leaf *x509.Certificate, err error) {
   656  	csr, err := certRequest(key, ck.domain, m.ExtraExtensions)
   657  	if err != nil {
   658  		return nil, nil, err
   659  	}
   660  
   661  	client, err := m.acmeClient(ctx)
   662  	if err != nil {
   663  		return nil, nil, err
   664  	}
   665  	dir, err := client.Discover(ctx)
   666  	if err != nil {
   667  		return nil, nil, err
   668  	}
   669  	if dir.OrderURL == "" {
   670  		return nil, nil, errPreRFC
   671  	}
   672  
   673  	o, err := m.verifyRFC(ctx, client, ck.domain)
   674  	if err != nil {
   675  		return nil, nil, err
   676  	}
   677  	chain, _, err := client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
   678  	if err != nil {
   679  		return nil, nil, err
   680  	}
   681  
   682  	leaf, err = validCert(ck, chain, key, m.now())
   683  	if err != nil {
   684  		return nil, nil, err
   685  	}
   686  	return chain, leaf, nil
   687  }
   688  
   689  // verifyRFC runs the identifier (domain) order-based authorization flow for RFC compliant CAs
   690  // using each applicable ACME challenge type.
   691  func (m *Manager) verifyRFC(ctx context.Context, client *acme.Client, domain string) (*acme.Order, error) {
   692  	// Try each supported challenge type starting with a new order each time.
   693  	// The nextTyp index of the next challenge type to try is shared across
   694  	// all order authorizations: if we've tried a challenge type once and it didn't work,
   695  	// it will most likely not work on another order's authorization either.
   696  	challengeTypes := m.supportedChallengeTypes()
   697  	nextTyp := 0 // challengeTypes index
   698  AuthorizeOrderLoop:
   699  	for {
   700  		o, err := client.AuthorizeOrder(ctx, acme.DomainIDs(domain))
   701  		if err != nil {
   702  			return nil, err
   703  		}
   704  		// Remove all hanging authorizations to reduce rate limit quotas
   705  		// after we're done.
   706  		defer func(urls []string) {
   707  			go m.deactivatePendingAuthz(urls)
   708  		}(o.AuthzURLs)
   709  
   710  		// Check if there's actually anything we need to do.
   711  		switch o.Status {
   712  		case acme.StatusReady:
   713  			// Already authorized.
   714  			return o, nil
   715  		case acme.StatusPending:
   716  			// Continue normal Order-based flow.
   717  		default:
   718  			return nil, fmt.Errorf("acme/autocert: invalid new order status %q; order URL: %q", o.Status, o.URI)
   719  		}
   720  
   721  		// Satisfy all pending authorizations.
   722  		for _, zurl := range o.AuthzURLs {
   723  			z, err := client.GetAuthorization(ctx, zurl)
   724  			if err != nil {
   725  				return nil, err
   726  			}
   727  			if z.Status != acme.StatusPending {
   728  				// We are interested only in pending authorizations.
   729  				continue
   730  			}
   731  			// Pick the next preferred challenge.
   732  			var chal *acme.Challenge
   733  			for chal == nil && nextTyp < len(challengeTypes) {
   734  				chal = pickChallenge(challengeTypes[nextTyp], z.Challenges)
   735  				nextTyp++
   736  			}
   737  			if chal == nil {
   738  				return nil, fmt.Errorf("acme/autocert: unable to satisfy %q for domain %q: no viable challenge type found", z.URI, domain)
   739  			}
   740  			// Respond to the challenge and wait for validation result.
   741  			cleanup, err := m.fulfill(ctx, client, chal, domain)
   742  			if err != nil {
   743  				continue AuthorizeOrderLoop
   744  			}
   745  			defer cleanup()
   746  			if _, err := client.Accept(ctx, chal); err != nil {
   747  				continue AuthorizeOrderLoop
   748  			}
   749  			if _, err := client.WaitAuthorization(ctx, z.URI); err != nil {
   750  				continue AuthorizeOrderLoop
   751  			}
   752  		}
   753  
   754  		// All authorizations are satisfied.
   755  		// Wait for the CA to update the order status.
   756  		o, err = client.WaitOrder(ctx, o.URI)
   757  		if err != nil {
   758  			continue AuthorizeOrderLoop
   759  		}
   760  		return o, nil
   761  	}
   762  }
   763  
   764  func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
   765  	for _, c := range chal {
   766  		if c.Type == typ {
   767  			return c
   768  		}
   769  	}
   770  	return nil
   771  }
   772  
   773  func (m *Manager) supportedChallengeTypes() []string {
   774  	m.challengeMu.RLock()
   775  	defer m.challengeMu.RUnlock()
   776  	typ := []string{"tls-alpn-01"}
   777  	if m.tryHTTP01 {
   778  		typ = append(typ, "http-01")
   779  	}
   780  	return typ
   781  }
   782  
   783  // deactivatePendingAuthz relinquishes all authorizations identified by the elements
   784  // of the provided uri slice which are in "pending" state.
   785  // It ignores revocation errors.
   786  //
   787  // deactivatePendingAuthz takes no context argument and instead runs with its own
   788  // "detached" context because deactivations are done in a goroutine separate from
   789  // that of the main issuance or renewal flow.
   790  func (m *Manager) deactivatePendingAuthz(uri []string) {
   791  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
   792  	defer cancel()
   793  	client, err := m.acmeClient(ctx)
   794  	if err != nil {
   795  		return
   796  	}
   797  	for _, u := range uri {
   798  		z, err := client.GetAuthorization(ctx, u)
   799  		if err == nil && z.Status == acme.StatusPending {
   800  			client.RevokeAuthorization(ctx, u)
   801  		}
   802  	}
   803  }
   804  
   805  // fulfill provisions a response to the challenge chal.
   806  // The cleanup is non-nil only if provisioning succeeded.
   807  func (m *Manager) fulfill(ctx context.Context, client *acme.Client, chal *acme.Challenge, domain string) (cleanup func(), err error) {
   808  	switch chal.Type {
   809  	case "tls-alpn-01":
   810  		cert, err := client.TLSALPN01ChallengeCert(chal.Token, domain)
   811  		if err != nil {
   812  			return nil, err
   813  		}
   814  		m.putCertToken(ctx, domain, &cert)
   815  		return func() { go m.deleteCertToken(domain) }, nil
   816  	case "http-01":
   817  		resp, err := client.HTTP01ChallengeResponse(chal.Token)
   818  		if err != nil {
   819  			return nil, err
   820  		}
   821  		p := client.HTTP01ChallengePath(chal.Token)
   822  		m.putHTTPToken(ctx, p, resp)
   823  		return func() { go m.deleteHTTPToken(p) }, nil
   824  	}
   825  	return nil, fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
   826  }
   827  
   828  // putCertToken stores the token certificate with the specified name
   829  // in both m.certTokens map and m.Cache.
   830  func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
   831  	m.challengeMu.Lock()
   832  	defer m.challengeMu.Unlock()
   833  	if m.certTokens == nil {
   834  		m.certTokens = make(map[string]*tls.Certificate)
   835  	}
   836  	m.certTokens[name] = cert
   837  	m.cachePut(ctx, certKey{domain: name, isToken: true}, cert)
   838  }
   839  
   840  // deleteCertToken removes the token certificate with the specified name
   841  // from both m.certTokens map and m.Cache.
   842  func (m *Manager) deleteCertToken(name string) {
   843  	m.challengeMu.Lock()
   844  	defer m.challengeMu.Unlock()
   845  	delete(m.certTokens, name)
   846  	if m.Cache != nil {
   847  		ck := certKey{domain: name, isToken: true}
   848  		m.Cache.Delete(context.Background(), ck.String())
   849  	}
   850  }
   851  
   852  // httpToken retrieves an existing http-01 token value from an in-memory map
   853  // or the optional cache.
   854  func (m *Manager) httpToken(ctx context.Context, tokenPath string) ([]byte, error) {
   855  	m.challengeMu.RLock()
   856  	defer m.challengeMu.RUnlock()
   857  	if v, ok := m.httpTokens[tokenPath]; ok {
   858  		return v, nil
   859  	}
   860  	if m.Cache == nil {
   861  		return nil, fmt.Errorf("acme/autocert: no token at %q", tokenPath)
   862  	}
   863  	return m.Cache.Get(ctx, httpTokenCacheKey(tokenPath))
   864  }
   865  
   866  // putHTTPToken stores an http-01 token value using tokenPath as key
   867  // in both in-memory map and the optional Cache.
   868  //
   869  // It ignores any error returned from Cache.Put.
   870  func (m *Manager) putHTTPToken(ctx context.Context, tokenPath, val string) {
   871  	m.challengeMu.Lock()
   872  	defer m.challengeMu.Unlock()
   873  	if m.httpTokens == nil {
   874  		m.httpTokens = make(map[string][]byte)
   875  	}
   876  	b := []byte(val)
   877  	m.httpTokens[tokenPath] = b
   878  	if m.Cache != nil {
   879  		m.Cache.Put(ctx, httpTokenCacheKey(tokenPath), b)
   880  	}
   881  }
   882  
   883  // deleteHTTPToken removes an http-01 token value from both in-memory map
   884  // and the optional Cache, ignoring any error returned from the latter.
   885  //
   886  // If m.Cache is non-nil, it blocks until Cache.Delete returns without a timeout.
   887  func (m *Manager) deleteHTTPToken(tokenPath string) {
   888  	m.challengeMu.Lock()
   889  	defer m.challengeMu.Unlock()
   890  	delete(m.httpTokens, tokenPath)
   891  	if m.Cache != nil {
   892  		m.Cache.Delete(context.Background(), httpTokenCacheKey(tokenPath))
   893  	}
   894  }
   895  
   896  // httpTokenCacheKey returns a key at which an http-01 token value may be stored
   897  // in the Manager's optional Cache.
   898  func httpTokenCacheKey(tokenPath string) string {
   899  	return path.Base(tokenPath) + "+http-01"
   900  }
   901  
   902  // startRenew starts a cert renewal timer loop, one per domain.
   903  //
   904  // The loop is scheduled in two cases:
   905  // - a cert was fetched from cache for the first time (wasn't in m.state)
   906  // - a new cert was created by m.createCert
   907  //
   908  // The key argument is a certificate private key.
   909  // The exp argument is the cert expiration time (NotAfter).
   910  func (m *Manager) startRenew(ck certKey, key crypto.Signer, exp time.Time) {
   911  	m.renewalMu.Lock()
   912  	defer m.renewalMu.Unlock()
   913  	if m.renewal[ck] != nil {
   914  		// another goroutine is already on it
   915  		return
   916  	}
   917  	if m.renewal == nil {
   918  		m.renewal = make(map[certKey]*domainRenewal)
   919  	}
   920  	dr := &domainRenewal{m: m, ck: ck, key: key}
   921  	m.renewal[ck] = dr
   922  	dr.start(exp)
   923  }
   924  
   925  // stopRenew stops all currently running cert renewal timers.
   926  // The timers are not restarted during the lifetime of the Manager.
   927  func (m *Manager) stopRenew() {
   928  	m.renewalMu.Lock()
   929  	defer m.renewalMu.Unlock()
   930  	for name, dr := range m.renewal {
   931  		delete(m.renewal, name)
   932  		dr.stop()
   933  	}
   934  }
   935  
   936  func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
   937  	const keyName = "acme_account+key"
   938  
   939  	// Previous versions of autocert stored the value under a different key.
   940  	const legacyKeyName = "acme_account.key"
   941  
   942  	genKey := func() (*ecdsa.PrivateKey, error) {
   943  		return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   944  	}
   945  
   946  	if m.Cache == nil {
   947  		return genKey()
   948  	}
   949  
   950  	data, err := m.Cache.Get(ctx, keyName)
   951  	if err == ErrCacheMiss {
   952  		data, err = m.Cache.Get(ctx, legacyKeyName)
   953  	}
   954  	if err == ErrCacheMiss {
   955  		key, err := genKey()
   956  		if err != nil {
   957  			return nil, err
   958  		}
   959  		var buf bytes.Buffer
   960  		if err := encodeECDSAKey(&buf, key); err != nil {
   961  			return nil, err
   962  		}
   963  		if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
   964  			return nil, err
   965  		}
   966  		return key, nil
   967  	}
   968  	if err != nil {
   969  		return nil, err
   970  	}
   971  
   972  	priv, _ := pem.Decode(data)
   973  	if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
   974  		return nil, errors.New("acme/autocert: invalid account key found in cache")
   975  	}
   976  	return parsePrivateKey(priv.Bytes)
   977  }
   978  
   979  func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
   980  	m.clientMu.Lock()
   981  	defer m.clientMu.Unlock()
   982  	if m.client != nil {
   983  		return m.client, nil
   984  	}
   985  
   986  	client := m.Client
   987  	if client == nil {
   988  		client = &acme.Client{DirectoryURL: DefaultACMEDirectory}
   989  	}
   990  	if client.Key == nil {
   991  		var err error
   992  		client.Key, err = m.accountKey(ctx)
   993  		if err != nil {
   994  			return nil, err
   995  		}
   996  	}
   997  	if client.UserAgent == "" {
   998  		client.UserAgent = "autocert"
   999  	}
  1000  	var contact []string
  1001  	if m.Email != "" {
  1002  		contact = []string{"mailto:" + m.Email}
  1003  	}
  1004  	a := &acme.Account{Contact: contact, ExternalAccountBinding: m.ExternalAccountBinding}
  1005  	_, err := client.Register(ctx, a, m.Prompt)
  1006  	if err == nil || isAccountAlreadyExist(err) {
  1007  		m.client = client
  1008  		err = nil
  1009  	}
  1010  	return m.client, err
  1011  }
  1012  
  1013  // isAccountAlreadyExist reports whether the err, as returned from acme.Client.Register,
  1014  // indicates the account has already been registered.
  1015  func isAccountAlreadyExist(err error) bool {
  1016  	if err == acme.ErrAccountAlreadyExists {
  1017  		return true
  1018  	}
  1019  	ae, ok := err.(*acme.Error)
  1020  	return ok && ae.StatusCode == http.StatusConflict
  1021  }
  1022  
  1023  func (m *Manager) hostPolicy() HostPolicy {
  1024  	if m.HostPolicy != nil {
  1025  		return m.HostPolicy
  1026  	}
  1027  	return defaultHostPolicy
  1028  }
  1029  
  1030  func (m *Manager) renewBefore() time.Duration {
  1031  	if m.RenewBefore > renewJitter {
  1032  		return m.RenewBefore
  1033  	}
  1034  	return 720 * time.Hour // 30 days
  1035  }
  1036  
  1037  func (m *Manager) now() time.Time {
  1038  	if m.nowFunc != nil {
  1039  		return m.nowFunc()
  1040  	}
  1041  	return time.Now()
  1042  }
  1043  
  1044  // certState is ready when its mutex is unlocked for reading.
  1045  type certState struct {
  1046  	sync.RWMutex
  1047  	locked bool              // locked for read/write
  1048  	key    crypto.Signer     // private key for cert
  1049  	cert   [][]byte          // DER encoding
  1050  	leaf   *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
  1051  }
  1052  
  1053  // tlscert creates a tls.Certificate from s.key and s.cert.
  1054  // Callers should wrap it in s.RLock() and s.RUnlock().
  1055  func (s *certState) tlscert() (*tls.Certificate, error) {
  1056  	if s.key == nil {
  1057  		return nil, errors.New("acme/autocert: missing signer")
  1058  	}
  1059  	if len(s.cert) == 0 {
  1060  		return nil, errors.New("acme/autocert: missing certificate")
  1061  	}
  1062  	return &tls.Certificate{
  1063  		PrivateKey:  s.key,
  1064  		Certificate: s.cert,
  1065  		Leaf:        s.leaf,
  1066  	}, nil
  1067  }
  1068  
  1069  // certRequest generates a CSR for the given common name.
  1070  func certRequest(key crypto.Signer, name string, ext []pkix.Extension) ([]byte, error) {
  1071  	req := &x509.CertificateRequest{
  1072  		Subject:         pkix.Name{CommonName: name},
  1073  		DNSNames:        []string{name},
  1074  		ExtraExtensions: ext,
  1075  	}
  1076  	return x509.CreateCertificateRequest(rand.Reader, req, key)
  1077  }
  1078  
  1079  // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
  1080  // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
  1081  // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
  1082  //
  1083  // Inspired by parsePrivateKey in crypto/tls/tls.go.
  1084  func parsePrivateKey(der []byte) (crypto.Signer, error) {
  1085  	if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
  1086  		return key, nil
  1087  	}
  1088  	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
  1089  		switch key := key.(type) {
  1090  		case *rsa.PrivateKey:
  1091  			return key, nil
  1092  		case *ecdsa.PrivateKey:
  1093  			return key, nil
  1094  		default:
  1095  			return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
  1096  		}
  1097  	}
  1098  	if key, err := x509.ParseECPrivateKey(der); err == nil {
  1099  		return key, nil
  1100  	}
  1101  
  1102  	return nil, errors.New("acme/autocert: failed to parse private key")
  1103  }
  1104  
  1105  // validCert parses a cert chain provided as der argument and verifies the leaf and der[0]
  1106  // correspond to the private key, the domain and key type match, and expiration dates
  1107  // are valid. It doesn't do any revocation checking.
  1108  //
  1109  // The returned value is the verified leaf cert.
  1110  func validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf *x509.Certificate, err error) {
  1111  	// parse public part(s)
  1112  	var n int
  1113  	for _, b := range der {
  1114  		n += len(b)
  1115  	}
  1116  	pub := make([]byte, n)
  1117  	n = 0
  1118  	for _, b := range der {
  1119  		n += copy(pub[n:], b)
  1120  	}
  1121  	x509Cert, err := x509.ParseCertificates(pub)
  1122  	if err != nil || len(x509Cert) == 0 {
  1123  		return nil, errors.New("acme/autocert: no public key found")
  1124  	}
  1125  	// verify the leaf is not expired and matches the domain name
  1126  	leaf = x509Cert[0]
  1127  	if now.Before(leaf.NotBefore) {
  1128  		return nil, errors.New("acme/autocert: certificate is not valid yet")
  1129  	}
  1130  	if now.After(leaf.NotAfter) {
  1131  		return nil, errors.New("acme/autocert: expired certificate")
  1132  	}
  1133  	if err := leaf.VerifyHostname(ck.domain); err != nil {
  1134  		return nil, err
  1135  	}
  1136  	// renew certificates revoked by Let's Encrypt in January 2022
  1137  	if isRevokedLetsEncrypt(leaf) {
  1138  		return nil, errors.New("acme/autocert: certificate was probably revoked by Let's Encrypt")
  1139  	}
  1140  	// ensure the leaf corresponds to the private key and matches the certKey type
  1141  	switch pub := leaf.PublicKey.(type) {
  1142  	case *rsa.PublicKey:
  1143  		prv, ok := key.(*rsa.PrivateKey)
  1144  		if !ok {
  1145  			return nil, errors.New("acme/autocert: private key type does not match public key type")
  1146  		}
  1147  		if pub.N.Cmp(prv.N) != 0 {
  1148  			return nil, errors.New("acme/autocert: private key does not match public key")
  1149  		}
  1150  		if !ck.isRSA && !ck.isToken {
  1151  			return nil, errors.New("acme/autocert: key type does not match expected value")
  1152  		}
  1153  	case *ecdsa.PublicKey:
  1154  		prv, ok := key.(*ecdsa.PrivateKey)
  1155  		if !ok {
  1156  			return nil, errors.New("acme/autocert: private key type does not match public key type")
  1157  		}
  1158  		if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
  1159  			return nil, errors.New("acme/autocert: private key does not match public key")
  1160  		}
  1161  		if ck.isRSA && !ck.isToken {
  1162  			return nil, errors.New("acme/autocert: key type does not match expected value")
  1163  		}
  1164  	default:
  1165  		return nil, errors.New("acme/autocert: unknown public key algorithm")
  1166  	}
  1167  	return leaf, nil
  1168  }
  1169  
  1170  // https://community.letsencrypt.org/t/2022-01-25-issue-with-tls-alpn-01-validation-method/170450
  1171  var letsEncryptFixDeployTime = time.Date(2022, time.January, 26, 00, 48, 0, 0, time.UTC)
  1172  
  1173  // isRevokedLetsEncrypt returns whether the certificate is likely to be part of
  1174  // a batch of certificates revoked by Let's Encrypt in January 2022. This check
  1175  // can be safely removed from May 2022.
  1176  func isRevokedLetsEncrypt(cert *x509.Certificate) bool {
  1177  	O := cert.Issuer.Organization
  1178  	return len(O) == 1 && O[0] == "Let's Encrypt" &&
  1179  		cert.NotBefore.Before(letsEncryptFixDeployTime)
  1180  }
  1181  
  1182  type lockedMathRand struct {
  1183  	sync.Mutex
  1184  	rnd *mathrand.Rand
  1185  }
  1186  
  1187  func (r *lockedMathRand) int63n(max int64) int64 {
  1188  	r.Lock()
  1189  	n := r.rnd.Int63n(max)
  1190  	r.Unlock()
  1191  	return n
  1192  }
  1193  
  1194  // For easier testing.
  1195  var (
  1196  	// Called when a state is removed.
  1197  	testDidRemoveState = func(certKey) {}
  1198  )
  1199  

View as plain text