From 87649d32ad16a9a0b7bd5dbd1c124b2032a270f1 Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Wed, 1 Mar 2017 10:43:57 -0800 Subject: [PATCH] crypto/tls: make Config.Clone also clone the GetClientCertificate field Using GetClientCertificate with the http client is currently completely broken because inside the transport we clone the tls.Config and pass it off to the tls.Client. Since tls.Config.Clone() does not pass forward the GetClientCertificate field, GetClientCertificate is ignored in this context. Fixes #19264 Change-Id: Ie214f9f0039ac7c3a2dab8ffd14d30668bdb4c71 Signed-off-by: Mike Danese Reviewed-on: https://go-review.googlesource.com/37541 Reviewed-by: Filippo Valsorda Reviewed-by: Adam Langley Run-TryBot: Adam Langley TryBot-Result: Gobot Gobot --- src/crypto/tls/common.go | 1 + src/crypto/tls/tls_test.go | 90 ++++++++++++++++++++++++++++---------- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go index f0e30dcc5d..6bf9dc193e 100644 --- a/src/crypto/tls/common.go +++ b/src/crypto/tls/common.go @@ -564,6 +564,7 @@ func (c *Config) Clone() *Config { Certificates: c.Certificates, NameToCertificate: c.NameToCertificate, GetCertificate: c.GetCertificate, + GetClientCertificate: c.GetClientCertificate, GetConfigForClient: c.GetConfigForClient, VerifyPeerCertificate: c.VerifyPeerCertificate, RootCAs: c.RootCAs, diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go index 8933f4f201..86812f0c97 100644 --- a/src/crypto/tls/tls_test.go +++ b/src/crypto/tls/tls_test.go @@ -13,13 +13,11 @@ import ( "io" "io/ioutil" "math" - "math/rand" "net" "os" "reflect" "strings" "testing" - "testing/quick" "time" ) @@ -568,11 +566,50 @@ func TestConnCloseWrite(t *testing.T) { } } -func TestClone(t *testing.T) { +func TestCloneFuncFields(t *testing.T) { + const expectedCount = 5 + called := 0 + + c1 := Config{ + Time: func() time.Time { + called |= 1 << 0 + return time.Time{} + }, + GetCertificate: func(*ClientHelloInfo) (*Certificate, error) { + called |= 1 << 1 + return nil, nil + }, + GetClientCertificate: func(*CertificateRequestInfo) (*Certificate, error) { + called |= 1 << 2 + return nil, nil + }, + GetConfigForClient: func(*ClientHelloInfo) (*Config, error) { + called |= 1 << 3 + return nil, nil + }, + VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + called |= 1 << 4 + return nil + }, + } + + c2 := c1.Clone() + + c2.Time() + c2.GetCertificate(nil) + c2.GetClientCertificate(nil) + c2.GetConfigForClient(nil) + c2.VerifyPeerCertificate(nil, nil) + + if called != (1<