summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/pkg/tlscfg/config.go
blob: 60e152e0fd2537b7f78f4eef96eacbd298d934f1 (plain)
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
// SPDX-License-Identifier: GPL-3.0-or-later

package tlscfg

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"os"
)

// TLSConfig represents the standard client TLS configuration.
type TLSConfig struct {
	// TLSCA specifies the certificate authority to use when verifying server certificates.
	TLSCA string `yaml:"tls_ca" json:"tls_ca"`

	// TLSCert specifies tls certificate file.
	TLSCert string `yaml:"tls_cert" json:"tls_cert"`

	// TLSKey specifies tls key file.
	TLSKey string `yaml:"tls_key" json:"tls_key"`

	// InsecureSkipVerify controls whether a client verifies the server's certificate chain and host name.
	InsecureSkipVerify bool `yaml:"tls_skip_verify" json:"tls_skip_verify"`
}

// NewTLSConfig creates a tls.Config, may be nil without an error if TLS is not configured.
func NewTLSConfig(cfg TLSConfig) (*tls.Config, error) {
	if cfg.TLSCA == "" && cfg.TLSKey == "" && cfg.TLSCert == "" && !cfg.InsecureSkipVerify {
		return nil, nil
	}

	tlsConfig := &tls.Config{
		InsecureSkipVerify: cfg.InsecureSkipVerify,
		Renegotiation:      tls.RenegotiateNever,
	}

	if cfg.TLSCA != "" {
		pool, err := loadCertPool([]string{cfg.TLSCA})
		if err != nil {
			return nil, err
		}
		tlsConfig.RootCAs = pool
	}

	if cfg.TLSCert != "" && cfg.TLSKey != "" {
		cert, err := loadCertificate(cfg.TLSCert, cfg.TLSKey)
		if err != nil {
			return nil, err
		}
		tlsConfig.Certificates = []tls.Certificate{cert}
	}

	return tlsConfig, nil
}

func loadCertPool(certFiles []string) (*x509.CertPool, error) {
	pool := x509.NewCertPool()
	for _, certFile := range certFiles {
		pem, err := os.ReadFile(certFile)
		if err != nil {
			return nil, fmt.Errorf("could not read certificate %q: %v", certFile, err)
		}
		if !pool.AppendCertsFromPEM(pem) {
			return nil, fmt.Errorf("could not parse any PEM certificates %q: %v", certFile, err)
		}
	}
	return pool, nil
}

func loadCertificate(certFile, keyFile string) (tls.Certificate, error) {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return tls.Certificate{}, fmt.Errorf("could not load keypair %s:%s: %v", certFile, keyFile, err)
	}
	return cert, nil
}