From 01889905767f6d8315e27fea539a134620806120 Mon Sep 17 00:00:00 2001 From: Norbert Biczo Date: Wed, 16 Mar 2022 20:03:33 +0100 Subject: [PATCH] fix: set the minimum TLS version in the client to v1.2 (#156) This commit sets the minimum required TLS version by the client to 1.2. --- v5/core/base_service.go | 18 +++++++++++++++++- v5/core/base_service_test.go | 32 ++++++++++++++++++++++++++++++++ v5/core/common_test.go | 3 ++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/v5/core/base_service.go b/v5/core/base_service.go index 264ea70..6894ec4 100644 --- a/v5/core/base_service.go +++ b/v5/core/base_service.go @@ -229,6 +229,7 @@ func (service *BaseService) SetDefaultHeaders(headers http.Header) { // SetHTTPClient updates the client handling the requests. func (service *BaseService) SetHTTPClient(client *http.Client) { + setMinimumTLSVersion(client) service.Client = client } @@ -303,6 +304,18 @@ func getClientTransportForSSL(client *http.Client) *http.Transport { return nil } +// setMinimumTLSVersion sets the minimum TLS version required by the client to TLS v1.2 +func setMinimumTLSVersion(client *http.Client) { + tr := getClientTransportForSSL(client) + if tr != nil { + if tr.TLSClientConfig == nil { + tr.TLSClientConfig = &tls.Config{} // #nosec G402 + } + + tr.TLSClientConfig.MinVersion = tls.VersionTLS12 + } +} + // SetEnableGzipCompression sets the service's EnableGzipCompression field func (service *BaseService) SetEnableGzipCompression(enableGzip bool) { service.Options.EnableGzipCompression = enableGzip @@ -669,7 +682,9 @@ func (service *BaseService) DisableRetries() { // DefaultHTTPClient returns a non-retryable http client with default configuration. func DefaultHTTPClient() *http.Client { - return cleanhttp.DefaultPooledClient() + client := cleanhttp.DefaultPooledClient() + setMinimumTLSVersion(client) + return client } // httpLogger is a shim layer used to allow the Go core's logger to be used with the retryablehttp interfaces. @@ -691,6 +706,7 @@ func NewRetryableHTTPClient() *retryablehttp.Client { client.CheckRetry = IBMCloudSDKRetryPolicy client.Backoff = IBMCloudSDKBackoffPolicy client.ErrorHandler = retryablehttp.PassthroughErrorHandler + setMinimumTLSVersion(client.HTTPClient) return client } diff --git a/v5/core/base_service_test.go b/v5/core/base_service_test.go index 0c035cc..bd3340f 100644 --- a/v5/core/base_service_test.go +++ b/v5/core/base_service_test.go @@ -1,3 +1,4 @@ +//go:build all || fast || basesvc // +build all fast basesvc package core @@ -18,6 +19,7 @@ package core import ( "bytes" + "crypto/tls" "encoding/json" "fmt" "io" @@ -1966,3 +1968,33 @@ func TestErrorMessage(t *testing.T) { `{"errorMessage":{"statusCode":500,"message":"Internal Server Error"}}`, "Internal Server Error") } + +func TestMinSSLVersion(t *testing.T) { + service, err := NewBaseService( + &ServiceOptions{ + Authenticator: &NoAuthAuthenticator{}, + }) + assert.Nil(t, err) + assert.NotNil(t, service) + assert.NotNil(t, service.Client) + + // Check the default config. + minTLS := int(getClientTransportForSSL(service.Client).TLSClientConfig.MinVersion) + assert.Equal(t, minTLS, tls.VersionTLS12) + + // Set a insecureClient with different value. + insecureClient := &http.Client{} + insecureClient.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{ + MinVersion: tls.VersionTLS10, + }, + } + service.SetHTTPClient(insecureClient) + minTLS = int(getClientTransportForSSL(service.Client).TLSClientConfig.MinVersion) + assert.Equal(t, minTLS, tls.VersionTLS12) + + // Check retryable client config. + service.EnableRetries(3, 30*time.Second) + minTLS = int(getClientTransportForSSL(service.Client).TLSClientConfig.MinVersion) + assert.Equal(t, minTLS, tls.VersionTLS12) +} diff --git a/v5/core/common_test.go b/v5/core/common_test.go index bce4fda..407b76f 100644 --- a/v5/core/common_test.go +++ b/v5/core/common_test.go @@ -1,4 +1,5 @@ -// +build all +//go:build all || fast || basesvc +// +build all fast basesvc package core