-
Notifications
You must be signed in to change notification settings - Fork 351
/
certregistry.go
71 lines (62 loc) · 1.77 KB
/
certregistry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package certregistry
import (
"crypto/tls"
"crypto/x509"
"fmt"
"sync"
log "github.com/sirupsen/logrus"
)
// CertRegistry object holds TLS certificates to be used to terminate TLS connections
// ensuring syncronized access to them.
type CertRegistry struct {
lookup map[string]*tls.Certificate
mx *sync.Mutex
}
// NewCertRegistry initializes the certificate registry.
func NewCertRegistry() *CertRegistry {
l := make(map[string]*tls.Certificate)
return &CertRegistry{
lookup: l,
mx: &sync.Mutex{},
}
}
// Configures certificate for the host if no configuration exists or
// if certificate is valid (`NotBefore` field) after previously configured certificate.
func (r *CertRegistry) ConfigureCertificate(host string, cert *tls.Certificate) error {
if cert == nil {
return fmt.Errorf("cannot configure nil certificate")
}
// loading parsed leaf certificate to certificate
leaf, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return fmt.Errorf("failed parsing leaf certificate: %w", err)
}
cert.Leaf = leaf
r.mx.Lock()
defer r.mx.Unlock()
curr, found := r.lookup[host]
if found {
if cert.Leaf.NotBefore.After(curr.Leaf.NotBefore) {
log.Infof("updating certificate in registry - %s", host)
r.lookup[host] = cert
return nil
} else {
return nil
}
} else {
log.Infof("adding certificate to registry - %s", host)
r.lookup[host] = cert
return nil
}
}
// GetCertFromHello reads the SNI from a TLS client and returns the appropriate certificate.
// If no certificate is found for the host it will return nil.
func (r *CertRegistry) GetCertFromHello(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
r.mx.Lock()
cert, found := r.lookup[hello.ServerName]
r.mx.Unlock()
if found {
return cert, nil
}
return nil, nil
}