fix(tls): Pass certificate and private key files to listener method (#531)

Fixes #530
This commit is contained in:
TwiN
2023-07-20 19:02:34 -04:00
committed by GitHub
parent 2f6b8f23f7
commit fd17dcd204
4 changed files with 57 additions and 26 deletions

View File

@ -34,8 +34,6 @@ type TLSConfig struct {
// PrivateKeyFile is the private key file for TLS in PEM format.
PrivateKeyFile string `yaml:"private-key-file,omitempty"`
tlsConfig *tls.Config
}
// GetDefaultConfig returns a Config struct with the default values
@ -57,33 +55,29 @@ func (web *Config) ValidateAndSetDefaults() error {
}
// Try to load the TLS certificates
if web.TLS != nil {
if err := web.TLS.loadConfig(); err != nil {
if err := web.TLS.isValid(); err != nil {
return fmt.Errorf("invalid tls config: %w", err)
}
}
return nil
}
func (web *Config) HasTLS() bool {
return web.TLS != nil && len(web.TLS.CertificateFile) > 0 && len(web.TLS.PrivateKeyFile) > 0
}
// SocketAddress returns the combination of the Address and the Port
func (web *Config) SocketAddress() string {
return fmt.Sprintf("%s:%d", web.Address, web.Port)
}
func (t *TLSConfig) loadConfig() error {
func (t *TLSConfig) isValid() error {
if len(t.CertificateFile) > 0 && len(t.PrivateKeyFile) > 0 {
certificate, err := tls.LoadX509KeyPair(t.CertificateFile, t.PrivateKeyFile)
_, err := tls.LoadX509KeyPair(t.CertificateFile, t.PrivateKeyFile)
if err != nil {
return err
}
t.tlsConfig = &tls.Config{Certificates: []tls.Certificate{certificate}}
return nil
}
return errors.New("certificate-file and private-key-file must be specified")
}
func (web *Config) TLSConfig() *tls.Config {
if web.TLS != nil {
return web.TLS.tlsConfig
}
return nil
}

View File

@ -37,6 +37,27 @@ func TestConfig_ValidateAndSetDefaults(t *testing.T) {
cfg: &Config{Port: 100000000},
expectedErr: true,
},
{
name: "with-good-tls-config",
cfg: &Config{Port: 443, TLS: &TLSConfig{CertificateFile: "../../testdata/cert.pem", PrivateKeyFile: "../../testdata/cert.key"}},
expectedAddress: "0.0.0.0",
expectedPort: 443,
expectedErr: false,
},
{
name: "with-bad-tls-config",
cfg: &Config{Port: 443, TLS: &TLSConfig{CertificateFile: "../../testdata/badcert.pem", PrivateKeyFile: "../../testdata/cert.key"}},
expectedAddress: "0.0.0.0",
expectedPort: 443,
expectedErr: true,
},
{
name: "with-partial-tls-config",
cfg: &Config{Port: 443, TLS: &TLSConfig{CertificateFile: "", PrivateKeyFile: "../../testdata/cert.key"}},
expectedAddress: "0.0.0.0",
expectedPort: 443,
expectedErr: true,
},
}
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
@ -67,7 +88,7 @@ func TestConfig_SocketAddress(t *testing.T) {
}
}
func TestConfig_TLSConfig(t *testing.T) {
func TestConfig_isValid(t *testing.T) {
scenarios := []struct {
name string
cfg *Config
@ -79,27 +100,37 @@ func TestConfig_TLSConfig(t *testing.T) {
expectedErr: false,
},
{
name: "missing-crt-file",
name: "missing-certificate-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "doesnotexist", PrivateKeyFile: "../../testdata/cert.key"}},
expectedErr: true,
},
{
name: "bad-crt-file",
name: "bad-certificate-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "../../testdata/badcert.pem", PrivateKeyFile: "../../testdata/cert.key"}},
expectedErr: true,
},
{
name: "no-certificate-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "", PrivateKeyFile: "../../testdata/cert.key"}},
expectedErr: true,
},
{
name: "missing-private-key-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "../../testdata/cert.pem", PrivateKeyFile: "doesnotexist"}},
expectedErr: true,
},
{
name: "no-private-key-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "../../testdata/cert.pem", PrivateKeyFile: ""}},
expectedErr: true,
},
{
name: "bad-private-key-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "../../testdata/cert.pem", PrivateKeyFile: "../../testdata/badcert.key"}},
expectedErr: true,
},
{
name: "bad-cert-and-private-key-file",
name: "bad-certificate-and-private-key-file",
cfg: &Config{TLS: &TLSConfig{CertificateFile: "../../testdata/badcert.pem", PrivateKeyFile: "../../testdata/badcert.key"}},
expectedErr: true,
},
@ -112,8 +143,8 @@ func TestConfig_TLSConfig(t *testing.T) {
return
}
if !scenario.expectedErr {
if scenario.cfg.TLS.tlsConfig == nil {
t.Error("TLS configuration was not correctly loaded although no error was returned")
if scenario.cfg.TLS.isValid() != nil {
t.Error("cfg.TLS.isValid() returned an error even though no error was expected")
}
}
})