Skip to content

Commit

Permalink
crypto/tls: enable TLS 1.3 and update tests
Browse files Browse the repository at this point in the history
To disable TLS 1.3, simply remove VersionTLS13 from supportedVersions,
as tested by TestEscapeRoute, and amend documentation. To make it
opt-in, revert the change to (*Config).supportedVersions from this CL.

I did not have the heart to implement the early data skipping feature
when I realized that it did not offer a choice between two
abstraction-breaking options, but demanded them both (look for handshake
type in case of HelloRetryRequest, trial decryption otherwise). It's a
lot of complexity for an apparently small gain, but if anyone has strong
opinions about it let me know.

Note that in TLS 1.3 alerts are encrypted, so the close_notify peeking
to return (n > 0, io.EOF) from Read doesn't work. If we are lucky, those
servers that unexpectedly close connections after serving a single
request will have stopped (maybe thanks to H/2) before they got updated
to TLS 1.3.

Relatedly, session tickets are now provisioned on the client first Read
instead of at Handshake time, because they are, well, post-handshake
messages. If this proves to be a problem we might try to peek at them.

Doubled the tests that cover logic that's different in TLS 1.3.

The benchmarks for TLS 1.2 compared to be0f3c2 (before TLS 1.3 and
its refactors, after CL 142817 changed them to use real connections)
show little movement.

name                                       old time/op   new time/op   delta
HandshakeServer/RSA-8                        795µs ± 1%    798µs ± 1%    ~     (p=0.057 n=10+18)
HandshakeServer/ECDHE-P256-RSA-8             903µs ± 0%    909µs ± 1%  +0.68%  (p=0.000 n=8+17)
HandshakeServer/ECDHE-P256-ECDSA-P256-8      198µs ± 0%    204µs ± 1%  +3.24%  (p=0.000 n=9+18)
HandshakeServer/ECDHE-X25519-ECDSA-P256-8    202µs ± 3%    208µs ± 1%  +2.98%  (p=0.000 n=9+20)
HandshakeServer/ECDHE-P521-ECDSA-P521-8     15.5ms ± 1%   15.9ms ± 2%  +2.49%  (p=0.000 n=10+20)
Throughput/MaxPacket/1MB-8                  5.81ms ±23%   6.14ms ±44%    ~     (p=0.605 n=8+18)
Throughput/MaxPacket/2MB-8                  8.91ms ±22%   8.74ms ±33%    ~     (p=0.498 n=9+19)
Throughput/MaxPacket/4MB-8                  12.8ms ± 3%   14.0ms ±10%  +9.74%  (p=0.000 n=10+17)
Throughput/MaxPacket/8MB-8                  25.1ms ± 7%   24.6ms ±16%    ~     (p=0.129 n=9+19)
Throughput/MaxPacket/16MB-8                 46.3ms ± 4%   45.9ms ±12%    ~     (p=0.340 n=9+20)
Throughput/MaxPacket/32MB-8                 88.5ms ± 4%   86.0ms ± 4%  -2.82%  (p=0.004 n=10+20)
Throughput/MaxPacket/64MB-8                  173ms ± 2%    167ms ± 7%  -3.42%  (p=0.001 n=10+19)
Throughput/DynamicPacket/1MB-8              5.88ms ± 4%   6.59ms ±64%    ~     (p=0.232 n=9+18)
Throughput/DynamicPacket/2MB-8              9.08ms ±12%   8.73ms ±21%    ~     (p=0.408 n=10+18)
Throughput/DynamicPacket/4MB-8              14.2ms ± 5%   14.0ms ±11%    ~     (p=0.188 n=9+19)
Throughput/DynamicPacket/8MB-8              25.1ms ± 6%   24.0ms ± 7%  -4.39%  (p=0.000 n=10+18)
Throughput/DynamicPacket/16MB-8             45.6ms ± 3%   43.3ms ± 1%  -5.22%  (p=0.000 n=10+8)
Throughput/DynamicPacket/32MB-8             88.4ms ± 3%   84.8ms ± 2%  -4.06%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8              175ms ± 3%    167ms ± 2%  -4.63%  (p=0.000 n=10+10)
Latency/MaxPacket/200kbps-8                  694ms ± 0%    694ms ± 0%  -0.02%  (p=0.000 n=9+9)
Latency/MaxPacket/500kbps-8                  279ms ± 0%    279ms ± 0%  -0.09%  (p=0.000 n=10+10)
Latency/MaxPacket/1000kbps-8                 140ms ± 0%    140ms ± 0%  -0.15%  (p=0.000 n=10+9)
Latency/MaxPacket/2000kbps-8                71.1ms ± 0%   71.0ms ± 0%  -0.09%  (p=0.001 n=8+9)
Latency/MaxPacket/5000kbps-8                30.5ms ± 6%   30.1ms ± 6%    ~     (p=0.905 n=10+9)
Latency/DynamicPacket/200kbps-8              134ms ± 0%    134ms ± 0%    ~     (p=0.796 n=9+9)
Latency/DynamicPacket/500kbps-8             54.8ms ± 0%   54.7ms ± 0%  -0.18%  (p=0.000 n=8+10)
Latency/DynamicPacket/1000kbps-8            28.5ms ± 0%   29.1ms ± 8%    ~     (p=0.173 n=8+10)
Latency/DynamicPacket/2000kbps-8            15.3ms ± 6%   15.9ms ±10%    ~     (p=0.905 n=9+10)
Latency/DynamicPacket/5000kbps-8            9.14ms ±21%   9.65ms ±82%    ~     (p=0.529 n=10+10)

name                                       old speed     new speed     delta
Throughput/MaxPacket/1MB-8                 175MB/s ±13%  167MB/s ±64%    ~     (p=0.646 n=7+20)
Throughput/MaxPacket/2MB-8                 241MB/s ±25%  241MB/s ±40%    ~     (p=0.660 n=9+20)
Throughput/MaxPacket/4MB-8                 328MB/s ± 3%  300MB/s ± 9%  -8.70%  (p=0.000 n=10+17)
Throughput/MaxPacket/8MB-8                 335MB/s ± 7%  340MB/s ±17%    ~     (p=0.212 n=9+20)
Throughput/MaxPacket/16MB-8                363MB/s ± 4%  367MB/s ±11%    ~     (p=0.340 n=9+20)
Throughput/MaxPacket/32MB-8                379MB/s ± 4%  390MB/s ± 4%  +2.93%  (p=0.004 n=10+20)
Throughput/MaxPacket/64MB-8                388MB/s ± 2%  401MB/s ± 7%  +3.25%  (p=0.004 n=10+20)
Throughput/DynamicPacket/1MB-8             178MB/s ± 4%  157MB/s ±73%    ~     (p=0.127 n=9+20)
Throughput/DynamicPacket/2MB-8             232MB/s ±11%  243MB/s ±18%    ~     (p=0.415 n=10+18)
Throughput/DynamicPacket/4MB-8             296MB/s ± 5%  299MB/s ±15%    ~     (p=0.295 n=9+20)
Throughput/DynamicPacket/8MB-8             334MB/s ± 6%  350MB/s ± 7%  +4.58%  (p=0.000 n=10+18)
Throughput/DynamicPacket/16MB-8            368MB/s ± 3%  388MB/s ± 1%  +5.48%  (p=0.000 n=10+8)
Throughput/DynamicPacket/32MB-8            380MB/s ± 3%  396MB/s ± 2%  +4.20%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8            384MB/s ± 3%  403MB/s ± 2%  +4.83%  (p=0.000 n=10+10)

Comparing TLS 1.2 and TLS 1.3 at tip shows a slight (~5-10%) slowdown of
handshakes, which might be worth looking at next cycle, but the latency
improvements are expected to overshadow that.

