From 82fad13a56339261dd68f563ddce63bbf4ccb642 Mon Sep 17 00:00:00 2001 From: Gari Singh Date: Mon, 19 Jun 2017 09:22:55 -0400 Subject: [PATCH] [FAB-4856] Only allow TLS 1.2 It is currently possible to establish TLS connections with the fabric-ca-server using TLS versions < 1.2. This change sets the min/max version of TLS for the server endpoint to 1.2. Change-Id: I8035591484da772548c506cc2b4c866a585eff72 Signed-off-by: Gari Singh --- lib/server.go | 2 ++ lib/server_test.go | 44 +++++++++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/lib/server.go b/lib/server.go index f6f398026..461c04872 100644 --- a/lib/server.go +++ b/lib/server.go @@ -449,6 +449,8 @@ func (s *Server) listenAndServe() (err error) { Certificates: []tls.Certificate{*cer}, ClientAuth: clientAuth, ClientCAs: certPool, + MinVersion: tls.VersionTLS12, + MaxVersion: tls.VersionTLS12, } listener, err = tls.Listen("tcp", addr, config) diff --git a/lib/server_test.go b/lib/server_test.go index c53d04457..37bf77bde 100644 --- a/lib/server_test.go +++ b/lib/server_test.go @@ -18,6 +18,8 @@ package lib_test import ( "bytes" + "crypto/tls" + "crypto/x509" "fmt" "io/ioutil" "net/http" @@ -32,7 +34,7 @@ import ( "github.com/hyperledger/fabric-ca/api" . "github.com/hyperledger/fabric-ca/lib" "github.com/hyperledger/fabric-ca/lib/dbutil" - "github.com/hyperledger/fabric-ca/lib/tls" + libtls "github.com/hyperledger/fabric-ca/lib/tls" "github.com/hyperledger/fabric-ca/util" "github.com/hyperledger/fabric/bccsp/factory" "github.com/stretchr/testify/assert" @@ -399,9 +401,9 @@ func TestRunningTLSServer(t *testing.T) { clientConfig := &ClientConfig{ URL: fmt.Sprintf("https://localhost:%d", rootPort), - TLS: tls.ClientTLSConfig{ + TLS: libtls.ClientTLSConfig{ CertFiles: []string{"../testdata/root.pem"}, - Client: tls.KeyCertFiles{ + Client: libtls.KeyCertFiles{ KeyFile: "../testdata/tls_client-key.pem", CertFile: "../testdata/tls_client-cert.pem", }, @@ -415,6 +417,26 @@ func TestRunningTLSServer(t *testing.T) { t.Errorf("Failed to enroll over TLS: %s", err) } + // make sure only TLS 1.2 is supported + rootPool := x509.NewCertPool() + rootBytes, _ := ioutil.ReadFile("../testdata/root.pem") + rootPool.AppendCertsFromPEM(rootBytes) + _, err = tls.Dial("tcp", fmt.Sprintf("localhost:%d", rootPort), &tls.Config{ + RootCAs: rootPool, + MinVersion: tls.VersionTLS12, + MaxVersion: tls.VersionTLS12, + }) + assert.NoError(t, err, "Should have connected using TLS 1.2") + for _, tlsVersion := range []uint16{tls.VersionSSL30, tls.VersionTLS10, tls.VersionTLS11} { + _, err = tls.Dial("tcp", fmt.Sprintf("localhost:%d", rootPort), &tls.Config{ + MinVersion: tlsVersion, + MaxVersion: tlsVersion, + }) + t.Logf("Attempting TLS version [%d]", tlsVersion) + assert.Error(t, err, "Should not have been able to connect with TLS version < 1.2") + assert.Contains(t, err.Error(), "protocol version not supported") + } + err = srv.Stop() if err != nil { t.Errorf("Server stop failed: %s", err) @@ -1015,7 +1037,7 @@ func testNoClientCert(t *testing.T) { clientConfig := &ClientConfig{ URL: fmt.Sprintf("https://localhost:%d", rootPort), - TLS: tls.ClientTLSConfig{ + TLS: libtls.ClientTLSConfig{ CertFiles: []string{"../testdata/root.pem"}, }, } @@ -1074,7 +1096,7 @@ func testClientAuth(t *testing.T) { clientConfig := &ClientConfig{ URL: fmt.Sprintf("https://localhost:%d", rootPort), - TLS: tls.ClientTLSConfig{ + TLS: libtls.ClientTLSConfig{ CertFiles: []string{"../testdata/root.pem"}, }, } @@ -1090,9 +1112,9 @@ func testClientAuth(t *testing.T) { // Client created with certificate and key for TLS clientConfig = &ClientConfig{ URL: fmt.Sprintf("https://localhost:%d", rootPort), - TLS: tls.ClientTLSConfig{ + TLS: libtls.ClientTLSConfig{ CertFiles: []string{"../testdata/root.pem"}, - Client: tls.KeyCertFiles{ + Client: libtls.KeyCertFiles{ KeyFile: "../testdata/tls_client-key.pem", CertFile: "../testdata/tls_client-cert.pem", }, @@ -1201,7 +1223,7 @@ func TestNewUserRegistryMySQL(t *testing.T) { datasource := "" // Test with no cert files specified - tlsConfig := &tls.ClientTLSConfig{ + tlsConfig := &libtls.ClientTLSConfig{ Enabled: true, } csp := util.GetDefaultBCCSP() @@ -1210,7 +1232,7 @@ func TestNewUserRegistryMySQL(t *testing.T) { assert.Contains(t, err.Error(), "No TLS certificate files were provided") // Test with with a file that does not exist - tlsConfig = &tls.ClientTLSConfig{ + tlsConfig = &libtls.ClientTLSConfig{ Enabled: true, CertFiles: []string{"doesnotexit.pem"}, } @@ -1219,7 +1241,7 @@ func TestNewUserRegistryMySQL(t *testing.T) { assert.Contains(t, err.Error(), "no such file or directory") // Test with a file that is not of appropriate format - tlsConfig = &tls.ClientTLSConfig{ + tlsConfig = &libtls.ClientTLSConfig{ Enabled: true, CertFiles: []string{"../testdata/empty.json"}, } @@ -1233,7 +1255,7 @@ func TestNewUserRegistryMySQL(t *testing.T) { fmt.Println(err) } - tlsConfig = &tls.ClientTLSConfig{ + tlsConfig = &libtls.ClientTLSConfig{ Enabled: true, CertFiles: []string{"../testdata/root.pem"}, }