github.com/Carcraftz/utls@v0.0.0-20220413235215-6b7c52fd78b6/u_conn_test.go (about)

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