forked from smallstep/certificates
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmutable_tls_config.go
109 lines (97 loc) · 2.65 KB
/
mutable_tls_config.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package ca
import (
"crypto/tls"
"crypto/x509"
"sync"
"github.com/smallstep/certificates/api"
)
// mutableTLSConfig allows to use a tls.Config with mutable cert pools.
type mutableTLSConfig struct {
sync.RWMutex
config *tls.Config
clientCerts []*x509.Certificate
rootCerts []*x509.Certificate
mutClientCerts []*x509.Certificate
mutRootCerts []*x509.Certificate
}
// newMutableTLSConfig creates a new mutableTLSConfig that will be later
// initialized with a tls.Config.
func newMutableTLSConfig() *mutableTLSConfig {
return &mutableTLSConfig{
clientCerts: []*x509.Certificate{},
rootCerts: []*x509.Certificate{},
mutClientCerts: []*x509.Certificate{},
mutRootCerts: []*x509.Certificate{},
}
}
// Init initializes the mutable tls.Config with the given tls.Config.
func (c *mutableTLSConfig) Init(base *tls.Config) {
c.Lock()
c.config = base.Clone()
c.Unlock()
}
// TLSConfig returns the updated tls.Config it it has changed. It's used in the
// tls.Config GetConfigForClient.
func (c *mutableTLSConfig) TLSConfig() (config *tls.Config) {
c.RLock()
config = c.config.Clone()
c.RUnlock()
return
}
// Reload reloads the tls.Config with the new CAs.
func (c *mutableTLSConfig) Reload() {
// Prepare new pools
c.RLock()
rootCAs := x509.NewCertPool()
clientCAs := x509.NewCertPool()
// Fixed certs
for _, cert := range c.rootCerts {
rootCAs.AddCert(cert)
}
for _, cert := range c.clientCerts {
clientCAs.AddCert(cert)
}
// Mutable certs
for _, cert := range c.mutRootCerts {
rootCAs.AddCert(cert)
}
for _, cert := range c.mutClientCerts {
clientCAs.AddCert(cert)
}
c.RUnlock()
// Set new pool
c.Lock()
c.config.RootCAs = rootCAs
c.config.ClientCAs = clientCAs
c.mutRootCerts = []*x509.Certificate{}
c.mutClientCerts = []*x509.Certificate{}
c.Unlock()
}
// AddImmutableClientCACert add an immutable cert to ClientCAs.
func (c *mutableTLSConfig) AddImmutableClientCACert(cert *x509.Certificate) {
c.Lock()
c.clientCerts = append(c.clientCerts, cert)
c.Unlock()
}
// AddImmutableRootCACert add an immutable cert to RootCas.
func (c *mutableTLSConfig) AddImmutableRootCACert(cert *x509.Certificate) {
c.Lock()
c.rootCerts = append(c.rootCerts, cert)
c.Unlock()
}
// AddClientCAs add mutable certs to ClientCAs.
func (c *mutableTLSConfig) AddClientCAs(certs []api.Certificate) {
c.Lock()
for _, cert := range certs {
c.mutClientCerts = append(c.mutClientCerts, cert.Certificate)
}
c.Unlock()
}
// AddRootCAs add mutable certs to RootCAs.
func (c *mutableTLSConfig) AddRootCAs(certs []api.Certificate) {
c.Lock()
for _, cert := range certs {
c.mutRootCerts = append(c.mutRootCerts, cert.Certificate)
}
c.Unlock()
}