From 87b669d7e33bba43f100bbf4db764026f1be5d83 Mon Sep 17 00:00:00 2001 From: Lyas Spiehler Date: Thu, 8 Dec 2022 06:15:53 -0600 Subject: [PATCH] Add the ability to specify the maximum acceptable TLS version (#414) Signed-off-by: Lyas Spiehler --- config/http_config.go | 9 +++++ .../tls_config.max_and_min_version.bad.json | 2 ++ .../tls_config.max_and_min_version.bad.yml | 2 ++ .../tls_config.max_and_min_version.good.json | 2 ++ .../tls_config.max_and_min_version.good.yml | 2 ++ ..._config.max_and_min_version_same.good.json | 2 ++ ...s_config.max_and_min_version_same.good.yml | 2 ++ .../testdata/tls_config.max_version.good.json | 1 + .../testdata/tls_config.max_version.good.yml | 1 + config/tls_config_test.go | 36 +++++++++++++++++++ 10 files changed, 59 insertions(+) create mode 100644 config/testdata/tls_config.max_and_min_version.bad.json create mode 100644 config/testdata/tls_config.max_and_min_version.bad.yml create mode 100644 config/testdata/tls_config.max_and_min_version.good.json create mode 100644 config/testdata/tls_config.max_and_min_version.good.yml create mode 100644 config/testdata/tls_config.max_and_min_version_same.good.json create mode 100644 config/testdata/tls_config.max_and_min_version_same.good.yml create mode 100644 config/testdata/tls_config.max_version.good.json create mode 100644 config/testdata/tls_config.max_version.good.yml diff --git a/config/http_config.go b/config/http_config.go index c07f696a..92699b58 100644 --- a/config/http_config.go +++ b/config/http_config.go @@ -779,6 +779,13 @@ func NewTLSConfig(cfg *TLSConfig) (*tls.Config, error) { tlsConfig := &tls.Config{ InsecureSkipVerify: cfg.InsecureSkipVerify, MinVersion: uint16(cfg.MinVersion), + MaxVersion: uint16(cfg.MaxVersion), + } + + if cfg.MaxVersion != 0 && cfg.MinVersion != 0 { + if cfg.MaxVersion < cfg.MinVersion { + return nil, fmt.Errorf("tls_config.max_version must be greater than or equal to tls_config.min_version if both are specified") + } } // If a CA cert is provided then let's read it in so we can validate the @@ -826,6 +833,8 @@ type TLSConfig struct { InsecureSkipVerify bool `yaml:"insecure_skip_verify" json:"insecure_skip_verify"` // Minimum TLS version. MinVersion TLSVersion `yaml:"min_version,omitempty" json:"min_version,omitempty"` + // Maximum TLS version. + MaxVersion TLSVersion `yaml:"max_version,omitempty" json:"max_version,omitempty"` } // SetDirectory joins any relative file paths with dir. diff --git a/config/testdata/tls_config.max_and_min_version.bad.json b/config/testdata/tls_config.max_and_min_version.bad.json new file mode 100644 index 00000000..18cb01e9 --- /dev/null +++ b/config/testdata/tls_config.max_and_min_version.bad.json @@ -0,0 +1,2 @@ +{"max_version": "TLS11", +"min_version": "TLS12"} diff --git a/config/testdata/tls_config.max_and_min_version.bad.yml b/config/testdata/tls_config.max_and_min_version.bad.yml new file mode 100644 index 00000000..1d31a350 --- /dev/null +++ b/config/testdata/tls_config.max_and_min_version.bad.yml @@ -0,0 +1,2 @@ +max_version: TLS11 +min_version: TLS12 \ No newline at end of file diff --git a/config/testdata/tls_config.max_and_min_version.good.json b/config/testdata/tls_config.max_and_min_version.good.json new file mode 100644 index 00000000..8e97cf02 --- /dev/null +++ b/config/testdata/tls_config.max_and_min_version.good.json @@ -0,0 +1,2 @@ +{"max_version": "TLS12", +"min_version": "TLS11"} diff --git a/config/testdata/tls_config.max_and_min_version.good.yml b/config/testdata/tls_config.max_and_min_version.good.yml new file mode 100644 index 00000000..1624dd96 --- /dev/null +++ b/config/testdata/tls_config.max_and_min_version.good.yml @@ -0,0 +1,2 @@ +max_version: TLS12 +min_version: TLS11 \ No newline at end of file diff --git a/config/testdata/tls_config.max_and_min_version_same.good.json b/config/testdata/tls_config.max_and_min_version_same.good.json new file mode 100644 index 00000000..09476657 --- /dev/null +++ b/config/testdata/tls_config.max_and_min_version_same.good.json @@ -0,0 +1,2 @@ +{"max_version": "TLS12", +"min_version": "TLS12"} diff --git a/config/testdata/tls_config.max_and_min_version_same.good.yml b/config/testdata/tls_config.max_and_min_version_same.good.yml new file mode 100644 index 00000000..bc3e4f05 --- /dev/null +++ b/config/testdata/tls_config.max_and_min_version_same.good.yml @@ -0,0 +1,2 @@ +max_version: TLS12 +min_version: TLS12 \ No newline at end of file diff --git a/config/testdata/tls_config.max_version.good.json b/config/testdata/tls_config.max_version.good.json new file mode 100644 index 00000000..d9a3710f --- /dev/null +++ b/config/testdata/tls_config.max_version.good.json @@ -0,0 +1 @@ +{"max_version": "TLS12"} diff --git a/config/testdata/tls_config.max_version.good.yml b/config/testdata/tls_config.max_version.good.yml new file mode 100644 index 00000000..ed38626c --- /dev/null +++ b/config/testdata/tls_config.max_version.good.yml @@ -0,0 +1 @@ +max_version: TLS12 diff --git a/config/tls_config_test.go b/config/tls_config_test.go index 8799d7eb..df3aee2f 100644 --- a/config/tls_config_test.go +++ b/config/tls_config_test.go @@ -20,6 +20,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "testing" "encoding/json" @@ -64,6 +65,9 @@ var expectedTLSConfigs = []struct { }, { filename: "tls_config.tlsversion.good.json", config: &tls.Config{MinVersion: tls.VersionTLS11}, + }, { + filename: "tls_config.max_version.good.json", + config: &tls.Config{MaxVersion: tls.VersionTLS12}, }, { filename: "tls_config.empty.good.yml", @@ -74,6 +78,15 @@ var expectedTLSConfigs = []struct { }, { filename: "tls_config.tlsversion.good.yml", config: &tls.Config{MinVersion: tls.VersionTLS11}, + }, { + filename: "tls_config.max_version.good.yml", + config: &tls.Config{MaxVersion: tls.VersionTLS12}, + }, { + filename: "tls_config.max_and_min_version.good.yml", + config: &tls.Config{MaxVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS11}, + }, { + filename: "tls_config.max_and_min_version_same.good.yml", + config: &tls.Config{MaxVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12}, }, } @@ -91,6 +104,29 @@ func TestValidTLSConfig(t *testing.T) { } } +var invalidTLSConfigs = []struct { + filename string + errMsg string +}{ + { + filename: "tls_config.max_and_min_version.bad.yml", + errMsg: "tls_config.max_version must be greater than or equal to tls_config.min_version if both are specified", + }, +} + +func TestInvalidTLSConfig(t *testing.T) { + for _, ee := range invalidTLSConfigs { + _, err := LoadTLSConfig("testdata/" + ee.filename) + if err == nil { + t.Error("Expected error with config but got none") + continue + } + if !strings.Contains(err.Error(), ee.errMsg) { + t.Errorf("Expected error for invalid HTTP client configuration to contain %q but got: %s", ee.errMsg, err) + } + } +} + func TestStringer(t *testing.T) { if s := (TLSVersion)(tls.VersionTLS13); s.String() != "TLS13" { t.Fatalf("tls.VersionTLS13 string should be TLS13, got %s", s.String())