aboutsummaryrefslogtreecommitdiff
path: root/crypto/acme/autocert/autocert.go
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/acme/autocert/autocert.go')
-rw-r--r--crypto/acme/autocert/autocert.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/crypto/acme/autocert/autocert.go b/crypto/acme/autocert/autocert.go
new file mode 100644
index 0000000..f99c36e
--- /dev/null
+++ b/crypto/acme/autocert/autocert.go
@@ -0,0 +1,85 @@
1package autocert
2
3import (
4 "context"
5 "crypto/tls"
6 "fmt"
7 "net"
8
9 "code.crute.us/mcrute/golib/service"
10 "golang.org/x/net/idna"
11)
12
13type InfoReporter interface {
14 Info(...interface{})
15}
16
17type CertProvider interface {
18 GetCertificate(*tls.ClientHelloInfo) (*tls.Certificate, error)
19 Listener() net.Listener
20 TLSConfig() *tls.Config
21}
22
23type PrimingCertProvider interface {
24 CertProvider
25 PrimeCache() error
26 PrimingReporter(InfoReporter) service.RunnerFunc
27}
28
29type ACMEHostList struct {
30 hosts map[string]bool
31}
32
33func NewACMEHostList(hosts ...string) *ACMEHostList {
34 hl := make(map[string]bool, len(hosts))
35 for _, h := range hosts {
36 if h, err := idna.Lookup.ToASCII(h); err == nil {
37 hl[h] = true
38 }
39 }
40 return &ACMEHostList{hl}
41}
42
43func (h *ACMEHostList) HostPolicy(_ context.Context, host string) error {
44 if !h.hosts[host] {
45 return fmt.Errorf("acme/autocert: host %q not configured in HostWhitelist", host)
46 }
47 return nil
48}
49
50func (h *ACMEHostList) Hosts() []string {
51 out := []string{}
52 for k, _ := range h.hosts {
53 out = append(out, k)
54 }
55 return out
56}
57
58// PrimeCache makes a request to the autocert.Manager.GetCertificate function
59// for each host in the host list. It will request ECDSA certificates. This
60// will fill a certificate cache if it has not yet been filled and has the side
61// effect of starting renewal goroutines for each allowed host.
62//
63// If reportcb is not nil it will be called with a log message for each host
64// that is being primed.
65func (h *ACMEHostList) PrimeCache(m CertProvider, report chan<- string) error {
66 for k, _ := range h.hosts {
67 if report != nil {
68 report <- fmt.Sprintf("Priming certificate cache for %s", k)
69 }
70 // ECDSA Version
71 if _, err := m.GetCertificate(&tls.ClientHelloInfo{
72 ServerName: k,
73 SignatureSchemes: []tls.SignatureScheme{tls.ECDSAWithP256AndSHA256},
74 }); err != nil {
75 return err
76 }
77 // RSA Version
78 if _, err := m.GetCertificate(&tls.ClientHelloInfo{
79 ServerName: k,
80 }); err != nil {
81 return err
82 }
83 }
84 return nil
85}