-
Notifications
You must be signed in to change notification settings - Fork 522
/
tls.go
88 lines (76 loc) · 2.58 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 clouds
import (
"bytes"
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
)
func computeTLSConfig(cloud Cloud, options cloudOpts) (*tls.Config, error) {
tlsConfig := new(tls.Config)
if caCertPath := coalesce(options.caCertPath, os.Getenv("OS_CACERT"), cloud.CACertFile); caCertPath != "" {
caCertPath, err := resolveTilde(caCertPath)
if err != nil {
return nil, fmt.Errorf("failed to resolve user home directory: %w", err)
}
caCert, err := ioutil.ReadFile(caCertPath)
if err != nil {
return nil, fmt.Errorf("failed to open the CA cert file: %w", err)
}
caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(bytes.TrimSpace(caCert)); !ok {
return nil, fmt.Errorf("failed to parse the CA Cert from %q", caCertPath)
}
tlsConfig.RootCAs = caCertPool
}
tlsConfig.InsecureSkipVerify = func() bool {
if options.insecure != nil {
return *options.insecure
}
if cloud.Verify != nil {
return !*cloud.Verify
}
return false
}()
if clientCertPath, clientKeyPath := coalesce(options.clientCertPath, os.Getenv("OS_CERT"), cloud.ClientCertFile), coalesce(options.clientKeyPath, os.Getenv("OS_KEY"), cloud.ClientKeyFile); clientCertPath != "" && clientKeyPath != "" {
clientCertPath, err := resolveTilde(clientCertPath)
if err != nil {
return nil, fmt.Errorf("failed to resolve user home directory in client cert path: %w", err)
}
clientKeyPath, err := resolveTilde(clientKeyPath)
if err != nil {
return nil, fmt.Errorf("failed to resolve user home directory in client cert key path: %w", err)
}
clientCert, err := ioutil.ReadFile(clientCertPath)
if err != nil {
return nil, fmt.Errorf("failed to read the client cert file: %w", err)
}
clientKey, err := ioutil.ReadFile(clientKeyPath)
if err != nil {
return nil, fmt.Errorf("failed to read the client cert key file: %w", err)
}
cert, err := tls.X509KeyPair(clientCert, clientKey)
if err != nil {
return nil, err
}
tlsConfig.Certificates = []tls.Certificate{cert}
} else if clientCertPath != "" && clientKeyPath == "" {
return nil, fmt.Errorf("client cert is set, but client cert key is missing")
} else if clientCertPath == "" && clientKeyPath != "" {
return nil, fmt.Errorf("client cert key is set, but client cert is missing")
}
return tlsConfig, nil
}
func resolveTilde(p string) (string, error) {
if after := strings.TrimPrefix(p, "~/"); after != p {
h, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("failed to resolve user home directory: %w", err)
}
return path.Join(h, after), nil
}
return p, nil
}