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.
33 "golang.org/x/crypto/acme"
36 // createCertRetryAfter is how much time to wait before removing a failed state
37 // entry due to an unsuccessful createCert call.
38 // This is a variable instead of a const for testing.
39 // TODO: Consider making it configurable or an exp backoff?
40 var createCertRetryAfter = time.Minute
42 // pseudoRand is safe for concurrent use.
43 var pseudoRand *lockedMathRand
46 src := mathrand.NewSource(timeNow().UnixNano())
47 pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
50 // AcceptTOS is a Manager.Prompt function that always returns true to
51 // indicate acceptance of the CA's Terms of Service during account
53 func AcceptTOS(tosURL string) bool { return true }
55 // HostPolicy specifies which host names the Manager is allowed to respond to.
56 // It returns a non-nil error if the host should be rejected.
57 // The returned error is accessible via tls.Conn.Handshake and its callers.
58 // See Manager's HostPolicy field and GetCertificate method docs for more details.
59 type HostPolicy func(ctx context.Context, host string) error
61 // HostWhitelist returns a policy where only the specified host names are allowed.
62 // Only exact matches are currently supported. Subdomains, regexp or wildcard
64 func HostWhitelist(hosts ...string) HostPolicy {
65 whitelist := make(map[string]bool, len(hosts))
66 for _, h := range hosts {
69 return func(_ context.Context, host string) error {
71 return errors.New("acme/autocert: host not configured")
77 // defaultHostPolicy is used when Manager.HostPolicy is not set.
78 func defaultHostPolicy(context.Context, string) error {
82 // Manager is a stateful certificate manager built on top of acme.Client.
83 // It obtains and refreshes certificates automatically,
84 // as well as providing them to a TLS server via tls.Config.
86 // To preserve issued certificates and improve overall performance,
87 // use a cache implementation of Cache. For instance, DirCache.
89 // Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).
90 // The registration may require the caller to agree to the CA's TOS.
91 // If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report
92 // whether the caller agrees to the terms.
94 // To always accept the terms, the callers can use AcceptTOS.
95 Prompt func(tosURL string) bool
97 // Cache optionally stores and retrieves previously-obtained certificates.
98 // If nil, certs will only be cached for the lifetime of the Manager.
100 // Manager passes the Cache certificates data encoded in PEM, with private/public
101 // parts combined in a single Cache.Put call, private key first.
104 // HostPolicy controls which domains the Manager will attempt
105 // to retrieve new certificates for. It does not affect cached certs.
107 // If non-nil, HostPolicy is called before requesting a new cert.
108 // If nil, all hosts are currently allowed. This is not recommended,
109 // as it opens a potential attack where clients connect to a server
110 // by IP address and pretend to be asking for an incorrect host name.
111 // Manager will attempt to obtain a certificate for that host, incorrectly,
112 // eventually reaching the CA's rate limit for certificate requests
113 // and making it impossible to obtain actual certificates.
115 // See GetCertificate for more details.
116 HostPolicy HostPolicy
118 // RenewBefore optionally specifies how early certificates should
119 // be renewed before they expire.
121 // If zero, they're renewed 30 days before expiration.
122 RenewBefore time.Duration
124 // Client is used to perform low-level operations, such as account registration
125 // and requesting new certificates.
126 // If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
127 // directory endpoint and a newly-generated ECDSA P-256 key.
129 // Mutating the field after the first call of GetCertificate method will have no effect.
132 // Email optionally specifies a contact email address.
133 // This is used by CAs, such as Let's Encrypt, to notify about problems
134 // with issued certificates.
136 // If the Client's account key is already registered, Email is not used.
139 // ForceRSA makes the Manager generate certificates with 2048-bit RSA keys.
141 // If false, a default is used. Currently the default
142 // is EC-based keys using the P-256 curve.
146 client *acme.Client // initialized by acmeClient method
149 state map[string]*certState // keyed by domain name
151 // tokenCert is keyed by token domain name, which matches server name
152 // of ClientHello. Keys always have ".acme.invalid" suffix.
153 tokenCertMu sync.RWMutex
154 tokenCert map[string]*tls.Certificate
156 // renewal tracks the set of domains currently running renewal timers.
157 // It is keyed by domain name.
159 renewal map[string]*domainRenewal
162 // GetCertificate implements the tls.Config.GetCertificate hook.
163 // It provides a TLS certificate for hello.ServerName host, including answering
164 // *.acme.invalid (TLS-SNI) challenges. All other fields of hello are ignored.
166 // If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
167 // a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
168 // The error is propagated back to the caller of GetCertificate and is user-visible.
169 // This does not affect cached certs. See HostPolicy field description for more details.
170 func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
172 return nil, errors.New("acme/autocert: Manager.Prompt not set")
175 name := hello.ServerName
177 return nil, errors.New("acme/autocert: missing server name")
179 if !strings.Contains(strings.Trim(name, "."), ".") {
180 return nil, errors.New("acme/autocert: server name component count invalid")
182 if strings.ContainsAny(name, `/\`) {
183 return nil, errors.New("acme/autocert: server name contains invalid character")
186 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
189 // check whether this is a token cert requested for TLS-SNI challenge
190 if strings.HasSuffix(name, ".acme.invalid") {
191 m.tokenCertMu.RLock()
192 defer m.tokenCertMu.RUnlock()
193 if cert := m.tokenCert[name]; cert != nil {
196 if cert, err := m.cacheGet(ctx, name); err == nil {
199 // TODO: cache error results?
200 return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
204 name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
205 cert, err := m.cert(ctx, name)
209 if err != ErrCacheMiss {
214 if err := m.hostPolicy()(ctx, name); err != nil {
217 cert, err = m.createCert(ctx, name)
221 m.cachePut(ctx, name, cert)
225 // cert returns an existing certificate either from m.state or cache.
226 // If a certificate is found in cache but not in m.state, the latter will be filled
227 // with the cached value.
228 func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, error) {
230 if s, ok := m.state[name]; ok {
236 defer m.stateMu.Unlock()
237 cert, err := m.cacheGet(ctx, name)
241 signer, ok := cert.PrivateKey.(crypto.Signer)
243 return nil, errors.New("acme/autocert: private key cannot sign")
246 m.state = make(map[string]*certState)
250 cert: cert.Certificate,
254 go m.renew(name, s.key, s.leaf.NotAfter)
258 // cacheGet always returns a valid certificate, or an error otherwise.
259 // If a cached certficate exists but is not valid, ErrCacheMiss is returned.
260 func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate, error) {
262 return nil, ErrCacheMiss
264 data, err := m.Cache.Get(ctx, domain)
270 priv, pub := pem.Decode(data)
271 if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
272 return nil, ErrCacheMiss
274 privKey, err := parsePrivateKey(priv.Bytes)
283 b, pub = pem.Decode(pub)
287 pubDER = append(pubDER, b.Bytes)
290 // Leftover content not consumed by pem.Decode. Corrupt. Ignore.
291 return nil, ErrCacheMiss
294 // verify and create TLS cert
295 leaf, err := validCert(domain, pubDER, privKey)
297 return nil, ErrCacheMiss
299 tlscert := &tls.Certificate{
307 func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Certificate) error {
312 // contains PEM-encoded data
316 switch key := tlscert.PrivateKey.(type) {
317 case *ecdsa.PrivateKey:
318 if err := encodeECDSAKey(&buf, key); err != nil {
321 case *rsa.PrivateKey:
322 b := x509.MarshalPKCS1PrivateKey(key)
323 pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: b}
324 if err := pem.Encode(&buf, pb); err != nil {
328 return errors.New("acme/autocert: unknown private key type")
332 for _, b := range tlscert.Certificate {
333 pb := &pem.Block{Type: "CERTIFICATE", Bytes: b}
334 if err := pem.Encode(&buf, pb); err != nil {
339 return m.Cache.Put(ctx, domain, buf.Bytes())
342 func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
343 b, err := x509.MarshalECPrivateKey(key)
347 pb := &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
348 return pem.Encode(w, pb)
351 // createCert starts the domain ownership verification and returns a certificate
352 // for that domain upon success.
354 // If the domain is already being verified, it waits for the existing verification to complete.
355 // Either way, createCert blocks for the duration of the whole process.
356 func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certificate, error) {
357 // TODO: maybe rewrite this whole piece using sync.Once
358 state, err := m.certState(domain)
362 // state may exist if another goroutine is already working on it
363 // in which case just wait for it to finish
366 defer state.RUnlock()
367 return state.tlscert()
370 // We are the first; state is locked.
371 // Unblock the readers when domain ownership is verified
372 // and the we got the cert or the process failed.
376 der, leaf, err := m.authorizedCert(ctx, state.key, domain)
378 // Remove the failed state after some time,
379 // making the manager call createCert again on the following TLS hello.
380 time.AfterFunc(createCertRetryAfter, func() {
381 defer testDidRemoveState(domain)
383 defer m.stateMu.Unlock()
384 // Verify the state hasn't changed and it's still invalid
386 s, ok := m.state[domain]
390 if _, err := validCert(domain, s.cert, s.key); err == nil {
393 delete(m.state, domain)
399 go m.renew(domain, state.key, state.leaf.NotAfter)
400 return state.tlscert()
403 // certState returns a new or existing certState.
404 // If a new certState is returned, state.exist is false and the state is locked.
405 // The returned error is non-nil only in the case where a new state could not be created.
406 func (m *Manager) certState(domain string) (*certState, error) {
408 defer m.stateMu.Unlock()
410 m.state = make(map[string]*certState)
413 if state, ok := m.state[domain]; ok {
423 key, err = rsa.GenerateKey(rand.Reader, 2048)
425 key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
435 state.Lock() // will be unlocked by m.certState caller
436 m.state[domain] = state
440 // authorizedCert starts domain ownership verification process and requests a new cert upon success.
441 // The key argument is the certificate private key.
442 func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
443 if err := m.verify(ctx, domain); err != nil {
446 client, err := m.acmeClient(ctx)
450 csr, err := certRequest(key, domain)
454 der, _, err = client.CreateCert(ctx, csr, 0, true)
458 leaf, err = validCert(domain, der, key)
462 return der, leaf, nil
465 // verify starts a new identifier (domain) authorization flow.
466 // It prepares a challenge response and then blocks until the authorization
467 // is marked as "completed" by the CA (either succeeded or failed).
469 // verify returns nil iff the verification was successful.
470 func (m *Manager) verify(ctx context.Context, domain string) error {
471 client, err := m.acmeClient(ctx)
476 // start domain authorization and get the challenge
477 authz, err := client.Authorize(ctx, domain)
481 // maybe don't need to at all
482 if authz.Status == acme.StatusValid {
486 // pick a challenge: prefer tls-sni-02 over tls-sni-01
487 // TODO: consider authz.Combinations
488 var chal *acme.Challenge
489 for _, c := range authz.Challenges {
490 if c.Type == "tls-sni-02" {
494 if c.Type == "tls-sni-01" {
499 return errors.New("acme/autocert: no supported challenge type found")
502 // create a token cert for the challenge response
509 cert, name, err = client.TLSSNI01ChallengeCert(chal.Token)
511 cert, name, err = client.TLSSNI02ChallengeCert(chal.Token)
513 err = fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
518 m.putTokenCert(ctx, name, &cert)
520 // verification has ended at this point
521 // don't need token cert anymore
522 go m.deleteTokenCert(name)
525 // ready to fulfill the challenge
526 if _, err := client.Accept(ctx, chal); err != nil {
529 // wait for the CA to validate
530 _, err = client.WaitAuthorization(ctx, authz.URI)
534 // putTokenCert stores the cert under the named key in both m.tokenCert map
536 func (m *Manager) putTokenCert(ctx context.Context, name string, cert *tls.Certificate) {
538 defer m.tokenCertMu.Unlock()
539 if m.tokenCert == nil {
540 m.tokenCert = make(map[string]*tls.Certificate)
542 m.tokenCert[name] = cert
543 m.cachePut(ctx, name, cert)
546 // deleteTokenCert removes the token certificate for the specified domain name
547 // from both m.tokenCert map and m.Cache.
548 func (m *Manager) deleteTokenCert(name string) {
550 defer m.tokenCertMu.Unlock()
551 delete(m.tokenCert, name)
553 m.Cache.Delete(context.Background(), name)
557 // renew starts a cert renewal timer loop, one per domain.
559 // The loop is scheduled in two cases:
560 // - a cert was fetched from cache for the first time (wasn't in m.state)
561 // - a new cert was created by m.createCert
563 // The key argument is a certificate private key.
564 // The exp argument is the cert expiration time (NotAfter).
565 func (m *Manager) renew(domain string, key crypto.Signer, exp time.Time) {
567 defer m.renewalMu.Unlock()
568 if m.renewal[domain] != nil {
569 // another goroutine is already on it
572 if m.renewal == nil {
573 m.renewal = make(map[string]*domainRenewal)
575 dr := &domainRenewal{m: m, domain: domain, key: key}
576 m.renewal[domain] = dr
580 // stopRenew stops all currently running cert renewal timers.
581 // The timers are not restarted during the lifetime of the Manager.
582 func (m *Manager) stopRenew() {
584 defer m.renewalMu.Unlock()
585 for name, dr := range m.renewal {
586 delete(m.renewal, name)
591 func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
592 const keyName = "acme_account.key"
594 genKey := func() (*ecdsa.PrivateKey, error) {
595 return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
602 data, err := m.Cache.Get(ctx, keyName)
603 if err == ErrCacheMiss {
609 if err := encodeECDSAKey(&buf, key); err != nil {
612 if err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {
621 priv, _ := pem.Decode(data)
622 if priv == nil || !strings.Contains(priv.Type, "PRIVATE") {
623 return nil, errors.New("acme/autocert: invalid account key found in cache")
625 return parsePrivateKey(priv.Bytes)
628 func (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {
630 defer m.clientMu.Unlock()
637 client = &acme.Client{DirectoryURL: acme.LetsEncryptURL}
639 if client.Key == nil {
641 client.Key, err = m.accountKey(ctx)
648 contact = []string{"mailto:" + m.Email}
650 a := &acme.Account{Contact: contact}
651 _, err := client.Register(ctx, a, m.Prompt)
652 if ae, ok := err.(*acme.Error); err == nil || ok && ae.StatusCode == http.StatusConflict {
653 // conflict indicates the key is already registered
660 func (m *Manager) hostPolicy() HostPolicy {
661 if m.HostPolicy != nil {
664 return defaultHostPolicy
667 func (m *Manager) renewBefore() time.Duration {
668 if m.RenewBefore > renewJitter {
671 return 720 * time.Hour // 30 days
674 // certState is ready when its mutex is unlocked for reading.
675 type certState struct {
677 locked bool // locked for read/write
678 key crypto.Signer // private key for cert
679 cert [][]byte // DER encoding
680 leaf *x509.Certificate // parsed cert[0]; always non-nil if cert != nil
683 // tlscert creates a tls.Certificate from s.key and s.cert.
684 // Callers should wrap it in s.RLock() and s.RUnlock().
685 func (s *certState) tlscert() (*tls.Certificate, error) {
687 return nil, errors.New("acme/autocert: missing signer")
689 if len(s.cert) == 0 {
690 return nil, errors.New("acme/autocert: missing certificate")
692 return &tls.Certificate{
699 // certRequest creates a certificate request for the given common name cn
700 // and optional SANs.
701 func certRequest(key crypto.Signer, cn string, san ...string) ([]byte, error) {
702 req := &x509.CertificateRequest{
703 Subject: pkix.Name{CommonName: cn},
706 return x509.CreateCertificateRequest(rand.Reader, req, key)
709 // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
710 // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.
711 // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
713 // Inspired by parsePrivateKey in crypto/tls/tls.go.
714 func parsePrivateKey(der []byte) (crypto.Signer, error) {
715 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
718 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
719 switch key := key.(type) {
720 case *rsa.PrivateKey:
722 case *ecdsa.PrivateKey:
725 return nil, errors.New("acme/autocert: unknown private key type in PKCS#8 wrapping")
728 if key, err := x509.ParseECPrivateKey(der); err == nil {
732 return nil, errors.New("acme/autocert: failed to parse private key")
735 // validCert parses a cert chain provided as der argument and verifies the leaf, der[0],
736 // corresponds to the private key, as well as the domain match and expiration dates.
737 // It doesn't do any revocation checking.
739 // The returned value is the verified leaf cert.
740 func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
741 // parse public part(s)
743 for _, b := range der {
746 pub := make([]byte, n)
748 for _, b := range der {
749 n += copy(pub[n:], b)
751 x509Cert, err := x509.ParseCertificates(pub)
752 if len(x509Cert) == 0 {
753 return nil, errors.New("acme/autocert: no public key found")
755 // verify the leaf is not expired and matches the domain name
758 if now.Before(leaf.NotBefore) {
759 return nil, errors.New("acme/autocert: certificate is not valid yet")
761 if now.After(leaf.NotAfter) {
762 return nil, errors.New("acme/autocert: expired certificate")
764 if err := leaf.VerifyHostname(domain); err != nil {
767 // ensure the leaf corresponds to the private key
768 switch pub := leaf.PublicKey.(type) {
770 prv, ok := key.(*rsa.PrivateKey)
772 return nil, errors.New("acme/autocert: private key type does not match public key type")
774 if pub.N.Cmp(prv.N) != 0 {
775 return nil, errors.New("acme/autocert: private key does not match public key")
777 case *ecdsa.PublicKey:
778 prv, ok := key.(*ecdsa.PrivateKey)
780 return nil, errors.New("acme/autocert: private key type does not match public key type")
782 if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
783 return nil, errors.New("acme/autocert: private key does not match public key")
786 return nil, errors.New("acme/autocert: unknown public key algorithm")
791 func retryAfter(v string) time.Duration {
792 if i, err := strconv.Atoi(v); err == nil {
793 return time.Duration(i) * time.Second
795 if t, err := http.ParseTime(v); err == nil {
796 return t.Sub(timeNow())
801 type lockedMathRand struct {
806 func (r *lockedMathRand) int63n(max int64) int64 {
808 n := r.rnd.Int63n(max)
813 // For easier testing.
817 // Called when a state is removed.
818 testDidRemoveState = func(domain string) {}