github.com/euank/go@v0.0.0-20160829210321-495514729181/src/crypto/tls/handshake_client_test.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "bytes" 9 "crypto/ecdsa" 10 "crypto/rsa" 11 "crypto/x509" 12 "encoding/base64" 13 "encoding/binary" 14 "encoding/pem" 15 "errors" 16 "fmt" 17 "io" 18 "net" 19 "os" 20 "os/exec" 21 "path/filepath" 22 "strconv" 23 "strings" 24 "testing" 25 "time" 26 ) 27 28 // Note: see comment in handshake_test.go for details of how the reference 29 // tests work. 30 31 // opensslInputEvent enumerates possible inputs that can be sent to an `openssl 32 // s_client` process. 33 type opensslInputEvent int 34 35 const ( 36 // opensslRenegotiate causes OpenSSL to request a renegotiation of the 37 // connection. 38 opensslRenegotiate opensslInputEvent = iota 39 40 // opensslSendBanner causes OpenSSL to send the contents of 41 // opensslSentinel on the connection. 42 opensslSendSentinel 43 ) 44 45 const opensslSentinel = "SENTINEL\n" 46 47 type opensslInput chan opensslInputEvent 48 49 func (i opensslInput) Read(buf []byte) (n int, err error) { 50 for event := range i { 51 switch event { 52 case opensslRenegotiate: 53 return copy(buf, []byte("R\n")), nil 54 case opensslSendSentinel: 55 return copy(buf, []byte(opensslSentinel)), nil 56 default: 57 panic("unknown event") 58 } 59 } 60 61 return 0, io.EOF 62 } 63 64 // opensslOutputSink is an io.Writer that receives the stdout and stderr from 65 // an `openssl` process and sends a value to handshakeComplete when it sees a 66 // log message from a completed server handshake. 67 type opensslOutputSink struct { 68 handshakeComplete chan struct{} 69 all []byte 70 line []byte 71 } 72 73 func newOpensslOutputSink() *opensslOutputSink { 74 return &opensslOutputSink{make(chan struct{}), nil, nil} 75 } 76 77 // opensslEndOfHandshake is a message that the “openssl s_server” tool will 78 // print when a handshake completes if run with “-state”. 79 const opensslEndOfHandshake = "SSL_accept:SSLv3 write finished A" 80 81 func (o *opensslOutputSink) Write(data []byte) (n int, err error) { 82 o.line = append(o.line, data...) 83 o.all = append(o.all, data...) 84 85 for { 86 i := bytes.Index(o.line, []byte{'\n'}) 87 if i < 0 { 88 break 89 } 90 91 if bytes.Equal([]byte(opensslEndOfHandshake), o.line[:i]) { 92 o.handshakeComplete <- struct{}{} 93 } 94 o.line = o.line[i+1:] 95 } 96 97 return len(data), nil 98 } 99 100 func (o *opensslOutputSink) WriteTo(w io.Writer) (int64, error) { 101 n, err := w.Write(o.all) 102 return int64(n), err 103 } 104 105 // clientTest represents a test of the TLS client handshake against a reference 106 // implementation. 107 type clientTest struct { 108 // name is a freeform string identifying the test and the file in which 109 // the expected results will be stored. 110 name string 111 // command, if not empty, contains a series of arguments for the 112 // command to run for the reference server. 113 command []string 114 // config, if not nil, contains a custom Config to use for this test. 115 config *Config 116 // cert, if not empty, contains a DER-encoded certificate for the 117 // reference server. 118 cert []byte 119 // key, if not nil, contains either a *rsa.PrivateKey or 120 // *ecdsa.PrivateKey which is the private key for the reference server. 121 key interface{} 122 // extensions, if not nil, contains a list of extension data to be returned 123 // from the ServerHello. The data should be in standard TLS format with 124 // a 2-byte uint16 type, 2-byte data length, followed by the extension data. 125 extensions [][]byte 126 // validate, if not nil, is a function that will be called with the 127 // ConnectionState of the resulting connection. It returns a non-nil 128 // error if the ConnectionState is unacceptable. 129 validate func(ConnectionState) error 130 // numRenegotiations is the number of times that the connection will be 131 // renegotiated. 132 numRenegotiations int 133 // renegotiationExpectedToFail, if not zero, is the number of the 134 // renegotiation attempt that is expected to fail. 135 renegotiationExpectedToFail int 136 // checkRenegotiationError, if not nil, is called with any error 137 // arising from renegotiation. It can map expected errors to nil to 138 // ignore them. 139 checkRenegotiationError func(renegotiationNum int, err error) error 140 } 141 142 var defaultServerCommand = []string{"openssl", "s_server"} 143 144 // connFromCommand starts the reference server process, connects to it and 145 // returns a recordingConn for the connection. The stdin return value is an 146 // opensslInput for the stdin of the child process. It must be closed before 147 // Waiting for child. 148 func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin opensslInput, stdout *opensslOutputSink, err error) { 149 cert := testRSACertificate 150 if len(test.cert) > 0 { 151 cert = test.cert 152 } 153 certPath := tempFile(string(cert)) 154 defer os.Remove(certPath) 155 156 var key interface{} = testRSAPrivateKey 157 if test.key != nil { 158 key = test.key 159 } 160 var pemType string 161 var derBytes []byte 162 switch key := key.(type) { 163 case *rsa.PrivateKey: 164 pemType = "RSA" 165 derBytes = x509.MarshalPKCS1PrivateKey(key) 166 case *ecdsa.PrivateKey: 167 pemType = "EC" 168 var err error 169 derBytes, err = x509.MarshalECPrivateKey(key) 170 if err != nil { 171 panic(err) 172 } 173 default: 174 panic("unknown key type") 175 } 176 177 var pemOut bytes.Buffer 178 pem.Encode(&pemOut, &pem.Block{Type: pemType + " PRIVATE KEY", Bytes: derBytes}) 179 180 keyPath := tempFile(string(pemOut.Bytes())) 181 defer os.Remove(keyPath) 182 183 var command []string 184 if len(test.command) > 0 { 185 command = append(command, test.command...) 186 } else { 187 command = append(command, defaultServerCommand...) 188 } 189 command = append(command, "-cert", certPath, "-certform", "DER", "-key", keyPath) 190 // serverPort contains the port that OpenSSL will listen on. OpenSSL 191 // can't take "0" as an argument here so we have to pick a number and 192 // hope that it's not in use on the machine. Since this only occurs 193 // when -update is given and thus when there's a human watching the 194 // test, this isn't too bad. 195 const serverPort = 24323 196 command = append(command, "-accept", strconv.Itoa(serverPort)) 197 198 if len(test.extensions) > 0 { 199 var serverInfo bytes.Buffer 200 for _, ext := range test.extensions { 201 pem.Encode(&serverInfo, &pem.Block{ 202 Type: fmt.Sprintf("SERVERINFO FOR EXTENSION %d", binary.BigEndian.Uint16(ext)), 203 Bytes: ext, 204 }) 205 } 206 serverInfoPath := tempFile(serverInfo.String()) 207 defer os.Remove(serverInfoPath) 208 command = append(command, "-serverinfo", serverInfoPath) 209 } 210 211 if test.numRenegotiations > 0 { 212 found := false 213 for _, flag := range command[1:] { 214 if flag == "-state" { 215 found = true 216 break 217 } 218 } 219 220 if !found { 221 panic("-state flag missing to OpenSSL. You need this if testing renegotiation") 222 } 223 } 224 225 cmd := exec.Command(command[0], command[1:]...) 226 stdin = opensslInput(make(chan opensslInputEvent)) 227 cmd.Stdin = stdin 228 out := newOpensslOutputSink() 229 cmd.Stdout = out 230 cmd.Stderr = out 231 if err := cmd.Start(); err != nil { 232 return nil, nil, nil, nil, err 233 } 234 235 // OpenSSL does print an "ACCEPT" banner, but it does so *before* 236 // opening the listening socket, so we can't use that to wait until it 237 // has started listening. Thus we are forced to poll until we get a 238 // connection. 239 var tcpConn net.Conn 240 for i := uint(0); i < 5; i++ { 241 tcpConn, err = net.DialTCP("tcp", nil, &net.TCPAddr{ 242 IP: net.IPv4(127, 0, 0, 1), 243 Port: serverPort, 244 }) 245 if err == nil { 246 break 247 } 248 time.Sleep((1 << i) * 5 * time.Millisecond) 249 } 250 if err != nil { 251 close(stdin) 252 out.WriteTo(os.Stdout) 253 cmd.Process.Kill() 254 return nil, nil, nil, nil, cmd.Wait() 255 } 256 257 record := &recordingConn{ 258 Conn: tcpConn, 259 } 260 261 return record, cmd, stdin, out, nil 262 } 263 264 func (test *clientTest) dataPath() string { 265 return filepath.Join("testdata", "Client-"+test.name) 266 } 267 268 func (test *clientTest) loadData() (flows [][]byte, err error) { 269 in, err := os.Open(test.dataPath()) 270 if err != nil { 271 return nil, err 272 } 273 defer in.Close() 274 return parseTestData(in) 275 } 276 277 func (test *clientTest) run(t *testing.T, write bool) { 278 var clientConn, serverConn net.Conn 279 var recordingConn *recordingConn 280 var childProcess *exec.Cmd 281 var stdin opensslInput 282 var stdout *opensslOutputSink 283 284 if write { 285 var err error 286 recordingConn, childProcess, stdin, stdout, err = test.connFromCommand() 287 if err != nil { 288 t.Fatalf("Failed to start subcommand: %s", err) 289 } 290 clientConn = recordingConn 291 } else { 292 clientConn, serverConn = net.Pipe() 293 } 294 295 config := test.config 296 if config == nil { 297 config = testConfig 298 } 299 client := Client(clientConn, config) 300 301 doneChan := make(chan bool) 302 go func() { 303 defer func() { doneChan <- true }() 304 defer clientConn.Close() 305 defer client.Close() 306 307 if _, err := client.Write([]byte("hello\n")); err != nil { 308 t.Errorf("Client.Write failed: %s", err) 309 return 310 } 311 312 for i := 1; i <= test.numRenegotiations; i++ { 313 // The initial handshake will generate a 314 // handshakeComplete signal which needs to be quashed. 315 if i == 1 && write { 316 <-stdout.handshakeComplete 317 } 318 319 // OpenSSL will try to interleave application data and 320 // a renegotiation if we send both concurrently. 321 // Therefore: ask OpensSSL to start a renegotiation, run 322 // a goroutine to call client.Read and thus process the 323 // renegotiation request, watch for OpenSSL's stdout to 324 // indicate that the handshake is complete and, 325 // finally, have OpenSSL write something to cause 326 // client.Read to complete. 327 if write { 328 stdin <- opensslRenegotiate 329 } 330 331 signalChan := make(chan struct{}) 332 333 go func() { 334 defer func() { signalChan <- struct{}{} }() 335 336 buf := make([]byte, 256) 337 n, err := client.Read(buf) 338 339 if test.checkRenegotiationError != nil { 340 newErr := test.checkRenegotiationError(i, err) 341 if err != nil && newErr == nil { 342 return 343 } 344 err = newErr 345 } 346 347 if err != nil { 348 t.Errorf("Client.Read failed after renegotiation #%d: %s", i, err) 349 return 350 } 351 352 buf = buf[:n] 353 if !bytes.Equal([]byte(opensslSentinel), buf) { 354 t.Errorf("Client.Read returned %q, but wanted %q", string(buf), opensslSentinel) 355 } 356 357 if expected := i + 1; client.handshakes != expected { 358 t.Errorf("client should have recorded %d handshakes, but believes that %d have occured", expected, client.handshakes) 359 } 360 }() 361 362 if write && test.renegotiationExpectedToFail != i { 363 <-stdout.handshakeComplete 364 stdin <- opensslSendSentinel 365 } 366 <-signalChan 367 } 368 369 if test.validate != nil { 370 if err := test.validate(client.ConnectionState()); err != nil { 371 t.Errorf("validate callback returned error: %s", err) 372 } 373 } 374 }() 375 376 if !write { 377 flows, err := test.loadData() 378 if err != nil { 379 t.Fatalf("%s: failed to load data from %s: %v", test.name, test.dataPath(), err) 380 } 381 for i, b := range flows { 382 if i%2 == 1 { 383 serverConn.Write(b) 384 continue 385 } 386 bb := make([]byte, len(b)) 387 _, err := io.ReadFull(serverConn, bb) 388 if err != nil { 389 t.Fatalf("%s #%d: %s", test.name, i, err) 390 } 391 if !bytes.Equal(b, bb) { 392 t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i, bb, b) 393 } 394 } 395 serverConn.Close() 396 } 397 398 <-doneChan 399 400 if write { 401 path := test.dataPath() 402 out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 403 if err != nil { 404 t.Fatalf("Failed to create output file: %s", err) 405 } 406 defer out.Close() 407 recordingConn.Close() 408 close(stdin) 409 childProcess.Process.Kill() 410 childProcess.Wait() 411 if len(recordingConn.flows) < 3 { 412 childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout) 413 t.Fatalf("Client connection didn't work") 414 } 415 recordingConn.WriteTo(out) 416 fmt.Printf("Wrote %s\n", path) 417 } 418 } 419 420 func runClientTestForVersion(t *testing.T, template *clientTest, prefix, option string) { 421 test := *template 422 test.name = prefix + test.name 423 if len(test.command) == 0 { 424 test.command = defaultClientCommand 425 } 426 test.command = append([]string(nil), test.command...) 427 test.command = append(test.command, option) 428 test.run(t, *update) 429 } 430 431 func runClientTestTLS10(t *testing.T, template *clientTest) { 432 runClientTestForVersion(t, template, "TLSv10-", "-tls1") 433 } 434 435 func runClientTestTLS11(t *testing.T, template *clientTest) { 436 runClientTestForVersion(t, template, "TLSv11-", "-tls1_1") 437 } 438 439 func runClientTestTLS12(t *testing.T, template *clientTest) { 440 runClientTestForVersion(t, template, "TLSv12-", "-tls1_2") 441 } 442 443 func TestHandshakeClientRSARC4(t *testing.T) { 444 test := &clientTest{ 445 name: "RSA-RC4", 446 command: []string{"openssl", "s_server", "-cipher", "RC4-SHA"}, 447 } 448 runClientTestTLS10(t, test) 449 runClientTestTLS11(t, test) 450 runClientTestTLS12(t, test) 451 } 452 453 func TestHandshakeClientRSAAES128GCM(t *testing.T) { 454 test := &clientTest{ 455 name: "AES128-GCM-SHA256", 456 command: []string{"openssl", "s_server", "-cipher", "AES128-GCM-SHA256"}, 457 } 458 runClientTestTLS12(t, test) 459 } 460 461 func TestHandshakeClientRSAAES256GCM(t *testing.T) { 462 test := &clientTest{ 463 name: "AES256-GCM-SHA384", 464 command: []string{"openssl", "s_server", "-cipher", "AES256-GCM-SHA384"}, 465 } 466 runClientTestTLS12(t, test) 467 } 468 469 func TestHandshakeClientECDHERSAAES(t *testing.T) { 470 test := &clientTest{ 471 name: "ECDHE-RSA-AES", 472 command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES128-SHA"}, 473 } 474 runClientTestTLS10(t, test) 475 runClientTestTLS11(t, test) 476 runClientTestTLS12(t, test) 477 } 478 479 func TestHandshakeClientECDHEECDSAAES(t *testing.T) { 480 test := &clientTest{ 481 name: "ECDHE-ECDSA-AES", 482 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA"}, 483 cert: testECDSACertificate, 484 key: testECDSAPrivateKey, 485 } 486 runClientTestTLS10(t, test) 487 runClientTestTLS11(t, test) 488 runClientTestTLS12(t, test) 489 } 490 491 func TestHandshakeClientECDHEECDSAAESGCM(t *testing.T) { 492 test := &clientTest{ 493 name: "ECDHE-ECDSA-AES-GCM", 494 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-GCM-SHA256"}, 495 cert: testECDSACertificate, 496 key: testECDSAPrivateKey, 497 } 498 runClientTestTLS12(t, test) 499 } 500 501 func TestHandshakeClientAES256GCMSHA384(t *testing.T) { 502 test := &clientTest{ 503 name: "ECDHE-ECDSA-AES256-GCM-SHA384", 504 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES256-GCM-SHA384"}, 505 cert: testECDSACertificate, 506 key: testECDSAPrivateKey, 507 } 508 runClientTestTLS12(t, test) 509 } 510 511 func TestHandshakeClientAES128CBCSHA256(t *testing.T) { 512 test := &clientTest{ 513 name: "AES128-SHA256", 514 command: []string{"openssl", "s_server", "-cipher", "AES128-SHA256"}, 515 } 516 runClientTestTLS12(t, test) 517 } 518 519 func TestHandshakeClientECDHERSAAES128CBCSHA256(t *testing.T) { 520 test := &clientTest{ 521 name: "ECDHE-RSA-AES128-SHA256", 522 command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES128-SHA256"}, 523 } 524 runClientTestTLS12(t, test) 525 } 526 527 func TestHandshakeClientECDHEECDSAAES128CBCSHA256(t *testing.T) { 528 test := &clientTest{ 529 name: "ECDHE-ECDSA-AES128-SHA256", 530 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA256"}, 531 cert: testECDSACertificate, 532 key: testECDSAPrivateKey, 533 } 534 runClientTestTLS12(t, test) 535 } 536 537 func TestHandshakeClientCertRSA(t *testing.T) { 538 config := testConfig.clone() 539 cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM)) 540 config.Certificates = []Certificate{cert} 541 542 test := &clientTest{ 543 name: "ClientCert-RSA-RSA", 544 command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"}, 545 config: config, 546 } 547 548 runClientTestTLS10(t, test) 549 runClientTestTLS12(t, test) 550 551 test = &clientTest{ 552 name: "ClientCert-RSA-ECDSA", 553 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"}, 554 config: config, 555 cert: testECDSACertificate, 556 key: testECDSAPrivateKey, 557 } 558 559 runClientTestTLS10(t, test) 560 runClientTestTLS12(t, test) 561 562 test = &clientTest{ 563 name: "ClientCert-RSA-AES256-GCM-SHA384", 564 command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384", "-verify", "1"}, 565 config: config, 566 cert: testRSACertificate, 567 key: testRSAPrivateKey, 568 } 569 570 runClientTestTLS12(t, test) 571 } 572 573 func TestHandshakeClientCertECDSA(t *testing.T) { 574 config := testConfig.clone() 575 cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM)) 576 config.Certificates = []Certificate{cert} 577 578 test := &clientTest{ 579 name: "ClientCert-ECDSA-RSA", 580 command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"}, 581 config: config, 582 } 583 584 runClientTestTLS10(t, test) 585 runClientTestTLS12(t, test) 586 587 test = &clientTest{ 588 name: "ClientCert-ECDSA-ECDSA", 589 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"}, 590 config: config, 591 cert: testECDSACertificate, 592 key: testECDSAPrivateKey, 593 } 594 595 runClientTestTLS10(t, test) 596 runClientTestTLS12(t, test) 597 } 598 599 func TestClientResumption(t *testing.T) { 600 serverConfig := &Config{ 601 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 602 Certificates: testConfig.Certificates, 603 } 604 605 issuer, err := x509.ParseCertificate(testRSACertificateIssuer) 606 if err != nil { 607 panic(err) 608 } 609 610 rootCAs := x509.NewCertPool() 611 rootCAs.AddCert(issuer) 612 613 clientConfig := &Config{ 614 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 615 ClientSessionCache: NewLRUClientSessionCache(32), 616 RootCAs: rootCAs, 617 ServerName: "example.golang", 618 } 619 620 testResumeState := func(test string, didResume bool) { 621 _, hs, err := testHandshake(clientConfig, serverConfig) 622 if err != nil { 623 t.Fatalf("%s: handshake failed: %s", test, err) 624 } 625 if hs.DidResume != didResume { 626 t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume) 627 } 628 if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) { 629 t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifiedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains) 630 } 631 } 632 633 getTicket := func() []byte { 634 return clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).state.sessionTicket 635 } 636 randomKey := func() [32]byte { 637 var k [32]byte 638 if _, err := io.ReadFull(serverConfig.rand(), k[:]); err != nil { 639 t.Fatalf("Failed to read new SessionTicketKey: %s", err) 640 } 641 return k 642 } 643 644 testResumeState("Handshake", false) 645 ticket := getTicket() 646 testResumeState("Resume", true) 647 if !bytes.Equal(ticket, getTicket()) { 648 t.Fatal("first ticket doesn't match ticket after resumption") 649 } 650 651 key1 := randomKey() 652 serverConfig.SetSessionTicketKeys([][32]byte{key1}) 653 654 testResumeState("InvalidSessionTicketKey", false) 655 testResumeState("ResumeAfterInvalidSessionTicketKey", true) 656 657 key2 := randomKey() 658 serverConfig.SetSessionTicketKeys([][32]byte{key2, key1}) 659 ticket = getTicket() 660 testResumeState("KeyChange", true) 661 if bytes.Equal(ticket, getTicket()) { 662 t.Fatal("new ticket wasn't included while resuming") 663 } 664 testResumeState("KeyChangeFinish", true) 665 666 // Reset serverConfig to ensure that calling SetSessionTicketKeys 667 // before the serverConfig is used works. 668 serverConfig = &Config{ 669 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 670 Certificates: testConfig.Certificates, 671 } 672 serverConfig.SetSessionTicketKeys([][32]byte{key2}) 673 674 testResumeState("FreshConfig", true) 675 676 clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA} 677 testResumeState("DifferentCipherSuite", false) 678 testResumeState("DifferentCipherSuiteRecovers", true) 679 680 clientConfig.ClientSessionCache = nil 681 testResumeState("WithoutSessionCache", false) 682 } 683 684 func TestLRUClientSessionCache(t *testing.T) { 685 // Initialize cache of capacity 4. 686 cache := NewLRUClientSessionCache(4) 687 cs := make([]ClientSessionState, 6) 688 keys := []string{"0", "1", "2", "3", "4", "5", "6"} 689 690 // Add 4 entries to the cache and look them up. 691 for i := 0; i < 4; i++ { 692 cache.Put(keys[i], &cs[i]) 693 } 694 for i := 0; i < 4; i++ { 695 if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] { 696 t.Fatalf("session cache failed lookup for added key: %s", keys[i]) 697 } 698 } 699 700 // Add 2 more entries to the cache. First 2 should be evicted. 701 for i := 4; i < 6; i++ { 702 cache.Put(keys[i], &cs[i]) 703 } 704 for i := 0; i < 2; i++ { 705 if s, ok := cache.Get(keys[i]); ok || s != nil { 706 t.Fatalf("session cache should have evicted key: %s", keys[i]) 707 } 708 } 709 710 // Touch entry 2. LRU should evict 3 next. 711 cache.Get(keys[2]) 712 cache.Put(keys[0], &cs[0]) 713 if s, ok := cache.Get(keys[3]); ok || s != nil { 714 t.Fatalf("session cache should have evicted key 3") 715 } 716 717 // Update entry 0 in place. 718 cache.Put(keys[0], &cs[3]) 719 if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] { 720 t.Fatalf("session cache failed update for key 0") 721 } 722 723 // Adding a nil entry is valid. 724 cache.Put(keys[0], nil) 725 if s, ok := cache.Get(keys[0]); !ok || s != nil { 726 t.Fatalf("failed to add nil entry to cache") 727 } 728 } 729 730 func TestHandshakeClientKeyLog(t *testing.T) { 731 config := testConfig.clone() 732 buf := &bytes.Buffer{} 733 config.KeyLogWriter = buf 734 735 // config.Rand is zero reader, so client random is all-0 736 var zeroRandom = strings.Repeat("0", 64) 737 738 test := &clientTest{ 739 name: "KeyLogWriter", 740 command: []string{"openssl", "s_server"}, 741 config: config, 742 validate: func(state ConnectionState) error { 743 var format, clientRandom, masterSecret string 744 if _, err := fmt.Fscanf(buf, "%s %s %s\n", &format, &clientRandom, &masterSecret); err != nil { 745 return fmt.Errorf("failed to parse KeyLogWriter: " + err.Error()) 746 } 747 if format != "CLIENT_RANDOM" { 748 return fmt.Errorf("got key log format %q, wanted CLIENT_RANDOM", format) 749 } 750 if clientRandom != zeroRandom { 751 return fmt.Errorf("got key log client random %q, wanted %q", clientRandom, zeroRandom) 752 } 753 754 // Master secret is random from server; check length only 755 if len(masterSecret) != 96 { 756 return fmt.Errorf("got wrong length master secret in key log %v, want 96", len(masterSecret)) 757 } 758 759 // buf should contain no more lines 760 var trailingGarbage string 761 if _, err := fmt.Fscanln(buf, &trailingGarbage); err == nil { 762 return fmt.Errorf("expected exactly one key in log, got trailing garbage %q", trailingGarbage) 763 } 764 765 return nil 766 }, 767 } 768 runClientTestTLS10(t, test) 769 } 770 771 func TestHandshakeClientALPNMatch(t *testing.T) { 772 config := testConfig.clone() 773 config.NextProtos = []string{"proto2", "proto1"} 774 775 test := &clientTest{ 776 name: "ALPN", 777 // Note that this needs OpenSSL 1.0.2 because that is the first 778 // version that supports the -alpn flag. 779 command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"}, 780 config: config, 781 validate: func(state ConnectionState) error { 782 // The server's preferences should override the client. 783 if state.NegotiatedProtocol != "proto1" { 784 return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol) 785 } 786 return nil 787 }, 788 } 789 runClientTestTLS12(t, test) 790 } 791 792 func TestHandshakeClientALPNNoMatch(t *testing.T) { 793 config := testConfig.clone() 794 config.NextProtos = []string{"proto3"} 795 796 test := &clientTest{ 797 name: "ALPN-NoMatch", 798 // Note that this needs OpenSSL 1.0.2 because that is the first 799 // version that supports the -alpn flag. 800 command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"}, 801 config: config, 802 validate: func(state ConnectionState) error { 803 // There's no overlap so OpenSSL will not select a protocol. 804 if state.NegotiatedProtocol != "" { 805 return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol) 806 } 807 return nil 808 }, 809 } 810 runClientTestTLS12(t, test) 811 } 812 813 // sctsBase64 contains data from `openssl s_client -serverinfo 18 -connect ritter.vg:443` 814 const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0=" 815 816 func TestHandshakClientSCTs(t *testing.T) { 817 config := testConfig.clone() 818 819 scts, err := base64.StdEncoding.DecodeString(sctsBase64) 820 if err != nil { 821 t.Fatal(err) 822 } 823 824 test := &clientTest{ 825 name: "SCT", 826 // Note that this needs OpenSSL 1.0.2 because that is the first 827 // version that supports the -serverinfo flag. 828 command: []string{"openssl", "s_server"}, 829 config: config, 830 extensions: [][]byte{scts}, 831 validate: func(state ConnectionState) error { 832 expectedSCTs := [][]byte{ 833 scts[8:125], 834 scts[127:245], 835 scts[247:], 836 } 837 if n := len(state.SignedCertificateTimestamps); n != len(expectedSCTs) { 838 return fmt.Errorf("Got %d scts, wanted %d", n, len(expectedSCTs)) 839 } 840 for i, expected := range expectedSCTs { 841 if sct := state.SignedCertificateTimestamps[i]; !bytes.Equal(sct, expected) { 842 return fmt.Errorf("SCT #%d contained %x, expected %x", i, sct, expected) 843 } 844 } 845 return nil 846 }, 847 } 848 runClientTestTLS12(t, test) 849 } 850 851 func TestRenegotiationRejected(t *testing.T) { 852 config := testConfig.clone() 853 test := &clientTest{ 854 name: "RenegotiationRejected", 855 command: []string{"openssl", "s_server", "-state"}, 856 config: config, 857 numRenegotiations: 1, 858 renegotiationExpectedToFail: 1, 859 checkRenegotiationError: func(renegotiationNum int, err error) error { 860 if err == nil { 861 return errors.New("expected error from renegotiation but got nil") 862 } 863 if !strings.Contains(err.Error(), "no renegotiation") { 864 return fmt.Errorf("expected renegotiation to be rejected but got %q", err) 865 } 866 return nil 867 }, 868 } 869 870 runClientTestTLS12(t, test) 871 } 872 873 func TestRenegotiateOnce(t *testing.T) { 874 config := testConfig.clone() 875 config.Renegotiation = RenegotiateOnceAsClient 876 877 test := &clientTest{ 878 name: "RenegotiateOnce", 879 command: []string{"openssl", "s_server", "-state"}, 880 config: config, 881 numRenegotiations: 1, 882 } 883 884 runClientTestTLS12(t, test) 885 } 886 887 func TestRenegotiateTwice(t *testing.T) { 888 config := testConfig.clone() 889 config.Renegotiation = RenegotiateFreelyAsClient 890 891 test := &clientTest{ 892 name: "RenegotiateTwice", 893 command: []string{"openssl", "s_server", "-state"}, 894 config: config, 895 numRenegotiations: 2, 896 } 897 898 runClientTestTLS12(t, test) 899 } 900 901 func TestRenegotiateTwiceRejected(t *testing.T) { 902 config := testConfig.clone() 903 config.Renegotiation = RenegotiateOnceAsClient 904 905 test := &clientTest{ 906 name: "RenegotiateTwiceRejected", 907 command: []string{"openssl", "s_server", "-state"}, 908 config: config, 909 numRenegotiations: 2, 910 renegotiationExpectedToFail: 2, 911 checkRenegotiationError: func(renegotiationNum int, err error) error { 912 if renegotiationNum == 1 { 913 return err 914 } 915 916 if err == nil { 917 return errors.New("expected error from renegotiation but got nil") 918 } 919 if !strings.Contains(err.Error(), "no renegotiation") { 920 return fmt.Errorf("expected renegotiation to be rejected but got %q", err) 921 } 922 return nil 923 }, 924 } 925 926 runClientTestTLS12(t, test) 927 } 928 929 var hostnameInSNITests = []struct { 930 in, out string 931 }{ 932 // Opaque string 933 {"", ""}, 934 {"localhost", "localhost"}, 935 {"foo, bar, baz and qux", "foo, bar, baz and qux"}, 936 937 // DNS hostname 938 {"golang.org", "golang.org"}, 939 {"golang.org.", "golang.org"}, 940 941 // Literal IPv4 address 942 {"1.2.3.4", ""}, 943 944 // Literal IPv6 address 945 {"::1", ""}, 946 {"::1%lo0", ""}, // with zone identifier 947 {"[::1]", ""}, // as per RFC 5952 we allow the [] style as IPv6 literal 948 {"[::1%lo0]", ""}, 949 } 950 951 func TestHostnameInSNI(t *testing.T) { 952 for _, tt := range hostnameInSNITests { 953 c, s := net.Pipe() 954 955 go func(host string) { 956 Client(c, &Config{ServerName: host, InsecureSkipVerify: true}).Handshake() 957 }(tt.in) 958 959 var header [5]byte 960 if _, err := io.ReadFull(s, header[:]); err != nil { 961 t.Fatal(err) 962 } 963 recordLen := int(header[3])<<8 | int(header[4]) 964 965 record := make([]byte, recordLen) 966 if _, err := io.ReadFull(s, record[:]); err != nil { 967 t.Fatal(err) 968 } 969 970 c.Close() 971 s.Close() 972 973 var m clientHelloMsg 974 if !m.unmarshal(record) { 975 t.Errorf("unmarshaling ClientHello for %q failed", tt.in) 976 continue 977 } 978 if tt.in != tt.out && m.serverName == tt.in { 979 t.Errorf("prohibited %q found in ClientHello: %x", tt.in, record) 980 } 981 if m.serverName != tt.out { 982 t.Errorf("expected %q not found in ClientHello: %x", tt.out, record) 983 } 984 } 985 } 986 987 func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) { 988 // This checks that the server can't select a cipher suite that the 989 // client didn't offer. See #13174. 990 991 c, s := net.Pipe() 992 errChan := make(chan error, 1) 993 994 go func() { 995 client := Client(c, &Config{ 996 ServerName: "foo", 997 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 998 }) 999 errChan <- client.Handshake() 1000 }() 1001 1002 var header [5]byte 1003 if _, err := io.ReadFull(s, header[:]); err != nil { 1004 t.Fatal(err) 1005 } 1006 recordLen := int(header[3])<<8 | int(header[4]) 1007 1008 record := make([]byte, recordLen) 1009 if _, err := io.ReadFull(s, record); err != nil { 1010 t.Fatal(err) 1011 } 1012 1013 // Create a ServerHello that selects a different cipher suite than the 1014 // sole one that the client offered. 1015 serverHello := &serverHelloMsg{ 1016 vers: VersionTLS12, 1017 random: make([]byte, 32), 1018 cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384, 1019 } 1020 serverHelloBytes := serverHello.marshal() 1021 1022 s.Write([]byte{ 1023 byte(recordTypeHandshake), 1024 byte(VersionTLS12 >> 8), 1025 byte(VersionTLS12 & 0xff), 1026 byte(len(serverHelloBytes) >> 8), 1027 byte(len(serverHelloBytes)), 1028 }) 1029 s.Write(serverHelloBytes) 1030 s.Close() 1031 1032 if err := <-errChan; !strings.Contains(err.Error(), "unconfigured cipher") { 1033 t.Fatalf("Expected error about unconfigured cipher suite but got %q", err) 1034 } 1035 } 1036 1037 // brokenConn wraps a net.Conn and causes all Writes after a certain number to 1038 // fail with brokenConnErr. 1039 type brokenConn struct { 1040 net.Conn 1041 1042 // breakAfter is the number of successful writes that will be allowed 1043 // before all subsequent writes fail. 1044 breakAfter int 1045 1046 // numWrites is the number of writes that have been done. 1047 numWrites int 1048 } 1049 1050 // brokenConnErr is the error that brokenConn returns once exhausted. 1051 var brokenConnErr = errors.New("too many writes to brokenConn") 1052 1053 func (b *brokenConn) Write(data []byte) (int, error) { 1054 if b.numWrites >= b.breakAfter { 1055 return 0, brokenConnErr 1056 } 1057 1058 b.numWrites++ 1059 return b.Conn.Write(data) 1060 } 1061 1062 func TestFailedWrite(t *testing.T) { 1063 // Test that a write error during the handshake is returned. 1064 for _, breakAfter := range []int{0, 1} { 1065 c, s := net.Pipe() 1066 done := make(chan bool) 1067 1068 go func() { 1069 Server(s, testConfig).Handshake() 1070 s.Close() 1071 done <- true 1072 }() 1073 1074 brokenC := &brokenConn{Conn: c, breakAfter: breakAfter} 1075 err := Client(brokenC, testConfig).Handshake() 1076 if err != brokenConnErr { 1077 t.Errorf("#%d: expected error from brokenConn but got %q", breakAfter, err) 1078 } 1079 brokenC.Close() 1080 1081 <-done 1082 } 1083 } 1084 1085 // writeCountingConn wraps a net.Conn and counts the number of Write calls. 1086 type writeCountingConn struct { 1087 net.Conn 1088 1089 // numWrites is the number of writes that have been done. 1090 numWrites int 1091 } 1092 1093 func (wcc *writeCountingConn) Write(data []byte) (int, error) { 1094 wcc.numWrites++ 1095 return wcc.Conn.Write(data) 1096 } 1097 1098 func TestBuffering(t *testing.T) { 1099 c, s := net.Pipe() 1100 done := make(chan bool) 1101 1102 clientWCC := &writeCountingConn{Conn: c} 1103 serverWCC := &writeCountingConn{Conn: s} 1104 1105 go func() { 1106 Server(serverWCC, testConfig).Handshake() 1107 serverWCC.Close() 1108 done <- true 1109 }() 1110 1111 err := Client(clientWCC, testConfig).Handshake() 1112 if err != nil { 1113 t.Fatal(err) 1114 } 1115 clientWCC.Close() 1116 <-done 1117 1118 if n := clientWCC.numWrites; n != 2 { 1119 t.Errorf("expected client handshake to complete with only two writes, but saw %d", n) 1120 } 1121 1122 if n := serverWCC.numWrites; n != 2 { 1123 t.Errorf("expected server handshake to complete with only two writes, but saw %d", n) 1124 } 1125 }