name                                       old time/op   new time/op   delta
HandshakeServer/ECDHE-P256-RSA-8             909µs ± 1%    963µs ± 0%   +5.87%  (p=0.000 n=17+18)
HandshakeServer/ECDHE-P256-ECDSA-P256-8      204µs ± 1%    225µs ± 2%  +10.20%  (p=0.000 n=18+20)
HandshakeServer/ECDHE-X25519-ECDSA-P256-8    208µs ± 1%    230µs ± 2%  +10.35%  (p=0.000 n=20+18)
HandshakeServer/ECDHE-P521-ECDSA-P521-8     15.9ms ± 2%   15.9ms ± 1%     ~     (p=0.444 n=20+19)
Throughput/MaxPacket/1MB-8                  6.14ms ±44%   7.07ms ±46%     ~     (p=0.057 n=18+19)
Throughput/MaxPacket/2MB-8                  8.74ms ±33%   8.61ms ± 9%     ~     (p=0.552 n=19+17)
Throughput/MaxPacket/4MB-8                  14.0ms ±10%   14.1ms ±12%     ~     (p=0.707 n=17+20)
Throughput/MaxPacket/8MB-8                  24.6ms ±16%   25.6ms ±14%     ~     (p=0.107 n=19+20)
Throughput/MaxPacket/16MB-8                 45.9ms ±12%   44.7ms ± 6%     ~     (p=0.607 n=20+19)
Throughput/MaxPacket/32MB-8                 86.0ms ± 4%   87.9ms ± 8%     ~     (p=0.113 n=20+19)
Throughput/MaxPacket/64MB-8                  167ms ± 7%    169ms ± 2%   +1.26%  (p=0.011 n=19+19)
Throughput/DynamicPacket/1MB-8              6.59ms ±64%   6.79ms ±43%     ~     (p=0.480 n=18+19)
Throughput/DynamicPacket/2MB-8              8.73ms ±21%   9.58ms ±13%   +9.71%  (p=0.006 n=18+20)
Throughput/DynamicPacket/4MB-8              14.0ms ±11%   13.9ms ±10%     ~     (p=0.687 n=19+20)
Throughput/DynamicPacket/8MB-8              24.0ms ± 7%   24.6ms ± 8%   +2.36%  (p=0.045 n=18+17)
Throughput/DynamicPacket/16MB-8             43.3ms ± 1%   44.3ms ± 2%   +2.48%  (p=0.001 n=8+9)
Throughput/DynamicPacket/32MB-8             84.8ms ± 2%   86.7ms ± 2%   +2.27%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8              167ms ± 2%    170ms ± 3%   +1.89%  (p=0.005 n=10+10)
Latency/MaxPacket/200kbps-8                  694ms ± 0%    699ms ± 0%   +0.65%  (p=0.000 n=9+10)
Latency/MaxPacket/500kbps-8                  279ms ± 0%    280ms ± 0%   +0.68%  (p=0.000 n=10+10)
Latency/MaxPacket/1000kbps-8                 140ms ± 0%    141ms ± 0%   +0.59%  (p=0.000 n=9+9)
Latency/MaxPacket/2000kbps-8                71.0ms ± 0%   71.3ms ± 0%   +0.42%  (p=0.000 n=9+9)
Latency/MaxPacket/5000kbps-8                30.1ms ± 6%   30.7ms ±10%   +1.93%  (p=0.019 n=9+9)
Latency/DynamicPacket/200kbps-8              134ms ± 0%    138ms ± 0%   +3.22%  (p=0.000 n=9+10)
Latency/DynamicPacket/500kbps-8             54.7ms ± 0%   56.3ms ± 0%   +3.03%  (p=0.000 n=10+8)
Latency/DynamicPacket/1000kbps-8            29.1ms ± 8%   29.1ms ± 0%     ~     (p=0.173 n=10+8)
Latency/DynamicPacket/2000kbps-8            15.9ms ±10%   16.4ms ±36%     ~     (p=0.633 n=10+8)
Latency/DynamicPacket/5000kbps-8            9.65ms ±82%   8.32ms ± 8%     ~     (p=0.573 n=10+8)

