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