1// Copyright 2009 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 5package qtls 6 7import ( 8 "bytes" 9 "crypto" 10 "crypto/elliptic" 11 "crypto/x509" 12 "encoding/pem" 13 "errors" 14 "fmt" 15 "io" 16 "net" 17 "os" 18 "os/exec" 19 "path/filepath" 20 "strings" 21 "testing" 22 "time" 23 24 "golang.org/x/crypto/curve25519" 25) 26 27func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) { 28 testClientHelloFailure(t, serverConfig, m, "") 29} 30 31func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) { 32 c, s := localPipe(t) 33 go func() { 34 cli := Client(c, testConfig, nil) 35 if ch, ok := m.(*clientHelloMsg); ok { 36 cli.vers = ch.vers 37 } 38 cli.writeRecord(recordTypeHandshake, m.marshal()) 39 c.Close() 40 }() 41 conn := Server(s, serverConfig, nil) 42 ch, err := conn.readClientHello() 43 hs := serverHandshakeState{ 44 c: conn, 45 clientHello: ch, 46 } 47 if err == nil { 48 err = hs.processClientHello() 49 } 50 if err == nil { 51 err = hs.pickCipherSuite() 52 } 53 s.Close() 54 if len(expectedSubStr) == 0 { 55 if err != nil && err != io.EOF { 56 t.Errorf("Got error: %s; expected to succeed", err) 57 } 58 } else if err == nil || !strings.Contains(err.Error(), expectedSubStr) { 59 t.Errorf("Got error: %v; expected to match substring '%s'", err, expectedSubStr) 60 } 61} 62 63func TestSimpleError(t *testing.T) { 64 testClientHelloFailure(t, testConfig, &serverHelloDoneMsg{}, "unexpected handshake message") 65} 66 67var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205, VersionSSL30} 68 69func TestRejectBadProtocolVersion(t *testing.T) { 70 config := testConfig.Clone() 71 config.MinVersion = VersionSSL30 72 for _, v := range badProtocolVersions { 73 testClientHelloFailure(t, config, &clientHelloMsg{ 74 vers: v, 75 random: make([]byte, 32), 76 }, "unsupported versions") 77 } 78 testClientHelloFailure(t, config, &clientHelloMsg{ 79 vers: VersionTLS12, 80 supportedVersions: badProtocolVersions, 81 random: make([]byte, 32), 82 }, "unsupported versions") 83} 84 85func TestNoSuiteOverlap(t *testing.T) { 86 clientHello := &clientHelloMsg{ 87 vers: VersionTLS10, 88 random: make([]byte, 32), 89 cipherSuites: []uint16{0xff00}, 90 compressionMethods: []uint8{compressionNone}, 91 } 92 testClientHelloFailure(t, testConfig, clientHello, "no cipher suite supported by both client and server") 93} 94 95func TestNoCompressionOverlap(t *testing.T) { 96 clientHello := &clientHelloMsg{ 97 vers: VersionTLS10, 98 random: make([]byte, 32), 99 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 100 compressionMethods: []uint8{0xff}, 101 } 102 testClientHelloFailure(t, testConfig, clientHello, "client does not support uncompressed connections") 103} 104 105func TestNoRC4ByDefault(t *testing.T) { 106 clientHello := &clientHelloMsg{ 107 vers: VersionTLS10, 108 random: make([]byte, 32), 109 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 110 compressionMethods: []uint8{compressionNone}, 111 } 112 serverConfig := testConfig.Clone() 113 // Reset the enabled cipher suites to nil in order to test the 114 // defaults. 115 serverConfig.CipherSuites = nil 116 testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server") 117} 118 119func TestRejectSNIWithTrailingDot(t *testing.T) { 120 testClientHelloFailure(t, testConfig, &clientHelloMsg{ 121 vers: VersionTLS12, 122 random: make([]byte, 32), 123 serverName: "foo.com.", 124 }, "unexpected message") 125} 126 127func TestDontSelectECDSAWithRSAKey(t *testing.T) { 128 // Test that, even when both sides support an ECDSA cipher suite, it 129 // won't be selected if the server's private key doesn't support it. 130 clientHello := &clientHelloMsg{ 131 vers: VersionTLS10, 132 random: make([]byte, 32), 133 cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, 134 compressionMethods: []uint8{compressionNone}, 135 supportedCurves: []CurveID{CurveP256}, 136 supportedPoints: []uint8{pointFormatUncompressed}, 137 } 138 serverConfig := testConfig.Clone() 139 serverConfig.CipherSuites = clientHello.cipherSuites 140 serverConfig.Certificates = make([]Certificate, 1) 141 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate} 142 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey 143 serverConfig.BuildNameToCertificate() 144 // First test that it *does* work when the server's key is ECDSA. 145 testClientHello(t, serverConfig, clientHello) 146 147 // Now test that switching to an RSA key causes the expected error (and 148 // not an internal error about a signing failure). 149 serverConfig.Certificates = testConfig.Certificates 150 testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server") 151} 152 153func TestDontSelectRSAWithECDSAKey(t *testing.T) { 154 // Test that, even when both sides support an RSA cipher suite, it 155 // won't be selected if the server's private key doesn't support it. 156 clientHello := &clientHelloMsg{ 157 vers: VersionTLS10, 158 random: make([]byte, 32), 159 cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 160 compressionMethods: []uint8{compressionNone}, 161 supportedCurves: []CurveID{CurveP256}, 162 supportedPoints: []uint8{pointFormatUncompressed}, 163 } 164 serverConfig := testConfig.Clone() 165 serverConfig.CipherSuites = clientHello.cipherSuites 166 // First test that it *does* work when the server's key is RSA. 167 testClientHello(t, serverConfig, clientHello) 168 169 // Now test that switching to an ECDSA key causes the expected error 170 // (and not an internal error about a signing failure). 171 serverConfig.Certificates = make([]Certificate, 1) 172 serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate} 173 serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey 174 serverConfig.BuildNameToCertificate() 175 testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server") 176} 177 178func TestRenegotiationExtension(t *testing.T) { 179 clientHello := &clientHelloMsg{ 180 vers: VersionTLS12, 181 compressionMethods: []uint8{compressionNone}, 182 random: make([]byte, 32), 183 secureRenegotiationSupported: true, 184 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 185 } 186 187 bufChan := make(chan []byte, 1) 188 c, s := localPipe(t) 189 190 go func() { 191 cli := Client(c, testConfig, nil) 192 cli.vers = clientHello.vers 193 cli.writeRecord(recordTypeHandshake, clientHello.marshal()) 194 195 buf := make([]byte, 1024) 196 n, err := c.Read(buf) 197 if err != nil { 198 t.Errorf("Server read returned error: %s", err) 199 return 200 } 201 c.Close() 202 bufChan <- buf[:n] 203 }() 204 205 Server(s, testConfig, nil).Handshake() 206 buf := <-bufChan 207 208 if len(buf) < 5+4 { 209 t.Fatalf("Server returned short message of length %d", len(buf)) 210 } 211 // buf contains a TLS record, with a 5 byte record header and a 4 byte 212 // handshake header. The length of the ServerHello is taken from the 213 // handshake header. 214 serverHelloLen := int(buf[6])<<16 | int(buf[7])<<8 | int(buf[8]) 215 216 var serverHello serverHelloMsg 217 // unmarshal expects to be given the handshake header, but 218 // serverHelloLen doesn't include it. 219 if !serverHello.unmarshal(buf[5 : 9+serverHelloLen]) { 220 t.Fatalf("Failed to parse ServerHello") 221 } 222 223 if !serverHello.secureRenegotiationSupported { 224 t.Errorf("Secure renegotiation extension was not echoed.") 225 } 226} 227 228func TestTLS12OnlyCipherSuites(t *testing.T) { 229 // Test that a Server doesn't select a TLS 1.2-only cipher suite when 230 // the client negotiates TLS 1.1. 231 clientHello := &clientHelloMsg{ 232 vers: VersionTLS11, 233 random: make([]byte, 32), 234 cipherSuites: []uint16{ 235 // The Server, by default, will use the client's 236 // preference order. So the GCM cipher suite 237 // will be selected unless it's excluded because 238 // of the version in this ClientHello. 239 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 240 TLS_RSA_WITH_RC4_128_SHA, 241 }, 242 compressionMethods: []uint8{compressionNone}, 243 supportedCurves: []CurveID{CurveP256, CurveP384, CurveP521}, 244 supportedPoints: []uint8{pointFormatUncompressed}, 245 } 246 247 c, s := localPipe(t) 248 replyChan := make(chan interface{}) 249 go func() { 250 cli := Client(c, testConfig, nil) 251 cli.vers = clientHello.vers 252 cli.writeRecord(recordTypeHandshake, clientHello.marshal()) 253 reply, err := cli.readHandshake() 254 c.Close() 255 if err != nil { 256 replyChan <- err 257 } else { 258 replyChan <- reply 259 } 260 }() 261 config := testConfig.Clone() 262 config.CipherSuites = clientHello.cipherSuites 263 Server(s, config, nil).Handshake() 264 s.Close() 265 reply := <-replyChan 266 if err, ok := reply.(error); ok { 267 t.Fatal(err) 268 } 269 serverHello, ok := reply.(*serverHelloMsg) 270 if !ok { 271 t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply) 272 } 273 if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA { 274 t.Fatalf("bad cipher suite from server: %x", s) 275 } 276} 277 278func TestTLSPointFormats(t *testing.T) { 279 // Test that a Server returns the ec_point_format extension when ECC is 280 // negotiated, and not returned on RSA handshake. 281 tests := []struct { 282 name string 283 cipherSuites []uint16 284 supportedCurves []CurveID 285 supportedPoints []uint8 286 wantSupportedPoints bool 287 }{ 288 {"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{compressionNone}, true}, 289 {"RSA", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, nil, false}, 290 } 291 for _, tt := range tests { 292 t.Run(tt.name, func(t *testing.T) { 293 clientHello := &clientHelloMsg{ 294 vers: VersionTLS12, 295 random: make([]byte, 32), 296 cipherSuites: tt.cipherSuites, 297 compressionMethods: []uint8{compressionNone}, 298 supportedCurves: tt.supportedCurves, 299 supportedPoints: tt.supportedPoints, 300 } 301 302 c, s := localPipe(t) 303 replyChan := make(chan interface{}) 304 go func() { 305 cli := Client(c, testConfig, nil) 306 cli.vers = clientHello.vers 307 cli.writeRecord(recordTypeHandshake, clientHello.marshal()) 308 reply, err := cli.readHandshake() 309 c.Close() 310 if err != nil { 311 replyChan <- err 312 } else { 313 replyChan <- reply 314 } 315 }() 316 config := testConfig.Clone() 317 config.CipherSuites = clientHello.cipherSuites 318 Server(s, config, nil).Handshake() 319 s.Close() 320 reply := <-replyChan 321 if err, ok := reply.(error); ok { 322 t.Fatal(err) 323 } 324 serverHello, ok := reply.(*serverHelloMsg) 325 if !ok { 326 t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply) 327 } 328 if tt.wantSupportedPoints { 329 if len(serverHello.supportedPoints) < 1 { 330 t.Fatal("missing ec_point_format extension from server") 331 } 332 found := false 333 for _, p := range serverHello.supportedPoints { 334 if p == pointFormatUncompressed { 335 found = true 336 break 337 } 338 } 339 if !found { 340 t.Fatal("missing uncompressed format in ec_point_format extension from server") 341 } 342 } else { 343 if len(serverHello.supportedPoints) != 0 { 344 t.Fatalf("unexcpected ec_point_format extension from server: %v", serverHello.supportedPoints) 345 } 346 } 347 }) 348 } 349} 350 351func TestAlertForwarding(t *testing.T) { 352 c, s := localPipe(t) 353 go func() { 354 Client(c, testConfig, nil).sendAlert(alertUnknownCA) 355 c.Close() 356 }() 357 358 err := Server(s, testConfig, nil).Handshake() 359 s.Close() 360 var opErr *net.OpError 361 if !errors.As(err, &opErr) || opErr.Err != error(alertUnknownCA) { 362 t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA)) 363 } 364} 365 366func TestClose(t *testing.T) { 367 c, s := localPipe(t) 368 go c.Close() 369 370 err := Server(s, testConfig, nil).Handshake() 371 s.Close() 372 if err != io.EOF { 373 t.Errorf("Got error: %s; expected: %s", err, io.EOF) 374 } 375} 376 377func TestVersion(t *testing.T) { 378 serverConfig := &Config{ 379 Certificates: testConfig.Certificates, 380 MaxVersion: VersionTLS11, 381 } 382 clientConfig := &Config{ 383 InsecureSkipVerify: true, 384 } 385 state, _, err := testHandshake(t, clientConfig, serverConfig) 386 if err != nil { 387 t.Fatalf("handshake failed: %s", err) 388 } 389 if state.Version != VersionTLS11 { 390 t.Fatalf("Incorrect version %x, should be %x", state.Version, VersionTLS11) 391 } 392} 393 394func TestCipherSuitePreference(t *testing.T) { 395 serverConfig := &Config{ 396 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 397 Certificates: testConfig.Certificates, 398 MaxVersion: VersionTLS11, 399 } 400 clientConfig := &Config{ 401 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA}, 402 InsecureSkipVerify: true, 403 } 404 state, _, err := testHandshake(t, clientConfig, serverConfig) 405 if err != nil { 406 t.Fatalf("handshake failed: %s", err) 407 } 408 if state.CipherSuite != TLS_RSA_WITH_AES_128_CBC_SHA { 409 // By default the server should use the client's preference. 410 t.Fatalf("Client's preference was not used, got %x", state.CipherSuite) 411 } 412 413 serverConfig.PreferServerCipherSuites = true 414 state, _, err = testHandshake(t, clientConfig, serverConfig) 415 if err != nil { 416 t.Fatalf("handshake failed: %s", err) 417 } 418 if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA { 419 t.Fatalf("Server's preference was not used, got %x", state.CipherSuite) 420 } 421} 422 423func TestCipherSuitePreferenceTLS13(t *testing.T) { 424 serverConfig := &Config{ 425 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256}, 426 Certificates: testConfig.Certificates, 427 } 428 clientConfig := &Config{ 429 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256}, 430 InsecureSkipVerify: true, 431 } 432 state, _, err := testHandshake(t, clientConfig, serverConfig) 433 if err != nil { 434 t.Fatalf("handshake failed: %s", err) 435 } 436 if state.CipherSuite != TLS_CHACHA20_POLY1305_SHA256 { 437 // By default the server should use the client's preference. 438 t.Fatalf("Client's preference was not used, got %x", state.CipherSuite) 439 } 440 441 serverConfig.PreferServerCipherSuites = true 442 state, _, err = testHandshake(t, clientConfig, serverConfig) 443 if err != nil { 444 t.Fatalf("handshake failed: %s", err) 445 } 446 if state.CipherSuite != TLS_AES_128_GCM_SHA256 { 447 t.Fatalf("Server's preference was not used, got %x", state.CipherSuite) 448 } 449} 450 451func TestSCTHandshake(t *testing.T) { 452 t.Run("TLSv12", func(t *testing.T) { testSCTHandshake(t, VersionTLS12) }) 453 t.Run("TLSv13", func(t *testing.T) { testSCTHandshake(t, VersionTLS13) }) 454} 455 456func testSCTHandshake(t *testing.T, version uint16) { 457 expected := [][]byte{[]byte("certificate"), []byte("transparency")} 458 serverConfig := &Config{ 459 Certificates: []Certificate{{ 460 Certificate: [][]byte{testRSACertificate}, 461 PrivateKey: testRSAPrivateKey, 462 SignedCertificateTimestamps: expected, 463 }}, 464 MaxVersion: version, 465 } 466 clientConfig := &Config{ 467 InsecureSkipVerify: true, 468 } 469 _, state, err := testHandshake(t, clientConfig, serverConfig) 470 if err != nil { 471 t.Fatalf("handshake failed: %s", err) 472 } 473 actual := state.SignedCertificateTimestamps 474 if len(actual) != len(expected) { 475 t.Fatalf("got %d scts, want %d", len(actual), len(expected)) 476 } 477 for i, sct := range expected { 478 if !bytes.Equal(sct, actual[i]) { 479 t.Fatalf("SCT #%d was %x, but expected %x", i, actual[i], sct) 480 } 481 } 482} 483 484func TestCrossVersionResume(t *testing.T) { 485 t.Run("TLSv12", func(t *testing.T) { testCrossVersionResume(t, VersionTLS12) }) 486 t.Run("TLSv13", func(t *testing.T) { testCrossVersionResume(t, VersionTLS13) }) 487} 488 489func testCrossVersionResume(t *testing.T, version uint16) { 490 serverConfig := &Config{ 491 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 492 Certificates: testConfig.Certificates, 493 } 494 clientConfig := &Config{ 495 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 496 InsecureSkipVerify: true, 497 ClientSessionCache: NewLRUClientSessionCache(1), 498 ServerName: "servername", 499 } 500 501 // Establish a session at TLS 1.1. 502 clientConfig.MaxVersion = VersionTLS11 503 _, _, err := testHandshake(t, clientConfig, serverConfig) 504 if err != nil { 505 t.Fatalf("handshake failed: %s", err) 506 } 507 508 // The client session cache now contains a TLS 1.1 session. 509 state, _, err := testHandshake(t, clientConfig, serverConfig) 510 if err != nil { 511 t.Fatalf("handshake failed: %s", err) 512 } 513 if !state.DidResume { 514 t.Fatalf("handshake did not resume at the same version") 515 } 516 517 // Test that the server will decline to resume at a lower version. 518 clientConfig.MaxVersion = VersionTLS10 519 state, _, err = testHandshake(t, clientConfig, serverConfig) 520 if err != nil { 521 t.Fatalf("handshake failed: %s", err) 522 } 523 if state.DidResume { 524 t.Fatalf("handshake resumed at a lower version") 525 } 526 527 // The client session cache now contains a TLS 1.0 session. 528 state, _, err = testHandshake(t, clientConfig, serverConfig) 529 if err != nil { 530 t.Fatalf("handshake failed: %s", err) 531 } 532 if !state.DidResume { 533 t.Fatalf("handshake did not resume at the same version") 534 } 535 536 // Test that the server will decline to resume at a higher version. 537 clientConfig.MaxVersion = VersionTLS11 538 state, _, err = testHandshake(t, clientConfig, serverConfig) 539 if err != nil { 540 t.Fatalf("handshake failed: %s", err) 541 } 542 if state.DidResume { 543 t.Fatalf("handshake resumed at a higher version") 544 } 545} 546 547// Note: see comment in handshake_test.go for details of how the reference 548// tests work. 549 550// serverTest represents a test of the TLS server handshake against a reference 551// implementation. 552type serverTest struct { 553 // name is a freeform string identifying the test and the file in which 554 // the expected results will be stored. 555 name string 556 // command, if not empty, contains a series of arguments for the 557 // command to run for the reference server. 558 command []string 559 // expectedPeerCerts contains a list of PEM blocks of expected 560 // certificates from the client. 561 expectedPeerCerts []string 562 // config, if not nil, contains a custom Config to use for this test. 563 config *Config 564 // expectHandshakeErrorIncluding, when not empty, contains a string 565 // that must be a substring of the error resulting from the handshake. 566 expectHandshakeErrorIncluding string 567 // validate, if not nil, is a function that will be called with the 568 // ConnectionState of the resulting connection. It returns false if the 569 // ConnectionState is unacceptable. 570 validate func(ConnectionState) error 571 // wait, if true, prevents this subtest from calling t.Parallel. 572 // If false, runServerTest* returns immediately. 573 wait bool 574} 575 576var defaultClientCommand = []string{"openssl", "s_client", "-no_ticket"} 577 578// connFromCommand starts opens a listening socket and starts the reference 579// client to connect to it. It returns a recordingConn that wraps the resulting 580// connection. 581func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, err error) { 582 l, err := net.ListenTCP("tcp", &net.TCPAddr{ 583 IP: net.IPv4(127, 0, 0, 1), 584 Port: 0, 585 }) 586 if err != nil { 587 return nil, nil, err 588 } 589 defer l.Close() 590 591 port := l.Addr().(*net.TCPAddr).Port 592 593 var command []string 594 command = append(command, test.command...) 595 if len(command) == 0 { 596 command = defaultClientCommand 597 } 598 command = append(command, "-connect") 599 command = append(command, fmt.Sprintf("127.0.0.1:%d", port)) 600 cmd := exec.Command(command[0], command[1:]...) 601 cmd.Stdin = nil 602 var output bytes.Buffer 603 cmd.Stdout = &output 604 cmd.Stderr = &output 605 if err := cmd.Start(); err != nil { 606 return nil, nil, err 607 } 608 609 connChan := make(chan interface{}, 1) 610 go func() { 611 tcpConn, err := l.Accept() 612 if err != nil { 613 connChan <- err 614 return 615 } 616 connChan <- tcpConn 617 }() 618 619 var tcpConn net.Conn 620 select { 621 case connOrError := <-connChan: 622 if err, ok := connOrError.(error); ok { 623 return nil, nil, err 624 } 625 tcpConn = connOrError.(net.Conn) 626 case <-time.After(2 * time.Second): 627 return nil, nil, errors.New("timed out waiting for connection from child process") 628 } 629 630 record := &recordingConn{ 631 Conn: tcpConn, 632 } 633 634 return record, cmd, nil 635} 636 637func (test *serverTest) dataPath() string { 638 return filepath.Join("testdata", "Server-"+test.name) 639} 640 641func (test *serverTest) loadData() (flows [][]byte, err error) { 642 in, err := os.Open(test.dataPath()) 643 if err != nil { 644 return nil, err 645 } 646 defer in.Close() 647 return parseTestData(in) 648} 649 650func (test *serverTest) run(t *testing.T, write bool) { 651 var clientConn, serverConn net.Conn 652 var recordingConn *recordingConn 653 var childProcess *exec.Cmd 654 655 if write { 656 var err error 657 recordingConn, childProcess, err = test.connFromCommand() 658 if err != nil { 659 t.Fatalf("Failed to start subcommand: %s", err) 660 } 661 serverConn = recordingConn 662 defer func() { 663 if t.Failed() { 664 t.Logf("OpenSSL output:\n\n%s", childProcess.Stdout) 665 } 666 }() 667 } else { 668 clientConn, serverConn = localPipe(t) 669 } 670 config := test.config 671 if config == nil { 672 config = testConfig 673 } 674 server := Server(serverConn, config, nil) 675 connStateChan := make(chan ConnectionState, 1) 676 go func() { 677 _, err := server.Write([]byte("hello, world\n")) 678 if len(test.expectHandshakeErrorIncluding) > 0 { 679 if err == nil { 680 t.Errorf("Error expected, but no error returned") 681 } else if s := err.Error(); !strings.Contains(s, test.expectHandshakeErrorIncluding) { 682 t.Errorf("Error expected containing '%s' but got '%s'", test.expectHandshakeErrorIncluding, s) 683 } 684 } else { 685 if err != nil { 686 t.Logf("Error from Server.Write: '%s'", err) 687 } 688 } 689 server.Close() 690 serverConn.Close() 691 connStateChan <- server.ConnectionState() 692 }() 693 694 if !write { 695 flows, err := test.loadData() 696 if err != nil { 697 t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath()) 698 } 699 for i, b := range flows { 700 if i%2 == 0 { 701 if *fast { 702 clientConn.SetWriteDeadline(time.Now().Add(1 * time.Second)) 703 } else { 704 clientConn.SetWriteDeadline(time.Now().Add(1 * time.Minute)) 705 } 706 clientConn.Write(b) 707 continue 708 } 709 bb := make([]byte, len(b)) 710 if *fast { 711 clientConn.SetReadDeadline(time.Now().Add(1 * time.Second)) 712 } else { 713 clientConn.SetReadDeadline(time.Now().Add(1 * time.Minute)) 714 } 715 n, err := io.ReadFull(clientConn, bb) 716 if err != nil { 717 t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", test.name, i+1, err, n, len(bb), bb[:n], b) 718 } 719 if !bytes.Equal(b, bb) { 720 t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b) 721 } 722 } 723 clientConn.Close() 724 } 725 726 connState := <-connStateChan 727 peerCerts := connState.PeerCertificates 728 if len(peerCerts) == len(test.expectedPeerCerts) { 729 for i, peerCert := range peerCerts { 730 block, _ := pem.Decode([]byte(test.expectedPeerCerts[i])) 731 if !bytes.Equal(block.Bytes, peerCert.Raw) { 732 t.Fatalf("%s: mismatch on peer cert %d", test.name, i+1) 733 } 734 } 735 } else { 736 t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", test.name, len(test.expectedPeerCerts), len(peerCerts)) 737 } 738 739 if test.validate != nil { 740 if err := test.validate(connState); err != nil { 741 t.Fatalf("validate callback returned error: %s", err) 742 } 743 } 744 745 if write { 746 path := test.dataPath() 747 out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 748 if err != nil { 749 t.Fatalf("Failed to create output file: %s", err) 750 } 751 defer out.Close() 752 recordingConn.Close() 753 if len(recordingConn.flows) < 3 { 754 if len(test.expectHandshakeErrorIncluding) == 0 { 755 t.Fatalf("Handshake failed") 756 } 757 } 758 recordingConn.WriteTo(out) 759 t.Logf("Wrote %s\n", path) 760 childProcess.Wait() 761 } 762} 763 764func runServerTestForVersion(t *testing.T, template *serverTest, version, option string) { 765 // Make a deep copy of the template before going parallel. 766 test := *template 767 if template.config != nil { 768 test.config = template.config.Clone() 769 } 770 test.name = version + "-" + test.name 771 if len(test.command) == 0 { 772 test.command = defaultClientCommand 773 } 774 test.command = append([]string(nil), test.command...) 775 test.command = append(test.command, option) 776 777 runTestAndUpdateIfNeeded(t, version, test.run, test.wait) 778} 779 780func runServerTestTLS10(t *testing.T, template *serverTest) { 781 runServerTestForVersion(t, template, "TLSv10", "-tls1") 782} 783 784func runServerTestTLS11(t *testing.T, template *serverTest) { 785 runServerTestForVersion(t, template, "TLSv11", "-tls1_1") 786} 787 788func runServerTestTLS12(t *testing.T, template *serverTest) { 789 runServerTestForVersion(t, template, "TLSv12", "-tls1_2") 790} 791 792func runServerTestTLS13(t *testing.T, template *serverTest) { 793 runServerTestForVersion(t, template, "TLSv13", "-tls1_3") 794} 795 796func TestHandshakeServerRSARC4(t *testing.T) { 797 test := &serverTest{ 798 name: "RSA-RC4", 799 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"}, 800 } 801 runServerTestTLS10(t, test) 802 runServerTestTLS11(t, test) 803 runServerTestTLS12(t, test) 804} 805 806func TestHandshakeServerRSA3DES(t *testing.T) { 807 test := &serverTest{ 808 name: "RSA-3DES", 809 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"}, 810 } 811 runServerTestTLS10(t, test) 812 runServerTestTLS12(t, test) 813} 814 815func TestHandshakeServerRSAAES(t *testing.T) { 816 test := &serverTest{ 817 name: "RSA-AES", 818 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"}, 819 } 820 runServerTestTLS10(t, test) 821 runServerTestTLS12(t, test) 822} 823 824func TestHandshakeServerAESGCM(t *testing.T) { 825 test := &serverTest{ 826 name: "RSA-AES-GCM", 827 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"}, 828 } 829 runServerTestTLS12(t, test) 830} 831 832func TestHandshakeServerAES256GCMSHA384(t *testing.T) { 833 test := &serverTest{ 834 name: "RSA-AES256-GCM-SHA384", 835 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384"}, 836 } 837 runServerTestTLS12(t, test) 838} 839 840func TestHandshakeServerAES128SHA256(t *testing.T) { 841 test := &serverTest{ 842 name: "AES128-SHA256", 843 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_AES_128_GCM_SHA256"}, 844 } 845 runServerTestTLS13(t, test) 846} 847func TestHandshakeServerAES256SHA384(t *testing.T) { 848 test := &serverTest{ 849 name: "AES256-SHA384", 850 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_AES_256_GCM_SHA384"}, 851 } 852 runServerTestTLS13(t, test) 853} 854func TestHandshakeServerCHACHA20SHA256(t *testing.T) { 855 test := &serverTest{ 856 name: "CHACHA20-SHA256", 857 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, 858 } 859 runServerTestTLS13(t, test) 860} 861 862func TestHandshakeServerECDHEECDSAAES(t *testing.T) { 863 config := testConfig.Clone() 864 config.Certificates = make([]Certificate, 1) 865 config.Certificates[0].Certificate = [][]byte{testECDSACertificate} 866 config.Certificates[0].PrivateKey = testECDSAPrivateKey 867 config.BuildNameToCertificate() 868 869 test := &serverTest{ 870 name: "ECDHE-ECDSA-AES", 871 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"}, 872 config: config, 873 } 874 runServerTestTLS10(t, test) 875 runServerTestTLS12(t, test) 876 runServerTestTLS13(t, test) 877} 878 879func TestHandshakeServerX25519(t *testing.T) { 880 config := testConfig.Clone() 881 config.CurvePreferences = []CurveID{X25519} 882 883 test := &serverTest{ 884 name: "X25519", 885 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519"}, 886 config: config, 887 } 888 runServerTestTLS12(t, test) 889 runServerTestTLS13(t, test) 890} 891 892func TestHandshakeServerP256(t *testing.T) { 893 config := testConfig.Clone() 894 config.CurvePreferences = []CurveID{CurveP256} 895 896 test := &serverTest{ 897 name: "P256", 898 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "P-256"}, 899 config: config, 900 } 901 runServerTestTLS12(t, test) 902 runServerTestTLS13(t, test) 903} 904 905func TestHandshakeServerHelloRetryRequest(t *testing.T) { 906 config := testConfig.Clone() 907 config.CurvePreferences = []CurveID{CurveP256} 908 909 test := &serverTest{ 910 name: "HelloRetryRequest", 911 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519:P-256"}, 912 config: config, 913 } 914 runServerTestTLS13(t, test) 915} 916 917func TestHandshakeServerALPN(t *testing.T) { 918 config := testConfig.Clone() 919 config.NextProtos = []string{"proto1", "proto2"} 920 921 test := &serverTest{ 922 name: "ALPN", 923 // Note that this needs OpenSSL 1.0.2 because that is the first 924 // version that supports the -alpn flag. 925 command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, 926 config: config, 927 validate: func(state ConnectionState) error { 928 // The server's preferences should override the client. 929 if state.NegotiatedProtocol != "proto1" { 930 return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol) 931 } 932 return nil 933 }, 934 } 935 runServerTestTLS12(t, test) 936 runServerTestTLS13(t, test) 937} 938 939func TestHandshakeServerEnforceALPNMatch(t *testing.T) { 940 clientConn, serverConn := localPipe(t) 941 serverConfig := testConfig.Clone() 942 serverConfig.NextProtos = []string{"proto1", "proto2"} 943 client := Client(clientConn, serverConfig, nil) 944 945 cErrChan := make(chan error) 946 go func() { 947 cErrChan <- client.Handshake() 948 }() 949 950 config := testConfig.Clone() 951 config.NextProtos = []string{"proto3"} 952 extraConf := &ExtraConfig{EnforceNextProtoSelection: true} 953 954 server := Server(serverConn, config, extraConf) 955 err := server.Handshake() 956 if err == nil || err.Error() != "ALPN negotiation failed. Client offered: [\"proto1\" \"proto2\"]" { 957 t.Fatalf("Expected APLN negotiation to fail, got %s", err) 958 } 959 cErr := <-cErrChan 960 if cErr == nil || !strings.Contains(cErr.Error(), "no application protocol") { 961 t.Fatalf("Expect 'no_application_protocol' error, got %s", cErr) 962 } 963} 964 965func TestHandshakeServerALPNNoMatch(t *testing.T) { 966 config := testConfig.Clone() 967 config.NextProtos = []string{"proto3"} 968 969 test := &serverTest{ 970 name: "ALPN-NoMatch", 971 // Note that this needs OpenSSL 1.0.2 because that is the first 972 // version that supports the -alpn flag. 973 command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, 974 config: config, 975 validate: func(state ConnectionState) error { 976 // Rather than reject the connection, Go doesn't select 977 // a protocol when there is no overlap. 978 if state.NegotiatedProtocol != "" { 979 return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol) 980 } 981 return nil 982 }, 983 } 984 runServerTestTLS12(t, test) 985 runServerTestTLS13(t, test) 986} 987 988// TestHandshakeServerSNI involves a client sending an SNI extension of 989// "snitest.com", which happens to match the CN of testSNICertificate. The test 990// verifies that the server correctly selects that certificate. 991func TestHandshakeServerSNI(t *testing.T) { 992 test := &serverTest{ 993 name: "SNI", 994 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"}, 995 } 996 runServerTestTLS12(t, test) 997} 998 999// TestHandshakeServerSNICertForName is similar to TestHandshakeServerSNI, but 1000// tests the dynamic GetCertificate method 1001func TestHandshakeServerSNIGetCertificate(t *testing.T) { 1002 config := testConfig.Clone() 1003 1004 // Replace the NameToCertificate map with a GetCertificate function 1005 nameToCert := config.NameToCertificate 1006 config.NameToCertificate = nil 1007 config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) { 1008 cert := nameToCert[clientHello.ServerName] 1009 return cert, nil 1010 } 1011 test := &serverTest{ 1012 name: "SNI-GetCertificate", 1013 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"}, 1014 config: config, 1015 } 1016 runServerTestTLS12(t, test) 1017} 1018 1019// TestHandshakeServerSNICertForNameNotFound is similar to 1020// TestHandshakeServerSNICertForName, but tests to make sure that when the 1021// GetCertificate method doesn't return a cert, we fall back to what's in 1022// the NameToCertificate map. 1023func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) { 1024 config := testConfig.Clone() 1025 1026 config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) { 1027 return nil, nil 1028 } 1029 test := &serverTest{ 1030 name: "SNI-GetCertificateNotFound", 1031 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"}, 1032 config: config, 1033 } 1034 runServerTestTLS12(t, test) 1035} 1036 1037// TestHandshakeServerSNICertForNameError tests to make sure that errors in 1038// GetCertificate result in a tls alert. 1039func TestHandshakeServerSNIGetCertificateError(t *testing.T) { 1040 const errMsg = "TestHandshakeServerSNIGetCertificateError error" 1041 1042 serverConfig := testConfig.Clone() 1043 serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) { 1044 return nil, errors.New(errMsg) 1045 } 1046 1047 clientHello := &clientHelloMsg{ 1048 vers: VersionTLS10, 1049 random: make([]byte, 32), 1050 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 1051 compressionMethods: []uint8{compressionNone}, 1052 serverName: "test", 1053 } 1054 testClientHelloFailure(t, serverConfig, clientHello, errMsg) 1055} 1056 1057// TestHandshakeServerEmptyCertificates tests that GetCertificates is called in 1058// the case that Certificates is empty, even without SNI. 1059func TestHandshakeServerEmptyCertificates(t *testing.T) { 1060 const errMsg = "TestHandshakeServerEmptyCertificates error" 1061 1062 serverConfig := testConfig.Clone() 1063 serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) { 1064 return nil, errors.New(errMsg) 1065 } 1066 serverConfig.Certificates = nil 1067 1068 clientHello := &clientHelloMsg{ 1069 vers: VersionTLS10, 1070 random: make([]byte, 32), 1071 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 1072 compressionMethods: []uint8{compressionNone}, 1073 } 1074 testClientHelloFailure(t, serverConfig, clientHello, errMsg) 1075 1076 // With an empty Certificates and a nil GetCertificate, the server 1077 // should always return a “no certificates” error. 1078 serverConfig.GetCertificate = nil 1079 1080 clientHello = &clientHelloMsg{ 1081 vers: VersionTLS10, 1082 random: make([]byte, 32), 1083 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 1084 compressionMethods: []uint8{compressionNone}, 1085 } 1086 testClientHelloFailure(t, serverConfig, clientHello, "no certificates") 1087} 1088 1089// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with 1090// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate. 1091func TestCipherSuiteCertPreferenceECDSA(t *testing.T) { 1092 config := testConfig.Clone() 1093 config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA} 1094 config.PreferServerCipherSuites = true 1095 1096 test := &serverTest{ 1097 name: "CipherSuiteCertPreferenceRSA", 1098 config: config, 1099 } 1100 runServerTestTLS12(t, test) 1101 1102 config = testConfig.Clone() 1103 config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} 1104 config.Certificates = []Certificate{ 1105 { 1106 Certificate: [][]byte{testECDSACertificate}, 1107 PrivateKey: testECDSAPrivateKey, 1108 }, 1109 } 1110 config.BuildNameToCertificate() 1111 config.PreferServerCipherSuites = true 1112 1113 test = &serverTest{ 1114 name: "CipherSuiteCertPreferenceECDSA", 1115 config: config, 1116 } 1117 runServerTestTLS12(t, test) 1118} 1119 1120func TestServerResumption(t *testing.T) { 1121 sessionFilePath := tempFile("") 1122 defer os.Remove(sessionFilePath) 1123 1124 testIssue := &serverTest{ 1125 name: "IssueTicket", 1126 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath}, 1127 wait: true, 1128 } 1129 testResume := &serverTest{ 1130 name: "Resume", 1131 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath}, 1132 validate: func(state ConnectionState) error { 1133 if !state.DidResume { 1134 return errors.New("did not resume") 1135 } 1136 return nil 1137 }, 1138 } 1139 1140 runServerTestTLS12(t, testIssue) 1141 runServerTestTLS12(t, testResume) 1142 1143 runServerTestTLS13(t, testIssue) 1144 runServerTestTLS13(t, testResume) 1145 1146 config := testConfig.Clone() 1147 config.CurvePreferences = []CurveID{CurveP256} 1148 1149 testResumeHRR := &serverTest{ 1150 name: "Resume-HelloRetryRequest", 1151 command: []string{"openssl", "s_client", "-curves", "X25519:P-256", "-cipher", "AES128-SHA", "-ciphersuites", 1152 "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath}, 1153 config: config, 1154 validate: func(state ConnectionState) error { 1155 if !state.DidResume { 1156 return errors.New("did not resume") 1157 } 1158 return nil 1159 }, 1160 } 1161 1162 runServerTestTLS13(t, testResumeHRR) 1163} 1164 1165func TestServerResumptionDisabled(t *testing.T) { 1166 sessionFilePath := tempFile("") 1167 defer os.Remove(sessionFilePath) 1168 1169 config := testConfig.Clone() 1170 1171 testIssue := &serverTest{ 1172 name: "IssueTicketPreDisable", 1173 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath}, 1174 config: config, 1175 wait: true, 1176 } 1177 testResume := &serverTest{ 1178 name: "ResumeDisabled", 1179 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath}, 1180 config: config, 1181 validate: func(state ConnectionState) error { 1182 if state.DidResume { 1183 return errors.New("resumed with SessionTicketsDisabled") 1184 } 1185 return nil 1186 }, 1187 } 1188 1189 config.SessionTicketsDisabled = false 1190 runServerTestTLS12(t, testIssue) 1191 config.SessionTicketsDisabled = true 1192 runServerTestTLS12(t, testResume) 1193 1194 config.SessionTicketsDisabled = false 1195 runServerTestTLS13(t, testIssue) 1196 config.SessionTicketsDisabled = true 1197 runServerTestTLS13(t, testResume) 1198} 1199 1200func TestFallbackSCSV(t *testing.T) { 1201 serverConfig := Config{ 1202 Certificates: testConfig.Certificates, 1203 } 1204 test := &serverTest{ 1205 name: "FallbackSCSV", 1206 config: &serverConfig, 1207 // OpenSSL 1.0.1j is needed for the -fallback_scsv option. 1208 command: []string{"openssl", "s_client", "-fallback_scsv"}, 1209 expectHandshakeErrorIncluding: "inappropriate protocol fallback", 1210 } 1211 runServerTestTLS11(t, test) 1212} 1213 1214func TestHandshakeServerExportKeyingMaterial(t *testing.T) { 1215 test := &serverTest{ 1216 name: "ExportKeyingMaterial", 1217 command: []string{"openssl", "s_client", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, 1218 config: testConfig.Clone(), 1219 validate: func(state ConnectionState) error { 1220 if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil { 1221 return fmt.Errorf("ExportKeyingMaterial failed: %v", err) 1222 } else if len(km) != 42 { 1223 return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42) 1224 } 1225 return nil 1226 }, 1227 } 1228 runServerTestTLS10(t, test) 1229 runServerTestTLS12(t, test) 1230 runServerTestTLS13(t, test) 1231} 1232 1233func TestHandshakeServerRSAPKCS1v15(t *testing.T) { 1234 test := &serverTest{ 1235 name: "RSA-RSAPKCS1v15", 1236 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-sigalgs", "rsa_pkcs1_sha256"}, 1237 } 1238 runServerTestTLS12(t, test) 1239} 1240 1241func TestHandshakeServerRSAPSS(t *testing.T) { 1242 // We send rsa_pss_rsae_sha512 first, as the test key won't fit, and we 1243 // verify the server implementation will disregard the client preference in 1244 // that case. See Issue 29793. 1245 test := &serverTest{ 1246 name: "RSA-RSAPSS", 1247 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512:rsa_pss_rsae_sha256"}, 1248 } 1249 runServerTestTLS12(t, test) 1250 runServerTestTLS13(t, test) 1251 1252 test = &serverTest{ 1253 name: "RSA-RSAPSS-TooSmall", 1254 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512"}, 1255 expectHandshakeErrorIncluding: "peer doesn't support any of the certificate's signature algorithms", 1256 } 1257 runServerTestTLS13(t, test) 1258} 1259 1260func TestHandshakeServerEd25519(t *testing.T) { 1261 config := testConfig.Clone() 1262 config.Certificates = make([]Certificate, 1) 1263 config.Certificates[0].Certificate = [][]byte{testEd25519Certificate} 1264 config.Certificates[0].PrivateKey = testEd25519PrivateKey 1265 config.BuildNameToCertificate() 1266 1267 test := &serverTest{ 1268 name: "Ed25519", 1269 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, 1270 config: config, 1271 } 1272 runServerTestTLS12(t, test) 1273 runServerTestTLS13(t, test) 1274} 1275 1276func benchmarkHandshakeServer(b *testing.B, version uint16, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) { 1277 config := testConfig.Clone() 1278 config.CipherSuites = []uint16{cipherSuite} 1279 config.CurvePreferences = []CurveID{curve} 1280 config.Certificates = make([]Certificate, 1) 1281 config.Certificates[0].Certificate = [][]byte{cert} 1282 config.Certificates[0].PrivateKey = key 1283 config.BuildNameToCertificate() 1284 1285 clientConn, serverConn := localPipe(b) 1286 serverConn = &recordingConn{Conn: serverConn} 1287 go func() { 1288 config := testConfig.Clone() 1289 config.MaxVersion = version 1290 config.CurvePreferences = []CurveID{curve} 1291 client := Client(clientConn, config, nil) 1292 client.Handshake() 1293 }() 1294 server := Server(serverConn, config, nil) 1295 if err := server.Handshake(); err != nil { 1296 b.Fatalf("handshake failed: %v", err) 1297 } 1298 serverConn.Close() 1299 flows := serverConn.(*recordingConn).flows 1300 1301 feeder := make(chan struct{}) 1302 clientConn, serverConn = localPipe(b) 1303 1304 go func() { 1305 for range feeder { 1306 for i, f := range flows { 1307 if i%2 == 0 { 1308 clientConn.Write(f) 1309 continue 1310 } 1311 ff := make([]byte, len(f)) 1312 n, err := io.ReadFull(clientConn, ff) 1313 if err != nil { 1314 b.Errorf("#%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", i+1, err, n, len(ff), ff[:n], f) 1315 } 1316 if !bytes.Equal(f, ff) { 1317 b.Errorf("#%d: mismatch on read: got:%x want:%x", i+1, ff, f) 1318 } 1319 } 1320 } 1321 }() 1322 1323 b.ResetTimer() 1324 for i := 0; i < b.N; i++ { 1325 feeder <- struct{}{} 1326 server := Server(serverConn, config, nil) 1327 if err := server.Handshake(); err != nil { 1328 b.Fatalf("handshake failed: %v", err) 1329 } 1330 } 1331 close(feeder) 1332} 1333 1334func BenchmarkHandshakeServer(b *testing.B) { 1335 b.Run("RSA", func(b *testing.B) { 1336 benchmarkHandshakeServer(b, VersionTLS12, TLS_RSA_WITH_AES_128_GCM_SHA256, 1337 0, testRSACertificate, testRSAPrivateKey) 1338 }) 1339 b.Run("ECDHE-P256-RSA", func(b *testing.B) { 1340 b.Run("TLSv13", func(b *testing.B) { 1341 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1342 CurveP256, testRSACertificate, testRSAPrivateKey) 1343 }) 1344 b.Run("TLSv12", func(b *testing.B) { 1345 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1346 CurveP256, testRSACertificate, testRSAPrivateKey) 1347 }) 1348 }) 1349 b.Run("ECDHE-P256-ECDSA-P256", func(b *testing.B) { 1350 b.Run("TLSv13", func(b *testing.B) { 1351 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 1352 CurveP256, testP256Certificate, testP256PrivateKey) 1353 }) 1354 b.Run("TLSv12", func(b *testing.B) { 1355 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 1356 CurveP256, testP256Certificate, testP256PrivateKey) 1357 }) 1358 }) 1359 b.Run("ECDHE-X25519-ECDSA-P256", func(b *testing.B) { 1360 b.Run("TLSv13", func(b *testing.B) { 1361 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 1362 X25519, testP256Certificate, testP256PrivateKey) 1363 }) 1364 b.Run("TLSv12", func(b *testing.B) { 1365 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 1366 X25519, testP256Certificate, testP256PrivateKey) 1367 }) 1368 }) 1369 b.Run("ECDHE-P521-ECDSA-P521", func(b *testing.B) { 1370 if testECDSAPrivateKey.PublicKey.Curve != elliptic.P521() { 1371 b.Fatal("test ECDSA key doesn't use curve P-521") 1372 } 1373 b.Run("TLSv13", func(b *testing.B) { 1374 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 1375 CurveP521, testECDSACertificate, testECDSAPrivateKey) 1376 }) 1377 b.Run("TLSv12", func(b *testing.B) { 1378 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 1379 CurveP521, testECDSACertificate, testECDSAPrivateKey) 1380 }) 1381 }) 1382} 1383 1384func TestClientAuth(t *testing.T) { 1385 var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath, ed25519CertPath, ed25519KeyPath string 1386 1387 if *update { 1388 certPath = tempFile(clientCertificatePEM) 1389 defer os.Remove(certPath) 1390 keyPath = tempFile(clientKeyPEM) 1391 defer os.Remove(keyPath) 1392 ecdsaCertPath = tempFile(clientECDSACertificatePEM) 1393 defer os.Remove(ecdsaCertPath) 1394 ecdsaKeyPath = tempFile(clientECDSAKeyPEM) 1395 defer os.Remove(ecdsaKeyPath) 1396 ed25519CertPath = tempFile(clientEd25519CertificatePEM) 1397 defer os.Remove(ed25519CertPath) 1398 ed25519KeyPath = tempFile(clientEd25519KeyPEM) 1399 defer os.Remove(ed25519KeyPath) 1400 } else { 1401 t.Parallel() 1402 } 1403 1404 config := testConfig.Clone() 1405 config.ClientAuth = RequestClientCert 1406 1407 test := &serverTest{ 1408 name: "ClientAuthRequestedNotGiven", 1409 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"}, 1410 config: config, 1411 } 1412 runServerTestTLS12(t, test) 1413 runServerTestTLS13(t, test) 1414 1415 test = &serverTest{ 1416 name: "ClientAuthRequestedAndGiven", 1417 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", 1418 "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pss_rsae_sha256"}, 1419 config: config, 1420 expectedPeerCerts: []string{clientCertificatePEM}, 1421 } 1422 runServerTestTLS12(t, test) 1423 runServerTestTLS13(t, test) 1424 1425 test = &serverTest{ 1426 name: "ClientAuthRequestedAndECDSAGiven", 1427 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", 1428 "-cert", ecdsaCertPath, "-key", ecdsaKeyPath}, 1429 config: config, 1430 expectedPeerCerts: []string{clientECDSACertificatePEM}, 1431 } 1432 runServerTestTLS12(t, test) 1433 runServerTestTLS13(t, test) 1434 1435 test = &serverTest{ 1436 name: "ClientAuthRequestedAndEd25519Given", 1437 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", 1438 "-cert", ed25519CertPath, "-key", ed25519KeyPath}, 1439 config: config, 1440 expectedPeerCerts: []string{clientEd25519CertificatePEM}, 1441 } 1442 runServerTestTLS12(t, test) 1443 runServerTestTLS13(t, test) 1444 1445 test = &serverTest{ 1446 name: "ClientAuthRequestedAndPKCS1v15Given", 1447 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", 1448 "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pkcs1_sha256"}, 1449 config: config, 1450 expectedPeerCerts: []string{clientCertificatePEM}, 1451 } 1452 runServerTestTLS12(t, test) 1453} 1454 1455func TestSNIGivenOnFailure(t *testing.T) { 1456 const expectedServerName = "test.testing" 1457 1458 clientHello := &clientHelloMsg{ 1459 vers: VersionTLS10, 1460 random: make([]byte, 32), 1461 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 1462 compressionMethods: []uint8{compressionNone}, 1463 serverName: expectedServerName, 1464 } 1465 1466 serverConfig := testConfig.Clone() 1467 // Erase the server's cipher suites to ensure the handshake fails. 1468 serverConfig.CipherSuites = nil 1469 1470 c, s := localPipe(t) 1471 go func() { 1472 cli := Client(c, testConfig, nil) 1473 cli.vers = clientHello.vers 1474 cli.writeRecord(recordTypeHandshake, clientHello.marshal()) 1475 c.Close() 1476 }() 1477 conn := Server(s, serverConfig, nil) 1478 ch, err := conn.readClientHello() 1479 hs := serverHandshakeState{ 1480 c: conn, 1481 clientHello: ch, 1482 } 1483 if err == nil { 1484 err = hs.processClientHello() 1485 } 1486 if err == nil { 1487 err = hs.pickCipherSuite() 1488 } 1489 defer s.Close() 1490 1491 if err == nil { 1492 t.Error("No error reported from server") 1493 } 1494 1495 cs := hs.c.ConnectionState() 1496 if cs.HandshakeComplete { 1497 t.Error("Handshake registered as complete") 1498 } 1499 1500 if cs.ServerName != expectedServerName { 1501 t.Errorf("Expected ServerName of %q, but got %q", expectedServerName, cs.ServerName) 1502 } 1503} 1504 1505var getConfigForClientTests = []struct { 1506 setup func(config *Config) 1507 callback func(clientHello *ClientHelloInfo) (*Config, error) 1508 errorSubstring string 1509 verify func(config *Config) error 1510}{ 1511 { 1512 nil, 1513 func(clientHello *ClientHelloInfo) (*Config, error) { 1514 return nil, nil 1515 }, 1516 "", 1517 nil, 1518 }, 1519 { 1520 nil, 1521 func(clientHello *ClientHelloInfo) (*Config, error) { 1522 return nil, errors.New("should bubble up") 1523 }, 1524 "should bubble up", 1525 nil, 1526 }, 1527 { 1528 nil, 1529 func(clientHello *ClientHelloInfo) (*Config, error) { 1530 config := testConfig.Clone() 1531 // Setting a maximum version of TLS 1.1 should cause 1532 // the handshake to fail, as the client MinVersion is TLS 1.2. 1533 config.MaxVersion = VersionTLS11 1534 return config, nil 1535 }, 1536 "client offered only unsupported versions", 1537 nil, 1538 }, 1539 { 1540 func(config *Config) { 1541 for i := range config.SessionTicketKey { 1542 config.SessionTicketKey[i] = byte(i) 1543 } 1544 fromConfig(config).sessionTicketKeys = nil 1545 }, 1546 func(clientHello *ClientHelloInfo) (*Config, error) { 1547 config := testConfig.Clone() 1548 for i := range config.SessionTicketKey { 1549 config.SessionTicketKey[i] = 0 1550 } 1551 fromConfig(config).sessionTicketKeys = nil 1552 return config, nil 1553 }, 1554 "", 1555 func(config *Config) error { 1556 if config.SessionTicketKey == [32]byte{} { 1557 return fmt.Errorf("expected SessionTicketKey to be set") 1558 } 1559 return nil 1560 }, 1561 }, 1562 { 1563 func(config *Config) { 1564 var dummyKey [32]byte 1565 for i := range dummyKey { 1566 dummyKey[i] = byte(i) 1567 } 1568 1569 config.SetSessionTicketKeys([][32]byte{dummyKey}) 1570 }, 1571 func(clientHello *ClientHelloInfo) (*Config, error) { 1572 config := testConfig.Clone() 1573 fromConfig(config).sessionTicketKeys = nil 1574 return config, nil 1575 }, 1576 "", 1577 func(config *Config) error { 1578 if config.SessionTicketKey == [32]byte{} { 1579 return fmt.Errorf("expected SessionTicketKey to be set") 1580 } 1581 return nil 1582 }, 1583 }, 1584} 1585 1586func TestGetConfigForClient(t *testing.T) { 1587 serverConfig := testConfig.Clone() 1588 clientConfig := testConfig.Clone() 1589 clientConfig.MinVersion = VersionTLS12 1590 1591 for i, test := range getConfigForClientTests { 1592 if test.setup != nil { 1593 test.setup(serverConfig) 1594 } 1595 1596 var configReturned *Config 1597 serverConfig.GetConfigForClient = func(clientHello *ClientHelloInfo) (*Config, error) { 1598 config, err := test.callback(clientHello) 1599 configReturned = config 1600 return config, err 1601 } 1602 c, s := localPipe(t) 1603 done := make(chan error) 1604 1605 go func() { 1606 defer s.Close() 1607 done <- Server(s, serverConfig, nil).Handshake() 1608 }() 1609 1610 clientErr := Client(c, clientConfig, nil).Handshake() 1611 c.Close() 1612 1613 serverErr := <-done 1614 1615 if len(test.errorSubstring) == 0 { 1616 if serverErr != nil || clientErr != nil { 1617 t.Errorf("test[%d]: expected no error but got serverErr: %q, clientErr: %q", i, serverErr, clientErr) 1618 } 1619 if test.verify != nil { 1620 if err := test.verify(configReturned); err != nil { 1621 t.Errorf("test[%d]: verify returned error: %v", i, err) 1622 } 1623 } 1624 } else { 1625 if serverErr == nil { 1626 t.Errorf("test[%d]: expected error containing %q but got no error", i, test.errorSubstring) 1627 } else if !strings.Contains(serverErr.Error(), test.errorSubstring) { 1628 t.Errorf("test[%d]: expected error to contain %q but it was %q", i, test.errorSubstring, serverErr) 1629 } 1630 } 1631 } 1632} 1633 1634func TestAdditionalExtensionsReceivedByServer(t *testing.T) { 1635 c, s := net.Pipe() 1636 done := make(chan bool) 1637 1638 config := testConfig.Clone() 1639 config.MinVersion = VersionTLS13 1640 config.MaxVersion = VersionTLS13 1641 cExtraConf := &ExtraConfig{} 1642 cExtraConf.GetExtensions = func(_ uint8) []Extension { 1643 return []Extension{ 1644 {Type: 0x1337, Data: []byte("foobar")}, 1645 } 1646 } 1647 go func() { 1648 Client(s, config, cExtraConf).Handshake() 1649 s.Close() 1650 done <- true 1651 }() 1652 1653 var receivedExtensions bool 1654 sExtraConf := &ExtraConfig{} 1655 sExtraConf.ReceivedExtensions = func(handshakeMessageType uint8, exts []Extension) { 1656 receivedExtensions = true 1657 if handshakeMessageType != typeClientHello { 1658 t.Errorf("expected handshake message type to be %d, but got %d", typeClientHello, handshakeMessageType) 1659 } 1660 // TODO(#84): parse signature_algorithms_cert 1661 if len(exts) == 2 && exts[0].Type == 50 { 1662 exts = exts[1:] 1663 } 1664 if len(exts) != 1 { 1665 t.Errorf("expected to received 1 extension, got %d", len(exts)) 1666 } 1667 if exts[0].Type != 0x1337 { 1668 t.Errorf("expected extension type 0x1337, got %#x", exts[0].Type) 1669 } 1670 if string(exts[0].Data) != "foobar" { 1671 t.Errorf("expection extension data to be foobar, got %s", exts[0].Data) 1672 } 1673 } 1674 err := Server(c, config, sExtraConf).Handshake() 1675 if err != nil { 1676 t.Errorf("expected client to complete handshake, got %s", err) 1677 } 1678 if !receivedExtensions { 1679 t.Errorf("expected client to receive extensions") 1680 } 1681} 1682 1683func TestCloseServerConnectionOnIdleClient(t *testing.T) { 1684 clientConn, serverConn := localPipe(t) 1685 server := Server(serverConn, testConfig.Clone(), nil) 1686 go func() { 1687 clientConn.Write([]byte{'0'}) 1688 server.Close() 1689 }() 1690 server.SetReadDeadline(time.Now().Add(time.Minute)) 1691 err := server.Handshake() 1692 if err != nil { 1693 if err, ok := err.(net.Error); ok && err.Timeout() { 1694 t.Errorf("Expected a closed network connection error but got '%s'", err.Error()) 1695 } 1696 } else { 1697 t.Errorf("Error expected, but no error returned") 1698 } 1699} 1700 1701func TestCloneHash(t *testing.T) { 1702 h1 := crypto.SHA256.New() 1703 h1.Write([]byte("test")) 1704 s1 := h1.Sum(nil) 1705 h2 := cloneHash(h1, crypto.SHA256) 1706 s2 := h2.Sum(nil) 1707 if !bytes.Equal(s1, s2) { 1708 t.Error("cloned hash generated a different sum") 1709 } 1710} 1711 1712func expectError(t *testing.T, err error, sub string) { 1713 if err == nil { 1714 t.Errorf(`expected error %q, got nil`, sub) 1715 } else if !strings.Contains(err.Error(), sub) { 1716 t.Errorf(`expected error %q, got %q`, sub, err) 1717 } 1718} 1719 1720func TestKeyTooSmallForRSAPSS(t *testing.T) { 1721 cert, err := X509KeyPair([]byte(`-----BEGIN CERTIFICATE----- 1722MIIBcTCCARugAwIBAgIQGjQnkCFlUqaFlt6ixyz/tDANBgkqhkiG9w0BAQsFADAS 1723MRAwDgYDVQQKEwdBY21lIENvMB4XDTE5MDExODIzMjMyOFoXDTIwMDExODIzMjMy 1724OFowEjEQMA4GA1UEChMHQWNtZSBDbzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDd 1725ez1rFUDwax2HTxbcnFUP9AhcgEGMHVV2nn4VVEWFJB6I8C/Nkx0XyyQlrmFYBzEQ 1726nIPhKls4T0hFoLvjJnXpAgMBAAGjTTBLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE 1727DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBYGA1UdEQQPMA2CC2V4YW1wbGUu 1728Y29tMA0GCSqGSIb3DQEBCwUAA0EAxDuUS+BrrS3c+h+k+fQPOmOScy6yTX9mHw0Q 1729KbucGamXYEy0URIwOdO0tQ3LHPc1YGvYSPwkDjkjqECs2Vm/AA== 1730-----END CERTIFICATE-----`), []byte(testingKey(`-----BEGIN RSA TESTING KEY----- 1731MIIBOgIBAAJBAN17PWsVQPBrHYdPFtycVQ/0CFyAQYwdVXaefhVURYUkHojwL82T 1732HRfLJCWuYVgHMRCcg+EqWzhPSEWgu+MmdekCAwEAAQJBALjQYNTdXF4CFBbXwUz/ 1733yt9QFDYT9B5WT/12jeGAe653gtYS6OOi/+eAkGmzg1GlRnw6fOfn+HYNFDORST7z 17344j0CIQDn2xz9hVWQEu9ee3vecNT3f60huDGTNoRhtqgweQGX0wIhAPSLj1VcRZEz 1735nKpbtU22+PbIMSJ+e80fmY9LIPx5N4HTAiAthGSimMR9bloz0EY3GyuUEyqoDgMd 1736hXxjuno2WesoJQIgemilbcALXpxsLmZLgcQ2KSmaVr7jb5ECx9R+hYKTw1sCIG4s 1737T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g 1738-----END RSA TESTING KEY-----`))) 1739 if err != nil { 1740 t.Fatal(err) 1741 } 1742 1743 clientConn, serverConn := localPipe(t) 1744 client := Client(clientConn, testConfig, nil) 1745 done := make(chan struct{}) 1746 go func() { 1747 config := testConfig.Clone() 1748 config.Certificates = []Certificate{cert} 1749 config.MinVersion = VersionTLS13 1750 server := Server(serverConn, config, nil) 1751 err := server.Handshake() 1752 expectError(t, err, "key size too small") 1753 close(done) 1754 }() 1755 err = client.Handshake() 1756 expectError(t, err, "handshake failure") 1757 <-done 1758} 1759 1760func TestMultipleCertificates(t *testing.T) { 1761 clientConfig := testConfig.Clone() 1762 clientConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256} 1763 clientConfig.MaxVersion = VersionTLS12 1764 1765 serverConfig := testConfig.Clone() 1766 serverConfig.Certificates = []Certificate{{ 1767 Certificate: [][]byte{testECDSACertificate}, 1768 PrivateKey: testECDSAPrivateKey, 1769 }, { 1770 Certificate: [][]byte{testRSACertificate}, 1771 PrivateKey: testRSAPrivateKey, 1772 }} 1773 1774 _, clientState, err := testHandshake(t, clientConfig, serverConfig) 1775 if err != nil { 1776 t.Fatal(err) 1777 } 1778 if got := clientState.PeerCertificates[0].PublicKeyAlgorithm; got != x509.RSA { 1779 t.Errorf("expected RSA certificate, got %v", got) 1780 } 1781} 1782 1783func TestAESCipherReordering(t *testing.T) { 1784 currentAESSupport := hasAESGCMHardwareSupport 1785 defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }() 1786 1787 tests := []struct { 1788 name string 1789 clientCiphers []uint16 1790 serverHasAESGCM bool 1791 preferServerCipherSuites bool 1792 serverCiphers []uint16 1793 expectedCipher uint16 1794 }{ 1795 { 1796 name: "server has hardware AES, client doesn't (pick ChaCha)", 1797 clientCiphers: []uint16{ 1798 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1799 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1800 TLS_RSA_WITH_AES_128_CBC_SHA, 1801 }, 1802 serverHasAESGCM: true, 1803 preferServerCipherSuites: true, 1804 expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1805 }, 1806 { 1807 name: "server strongly prefers AES-GCM, client doesn't (pick AES-GCM)", 1808 clientCiphers: []uint16{ 1809 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1810 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1811 TLS_RSA_WITH_AES_128_CBC_SHA, 1812 }, 1813 serverHasAESGCM: true, 1814 preferServerCipherSuites: true, 1815 serverCiphers: []uint16{ 1816 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1817 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1818 TLS_RSA_WITH_AES_128_CBC_SHA, 1819 }, 1820 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1821 }, 1822 { 1823 name: "client prefers AES-GCM, server doesn't have hardware AES (pick ChaCha)", 1824 clientCiphers: []uint16{ 1825 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1826 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1827 TLS_RSA_WITH_AES_128_CBC_SHA, 1828 }, 1829 serverHasAESGCM: false, 1830 expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1831 }, 1832 { 1833 name: "client prefers AES-GCM, server has hardware AES (pick AES-GCM)", 1834 clientCiphers: []uint16{ 1835 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1836 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1837 TLS_RSA_WITH_AES_128_CBC_SHA, 1838 }, 1839 serverHasAESGCM: true, 1840 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1841 }, 1842 { 1843 name: "client prefers AES-GCM and sends GREASE, server has hardware AES (pick AES-GCM)", 1844 clientCiphers: []uint16{ 1845 0x0A0A, // GREASE value 1846 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1847 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1848 TLS_RSA_WITH_AES_128_CBC_SHA, 1849 }, 1850 serverHasAESGCM: true, 1851 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1852 }, 1853 { 1854 name: "client prefers AES-GCM and doesn't support ChaCha, server doesn't have hardware AES (pick AES-GCM)", 1855 clientCiphers: []uint16{ 1856 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1857 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 1858 TLS_RSA_WITH_AES_128_CBC_SHA, 1859 }, 1860 serverHasAESGCM: false, 1861 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1862 }, 1863 { 1864 name: "client prefers AES-GCM and AES-CBC over ChaCha, server doesn't have hardware AES (pick AES-GCM)", 1865 clientCiphers: []uint16{ 1866 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1867 TLS_RSA_WITH_AES_128_CBC_SHA, 1868 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1869 }, 1870 serverHasAESGCM: false, 1871 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1872 }, 1873 { 1874 name: "client prefers AES-GCM over ChaCha and sends GREASE, server doesn't have hardware AES (pick ChaCha)", 1875 clientCiphers: []uint16{ 1876 0x0A0A, // GREASE value 1877 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1878 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1879 TLS_RSA_WITH_AES_128_CBC_SHA, 1880 }, 1881 serverHasAESGCM: false, 1882 expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1883 }, 1884 { 1885 name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (pick corrent AES-GCM)", 1886 clientCiphers: []uint16{ 1887 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 1888 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 1889 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1890 }, 1891 serverHasAESGCM: false, 1892 serverCiphers: []uint16{ 1893 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 1894 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1895 }, 1896 expectedCipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 1897 }, 1898 } 1899 1900 for _, tc := range tests { 1901 t.Run(tc.name, func(t *testing.T) { 1902 hasAESGCMHardwareSupport = tc.serverHasAESGCM 1903 initDefaultCipherSuites() 1904 hs := &serverHandshakeState{ 1905 c: &Conn{ 1906 config: &config{ 1907 PreferServerCipherSuites: tc.preferServerCipherSuites, 1908 CipherSuites: tc.serverCiphers, 1909 }, 1910 vers: VersionTLS12, 1911 }, 1912 clientHello: &clientHelloMsg{ 1913 cipherSuites: tc.clientCiphers, 1914 vers: VersionTLS12, 1915 }, 1916 ecdheOk: true, 1917 rsaSignOk: true, 1918 rsaDecryptOk: true, 1919 } 1920 1921 err := hs.pickCipherSuite() 1922 if err != nil { 1923 t.Errorf("pickCipherSuite failed: %s", err) 1924 } 1925 1926 if tc.expectedCipher != hs.suite.id { 1927 t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id) 1928 } 1929 }) 1930 } 1931} 1932 1933func TestAESCipherReordering13(t *testing.T) { 1934 currentAESSupport := hasAESGCMHardwareSupport 1935 defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }() 1936 1937 tests := []struct { 1938 name string 1939 clientCiphers []uint16 1940 serverHasAESGCM bool 1941 preferServerCipherSuites bool 1942 expectedCipher uint16 1943 }{ 1944 { 1945 name: "server has hardware AES, client doesn't (pick ChaCha)", 1946 clientCiphers: []uint16{ 1947 TLS_CHACHA20_POLY1305_SHA256, 1948 TLS_AES_128_GCM_SHA256, 1949 }, 1950 serverHasAESGCM: true, 1951 preferServerCipherSuites: true, 1952 expectedCipher: TLS_CHACHA20_POLY1305_SHA256, 1953 }, 1954 { 1955 name: "neither server nor client have hardware AES (pick ChaCha)", 1956 clientCiphers: []uint16{ 1957 TLS_CHACHA20_POLY1305_SHA256, 1958 TLS_AES_128_GCM_SHA256, 1959 }, 1960 serverHasAESGCM: false, 1961 preferServerCipherSuites: true, 1962 expectedCipher: TLS_CHACHA20_POLY1305_SHA256, 1963 }, 1964 { 1965 name: "client prefers AES, server doesn't have hardware, prefer server ciphers (pick ChaCha)", 1966 clientCiphers: []uint16{ 1967 TLS_AES_128_GCM_SHA256, 1968 TLS_CHACHA20_POLY1305_SHA256, 1969 }, 1970 serverHasAESGCM: false, 1971 preferServerCipherSuites: true, 1972 expectedCipher: TLS_CHACHA20_POLY1305_SHA256, 1973 }, 1974 { 1975 name: "client prefers AES and sends GREASE, server doesn't have hardware, prefer server ciphers (pick ChaCha)", 1976 clientCiphers: []uint16{ 1977 0x0A0A, // GREASE value 1978 TLS_AES_128_GCM_SHA256, 1979 TLS_CHACHA20_POLY1305_SHA256, 1980 }, 1981 serverHasAESGCM: false, 1982 preferServerCipherSuites: true, 1983 expectedCipher: TLS_CHACHA20_POLY1305_SHA256, 1984 }, 1985 { 1986 name: "client prefers AES, server doesn't (pick ChaCha)", 1987 clientCiphers: []uint16{ 1988 TLS_AES_128_GCM_SHA256, 1989 TLS_CHACHA20_POLY1305_SHA256, 1990 }, 1991 serverHasAESGCM: false, 1992 expectedCipher: TLS_CHACHA20_POLY1305_SHA256, 1993 }, 1994 { 1995 name: "client prefers AES, server has hardware AES (pick AES)", 1996 clientCiphers: []uint16{ 1997 TLS_AES_128_GCM_SHA256, 1998 TLS_CHACHA20_POLY1305_SHA256, 1999 }, 2000 serverHasAESGCM: true, 2001 expectedCipher: TLS_AES_128_GCM_SHA256, 2002 }, 2003 { 2004 name: "client prefers AES and sends GREASE, server has hardware AES (pick AES)", 2005 clientCiphers: []uint16{ 2006 0x0A0A, // GREASE value 2007 TLS_AES_128_GCM_SHA256, 2008 TLS_CHACHA20_POLY1305_SHA256, 2009 }, 2010 serverHasAESGCM: true, 2011 expectedCipher: TLS_AES_128_GCM_SHA256, 2012 }, 2013 } 2014 2015 for _, tc := range tests { 2016 t.Run(tc.name, func(t *testing.T) { 2017 hasAESGCMHardwareSupport = tc.serverHasAESGCM 2018 initDefaultCipherSuites() 2019 hs := &serverHandshakeStateTLS13{ 2020 c: &Conn{ 2021 config: &config{ 2022 PreferServerCipherSuites: tc.preferServerCipherSuites, 2023 }, 2024 vers: VersionTLS13, 2025 }, 2026 clientHello: &clientHelloMsg{ 2027 cipherSuites: tc.clientCiphers, 2028 supportedVersions: []uint16{VersionTLS13}, 2029 compressionMethods: []uint8{compressionNone}, 2030 keyShares: []keyShare{{group: X25519, data: curve25519.Basepoint}}, 2031 }, 2032 } 2033 2034 err := hs.processClientHello() 2035 if err != nil { 2036 t.Errorf("pickCipherSuite failed: %s", err) 2037 } 2038 2039 if tc.expectedCipher != hs.suite.id { 2040 t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id) 2041 } 2042 }) 2043 } 2044} 2045