name                                       old speed     new speed     delta
Throughput/MaxPacket/1MB-8                 167MB/s ±64%  155MB/s ±55%     ~     (p=0.224 n=20+19)
Throughput/MaxPacket/2MB-8                 241MB/s ±40%  244MB/s ± 9%     ~     (p=0.407 n=20+17)
Throughput/MaxPacket/4MB-8                 300MB/s ± 9%  298MB/s ±11%     ~     (p=0.707 n=17+20)
Throughput/MaxPacket/8MB-8                 340MB/s ±17%  330MB/s ±13%     ~     (p=0.201 n=20+20)
Throughput/MaxPacket/16MB-8                367MB/s ±11%  375MB/s ± 5%     ~     (p=0.607 n=20+19)
Throughput/MaxPacket/32MB-8                390MB/s ± 4%  382MB/s ± 8%     ~     (p=0.113 n=20+19)
Throughput/MaxPacket/64MB-8                401MB/s ± 7%  397MB/s ± 2%   -0.96%  (p=0.030 n=20+19)
Throughput/DynamicPacket/1MB-8             157MB/s ±73%  156MB/s ±39%     ~     (p=0.738 n=20+20)
Throughput/DynamicPacket/2MB-8             243MB/s ±18%  220MB/s ±14%   -9.65%  (p=0.006 n=18+20)
Throughput/DynamicPacket/4MB-8             299MB/s ±15%  303MB/s ± 9%     ~     (p=0.512 n=20+20)
Throughput/DynamicPacket/8MB-8             350MB/s ± 7%  342MB/s ± 8%   -2.27%  (p=0.045 n=18+17)
Throughput/DynamicPacket/16MB-8            388MB/s ± 1%  378MB/s ± 2%   -2.41%  (p=0.001 n=8+9)
Throughput/DynamicPacket/32MB-8            396MB/s ± 2%  387MB/s ± 2%   -2.21%  (p=0.000 n=10+10)
Throughput/DynamicPacket/64MB-8            403MB/s ± 2%  396MB/s ± 3%   -1.84%  (p=0.005 n=10+10)

Fixes #9671

Change-Id: Ieb57c5140eb2c083b8be0d42b240cd2eeec0dcf6
Reviewed-on: https://go-review.googlesource.com/c/147638
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
  • Loading branch information
FiloSottile committed Nov 12, 2018
1 parent 039c208 commit 30cc978
Show file tree
Hide file tree
Showing 84 changed files with 3,734 additions and 3,281 deletions.
9 changes: 1 addition & 8 deletions src/crypto/tls/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ const (
VersionTLS10 = 0x0301
VersionTLS11 = 0x0302
VersionTLS12 = 0x0303

// VersionTLS13 is under development in this library and can't be selected
// nor negotiated yet on either side.
VersionTLS13 = 0x0304
)

Expand Down Expand Up @@ -557,7 +554,7 @@ type Config struct {

// MaxVersion contains the maximum SSL/TLS version that is acceptable.
// If zero, then the maximum version supported by this package is used,
// which is currently TLS 1.2.
// which is currently TLS 1.3.
MaxVersion uint16

// CurvePreferences contains the elliptic curves that will be used in
Expand Down Expand Up @@ -773,10 +770,6 @@ func (c *Config) supportedVersions(isClient bool) []uint16 {
if isClient && v < VersionTLS10 {
continue
}
// TLS 1.3 is only supported if explicitly requested while in development.
if v == VersionTLS13 && (c == nil || c.MaxVersion != VersionTLS13) {
continue
}
versions = append(versions, v)
}
return versions
Expand Down
19 changes: 12 additions & 7 deletions src/crypto/tls/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,7 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) {
return
}

// The last record will be a close_notify alert, which
// we don't wish to record.
if recordType(recordHeader[0]) == recordTypeApplicationData {
recordSizes = append(recordSizes, recordHeaderLen+length)
}
recordSizes = append(recordSizes, recordHeaderLen+length)
}

recordSizesChan <- recordSizes
Expand Down Expand Up @@ -215,8 +211,9 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) {
t.Fatalf("Client encountered an error")
}

// Drop the size of last record, which is likely to be truncated.
recordSizes = recordSizes[:len(recordSizes)-1]
// Drop the size of the second to last record, which is likely to be
// truncated, and the last record, which is a close_notify alert.
recordSizes = recordSizes[:len(recordSizes)-2]

// recordSizes should contain a series of records smaller than
// tcpMSSEstimate followed by some larger than maxPlaintext.
Expand All @@ -241,22 +238,30 @@ func runDynamicRecordSizingTest(t *testing.T, config *Config) {

func TestDynamicRecordSizingWithStreamCipher(t *testing.T) {
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
runDynamicRecordSizingTest(t, config)
}

func TestDynamicRecordSizingWithCBC(t *testing.T) {
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA}
runDynamicRecordSizingTest(t, config)
}

