github.com/Jeffail/benthos/v3@v3.65.0/lib/util/tls/type.go (about) 1 package tls 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "errors" 7 "os" 8 ) 9 10 //------------------------------------------------------------------------------ 11 12 // Documentation is a markdown description of how and why to use TLS settings. 13 const Documentation = `### TLS 14 15 Custom TLS settings can be used to override system defaults. This includes 16 providing a collection of root certificate authorities, providing a list of 17 client certificates to use for client verification and skipping certificate 18 verification. 19 20 Client certificates can either be added by file or by raw contents: 21 22 ` + "``` yaml" + ` 23 enabled: true 24 client_certs: 25 - cert_file: ./example.pem 26 key_file: ./example.key 27 - cert: foo 28 key: bar 29 ` + "```" + `` 30 31 //------------------------------------------------------------------------------ 32 33 // ClientCertConfig contains config fields for a client certificate. 34 type ClientCertConfig struct { 35 CertFile string `json:"cert_file" yaml:"cert_file"` 36 KeyFile string `json:"key_file" yaml:"key_file"` 37 Cert string `json:"cert" yaml:"cert"` 38 Key string `json:"key" yaml:"key"` 39 } 40 41 // Config contains configuration params for TLS. 42 type Config struct { 43 Enabled bool `json:"enabled" yaml:"enabled"` 44 RootCAs string `json:"root_cas" yaml:"root_cas"` 45 RootCAsFile string `json:"root_cas_file" yaml:"root_cas_file"` 46 InsecureSkipVerify bool `json:"skip_cert_verify" yaml:"skip_cert_verify"` 47 ClientCertificates []ClientCertConfig `json:"client_certs" yaml:"client_certs"` 48 EnableRenegotiation bool `json:"enable_renegotiation" yaml:"enable_renegotiation"` 49 } 50 51 // NewConfig creates a new Config with default values. 52 func NewConfig() Config { 53 return Config{ 54 Enabled: false, 55 RootCAs: "", 56 RootCAsFile: "", 57 InsecureSkipVerify: false, 58 ClientCertificates: []ClientCertConfig{}, 59 EnableRenegotiation: false, 60 } 61 } 62 63 //------------------------------------------------------------------------------ 64 65 // Get returns a valid *tls.Config based on the configuration values of Config. 66 // If none of the config fields are set then a nil config is returned. 67 func (c *Config) Get() (*tls.Config, error) { 68 var tlsConf *tls.Config 69 initConf := func() { 70 if tlsConf != nil { 71 return 72 } 73 tlsConf = &tls.Config{ 74 MinVersion: tls.VersionTLS12, 75 } 76 } 77 78 if len(c.RootCAs) > 0 && len(c.RootCAsFile) > 0 { 79 return nil, errors.New("only one field between root_cas and root_cas_file can be specified") 80 } 81 82 if len(c.RootCAsFile) > 0 { 83 caCert, err := os.ReadFile(c.RootCAsFile) 84 if err != nil { 85 return nil, err 86 } 87 initConf() 88 tlsConf.RootCAs = x509.NewCertPool() 89 tlsConf.RootCAs.AppendCertsFromPEM(caCert) 90 } 91 92 if len(c.RootCAs) > 0 { 93 initConf() 94 tlsConf.RootCAs = x509.NewCertPool() 95 tlsConf.RootCAs.AppendCertsFromPEM([]byte(c.RootCAs)) 96 } 97 98 for _, conf := range c.ClientCertificates { 99 cert, err := conf.Load() 100 if err != nil { 101 return nil, err 102 } 103 initConf() 104 tlsConf.Certificates = append(tlsConf.Certificates, cert) 105 } 106 107 if c.EnableRenegotiation { 108 initConf() 109 tlsConf.Renegotiation = tls.RenegotiateFreelyAsClient 110 } 111 112 if c.InsecureSkipVerify { 113 initConf() 114 tlsConf.InsecureSkipVerify = true 115 } 116 117 return tlsConf, nil 118 } 119 120 // Load returns a TLS certificate, based on either file paths in the 121 // config or the raw certs as strings. 122 func (c *ClientCertConfig) Load() (tls.Certificate, error) { 123 if c.CertFile != "" || c.KeyFile != "" { 124 if c.CertFile == "" { 125 return tls.Certificate{}, errors.New("missing cert_file field in client certificate config") 126 } 127 if c.KeyFile == "" { 128 return tls.Certificate{}, errors.New("missing key_file field in client certificate config") 129 } 130 return tls.LoadX509KeyPair(c.CertFile, c.KeyFile) 131 } 132 if c.Cert == "" { 133 return tls.Certificate{}, errors.New("missing cert field in client certificate config") 134 } 135 if c.Key == "" { 136 return tls.Certificate{}, errors.New("missing key field in client certificate config") 137 } 138 return tls.X509KeyPair([]byte(c.Cert), []byte(c.Key)) 139 } 140 141 //------------------------------------------------------------------------------