-
-
Notifications
You must be signed in to change notification settings - Fork 17
/
certManager.go
87 lines (78 loc) · 2.84 KB
/
certManager.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
package server
import (
"crypto/tls"
"errors"
"fmt"
"github.com/plgd-dev/hub/v2/pkg/config/property/urischeme"
"github.com/plgd-dev/hub/v2/pkg/fsnotify"
"github.com/plgd-dev/hub/v2/pkg/log"
"github.com/plgd-dev/hub/v2/pkg/security/certManager/general"
"github.com/plgd-dev/hub/v2/pkg/strings"
)
// Config provides configuration of a file based Server Certificate manager. CAPool can be a string or an array of strings.
type Config struct {
CAPool interface{} `yaml:"caPool" json:"caPool" description:"file path to the root certificates in PEM format"`
KeyFile urischeme.URIScheme `yaml:"keyFile" json:"keyFile" description:"file name of private key in PEM format"`
CertFile urischeme.URIScheme `yaml:"certFile" json:"certFile" description:"file name of certificate in PEM format"`
ClientCertificateRequired bool `yaml:"clientCertificateRequired" json:"clientCertificateRequired" description:"require client certificate"`
CAPoolIsOptional bool `yaml:"-" json:"-"`
caPoolArray []urischeme.URIScheme `yaml:"-" json:"-"`
validated bool
}
func (c *Config) Validate() error {
caPoolArray, ok := strings.ToStringArray(c.CAPool)
if !ok {
return fmt.Errorf("caPool('%v') - unsupported", c.CAPool)
}
c.caPoolArray = urischeme.ToURISchemeArray(caPoolArray)
if !c.CAPoolIsOptional && len(caPoolArray) == 0 {
return fmt.Errorf("caPool('%v') - is empty", c.CAPool)
}
if c.CertFile == "" {
return fmt.Errorf("certFile('%v')", c.CertFile)
}
if c.KeyFile == "" {
return fmt.Errorf("keyFile('%v')", c.KeyFile)
}
c.validated = true
return nil
}
func (c *Config) CAPoolArray() ([]urischeme.URIScheme, error) {
if !c.validated {
return nil, errors.New("call Validate() first")
}
return c.caPoolArray, nil
}
// CertManager holds certificates from filesystem watched for changes
type CertManager struct {
c *general.CertManager
}
// GetTLSConfig returns tls configuration for clients
func (c *CertManager) GetTLSConfig() *tls.Config {
return c.c.GetServerTLSConfig()
}
// Close ends watching certificates
func (c *CertManager) Close() {
c.c.Close()
}
// New creates a new certificate manager which watches for certs in a filesystem
func New(config Config, fileWatcher *fsnotify.Watcher, logger log.Logger) (*CertManager, error) {
if !config.validated {
if err := config.Validate(); err != nil {
return nil, err
}
}
c, err := general.New(general.Config{
CAPool: config.caPoolArray,
KeyFile: config.KeyFile,
CertFile: config.CertFile,
ClientCertificateRequired: config.ClientCertificateRequired,
UseSystemCAPool: false,
}, fileWatcher, logger.With(log.CertManagerKey, "server"))
if err != nil {
return nil, err
}
return &CertManager{
c: c,
}, nil
}