Home | History | Annotate | Download | only in tls
      1 // Copyright 2012 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package tls
      6 
      7 import (
      8 	"bytes"
      9 	"crypto/x509"
     10 	"errors"
     11 	"fmt"
     12 	"internal/testenv"
     13 	"io"
     14 	"io/ioutil"
     15 	"math"
     16 	"math/rand"
     17 	"net"
     18 	"os"
     19 	"reflect"
     20 	"strings"
     21 	"testing"
     22 	"testing/quick"
     23 	"time"
     24 )
     25 
     26 var rsaCertPEM = `-----BEGIN CERTIFICATE-----
     27 MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
     28 BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
     29 aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
     30 MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
     31 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
     32 hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
     33 rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
     34 zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
     35 MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
     36 r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
     37 -----END CERTIFICATE-----
     38 `
     39 
     40 var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
     41 MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
     42 k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
     43 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
     44 MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
     45 SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
     46 xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
     47 D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
     48 -----END RSA PRIVATE KEY-----
     49 `
     50 
     51 // keyPEM is the same as rsaKeyPEM, but declares itself as just
     52 // "PRIVATE KEY", not "RSA PRIVATE KEY".  https://golang.org/issue/4477
     53 var keyPEM = `-----BEGIN PRIVATE KEY-----
     54 MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
     55 k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
     56 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
     57 MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
     58 SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
     59 xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
     60 D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
     61 -----END PRIVATE KEY-----
     62 `
     63 
     64 var ecdsaCertPEM = `-----BEGIN CERTIFICATE-----
     65 MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
     66 EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
     67 eSBMdGQwHhcNMTIxMTE0MTI0MDQ4WhcNMTUxMTE0MTI0MDQ4WjBFMQswCQYDVQQG
     68 EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
     69 Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBY9+my9OoeSUR
     70 lDQdV/x8LsOuLilthhiS1Tz4aGDHIPwC1mlvnf7fg5lecYpMCrLLhauAc1UJXcgl
     71 01xoLuzgtAEAgv2P/jgytzRSpUYvgLBt1UA0leLYBy6mQQbrNEuqT3INapKIcUv8
     72 XxYP0xMEUksLPq6Ca+CRSqTtrd/23uTnapkwCQYHKoZIzj0EAQOBigAwgYYCQXJo
     73 A7Sl2nLVf+4Iu/tAX/IF4MavARKC4PPHK3zfuGfPR3oCCcsAoz3kAzOeijvd0iXb
     74 H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1
     75 +jwM1FGS4fREIOvlBYr/SzzQRtwrvrzGYxDEDbsC0ZGRnA==
     76 -----END CERTIFICATE-----
     77 `
     78 
     79 var ecdsaKeyPEM = `-----BEGIN EC PARAMETERS-----
     80 BgUrgQQAIw==
     81 -----END EC PARAMETERS-----
     82 -----BEGIN EC PRIVATE KEY-----
     83 MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0
     84 NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL
     85 06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz
     86 VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q
     87 kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ==
     88 -----END EC PRIVATE KEY-----
     89 `
     90 
     91 var keyPairTests = []struct {
     92 	algo string
     93 	cert string
     94 	key  string
     95 }{
     96 	{"ECDSA", ecdsaCertPEM, ecdsaKeyPEM},
     97 	{"RSA", rsaCertPEM, rsaKeyPEM},
     98 	{"RSA-untyped", rsaCertPEM, keyPEM}, // golang.org/issue/4477
     99 }
    100 
    101 func TestX509KeyPair(t *testing.T) {
    102 	t.Parallel()
    103 	var pem []byte
    104 	for _, test := range keyPairTests {
    105 		pem = []byte(test.cert + test.key)
    106 		if _, err := X509KeyPair(pem, pem); err != nil {
    107 			t.Errorf("Failed to load %s cert followed by %s key: %s", test.algo, test.algo, err)
    108 		}
    109 		pem = []byte(test.key + test.cert)
    110 		if _, err := X509KeyPair(pem, pem); err != nil {
    111 			t.Errorf("Failed to load %s key followed by %s cert: %s", test.algo, test.algo, err)
    112 		}
    113 	}
    114 }
    115 
    116 func TestX509KeyPairErrors(t *testing.T) {
    117 	_, err := X509KeyPair([]byte(rsaKeyPEM), []byte(rsaCertPEM))
    118 	if err == nil {
    119 		t.Fatalf("X509KeyPair didn't return an error when arguments were switched")
    120 	}
    121 	if subStr := "been switched"; !strings.Contains(err.Error(), subStr) {
    122 		t.Fatalf("Expected %q in the error when switching arguments to X509KeyPair, but the error was %q", subStr, err)
    123 	}
    124 
    125 	_, err = X509KeyPair([]byte(rsaCertPEM), []byte(rsaCertPEM))
    126 	if err == nil {
    127 		t.Fatalf("X509KeyPair didn't return an error when both arguments were certificates")
    128 	}
    129 	if subStr := "certificate"; !strings.Contains(err.Error(), subStr) {
    130 		t.Fatalf("Expected %q in the error when both arguments to X509KeyPair were certificates, but the error was %q", subStr, err)
    131 	}
    132 
    133 	const nonsensePEM = `
    134 -----BEGIN NONSENSE-----
    135 Zm9vZm9vZm9v
    136 -----END NONSENSE-----
    137 `
    138 
    139 	_, err = X509KeyPair([]byte(nonsensePEM), []byte(nonsensePEM))
    140 	if err == nil {
    141 		t.Fatalf("X509KeyPair didn't return an error when both arguments were nonsense")
    142 	}
    143 	if subStr := "NONSENSE"; !strings.Contains(err.Error(), subStr) {
    144 		t.Fatalf("Expected %q in the error when both arguments to X509KeyPair were nonsense, but the error was %q", subStr, err)
    145 	}
    146 }
    147 
    148 func TestX509MixedKeyPair(t *testing.T) {
    149 	if _, err := X509KeyPair([]byte(rsaCertPEM), []byte(ecdsaKeyPEM)); err == nil {
    150 		t.Error("Load of RSA certificate succeeded with ECDSA private key")
    151 	}
    152 	if _, err := X509KeyPair([]byte(ecdsaCertPEM), []byte(rsaKeyPEM)); err == nil {
    153 		t.Error("Load of ECDSA certificate succeeded with RSA private key")
    154 	}
    155 }
    156 
    157 func newLocalListener(t testing.TB) net.Listener {
    158 	ln, err := net.Listen("tcp", "127.0.0.1:0")
    159 	if err != nil {
    160 		ln, err = net.Listen("tcp6", "[::1]:0")
    161 	}
    162 	if err != nil {
    163 		t.Fatal(err)
    164 	}
    165 	return ln
    166 }
    167 
    168 func TestDialTimeout(t *testing.T) {
    169 	if testing.Short() {
    170 		t.Skip("skipping in short mode")
    171 	}
    172 	listener := newLocalListener(t)
    173 
    174 	addr := listener.Addr().String()
    175 	defer listener.Close()
    176 
    177 	complete := make(chan bool)
    178 	defer close(complete)
    179 
    180 	go func() {
    181 		conn, err := listener.Accept()
    182 		if err != nil {
    183 			t.Error(err)
    184 			return
    185 		}
    186 		<-complete
    187 		conn.Close()
    188 	}()
    189 
    190 	dialer := &net.Dialer{
    191 		Timeout: 10 * time.Millisecond,
    192 	}
    193 
    194 	var err error
    195 	if _, err = DialWithDialer(dialer, "tcp", addr, nil); err == nil {
    196 		t.Fatal("DialWithTimeout completed successfully")
    197 	}
    198 
    199 	if !isTimeoutError(err) {
    200 		t.Errorf("resulting error not a timeout: %v\nType %T: %#v", err, err, err)
    201 	}
    202 }
    203 
    204 func isTimeoutError(err error) bool {
    205 	if ne, ok := err.(net.Error); ok {
    206 		return ne.Timeout()
    207 	}
    208 	return false
    209 }
    210 
    211 // tests that Conn.Read returns (non-zero, io.EOF) instead of
    212 // (non-zero, nil) when a Close (alertCloseNotify) is sitting right
    213 // behind the application data in the buffer.
    214 func TestConnReadNonzeroAndEOF(t *testing.T) {
    215 	// This test is racy: it assumes that after a write to a
    216 	// localhost TCP connection, the peer TCP connection can
    217 	// immediately read it. Because it's racy, we skip this test
    218 	// in short mode, and then retry it several times with an
    219 	// increasing sleep in between our final write (via srv.Close
    220 	// below) and the following read.
    221 	if testing.Short() {
    222 		t.Skip("skipping in short mode")
    223 	}
    224 	var err error
    225 	for delay := time.Millisecond; delay <= 64*time.Millisecond; delay *= 2 {
    226 		if err = testConnReadNonzeroAndEOF(t, delay); err == nil {
    227 			return
    228 		}
    229 	}
    230 	t.Error(err)
    231 }
    232 
    233 func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
    234 	ln := newLocalListener(t)
    235 	defer ln.Close()
    236 
    237 	srvCh := make(chan *Conn, 1)
    238 	var serr error
    239 	go func() {
    240 		sconn, err := ln.Accept()
    241 		if err != nil {
    242 			serr = err
    243 			srvCh <- nil
    244 			return
    245 		}
    246 		serverConfig := testConfig.Clone()
    247 		srv := Server(sconn, serverConfig)
    248 		if err := srv.Handshake(); err != nil {
    249 			serr = fmt.Errorf("handshake: %v", err)
    250 			srvCh <- nil
    251 			return
    252 		}
    253 		srvCh <- srv
    254 	}()
    255 
    256 	clientConfig := testConfig.Clone()
    257 	conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
    258 	if err != nil {
    259 		t.Fatal(err)
    260 	}
    261 	defer conn.Close()
    262 
    263 	srv := <-srvCh
    264 	if srv == nil {
    265 		return serr
    266 	}
    267 
    268 	buf := make([]byte, 6)
    269 
    270 	srv.Write([]byte("foobar"))
    271 	n, err := conn.Read(buf)
    272 	if n != 6 || err != nil || string(buf) != "foobar" {
    273 		return fmt.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
    274 	}
    275 
    276 	srv.Write([]byte("abcdef"))
    277 	srv.Close()
    278 	time.Sleep(delay)
    279 	n, err = conn.Read(buf)
    280 	if n != 6 || string(buf) != "abcdef" {
    281 		return fmt.Errorf("Read = %d, buf= %q; want 6, abcdef", n, buf)
    282 	}
    283 	if err != io.EOF {
    284 		return fmt.Errorf("Second Read error = %v; want io.EOF", err)
    285 	}
    286 	return nil
    287 }
    288 
    289 func TestTLSUniqueMatches(t *testing.T) {
    290 	ln := newLocalListener(t)
    291 	defer ln.Close()
    292 
    293 	serverTLSUniques := make(chan []byte)
    294 	go func() {
    295 		for i := 0; i < 2; i++ {
    296 			sconn, err := ln.Accept()
    297 			if err != nil {
    298 				t.Error(err)
    299 				return
    300 			}
    301 			serverConfig := testConfig.Clone()
    302 			srv := Server(sconn, serverConfig)
    303 			if err := srv.Handshake(); err != nil {
    304 				t.Error(err)
    305 				return
    306 			}
    307 			serverTLSUniques <- srv.ConnectionState().TLSUnique
    308 		}
    309 	}()
    310 
    311 	clientConfig := testConfig.Clone()
    312 	clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
    313 	conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
    314 	if err != nil {
    315 		t.Fatal(err)
    316 	}
    317 	if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
    318 		t.Error("client and server channel bindings differ")
    319 	}
    320 	conn.Close()
    321 
    322 	conn, err = Dial("tcp", ln.Addr().String(), clientConfig)
    323 	if err != nil {
    324 		t.Fatal(err)
    325 	}
    326 	defer conn.Close()
    327 	if !conn.ConnectionState().DidResume {
    328 		t.Error("second session did not use resumption")
    329 	}
    330 	if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
    331 		t.Error("client and server channel bindings differ when session resumption is used")
    332 	}
    333 }
    334 
    335 func TestVerifyHostname(t *testing.T) {
    336 	testenv.MustHaveExternalNetwork(t)
    337 
    338 	c, err := Dial("tcp", "www.google.com:https", nil)
    339 	if err != nil {
    340 		t.Fatal(err)
    341 	}
    342 	if err := c.VerifyHostname("www.google.com"); err != nil {
    343 		t.Fatalf("verify www.google.com: %v", err)
    344 	}
    345 	if err := c.VerifyHostname("www.yahoo.com"); err == nil {
    346 		t.Fatalf("verify www.yahoo.com succeeded")
    347 	}
    348 
    349 	c, err = Dial("tcp", "www.google.com:https", &Config{InsecureSkipVerify: true})
    350 	if err != nil {
    351 		t.Fatal(err)
    352 	}
    353 	if err := c.VerifyHostname("www.google.com"); err == nil {
    354 		t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
    355 	}
    356 	if err := c.VerifyHostname("www.yahoo.com"); err == nil {
    357 		t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
    358 	}
    359 }
    360 
    361 func TestVerifyHostnameResumed(t *testing.T) {
    362 	testenv.MustHaveExternalNetwork(t)
    363 
    364 	config := &Config{
    365 		ClientSessionCache: NewLRUClientSessionCache(32),
    366 	}
    367 	for i := 0; i < 2; i++ {
    368 		c, err := Dial("tcp", "www.google.com:https", config)
    369 		if err != nil {
    370 			t.Fatalf("Dial #%d: %v", i, err)
    371 		}
    372 		cs := c.ConnectionState()
    373 		if i > 0 && !cs.DidResume {
    374 			t.Fatalf("Subsequent connection unexpectedly didn't resume")
    375 		}
    376 		if cs.VerifiedChains == nil {
    377 			t.Fatalf("Dial #%d: cs.VerifiedChains == nil", i)
    378 		}
    379 		if err := c.VerifyHostname("www.google.com"); err != nil {
    380 			t.Fatalf("verify www.google.com #%d: %v", i, err)
    381 		}
    382 		c.Close()
    383 	}
    384 }
    385 
    386 func TestConnCloseBreakingWrite(t *testing.T) {
    387 	ln := newLocalListener(t)
    388 	defer ln.Close()
    389 
    390 	srvCh := make(chan *Conn, 1)
    391 	var serr error
    392 	var sconn net.Conn
    393 	go func() {
    394 		var err error
    395 		sconn, err = ln.Accept()
    396 		if err != nil {
    397 			serr = err
    398 			srvCh <- nil
    399 			return
    400 		}
    401 		serverConfig := testConfig.Clone()
    402 		srv := Server(sconn, serverConfig)
    403 		if err := srv.Handshake(); err != nil {
    404 			serr = fmt.Errorf("handshake: %v", err)
    405 			srvCh <- nil
    406 			return
    407 		}
    408 		srvCh <- srv
    409 	}()
    410 
    411 	cconn, err := net.Dial("tcp", ln.Addr().String())
    412 	if err != nil {
    413 		t.Fatal(err)
    414 	}
    415 	defer cconn.Close()
    416 
    417 	conn := &changeImplConn{
    418 		Conn: cconn,
    419 	}
    420 
    421 	clientConfig := testConfig.Clone()
    422 	tconn := Client(conn, clientConfig)
    423 	if err := tconn.Handshake(); err != nil {
    424 		t.Fatal(err)
    425 	}
    426 
    427 	srv := <-srvCh
    428 	if srv == nil {
    429 		t.Fatal(serr)
    430 	}
    431 	defer sconn.Close()
    432 
    433 	connClosed := make(chan struct{})
    434 	conn.closeFunc = func() error {
    435 		close(connClosed)
    436 		return nil
    437 	}
    438 
    439 	inWrite := make(chan bool, 1)
    440 	var errConnClosed = errors.New("conn closed for test")
    441 	conn.writeFunc = func(p []byte) (n int, err error) {
    442 		inWrite <- true
    443 		<-connClosed
    444 		return 0, errConnClosed
    445 	}
    446 
    447 	closeReturned := make(chan bool, 1)
    448 	go func() {
    449 		<-inWrite
    450 		tconn.Close() // test that this doesn't block forever.
    451 		closeReturned <- true
    452 	}()
    453 
    454 	_, err = tconn.Write([]byte("foo"))
    455 	if err != errConnClosed {
    456 		t.Errorf("Write error = %v; want errConnClosed", err)
    457 	}
    458 
    459 	<-closeReturned
    460 	if err := tconn.Close(); err != errClosed {
    461 		t.Errorf("Close error = %v; want errClosed", err)
    462 	}
    463 }
    464 
    465 func TestConnCloseWrite(t *testing.T) {
    466 	ln := newLocalListener(t)
    467 	defer ln.Close()
    468 
    469 	clientDoneChan := make(chan struct{})
    470 
    471 	serverCloseWrite := func() error {
    472 		sconn, err := ln.Accept()
    473 		if err != nil {
    474 			return fmt.Errorf("accept: %v", err)
    475 		}
    476 		defer sconn.Close()
    477 
    478 		serverConfig := testConfig.Clone()
    479 		srv := Server(sconn, serverConfig)
    480 		if err := srv.Handshake(); err != nil {
    481 			return fmt.Errorf("handshake: %v", err)
    482 		}
    483 		defer srv.Close()
    484 
    485 		data, err := ioutil.ReadAll(srv)
    486 		if err != nil {
    487 			return err
    488 		}
    489 		if len(data) > 0 {
    490 			return fmt.Errorf("Read data = %q; want nothing", data)
    491 		}
    492 
    493 		if err := srv.CloseWrite(); err != nil {
    494 			return fmt.Errorf("server CloseWrite: %v", err)
    495 		}
    496 
    497 		// Wait for clientCloseWrite to finish, so we know we
    498 		// tested the CloseWrite before we defer the
    499 		// sconn.Close above, which would also cause the
    500 		// client to unblock like CloseWrite.
    501 		<-clientDoneChan
    502 		return nil
    503 	}
    504 
    505 	clientCloseWrite := func() error {
    506 		defer close(clientDoneChan)
    507 
    508 		clientConfig := testConfig.Clone()
    509 		conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
    510 		if err != nil {
    511 			return err
    512 		}
    513 		if err := conn.Handshake(); err != nil {
    514 			return err
    515 		}
    516 		defer conn.Close()
    517 
    518 		if err := conn.CloseWrite(); err != nil {
    519 			return fmt.Errorf("client CloseWrite: %v", err)
    520 		}
    521 
    522 		if _, err := conn.Write([]byte{0}); err != errShutdown {
    523 			return fmt.Errorf("CloseWrite error = %v; want errShutdown", err)
    524 		}
    525 
    526 		data, err := ioutil.ReadAll(conn)
    527 		if err != nil {
    528 			return err
    529 		}
    530 		if len(data) > 0 {
    531 			return fmt.Errorf("Read data = %q; want nothing", data)
    532 		}
    533 		return nil
    534 	}
    535 
    536 	errChan := make(chan error, 2)
    537 
    538 	go func() { errChan <- serverCloseWrite() }()
    539 	go func() { errChan <- clientCloseWrite() }()
    540 
    541 	for i := 0; i < 2; i++ {
    542 		select {
    543 		case err := <-errChan:
    544 			if err != nil {
    545 				t.Fatal(err)
    546 			}
    547 		case <-time.After(10 * time.Second):
    548 			t.Fatal("deadlock")
    549 		}
    550 	}
    551 
    552 	// Also test CloseWrite being called before the handshake is
    553 	// finished:
    554 	{
    555 		ln2 := newLocalListener(t)
    556 		defer ln2.Close()
    557 
    558 		netConn, err := net.Dial("tcp", ln2.Addr().String())
    559 		if err != nil {
    560 			t.Fatal(err)
    561 		}
    562 		defer netConn.Close()
    563 		conn := Client(netConn, testConfig.Clone())
    564 
    565 		if err := conn.CloseWrite(); err != errEarlyCloseWrite {
    566 			t.Errorf("CloseWrite error = %v; want errEarlyCloseWrite", err)
    567 		}
    568 	}
    569 }
    570 
    571 func TestClone(t *testing.T) {
    572 	var c1 Config
    573 	v := reflect.ValueOf(&c1).Elem()
    574 
    575 	rnd := rand.New(rand.NewSource(time.Now().Unix()))
    576 	typ := v.Type()
    577 	for i := 0; i < typ.NumField(); i++ {
    578 		f := v.Field(i)
    579 		if !f.CanSet() {
    580 			// unexported field; not cloned.
    581 			continue
    582 		}
    583 
    584 		// testing/quick can't handle functions or interfaces.
    585 		fn := typ.Field(i).Name
    586 		switch fn {
    587 		case "Rand":
    588 			f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
    589 			continue
    590 		case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "GetClientCertificate":
    591 			// DeepEqual can't compare functions.
    592 			continue
    593 		case "Certificates":
    594 			f.Set(reflect.ValueOf([]Certificate{
    595 				{Certificate: [][]byte{{'b'}}},
    596 			}))
    597 			continue
    598 		case "NameToCertificate":
    599 			f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
    600 			continue
    601 		case "RootCAs", "ClientCAs":
    602 			f.Set(reflect.ValueOf(x509.NewCertPool()))
    603 			continue
    604 		case "ClientSessionCache":
    605 			f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
    606 			continue
    607 		case "KeyLogWriter":
    608 			f.Set(reflect.ValueOf(io.Writer(os.Stdout)))
    609 			continue
    610 
    611 		}
    612 
    613 		q, ok := quick.Value(f.Type(), rnd)
    614 		if !ok {
    615 			t.Fatalf("quick.Value failed on field %s", fn)
    616 		}
    617 		f.Set(q)
    618 	}
    619 
    620 	c2 := c1.Clone()
    621 	// DeepEqual also compares unexported fields, thus c2 needs to have run
    622 	// serverInit in order to be DeepEqual to c1. Cloning it and discarding
    623 	// the result is sufficient.
    624 	c2.Clone()
    625 
    626 	if !reflect.DeepEqual(&c1, c2) {
    627 		t.Errorf("clone failed to copy a field")
    628 	}
    629 }
    630 
    631 // changeImplConn is a net.Conn which can change its Write and Close
    632 // methods.
    633 type changeImplConn struct {
    634 	net.Conn
    635 	writeFunc func([]byte) (int, error)
    636 	closeFunc func() error
    637 }
    638 
    639 func (w *changeImplConn) Write(p []byte) (n int, err error) {
    640 	if w.writeFunc != nil {
    641 		return w.writeFunc(p)
    642 	}
    643 	return w.Conn.Write(p)
    644 }
    645 
    646 func (w *changeImplConn) Close() error {
    647 	if w.closeFunc != nil {
    648 		return w.closeFunc()
    649 	}
    650 	return w.Conn.Close()
    651 }
    652 
    653 func throughput(b *testing.B, totalBytes int64, dynamicRecordSizingDisabled bool) {
    654 	ln := newLocalListener(b)
    655 	defer ln.Close()
    656 
    657 	N := b.N
    658 
    659 	// Less than 64KB because Windows appears to use a TCP rwin < 64KB.
    660 	// See Issue #15899.
    661 	const bufsize = 32 << 10
    662 
    663 	go func() {
    664 		buf := make([]byte, bufsize)
    665 		for i := 0; i < N; i++ {
    666 			sconn, err := ln.Accept()
    667 			if err != nil {
    668 				// panic rather than synchronize to avoid benchmark overhead
    669 				// (cannot call b.Fatal in goroutine)
    670 				panic(fmt.Errorf("accept: %v", err))
    671 			}
    672 			serverConfig := testConfig.Clone()
    673 			serverConfig.CipherSuites = nil // the defaults may prefer faster ciphers
    674 			serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
    675 			srv := Server(sconn, serverConfig)
    676 			if err := srv.Handshake(); err != nil {
    677 				panic(fmt.Errorf("handshake: %v", err))
    678 			}
    679 			if _, err := io.CopyBuffer(srv, srv, buf); err != nil {
    680 				panic(fmt.Errorf("copy buffer: %v", err))
    681 			}
    682 		}
    683 	}()
    684 
    685 	b.SetBytes(totalBytes)
    686 	clientConfig := testConfig.Clone()
    687 	clientConfig.CipherSuites = nil // the defaults may prefer faster ciphers
    688 	clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
    689 
    690 	buf := make([]byte, bufsize)
    691 	chunks := int(math.Ceil(float64(totalBytes) / float64(len(buf))))
    692 	for i := 0; i < N; i++ {
    693 		conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
    694 		if err != nil {
    695 			b.Fatal(err)
    696 		}
    697 		for j := 0; j < chunks; j++ {
    698 			_, err := conn.Write(buf)
    699 			if err != nil {
    700 				b.Fatal(err)
    701 			}
    702 			_, err = io.ReadFull(conn, buf)
    703 			if err != nil {
    704 				b.Fatal(err)
    705 			}
    706 		}
    707 		conn.Close()
    708 	}
    709 }
    710 
    711 func BenchmarkThroughput(b *testing.B) {
    712 	for _, mode := range []string{"Max", "Dynamic"} {
    713 		for size := 1; size <= 64; size <<= 1 {
    714 			name := fmt.Sprintf("%sPacket/%dMB", mode, size)
    715 			b.Run(name, func(b *testing.B) {
    716 				throughput(b, int64(size<<20), mode == "Max")
    717 			})
    718 		}
    719 	}
    720 }
    721 
    722 type slowConn struct {
    723 	net.Conn
    724 	bps int
    725 }
    726 
    727 func (c *slowConn) Write(p []byte) (int, error) {
    728 	if c.bps == 0 {
    729 		panic("too slow")
    730 	}
    731 	t0 := time.Now()
    732 	wrote := 0
    733 	for wrote < len(p) {
    734 		time.Sleep(100 * time.Microsecond)
    735 		allowed := int(time.Since(t0).Seconds()*float64(c.bps)) / 8
    736 		if allowed > len(p) {
    737 			allowed = len(p)
    738 		}
    739 		if wrote < allowed {
    740 			n, err := c.Conn.Write(p[wrote:allowed])
    741 			wrote += n
    742 			if err != nil {
    743 				return wrote, err
    744 			}
    745 		}
    746 	}
    747 	return len(p), nil
    748 }
    749 
    750 func latency(b *testing.B, bps int, dynamicRecordSizingDisabled bool) {
    751 	ln := newLocalListener(b)
    752 	defer ln.Close()
    753 
    754 	N := b.N
    755 
    756 	go func() {
    757 		for i := 0; i < N; i++ {
    758 			sconn, err := ln.Accept()
    759 			if err != nil {
    760 				// panic rather than synchronize to avoid benchmark overhead
    761 				// (cannot call b.Fatal in goroutine)
    762 				panic(fmt.Errorf("accept: %v", err))
    763 			}
    764 			serverConfig := testConfig.Clone()
    765 			serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
    766 			srv := Server(&slowConn{sconn, bps}, serverConfig)
    767 			if err := srv.Handshake(); err != nil {
    768 				panic(fmt.Errorf("handshake: %v", err))
    769 			}
    770 			io.Copy(srv, srv)
    771 		}
    772 	}()
    773 
    774 	clientConfig := testConfig.Clone()
    775 	clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
    776 
    777 	buf := make([]byte, 16384)
    778 	peek := make([]byte, 1)
    779 
    780 	for i := 0; i < N; i++ {
    781 		conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
    782 		if err != nil {
    783 			b.Fatal(err)
    784 		}
    785 		// make sure we're connected and previous connection has stopped
    786 		if _, err := conn.Write(buf[:1]); err != nil {
    787 			b.Fatal(err)
    788 		}
    789 		if _, err := io.ReadFull(conn, peek); err != nil {
    790 			b.Fatal(err)
    791 		}
    792 		if _, err := conn.Write(buf); err != nil {
    793 			b.Fatal(err)
    794 		}
    795 		if _, err = io.ReadFull(conn, peek); err != nil {
    796 			b.Fatal(err)
    797 		}
    798 		conn.Close()
    799 	}
    800 }
    801 
    802 func BenchmarkLatency(b *testing.B) {
    803 	for _, mode := range []string{"Max", "Dynamic"} {
    804 		for _, kbps := range []int{200, 500, 1000, 2000, 5000} {
    805 			name := fmt.Sprintf("%sPacket/%dkbps", mode, kbps)
    806 			b.Run(name, func(b *testing.B) {
    807 				latency(b, kbps*1000, mode == "Max")
    808 			})
    809 		}
    810 	}
    811 }
    812