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