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.
5 // Package autocert provides automatic access to certificates from Let's Encrypt
6 // and any other ACME-based CA.
8 // This package is a work in progress and makes no API stability promises.
34 "golang.org/x/crypto/acme"
35 "golang.org/x/net/idna"
38 // createCertRetryAfter is how much time to wait before removing a failed state
39 // entry due to an unsuccessful createCert call.
40 // This is a variable instead of a const for testing.
41 // TODO: Consider making it configurable or an exp backoff?
42 var createCertRetryAfter = time.Minute
44 // pseudoRand is safe for concurrent use.
45 var pseudoRand *lockedMathRand
48 src := mathrand.NewSource(time.Now().UnixNano())
49 pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
52 // AcceptTOS is a Manager.Prompt function that always returns true to
53 // indicate acceptance of the CA's Terms of Service during account
55 func AcceptTOS(tosURL string) bool { return true }
57 // HostPolicy specifies which host names the Manager is allowed to respond to.
58 // It returns a non-nil error if the host should be rejected.
59 // The returned error is accessible via tls.Conn.Handshake and its callers.
60 // See Manager's HostPolicy field and GetCertificate method docs for more details.
61 type HostPolicy func(ctx context.Context, host string) error
63 // HostWhitelist returns a policy where only the specified host names are allowed.
64 // Only exact matches are currently supported. Subdomains, regexp or wildcard
67 // Note that all hosts will be converted to Punycode via idna.Lookup.ToASCII so that
68 // Manager.GetCertificate can handle the Unicode IDN and mixedcase hosts correctly.
69 // Invalid hosts will be silently ignored.
70 func HostWhitelist(hosts ...string) HostPolicy {
71 whitelist := make(map[string]bool, len(hosts))
72 for _, h := range hosts {
73 if h, err := idna.Lookup.ToASCII(h); err == nil {
77 return func(_ context.Context, host string) error {
79 return fmt.Errorf("acme/autocert: host %q not configured in HostWhitelist", host)
85 // defaultHostPolicy is used when Manager.HostPolicy is not set.
86 func defaultHostPolicy(context.Context, string) error {
90 // Manager is a stateful certificate manager built on top of acme.Client.
91 // It obtains and refreshes certificates automatically using "tls-alpn-01",
92 // "tls-sni-01", "tls-sni-02" and "http-01" challenge types,
93 // as well as providing them to a TLS server via tls.Config.
95 // You must specify a cache implementation, such as DirCache,
96 // to reuse obtained certificates across program restarts.
97 // Otherwise your server is very likely to exceed the certificate
98 // issuer's request rate limits.
100 // Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
101 // The registration may require the caller to agree to the CA's TOS.
102 // If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
103 // whether the caller agrees to the terms.
105 // To always accept the terms, the callers can use AcceptTOS.
106 Prompt func(tosURL string) bool
108 // Cache optionally stores and retrieves previously-obtained certificates
109 // and other state. If nil, certs will only be cached for the lifetime of
110 // the Manager. Multiple Managers can share the same Cache.
112 // Using a persistent Cache, such as DirCache, is strongly recommended.
115 // HostPolicy controls which domains the Manager will attempt
116 // to retrieve new certificates for. It does not affect cached certs.
118 // If non-nil, HostPolicy is called before requesting a new cert.
119 // If nil, all hosts are currently allowed. This is not recommended,
120 // as it opens a potential attack where clients connect to a server
121 // by IP address and pretend to be asking for an incorrect host name.
122 // Manager will attempt to obtain a certificate for that host, incorrectly,
123 // eventually reaching the CA's rate limit for certificate requests
124 // and making it impossible to obtain actual certificates.
126 // See GetCertificate for more details.
127 HostPolicy HostPolicy
129 // RenewBefore optionally specifies how early certificates should
130 // be renewed before they expire.
132 // If zero, they're renewed 30 days before expiration.
133 RenewBefore time.Duration
135 // Client is used to perform low-level operations, such as account registration
136 // and requesting new certificates.
138 // If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
139 // as directory endpoint. If the Client.Key is nil, a new ECDSA P-256 key is
140 // generated and, if Cache is not nil, stored in cache.
142 // Mutating the field after the first call of GetCertificate method will have no effect.
145 // Email optionally specifies a contact email address.
146 // This is used by CAs, such as Let's Encrypt, to notify about problems
147 // with issued certificates.
149 // If the Client's account key is already registered, Email is not used.
152 // ForceRSA used to make the Manager generate RSA certificates. It is now ignored.
154 // Deprecated: the Manager will request the correct type of certificate based
155 // on what each client supports.
158 // ExtraExtensions are used when generating a new CSR (Certificate Request),
159 // thus allowing customization of the resulting certificate.
160 // For instance, TLS Feature Extension (RFC 7633) can be used
161 // to prevent an OCSP downgrade attack.
163 // The field value is passed to crypto/x509.CreateCertificateRequest
164 // in the template's ExtraExtensions field as is.
165 ExtraExtensions []pkix.Extension
168 client *acme.Client // initialized by acmeClient method
171 state map[certKey]*certState
173 // renewal tracks the set of domains currently running renewal timers.
175 renewal map[certKey]*domainRenewal
177 // tokensMu guards the rest of the fields: tryHTTP01, certTokens and httpTokens.
178 tokensMu sync.RWMutex
179 // tryHTTP01 indicates whether the Manager should try "http-01" challenge type
180 // during the authorization flow.
182 // httpTokens contains response body values for http-01 challenges
183 // and is keyed by the URL path at which a challenge response is expected
184 // to be provisioned.
185 // The entries are stored for the duration of the authorization flow.
186 httpTokens map[string][]byte
187 // certTokens contains temporary certificates for tls-sni and tls-alpn challenges
188 // and is keyed by token domain name, which matches server name of ClientHello.
189 // Keys always have ".acme.invalid" suffix for tls-sni. Otherwise, they are domain names
191 // The entries are stored for the duration of the authorization flow.
192 certTokens map[string]*tls.Certificate
193 // nowFunc, if not nil, returns the current time. This may be set for
195 nowFunc func() time.Time
198 // certKey is the key by which certificates are tracked in state, renewal and cache.
199 type certKey struct {
200 domain string // without trailing dot
201 isRSA bool // RSA cert for legacy clients (as opposed to default ECDSA)
202 isToken bool // tls-based challenge token cert; key type is undefined regardless of isRSA
205 func (c certKey) String() string {
207 return c.domain + "+token"
210 return c.domain + "+rsa"
215 // TLSConfig creates a new TLS config suitable for net/http.Server servers,
216 // supporting HTTP/2 and the tls-alpn-01 ACME challenge type.
217 func (m *Manager) TLSConfig() *tls.Config {
219 GetCertificate: m.GetCertificate,
220 NextProtos: []string{
221 "h2", "http/1.1", // enable HTTP/2
222 acme.ALPNProto, // enable tls-alpn ACME challenges
227 // GetCertificate implements the tls.Config.GetCertificate hook.
228 // It provides a TLS certificate for hello.ServerName host, including answering
229 // tls-alpn-01 and *.acme.invalid (tls-sni-01 and tls-sni-02) challenges.
230 // All other fields of hello are ignored.
232 // If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
233 // a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
234 // The error is propagated back to the caller of GetCertificate and is user-visible.
235 // This does not affect cached certs. See HostPolicy field description for more details.
237 // If GetCertificate is used directly, instead of via Manager.TLSConfig, package users will
238 // also have to add acme.ALPNProto to NextProtos for tls-alpn-01, or use HTTPHandler
239 // for http-01. (The tls-sni-* challenges have been deprecated by popular ACME providers
240 // due to security issues in the ecosystem.)
241 func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
243 return nil, errors.New("acme/autocert: Manager.Prompt not set")
246 name := hello.ServerName
248 return nil, errors.New("acme/autocert: missing server name")
250 if !strings.Contains(strings.Trim(name, "."), ".") {
251 return nil, errors.New("acme/autocert: server name component count invalid")
254 // Note that this conversion is necessary because some server names in the handshakes
255 // started by some clients (such as cURL) are not converted to Punycode, which will
256 // prevent us from obtaining certificates for them. In addition, we should also treat
257 // example.com and EXAMPLE.COM as equivalent and return the same certificate for them.
258 // Fortunately, this conversion also helped us deal with this kind of mixedcase problems.
260 // Due to the "σςΣ" problem (see https://unicode.org/faq/idn.html#22), we can't use
261 // idna.Punycode.ToASCII (or just idna.ToASCII) here.
262 name, err := idna.Lookup.ToASCII(name)
264 return nil, errors.New("acme/autocert: server name contains invalid character")
267 // In the worst-case scenario, the timeout needs to account for caching, host policy,
268 // domain ownership verification and certificate issuance.
269 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
272 // Check whether this is a token cert requested for TLS-SNI or TLS-ALPN challenge.
273 if wantsTokenCert(hello) {
275 defer m.tokensMu.RUnlock()
276 // It's ok to use the same token cert key for both tls-sni and tls-alpn
277 // because there's always at most 1 token cert per on-going domain authorization.
278 // See m.verify for details.
279 if cert := m.certTokens[name]; cert != nil {
282 if cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {
285 // TODO: cache error results?
286 return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
291 domain: strings.TrimSuffix(name, "."), // golang.org/issue/18114
292 isRSA: !supportsECDSA(hello),
294 cert, err := m.cert(ctx, ck)
298 if err != ErrCacheMiss {
303 if err := m.hostPolicy()(ctx, name); err != nil {
306 cert, err = m.createCert(ctx, ck)
310 m.cachePut(ctx, ck, cert)
314 // wantsTokenCert reports whether a TLS request with SNI is made by a CA server
315 // for a challenge verification.
316 func wantsTokenCert(hello *tls.ClientHelloInfo) bool {
318 if len(hello.SupportedProtos) == 1 && hello.SupportedProtos[0] == acme.ALPNProto {
322 return strings.HasSuffix(hello.ServerName, ".acme.invalid")
325 func supportsECDSA(hello *tls.ClientHelloInfo) bool {
326 // The "signature_algorithms" extension, if present, limits the key exchange
327 // algorithms allowed by the cipher suites. See RFC 5246, section 7.4.1.4.1.
328 if hello.SignatureSchemes != nil {
331 for _, scheme := range hello.SignatureSchemes {
332 const tlsECDSAWithSHA1 tls.SignatureScheme = 0x0203 // constant added in Go 1.10
334 case tlsECDSAWithSHA1, tls.ECDSAWithP256AndSHA256,
335 tls.ECDSAWithP384AndSHA384, tls.ECDSAWithP521AndSHA512:
344 if hello.SupportedCurves != nil {
346 for _, curve := range hello.SupportedCurves {
347 if curve == tls.CurveP256 {
356 for _, suite := range hello.CipherSuites {
358 case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
359 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
360 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
361 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
362 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
363 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
364 tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
371 // HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
372 // It returns an http.Handler that responds to the challenges and must be
373 // running on port 80. If it receives a request that is not an ACME challenge,
374 // it delegates the request to the optional fallback handler.
376 // If fallback is nil, the returned handler redirects all GET and HEAD requests
377 // to the default TLS port 443 with 302 Found status code, preserving the original
378 // request path and query. It responds with 400 Bad Request to all other HTTP methods.
379 // The fallback is not protected by the optional HostPolicy.
381 // Because the fallback handler is run with unencrypted port 80 requests,
382 // the fallback should not serve TLS-only requests.
384 // If HTTPHandler is never called, the Manager will only use the "tls-alpn-01"
385 // challenge for domain verification.
386 func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
388 defer m.tokensMu.Unlock()
392 fallback = http.HandlerFunc(handleHTTPRedirect)
394 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
395 if !strings.HasPrefix(r.URL.Path, "/.well-known/acme-challenge/") {
396 fallback.ServeHTTP(w, r)
399 // A reasonable context timeout for cache and host policy only,
400 // because we don't wait for a new certificate issuance here.
401 ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
403 if err := m.hostPolicy()(ctx, r.Host); err != nil {
404 http.Error(w, err.Error(), http.StatusForbidden)
407 data, err := m.httpToken(ctx, r.URL.Path)
409 http.Error(w, err.Error(), http.StatusNotFound)
416 func handleHTTPRedirect(w http.ResponseWriter, r *http.Request) {
417 if r.Method != "GET" && r.Method != "HEAD" {
418 http.Error(w, "Use HTTPS", http.StatusBadRequest)
421 target := "https://" + stripPort(r.Host) + r.URL.RequestURI()
422 http.Redirect(w, r, target, http.StatusFound)
425 func stripPort(hostport string) string {
426 host, _, err := net.SplitHostPort(hostport)
430 return net.JoinHostPort(host, "443")
433 // cert returns an existing certificate either from m.state or cache.
434 // If a certificate is found in cache but not in m.state, the latter will be filled
435 // with the cached value.
436 func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
438 if s, ok := m.state[ck]; ok {
444 defer m.stateMu.Unlock()
445 cert, err := m.cacheGet(ctx, ck)
449 signer, ok := cert.PrivateKey.(crypto.Signer)
451 return nil, errors.New("acme/autocert: private key cannot sign")
454 m.state = make(map[certKey]*certState)
458 cert: cert.Certificate,
462 go m.renew(ck, s.key, s.leaf.NotAfter)
466 // cacheGet always returns a valid certificate, or an error otherwise.
467 // If a cached certificate exists but is not valid, ErrCacheMiss is returned.
468 func (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, error) {
470 return nil, ErrCacheMiss
472 data, err := m.Cache.Get(ctx, ck.String())
478 priv, pub := pem.Decode(data)
479 if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
480 return nil, ErrCacheMiss
482 privKey, err := parsePrivateKey(priv.Bytes)
491 b, pub = pem.Decode(pub)
495 pubDER = append(pubDER, b.Bytes)
498 // Leftover content not consumed by pem.Decode. Corrupt. Ignore.
499 return nil, ErrCacheMiss
502 // verify and create TLS cert
503 leaf, err := validCert(ck, pubDER, privKey, m.now())
505 return nil, ErrCacheMiss
507 tlscert := &tls.Certificate{
515 func (m *Manager) cachePut(ctx context.Context, ck certKey, tlscert *tls.Certificate) error {
520 // contains PEM-encoded data
524 switch key := tlscert.PrivateKey.(type) {
525 case *ecdsa.PrivateKey:
526 if err := encodeECDSAKey(&buf, key); err != nil {
529 case *rsa.PrivateKey:
530 b := x509.MarshalPKCS1PrivateKey(key)
531 pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
532 if err := pem.Encode(&buf, pb); err != nil {
536 return errors.New("acme/autocert: unknown private key type")
540 for _, b := range tlscert.Certificate {
541 pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
542 if err := pem.Encode(&buf, pb); err != nil {
547 return m.Cache.Put(ctx, ck.String(), buf.Bytes())
550 func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
551 b, err := x509.MarshalECPrivateKey(key)
555 pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
556 return pem.Encode(w, pb)
559 // createCert starts the domain ownership verification and returns a certificate
560 // for that domain upon success.
562 // If the domain is already being verified, it waits for the existing verification to complete.
563 // Either way, createCert blocks for the duration of the whole process.
564 func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
565 // TODO: maybe rewrite this whole piece using sync.Once
566 state, err := m.certState(ck)
570 // state may exist if another goroutine is already working on it
571 // in which case just wait for it to finish
574 defer state.RUnlock()
575 return state.tlscert()
578 // We are the first; state is locked.
579 // Unblock the readers when domain ownership is verified
580 // and we got the cert or the process failed.
584 der, leaf, err := m.authorizedCert(ctx, state.key, ck)
586 // Remove the failed state after some time,
587 // making the manager call createCert again on the following TLS hello.
588 time.AfterFunc(createCertRetryAfter, func() {
589 defer testDidRemoveState(ck)
591 defer m.stateMu.Unlock()
592 // Verify the state hasn't changed and it's still invalid
598 if _, err := validCert(ck, s.cert, s.key, m.now()); err == nil {
607 go m.renew(ck, state.key, state.leaf.NotAfter)
608 return state.tlscert()
611 // certState returns a new or existing certState.
612 // If a new certState is returned, state.exist is false and the state is locked.
613 // The returned error is non-nil only in the case where a new state could not be created.
614 func (m *Manager) certState(ck certKey) (*certState, error) {
616 defer m.stateMu.Unlock()
618 m.state = make(map[certKey]*certState)
621 if state, ok := m.state[ck]; ok {
631 key, err = rsa.GenerateKey(rand.Reader, 2048)
633 key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
643 state.Lock() // will be unlocked by m.certState caller
648 // authorizedCert starts the domain ownership verification process and requests a new cert upon success.
649 // The key argument is the certificate private key.
650 func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck certKey) (der [][]byte, leaf *x509.Certificate, err error) {
651 client, err := m.acmeClient(ctx)
656 if err := m.verify(ctx, client, ck.domain); err != nil {
659 csr, err := certRequest(key, ck.domain, m.ExtraExtensions)
663 der, _, err = client.CreateCert(ctx, csr, 0, true)
667 leaf, err = validCert(ck, der, key, m.now())
671 return der, leaf, nil
674 // revokePendingAuthz revokes all authorizations idenfied by the elements of uri slice.
675 // It ignores revocation errors.
676 func (m *Manager) revokePendingAuthz(ctx context.Context, uri []string) {
677 client, err := m.acmeClient(ctx)
681 for _, u := range uri {
682 client.RevokeAuthorization(ctx, u)
686 // verify runs the identifier (domain) authorization flow
687 // using each applicable ACME challenge type.
688 func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
689 // The list of challenge types we'll try to fulfill
690 // in this specific order.
691 challengeTypes := []string{"tls-alpn-01", "tls-sni-02", "tls-sni-01"}
694 challengeTypes = append(challengeTypes, "http-01")
698 // Keep track of pending authzs and revoke the ones that did not validate.
699 pendingAuthzs := make(map[string]bool)
702 for k, pending := range pendingAuthzs {
708 // Use "detached" background context.
709 // The revocations need not happen in the current verification flow.
710 go m.revokePendingAuthz(context.Background(), uri)
714 // errs accumulates challenge failure errors, printed if all fail
715 errs := make(map[*acme.Challenge]error)
716 var nextTyp int // challengeType index of the next challenge type to try
718 // Start domain authorization and get the challenge.
719 authz, err := client.Authorize(ctx, domain)
723 // No point in accepting challenges if the authorization status
724 // is in a final state.
725 switch authz.Status {
726 case acme.StatusValid:
727 return nil // already authorized
728 case acme.StatusInvalid:
729 return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
732 pendingAuthzs[authz.URI] = true
734 // Pick the next preferred challenge.
735 var chal *acme.Challenge
736 for chal == nil && nextTyp < len(challengeTypes) {
737 chal = pickChallenge(challengeTypes[nextTyp], authz.Challenges)
741 errorMsg := fmt.Sprintf("acme/autocert: unable to authorize %q", domain)
742 for chal, err := range errs {
743 errorMsg += fmt.Sprintf("; challenge %q failed with error: %v", chal.Type, err)
745 return errors.New(errorMsg)
747 cleanup, err := m.fulfill(ctx, client, chal, domain)
753 if _, err := client.Accept(ctx, chal); err != nil {
758 // A challenge is fulfilled and accepted: wait for the CA to validate.
759 if _, err := client.WaitAuthorization(ctx, authz.URI); err != nil {
763 delete(pendingAuthzs, authz.URI)
768 // fulfill provisions a response to the challenge chal.
769 // The cleanup is non-nil only if provisioning succeeded.
770 func (m *Manager) fulfill(ctx context.Context, client *acme.Client, chal *acme.Challenge, domain string) (cleanup func(), err error) {
773 cert, err := client.TLSALPN01ChallengeCert(chal.Token, domain)
777 m.putCertToken(ctx, domain, &cert)
778 return func() { go m.deleteCertToken(domain) }, nil
780 cert, name, err := client.TLSSNI01ChallengeCert(chal.Token)
784 m.putCertToken(ctx, name, &cert)
785 return func() { go m.deleteCertToken(name) }, nil
787 cert, name, err := client.TLSSNI02ChallengeCert(chal.Token)
791 m.putCertToken(ctx, name, &cert)
792 return func() { go m.deleteCertToken(name) }, nil
794 resp, err := client.HTTP01ChallengeResponse(chal.Token)
798 p := client.HTTP01ChallengePath(chal.Token)
799 m.putHTTPToken(ctx, p, resp)
800 return func() { go m.deleteHTTPToken(p) }, nil
802 return nil, fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
805 func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
806 for _, c := range chal {
814 // putCertToken stores the token certificate with the specified name
815 // in both m.certTokens map and m.Cache.
816 func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
818 defer m.tokensMu.Unlock()
819 if m.certTokens == nil {
820 m.certTokens = make(map[string]*tls.Certificate)
822 m.certTokens[name] = cert
823 m.cachePut(ctx, certKey{domain: name, isToken: true}, cert)
826 // deleteCertToken removes the token certificate with the specified name
827 // from both m.certTokens map and m.Cache.
828 func (m *Manager) deleteCertToken(name string) {
830 defer m.tokensMu.Unlock()
831 delete(m.certTokens, name)
833 ck := certKey{domain: name, isToken: true}
834 m.Cache.Delete(context.Background(), ck.String())
838 // httpToken retrieves an existing http-01 token value from an in-memory map
839 // or the optional cache.
840 func (m *Manager) httpToken(ctx context.Context, tokenPath string) ([]byte, error) {
842 defer m.tokensMu.RUnlock()
843 if v, ok := m.httpTokens[tokenPath]; ok {
847 return nil, fmt.Errorf("acme/autocert: no token at %q", tokenPath)
849 return m.Cache.Get(ctx, httpTokenCacheKey(tokenPath))
852 // putHTTPToken stores an http-01 token value using tokenPath as key
853 // in both in-memory map and the optional Cache.
855 // It ignores any error returned from Cache.Put.
856 func (m *Manager) putHTTPToken(ctx context.Context, tokenPath, val string) {
858 defer m.tokensMu.Unlock()
859 if m.httpTokens == nil {
860 m.httpTokens = make(map[string][]byte)
863 m.httpTokens[tokenPath] = b
865 m.Cache.Put(ctx, httpTokenCacheKey(tokenPath), b)
869 // deleteHTTPToken removes an http-01 token value from both in-memory map
870 // and the optional Cache, ignoring any error returned from the latter.
872 // If m.Cache is non-nil, it blocks until Cache.Delete returns without a timeout.
873 func (m *Manager) deleteHTTPToken(tokenPath string) {
875 defer m.tokensMu.Unlock()
876 delete(m.httpTokens, tokenPath)
878 m.Cache.Delete(context.Background(), httpTokenCacheKey(tokenPath))
882 // httpTokenCacheKey returns a key at which an http-01 token value may be stored
883 // in the Manager's optional Cache.
884 func httpTokenCacheKey(tokenPath string) string {
885 return path.Base(tokenPath) + "+http-01"
888 // renew starts a cert renewal timer loop, one per domain.
890 // The loop is scheduled in two cases:
891 // - a cert was fetched from cache for the first time (wasn't in m.state)
892 // - a new cert was created by m.createCert
894 // The key argument is a certificate private key.
895 // The exp argument is the cert expiration time (NotAfter).
896 func (m *Manager) renew(ck certKey, key crypto.Signer, exp time.Time) {
898 defer m.renewalMu.Unlock()
899 if m.renewal[ck] != nil {
900 // another goroutine is already on it
903 if m.renewal == nil {
904 m.renewal = make(map[certKey]*domainRenewal)
906 dr := &domainRenewal{m: m, ck: ck, key: key}
911 // stopRenew stops all currently running cert renewal timers.
912 // The timers are not restarted during the lifetime of the Manager.
913 func (m *Manager) stopRenew() {
915 defer m.renewalMu.Unlock()
916 for name, dr := range m.renewal {
917 delete(m.renewal, name)
922 func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
923 const keyName = "acme_account+key"
925 // Previous versions of autocert stored the value under a different key.
926 const legacyKeyName = "acme_account.key"
928 genKey := func() (*ecdsa.PrivateKey, error) {
929 return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
936 data, err := m.Cache.Get(ctx, keyName)
937 if err == ErrCacheMiss {
938 data, err = m.Cache.Get(ctx, legacyKeyName)
940 if err == ErrCacheMiss {
946 if err := encodeECDSAKey(&buf, key); err != nil {
949 if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
958 priv, _ := pem.Decode(data)
959 if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
960 return nil, errors.New("acme/autocert: invalid account key found in cache")
962 return parsePrivateKey(priv.Bytes)
965 func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
967 defer m.clientMu.Unlock()
974 client = &acme.Client{DirectoryURL: acme.LetsEncryptURL}
976 if client.Key == nil {
978 client.Key, err = m.accountKey(ctx)
985 contact = []string{"mailto:" + m.Email}
987 a := &acme.Account{Contact: contact}
988 _, err := client.Register(ctx, a, m.Prompt)
989 if ae, ok := err.(*acme.Error); err == nil || ok && ae.StatusCode == http.StatusConflict {
990 // conflict indicates the key is already registered
997 func (m *Manager) hostPolicy() HostPolicy {
998 if m.HostPolicy != nil {
1001 return defaultHostPolicy
1004 func (m *Manager) renewBefore() time.Duration {
1005 if m.RenewBefore > renewJitter {
1006 return m.RenewBefore
1008 return 720 * time.Hour // 30 days
1011 func (m *Manager) now() time.Time {
1012 if m.nowFunc != nil {
1018 // certState is ready when its mutex is unlocked for reading.
1019 type certState struct {
1021 locked bool // locked for read/write
1022 key crypto.Signer // private key for cert
1023 cert [][]byte // DER encoding
1024 leaf *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
1027 // tlscert creates a tls.Certificate from s.key and s.cert.
1028 // Callers should wrap it in s.RLock() and s.RUnlock().
1029 func (s *certState) tlscert() (*tls.Certificate, error) {
1031 return nil, errors.New("acme/autocert: missing signer")
1033 if len(s.cert) == 0 {
1034 return nil, errors.New("acme/autocert: missing certificate")
1036 return &tls.Certificate{
1038 Certificate: s.cert,
1043 // certRequest generates a CSR for the given common name cn and optional SANs.
1044 func certRequest(key crypto.Signer, cn string, ext []pkix.Extension, san ...string) ([]byte, error) {
1045 req := &x509.CertificateRequest{
1046 Subject: pkix.Name{CommonName: cn},
1048 ExtraExtensions: ext,
1050 return x509.CreateCertificateRequest(rand.Reader, req, key)
1053 // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
1054 // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
1055 // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
1057 // Inspired by parsePrivateKey in crypto/tls/tls.go.
1058 func parsePrivateKey(der []byte) (crypto.Signer, error) {
1059 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
1062 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
1063 switch key := key.(type) {
1064 case *rsa.PrivateKey:
1066 case *ecdsa.PrivateKey:
1069 return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
1072 if key, err := x509.ParseECPrivateKey(der); err == nil {
1076 return nil, errors.New("acme/autocert: failed to parse private key")
1079 // validCert parses a cert chain provided as der argument and verifies the leaf and der[0]
1080 // correspond to the private key, the domain and key type match, and expiration dates
1081 // are valid. It doesn't do any revocation checking.
1083 // The returned value is the verified leaf cert.
1084 func validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf *x509.Certificate, err error) {
1085 // parse public part(s)
1087 for _, b := range der {
1090 pub := make([]byte, n)
1092 for _, b := range der {
1093 n += copy(pub[n:], b)
1095 x509Cert, err := x509.ParseCertificates(pub)
1096 if err != nil || len(x509Cert) == 0 {
1097 return nil, errors.New("acme/autocert: no public key found")
1099 // verify the leaf is not expired and matches the domain name
1101 if now.Before(leaf.NotBefore) {
1102 return nil, errors.New("acme/autocert: certificate is not valid yet")
1104 if now.After(leaf.NotAfter) {
1105 return nil, errors.New("acme/autocert: expired certificate")
1107 if err := leaf.VerifyHostname(ck.domain); err != nil {
1110 // ensure the leaf corresponds to the private key and matches the certKey type
1111 switch pub := leaf.PublicKey.(type) {
1112 case *rsa.PublicKey:
1113 prv, ok := key.(*rsa.PrivateKey)
1115 return nil, errors.New("acme/autocert: private key type does not match public key type")
1117 if pub.N.Cmp(prv.N) != 0 {
1118 return nil, errors.New("acme/autocert: private key does not match public key")
1120 if !ck.isRSA && !ck.isToken {
1121 return nil, errors.New("acme/autocert: key type does not match expected value")
1123 case *ecdsa.PublicKey:
1124 prv, ok := key.(*ecdsa.PrivateKey)
1126 return nil, errors.New("acme/autocert: private key type does not match public key type")
1128 if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
1129 return nil, errors.New("acme/autocert: private key does not match public key")
1131 if ck.isRSA && !ck.isToken {
1132 return nil, errors.New("acme/autocert: key type does not match expected value")
1135 return nil, errors.New("acme/autocert: unknown public key algorithm")
1140 type lockedMathRand struct {
1145 func (r *lockedMathRand) int63n(max int64) int64 {
1147 n := r.rnd.Int63n(max)
1152 // For easier testing.
1154 // Called when a state is removed.
1155 testDidRemoveState = func(certKey) {}