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: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
vanhempi
c7f1c5bf4e
commit
59e91483bd
@ -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 @@
|
|||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
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 (
|
|||||||
"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 {
|
|||||||
}
|
}
|
||||||
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) {
|
|||||||
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.
|
||||||
|
Ladataan…
Viittaa uudesa ongelmassa
Block a user