1// Copyright 2017 Google Inc. 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
5package tls
6
7import (
8	"bytes"
9	"crypto/tls"
10	"fmt"
11	"io"
12	"net"
13	"os"
14	"os/exec"
15	"strings"
16	"testing"
17	"time"
18)
19
20// helloStrategy is a sum type interface which allows us to pass either a ClientHelloID or a ClientHelloSpec and then act accordingly
21type helloStrategy interface {
22	helloName() string
23}
24
25type helloID struct {
26	id ClientHelloID
27}
28
29func (hid *helloID) helloName() string {
30	return hid.id.Str()
31}
32
33type helloSpec struct {
34	name string
35	spec *ClientHelloSpec
36}
37
38func (hs *helloSpec) helloName() string {
39	return hs.name
40}
41
42func TestUTLSMarshalNoOp(t *testing.T) {
43	str := "We rely on clientHelloMsg.marshal() not doing anything if clientHelloMsg.raw is set"
44	uconn := UClient(&net.TCPConn{}, &Config{ServerName: "foobar"}, HelloGolang)
45	msg, _, err := uconn.makeClientHello()
46	if err != nil {
47		t.Errorf("Got error: %s; expected to succeed", err)
48	}
49	msg.raw = []byte(str)
50	marshalledHello := msg.marshal()
51	if strings.Compare(string(marshalledHello), str) != 0 {
52		t.Errorf("clientHelloMsg.marshal() is not NOOP! Expected to get: %s, got: %s", str, string(marshalledHello))
53	}
54}
55
56func TestUTLSHandshakeClientParrotGolang(t *testing.T) {
57	hello := &helloID{HelloGolang}
58
59	testUTLSHandshakeClientECDHE_ECDSA_WITH_CHACHA20_POLY1305(t, hello)
60	testUTLSHandshakeClientECDHE_RSA_WITH_CHACHA20_POLY1305(t, hello)
61
62	testUTLSHandshakeClientECDHE_RSA_AES128_GCM_SHA256(t, hello)
63	testUTLSHandshakeClientECDHE_ECDSA_AES128_GCM_SHA256(t, hello)
64	testUTLSHandshakeClientECDHE_RSA_AES256_CBC_SHA(t, hello)
65	testUTLSHandshakeClientECDHE_ECDSA_AES256_CBC_SHA(t, hello)
66	testUTLSHandshakeClientECDHE_RSA_AES128_CBC_SHA(t, hello)
67	testUTLSHandshakeClientECDHE_ECDSA_AES128_CBC_SHA(t, hello)
68
69	testUTLSHandshakeClientRSA_AES128_GCM_SHA256(t, hello)
70}
71
72func TestUTLSHandshakeClientParrotChrome_70(t *testing.T) {
73	hello := &helloID{HelloChrome_70}
74
75	testUTLSHandshakeClientTLS13_AES_128_GCM_SHA256(t, hello)
76	testUTLSHandshakeClientTLS13_AES_256_GCM_SHA384(t, hello)
77	testUTLSHandshakeClientTLS13_CHACHA20_POLY1305_SHA256(t, hello)
78	//testUTLSHandshakeClientECDHE_ECDSA_AES128_GCM_SHA256(t, hello)
79	testUTLSHandshakeClientECDHE_RSA_AES128_GCM_SHA256(t, hello)
80	//testUTLSHandshakeClientECDHE_ECDSA_AES256_GCM_SHA256(t, hello)
81	testUTLSHandshakeClientECDHE_RSA_AES256_GCM_SHA256(t, hello)
82
83	//testUTLSHandshakeClientECDHE_ECDSA_WITH_CHACHA20_POLY1305(t, hello)
84	testUTLSHandshakeClientECDHE_RSA_WITH_CHACHA20_POLY1305(t, hello)
85
86	testUTLSHandshakeClientECDHE_RSA_AES128_CBC_SHA(t, hello)
87	testUTLSHandshakeClientECDHE_RSA_AES256_CBC_SHA(t, hello)
88
89	testUTLSHandshakeClientRSA_AES128_GCM_SHA256(t, hello)
90}
91
92func TestUTLSHandshakeClientParrotChrome_58(t *testing.T) {
93	hello := &helloID{HelloChrome_58}
94	// TODO: EC tests below are disabled because latest version of reference OpenSSL doesn't support p256 nor p384
95	// nor X25519 and I can't find configuration flag to enable it. Therefore I can't record replays.
96
97	//testUTLSHandshakeClientECDHE_ECDSA_AES128_GCM_SHA256(t, hello)
98	testUTLSHandshakeClientECDHE_RSA_AES128_GCM_SHA256(t, hello)
99	//testUTLSHandshakeClientECDHE_ECDSA_AES256_GCM_SHA256(t, hello)
100	testUTLSHandshakeClientECDHE_RSA_AES256_GCM_SHA256(t, hello)
101
102	//testUTLSHandshakeClientECDHE_ECDSA_WITH_CHACHA20_POLY1305(t, hello)
103	testUTLSHandshakeClientECDHE_RSA_WITH_CHACHA20_POLY1305(t, hello)
104
105	testUTLSHandshakeClientECDHE_RSA_AES128_CBC_SHA(t, hello)
106	testUTLSHandshakeClientECDHE_RSA_AES256_CBC_SHA(t, hello)
107
108	testUTLSHandshakeClientRSA_AES128_GCM_SHA256(t, hello)
109}
110
111func TestUTLSHandshakeClientParrotFirefox_63(t *testing.T) {
112	hello := &helloID{HelloFirefox_63}
113
114	testUTLSHandshakeClientTLS13_AES_128_GCM_SHA256(t, hello)
115	testUTLSHandshakeClientTLS13_AES_256_GCM_SHA384(t, hello)
116	testUTLSHandshakeClientTLS13_CHACHA20_POLY1305_SHA256(t, hello)
117
118	testUTLSHandshakeClientECDHE_ECDSA_AES128_GCM_SHA256(t, hello)
119	testUTLSHandshakeClientECDHE_RSA_AES128_GCM_SHA256(t, hello)
120
121	testUTLSHandshakeClientECDHE_ECDSA_WITH_CHACHA20_POLY1305(t, hello)
122	testUTLSHandshakeClientECDHE_RSA_WITH_CHACHA20_POLY1305(t, hello)
123
124	//testUTLSHandshakeClientECDHE_ECDSA_AES256_GCM_SHA256(t, hello) TODO: enable when OpenSSL supports it
125	testUTLSHandshakeClientECDHE_RSA_AES256_GCM_SHA256(t, hello)
126
127	testUTLSHandshakeClientECDHE_ECDSA_AES256_CBC_SHA(t, hello)
128	testUTLSHandshakeClientECDHE_ECDSA_AES128_CBC_SHA(t, hello)
129
130	testUTLSHandshakeClientECDHE_RSA_AES256_CBC_SHA(t, hello)
131	testUTLSHandshakeClientECDHE_RSA_AES128_CBC_SHA(t, hello)
132}
133
134func TestUTLSHandshakeClientParrotFirefox_55(t *testing.T) {
135	hello := &helloID{HelloFirefox_55}
136
137	testUTLSHandshakeClientECDHE_ECDSA_AES128_GCM_SHA256(t, hello)
138	testUTLSHandshakeClientECDHE_RSA_AES128_GCM_SHA256(t, hello)
139
140	testUTLSHandshakeClientECDHE_ECDSA_WITH_CHACHA20_POLY1305(t, hello)
141	testUTLSHandshakeClientECDHE_RSA_WITH_CHACHA20_POLY1305(t, hello)
142
143	//testUTLSHandshakeClientECDHE_ECDSA_AES256_GCM_SHA256(t, hello) TODO: enable when OpenSSL supports it
144	testUTLSHandshakeClientECDHE_RSA_AES256_GCM_SHA256(t, hello)
145
146	testUTLSHandshakeClientECDHE_ECDSA_AES256_CBC_SHA(t, hello)
147	testUTLSHandshakeClientECDHE_ECDSA_AES128_CBC_SHA(t, hello)
148
149	testUTLSHandshakeClientECDHE_RSA_AES256_CBC_SHA(t, hello)
150	testUTLSHandshakeClientECDHE_RSA_AES128_CBC_SHA(t, hello)
151}
152
153func TestUTLSHandshakeClientParrotChrome_58_setclienthello(t *testing.T) {
154	hello := &helloID{HelloChrome_58}
155	config := getUTLSTestConfig()
156
157	opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
158	test := &clientTest{
159		name:   "UTLS-setclienthello-" + opensslCipherName + "-" + hello.helloName(),
160		args:   []string{"-cipher", opensslCipherName},
161		config: config,
162	}
163
164	runUTLSClientTestTLS12(t, test, hello)
165}
166
167// tests consistency of fingerprint after HelloRetryRequest
168// chrome 70 is used, due to only specifying X25519 in keyshare, but being able to generate P-256 curve too
169// openssl server, configured to use P-256, will send HelloRetryRequest
170func TestUTLSHelloRetryRequest(t *testing.T) {
171	hello := &helloID{HelloChrome_70}
172	config := testConfig.Clone()
173	config.CurvePreferences = []CurveID{X25519, CurveP256}
174
175	test := &clientTest{
176		name:   "UTLS-HelloRetryRequest-" + hello.helloName(),
177		args:   []string{"-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "P-256"},
178		config: config,
179	}
180
181	runUTLSClientTestTLS13(t, test, hello)
182}
183
184func TestUTLSRemoveSNIExtension(t *testing.T) {
185	hello := &helloID{HelloChrome_70}
186
187	config := getUTLSTestConfig()
188
189	opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
190	test := &clientTest{
191		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName() + "-OmitSNI",
192		args:   []string{"-cipher", opensslCipherName},
193		config: config,
194	}
195
196	runUTLSClientTestForVersion(t, test, "TLSv12-", "-tls1_2", hello, true)
197}
198
199/*
200*
201 HELPER FUNCTIONS BELOW
202*
203*/
204
205func getUTLSTestConfig() *Config {
206	testUTLSConfig := &Config{
207		Time: func() time.Time {
208			return time.Unix(0, 0)
209		},
210		Rand:               zeroSource{},
211		InsecureSkipVerify: true,
212		MinVersion:         VersionSSL30,
213		MaxVersion:         VersionTLS13,
214		CipherSuites:       allCipherSuites(),
215	}
216	return testUTLSConfig
217}
218
219func testUTLSHandshakeClientECDHE_RSA_AES128_CBC_SHA(t *testing.T, hello helloStrategy) {
220	config := getUTLSTestConfig()
221	opensslCipherName := "ECDHE-RSA-AES128-SHA"
222	test := &clientTest{
223		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
224		args:   []string{"-cipher", opensslCipherName},
225		config: config,
226	}
227
228	runUTLSClientTestTLS12(t, test, hello)
229}
230
231func testUTLSHandshakeClientECDHE_RSA_AES256_CBC_SHA(t *testing.T, hello helloStrategy) {
232	config := getUTLSTestConfig()
233	opensslCipherName := "ECDHE-RSA-AES256-SHA"
234	test := &clientTest{
235		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
236		args:   []string{"-cipher", opensslCipherName},
237		config: config,
238	}
239
240	runUTLSClientTestTLS12(t, test, hello)
241}
242
243func testUTLSHandshakeClientECDHE_ECDSA_AES128_CBC_SHA(t *testing.T, hello helloStrategy) {
244	config := getUTLSTestConfig()
245	opensslCipherName := "ECDHE-ECDSA-AES128-SHA"
246	test := &clientTest{
247		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
248		args:   []string{"-cipher", opensslCipherName},
249		cert:   testECDSACertificate,
250		key:    testECDSAPrivateKey,
251		config: config,
252	}
253
254	runUTLSClientTestTLS12(t, test, hello)
255}
256
257func testUTLSHandshakeClientECDHE_ECDSA_AES256_CBC_SHA(t *testing.T, hello helloStrategy) {
258	config := getUTLSTestConfig()
259	opensslCipherName := "ECDHE-ECDSA-AES256-SHA"
260	test := &clientTest{
261		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
262		args:   []string{"-cipher", opensslCipherName},
263		cert:   testECDSACertificate,
264		key:    testECDSAPrivateKey,
265		config: config,
266	}
267
268	runUTLSClientTestTLS12(t, test, hello)
269}
270
271func testUTLSHandshakeClientRSA_AES128_GCM_SHA256(t *testing.T, hello helloStrategy) {
272	config := getUTLSTestConfig()
273	opensslCipherName := "AES128-GCM-SHA256"
274	test := &clientTest{
275		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
276		args:   []string{"-cipher", opensslCipherName},
277		config: config,
278	}
279
280	runUTLSClientTestTLS12(t, test, hello)
281}
282
283func testUTLSHandshakeClientECDHE_ECDSA_AES128_GCM_SHA256(t *testing.T, hello helloStrategy) {
284	config := getUTLSTestConfig()
285
286	opensslCipherName := "ECDHE-ECDSA-AES128-GCM-SHA256"
287	test := &clientTest{
288		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
289		args:   []string{"-cipher", opensslCipherName},
290		cert:   testECDSACertificate,
291		key:    testECDSAPrivateKey,
292		config: config,
293	}
294
295	runUTLSClientTestTLS12(t, test, hello)
296}
297
298func testUTLSHandshakeClientECDHE_RSA_AES128_GCM_SHA256(t *testing.T, hello helloStrategy) {
299	config := getUTLSTestConfig()
300
301	opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
302	test := &clientTest{
303		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
304		args:   []string{"-cipher", opensslCipherName},
305		config: config,
306	}
307
308	runUTLSClientTestTLS12(t, test, hello)
309}
310
311func testUTLSHandshakeClientECDHE_ECDSA_AES256_GCM_SHA256(t *testing.T, hello helloStrategy) {
312	config := getUTLSTestConfig()
313	opensslCipherName := "ECDHE-ECDSA-AES256-GCM-SHA256"
314	test := &clientTest{
315		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
316		args:   []string{"-cipher", opensslCipherName},
317		cert:   testECDSACertificate,
318		key:    testECDSAPrivateKey,
319		config: config,
320	}
321
322	runUTLSClientTestTLS12(t, test, hello)
323}
324
325func testUTLSHandshakeClientECDHE_RSA_AES256_GCM_SHA256(t *testing.T, hello helloStrategy) {
326	config := getUTLSTestConfig()
327	opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
328	test := &clientTest{
329		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
330		args:   []string{"-cipher", opensslCipherName},
331		config: config,
332	}
333
334	runUTLSClientTestTLS12(t, test, hello)
335}
336
337func testUTLSHandshakeClientTLS13_AES_128_GCM_SHA256(t *testing.T, hello helloStrategy) {
338	config := getUTLSTestConfig()
339
340	opensslCipherName := "TLS_AES_128_GCM_SHA256"
341	test := &clientTest{
342		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
343		args:   []string{"-ciphersuites", opensslCipherName},
344		config: config,
345	}
346
347	runUTLSClientTestTLS13(t, test, hello)
348}
349
350func testUTLSHandshakeClientTLS13_AES_256_GCM_SHA384(t *testing.T, hello helloStrategy) {
351	config := getUTLSTestConfig()
352
353	opensslCipherName := "TLS_AES_256_GCM_SHA384"
354	test := &clientTest{
355		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
356		args:   []string{"-ciphersuites", opensslCipherName},
357		config: config,
358	}
359
360	runUTLSClientTestTLS13(t, test, hello)
361}
362
363func testUTLSHandshakeClientTLS13_CHACHA20_POLY1305_SHA256(t *testing.T, hello helloStrategy) {
364	config := getUTLSTestConfig()
365
366	opensslCipherName := "TLS_CHACHA20_POLY1305_SHA256"
367	test := &clientTest{
368		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
369		args:   []string{"-ciphersuites", opensslCipherName},
370		config: config,
371	}
372
373	runUTLSClientTestTLS13(t, test, hello)
374}
375
376func testUTLSHandshakeClientECDHE_RSA_WITH_CHACHA20_POLY1305(t *testing.T, hello helloStrategy) {
377	config := getUTLSTestConfig()
378	config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305}
379	opensslCipherName := "ECDHE-RSA-CHACHA20-POLY1305"
380	test := &clientTest{
381		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
382		args:   []string{"-cipher", opensslCipherName},
383		config: config,
384	}
385
386	runUTLSClientTestTLS12(t, test, hello)
387}
388
389func testUTLSHandshakeClientECDHE_ECDSA_WITH_CHACHA20_POLY1305(t *testing.T, hello helloStrategy) {
390	config := getUTLSTestConfig()
391	config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305}
392	opensslCipherName := "ECDHE-ECDSA-CHACHA20-POLY1305"
393	test := &clientTest{
394		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
395		args:   []string{"-cipher", opensslCipherName},
396		config: config,
397		cert:   testECDSACertificate,
398		key:    testECDSAPrivateKey,
399	}
400
401	runUTLSClientTestTLS12(t, test, hello)
402}
403
404func runUTLSClientTestForVersion(t *testing.T, template *clientTest, prefix, option string, hello helloStrategy, omitSNI bool) {
405	test := *template
406	test.name = prefix + test.name
407	if len(test.args) == 0 {
408		test.args = defaultClientCommand
409	}
410	test.args = append([]string(nil), test.args...)
411	test.args = append(test.args, option)
412	test.runUTLS(t, *update, hello, omitSNI)
413}
414
415func runUTLSClientTestTLS12(t *testing.T, template *clientTest, hello helloStrategy) {
416	runUTLSClientTestForVersion(t, template, "TLSv12-", "-tls1_2", hello, false)
417}
418
419func runUTLSClientTestTLS13(t *testing.T, template *clientTest, hello helloStrategy) {
420	runUTLSClientTestForVersion(t, template, "TLSv13-", "-tls1_3", hello, false)
421}
422
423func (test *clientTest) runUTLS(t *testing.T, write bool, hello helloStrategy, omitSNIExtension bool) {
424	checkOpenSSLVersion(t)
425
426	var clientConn, serverConn net.Conn
427	var recordingConn *recordingConn
428	var childProcess *exec.Cmd
429	var stdin opensslInput
430	var stdout *opensslOutputSink
431
432	if write {
433		var err error
434		recordingConn, childProcess, stdin, stdout, err = test.connFromCommand()
435		if err != nil {
436			t.Fatalf("Failed to start subcommand: %s", err)
437		}
438		clientConn = recordingConn
439	} else {
440		clientConn, serverConn = localPipe(t)
441	}
442
443	config := test.config
444	if config == nil {
445		t.Error("Explicit config is mandatory")
446		return
447	}
448
449	var client *UConn
450	switch h := hello.(type) {
451	case *helloID:
452		client = UClient(clientConn, config, h.id)
453	case *helloSpec:
454		client = UClient(clientConn, config, HelloCustom)
455		if err := client.ApplyPreset(h.spec); err != nil {
456			t.Errorf("got error: %v; expected to succeed", err)
457			return
458		}
459	default:
460		panic("unknown helloStrategy")
461	}
462
463	if omitSNIExtension {
464		if err := client.RemoveSNIExtension(); err != nil {
465			t.Error("Failed to remove SNI extension")
466			return
467		}
468	}
469
470	if strings.HasPrefix(test.name, "TLSv12-UTLS-setclienthello-") {
471		err := client.BuildHandshakeState()
472		if err != nil {
473			t.Errorf("Client.BuildHandshakeState() failed: %s", err)
474			return
475		}
476		// TODO: fix this name hack if we ever decide to use non-standard testing object
477		err = client.SetClientRandom([]byte("Custom ClientRandom h^xbw8bf0sn3"))
478		if err != nil {
479			t.Errorf("Client.SetClientRandom() failed: %s", err)
480			return
481		}
482	}
483
484	doneChan := make(chan bool)
485	go func() {
486		defer func() {
487			// Give time to the send buffer to drain, to avoid the kernel
488			// sending a RST and cutting off the flow. See Issue 18701.
489			time.Sleep(10 * time.Millisecond)
490			client.Close()
491			clientConn.Close()
492			doneChan <- true
493		}()
494
495		if _, err := client.Write([]byte("hello\n")); err != nil {
496			t.Errorf("Client.Write failed: %s", err)
497			return
498		}
499
500		for i := 1; i <= test.numRenegotiations; i++ {
501			// The initial handshake will generate a
502			// handshakeComplete signal which needs to be quashed.
503			if i == 1 && write {
504				<-stdout.handshakeComplete
505			}
506
507			// OpenSSL will try to interleave application data and
508			// a renegotiation if we send both concurrently.
509			// Therefore: ask OpensSSL to start a renegotiation, run
510			// a goroutine to call client.Read and thus process the
511			// renegotiation request, watch for OpenSSL's stdout to
512			// indicate that the handshake is complete and,
513			// finally, have OpenSSL write something to cause
514			// client.Read to complete.
515			if write {
516				stdin <- opensslRenegotiate
517			}
518
519			signalChan := make(chan struct{})
520
521			go func() {
522				defer close(signalChan)
523
524				buf := make([]byte, 256)
525				n, err := client.Read(buf)
526
527				if test.checkRenegotiationError != nil {
528					newErr := test.checkRenegotiationError(i, err)
529					if err != nil && newErr == nil {
530						return
531					}
532					err = newErr
533				}
534
535				if err != nil {
536					t.Errorf("Client.Read failed after renegotiation #%d: %s", i, err)
537					return
538				}
539
540				buf = buf[:n]
541				if !bytes.Equal([]byte(opensslSentinel), buf) {
542					t.Errorf("Client.Read returned %q, but wanted %q", string(buf), opensslSentinel)
543				}
544
545				if expected := i + 1; client.handshakes != expected {
546					t.Errorf("client should have recorded %d handshakes, but believes that %d have occurred", expected, client.handshakes)
547				}
548			}()
549
550			if write && test.renegotiationExpectedToFail != i {
551				<-stdout.handshakeComplete
552				stdin <- opensslSendSentinel
553			}
554			<-signalChan
555		}
556
557		if test.sendKeyUpdate {
558			if write {
559				<-stdout.handshakeComplete
560				stdin <- opensslKeyUpdate
561			}
562
563			doneRead := make(chan struct{})
564
565			go func() {
566				defer close(doneRead)
567
568				buf := make([]byte, 256)
569				n, err := client.Read(buf)
570
571				if err != nil {
572					t.Errorf("Client.Read failed after KeyUpdate: %s", err)
573					return
574				}
575
576				buf = buf[:n]
577				if !bytes.Equal([]byte(opensslSentinel), buf) {
578					t.Errorf("Client.Read returned %q, but wanted %q", string(buf), opensslSentinel)
579				}
580			}()
581
582			if write {
583				// There's no real reason to wait for the client KeyUpdate to
584				// send data with the new server keys, except that s_server
585				// drops writes if they are sent at the wrong time.
586				<-stdout.readKeyUpdate
587				stdin <- opensslSendSentinel
588			}
589			<-doneRead
590
591			if _, err := client.Write([]byte("hello again\n")); err != nil {
592				t.Errorf("Client.Write failed: %s", err)
593				return
594			}
595		}
596
597		if test.validate != nil {
598			if err := test.validate(client.ConnectionState()); err != nil {
599				t.Errorf("validate callback returned error: %s", err)
600			}
601		}
602
603		// If the server sent us an alert after our last flight, give it a
604		// chance to arrive.
605		if write && test.renegotiationExpectedToFail == 0 {
606			client.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
607			if _, err := client.Read(make([]byte, 1)); err != nil {
608				if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() {
609					t.Errorf("final Read returned an error: %s", err)
610				}
611			}
612		}
613	}()
614
615	if !write {
616		flows, err := test.loadData()
617		if err != nil {
618			t.Fatalf("%s: failed to load data from %s: %v", test.name, test.dataPath(), err)
619		}
620		for i, b := range flows {
621			if i%2 == 1 {
622				serverConn.SetWriteDeadline(time.Now().Add(1 * time.Minute))
623				serverConn.Write(b)
624				continue
625			}
626			bb := make([]byte, len(b))
627			serverConn.SetReadDeadline(time.Now().Add(1 * time.Minute))
628			_, err := io.ReadFull(serverConn, bb)
629			if err != nil {
630				t.Fatalf("%s #%d: %s", test.name, i, err)
631			}
632			if !bytes.Equal(b, bb) {
633				t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i, bb, b)
634			}
635		}
636		// Give time to the send buffer to drain, to avoid the kernel
637		// sending a RST and cutting off the flow. See Issue 18701.
638		time.Sleep(10 * time.Millisecond)
639		serverConn.Close()
640	}
641
642	<-doneChan
643
644	if write {
645		path := test.dataPath()
646		out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
647		if err != nil {
648			t.Fatalf("Failed to create output file: %s", err)
649		}
650		defer out.Close()
651		recordingConn.Close()
652		close(stdin)
653		childProcess.Process.Kill()
654		childProcess.Wait()
655		if len(recordingConn.flows) < 3 {
656			os.Stdout.Write(stdout.all)
657			t.Fatalf("Client connection didn't work")
658		}
659		recordingConn.WriteTo(out)
660		fmt.Printf("Wrote %s\n", path)
661	}
662}
663
664func TestUTLSMakeConnWithCompleteHandshake(t *testing.T) {
665	serverConn, clientConn := net.Pipe()
666
667	masterSecret := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}
668	clientRandom := []byte{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71}
669	serverRandom := []byte{80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111}
670	serverTls := MakeConnWithCompleteHandshake(serverConn, tls.VersionTLS12, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
671		masterSecret, clientRandom, serverRandom, false)
672	clientTls := MakeConnWithCompleteHandshake(clientConn, tls.VersionTLS12, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
673		masterSecret, clientRandom, serverRandom, true)
674
675	clientMsg := []byte("Hello, world!")
676	serverMsg := []byte("Test response!")
677
678	go func() {
679		clientTls.Write(clientMsg)
680		resp := make([]byte, 20)
681		read, err := clientTls.Read(resp)
682		if !bytes.Equal(resp[:read], serverMsg) {
683			t.Errorf("client expected to receive: %v, got %v\n",
684				serverMsg, resp[:read])
685		}
686		if err != nil {
687			t.Errorf("error reading client: %+v\n", err)
688		}
689		clientConn.Close()
690	}()
691
692	buf := make([]byte, 20)
693	read, err := serverTls.Read(buf)
694	if !bytes.Equal(buf[:read], clientMsg) {
695		t.Errorf("server expected to receive: %v, got %v\n",
696			clientMsg, buf[:read])
697	}
698	if err != nil {
699		t.Errorf("error reading client: %+v\n", err)
700	}
701
702	serverTls.Write(serverMsg)
703}
704