Commit 3f459164 authored by Adam Langley's avatar Adam Langley Committed by Brad Fitzpatrick

crypto/tls: reject SNI values with a trailing dot.

SNI values may not include a trailing dot according to
https://tools.ietf.org/html/rfc6066#section-3. Although crypto/tls
handled this correctly as a client, it didn't reject this as a server.

This change makes sending an SNI value with a trailing dot a fatal
error.

Updates #18114.

Change-Id: Ib7897ab40e98d4a7a4646ff8469a55233621f631
Reviewed-on: https://go-review.googlesource.com/33904
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent e56be943
...@@ -815,7 +815,7 @@ func hostnameInSNI(name string) string { ...@@ -815,7 +815,7 @@ func hostnameInSNI(name string) string {
if net.ParseIP(host) != nil { if net.ParseIP(host) != nil {
return "" return ""
} }
if len(name) > 0 && name[len(name)-1] == '.' { for len(name) > 0 && name[len(name)-1] == '.' {
name = name[:len(name)-1] name = name[:len(name)-1]
} }
return name return name
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package tls package tls
import "bytes" import (
"bytes"
"strings"
)
type clientHelloMsg struct { type clientHelloMsg struct {
raw []byte raw []byte
...@@ -393,6 +396,12 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { ...@@ -393,6 +396,12 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
} }
if nameType == 0 { if nameType == 0 {
m.serverName = string(d[:nameLen]) m.serverName = string(d[:nameLen])
// An SNI value may not include a
// trailing dot. See
// https://tools.ietf.org/html/rfc6066#section-3.
if strings.HasSuffix(m.serverName, ".") {
return false
}
break break
} }
d = d[nameLen:] d = d[nameLen:]
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"bytes" "bytes"
"math/rand" "math/rand"
"reflect" "reflect"
"strings"
"testing" "testing"
"testing/quick" "testing/quick"
) )
...@@ -123,6 +124,9 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { ...@@ -123,6 +124,9 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
} }
if rand.Intn(10) > 5 { if rand.Intn(10) > 5 {
m.serverName = randomString(rand.Intn(255), rand) m.serverName = randomString(rand.Intn(255), rand)
for strings.HasSuffix(m.serverName, ".") {
m.serverName = m.serverName[:len(m.serverName)-1]
}
} }
m.ocspStapling = rand.Intn(10) > 5 m.ocspStapling = rand.Intn(10) > 5
m.supportedPoints = randomBytes(rand.Intn(5)+1, rand) m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
......
...@@ -137,6 +137,10 @@ func TestNoRC4ByDefault(t *testing.T) { ...@@ -137,6 +137,10 @@ func TestNoRC4ByDefault(t *testing.T) {
testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server") testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
} }
func TestRejectSNIWithTrailingDot(t *testing.T) {
testClientHelloFailure(t, testConfig, &clientHelloMsg{vers: VersionTLS12, serverName: "foo.com."}, "unexpected message")
}
func TestDontSelectECDSAWithRSAKey(t *testing.T) { func TestDontSelectECDSAWithRSAKey(t *testing.T) {
// Test that, even when both sides support an ECDSA cipher suite, it // Test that, even when both sides support an ECDSA cipher suite, it
// won't be selected if the server's private key doesn't support it. // won't be selected if the server's private key doesn't support it.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment