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.
24 "golang.org/x/crypto/curve25519"
27 func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
28 testClientHelloFailure(t, serverConfig, m, "")
31 func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) {
34 cli := Client(c, testConfig)
35 if ch, ok := m.(*clientHelloMsg); ok {
38 cli.writeRecord(recordTypeHandshake, m.marshal())
41 conn := Server(s, serverConfig)
42 ch, err := conn.readClientHello()
43 hs := serverHandshakeState{
48 err = hs.processClientHello()
51 err = hs.pickCipherSuite()
54 if len(expectedSubStr) == 0 {
55 if err != nil && err != io.EOF {
56 t.Errorf("Got error: %s; expected to succeed", err)
58 } else if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
59 t.Errorf("Got error: %v; expected to match substring '%s'", err, expectedSubStr)
63 func TestSimpleError(t *testing.T) {
64 testClientHelloFailure(t, testConfig, &serverHelloDoneMsg{}, "unexpected handshake message")
67 var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205, VersionSSL30}
69 func TestRejectBadProtocolVersion(t *testing.T) {
70 config := testConfig.Clone()
71 config.MinVersion = VersionSSL30
72 for _, v := range badProtocolVersions {
73 testClientHelloFailure(t, config, &clientHelloMsg{
75 random: make([]byte, 32),
76 }, "unsupported versions")
78 testClientHelloFailure(t, config, &clientHelloMsg{
80 supportedVersions: badProtocolVersions,
81 random: make([]byte, 32),
82 }, "unsupported versions")
85 func TestNoSuiteOverlap(t *testing.T) {
86 clientHello := &clientHelloMsg{
88 random: make([]byte, 32),
89 cipherSuites: []uint16{0xff00},
90 compressionMethods: []uint8{compressionNone},
92 testClientHelloFailure(t, testConfig, clientHello, "no cipher suite supported by both client and server")
95 func TestNoCompressionOverlap(t *testing.T) {
96 clientHello := &clientHelloMsg{
98 random: make([]byte, 32),
99 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
100 compressionMethods: []uint8{0xff},
102 testClientHelloFailure(t, testConfig, clientHello, "client does not support uncompressed connections")
105 func TestNoRC4ByDefault(t *testing.T) {
106 clientHello := &clientHelloMsg{
108 random: make([]byte, 32),
109 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
110 compressionMethods: []uint8{compressionNone},
112 serverConfig := testConfig.Clone()
113 // Reset the enabled cipher suites to nil in order to test the
115 serverConfig.CipherSuites = nil
116 testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
119 func TestRejectSNIWithTrailingDot(t *testing.T) {
120 testClientHelloFailure(t, testConfig, &clientHelloMsg{
122 random: make([]byte, 32),
123 serverName: "foo.com.",
124 }, "unexpected message")
127 func 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{
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},
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)
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")
153 func 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{
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},
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)
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")
178 func TestRenegotiationExtension(t *testing.T) {
179 clientHello := &clientHelloMsg{
181 compressionMethods: []uint8{compressionNone},
182 random: make([]byte, 32),
183 secureRenegotiationSupported: true,
184 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
187 bufChan := make(chan []byte, 1)
191 cli := Client(c, testConfig)
192 cli.vers = clientHello.vers
193 cli.writeRecord(recordTypeHandshake, clientHello.marshal())
195 buf := make([]byte, 1024)
196 n, err := c.Read(buf)
198 t.Errorf("Server read returned error: %s", err)
205 Server(s, testConfig).Handshake()
209 t.Fatalf("Server returned short message of length %d", len(buf))
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
214 serverHelloLen := int(buf[6])<<16 | int(buf[7])<<8 | int(buf[8])
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")
223 if !serverHello.secureRenegotiationSupported {
224 t.Errorf("Secure renegotiation extension was not echoed.")
228 func 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{
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,
242 compressionMethods: []uint8{compressionNone},
243 supportedCurves: []CurveID{CurveP256, CurveP384, CurveP521},
244 supportedPoints: []uint8{pointFormatUncompressed},
248 replyChan := make(chan interface{})
250 cli := Client(c, testConfig)
251 cli.vers = clientHello.vers
252 cli.writeRecord(recordTypeHandshake, clientHello.marshal())
253 reply, err := cli.readHandshake()
261 config := testConfig.Clone()
262 config.CipherSuites = clientHello.cipherSuites
263 Server(s, config).Handshake()
266 if err, ok := reply.(error); ok {
269 serverHello, ok := reply.(*serverHelloMsg)
271 t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
273 if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA {
274 t.Fatalf("bad cipher suite from server: %x", s)
278 func 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.
283 cipherSuites []uint16
284 supportedCurves []CurveID
285 supportedPoints []uint8
286 wantSupportedPoints bool
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},
291 for _, tt := range tests {
292 t.Run(tt.name, func(t *testing.T) {
293 clientHello := &clientHelloMsg{
295 random: make([]byte, 32),
296 cipherSuites: tt.cipherSuites,
297 compressionMethods: []uint8{compressionNone},
298 supportedCurves: tt.supportedCurves,
299 supportedPoints: tt.supportedPoints,
303 replyChan := make(chan interface{})
305 cli := Client(c, testConfig)
306 cli.vers = clientHello.vers
307 cli.writeRecord(recordTypeHandshake, clientHello.marshal())
308 reply, err := cli.readHandshake()
316 config := testConfig.Clone()
317 config.CipherSuites = clientHello.cipherSuites
318 Server(s, config).Handshake()
321 if err, ok := reply.(error); ok {
324 serverHello, ok := reply.(*serverHelloMsg)
326 t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
328 if tt.wantSupportedPoints {
329 if len(serverHello.supportedPoints) < 1 {
330 t.Fatal("missing ec_point_format extension from server")
333 for _, p := range serverHello.supportedPoints {
334 if p == pointFormatUncompressed {
340 t.Fatal("missing uncompressed format in ec_point_format extension from server")
343 if len(serverHello.supportedPoints) != 0 {
344 t.Fatalf("unexcpected ec_point_format extension from server: %v", serverHello.supportedPoints)
351 func TestAlertForwarding(t *testing.T) {
354 Client(c, testConfig).sendAlert(alertUnknownCA)
358 err := Server(s, testConfig).Handshake()
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))
366 func TestClose(t *testing.T) {
370 err := Server(s, testConfig).Handshake()
373 t.Errorf("Got error: %s; expected: %s", err, io.EOF)
377 func TestVersion(t *testing.T) {
378 serverConfig := &Config{
379 Certificates: testConfig.Certificates,
380 MaxVersion: VersionTLS11,
382 clientConfig := &Config{
383 InsecureSkipVerify: true,
385 state, _, err := testHandshake(t, clientConfig, serverConfig)
387 t.Fatalf("handshake failed: %s", err)
389 if state.Version != VersionTLS11 {
390 t.Fatalf("Incorrect version %x, should be %x", state.Version, VersionTLS11)
394 func 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,
400 clientConfig := &Config{
401 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA},
402 InsecureSkipVerify: true,
404 state, _, err := testHandshake(t, clientConfig, serverConfig)
406 t.Fatalf("handshake failed: %s", err)
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)
413 serverConfig.PreferServerCipherSuites = true
414 state, _, err = testHandshake(t, clientConfig, serverConfig)
416 t.Fatalf("handshake failed: %s", err)
418 if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA {
419 t.Fatalf("Server's preference was not used, got %x", state.CipherSuite)
423 func TestSCTHandshake(t *testing.T) {
424 t.Run("TLSv12", func(t *testing.T) { testSCTHandshake(t, VersionTLS12) })
425 t.Run("TLSv13", func(t *testing.T) { testSCTHandshake(t, VersionTLS13) })
428 func testSCTHandshake(t *testing.T, version uint16) {
429 expected := [][]byte{[]byte("certificate"), []byte("transparency")}
430 serverConfig := &Config{
431 Certificates: []Certificate{{
432 Certificate: [][]byte{testRSACertificate},
433 PrivateKey: testRSAPrivateKey,
434 SignedCertificateTimestamps: expected,
438 clientConfig := &Config{
439 InsecureSkipVerify: true,
441 _, state, err := testHandshake(t, clientConfig, serverConfig)
443 t.Fatalf("handshake failed: %s", err)
445 actual := state.SignedCertificateTimestamps
446 if len(actual) != len(expected) {
447 t.Fatalf("got %d scts, want %d", len(actual), len(expected))
449 for i, sct := range expected {
450 if !bytes.Equal(sct, actual[i]) {
451 t.Fatalf("SCT #%d was %x, but expected %x", i, actual[i], sct)
456 func TestCrossVersionResume(t *testing.T) {
457 t.Run("TLSv12", func(t *testing.T) { testCrossVersionResume(t, VersionTLS12) })
458 t.Run("TLSv13", func(t *testing.T) { testCrossVersionResume(t, VersionTLS13) })
461 func testCrossVersionResume(t *testing.T, version uint16) {
462 serverConfig := &Config{
463 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
464 Certificates: testConfig.Certificates,
466 clientConfig := &Config{
467 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
468 InsecureSkipVerify: true,
469 ClientSessionCache: NewLRUClientSessionCache(1),
470 ServerName: "servername",
473 // Establish a session at TLS 1.1.
474 clientConfig.MaxVersion = VersionTLS11
475 _, _, err := testHandshake(t, clientConfig, serverConfig)
477 t.Fatalf("handshake failed: %s", err)
480 // The client session cache now contains a TLS 1.1 session.
481 state, _, err := testHandshake(t, clientConfig, serverConfig)
483 t.Fatalf("handshake failed: %s", err)
485 if !state.DidResume {
486 t.Fatalf("handshake did not resume at the same version")
489 // Test that the server will decline to resume at a lower version.
490 clientConfig.MaxVersion = VersionTLS10
491 state, _, err = testHandshake(t, clientConfig, serverConfig)
493 t.Fatalf("handshake failed: %s", err)
496 t.Fatalf("handshake resumed at a lower version")
499 // The client session cache now contains a TLS 1.0 session.
500 state, _, err = testHandshake(t, clientConfig, serverConfig)
502 t.Fatalf("handshake failed: %s", err)
504 if !state.DidResume {
505 t.Fatalf("handshake did not resume at the same version")
508 // Test that the server will decline to resume at a higher version.
509 clientConfig.MaxVersion = VersionTLS11
510 state, _, err = testHandshake(t, clientConfig, serverConfig)
512 t.Fatalf("handshake failed: %s", err)
515 t.Fatalf("handshake resumed at a higher version")
519 // Note: see comment in handshake_test.go for details of how the reference
522 // serverTest represents a test of the TLS server handshake against a reference
524 type serverTest struct {
525 // name is a freeform string identifying the test and the file in which
526 // the expected results will be stored.
528 // command, if not empty, contains a series of arguments for the
529 // command to run for the reference server.
531 // expectedPeerCerts contains a list of PEM blocks of expected
532 // certificates from the client.
533 expectedPeerCerts []string
534 // config, if not nil, contains a custom Config to use for this test.
536 // expectHandshakeErrorIncluding, when not empty, contains a string
537 // that must be a substring of the error resulting from the handshake.
538 expectHandshakeErrorIncluding string
539 // validate, if not nil, is a function that will be called with the
540 // ConnectionState of the resulting connection. It returns false if the
541 // ConnectionState is unacceptable.
542 validate func(ConnectionState) error
543 // wait, if true, prevents this subtest from calling t.Parallel.
544 // If false, runServerTest* returns immediately.
548 var defaultClientCommand = []string{"openssl", "s_client", "-no_ticket"}
550 // connFromCommand starts opens a listening socket and starts the reference
551 // client to connect to it. It returns a recordingConn that wraps the resulting
553 func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, err error) {
554 l, err := net.ListenTCP("tcp", &net.TCPAddr{
555 IP: net.IPv4(127, 0, 0, 1),
563 port := l.Addr().(*net.TCPAddr).Port
566 command = append(command, test.command...)
567 if len(command) == 0 {
568 command = defaultClientCommand
570 command = append(command, "-connect")
571 command = append(command, fmt.Sprintf("127.0.0.1:%d", port))
572 cmd := exec.Command(command[0], command[1:]...)
574 var output bytes.Buffer
577 if err := cmd.Start(); err != nil {
581 connChan := make(chan interface{}, 1)
583 tcpConn, err := l.Accept()
593 case connOrError := <-connChan:
594 if err, ok := connOrError.(error); ok {
597 tcpConn = connOrError.(net.Conn)
598 case <-time.After(2 * time.Second):
599 return nil, nil, errors.New("timed out waiting for connection from child process")
602 record := &recordingConn{
606 return record, cmd, nil
609 func (test *serverTest) dataPath() string {
610 return filepath.Join("testdata", "Server-"+test.name)
613 func (test *serverTest) loadData() (flows [][]byte, err error) {
614 in, err := os.Open(test.dataPath())
619 return parseTestData(in)
622 func (test *serverTest) run(t *testing.T, write bool) {
623 var clientConn, serverConn net.Conn
624 var recordingConn *recordingConn
625 var childProcess *exec.Cmd
629 recordingConn, childProcess, err = test.connFromCommand()
631 t.Fatalf("Failed to start subcommand: %s", err)
633 serverConn = recordingConn
636 t.Logf("OpenSSL output:\n\n%s", childProcess.Stdout)
640 clientConn, serverConn = localPipe(t)
642 config := test.config
646 server := Server(serverConn, config)
647 connStateChan := make(chan ConnectionState, 1)
649 _, err := server.Write([]byte("hello, world\n"))
650 if len(test.expectHandshakeErrorIncluding) > 0 {
652 t.Errorf("Error expected, but no error returned")
653 } else if s := err.Error(); !strings.Contains(s, test.expectHandshakeErrorIncluding) {
654 t.Errorf("Error expected containing '%s' but got '%s'", test.expectHandshakeErrorIncluding, s)
658 t.Logf("Error from Server.Write: '%s'", err)
663 connStateChan <- server.ConnectionState()
667 flows, err := test.loadData()
669 t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
671 for i, b := range flows {
674 clientConn.SetWriteDeadline(time.Now().Add(1 * time.Second))
676 clientConn.SetWriteDeadline(time.Now().Add(1 * time.Minute))
681 bb := make([]byte, len(b))
683 clientConn.SetReadDeadline(time.Now().Add(1 * time.Second))
685 clientConn.SetReadDeadline(time.Now().Add(1 * time.Minute))
687 n, err := io.ReadFull(clientConn, bb)
689 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)
691 if !bytes.Equal(b, bb) {
692 t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
698 connState := <-connStateChan
699 peerCerts := connState.PeerCertificates
700 if len(peerCerts) == len(test.expectedPeerCerts) {
701 for i, peerCert := range peerCerts {
702 block, _ := pem.Decode([]byte(test.expectedPeerCerts[i]))
703 if !bytes.Equal(block.Bytes, peerCert.Raw) {
704 t.Fatalf("%s: mismatch on peer cert %d", test.name, i+1)
708 t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", test.name, len(test.expectedPeerCerts), len(peerCerts))
711 if test.validate != nil {
712 if err := test.validate(connState); err != nil {
713 t.Fatalf("validate callback returned error: %s", err)
718 path := test.dataPath()
719 out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
721 t.Fatalf("Failed to create output file: %s", err)
724 recordingConn.Close()
725 if len(recordingConn.flows) < 3 {
726 if len(test.expectHandshakeErrorIncluding) == 0 {
727 t.Fatalf("Handshake failed")
730 recordingConn.WriteTo(out)
731 t.Logf("Wrote %s\n", path)
736 func runServerTestForVersion(t *testing.T, template *serverTest, version, option string) {
737 // Make a deep copy of the template before going parallel.
739 if template.config != nil {
740 test.config = template.config.Clone()
742 test.name = version + "-" + test.name
743 if len(test.command) == 0 {
744 test.command = defaultClientCommand
746 test.command = append([]string(nil), test.command...)
747 test.command = append(test.command, option)
749 runTestAndUpdateIfNeeded(t, version, test.run, test.wait)
752 func runServerTestTLS10(t *testing.T, template *serverTest) {
753 runServerTestForVersion(t, template, "TLSv10", "-tls1")
756 func runServerTestTLS11(t *testing.T, template *serverTest) {
757 runServerTestForVersion(t, template, "TLSv11", "-tls1_1")
760 func runServerTestTLS12(t *testing.T, template *serverTest) {
761 runServerTestForVersion(t, template, "TLSv12", "-tls1_2")
764 func runServerTestTLS13(t *testing.T, template *serverTest) {
765 runServerTestForVersion(t, template, "TLSv13", "-tls1_3")
768 func TestHandshakeServerRSARC4(t *testing.T) {
771 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
773 runServerTestTLS10(t, test)
774 runServerTestTLS11(t, test)
775 runServerTestTLS12(t, test)
778 func TestHandshakeServerRSA3DES(t *testing.T) {
781 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"},
783 runServerTestTLS10(t, test)
784 runServerTestTLS12(t, test)
787 func TestHandshakeServerRSAAES(t *testing.T) {
790 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"},
792 runServerTestTLS10(t, test)
793 runServerTestTLS12(t, test)
796 func TestHandshakeServerAESGCM(t *testing.T) {
799 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"},
801 runServerTestTLS12(t, test)
804 func TestHandshakeServerAES256GCMSHA384(t *testing.T) {
806 name: "RSA-AES256-GCM-SHA384",
807 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384"},
809 runServerTestTLS12(t, test)
812 func TestHandshakeServerAES128SHA256(t *testing.T) {
814 name: "AES128-SHA256",
815 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_AES_128_GCM_SHA256"},
817 runServerTestTLS13(t, test)
819 func TestHandshakeServerAES256SHA384(t *testing.T) {
821 name: "AES256-SHA384",
822 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_AES_256_GCM_SHA384"},
824 runServerTestTLS13(t, test)
826 func TestHandshakeServerCHACHA20SHA256(t *testing.T) {
828 name: "CHACHA20-SHA256",
829 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
831 runServerTestTLS13(t, test)
834 func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
835 config := testConfig.Clone()
836 config.Certificates = make([]Certificate, 1)
837 config.Certificates[0].Certificate = [][]byte{testECDSACertificate}
838 config.Certificates[0].PrivateKey = testECDSAPrivateKey
839 config.BuildNameToCertificate()
842 name: "ECDHE-ECDSA-AES",
843 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"},
846 runServerTestTLS10(t, test)
847 runServerTestTLS12(t, test)
848 runServerTestTLS13(t, test)
851 func TestHandshakeServerX25519(t *testing.T) {
852 config := testConfig.Clone()
853 config.CurvePreferences = []CurveID{X25519}
857 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519"},
860 runServerTestTLS12(t, test)
861 runServerTestTLS13(t, test)
864 func TestHandshakeServerP256(t *testing.T) {
865 config := testConfig.Clone()
866 config.CurvePreferences = []CurveID{CurveP256}
870 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "P-256"},
873 runServerTestTLS12(t, test)
874 runServerTestTLS13(t, test)
877 func TestHandshakeServerHelloRetryRequest(t *testing.T) {
878 config := testConfig.Clone()
879 config.CurvePreferences = []CurveID{CurveP256}
882 name: "HelloRetryRequest",
883 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519:P-256"},
886 runServerTestTLS13(t, test)
889 func TestHandshakeServerALPN(t *testing.T) {
890 config := testConfig.Clone()
891 config.NextProtos = []string{"proto1", "proto2"}
895 // Note that this needs OpenSSL 1.0.2 because that is the first
896 // version that supports the -alpn flag.
897 command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
899 validate: func(state ConnectionState) error {
900 // The server's preferences should override the client.
901 if state.NegotiatedProtocol != "proto1" {
902 return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
907 runServerTestTLS12(t, test)
908 runServerTestTLS13(t, test)
911 func TestHandshakeServerALPNNoMatch(t *testing.T) {
912 config := testConfig.Clone()
913 config.NextProtos = []string{"proto3"}
916 name: "ALPN-NoMatch",
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"},
921 validate: func(state ConnectionState) error {
922 // Rather than reject the connection, Go doesn't select
923 // a protocol when there is no overlap.
924 if state.NegotiatedProtocol != "" {
925 return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol)
930 runServerTestTLS12(t, test)
931 runServerTestTLS13(t, test)
934 // TestHandshakeServerSNI involves a client sending an SNI extension of
935 // "snitest.com", which happens to match the CN of testSNICertificate. The test
936 // verifies that the server correctly selects that certificate.
937 func TestHandshakeServerSNI(t *testing.T) {
940 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
942 runServerTestTLS12(t, test)
945 // TestHandshakeServerSNICertForName is similar to TestHandshakeServerSNI, but
946 // tests the dynamic GetCertificate method
947 func TestHandshakeServerSNIGetCertificate(t *testing.T) {
948 config := testConfig.Clone()
950 // Replace the NameToCertificate map with a GetCertificate function
951 nameToCert := config.NameToCertificate
952 config.NameToCertificate = nil
953 config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
954 cert := nameToCert[clientHello.ServerName]
958 name: "SNI-GetCertificate",
959 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
962 runServerTestTLS12(t, test)
965 // TestHandshakeServerSNICertForNameNotFound is similar to
966 // TestHandshakeServerSNICertForName, but tests to make sure that when the
967 // GetCertificate method doesn't return a cert, we fall back to what's in
968 // the NameToCertificate map.
969 func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) {
970 config := testConfig.Clone()
972 config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
976 name: "SNI-GetCertificateNotFound",
977 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
980 runServerTestTLS12(t, test)
983 // TestHandshakeServerSNICertForNameError tests to make sure that errors in
984 // GetCertificate result in a tls alert.
985 func TestHandshakeServerSNIGetCertificateError(t *testing.T) {
986 const errMsg = "TestHandshakeServerSNIGetCertificateError error"
988 serverConfig := testConfig.Clone()
989 serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
990 return nil, errors.New(errMsg)
993 clientHello := &clientHelloMsg{
995 random: make([]byte, 32),
996 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
997 compressionMethods: []uint8{compressionNone},
1000 testClientHelloFailure(t, serverConfig, clientHello, errMsg)
1003 // TestHandshakeServerEmptyCertificates tests that GetCertificates is called in
1004 // the case that Certificates is empty, even without SNI.
1005 func TestHandshakeServerEmptyCertificates(t *testing.T) {
1006 const errMsg = "TestHandshakeServerEmptyCertificates error"
1008 serverConfig := testConfig.Clone()
1009 serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
1010 return nil, errors.New(errMsg)
1012 serverConfig.Certificates = nil
1014 clientHello := &clientHelloMsg{
1016 random: make([]byte, 32),
1017 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
1018 compressionMethods: []uint8{compressionNone},
1020 testClientHelloFailure(t, serverConfig, clientHello, errMsg)
1022 // With an empty Certificates and a nil GetCertificate, the server
1023 // should always return a “no certificates” error.
1024 serverConfig.GetCertificate = nil
1026 clientHello = &clientHelloMsg{
1028 random: make([]byte, 32),
1029 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
1030 compressionMethods: []uint8{compressionNone},
1032 testClientHelloFailure(t, serverConfig, clientHello, "no certificates")
1035 // TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
1036 // an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate.
1037 func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
1038 config := testConfig.Clone()
1039 config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}
1040 config.PreferServerCipherSuites = true
1042 test := &serverTest{
1043 name: "CipherSuiteCertPreferenceRSA",
1046 runServerTestTLS12(t, test)
1048 config = testConfig.Clone()
1049 config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}
1050 config.Certificates = []Certificate{
1052 Certificate: [][]byte{testECDSACertificate},
1053 PrivateKey: testECDSAPrivateKey,
1056 config.BuildNameToCertificate()
1057 config.PreferServerCipherSuites = true
1060 name: "CipherSuiteCertPreferenceECDSA",
1063 runServerTestTLS12(t, test)
1066 func TestServerResumption(t *testing.T) {
1067 sessionFilePath := tempFile("")
1068 defer os.Remove(sessionFilePath)
1070 testIssue := &serverTest{
1071 name: "IssueTicket",
1072 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath},
1075 testResume := &serverTest{
1077 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath},
1078 validate: func(state ConnectionState) error {
1079 if !state.DidResume {
1080 return errors.New("did not resume")
1086 runServerTestTLS12(t, testIssue)
1087 runServerTestTLS12(t, testResume)
1089 runServerTestTLS13(t, testIssue)
1090 runServerTestTLS13(t, testResume)
1092 config := testConfig.Clone()
1093 config.CurvePreferences = []CurveID{CurveP256}
1095 testResumeHRR := &serverTest{
1096 name: "Resume-HelloRetryRequest",
1097 command: []string{"openssl", "s_client", "-curves", "X25519:P-256", "-cipher", "AES128-SHA", "-ciphersuites",
1098 "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath},
1100 validate: func(state ConnectionState) error {
1101 if !state.DidResume {
1102 return errors.New("did not resume")
1108 runServerTestTLS13(t, testResumeHRR)
1111 func TestServerResumptionDisabled(t *testing.T) {
1112 sessionFilePath := tempFile("")
1113 defer os.Remove(sessionFilePath)
1115 config := testConfig.Clone()
1117 testIssue := &serverTest{
1118 name: "IssueTicketPreDisable",
1119 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath},
1123 testResume := &serverTest{
1124 name: "ResumeDisabled",
1125 command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath},
1127 validate: func(state ConnectionState) error {
1128 if state.DidResume {
1129 return errors.New("resumed with SessionTicketsDisabled")
1135 config.SessionTicketsDisabled = false
1136 runServerTestTLS12(t, testIssue)
1137 config.SessionTicketsDisabled = true
1138 runServerTestTLS12(t, testResume)
1140 config.SessionTicketsDisabled = false
1141 runServerTestTLS13(t, testIssue)
1142 config.SessionTicketsDisabled = true
1143 runServerTestTLS13(t, testResume)
1146 func TestFallbackSCSV(t *testing.T) {
1147 serverConfig := Config{
1148 Certificates: testConfig.Certificates,
1150 test := &serverTest{
1151 name: "FallbackSCSV",
1152 config: &serverConfig,
1153 // OpenSSL 1.0.1j is needed for the -fallback_scsv option.
1154 command: []string{"openssl", "s_client", "-fallback_scsv"},
1155 expectHandshakeErrorIncluding: "inappropriate protocol fallback",
1157 runServerTestTLS11(t, test)
1160 func TestHandshakeServerExportKeyingMaterial(t *testing.T) {
1161 test := &serverTest{
1162 name: "ExportKeyingMaterial",
1163 command: []string{"openssl", "s_client", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
1164 config: testConfig.Clone(),
1165 validate: func(state ConnectionState) error {
1166 if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
1167 return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
1168 } else if len(km) != 42 {
1169 return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
1174 runServerTestTLS10(t, test)
1175 runServerTestTLS12(t, test)
1176 runServerTestTLS13(t, test)
1179 func TestHandshakeServerRSAPKCS1v15(t *testing.T) {
1180 test := &serverTest{
1181 name: "RSA-RSAPKCS1v15",
1182 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-sigalgs", "rsa_pkcs1_sha256"},
1184 runServerTestTLS12(t, test)
1187 func TestHandshakeServerRSAPSS(t *testing.T) {
1188 // We send rsa_pss_rsae_sha512 first, as the test key won't fit, and we
1189 // verify the server implementation will disregard the client preference in
1190 // that case. See Issue 29793.
1191 test := &serverTest{
1193 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"},
1195 runServerTestTLS12(t, test)
1196 runServerTestTLS13(t, test)
1199 name: "RSA-RSAPSS-TooSmall",
1200 command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512"},
1201 expectHandshakeErrorIncluding: "peer doesn't support any of the certificate's signature algorithms",
1203 runServerTestTLS13(t, test)
1206 func TestHandshakeServerEd25519(t *testing.T) {
1207 config := testConfig.Clone()
1208 config.Certificates = make([]Certificate, 1)
1209 config.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
1210 config.Certificates[0].PrivateKey = testEd25519PrivateKey
1211 config.BuildNameToCertificate()
1213 test := &serverTest{
1215 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
1218 runServerTestTLS12(t, test)
1219 runServerTestTLS13(t, test)
1222 func benchmarkHandshakeServer(b *testing.B, version uint16, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
1223 config := testConfig.Clone()
1224 config.CipherSuites = []uint16{cipherSuite}
1225 config.CurvePreferences = []CurveID{curve}
1226 config.Certificates = make([]Certificate, 1)
1227 config.Certificates[0].Certificate = [][]byte{cert}
1228 config.Certificates[0].PrivateKey = key
1229 config.BuildNameToCertificate()
1231 clientConn, serverConn := localPipe(b)
1232 serverConn = &recordingConn{Conn: serverConn}
1234 config := testConfig.Clone()
1235 config.MaxVersion = version
1236 config.CurvePreferences = []CurveID{curve}
1237 client := Client(clientConn, config)
1240 server := Server(serverConn, config)
1241 if err := server.Handshake(); err != nil {
1242 b.Fatalf("handshake failed: %v", err)
1245 flows := serverConn.(*recordingConn).flows
1247 feeder := make(chan struct{})
1248 clientConn, serverConn = localPipe(b)
1252 for i, f := range flows {
1257 ff := make([]byte, len(f))
1258 n, err := io.ReadFull(clientConn, ff)
1260 b.Errorf("#%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", i+1, err, n, len(ff), ff[:n], f)
1262 if !bytes.Equal(f, ff) {
1263 b.Errorf("#%d: mismatch on read: got:%x want:%x", i+1, ff, f)
1270 for i := 0; i < b.N; i++ {
1271 feeder <- struct{}{}
1272 server := Server(serverConn, config)
1273 if err := server.Handshake(); err != nil {
1274 b.Fatalf("handshake failed: %v", err)
1280 func BenchmarkHandshakeServer(b *testing.B) {
1281 b.Run("RSA", func(b *testing.B) {
1282 benchmarkHandshakeServer(b, VersionTLS12, TLS_RSA_WITH_AES_128_GCM_SHA256,
1283 0, testRSACertificate, testRSAPrivateKey)
1285 b.Run("ECDHE-P256-RSA", func(b *testing.B) {
1286 b.Run("TLSv13", func(b *testing.B) {
1287 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1288 CurveP256, testRSACertificate, testRSAPrivateKey)
1290 b.Run("TLSv12", func(b *testing.B) {
1291 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1292 CurveP256, testRSACertificate, testRSAPrivateKey)
1295 b.Run("ECDHE-P256-ECDSA-P256", func(b *testing.B) {
1296 b.Run("TLSv13", func(b *testing.B) {
1297 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
1298 CurveP256, testP256Certificate, testP256PrivateKey)
1300 b.Run("TLSv12", func(b *testing.B) {
1301 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
1302 CurveP256, testP256Certificate, testP256PrivateKey)
1305 b.Run("ECDHE-X25519-ECDSA-P256", func(b *testing.B) {
1306 b.Run("TLSv13", func(b *testing.B) {
1307 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
1308 X25519, testP256Certificate, testP256PrivateKey)
1310 b.Run("TLSv12", func(b *testing.B) {
1311 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
1312 X25519, testP256Certificate, testP256PrivateKey)
1315 b.Run("ECDHE-P521-ECDSA-P521", func(b *testing.B) {
1316 if testECDSAPrivateKey.PublicKey.Curve != elliptic.P521() {
1317 b.Fatal("test ECDSA key doesn't use curve P-521")
1319 b.Run("TLSv13", func(b *testing.B) {
1320 benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
1321 CurveP521, testECDSACertificate, testECDSAPrivateKey)
1323 b.Run("TLSv12", func(b *testing.B) {
1324 benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
1325 CurveP521, testECDSACertificate, testECDSAPrivateKey)
1330 func TestClientAuth(t *testing.T) {
1331 var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath, ed25519CertPath, ed25519KeyPath string
1334 certPath = tempFile(clientCertificatePEM)
1335 defer os.Remove(certPath)
1336 keyPath = tempFile(clientKeyPEM)
1337 defer os.Remove(keyPath)
1338 ecdsaCertPath = tempFile(clientECDSACertificatePEM)
1339 defer os.Remove(ecdsaCertPath)
1340 ecdsaKeyPath = tempFile(clientECDSAKeyPEM)
1341 defer os.Remove(ecdsaKeyPath)
1342 ed25519CertPath = tempFile(clientEd25519CertificatePEM)
1343 defer os.Remove(ed25519CertPath)
1344 ed25519KeyPath = tempFile(clientEd25519KeyPEM)
1345 defer os.Remove(ed25519KeyPath)
1350 config := testConfig.Clone()
1351 config.ClientAuth = RequestClientCert
1353 test := &serverTest{
1354 name: "ClientAuthRequestedNotGiven",
1355 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"},
1358 runServerTestTLS12(t, test)
1359 runServerTestTLS13(t, test)
1362 name: "ClientAuthRequestedAndGiven",
1363 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256",
1364 "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pss_rsae_sha256"},
1366 expectedPeerCerts: []string{clientCertificatePEM},
1368 runServerTestTLS12(t, test)
1369 runServerTestTLS13(t, test)
1372 name: "ClientAuthRequestedAndECDSAGiven",
1373 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256",
1374 "-cert", ecdsaCertPath, "-key", ecdsaKeyPath},
1376 expectedPeerCerts: []string{clientECDSACertificatePEM},
1378 runServerTestTLS12(t, test)
1379 runServerTestTLS13(t, test)
1382 name: "ClientAuthRequestedAndEd25519Given",
1383 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256",
1384 "-cert", ed25519CertPath, "-key", ed25519KeyPath},
1386 expectedPeerCerts: []string{clientEd25519CertificatePEM},
1388 runServerTestTLS12(t, test)
1389 runServerTestTLS13(t, test)
1392 name: "ClientAuthRequestedAndPKCS1v15Given",
1393 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA",
1394 "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pkcs1_sha256"},
1396 expectedPeerCerts: []string{clientCertificatePEM},
1398 runServerTestTLS12(t, test)
1401 func TestSNIGivenOnFailure(t *testing.T) {
1402 const expectedServerName = "test.testing"
1404 clientHello := &clientHelloMsg{
1406 random: make([]byte, 32),
1407 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
1408 compressionMethods: []uint8{compressionNone},
1409 serverName: expectedServerName,
1412 serverConfig := testConfig.Clone()
1413 // Erase the server's cipher suites to ensure the handshake fails.
1414 serverConfig.CipherSuites = nil
1416 c, s := localPipe(t)
1418 cli := Client(c, testConfig)
1419 cli.vers = clientHello.vers
1420 cli.writeRecord(recordTypeHandshake, clientHello.marshal())
1423 conn := Server(s, serverConfig)
1424 ch, err := conn.readClientHello()
1425 hs := serverHandshakeState{
1430 err = hs.processClientHello()
1433 err = hs.pickCipherSuite()
1438 t.Error("No error reported from server")
1441 cs := hs.c.ConnectionState()
1442 if cs.HandshakeComplete {
1443 t.Error("Handshake registered as complete")
1446 if cs.ServerName != expectedServerName {
1447 t.Errorf("Expected ServerName of %q, but got %q", expectedServerName, cs.ServerName)
1451 var getConfigForClientTests = []struct {
1452 setup func(config *Config)
1453 callback func(clientHello *ClientHelloInfo) (*Config, error)
1454 errorSubstring string
1455 verify func(config *Config) error
1459 func(clientHello *ClientHelloInfo) (*Config, error) {
1467 func(clientHello *ClientHelloInfo) (*Config, error) {
1468 return nil, errors.New("should bubble up")
1475 func(clientHello *ClientHelloInfo) (*Config, error) {
1476 config := testConfig.Clone()
1477 // Setting a maximum version of TLS 1.1 should cause
1478 // the handshake to fail, as the client MinVersion is TLS 1.2.
1479 config.MaxVersion = VersionTLS11
1482 "client offered only unsupported versions",
1486 func(config *Config) {
1487 for i := range config.SessionTicketKey {
1488 config.SessionTicketKey[i] = byte(i)
1490 config.sessionTicketKeys = nil
1492 func(clientHello *ClientHelloInfo) (*Config, error) {
1493 config := testConfig.Clone()
1494 for i := range config.SessionTicketKey {
1495 config.SessionTicketKey[i] = 0
1497 config.sessionTicketKeys = nil
1501 func(config *Config) error {
1502 if config.SessionTicketKey == [32]byte{} {
1503 return fmt.Errorf("expected SessionTicketKey to be set")
1509 func(config *Config) {
1510 var dummyKey [32]byte
1511 for i := range dummyKey {
1512 dummyKey[i] = byte(i)
1515 config.SetSessionTicketKeys([][32]byte{dummyKey})
1517 func(clientHello *ClientHelloInfo) (*Config, error) {
1518 config := testConfig.Clone()
1519 config.sessionTicketKeys = nil
1523 func(config *Config) error {
1524 if config.SessionTicketKey == [32]byte{} {
1525 return fmt.Errorf("expected SessionTicketKey to be set")
1532 func TestGetConfigForClient(t *testing.T) {
1533 serverConfig := testConfig.Clone()
1534 clientConfig := testConfig.Clone()
1535 clientConfig.MinVersion = VersionTLS12
1537 for i, test := range getConfigForClientTests {
1538 if test.setup != nil {
1539 test.setup(serverConfig)
1542 var configReturned *Config
1543 serverConfig.GetConfigForClient = func(clientHello *ClientHelloInfo) (*Config, error) {
1544 config, err := test.callback(clientHello)
1545 configReturned = config
1548 c, s := localPipe(t)
1549 done := make(chan error)
1553 done <- Server(s, serverConfig).Handshake()
1556 clientErr := Client(c, clientConfig).Handshake()
1561 if len(test.errorSubstring) == 0 {
1562 if serverErr != nil || clientErr != nil {
1563 t.Errorf("test[%d]: expected no error but got serverErr: %q, clientErr: %q", i, serverErr, clientErr)
1565 if test.verify != nil {
1566 if err := test.verify(configReturned); err != nil {
1567 t.Errorf("test[%d]: verify returned error: %v", i, err)
1571 if serverErr == nil {
1572 t.Errorf("test[%d]: expected error containing %q but got no error", i, test.errorSubstring)
1573 } else if !strings.Contains(serverErr.Error(), test.errorSubstring) {
1574 t.Errorf("test[%d]: expected error to contain %q but it was %q", i, test.errorSubstring, serverErr)
1580 func TestCloseServerConnectionOnIdleClient(t *testing.T) {
1581 clientConn, serverConn := localPipe(t)
1582 server := Server(serverConn, testConfig.Clone())
1584 clientConn.Write([]byte{'0'})
1587 server.SetReadDeadline(time.Now().Add(time.Minute))
1588 err := server.Handshake()
1590 if err, ok := err.(net.Error); ok && err.Timeout() {
1591 t.Errorf("Expected a closed network connection error but got '%s'", err.Error())
1594 t.Errorf("Error expected, but no error returned")
1598 func TestCloneHash(t *testing.T) {
1599 h1 := crypto.SHA256.New()
1600 h1.Write([]byte("test"))
1602 h2 := cloneHash(h1, crypto.SHA256)
1604 if !bytes.Equal(s1, s2) {
1605 t.Error("cloned hash generated a different sum")
1609 func expectError(t *testing.T, err error, sub string) {
1611 t.Errorf(`expected error %q, got nil`, sub)
1612 } else if !strings.Contains(err.Error(), sub) {
1613 t.Errorf(`expected error %q, got %q`, sub, err)
1617 func TestKeyTooSmallForRSAPSS(t *testing.T) {
1618 cert, err := X509KeyPair([]byte(`-----BEGIN CERTIFICATE-----
1619 MIIBcTCCARugAwIBAgIQGjQnkCFlUqaFlt6ixyz/tDANBgkqhkiG9w0BAQsFADAS
1620 MRAwDgYDVQQKEwdBY21lIENvMB4XDTE5MDExODIzMjMyOFoXDTIwMDExODIzMjMy
1621 OFowEjEQMA4GA1UEChMHQWNtZSBDbzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDd
1622 ez1rFUDwax2HTxbcnFUP9AhcgEGMHVV2nn4VVEWFJB6I8C/Nkx0XyyQlrmFYBzEQ
1623 nIPhKls4T0hFoLvjJnXpAgMBAAGjTTBLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE
1624 DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBYGA1UdEQQPMA2CC2V4YW1wbGUu
1625 Y29tMA0GCSqGSIb3DQEBCwUAA0EAxDuUS+BrrS3c+h+k+fQPOmOScy6yTX9mHw0Q
1626 KbucGamXYEy0URIwOdO0tQ3LHPc1YGvYSPwkDjkjqECs2Vm/AA==
1627 -----END CERTIFICATE-----`), []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
1628 MIIBOgIBAAJBAN17PWsVQPBrHYdPFtycVQ/0CFyAQYwdVXaefhVURYUkHojwL82T
1629 HRfLJCWuYVgHMRCcg+EqWzhPSEWgu+MmdekCAwEAAQJBALjQYNTdXF4CFBbXwUz/
1630 yt9QFDYT9B5WT/12jeGAe653gtYS6OOi/+eAkGmzg1GlRnw6fOfn+HYNFDORST7z
1631 4j0CIQDn2xz9hVWQEu9ee3vecNT3f60huDGTNoRhtqgweQGX0wIhAPSLj1VcRZEz
1632 nKpbtU22+PbIMSJ+e80fmY9LIPx5N4HTAiAthGSimMR9bloz0EY3GyuUEyqoDgMd
1633 hXxjuno2WesoJQIgemilbcALXpxsLmZLgcQ2KSmaVr7jb5ECx9R+hYKTw1sCIG4s
1634 T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g
1635 -----END RSA TESTING KEY-----`)))
1640 clientConn, serverConn := localPipe(t)
1641 client := Client(clientConn, testConfig)
1642 done := make(chan struct{})
1644 config := testConfig.Clone()
1645 config.Certificates = []Certificate{cert}
1646 config.MinVersion = VersionTLS13
1647 server := Server(serverConn, config)
1648 err := server.Handshake()
1649 expectError(t, err, "key size too small")
1652 err = client.Handshake()
1653 expectError(t, err, "handshake failure")
1657 func TestMultipleCertificates(t *testing.T) {
1658 clientConfig := testConfig.Clone()
1659 clientConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}
1660 clientConfig.MaxVersion = VersionTLS12
1662 serverConfig := testConfig.Clone()
1663 serverConfig.Certificates = []Certificate{{
1664 Certificate: [][]byte{testECDSACertificate},
1665 PrivateKey: testECDSAPrivateKey,
1667 Certificate: [][]byte{testRSACertificate},
1668 PrivateKey: testRSAPrivateKey,
1671 _, clientState, err := testHandshake(t, clientConfig, serverConfig)
1675 if got := clientState.PeerCertificates[0].PublicKeyAlgorithm; got != x509.RSA {
1676 t.Errorf("expected RSA certificate, got %v", got)
1680 func TestAESCipherReordering(t *testing.T) {
1681 currentAESSupport := hasAESGCMHardwareSupport
1682 defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }()
1686 clientCiphers []uint16
1687 serverHasAESGCM bool
1688 preferServerCipherSuites bool
1689 serverCiphers []uint16
1690 expectedCipher uint16
1691 boringExpectedCipher uint16 // If non-zero, used when BoringCrypto is enabled.
1694 name: "server has hardware AES, client doesn't (pick ChaCha)",
1695 clientCiphers: []uint16{
1696 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1697 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1698 TLS_RSA_WITH_AES_128_CBC_SHA,
1700 serverHasAESGCM: true,
1701 preferServerCipherSuites: true,
1702 expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1705 name: "server strongly prefers AES-GCM, client doesn't (pick AES-GCM)",
1706 clientCiphers: []uint16{
1707 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1708 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1709 TLS_RSA_WITH_AES_128_CBC_SHA,
1711 serverHasAESGCM: true,
1712 preferServerCipherSuites: true,
1713 serverCiphers: []uint16{
1714 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1715 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1716 TLS_RSA_WITH_AES_128_CBC_SHA,
1718 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1721 name: "client prefers AES-GCM, server doesn't have hardware AES (pick ChaCha)",
1722 clientCiphers: []uint16{
1723 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1724 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1725 TLS_RSA_WITH_AES_128_CBC_SHA,
1727 serverHasAESGCM: false,
1728 expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1729 boringExpectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
1732 name: "client prefers AES-GCM, server has hardware AES (pick AES-GCM)",
1733 clientCiphers: []uint16{
1734 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1735 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1736 TLS_RSA_WITH_AES_128_CBC_SHA,
1738 serverHasAESGCM: true,
1739 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1742 name: "client prefers AES-GCM and sends GREASE, server has hardware AES (pick AES-GCM)",
1743 clientCiphers: []uint16{
1744 0x0A0A, // GREASE value
1745 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1746 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1747 TLS_RSA_WITH_AES_128_CBC_SHA,
1749 serverHasAESGCM: true,
1750 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1753 name: "client prefers AES-GCM and doesn't support ChaCha, server doesn't have hardware AES (pick AES-GCM)",
1754 clientCiphers: []uint16{
1755 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1756 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1757 TLS_RSA_WITH_AES_128_CBC_SHA,
1759 serverHasAESGCM: false,
1760 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1763 name: "client prefers AES-GCM and AES-CBC over ChaCha, server doesn't have hardware AES (pick AES-GCM)",
1764 clientCiphers: []uint16{
1765 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1766 TLS_RSA_WITH_AES_128_CBC_SHA,
1767 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1769 serverHasAESGCM: false,
1770 expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1773 name: "client prefers AES-GCM over ChaCha and sends GREASE, server doesn't have hardware AES (pick ChaCha)",
1774 clientCiphers: []uint16{
1775 0x0A0A, // GREASE value
1776 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1777 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1778 TLS_RSA_WITH_AES_128_CBC_SHA,
1780 serverHasAESGCM: false,
1781 expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1782 boringExpectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
1785 name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (pick corrent AES-GCM)",
1786 clientCiphers: []uint16{
1787 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
1788 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
1789 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1791 serverHasAESGCM: false,
1792 serverCiphers: []uint16{
1793 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
1794 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1796 expectedCipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
1800 for _, tc := range tests {
1801 t.Run(tc.name, func(t *testing.T) {
1802 hasAESGCMHardwareSupport = tc.serverHasAESGCM
1803 initDefaultCipherSuites()
1804 hs := &serverHandshakeState{
1807 PreferServerCipherSuites: tc.preferServerCipherSuites,
1808 CipherSuites: tc.serverCiphers,
1812 clientHello: &clientHelloMsg{
1813 cipherSuites: tc.clientCiphers,
1821 err := hs.pickCipherSuite()
1823 t.Errorf("pickCipherSuite failed: %s", err)
1826 want := tc.expectedCipher
1827 if boringEnabled && tc.boringExpectedCipher != 0 {
1828 want = tc.boringExpectedCipher
1830 if want != hs.suite.id {
1831 t.Errorf("unexpected cipher chosen: want %d, got %d", want, hs.suite.id)
1837 func TestAESCipherReordering13(t *testing.T) {
1838 currentAESSupport := hasAESGCMHardwareSupport
1839 defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }()
1843 clientCiphers []uint16
1844 serverHasAESGCM bool
1845 preferServerCipherSuites bool
1846 expectedCipher uint16
1847 boringExpectedCipher uint16 // If non-zero, used when BoringCrypto is enabled.
1850 name: "server has hardware AES, client doesn't (pick ChaCha)",
1851 clientCiphers: []uint16{
1852 TLS_CHACHA20_POLY1305_SHA256,
1853 TLS_AES_128_GCM_SHA256,
1855 serverHasAESGCM: true,
1856 preferServerCipherSuites: true,
1857 expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
1860 name: "neither server nor client have hardware AES (pick ChaCha)",
1861 clientCiphers: []uint16{
1862 TLS_CHACHA20_POLY1305_SHA256,
1863 TLS_AES_128_GCM_SHA256,
1865 serverHasAESGCM: false,
1866 preferServerCipherSuites: true,
1867 expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
1870 name: "client prefers AES, server doesn't have hardware, prefer server ciphers (pick ChaCha)",
1871 clientCiphers: []uint16{
1872 TLS_AES_128_GCM_SHA256,
1873 TLS_CHACHA20_POLY1305_SHA256,
1875 serverHasAESGCM: false,
1876 preferServerCipherSuites: true,
1877 expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
1878 boringExpectedCipher: TLS_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
1881 name: "client prefers AES and sends GREASE, server doesn't have hardware, prefer server ciphers (pick ChaCha)",
1882 clientCiphers: []uint16{
1883 0x0A0A, // GREASE value
1884 TLS_AES_128_GCM_SHA256,
1885 TLS_CHACHA20_POLY1305_SHA256,
1887 serverHasAESGCM: false,
1888 preferServerCipherSuites: true,
1889 expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
1890 boringExpectedCipher: TLS_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
1893 name: "client prefers AES, server doesn't (pick ChaCha)",
1894 clientCiphers: []uint16{
1895 TLS_AES_128_GCM_SHA256,
1896 TLS_CHACHA20_POLY1305_SHA256,
1898 serverHasAESGCM: false,
1899 expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
1900 boringExpectedCipher: TLS_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
1903 name: "client prefers AES, server has hardware AES (pick AES)",
1904 clientCiphers: []uint16{
1905 TLS_AES_128_GCM_SHA256,
1906 TLS_CHACHA20_POLY1305_SHA256,
1908 serverHasAESGCM: true,
1909 expectedCipher: TLS_AES_128_GCM_SHA256,
1912 name: "client prefers AES and sends GREASE, server has hardware AES (pick AES)",
1913 clientCiphers: []uint16{
1914 0x0A0A, // GREASE value
1915 TLS_AES_128_GCM_SHA256,
1916 TLS_CHACHA20_POLY1305_SHA256,
1918 serverHasAESGCM: true,
1919 expectedCipher: TLS_AES_128_GCM_SHA256,
1923 for _, tc := range tests {
1924 t.Run(tc.name, func(t *testing.T) {
1925 hasAESGCMHardwareSupport = tc.serverHasAESGCM
1926 initDefaultCipherSuites()
1927 hs := &serverHandshakeStateTLS13{
1930 PreferServerCipherSuites: tc.preferServerCipherSuites,
1934 clientHello: &clientHelloMsg{
1935 cipherSuites: tc.clientCiphers,
1936 supportedVersions: []uint16{VersionTLS13},
1937 compressionMethods: []uint8{compressionNone},
1938 keyShares: []keyShare{{group: X25519, data: curve25519.Basepoint}},
1942 err := hs.processClientHello()
1944 t.Errorf("pickCipherSuite failed: %s", err)
1947 want := tc.expectedCipher
1948 if boringEnabled && tc.boringExpectedCipher != 0 {
1949 want = tc.boringExpectedCipher
1951 if want != hs.suite.id {
1952 t.Errorf("unexpected cipher chosen: want %d, got %d", want, hs.suite.id)