github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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 TestHandshakeClientCertRSA(t *testing.T) { 512 config := *testConfig 513 cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM)) 514 config.Certificates = []Certificate{cert} 515 516 test := &clientTest{ 517 name: "ClientCert-RSA-RSA", 518 command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"}, 519 config: &config, 520 } 521 522 runClientTestTLS10(t, test) 523 runClientTestTLS12(t, test) 524 525 test = &clientTest{ 526 name: "ClientCert-RSA-ECDSA", 527 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"}, 528 config: &config, 529 cert: testECDSACertificate, 530 key: testECDSAPrivateKey, 531 } 532 533 runClientTestTLS10(t, test) 534 runClientTestTLS12(t, test) 535 536 test = &clientTest{ 537 name: "ClientCert-RSA-AES256-GCM-SHA384", 538 command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384", "-verify", "1"}, 539 config: &config, 540 cert: testRSACertificate, 541 key: testRSAPrivateKey, 542 } 543 544 runClientTestTLS12(t, test) 545 } 546 547 func TestHandshakeClientCertECDSA(t *testing.T) { 548 config := *testConfig 549 cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM)) 550 config.Certificates = []Certificate{cert} 551 552 test := &clientTest{ 553 name: "ClientCert-ECDSA-RSA", 554 command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"}, 555 config: &config, 556 } 557 558 runClientTestTLS10(t, test) 559 runClientTestTLS12(t, test) 560 561 test = &clientTest{ 562 name: "ClientCert-ECDSA-ECDSA", 563 command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"}, 564 config: &config, 565 cert: testECDSACertificate, 566 key: testECDSAPrivateKey, 567 } 568 569 runClientTestTLS10(t, test) 570 runClientTestTLS12(t, test) 571 } 572 573 func TestClientResumption(t *testing.T) { 574 serverConfig := &Config{ 575 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 576 Certificates: testConfig.Certificates, 577 } 578 579 issuer, err := x509.ParseCertificate(testRSACertificateIssuer) 580 if err != nil { 581 panic(err) 582 } 583 584 rootCAs := x509.NewCertPool() 585 rootCAs.AddCert(issuer) 586 587 clientConfig := &Config{ 588 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 589 ClientSessionCache: NewLRUClientSessionCache(32), 590 RootCAs: rootCAs, 591 ServerName: "example.golang", 592 } 593 594 testResumeState := func(test string, didResume bool) { 595 _, hs, err := testHandshake(clientConfig, serverConfig) 596 if err != nil { 597 t.Fatalf("%s: handshake failed: %s", test, err) 598 } 599 if hs.DidResume != didResume { 600 t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume) 601 } 602 if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) { 603 t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifiedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains) 604 } 605 } 606 607 getTicket := func() []byte { 608 return clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).state.sessionTicket 609 } 610 randomKey := func() [32]byte { 611 var k [32]byte 612 if _, err := io.ReadFull(serverConfig.rand(), k[:]); err != nil { 613 t.Fatalf("Failed to read new SessionTicketKey: %s", err) 614 } 615 return k 616 } 617 618 testResumeState("Handshake", false) 619 ticket := getTicket() 620 testResumeState("Resume", true) 621 if !bytes.Equal(ticket, getTicket()) { 622 t.Fatal("first ticket doesn't match ticket after resumption") 623 } 624 625 key2 := randomKey() 626 serverConfig.SetSessionTicketKeys([][32]byte{key2}) 627 628 testResumeState("InvalidSessionTicketKey", false) 629 testResumeState("ResumeAfterInvalidSessionTicketKey", true) 630 631 serverConfig.SetSessionTicketKeys([][32]byte{randomKey(), key2}) 632 ticket = getTicket() 633 testResumeState("KeyChange", true) 634 if bytes.Equal(ticket, getTicket()) { 635 t.Fatal("new ticket wasn't included while resuming") 636 } 637 testResumeState("KeyChangeFinish", true) 638 639 clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA} 640 testResumeState("DifferentCipherSuite", false) 641 testResumeState("DifferentCipherSuiteRecovers", true) 642 643 clientConfig.ClientSessionCache = nil 644 testResumeState("WithoutSessionCache", false) 645 } 646 647 func TestLRUClientSessionCache(t *testing.T) { 648 // Initialize cache of capacity 4. 649 cache := NewLRUClientSessionCache(4) 650 cs := make([]ClientSessionState, 6) 651 keys := []string{"0", "1", "2", "3", "4", "5", "6"} 652 653 // Add 4 entries to the cache and look them up. 654 for i := 0; i < 4; i++ { 655 cache.Put(keys[i], &cs[i]) 656 } 657 for i := 0; i < 4; i++ { 658 if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] { 659 t.Fatalf("session cache failed lookup for added key: %s", keys[i]) 660 } 661 } 662 663 // Add 2 more entries to the cache. First 2 should be evicted. 664 for i := 4; i < 6; i++ { 665 cache.Put(keys[i], &cs[i]) 666 } 667 for i := 0; i < 2; i++ { 668 if s, ok := cache.Get(keys[i]); ok || s != nil { 669 t.Fatalf("session cache should have evicted key: %s", keys[i]) 670 } 671 } 672 673 // Touch entry 2. LRU should evict 3 next. 674 cache.Get(keys[2]) 675 cache.Put(keys[0], &cs[0]) 676 if s, ok := cache.Get(keys[3]); ok || s != nil { 677 t.Fatalf("session cache should have evicted key 3") 678 } 679 680 // Update entry 0 in place. 681 cache.Put(keys[0], &cs[3]) 682 if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] { 683 t.Fatalf("session cache failed update for key 0") 684 } 685 686 // Adding a nil entry is valid. 687 cache.Put(keys[0], nil) 688 if s, ok := cache.Get(keys[0]); !ok || s != nil { 689 t.Fatalf("failed to add nil entry to cache") 690 } 691 } 692 693 func TestHandshakeClientALPNMatch(t *testing.T) { 694 config := *testConfig 695 config.NextProtos = []string{"proto2", "proto1"} 696 697 test := &clientTest{ 698 name: "ALPN", 699 // Note that this needs OpenSSL 1.0.2 because that is the first 700 // version that supports the -alpn flag. 701 command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"}, 702 config: &config, 703 validate: func(state ConnectionState) error { 704 // The server's preferences should override the client. 705 if state.NegotiatedProtocol != "proto1" { 706 return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol) 707 } 708 return nil 709 }, 710 } 711 runClientTestTLS12(t, test) 712 } 713 714 func TestHandshakeClientALPNNoMatch(t *testing.T) { 715 config := *testConfig 716 config.NextProtos = []string{"proto3"} 717 718 test := &clientTest{ 719 name: "ALPN-NoMatch", 720 // Note that this needs OpenSSL 1.0.2 because that is the first 721 // version that supports the -alpn flag. 722 command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"}, 723 config: &config, 724 validate: func(state ConnectionState) error { 725 // There's no overlap so OpenSSL will not select a protocol. 726 if state.NegotiatedProtocol != "" { 727 return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol) 728 } 729 return nil 730 }, 731 } 732 runClientTestTLS12(t, test) 733 } 734 735 // sctsBase64 contains data from `openssl s_client -serverinfo 18 -connect ritter.vg:443` 736 const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0=" 737 738 func TestHandshakClientSCTs(t *testing.T) { 739 config := *testConfig 740 741 scts, err := base64.StdEncoding.DecodeString(sctsBase64) 742 if err != nil { 743 t.Fatal(err) 744 } 745 746 test := &clientTest{ 747 name: "SCT", 748 // Note that this needs OpenSSL 1.0.2 because that is the first 749 // version that supports the -serverinfo flag. 750 command: []string{"openssl", "s_server"}, 751 config: &config, 752 extensions: [][]byte{scts}, 753 validate: func(state ConnectionState) error { 754 expectedSCTs := [][]byte{ 755 scts[8:125], 756 scts[127:245], 757 scts[247:], 758 } 759 if n := len(state.SignedCertificateTimestamps); n != len(expectedSCTs) { 760 return fmt.Errorf("Got %d scts, wanted %d", n, len(expectedSCTs)) 761 } 762 for i, expected := range expectedSCTs { 763 if sct := state.SignedCertificateTimestamps[i]; !bytes.Equal(sct, expected) { 764 return fmt.Errorf("SCT #%d contained %x, expected %x", i, sct, expected) 765 } 766 } 767 return nil 768 }, 769 } 770 runClientTestTLS12(t, test) 771 } 772 773 func TestRenegotiationRejected(t *testing.T) { 774 config := *testConfig 775 test := &clientTest{ 776 name: "RenegotiationRejected", 777 command: []string{"openssl", "s_server", "-state"}, 778 config: &config, 779 numRenegotiations: 1, 780 renegotiationExpectedToFail: 1, 781 checkRenegotiationError: func(renegotiationNum int, err error) error { 782 if err == nil { 783 return errors.New("expected error from renegotiation but got nil") 784 } 785 if !strings.Contains(err.Error(), "no renegotiation") { 786 return fmt.Errorf("expected renegotiation to be rejected but got %q", err) 787 } 788 return nil 789 }, 790 } 791 792 runClientTestTLS12(t, test) 793 } 794 795 func TestRenegotiateOnce(t *testing.T) { 796 config := *testConfig 797 config.Renegotiation = RenegotiateOnceAsClient 798 799 test := &clientTest{ 800 name: "RenegotiateOnce", 801 command: []string{"openssl", "s_server", "-state"}, 802 config: &config, 803 numRenegotiations: 1, 804 } 805 806 runClientTestTLS12(t, test) 807 } 808 809 func TestRenegotiateTwice(t *testing.T) { 810 config := *testConfig 811 config.Renegotiation = RenegotiateFreelyAsClient 812 813 test := &clientTest{ 814 name: "RenegotiateTwice", 815 command: []string{"openssl", "s_server", "-state"}, 816 config: &config, 817 numRenegotiations: 2, 818 } 819 820 runClientTestTLS12(t, test) 821 } 822 823 func TestRenegotiateTwiceRejected(t *testing.T) { 824 config := *testConfig 825 config.Renegotiation = RenegotiateOnceAsClient 826 827 test := &clientTest{ 828 name: "RenegotiateTwiceRejected", 829 command: []string{"openssl", "s_server", "-state"}, 830 config: &config, 831 numRenegotiations: 2, 832 renegotiationExpectedToFail: 2, 833 checkRenegotiationError: func(renegotiationNum int, err error) error { 834 if renegotiationNum == 1 { 835 return err 836 } 837 838 if err == nil { 839 return errors.New("expected error from renegotiation but got nil") 840 } 841 if !strings.Contains(err.Error(), "no renegotiation") { 842 return fmt.Errorf("expected renegotiation to be rejected but got %q", err) 843 } 844 return nil 845 }, 846 } 847 848 runClientTestTLS12(t, test) 849 } 850 851 var hostnameInSNITests = []struct { 852 in, out string 853 }{ 854 // Opaque string 855 {"", ""}, 856 {"localhost", "localhost"}, 857 {"foo, bar, baz and qux", "foo, bar, baz and qux"}, 858 859 // DNS hostname 860 {"golang.org", "golang.org"}, 861 {"golang.org.", "golang.org"}, 862 863 // Literal IPv4 address 864 {"1.2.3.4", ""}, 865 866 // Literal IPv6 address 867 {"::1", ""}, 868 {"::1%lo0", ""}, // with zone identifier 869 {"[::1]", ""}, // as per RFC 5952 we allow the [] style as IPv6 literal 870 {"[::1%lo0]", ""}, 871 } 872 873 func TestHostnameInSNI(t *testing.T) { 874 for _, tt := range hostnameInSNITests { 875 c, s := net.Pipe() 876 877 go func(host string) { 878 Client(c, &Config{ServerName: host, InsecureSkipVerify: true}).Handshake() 879 }(tt.in) 880 881 var header [5]byte 882 if _, err := io.ReadFull(s, header[:]); err != nil { 883 t.Fatal(err) 884 } 885 recordLen := int(header[3])<<8 | int(header[4]) 886 887 record := make([]byte, recordLen) 888 if _, err := io.ReadFull(s, record[:]); err != nil { 889 t.Fatal(err) 890 } 891 892 c.Close() 893 s.Close() 894 895 var m clientHelloMsg 896 if !m.unmarshal(record) { 897 t.Errorf("unmarshaling ClientHello for %q failed", tt.in) 898 continue 899 } 900 if tt.in != tt.out && m.serverName == tt.in { 901 t.Errorf("prohibited %q found in ClientHello: %x", tt.in, record) 902 } 903 if m.serverName != tt.out { 904 t.Errorf("expected %q not found in ClientHello: %x", tt.out, record) 905 } 906 } 907 } 908 909 func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) { 910 // This checks that the server can't select a cipher suite that the 911 // client didn't offer. See #13174. 912 913 c, s := net.Pipe() 914 errChan := make(chan error, 1) 915 916 go func() { 917 client := Client(c, &Config{ 918 ServerName: "foo", 919 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 920 }) 921 errChan <- client.Handshake() 922 }() 923 924 var header [5]byte 925 if _, err := io.ReadFull(s, header[:]); err != nil { 926 t.Fatal(err) 927 } 928 recordLen := int(header[3])<<8 | int(header[4]) 929 930 record := make([]byte, recordLen) 931 if _, err := io.ReadFull(s, record); err != nil { 932 t.Fatal(err) 933 } 934 935 // Create a ServerHello that selects a different cipher suite than the 936 // sole one that the client offered. 937 serverHello := &serverHelloMsg{ 938 vers: VersionTLS12, 939 random: make([]byte, 32), 940 cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384, 941 } 942 serverHelloBytes := serverHello.marshal() 943 944 s.Write([]byte{ 945 byte(recordTypeHandshake), 946 byte(VersionTLS12 >> 8), 947 byte(VersionTLS12 & 0xff), 948 byte(len(serverHelloBytes) >> 8), 949 byte(len(serverHelloBytes)), 950 }) 951 s.Write(serverHelloBytes) 952 s.Close() 953 954 if err := <-errChan; !strings.Contains(err.Error(), "unconfigured cipher") { 955 t.Fatalf("Expected error about unconfigured cipher suite but got %q", err) 956 } 957 } 958 959 // brokenConn wraps a net.Conn and causes all Writes after a certain number to 960 // fail with brokenConnErr. 961 type brokenConn struct { 962 net.Conn 963 964 // breakAfter is the number of successful writes that will be allowed 965 // before all subsequent writes fail. 966 breakAfter int 967 968 // numWrites is the number of writes that have been done. 969 numWrites int 970 } 971 972 // brokenConnErr is the error that brokenConn returns once exhausted. 973 var brokenConnErr = errors.New("too many writes to brokenConn") 974 975 func (b *brokenConn) Write(data []byte) (int, error) { 976 if b.numWrites >= b.breakAfter { 977 return 0, brokenConnErr 978 } 979 980 b.numWrites++ 981 return b.Conn.Write(data) 982 } 983 984 func TestFailedWrite(t *testing.T) { 985 // Test that a write error during the handshake is returned. 986 for _, breakAfter := range []int{0, 1} { 987 c, s := net.Pipe() 988 done := make(chan bool) 989 990 go func() { 991 Server(s, testConfig).Handshake() 992 s.Close() 993 done <- true 994 }() 995 996 brokenC := &brokenConn{Conn: c, breakAfter: breakAfter} 997 err := Client(brokenC, testConfig).Handshake() 998 if err != brokenConnErr { 999 t.Errorf("#%d: expected error from brokenConn but got %q", breakAfter, err) 1000 } 1001 brokenC.Close() 1002 1003 <-done 1004 } 1005 } 1006 1007 // writeCountingConn wraps a net.Conn and counts the number of Write calls. 1008 type writeCountingConn struct { 1009 net.Conn 1010 1011 // numWrites is the number of writes that have been done. 1012 numWrites int 1013 } 1014 1015 func (wcc *writeCountingConn) Write(data []byte) (int, error) { 1016 wcc.numWrites++ 1017 return wcc.Conn.Write(data) 1018 } 1019 1020 func TestBuffering(t *testing.T) { 1021 c, s := net.Pipe() 1022 done := make(chan bool) 1023 1024 clientWCC := &writeCountingConn{Conn: c} 1025 serverWCC := &writeCountingConn{Conn: s} 1026 1027 go func() { 1028 Server(serverWCC, testConfig).Handshake() 1029 serverWCC.Close() 1030 done <- true 1031 }() 1032 1033 err := Client(clientWCC, testConfig).Handshake() 1034 if err != nil { 1035 t.Fatal(err) 1036 } 1037 clientWCC.Close() 1038 <-done 1039 1040 if n := clientWCC.numWrites; n != 2 { 1041 t.Errorf("expected client handshake to complete with only two writes, but saw %d", n) 1042 } 1043 1044 if n := serverWCC.numWrites; n != 2 { 1045 t.Errorf("expected server handshake to complete with only two writes, but saw %d", n) 1046 } 1047 }