utls/link_test.go
Gaukas Wang 86e9b69fdd
sync: Go 1.21 with QUIC support (#208)
* sync: Go 1.21rc3, QUIC support added (#207)

* sync: merge with upstream tag/go-1.21rc3 (#11)

* fix: all tests pass

* impl: UQUIC Transport

* deps: bump up min Go version

* new: uquic

* fix: add QUICTransportParameter

* deprecated: Go 1.19 no longer supported

Go 1.19 will fail to build or pass the test once we bump up to the new version.

* sync: crypto/tls: restrict RSA keys in certificates to <= 8192 bits (#209)

* [release-branch.go1.21] crypto/tls: restrict RSA keys in certificates to <= 8192 bits

Extremely large RSA keys in certificate chains can cause a client/server
to expend significant CPU time verifying signatures. Limit this by
restricting the size of RSA keys transmitted during handshakes to <=
8192 bits.

Based on a survey of publicly trusted RSA keys, there are currently only
three certificates in circulation with keys larger than this, and all
three appear to be test certificates that are not actively deployed. It
is possible there are larger keys in use in private PKIs, but we target
the web PKI, so causing breakage here in the interests of increasing the
default safety of users of crypto/tls seems reasonable.

Thanks to Mateusz Poliwczak for reporting this issue.

Fixes CVE-2023-29409

* build: [ci skip] boring not included

* fix: typo [ci skip]

* docs: replenish readme [ci skip]

replace old build status badge with new ones, bump up required version noted in docs, update developer contact to reflect current status.
2023-08-03 23:22:53 -06:00

108 lines
2.4 KiB
Go

// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tls
import (
"bytes"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/refraction-networking/utls/testenv"
)
// Tests that the linker is able to remove references to the Client or Server if unused.
func TestLinkerGC(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
t.Parallel()
goBin := testenv.GoToolPath(t)
testenv.MustHaveGoBuild(t)
tests := []struct {
name string
program string
want []string
bad []string
}{
{
name: "empty_import",
program: `package main
import _ "crypto/tls"
func main() {}
`,
bad: []string{
"tls.(*Conn)",
"type:crypto/tls.clientHandshakeState",
"type:crypto/tls.serverHandshakeState",
},
},
{
name: "client_and_server",
program: `package main
import "crypto/tls"
func main() {
tls.Dial("", "", nil)
tls.Server(nil, nil)
}
`,
want: []string{
"crypto/tls.(*Conn).clientHandshake",
"crypto/tls.(*Conn).serverHandshake",
},
},
{
name: "only_client",
program: `package main
import "crypto/tls"
func main() { tls.Dial("", "", nil) }
`,
want: []string{
"crypto/tls.(*Conn).clientHandshake",
},
bad: []string{
"crypto/tls.(*Conn).serverHandshake",
},
},
// TODO: add only_server like func main() { tls.Server(nil, nil) }
// That currently brings in the client via Conn.handleRenegotiation.
}
tmpDir := t.TempDir()
goFile := filepath.Join(tmpDir, "x.go")
exeFile := filepath.Join(tmpDir, "x.exe")
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := os.WriteFile(goFile, []byte(tt.program), 0644); err != nil {
t.Fatal(err)
}
os.Remove(exeFile)
cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go")
cmd.Dir = tmpDir
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("compile: %v, %s", err, out)
}
cmd = exec.Command(goBin, "tool", "nm", "x.exe")
cmd.Dir = tmpDir
nm, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("nm: %v, %s", err, nm)
}
for _, sym := range tt.want {
if !bytes.Contains(nm, []byte(sym)) {
t.Errorf("expected symbol %q not found", sym)
}
}
for _, sym := range tt.bad {
if bytes.Contains(nm, []byte(sym)) {
t.Errorf("unexpected symbol %q found", sym)
}
}
})
}
}