func TestDynamicRecordSizingWithAEAD(t *testing.T) {
config := testConfig.Clone()
config.MaxVersion = VersionTLS12
config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
runDynamicRecordSizingTest(t, config)
}

func TestDynamicRecordSizingWithTLSv13(t *testing.T) {
config := testConfig.Clone()
runDynamicRecordSizingTest(t, config)
}

// hairpinConn is a net.Conn that makes a “hairpin” call when closed, back into
// the tls.Conn which is calling it.
type hairpinConn struct {
Expand Down
3 changes: 0 additions & 3 deletions src/crypto/tls/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ func ExampleConfig_keyLogWriter() {
// The resulting file can be used with Wireshark to decrypt the TLS
// connection by setting (Pre)-Master-Secret log filename in SSL Protocol
// preferences.

// Output:
// CLIENT_RANDOM 0000000000000000000000000000000000000000000000000000000000000000 baca0df460a688e44ce018b025183cc2353ae01f89755ef766eedd3ecc302888ee3b3a22962e45f48c20df15a98c0e80
}

func ExampleLoadX509KeyPair() {
Expand Down
52 changes: 26 additions & 26 deletions src/crypto/tls/handshake_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,6 @@ func (test *clientTest) loadData() (flows [][]byte, err error) {
func (test *clientTest) run(t *testing.T, write bool) {
checkOpenSSLVersion(t)

// TODO(filippo): regenerate client tests all at once after CL 146217,
// RSA-PSS and client-side TLS 1.3 are landed.
if !write && !strings.Contains(test.name, "TLSv13") {
t.Skip("recorded server tests are out of date")
}

var clientConn, serverConn net.Conn
var recordingConn *recordingConn
var childProcess *exec.Cmd
Expand Down Expand Up @@ -456,7 +450,7 @@ func (test *clientTest) run(t *testing.T, write bool) {

// If the server sent us an alert after our last flight, give it a
// chance to arrive.
if write {
if write && test.renegotiationExpectedToFail == 0 {
client.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
if _, err := client.Read(make([]byte, 1)); err != nil {
if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() {
Expand Down Expand Up @@ -550,12 +544,6 @@ func runClientTestTLS12(t *testing.T, template *clientTest) {
}

func runClientTestTLS13(t *testing.T, template *clientTest) {
// TODO(filippo): set MaxVersion to VersionTLS13 instead in testConfig
// while regenerating client tests.
if template.config == nil {
template.config = testConfig.Clone()
}
template.config.MaxVersion = VersionTLS13
runClientTestForVersion(t, template, "TLSv13", "-tls1_3")
}

Expand Down Expand Up @@ -1058,14 +1046,16 @@ func TestLRUClientSessionCache(t *testing.T) {
}
}

func TestKeyLog(t *testing.T) {
func TestKeyLogTLS12(t *testing.T) {
var serverBuf, clientBuf bytes.Buffer

clientConfig := testConfig.Clone()
clientConfig.KeyLogWriter = &clientBuf
clientConfig.MaxVersion = VersionTLS12

serverConfig := testConfig.Clone()
serverConfig.KeyLogWriter = &serverBuf
serverConfig.MaxVersion = VersionTLS12

c, s := localPipe(t)
done := make(chan bool)
Expand Down Expand Up @@ -1114,11 +1104,9 @@ func TestKeyLogTLS13(t *testing.T) {

clientConfig := testConfig.Clone()
clientConfig.KeyLogWriter = &clientBuf
clientConfig.MaxVersion = VersionTLS13

serverConfig := testConfig.Clone()
serverConfig.KeyLogWriter = &serverBuf
serverConfig.MaxVersion = VersionTLS13

c, s := localPipe(t)
done := make(chan bool)
Expand Down Expand Up @@ -1640,14 +1628,21 @@ func (wcc *writeCountingConn) Write(data []byte) (int, error) {
}

func TestBuffering(t *testing.T) {
t.Run("TLSv12", func(t *testing.T) { testBuffering(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testBuffering(t, VersionTLS13) })
}

func testBuffering(t *testing.T, version uint16) {
c, s := localPipe(t)
done := make(chan bool)

clientWCC := &writeCountingConn{Conn: c}
serverWCC := &writeCountingConn{Conn: s}

go func() {
Server(serverWCC, testConfig).Handshake()
config := testConfig.Clone()
config.MaxVersion = version
Server(serverWCC, config).Handshake()
serverWCC.Close()
done <- true
}()
Expand All @@ -1659,12 +1654,21 @@ func TestBuffering(t *testing.T) {
clientWCC.Close()
<-done

if n := clientWCC.numWrites; n != 2 {
t.Errorf("expected client handshake to complete with only two writes, but saw %d", n)
var expectedClient, expectedServer int
if version == VersionTLS13 {
expectedClient = 2
expectedServer = 1
} else {
expectedClient = 2
expectedServer = 2
}

if n := clientWCC.numWrites; n != expectedClient {
t.Errorf("expected client handshake to complete with %d writes, but saw %d", expectedClient, n)
}

if n := serverWCC.numWrites; n != 2 {
t.Errorf("expected server handshake to complete with only two writes, but saw %d", n)
if n := serverWCC.numWrites; n != expectedServer {
t.Errorf("expected server handshake to complete with %d writes, but saw %d", expectedServer, n)
}
}

Expand Down Expand Up @@ -1696,17 +1700,13 @@ func TestAlertFlushing(t *testing.T) {
t.Fatal("client unexpectedly returned no error")
}

const expectedError = "remote error: tls: handshake failure"
const expectedError = "remote error: tls: internal error"
if e := err.Error(); !strings.Contains(e, expectedError) {
t.Fatalf("expected to find %q in error but error was %q", expectedError, e)
}
clientWCC.Close()
<-done

if n := clientWCC.numWrites; n != 1 {
t.Errorf("expected client handshake to complete with one write, but saw %d", n)
}

if n := serverWCC.numWrites; n != 1 {
t.Errorf("expected server handshake to complete with one write, but saw %d", n)
}
Expand Down
73 changes: 50 additions & 23 deletions src/crypto/tls/handshake_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func init() {
Certificates: make([]Certificate, 2),
InsecureSkipVerify: true,
MinVersion: VersionSSL30,
MaxVersion: VersionTLS12,
MaxVersion: VersionTLS13,
CipherSuites: allCipherSuites(),
}
testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
Expand Down Expand Up @@ -434,13 +434,19 @@ func TestCipherSuitePreference(t *testing.T) {
}

func TestSCTHandshake(t *testing.T) {
t.Run("TLSv12", func(t *testing.T) { testSCTHandshake(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testSCTHandshake(t, VersionTLS13) })
}

func testSCTHandshake(t *testing.T, version uint16) {
expected := [][]byte{[]byte("certificate"), []byte("transparency")}
serverConfig := &Config{
Certificates: []Certificate{{
Certificate: [][]byte{testRSACertificate},
PrivateKey: testRSAPrivateKey,
SignedCertificateTimestamps: expected,
}},
MaxVersion: version,
}
clientConfig := &Config{
InsecureSkipVerify: true,
Expand All @@ -461,6 +467,11 @@ func TestSCTHandshake(t *testing.T) {
}

func TestCrossVersionResume(t *testing.T) {
t.Run("TLSv12", func(t *testing.T) { testCrossVersionResume(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testCrossVersionResume(t, VersionTLS13) })
}

func testCrossVersionResume(t *testing.T, version uint16) {
serverConfig := &Config{
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
Certificates: testConfig.Certificates,
Expand Down Expand Up @@ -622,11 +633,6 @@ func (test *serverTest) loadData() (flows [][]byte, err error) {
}

func (test *serverTest) run(t *testing.T, write bool) {
// TODO(filippo): regenerate server tests all at once.
if !write && !strings.Contains(test.name, "TLSv13") {
t.Skip("recorded client tests are out of date")
}

checkOpenSSLVersion(t)

var clientConn, serverConn net.Conn
Expand Down Expand Up @@ -769,12 +775,6 @@ func runServerTestTLS12(t *testing.T, template *serverTest) {
}

func runServerTestTLS13(t *testing.T, template *serverTest) {
// TODO(filippo): set MaxVersion to VersionTLS13 instead in testConfig
// while regenerating server tests.
if template.config == nil {
template.config = testConfig.Clone()
}
template.config.MaxVersion = VersionTLS13
runServerTestForVersion(t, template, "TLSv13", "-tls1_3")
}

Expand Down Expand Up @@ -1208,7 +1208,7 @@ func TestHandshakeServerRSAPSS(t *testing.T) {
runServerTestTLS13(t, test)
}

func benchmarkHandshakeServer(b *testing.B, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
func benchmarkHandshakeServer(b *testing.B, version uint16, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
config := testConfig.Clone()
config.CipherSuites = []uint16{cipherSuite}
config.CurvePreferences = []CurveID{curve}
Expand All @@ -1220,7 +1220,10 @@ func benchmarkHandshakeServer(b *testing.B, cipherSuite uint16, curve CurveID, c
clientConn, serverConn := localPipe(b)
serverConn = &recordingConn{Conn: serverConn}
go func() {
client := Client(clientConn, testConfig)
config := testConfig.Clone()
config.MaxVersion = version
config.CurvePreferences = []CurveID{curve}
client := Client(clientConn, config)
client.Handshake()
}()
server := Server(serverConn, config)
Expand Down Expand Up @@ -1265,27 +1268,51 @@ func benchmarkHandshakeServer(b *testing.B, cipherSuite uint16, curve CurveID, c

func BenchmarkHandshakeServer(b *testing.B) {
b.Run("RSA", func(b *testing.B) {
benchmarkHandshakeServer(b, TLS_RSA_WITH_AES_128_GCM_SHA256,
benchmarkHandshakeServer(b, VersionTLS12, TLS_RSA_WITH_AES_128_GCM_SHA256,
0, testRSACertificate, testRSAPrivateKey)
})
b.Run("ECDHE-P256-RSA", func(b *testing.B) {
benchmarkHandshakeServer(b, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
CurveP256, testRSACertificate, testRSAPrivateKey)
b.Run("TLSv13", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
CurveP256, testRSACertificate, testRSAPrivateKey)
})
b.Run("TLSv12", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
CurveP256, testRSACertificate, testRSAPrivateKey)
})
})
b.Run("ECDHE-P256-ECDSA-P256", func(b *testing.B) {
benchmarkHandshakeServer(b, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
CurveP256, testP256Certificate, testP256PrivateKey)
b.Run("TLSv13", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
CurveP256, testP256Certificate, testP256PrivateKey)
})
b.Run("TLSv12", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
CurveP256, testP256Certificate, testP256PrivateKey)
})
})
b.Run("ECDHE-X25519-ECDSA-P256", func(b *testing.B) {
benchmarkHandshakeServer(b, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
X25519, testP256Certificate, testP256PrivateKey)
b.Run("TLSv13", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
X25519, testP256Certificate, testP256PrivateKey)
})
b.Run("TLSv12", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
X25519, testP256Certificate, testP256PrivateKey)
})
})
b.Run("ECDHE-P521-ECDSA-P521", func(b *testing.B) {
if testECDSAPrivateKey.PublicKey.Curve != elliptic.P521() {
b.Fatal("test ECDSA key doesn't use curve P-521")
}
benchmarkHandshakeServer(b, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
CurveP521, testECDSACertificate, testECDSAPrivateKey)
b.Run("TLSv13", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
CurveP521, testECDSACertificate, testECDSAPrivateKey)
})
b.Run("TLSv12", func(b *testing.B) {
benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
CurveP521, testECDSACertificate, testECDSAPrivateKey)
})
})
}

Expand Down
9 changes: 8 additions & 1 deletion src/crypto/tls/handshake_server_tls13.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,14 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
}

if hs.clientHello.earlyData {
return errors.New("tls: early data skipping not implemented") // TODO(filippo)
// See RFC 8446, Section 4.2.10 for the complicated behavior required
// here. The scenario is that a different server at our address offered
// to accept early data in the past, which we can't handle. For now, all
// 0-RTT enabled session tickets need to expire before a Go server can
// replace a server or join a pool. That's the same requirement that
// applies to mixing or replacing with any TLS 1.2 server.
c.sendAlert(alertUnsupportedExtension)
return errors.New("tls: client sent unexpected early data")
}

hs.hello.sessionId = hs.clientHello.sessionId
Expand Down
Loading

0 comments on commit 30cc978

Please sign in to comment.