Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/tls: add SkipSNI option #28851

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/crypto/tls/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,9 @@ type Config struct {
// an IP address.
ServerName string

// SkipSNI is used to disable client send the SNI extension.
SkipSNI bool

// ClientAuth determines the server's policy for
// TLS Client Authentication. The default is NoClientCert.
ClientAuth ClientAuthType
Expand Down Expand Up @@ -644,6 +647,7 @@ func (c *Config) Clone() *Config {
RootCAs: c.RootCAs,
NextProtos: c.NextProtos,
ServerName: c.ServerName,
SkipSNI: c.SkipSNI,
ClientAuth: c.ClientAuth,
ClientCAs: c.ClientCAs,
InsecureSkipVerify: c.InsecureSkipVerify,
Expand Down
5 changes: 4 additions & 1 deletion src/crypto/tls/handshake_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
sessionId: make([]byte, 32),
ocspStapling: true,
scts: true,
serverName: hostnameInSNI(config.ServerName),
supportedCurves: config.curvePreferences(),
supportedPoints: []uint8{pointFormatUncompressed},
nextProtoNeg: len(config.NextProtos) > 0,
Expand All @@ -78,6 +77,10 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
supportedVersions: supportedVersions,
}

if !config.SkipSNI {
hello.serverName = hostnameInSNI(config.ServerName)
}

if c.handshakes > 0 {
hello.secureRenegotiation = c.clientFinished[:]
}
Expand Down
32 changes: 32 additions & 0 deletions src/crypto/tls/handshake_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,38 @@ func TestHostnameInSNI(t *testing.T) {
}
}

func TestSkipSNI(t *testing.T) {
c, s := localPipe(t)

host := "golang.org"

go func(host string) {
Client(c, &Config{ServerName: host, InsecureSkipVerify: true, SkipSNI: true}).Handshake()
}(host)

var header [5]byte
if _, err := io.ReadFull(s, header[:]); err != nil {
t.Fatal(err)
}
recordLen := int(header[3])<<8 | int(header[4])

record := make([]byte, recordLen)
if _, err := io.ReadFull(s, record[:]); err != nil {
t.Fatal(err)
}

c.Close()
s.Close()

var m clientHelloMsg
if !m.unmarshal(record) {
t.Errorf("unmarshaling ClientHello for %q failed", host)
}
if m.serverName != "" {
t.Errorf("expected empty serverName not found in ClientHello: %x", record)
}
}

func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) {
// This checks that the server can't select a cipher suite that the
// client didn't offer. See #13174.
Expand Down
2 changes: 2 additions & 0 deletions src/crypto/tls/tls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,8 @@ func TestCloneNonFuncFields(t *testing.T) {
f.Set(reflect.ValueOf([]string{"a", "b"}))
case "ServerName":
f.Set(reflect.ValueOf("b"))
case "SkipSNI":
f.Set(reflect.ValueOf(true))
case "ClientAuth":
f.Set(reflect.ValueOf(VerifyClientCertIfGiven))
case "InsecureSkipVerify", "SessionTicketsDisabled", "DynamicRecordSizingDisabled", "PreferServerCipherSuites":
Expand Down