Skip to content

Commit 4babafd

Browse files
authored
tlscommon: do not match host on server side verification mode 'full' (#242)
1 parent 0e8760f commit 4babafd

File tree

2 files changed

+19
-31
lines changed

2 files changed

+19
-31
lines changed

transport/tlscommon/tls_config.go

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (c *TLSConfig) ToConfig() *tls.Config {
113113
Certificates: c.Certificates,
114114
RootCAs: c.RootCAs,
115115
ClientCAs: c.ClientCAs,
116-
InsecureSkipVerify: insecure, //nolint: gosec // we are using our own verification for now
116+
InsecureSkipVerify: insecure, //nolint:gosec // we are using our own verification for now
117117
CipherSuites: convCipherSuites(c.CipherSuites),
118118
CurvePreferences: c.CurvePreferences,
119119
Renegotiation: c.Renegotiation,
@@ -123,13 +123,13 @@ func (c *TLSConfig) ToConfig() *tls.Config {
123123
}
124124
}
125125

126-
// BuildModuleConfig takes the TLSConfig and transform it into a `tls.Config`.
126+
// BuildModuleClientConfig takes the TLSConfig and transform it into a `tls.Config`.
127127
func (c *TLSConfig) BuildModuleClientConfig(host string) *tls.Config {
128128
if c == nil {
129129
// use default TLS settings, if config is empty.
130130
return &tls.Config{
131131
ServerName: host,
132-
InsecureSkipVerify: true, //nolint: gosec // we are using our own verification for now
132+
InsecureSkipVerify: true, //nolint:gosec // we are using our own verification for now
133133
VerifyConnection: makeVerifyConnection(&TLSConfig{
134134
Verification: VerifyFull,
135135
ServerName: host,
@@ -154,15 +154,16 @@ func (c *TLSConfig) BuildModuleClientConfig(host string) *tls.Config {
154154
return config
155155
}
156156

157-
// BuildServerConfig takes the TLSConfig and transform it into a `tls.Config` for server side objects.
157+
// BuildServerConfig takes the TLSConfig and transform it into a `tls.Config`
158+
// for server side connections.
158159
func (c *TLSConfig) BuildServerConfig(host string) *tls.Config {
159160
if c == nil {
160161
// use default TLS settings, if config is empty.
161162
return &tls.Config{
162163
ServerName: host,
163-
InsecureSkipVerify: true, //nolint: gosec // we are using our own verification for now
164+
InsecureSkipVerify: true, //nolint:gosec // we are using our own verification for now
164165
VerifyConnection: makeVerifyServerConnection(&TLSConfig{
165-
Verification: VerifyFull,
166+
Verification: VerifyCertificate,
166167
ServerName: host,
167168
}),
168169
}
@@ -285,27 +286,13 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error {
285286

286287
func makeVerifyServerConnection(cfg *TLSConfig) func(tls.ConnectionState) error {
287288
switch cfg.Verification {
288-
case VerifyFull:
289-
return func(cs tls.ConnectionState) error {
290-
if len(cs.PeerCertificates) == 0 {
291-
if cfg.ClientAuth == tls.RequireAndVerifyClientCert {
292-
return ErrMissingPeerCertificate
293-
}
294-
return nil
295-
}
296289

297-
opts := x509.VerifyOptions{
298-
Roots: cfg.ClientCAs,
299-
Intermediates: x509.NewCertPool(),
300-
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
301-
}
302-
err := verifyCertsWithOpts(cs.PeerCertificates, cfg.CASha256, opts)
303-
if err != nil {
304-
return err
305-
}
306-
return verifyHostname(cs.PeerCertificates[0], cs.ServerName)
307-
}
308-
case VerifyCertificate:
290+
// VerifyFull would attempt to match 'host' (c.ServerName) that is the host
291+
// the client is trying to connect to with a DNS, IP or the CN from the
292+
// client's certificate. Such validation, besides making no sense on the
293+
// server side also causes errors as the client certificate usually does not
294+
// contain a DNS, IP or CN matching the server's hostname.
295+
case VerifyFull, VerifyCertificate:
309296
return func(cs tls.ConnectionState) error {
310297
if len(cs.PeerCertificates) == 0 {
311298
if cfg.ClientAuth == tls.RequireAndVerifyClientCert {
@@ -331,7 +318,6 @@ func makeVerifyServerConnection(cfg *TLSConfig) func(tls.ConnectionState) error
331318
}
332319

333320
return nil
334-
335321
}
336322

337323
func verifyCertsWithOpts(certs []*x509.Certificate, casha256 []string, opts x509.VerifyOptions) error {

transport/tlscommon/tls_config_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ func TestMakeVerifyServerConnection(t *testing.T) {
7171
expectedCallback: true,
7272
expectedError: x509.CertificateInvalidError{Cert: testCerts["expired"], Reason: x509.Expired},
7373
},
74-
"default verification with certificates when required with incorrect server name in cert": {
74+
"default verification with certificates when required do not verify hostname": {
7575
verificationMode: VerifyFull,
7676
clientAuth: tls.RequireAndVerifyClientCert,
7777
certAuthorities: certPool,
7878
peerCerts: []*x509.Certificate{testCerts["correct"]},
79-
serverName: "bad.example.com",
79+
serverName: "some.example.com",
8080
expectedCallback: true,
81-
expectedError: x509.HostnameError{Certificate: testCerts["correct"], Host: "bad.example.com"},
81+
expectedError: nil,
8282
},
8383
"default verification with certificates when required with correct cert": {
8484
verificationMode: VerifyFull,
@@ -257,6 +257,7 @@ func TestTrustRootCA(t *testing.T) {
257257

258258
// we want to know the number of certificates in the CertPool (RootCAs), as it is not
259259
// directly available, we use this workaround of reading the number of subjects in the pool.
260+
//nolint:staticcheck // we do not expect the system root CAs.
260261
if got, expected := len(cfg.RootCAs.Subjects()), tc.expectedRootCAsLen; got != expected {
261262
t.Fatalf("expecting cfg.RootCAs to have %d element, got %d instead", expected, got)
262263
}
@@ -763,10 +764,11 @@ func genTestCerts(t *testing.T) map[string]*x509.Certificate {
763764
// We write the certificate to disk, so if the test fails the certs can
764765
// be inspected/reused
765766
certPEM := new(bytes.Buffer)
766-
pem.Encode(certPEM, &pem.Block{
767+
err = pem.Encode(certPEM, &pem.Block{
767768
Type: "CERTIFICATE",
768769
Bytes: cert.Leaf.Raw,
769770
})
771+
require.NoErrorf(t, err, "failed to encode certificste to PEM")
770772

771773
serverCertFile, err := os.Create(filepath.Join(tmpDir, certName+".crt"))
772774
if err != nil {

0 commit comments

Comments
 (0)