Skip to content

Commit

Permalink
Merge pull request refraction-networking#100 from max-b/maxb/sni-fixes
Browse files Browse the repository at this point in the history
Fix invalid SNI handling which could be fingerprinted
  • Loading branch information
gaukas authored Apr 28, 2022
2 parents c498a9e + 5c64f88 commit 423efbb
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
33 changes: 33 additions & 0 deletions u_conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ func TestUTLSRemoveSNIExtension(t *testing.T) {
runUTLSClientTestForVersion(t, test, "TLSv12-", "-tls1_2", hello, true)
}

func TestUTLSServerNameIP(t *testing.T) {
hello := &helloID{HelloChrome_70}

config := getUTLSTestConfig()
config.ServerName = "1.1.1.1"

opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
test := &clientTest{
name: "UTLS-" + opensslCipherName + "-" + hello.helloName() + "-ServerNameIP",
args: []string{"-cipher", opensslCipherName},
config: config,
}

runUTLSClientTestForVersion(t, test, "TLSv12-", "-tls1_2", hello, true)
}

func TestUTLSEmptyServerName(t *testing.T) {
hello := &helloID{HelloChrome_70}

config := getUTLSTestConfig()
config.ServerName = ""

opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
test := &clientTest{
name: "UTLS-" + opensslCipherName + "-" + hello.helloName() + "-EmptyServerName",
args: []string{"-cipher", opensslCipherName},
config: config,
}

runUTLSClientTestForVersion(t, test, "TLSv12-", "-tls1_2", hello, true)
}

/*
*
HELPER FUNCTIONS BELOW
Expand All @@ -212,6 +244,7 @@ func getUTLSTestConfig() *Config {
MinVersion: VersionSSL30,
MaxVersion: VersionTLS13,
CipherSuites: allCipherSuites(),
ServerName: "foobar.com",
}
return testUTLSConfig
}
Expand Down
32 changes: 23 additions & 9 deletions u_tls_extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,29 +49,43 @@ type SNIExtension struct {

func (e *SNIExtension) writeToUConn(uc *UConn) error {
uc.config.ServerName = e.ServerName
uc.HandshakeState.Hello.ServerName = e.ServerName
hostName := hostnameInSNI(e.ServerName)
uc.HandshakeState.Hello.ServerName = hostName

return nil
}

func (e *SNIExtension) Len() int {
return 4 + 2 + 1 + 2 + len(e.ServerName)
// Literal IP addresses, absolute FQDNs, and empty strings are not permitted as SNI values.
// See RFC 6066, Section 3.
hostName := hostnameInSNI(e.ServerName)
if len(hostName) == 0 {
return 0
}
return 4 + 2 + 1 + 2 + len(hostName)
}

func (e *SNIExtension) Read(b []byte) (int, error) {
// Literal IP addresses, absolute FQDNs, and empty strings are not permitted as SNI values.
// See RFC 6066, Section 3.
hostName := hostnameInSNI(e.ServerName)
if len(hostName) == 0 {
return 0, io.EOF
}
if len(b) < e.Len() {
return 0, io.ErrShortBuffer
}
// RFC 3546, section 3.1
b[0] = byte(extensionServerName >> 8)
b[1] = byte(extensionServerName)
b[2] = byte((len(e.ServerName) + 5) >> 8)
b[3] = byte((len(e.ServerName) + 5))
b[4] = byte((len(e.ServerName) + 3) >> 8)
b[5] = byte(len(e.ServerName) + 3)
b[2] = byte((len(hostName) + 5) >> 8)
b[3] = byte((len(hostName) + 5))
b[4] = byte((len(hostName) + 3) >> 8)
b[5] = byte(len(hostName) + 3)
// b[6] Server Name Type: host_name (0)
b[7] = byte(len(e.ServerName) >> 8)
b[8] = byte(len(e.ServerName))
copy(b[9:], []byte(e.ServerName))
b[7] = byte(len(hostName) >> 8)
b[8] = byte(len(hostName))
copy(b[9:], []byte(hostName))
return e.Len(), io.EOF
}

Expand Down

0 comments on commit 423efbb

Please sign in to comment.