-
Notifications
You must be signed in to change notification settings - Fork 801
/
tls.go
88 lines (75 loc) · 3.04 KB
/
tls.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
package tls
import (
"crypto/tls"
"crypto/x509"
"flag"
"os"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
)
// ClientConfig is the config for client TLS.
type ClientConfig struct {
CertPath string `yaml:"tls_cert_path"`
KeyPath string `yaml:"tls_key_path"`
CAPath string `yaml:"tls_ca_path"`
ServerName string `yaml:"tls_server_name"`
InsecureSkipVerify bool `yaml:"tls_insecure_skip_verify"`
}
var (
errKeyMissing = errors.New("certificate given but no key configured")
errCertMissing = errors.New("key given but no certificate configured")
)
// RegisterFlagsWithPrefix registers flags with prefix.
func (cfg *ClientConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) {
f.StringVar(&cfg.CertPath, prefix+".tls-cert-path", "", "Path to the client certificate file, which will be used for authenticating with the server. Also requires the key path to be configured.")
f.StringVar(&cfg.KeyPath, prefix+".tls-key-path", "", "Path to the key file for the client certificate. Also requires the client certificate to be configured.")
f.StringVar(&cfg.CAPath, prefix+".tls-ca-path", "", "Path to the CA certificates file to validate server certificate against. If not set, the host's root CA certificates are used.")
f.StringVar(&cfg.ServerName, prefix+".tls-server-name", "", "Override the expected name on the server certificate.")
f.BoolVar(&cfg.InsecureSkipVerify, prefix+".tls-insecure-skip-verify", false, "Skip validating server certificate.")
}
// GetTLSConfig initialises tls.Config from config options
func (cfg *ClientConfig) GetTLSConfig() (*tls.Config, error) {
config := &tls.Config{
InsecureSkipVerify: cfg.InsecureSkipVerify,
ServerName: cfg.ServerName,
}
// read ca certificates
if cfg.CAPath != "" {
var caCertPool *x509.CertPool
caCert, err := os.ReadFile(cfg.CAPath)
if err != nil {
return nil, errors.Wrapf(err, "error loading ca cert: %s", cfg.CAPath)
}
caCertPool = x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
config.RootCAs = caCertPool
}
// read client certificate
if cfg.CertPath != "" || cfg.KeyPath != "" {
if cfg.CertPath == "" {
return nil, errCertMissing
}
if cfg.KeyPath == "" {
return nil, errKeyMissing
}
clientCert, err := tls.LoadX509KeyPair(cfg.CertPath, cfg.KeyPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to load TLS certificate %s,%s", cfg.CertPath, cfg.KeyPath)
}
config.Certificates = []tls.Certificate{clientCert}
}
return config, nil
}
// GetGRPCDialOptions creates GRPC DialOptions for TLS
func (cfg *ClientConfig) GetGRPCDialOptions(enabled bool) ([]grpc.DialOption, error) {
if !enabled {
return []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}, nil
}
tlsConfig, err := cfg.GetTLSConfig()
if err != nil {
return nil, errors.Wrap(err, "error creating grpc dial options")
}
return []grpc.DialOption{grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))}, nil
}