github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/tls/handshake_server_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "bytes" 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/rsa" 12 "encoding/hex" 13 "encoding/pem" 14 "errors" 15 "fmt" 16 "io" 17 "math/big" 18 "net" 19 "os" 20 "os/exec" 21 "path/filepath" 22 "strings" 23 "testing" 24 "time" 25 26 "github.com/zmap/zcrypto/x509" 27 ) 28 29 // zeroSource is an io.Reader that returns an unlimited number of zero bytes. 30 type zeroSource struct{} 31 32 func (zeroSource) Read(b []byte) (n int, err error) { 33 for i := range b { 34 b[i] = 0 35 } 36 37 return len(b), nil 38 } 39 40 var testConfig *Config 41 42 func init() { 43 testConfig = &Config{ 44 Time: func() time.Time { return time.Unix(0, 0) }, 45 Rand: zeroSource{}, 46 Certificates: make([]Certificate, 2), 47 InsecureSkipVerify: true, 48 MinVersion: VersionSSL30, 49 MaxVersion: VersionTLS12, 50 } 51 testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate} 52 testConfig.Certificates[0].PrivateKey = testRSAPrivateKey 53 testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate} 54 testConfig.Certificates[1].PrivateKey = testRSAPrivateKey 55 testConfig.BuildNameToCertificate() 56 } 57 58 func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr string) { 59 // Create in-memory network connection, 60 // send message to server. Should return 61 // expected error. 62 c, s := net.Pipe() 63 go func() { 64 cli := Client(c, testConfig) 65 if ch, ok := m.(*clientHelloMsg); ok { 66 cli.vers = ch.vers 67 } 68 cli.writeRecord(recordTypeHandshake, m.marshal()) 69 c.Close() 70 }() 71 err := Server(s, testConfig).Handshake() 72 s.Close() 73 if err == nil || !strings.Contains(err.Error(), expectedSubStr) { 74 t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr) 75 } 76 } 77 78 func TestSimpleError(t *testing.T) { 79 testClientHelloFailure(t, &serverHelloDoneMsg{}, "unexpected handshake message") 80 } 81 82 var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205} 83 84 func TestRejectBadProtocolVersion(t *testing.T) { 85 for _, v := range badProtocolVersions { 86 testClientHelloFailure(t, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version") 87 } 88 } 89 90 func TestNoSuiteOverlap(t *testing.T) { 91 clientHello := &clientHelloMsg{ 92 vers: 0x0301, 93 cipherSuites: []uint16{0xff00}, 94 compressionMethods: []uint8{0}, 95 } 96 testClientHelloFailure(t, clientHello, "no cipher suite supported by both client and server") 97 } 98 99 func TestNoCompressionOverlap(t *testing.T) { 100 clientHello := &clientHelloMsg{ 101 vers: 0x0301, 102 cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 103 compressionMethods: []uint8{0xff}, 104 } 105 testClientHelloFailure(t, clientHello, "client does not support uncompressed connections") 106 } 107 108 func TestTLS12OnlyCipherSuites(t *testing.T) { 109 // Test that a Server doesn't select a TLS 1.2-only cipher suite when 110 // the client negotiates TLS 1.1. 111 var zeros [32]byte 112 113 clientHello := &clientHelloMsg{ 114 vers: VersionTLS11, 115 random: zeros[:], 116 cipherSuites: []uint16{ 117 // The Server, by default, will use the client's 118 // preference order. So the GCM cipher suite 119 // will be selected unless it's excluded because 120 // of the version in this ClientHello. 121 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 122 TLS_RSA_WITH_RC4_128_SHA, 123 }, 124 compressionMethods: []uint8{compressionNone}, 125 supportedCurves: []CurveID{CurveP256, CurveP384, CurveP521}, 126 supportedPoints: []uint8{pointFormatUncompressed}, 127 } 128 129 c, s := net.Pipe() 130 var reply interface{} 131 var clientErr error 132 go func() { 133 cli := Client(c, testConfig) 134 cli.vers = clientHello.vers 135 cli.writeRecord(recordTypeHandshake, clientHello.marshal()) 136 reply, clientErr = cli.readHandshake() 137 c.Close() 138 }() 139 config := *testConfig 140 config.CipherSuites = clientHello.cipherSuites 141 Server(s, &config).Handshake() 142 s.Close() 143 if clientErr != nil { 144 t.Fatal(clientErr) 145 } 146 serverHello, ok := reply.(*serverHelloMsg) 147 if !ok { 148 t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply) 149 } 150 if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA { 151 t.Fatalf("bad cipher suite from server: %x", s) 152 } 153 } 154 155 func TestAlertForwarding(t *testing.T) { 156 c, s := net.Pipe() 157 go func() { 158 Client(c, testConfig).sendAlert(alertUnknownCA) 159 c.Close() 160 }() 161 162 err := Server(s, testConfig).Handshake() 163 s.Close() 164 if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) { 165 t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA)) 166 } 167 } 168 169 func TestClose(t *testing.T) { 170 c, s := net.Pipe() 171 go c.Close() 172 173 err := Server(s, testConfig).Handshake() 174 s.Close() 175 if err != io.EOF { 176 t.Errorf("Got error: %s; expected: %s", err, io.EOF) 177 } 178 } 179 180 func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, err error) { 181 c, s := net.Pipe() 182 done := make(chan bool) 183 go func() { 184 cli := Client(c, clientConfig) 185 cli.Handshake() 186 c.Close() 187 done <- true 188 }() 189 server := Server(s, serverConfig) 190 err = server.Handshake() 191 if err == nil { 192 state = server.ConnectionState() 193 } 194 s.Close() 195 <-done 196 return 197 } 198 199 func TestVersion(t *testing.T) { 200 serverConfig := &Config{ 201 Certificates: testConfig.Certificates, 202 MaxVersion: VersionTLS11, 203 } 204 clientConfig := &Config{ 205 InsecureSkipVerify: true, 206 } 207 state, err := testHandshake(clientConfig, serverConfig) 208 if err != nil { 209 t.Fatalf("handshake failed: %s", err) 210 } 211 if state.Version != VersionTLS11 { 212 t.Fatalf("Incorrect version %x, should be %x", state.Version, VersionTLS11) 213 } 214 } 215 216 func TestCipherSuitePreference(t *testing.T) { 217 serverConfig := &Config{ 218 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 219 Certificates: testConfig.Certificates, 220 MaxVersion: VersionTLS11, 221 } 222 clientConfig := &Config{ 223 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA}, 224 InsecureSkipVerify: true, 225 } 226 state, err := testHandshake(clientConfig, serverConfig) 227 if err != nil { 228 t.Fatalf("handshake failed: %s", err) 229 } 230 if state.CipherSuite != TLS_RSA_WITH_AES_128_CBC_SHA { 231 // By default the server should use the client's preference. 232 t.Fatalf("Client's preference was not used, got %x", state.CipherSuite) 233 } 234 235 serverConfig.PreferServerCipherSuites = true 236 state, err = testHandshake(clientConfig, serverConfig) 237 if err != nil { 238 t.Fatalf("handshake failed: %s", err) 239 } 240 if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA { 241 t.Fatalf("Server's preference was not used, got %x", state.CipherSuite) 242 } 243 } 244 245 // Note: see comment in handshake_test.go for details of how the reference 246 // tests work. 247 248 // serverTest represents a test of the TLS server handshake against a reference 249 // implementation. 250 type serverTest struct { 251 // name is a freeform string identifying the test and the file in which 252 // the expected results will be stored. 253 name string 254 // command, if not empty, contains a series of arguments for the 255 // command to run for the reference server. 256 command []string 257 // expectedPeerCerts contains a list of PEM blocks of expected 258 // certificates from the client. 259 expectedPeerCerts []string 260 // config, if not nil, contains a custom Config to use for this test. 261 config *Config 262 } 263 264 var defaultClientCommand = []string{"openssl", "s_client", "-no_ticket"} 265 266 // connFromCommand starts opens a listening socket and starts the reference 267 // client to connect to it. It returns a recordingConn that wraps the resulting 268 // connection. 269 func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, err error) { 270 l, err := net.ListenTCP("tcp", &net.TCPAddr{ 271 IP: net.IPv4(127, 0, 0, 1), 272 Port: 0, 273 }) 274 if err != nil { 275 return nil, nil, err 276 } 277 defer l.Close() 278 279 port := l.Addr().(*net.TCPAddr).Port 280 281 var command []string 282 command = append(command, test.command...) 283 if len(command) == 0 { 284 command = defaultClientCommand 285 } 286 command = append(command, "-connect") 287 command = append(command, fmt.Sprintf("127.0.0.1:%d", port)) 288 cmd := exec.Command(command[0], command[1:]...) 289 cmd.Stdin = nil 290 var output bytes.Buffer 291 cmd.Stdout = &output 292 cmd.Stderr = &output 293 if err := cmd.Start(); err != nil { 294 return nil, nil, err 295 } 296 297 connChan := make(chan interface{}) 298 go func() { 299 tcpConn, err := l.Accept() 300 if err != nil { 301 connChan <- err 302 } 303 connChan <- tcpConn 304 }() 305 306 var tcpConn net.Conn 307 select { 308 case connOrError := <-connChan: 309 if err, ok := connOrError.(error); ok { 310 return nil, nil, err 311 } 312 tcpConn = connOrError.(net.Conn) 313 case <-time.After(2 * time.Second): 314 output.WriteTo(os.Stdout) 315 return nil, nil, errors.New("timed out waiting for connection from child process") 316 } 317 318 record := &recordingConn{ 319 Conn: tcpConn, 320 } 321 322 return record, cmd, nil 323 } 324 325 func (test *serverTest) dataPath() string { 326 return filepath.Join("testdata", "Server-"+test.name) 327 } 328 329 func (test *serverTest) loadData() (flows [][]byte, err error) { 330 in, err := os.Open(test.dataPath()) 331 if err != nil { 332 return nil, err 333 } 334 defer in.Close() 335 return parseTestData(in) 336 } 337 338 func (test *serverTest) run(t *testing.T, write bool) { 339 var clientConn, serverConn net.Conn 340 var recordingConn *recordingConn 341 var childProcess *exec.Cmd 342 343 if write { 344 var err error 345 recordingConn, childProcess, err = test.connFromCommand() 346 if err != nil { 347 t.Fatalf("Failed to start subcommand: %s", err) 348 } 349 serverConn = recordingConn 350 } else { 351 clientConn, serverConn = net.Pipe() 352 } 353 config := test.config 354 if config == nil { 355 config = testConfig 356 } 357 server := Server(serverConn, config) 358 peerCertsChan := make(chan []*x509.Certificate, 1) 359 go func() { 360 if _, err := server.Write([]byte("hello, world\n")); err != nil { 361 t.Logf("Error from Server.Write: %s", err) 362 } 363 server.Close() 364 serverConn.Close() 365 peerCertsChan <- server.ConnectionState().PeerCertificates 366 }() 367 368 if !write { 369 flows, err := test.loadData() 370 if err != nil { 371 t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath()) 372 } 373 for i, b := range flows { 374 if i%2 == 0 { 375 clientConn.Write(b) 376 continue 377 } 378 bb := make([]byte, len(b)) 379 n, err := io.ReadFull(clientConn, bb) 380 if err != nil { 381 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) 382 } 383 if !bytes.Equal(b, bb) { 384 t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b) 385 } 386 } 387 clientConn.Close() 388 } 389 390 peerCerts := <-peerCertsChan 391 if len(peerCerts) == len(test.expectedPeerCerts) { 392 for i, peerCert := range peerCerts { 393 block, _ := pem.Decode([]byte(test.expectedPeerCerts[i])) 394 if !bytes.Equal(block.Bytes, peerCert.Raw) { 395 t.Fatalf("%s: mismatch on peer cert %d", test.name, i+1) 396 } 397 } 398 } else { 399 t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", test.name, len(test.expectedPeerCerts), len(peerCerts)) 400 } 401 402 if write { 403 path := test.dataPath() 404 out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 405 if err != nil { 406 t.Fatalf("Failed to create output file: %s", err) 407 } 408 defer out.Close() 409 recordingConn.Close() 410 if len(recordingConn.flows) < 3 { 411 childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout) 412 t.Fatalf("Handshake failed") 413 } 414 recordingConn.WriteTo(out) 415 fmt.Printf("Wrote %s\n", path) 416 childProcess.Wait() 417 } 418 } 419 420 func runServerTestForVersion(t *testing.T, template *serverTest, prefix, option string) { 421 test := *template 422 test.name = prefix + test.name 423 if len(test.command) == 0 { 424 test.command = defaultClientCommand 425 } 426 test.command = append([]string(nil), test.command...) 427 test.command = append(test.command, option) 428 test.run(t, *update) 429 } 430 431 func runServerTestSSLv3(t *testing.T, template *serverTest) { 432 runServerTestForVersion(t, template, "SSLv3-", "-ssl3") 433 } 434 435 func runServerTestTLS10(t *testing.T, template *serverTest) { 436 runServerTestForVersion(t, template, "TLSv10-", "-tls1") 437 } 438 439 func runServerTestTLS11(t *testing.T, template *serverTest) { 440 runServerTestForVersion(t, template, "TLSv11-", "-tls1_1") 441 } 442 443 func runServerTestTLS12(t *testing.T, template *serverTest) { 444 runServerTestForVersion(t, template, "TLSv12-", "-tls1_2") 445 } 446 447 func TestHandshakeServerRSARC4(t *testing.T) { 448 test := &serverTest{ 449 name: "RSA-RC4", 450 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"}, 451 } 452 runServerTestSSLv3(t, test) 453 runServerTestTLS10(t, test) 454 runServerTestTLS11(t, test) 455 runServerTestTLS12(t, test) 456 } 457 458 func TestHandshakeServerRSA3DES(t *testing.T) { 459 test := &serverTest{ 460 name: "RSA-3DES", 461 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"}, 462 } 463 runServerTestSSLv3(t, test) 464 runServerTestTLS10(t, test) 465 runServerTestTLS12(t, test) 466 } 467 468 func TestHandshakeServerRSAAES(t *testing.T) { 469 test := &serverTest{ 470 name: "RSA-AES", 471 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"}, 472 } 473 runServerTestSSLv3(t, test) 474 runServerTestTLS10(t, test) 475 runServerTestTLS12(t, test) 476 } 477 478 func TestHandshakeServerAESGCM(t *testing.T) { 479 test := &serverTest{ 480 name: "RSA-AES-GCM", 481 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"}, 482 } 483 runServerTestTLS12(t, test) 484 } 485 486 // TODO: figure out why this test is failing 487 //func TestHandshakeServerECDHEECDSAAES(t *testing.T) { 488 // config := *testConfig 489 // config.Certificates = make([]Certificate, 1) 490 // config.Certificates[0].Certificate = [][]byte{testECDSACertificate} 491 // config.Certificates[0].PrivateKey = testECDSAPrivateKey 492 // config.BuildNameToCertificate() 493 // 494 // test := &serverTest{ 495 // name: "ECDHE-ECDSA-AES", 496 // command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA"}, 497 // config: &config, 498 // } 499 // runServerTestTLS10(t, test) 500 // runServerTestTLS12(t, test) 501 //} 502 503 // TestHandshakeServerSNI involves a client sending an SNI extension of 504 // "snitest.com", which happens to match the CN of testSNICertificate. The test 505 // verifies that the server correctly selects that certificate. 506 func TestHandshakeServerSNI(t *testing.T) { 507 test := &serverTest{ 508 name: "SNI", 509 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"}, 510 } 511 runServerTestTLS12(t, test) 512 } 513 514 // TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with 515 // an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate. 516 // TODO: figure out why this test is failing 517 //func TestCipherSuiteCertPreferenceECDSA(t *testing.T) { 518 // config := *testConfig 519 // config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA} 520 // config.PreferServerCipherSuites = true 521 // 522 // test := &serverTest{ 523 // name: "CipherSuiteCertPreferenceRSA", 524 // config: &config, 525 // } 526 // runServerTestTLS12(t, test) 527 // 528 // config = *testConfig 529 // config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA} 530 // config.Certificates = []Certificate{ 531 // Certificate{ 532 // Certificate: [][]byte{testECDSACertificate}, 533 // PrivateKey: testECDSAPrivateKey, 534 // }, 535 // } 536 // config.BuildNameToCertificate() 537 // config.PreferServerCipherSuites = true 538 // 539 // test = &serverTest{ 540 // name: "CipherSuiteCertPreferenceECDSA", 541 // config: &config, 542 // } 543 // runServerTestTLS12(t, test) 544 //} 545 546 func TestResumption(t *testing.T) { 547 sessionFilePath := tempFile("") 548 defer os.Remove(sessionFilePath) 549 550 test := &serverTest{ 551 name: "IssueTicket", 552 command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath}, 553 } 554 runServerTestTLS12(t, test) 555 556 test = &serverTest{ 557 name: "Resume", 558 command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath}, 559 } 560 runServerTestTLS12(t, test) 561 } 562 563 func TestResumptionDisabled(t *testing.T) { 564 sessionFilePath := tempFile("") 565 defer os.Remove(sessionFilePath) 566 567 config := *testConfig 568 569 test := &serverTest{ 570 name: "IssueTicketPreDisable", 571 command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath}, 572 config: &config, 573 } 574 runServerTestTLS12(t, test) 575 576 config.SessionTicketsDisabled = true 577 578 test = &serverTest{ 579 name: "ResumeDisabled", 580 command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath}, 581 config: &config, 582 } 583 runServerTestTLS12(t, test) 584 585 // One needs to manually confirm that the handshake in the golden data 586 // file for ResumeDisabled does not include a resumption handshake. 587 } 588 589 // cert.pem and key.pem were generated with generate_cert.go 590 // Thus, they have no ExtKeyUsage fields and trigger an error 591 // when verification is turned on. 592 593 const clientCertificatePEM = ` 594 -----BEGIN CERTIFICATE----- 595 MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD 596 bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4 597 MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc 598 MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG 599 hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE 600 ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e 601 E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw 602 DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A 603 p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4 604 hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE 605 GFGNEH5PlGffo05wc46QkYU= 606 -----END CERTIFICATE-----` 607 608 const clientKeyPEM = ` 609 -----BEGIN RSA PRIVATE KEY----- 610 MIICWgIBAAKBgE7QezHjgmTZWcDCh6ReHotzM8djU99mkgaE9mTVj+Q2px0r6LMg 611 NkUjteOVru3g9SCcjZXff1oS74fkW2jk6Q507ASKf96TJ8QBGXq98tw9FKvQVMoh 612 DNBNbocuXMXSu01LT862LPd+iOx81wKRdKYeDBra40paLt4TnExAiFmTAgMBAAEC 613 gYBxvXd8yNteFTns8A/2yomEMC4yeosJJSpp1CsN3BJ7g8/qTnrVPxBy+RU+qr63 614 t2WquaOu/cr5P8iEsa6lk20tf8pjKLNXeX0b1RTzK8rJLbS7nGzP3tvOhL096VtQ 615 dAo4ROEaro0TzYpHmpciSvxVIeEIAAdFDObDJPKqcJAxyQJBAJizfYgK8Gzx9fsx 616 hxp+VteCbVPg2euASH5Yv3K5LukRdKoSzHE2grUVQgN/LafC0eZibRanxHegYSr7 617 7qaswKUCQQCEIWor/X4XTMdVj3Oj+vpiw75y/S9gh682+myZL+d/02IEkwnB098P 618 RkKVpenBHyrGg0oeN5La7URILWKj7CPXAkBKo6F+d+phNjwIFoN1Xb/RA32w/D1I 619 saG9sF+UEhRt9AxUfW/U/tIQ9V0ZHHcSg1XaCM5Nvp934brdKdvTOKnJAkBD5h/3 620 Rybatlvg/fzBEaJFyq09zhngkxlZOUtBVTqzl17RVvY2orgH02U4HbCHy4phxOn7 621 qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN 622 1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvA 623 -----END RSA PRIVATE KEY-----` 624 625 const clientECDSACertificatePEM = ` 626 -----BEGIN CERTIFICATE----- 627 MIIB/DCCAV4CCQCaMIRsJjXZFzAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw 628 EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 629 eSBMdGQwHhcNMTIxMTE0MTMyNTUzWhcNMjIxMTEyMTMyNTUzWjBBMQswCQYDVQQG 630 EwJBVTEMMAoGA1UECBMDTlNXMRAwDgYDVQQHEwdQeXJtb250MRIwEAYDVQQDEwlK 631 b2VsIFNpbmcwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACVjJF1FMBexFe01MNv 632 ja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd3kfDdq0Z9kUs 633 jLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx+U56jb0JuK7q 634 ixgnTy5w/hOWusPTQBbNZU6sER7m8TAJBgcqhkjOPQQBA4GMADCBiAJCAOAUxGBg 635 C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa 636 2RU6+b0DeoeiIzXsAkIBo9SKeDUcSpoj0gq+KxAxnZxfvuiRs9oa9V2jI/Umi0Vw 637 jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes= 638 -----END CERTIFICATE-----` 639 640 const clientECDSAKeyPEM = ` 641 -----BEGIN EC PARAMETERS----- 642 BgUrgQQAIw== 643 -----END EC PARAMETERS----- 644 -----BEGIN EC PRIVATE KEY----- 645 MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8 646 k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1 647 FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd 648 3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx 649 +U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q== 650 -----END EC PRIVATE KEY-----` 651 652 func TestClientAuth(t *testing.T) { 653 var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath string 654 655 if *update { 656 certPath = tempFile(clientCertificatePEM) 657 defer os.Remove(certPath) 658 keyPath = tempFile(clientKeyPEM) 659 defer os.Remove(keyPath) 660 ecdsaCertPath = tempFile(clientECDSACertificatePEM) 661 defer os.Remove(ecdsaCertPath) 662 ecdsaKeyPath = tempFile(clientECDSAKeyPEM) 663 defer os.Remove(ecdsaKeyPath) 664 } 665 666 config := *testConfig 667 config.ClientAuth = RequestClientCert 668 669 test := &serverTest{ 670 name: "ClientAuthRequestedNotGiven", 671 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"}, 672 config: &config, 673 } 674 runServerTestTLS12(t, test) 675 676 test = &serverTest{ 677 name: "ClientAuthRequestedAndGiven", 678 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", certPath, "-key", keyPath}, 679 config: &config, 680 expectedPeerCerts: []string{clientCertificatePEM}, 681 } 682 runServerTestTLS12(t, test) 683 684 test = &serverTest{ 685 name: "ClientAuthRequestedAndECDSAGiven", 686 command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", ecdsaCertPath, "-key", ecdsaKeyPath}, 687 config: &config, 688 expectedPeerCerts: []string{clientECDSACertificatePEM}, 689 } 690 runServerTestTLS12(t, test) 691 } 692 693 var getConfigForClientTests = []struct { 694 setup func(config *Config) 695 callback func(clientHello *ClientHelloInfo) (*Config, error) 696 errorSubstring string 697 verify func(config *Config) error 698 }{ 699 { 700 nil, 701 func(clientHello *ClientHelloInfo) (*Config, error) { 702 return nil, nil 703 }, 704 "", 705 nil, 706 }, 707 { 708 nil, 709 func(clientHello *ClientHelloInfo) (*Config, error) { 710 return nil, errors.New("should bubble up") 711 }, 712 "should bubble up", 713 nil, 714 }, 715 /* TODO: Find out why this test hangs 716 { 717 nil, 718 func(clientHello *ClientHelloInfo) (*Config, error) { 719 config := testConfig.Clone() 720 // Setting a maximum version of TLS 1.1 should cause 721 // the handshake to fail. 722 config.MaxVersion = VersionTLS11 723 return config, nil 724 }, 725 "version 301 when expecting version 302", 726 nil, 727 }, 728 */ 729 { 730 func(config *Config) { 731 for i := range config.SessionTicketKey { 732 config.SessionTicketKey[i] = byte(i) 733 } 734 config.sessionTicketKeys = nil 735 }, 736 func(clientHello *ClientHelloInfo) (*Config, error) { 737 config := testConfig.Clone() 738 for i := range config.SessionTicketKey { 739 config.SessionTicketKey[i] = 0 740 } 741 config.sessionTicketKeys = nil 742 return config, nil 743 }, 744 "", 745 func(config *Config) error { 746 // The value of SessionTicketKey should have been 747 // duplicated into the per-connection Config. 748 for i := range config.SessionTicketKey { 749 if b := config.SessionTicketKey[i]; b != byte(i) { 750 return fmt.Errorf("SessionTicketKey was not duplicated from original Config: byte %d has value %d", i, b) 751 } 752 } 753 return nil 754 }, 755 }, 756 { 757 func(config *Config) { 758 var dummyKey [32]byte 759 for i := range dummyKey { 760 dummyKey[i] = byte(i) 761 } 762 763 config.SetSessionTicketKeys([][32]byte{dummyKey}) 764 }, 765 func(clientHello *ClientHelloInfo) (*Config, error) { 766 config := testConfig.Clone() 767 config.sessionTicketKeys = nil 768 return config, nil 769 }, 770 "", 771 func(config *Config) error { 772 // The session ticket keys should have been duplicated 773 // into the per-connection Config. 774 if l := len(config.sessionTicketKeys); l != 1 { 775 return fmt.Errorf("got len(sessionTicketKeys) == %d, wanted 1", l) 776 } 777 return nil 778 }, 779 }, 780 } 781 782 func TestGetConfigForClient(t *testing.T) { 783 serverConfig := testConfig.Clone() 784 clientConfig := testConfig.Clone() 785 clientConfig.MinVersion = VersionTLS12 786 787 for i, test := range getConfigForClientTests { 788 if test.setup != nil { 789 test.setup(serverConfig) 790 } 791 792 var configReturned *Config 793 serverConfig.GetConfigForClient = func(clientHello *ClientHelloInfo) (*Config, error) { 794 config, err := test.callback(clientHello) 795 configReturned = config 796 return config, err 797 } 798 c, s := net.Pipe() 799 done := make(chan error) 800 801 go func() { 802 defer s.Close() 803 done <- Server(s, serverConfig).Handshake() 804 }() 805 806 clientErr := Client(c, clientConfig).Handshake() 807 c.Close() 808 809 serverErr := <-done 810 811 if len(test.errorSubstring) == 0 { 812 if serverErr != nil || clientErr != nil { 813 t.Errorf("test[%d]: expected no error but got serverErr: %q, clientErr: %q", i, serverErr, clientErr) 814 } 815 if test.verify != nil { 816 if err := test.verify(configReturned); err != nil { 817 t.Errorf("test[%d]: verify returned error: %v", i, err) 818 } 819 } 820 } else { 821 if serverErr == nil { 822 t.Errorf("test[%d]: expected error containing %q but got no error", i, test.errorSubstring) 823 } else if !strings.Contains(serverErr.Error(), test.errorSubstring) { 824 t.Errorf("test[%d]: expected error to contain %q but it was %q", i, test.errorSubstring, serverErr) 825 } 826 } 827 } 828 } 829 830 func bigFromString(s string) *big.Int { 831 ret := new(big.Int) 832 ret.SetString(s, 10) 833 return ret 834 } 835 836 func fromHex(s string) []byte { 837 b, _ := hex.DecodeString(s) 838 return b 839 } 840 841 var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101050003818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a381a73081a4301d0603551d0e04160414b1ade2855acfcb28db69ce2369ded3268e18883930750603551d23046e306c8014b1ade2855acfcb28db69ce2369ded3268e188839a149a4473045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746482090085b0bba48a7fb8ca300c0603551d13040530030101ff300d06092a864886f70d010105050003818100086c4524c76bb159ab0c52ccf2b014d7879d7a6475b55a9566e4c52b8eae12661feb4f38b36e60d392fdf74108b52513b1187a24fb301dbaed98b917ece7d73159db95d31d78ea50565cd5825a2d5a5f33c4b6d8c97590968c0f5298b5cd981f89205ff2a01ca31b9694dda9fd57e970e8266d71999b266e3850296c90a7bdd9") 842 843 var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186000400c4a1edbe98f90b4873367ec316561122f23d53c33b4d213dcd6b75e6f6b0dc9adf26c1bcb287f072327cb3642f1c90bcea6823107efee325c0483a69e0286dd33700ef0462dd0da09c706283d881d36431aa9e9731bd96b068c09b23de76643f1a5c7fe9120e5858b65f70dd9bd8ead5d7f5d5ccb9b69f30665b669a20e227e5bffe3b300906072a8648ce3d040103818c0030818802420188a24febe245c5487d1bacf5ed989dae4770c05e1bb62fbdf1b64db76140d311a2ceee0b7e927eff769dc33b7ea53fcefa10e259ec472d7cacda4e970e15a06fd00242014dfcbe67139c2d050ebd3fa38c25c13313830d9406bbd4377af6ec7ac9862eddd711697f857c56defb31782be4c7780daecbbe9e4e3624317b6a0f399512078f2a") 844 845 var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a864886f70d01010530283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d301e170d3132303431313137343033355a170d3133303431313137343533355a30283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d30819d300b06092a864886f70d01010103818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a56fcf506bffa587b263fb5cd04d3d0c921964ac7f4549f5abfef427100fe1899077f7e887d7df10439c4a22edb51c97ce3c04c3b326601cfafb11db8719a1ddbdb896baeda2d790203010001a3323030300e0603551d0f0101ff0404030200a0300d0603551d0e0406040401020304300f0603551d2304083006800401020304300b06092a864886f70d0101050381810089c6455f1c1f5ef8eb1ab174ee2439059f5c4259bb1a8d86cdb1d056f56a717da40e95ab90f59e8deaf627c157995094db0802266eb34fc6842dea8a4b68d9c1389103ab84fb9e1f85d9b5d23ff2312c8670fbb540148245a4ebafe264d90c8a4cf4f85b0fac12ac2fc4a3154bad52462868af96c62c6525d652b6e31845bdcc") 846 847 var testRSAPrivateKey = &rsa.PrivateKey{ 848 PublicKey: rsa.PublicKey{ 849 N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"), 850 E: 65537, 851 }, 852 D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"), 853 Primes: []*big.Int{ 854 bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"), 855 bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"), 856 }, 857 } 858 859 var testECDSAPrivateKey = &ecdsa.PrivateKey{ 860 PublicKey: ecdsa.PublicKey{ 861 Curve: elliptic.P521(), 862 X: bigFromString("2636411247892461147287360222306590634450676461695221912739908880441342231985950069527906976759812296359387337367668045707086543273113073382714101597903639351"), 863 Y: bigFromString("3204695818431246682253994090650952614555094516658732116404513121125038617915183037601737180082382202488628239201196033284060130040574800684774115478859677243"), 864 }, 865 D: bigFromString("5477294338614160138026852784385529180817726002953041720191098180813046231640184669647735805135001309477695746518160084669446643325196003346204701381388769751"), 866 }