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