/
options.go
112 lines (91 loc) · 2.84 KB
/
options.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
110
111
112
// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.
package tls
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"path/filepath"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/pkg/errors"
)
// NewServerConfig provides new server TLS configuration.
func NewServerConfig(logger log.Logger, cert, key, clientCA string) (*tls.Config, error) {
if key == "" && cert == "" {
if clientCA != "" {
return nil, errors.New("when a client CA is used a server key and certificate must also be provided")
}
level.Info(logger).Log("msg", "disabled TLS, key and cert must be set to enable")
return nil, nil
}
level.Info(logger).Log("msg", "enabling server side TLS")
if key == "" || cert == "" {
return nil, errors.New("both server key and certificate must be provided")
}
tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS12,
}
tlsCert, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
return nil, errors.Wrap(err, "server credentials")
}
tlsCfg.Certificates = []tls.Certificate{tlsCert}
if clientCA != "" {
caPEM, err := ioutil.ReadFile(filepath.Clean(clientCA))
if err != nil {
return nil, errors.Wrap(err, "reading client CA")
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(caPEM) {
return nil, errors.Wrap(err, "building client CA")
}
tlsCfg.ClientCAs = certPool
tlsCfg.ClientAuth = tls.RequireAndVerifyClientCert
level.Info(logger).Log("msg", "server TLS client verification enabled")
}
return tlsCfg, nil
}
// NewClientConfig provides new client TLS configuration.
func NewClientConfig(logger log.Logger, cert, key, caCert, serverName string, skipVerify bool) (*tls.Config, error) {
var certPool *x509.CertPool
if caCert != "" {
caPEM, err := ioutil.ReadFile(filepath.Clean(caCert))
if err != nil {
return nil, errors.Wrap(err, "reading client CA")
}
certPool = x509.NewCertPool()
if !certPool.AppendCertsFromPEM(caPEM) {
return nil, errors.Wrap(err, "building client CA")
}
level.Info(logger).Log("msg", "TLS client using provided certificate pool")
} else {
var err error
certPool, err = x509.SystemCertPool()
if err != nil {
return nil, errors.Wrap(err, "reading system certificate pool")
}
level.Info(logger).Log("msg", "TLS client using system certificate pool")
}
tlsCfg := &tls.Config{
RootCAs: certPool,
}
if serverName != "" {
tlsCfg.ServerName = serverName
}
if skipVerify {
tlsCfg.InsecureSkipVerify = true
}
if (key != "") != (cert != "") {
return nil, errors.New("both client key and certificate must be provided")
}
if cert != "" {
cert, err := tls.LoadX509KeyPair(cert, key)
if err != nil {
return nil, errors.Wrap(err, "client credentials")
}
tlsCfg.Certificates = []tls.Certificate{cert}
level.Info(logger).Log("msg", "TLS client authentication enabled")
}
return tlsCfg, nil
}