1// Copyright (c) 2016, Google Inc. 2// 3// Permission to use, copy, modify, and/or distribute this software for any 4// purpose with or without fee is hereby granted, provided that the above 5// copyright notice and this permission notice appear in all copies. 6// 7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15package runner 16 17import ( 18 "bytes" 19 "crypto/ecdsa" 20 "crypto/elliptic" 21 "crypto/x509" 22 "encoding/base64" 23 "encoding/pem" 24 "flag" 25 "fmt" 26 "io" 27 "io/ioutil" 28 "math/big" 29 "net" 30 "os" 31 "os/exec" 32 "path" 33 "runtime" 34 "strconv" 35 "strings" 36 "sync" 37 "syscall" 38 "time" 39) 40 41var ( 42 useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind") 43 useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb") 44 useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb") 45 flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection") 46 mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.") 47 mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.") 48 jsonOutput = flag.String("json-output", "", "The file to output JSON results to.") 49 pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.") 50 testToRun = flag.String("test", "", "The name of a test to run, or empty to run all tests") 51 numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.") 52 shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.") 53 resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.") 54 fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.") 55 transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.") 56 idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.") 57 deterministic = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.") 58) 59 60const ( 61 rsaCertificateFile = "cert.pem" 62 ecdsaCertificateFile = "ecdsa_cert.pem" 63) 64 65const ( 66 rsaKeyFile = "key.pem" 67 ecdsaKeyFile = "ecdsa_key.pem" 68 channelIDKeyFile = "channel_id_key.pem" 69) 70 71var rsaCertificate, ecdsaCertificate Certificate 72var channelIDKey *ecdsa.PrivateKey 73var channelIDBytes []byte 74 75var testOCSPResponse = []byte{1, 2, 3, 4} 76var testSCTList = []byte{5, 6, 7, 8} 77 78func initCertificates() { 79 var err error 80 rsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, rsaCertificateFile), path.Join(*resourceDir, rsaKeyFile)) 81 if err != nil { 82 panic(err) 83 } 84 rsaCertificate.OCSPStaple = testOCSPResponse 85 rsaCertificate.SignedCertificateTimestampList = testSCTList 86 87 ecdsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, ecdsaCertificateFile), path.Join(*resourceDir, ecdsaKeyFile)) 88 if err != nil { 89 panic(err) 90 } 91 ecdsaCertificate.OCSPStaple = testOCSPResponse 92 ecdsaCertificate.SignedCertificateTimestampList = testSCTList 93 94 channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile)) 95 if err != nil { 96 panic(err) 97 } 98 channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock) 99 if channelIDDERBlock.Type != "EC PRIVATE KEY" { 100 panic("bad key type") 101 } 102 channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes) 103 if err != nil { 104 panic(err) 105 } 106 if channelIDKey.Curve != elliptic.P256() { 107 panic("bad curve") 108 } 109 110 channelIDBytes = make([]byte, 64) 111 writeIntPadded(channelIDBytes[:32], channelIDKey.X) 112 writeIntPadded(channelIDBytes[32:], channelIDKey.Y) 113} 114 115var certificateOnce sync.Once 116 117func getRSACertificate() Certificate { 118 certificateOnce.Do(initCertificates) 119 return rsaCertificate 120} 121 122func getECDSACertificate() Certificate { 123 certificateOnce.Do(initCertificates) 124 return ecdsaCertificate 125} 126 127type testType int 128 129const ( 130 clientTest testType = iota 131 serverTest 132) 133 134type protocol int 135 136const ( 137 tls protocol = iota 138 dtls 139) 140 141const ( 142 alpn = 1 143 npn = 2 144) 145 146type testCase struct { 147 testType testType 148 protocol protocol 149 name string 150 config Config 151 shouldFail bool 152 expectedError string 153 // expectedLocalError, if not empty, contains a substring that must be 154 // found in the local error. 155 expectedLocalError string 156 // expectedVersion, if non-zero, specifies the TLS version that must be 157 // negotiated. 158 expectedVersion uint16 159 // expectedResumeVersion, if non-zero, specifies the TLS version that 160 // must be negotiated on resumption. If zero, expectedVersion is used. 161 expectedResumeVersion uint16 162 // expectedCipher, if non-zero, specifies the TLS cipher suite that 163 // should be negotiated. 164 expectedCipher uint16 165 // expectChannelID controls whether the connection should have 166 // negotiated a Channel ID with channelIDKey. 167 expectChannelID bool 168 // expectedNextProto controls whether the connection should 169 // negotiate a next protocol via NPN or ALPN. 170 expectedNextProto string 171 // expectNoNextProto, if true, means that no next protocol should be 172 // negotiated. 173 expectNoNextProto bool 174 // expectedNextProtoType, if non-zero, is the expected next 175 // protocol negotiation mechanism. 176 expectedNextProtoType int 177 // expectedSRTPProtectionProfile is the DTLS-SRTP profile that 178 // should be negotiated. If zero, none should be negotiated. 179 expectedSRTPProtectionProfile uint16 180 // expectedOCSPResponse, if not nil, is the expected OCSP response to be received. 181 expectedOCSPResponse []uint8 182 // expectedSCTList, if not nil, is the expected SCT list to be received. 183 expectedSCTList []uint8 184 // expectedClientCertSignatureHash, if not zero, is the TLS id of the 185 // hash function that the client should have used when signing the 186 // handshake with a client certificate. 187 expectedClientCertSignatureHash uint8 188 // messageLen is the length, in bytes, of the test message that will be 189 // sent. 190 messageLen int 191 // messageCount is the number of test messages that will be sent. 192 messageCount int 193 // digestPrefs is the list of digest preferences from the client. 194 digestPrefs string 195 // certFile is the path to the certificate to use for the server. 196 certFile string 197 // keyFile is the path to the private key to use for the server. 198 keyFile string 199 // resumeSession controls whether a second connection should be tested 200 // which attempts to resume the first session. 201 resumeSession bool 202 // expectResumeRejected, if true, specifies that the attempted 203 // resumption must be rejected by the client. This is only valid for a 204 // serverTest. 205 expectResumeRejected bool 206 // resumeConfig, if not nil, points to a Config to be used on 207 // resumption. Unless newSessionsOnResume is set, 208 // SessionTicketKey, ServerSessionCache, and 209 // ClientSessionCache are copied from the initial connection's 210 // config. If nil, the initial connection's config is used. 211 resumeConfig *Config 212 // newSessionsOnResume, if true, will cause resumeConfig to 213 // use a different session resumption context. 214 newSessionsOnResume bool 215 // noSessionCache, if true, will cause the server to run without a 216 // session cache. 217 noSessionCache bool 218 // sendPrefix sends a prefix on the socket before actually performing a 219 // handshake. 220 sendPrefix string 221 // shimWritesFirst controls whether the shim sends an initial "hello" 222 // message before doing a roundtrip with the runner. 223 shimWritesFirst bool 224 // shimShutsDown, if true, runs a test where the shim shuts down the 225 // connection immediately after the handshake rather than echoing 226 // messages from the runner. 227 shimShutsDown bool 228 // renegotiate indicates the number of times the connection should be 229 // renegotiated during the exchange. 230 renegotiate int 231 // renegotiateCiphers is a list of ciphersuite ids that will be 232 // switched in just before renegotiation. 233 renegotiateCiphers []uint16 234 // replayWrites, if true, configures the underlying transport 235 // to replay every write it makes in DTLS tests. 236 replayWrites bool 237 // damageFirstWrite, if true, configures the underlying transport to 238 // damage the final byte of the first application data write. 239 damageFirstWrite bool 240 // exportKeyingMaterial, if non-zero, configures the test to exchange 241 // keying material and verify they match. 242 exportKeyingMaterial int 243 exportLabel string 244 exportContext string 245 useExportContext bool 246 // flags, if not empty, contains a list of command-line flags that will 247 // be passed to the shim program. 248 flags []string 249 // testTLSUnique, if true, causes the shim to send the tls-unique value 250 // which will be compared against the expected value. 251 testTLSUnique bool 252 // sendEmptyRecords is the number of consecutive empty records to send 253 // before and after the test message. 254 sendEmptyRecords int 255 // sendWarningAlerts is the number of consecutive warning alerts to send 256 // before and after the test message. 257 sendWarningAlerts int 258 // expectMessageDropped, if true, means the test message is expected to 259 // be dropped by the client rather than echoed back. 260 expectMessageDropped bool 261} 262 263var testCases []testCase 264 265func writeTranscript(test *testCase, isResume bool, data []byte) { 266 if len(data) == 0 { 267 return 268 } 269 270 protocol := "tls" 271 if test.protocol == dtls { 272 protocol = "dtls" 273 } 274 275 side := "client" 276 if test.testType == serverTest { 277 side = "server" 278 } 279 280 dir := path.Join(*transcriptDir, protocol, side) 281 if err := os.MkdirAll(dir, 0755); err != nil { 282 fmt.Fprintf(os.Stderr, "Error making %s: %s\n", dir, err) 283 return 284 } 285 286 name := test.name 287 if isResume { 288 name += "-Resume" 289 } else { 290 name += "-Normal" 291 } 292 293 if err := ioutil.WriteFile(path.Join(dir, name), data, 0644); err != nil { 294 fmt.Fprintf(os.Stderr, "Error writing %s: %s\n", name, err) 295 } 296} 297 298// A timeoutConn implements an idle timeout on each Read and Write operation. 299type timeoutConn struct { 300 net.Conn 301 timeout time.Duration 302} 303 304func (t *timeoutConn) Read(b []byte) (int, error) { 305 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil { 306 return 0, err 307 } 308 return t.Conn.Read(b) 309} 310 311func (t *timeoutConn) Write(b []byte) (int, error) { 312 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil { 313 return 0, err 314 } 315 return t.Conn.Write(b) 316} 317 318func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error { 319 conn = &timeoutConn{conn, *idleTimeout} 320 321 if test.protocol == dtls { 322 config.Bugs.PacketAdaptor = newPacketAdaptor(conn) 323 conn = config.Bugs.PacketAdaptor 324 } 325 326 if *flagDebug || len(*transcriptDir) != 0 { 327 local, peer := "client", "server" 328 if test.testType == clientTest { 329 local, peer = peer, local 330 } 331 connDebug := &recordingConn{ 332 Conn: conn, 333 isDatagram: test.protocol == dtls, 334 local: local, 335 peer: peer, 336 } 337 conn = connDebug 338 if *flagDebug { 339 defer connDebug.WriteTo(os.Stdout) 340 } 341 if len(*transcriptDir) != 0 { 342 defer func() { 343 writeTranscript(test, isResume, connDebug.Transcript()) 344 }() 345 } 346 347 if config.Bugs.PacketAdaptor != nil { 348 config.Bugs.PacketAdaptor.debug = connDebug 349 } 350 } 351 352 if test.replayWrites { 353 conn = newReplayAdaptor(conn) 354 } 355 356 var connDamage *damageAdaptor 357 if test.damageFirstWrite { 358 connDamage = newDamageAdaptor(conn) 359 conn = connDamage 360 } 361 362 if test.sendPrefix != "" { 363 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil { 364 return err 365 } 366 } 367 368 var tlsConn *Conn 369 if test.testType == clientTest { 370 if test.protocol == dtls { 371 tlsConn = DTLSServer(conn, config) 372 } else { 373 tlsConn = Server(conn, config) 374 } 375 } else { 376 config.InsecureSkipVerify = true 377 if test.protocol == dtls { 378 tlsConn = DTLSClient(conn, config) 379 } else { 380 tlsConn = Client(conn, config) 381 } 382 } 383 defer tlsConn.Close() 384 385 if err := tlsConn.Handshake(); err != nil { 386 return err 387 } 388 389 // TODO(davidben): move all per-connection expectations into a dedicated 390 // expectations struct that can be specified separately for the two 391 // legs. 392 expectedVersion := test.expectedVersion 393 if isResume && test.expectedResumeVersion != 0 { 394 expectedVersion = test.expectedResumeVersion 395 } 396 connState := tlsConn.ConnectionState() 397 if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion { 398 return fmt.Errorf("got version %x, expected %x", vers, expectedVersion) 399 } 400 401 if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher { 402 return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher) 403 } 404 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected { 405 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume) 406 } 407 408 if test.expectChannelID { 409 channelID := connState.ChannelID 410 if channelID == nil { 411 return fmt.Errorf("no channel ID negotiated") 412 } 413 if channelID.Curve != channelIDKey.Curve || 414 channelIDKey.X.Cmp(channelIDKey.X) != 0 || 415 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 { 416 return fmt.Errorf("incorrect channel ID") 417 } 418 } 419 420 if expected := test.expectedNextProto; expected != "" { 421 if actual := connState.NegotiatedProtocol; actual != expected { 422 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected) 423 } 424 } 425 426 if test.expectNoNextProto { 427 if actual := connState.NegotiatedProtocol; actual != "" { 428 return fmt.Errorf("got unexpected next proto %s", actual) 429 } 430 } 431 432 if test.expectedNextProtoType != 0 { 433 if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN { 434 return fmt.Errorf("next proto type mismatch") 435 } 436 } 437 438 if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile { 439 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile) 440 } 441 442 if test.expectedOCSPResponse != nil && !bytes.Equal(test.expectedOCSPResponse, tlsConn.OCSPResponse()) { 443 return fmt.Errorf("OCSP Response mismatch") 444 } 445 446 if test.expectedSCTList != nil && !bytes.Equal(test.expectedSCTList, connState.SCTList) { 447 return fmt.Errorf("SCT list mismatch") 448 } 449 450 if expected := test.expectedClientCertSignatureHash; expected != 0 && expected != connState.ClientCertSignatureHash { 451 return fmt.Errorf("expected client to sign handshake with hash %d, but got %d", expected, connState.ClientCertSignatureHash) 452 } 453 454 if test.exportKeyingMaterial > 0 { 455 actual := make([]byte, test.exportKeyingMaterial) 456 if _, err := io.ReadFull(tlsConn, actual); err != nil { 457 return err 458 } 459 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext) 460 if err != nil { 461 return err 462 } 463 if !bytes.Equal(actual, expected) { 464 return fmt.Errorf("keying material mismatch") 465 } 466 } 467 468 if test.testTLSUnique { 469 var peersValue [12]byte 470 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil { 471 return err 472 } 473 expected := tlsConn.ConnectionState().TLSUnique 474 if !bytes.Equal(peersValue[:], expected) { 475 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected) 476 } 477 } 478 479 if test.shimWritesFirst { 480 var buf [5]byte 481 _, err := io.ReadFull(tlsConn, buf[:]) 482 if err != nil { 483 return err 484 } 485 if string(buf[:]) != "hello" { 486 return fmt.Errorf("bad initial message") 487 } 488 } 489 490 for i := 0; i < test.sendEmptyRecords; i++ { 491 tlsConn.Write(nil) 492 } 493 494 for i := 0; i < test.sendWarningAlerts; i++ { 495 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage) 496 } 497 498 if test.renegotiate > 0 { 499 if test.renegotiateCiphers != nil { 500 config.CipherSuites = test.renegotiateCiphers 501 } 502 for i := 0; i < test.renegotiate; i++ { 503 if err := tlsConn.Renegotiate(); err != nil { 504 return err 505 } 506 } 507 } else if test.renegotiateCiphers != nil { 508 panic("renegotiateCiphers without renegotiate") 509 } 510 511 if test.damageFirstWrite { 512 connDamage.setDamage(true) 513 tlsConn.Write([]byte("DAMAGED WRITE")) 514 connDamage.setDamage(false) 515 } 516 517 messageLen := test.messageLen 518 if messageLen < 0 { 519 if test.protocol == dtls { 520 return fmt.Errorf("messageLen < 0 not supported for DTLS tests") 521 } 522 // Read until EOF. 523 _, err := io.Copy(ioutil.Discard, tlsConn) 524 return err 525 } 526 if messageLen == 0 { 527 messageLen = 32 528 } 529 530 messageCount := test.messageCount 531 if messageCount == 0 { 532 messageCount = 1 533 } 534 535 for j := 0; j < messageCount; j++ { 536 testMessage := make([]byte, messageLen) 537 for i := range testMessage { 538 testMessage[i] = 0x42 ^ byte(j) 539 } 540 tlsConn.Write(testMessage) 541 542 for i := 0; i < test.sendEmptyRecords; i++ { 543 tlsConn.Write(nil) 544 } 545 546 for i := 0; i < test.sendWarningAlerts; i++ { 547 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage) 548 } 549 550 if test.shimShutsDown || test.expectMessageDropped { 551 // The shim will not respond. 552 continue 553 } 554 555 buf := make([]byte, len(testMessage)) 556 if test.protocol == dtls { 557 bufTmp := make([]byte, len(buf)+1) 558 n, err := tlsConn.Read(bufTmp) 559 if err != nil { 560 return err 561 } 562 if n != len(buf) { 563 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf)) 564 } 565 copy(buf, bufTmp) 566 } else { 567 _, err := io.ReadFull(tlsConn, buf) 568 if err != nil { 569 return err 570 } 571 } 572 573 for i, v := range buf { 574 if v != testMessage[i]^0xff { 575 return fmt.Errorf("bad reply contents at byte %d", i) 576 } 577 } 578 } 579 580 return nil 581} 582 583func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd { 584 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full"} 585 if dbAttach { 586 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p") 587 } 588 valgrindArgs = append(valgrindArgs, path) 589 valgrindArgs = append(valgrindArgs, args...) 590 591 return exec.Command("valgrind", valgrindArgs...) 592} 593 594func gdbOf(path string, args ...string) *exec.Cmd { 595 xtermArgs := []string{"-e", "gdb", "--args"} 596 xtermArgs = append(xtermArgs, path) 597 xtermArgs = append(xtermArgs, args...) 598 599 return exec.Command("xterm", xtermArgs...) 600} 601 602func lldbOf(path string, args ...string) *exec.Cmd { 603 xtermArgs := []string{"-e", "lldb", "--"} 604 xtermArgs = append(xtermArgs, path) 605 xtermArgs = append(xtermArgs, args...) 606 607 return exec.Command("xterm", xtermArgs...) 608} 609 610type moreMallocsError struct{} 611 612func (moreMallocsError) Error() string { 613 return "child process did not exhaust all allocation calls" 614} 615 616var errMoreMallocs = moreMallocsError{} 617 618// accept accepts a connection from listener, unless waitChan signals a process 619// exit first. 620func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error) { 621 type connOrError struct { 622 conn net.Conn 623 err error 624 } 625 connChan := make(chan connOrError, 1) 626 go func() { 627 conn, err := listener.Accept() 628 connChan <- connOrError{conn, err} 629 close(connChan) 630 }() 631 select { 632 case result := <-connChan: 633 return result.conn, result.err 634 case childErr := <-waitChan: 635 waitChan <- childErr 636 return nil, fmt.Errorf("child exited early: %s", childErr) 637 } 638} 639 640func runTest(test *testCase, shimPath string, mallocNumToFail int64) error { 641 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) { 642 panic("Error expected without shouldFail in " + test.name) 643 } 644 645 if test.expectResumeRejected && !test.resumeSession { 646 panic("expectResumeRejected without resumeSession in " + test.name) 647 } 648 649 if test.testType != clientTest && test.expectedClientCertSignatureHash != 0 { 650 panic("expectedClientCertSignatureHash non-zero with serverTest in " + test.name) 651 } 652 653 listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}}) 654 if err != nil { 655 panic(err) 656 } 657 defer func() { 658 if listener != nil { 659 listener.Close() 660 } 661 }() 662 663 flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)} 664 if test.testType == serverTest { 665 flags = append(flags, "-server") 666 667 flags = append(flags, "-key-file") 668 if test.keyFile == "" { 669 flags = append(flags, path.Join(*resourceDir, rsaKeyFile)) 670 } else { 671 flags = append(flags, path.Join(*resourceDir, test.keyFile)) 672 } 673 674 flags = append(flags, "-cert-file") 675 if test.certFile == "" { 676 flags = append(flags, path.Join(*resourceDir, rsaCertificateFile)) 677 } else { 678 flags = append(flags, path.Join(*resourceDir, test.certFile)) 679 } 680 } 681 682 if test.digestPrefs != "" { 683 flags = append(flags, "-digest-prefs") 684 flags = append(flags, test.digestPrefs) 685 } 686 687 if test.protocol == dtls { 688 flags = append(flags, "-dtls") 689 } 690 691 if test.resumeSession { 692 flags = append(flags, "-resume") 693 } 694 695 if test.shimWritesFirst { 696 flags = append(flags, "-shim-writes-first") 697 } 698 699 if test.shimShutsDown { 700 flags = append(flags, "-shim-shuts-down") 701 } 702 703 if test.exportKeyingMaterial > 0 { 704 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial)) 705 flags = append(flags, "-export-label", test.exportLabel) 706 flags = append(flags, "-export-context", test.exportContext) 707 if test.useExportContext { 708 flags = append(flags, "-use-export-context") 709 } 710 } 711 if test.expectResumeRejected { 712 flags = append(flags, "-expect-session-miss") 713 } 714 715 if test.testTLSUnique { 716 flags = append(flags, "-tls-unique") 717 } 718 719 flags = append(flags, test.flags...) 720 721 var shim *exec.Cmd 722 if *useValgrind { 723 shim = valgrindOf(false, shimPath, flags...) 724 } else if *useGDB { 725 shim = gdbOf(shimPath, flags...) 726 } else if *useLLDB { 727 shim = lldbOf(shimPath, flags...) 728 } else { 729 shim = exec.Command(shimPath, flags...) 730 } 731 shim.Stdin = os.Stdin 732 var stdoutBuf, stderrBuf bytes.Buffer 733 shim.Stdout = &stdoutBuf 734 shim.Stderr = &stderrBuf 735 if mallocNumToFail >= 0 { 736 shim.Env = os.Environ() 737 shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10)) 738 if *mallocTestDebug { 739 shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1") 740 } 741 shim.Env = append(shim.Env, "_MALLOC_CHECK=1") 742 } 743 744 if err := shim.Start(); err != nil { 745 panic(err) 746 } 747 waitChan := make(chan error, 1) 748 go func() { waitChan <- shim.Wait() }() 749 750 config := test.config 751 if !test.noSessionCache { 752 config.ClientSessionCache = NewLRUClientSessionCache(1) 753 config.ServerSessionCache = NewLRUServerSessionCache(1) 754 } 755 if test.testType == clientTest { 756 if len(config.Certificates) == 0 { 757 config.Certificates = []Certificate{getRSACertificate()} 758 } 759 } else { 760 // Supply a ServerName to ensure a constant session cache key, 761 // rather than falling back to net.Conn.RemoteAddr. 762 if len(config.ServerName) == 0 { 763 config.ServerName = "test" 764 } 765 } 766 if *fuzzer { 767 config.Bugs.NullAllCiphers = true 768 } 769 if *deterministic { 770 config.Rand = &deterministicRand{} 771 } 772 773 conn, err := acceptOrWait(listener, waitChan) 774 if err == nil { 775 err = doExchange(test, &config, conn, false /* not a resumption */) 776 conn.Close() 777 } 778 779 if err == nil && test.resumeSession { 780 var resumeConfig Config 781 if test.resumeConfig != nil { 782 resumeConfig = *test.resumeConfig 783 if len(resumeConfig.ServerName) == 0 { 784 resumeConfig.ServerName = config.ServerName 785 } 786 if len(resumeConfig.Certificates) == 0 { 787 resumeConfig.Certificates = []Certificate{getRSACertificate()} 788 } 789 if test.newSessionsOnResume { 790 if !test.noSessionCache { 791 resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1) 792 resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1) 793 } 794 } else { 795 resumeConfig.SessionTicketKey = config.SessionTicketKey 796 resumeConfig.ClientSessionCache = config.ClientSessionCache 797 resumeConfig.ServerSessionCache = config.ServerSessionCache 798 } 799 if *fuzzer { 800 resumeConfig.Bugs.NullAllCiphers = true 801 } 802 resumeConfig.Rand = config.Rand 803 } else { 804 resumeConfig = config 805 } 806 var connResume net.Conn 807 connResume, err = acceptOrWait(listener, waitChan) 808 if err == nil { 809 err = doExchange(test, &resumeConfig, connResume, true /* resumption */) 810 connResume.Close() 811 } 812 } 813 814 // Close the listener now. This is to avoid hangs should the shim try to 815 // open more connections than expected. 816 listener.Close() 817 listener = nil 818 819 childErr := <-waitChan 820 if exitError, ok := childErr.(*exec.ExitError); ok { 821 if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 { 822 return errMoreMallocs 823 } 824 } 825 826 // Account for Windows line endings. 827 stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1) 828 stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1) 829 830 // Separate the errors from the shim and those from tools like 831 // AddressSanitizer. 832 var extraStderr string 833 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 { 834 stderr = stderrParts[0] 835 extraStderr = stderrParts[1] 836 } 837 838 failed := err != nil || childErr != nil 839 correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError) 840 localError := "none" 841 if err != nil { 842 localError = err.Error() 843 } 844 if len(test.expectedLocalError) != 0 { 845 correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError) 846 } 847 848 if failed != test.shouldFail || failed && !correctFailure { 849 childError := "none" 850 if childErr != nil { 851 childError = childErr.Error() 852 } 853 854 var msg string 855 switch { 856 case failed && !test.shouldFail: 857 msg = "unexpected failure" 858 case !failed && test.shouldFail: 859 msg = "unexpected success" 860 case failed && !correctFailure: 861 msg = "bad error (wanted '" + test.expectedError + "' / '" + test.expectedLocalError + "')" 862 default: 863 panic("internal error") 864 } 865 866 return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, stdout, stderr) 867 } 868 869 if !*useValgrind && (len(extraStderr) > 0 || (!failed && len(stderr) > 0)) { 870 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr) 871 } 872 873 return nil 874} 875 876var tlsVersions = []struct { 877 name string 878 version uint16 879 flag string 880 hasDTLS bool 881}{ 882 {"SSL3", VersionSSL30, "-no-ssl3", false}, 883 {"TLS1", VersionTLS10, "-no-tls1", true}, 884 {"TLS11", VersionTLS11, "-no-tls11", false}, 885 {"TLS12", VersionTLS12, "-no-tls12", true}, 886} 887 888var testCipherSuites = []struct { 889 name string 890 id uint16 891}{ 892 {"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 893 {"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256}, 894 {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA}, 895 {"AES128-SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256}, 896 {"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384}, 897 {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA}, 898 {"AES256-SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256}, 899 {"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 900 {"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA}, 901 {"DHE-RSA-AES128-SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256}, 902 {"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384}, 903 {"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA}, 904 {"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256}, 905 {"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 906 {"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, 907 {"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}, 908 {"ECDHE-ECDSA-AES256-GCM", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, 909 {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, 910 {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384}, 911 {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, 912 {"ECDHE-ECDSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD}, 913 {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA}, 914 {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 915 {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 916 {"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, 917 {"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, 918 {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 919 {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384}, 920 {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 921 {"ECDHE-RSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD}, 922 {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 923 {"CECPQ1-RSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256}, 924 {"CECPQ1-ECDSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, 925 {"CECPQ1-RSA-AES256-GCM-SHA384", TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, 926 {"CECPQ1-ECDSA-AES256-GCM-SHA384", TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384}, 927 {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA}, 928 {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA}, 929 {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 930 {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA}, 931 {"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, 932 {"ECDHE-PSK-AES128-GCM-SHA256", TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256}, 933 {"ECDHE-PSK-AES256-GCM-SHA384", TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384}, 934 {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA}, 935 {"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5}, 936 {"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA}, 937 {"NULL-SHA", TLS_RSA_WITH_NULL_SHA}, 938} 939 940func hasComponent(suiteName, component string) bool { 941 return strings.Contains("-"+suiteName+"-", "-"+component+"-") 942} 943 944func isTLSOnly(suiteName string) bool { 945 // BoringSSL doesn't support ECDHE without a curves extension, and 946 // SSLv3 doesn't contain extensions. 947 return hasComponent(suiteName, "ECDHE") || isTLS12Only(suiteName) 948} 949 950func isTLS12Only(suiteName string) bool { 951 return hasComponent(suiteName, "GCM") || 952 hasComponent(suiteName, "SHA256") || 953 hasComponent(suiteName, "SHA384") || 954 hasComponent(suiteName, "POLY1305") 955} 956 957func isDTLSCipher(suiteName string) bool { 958 return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL") 959} 960 961func bigFromHex(hex string) *big.Int { 962 ret, ok := new(big.Int).SetString(hex, 16) 963 if !ok { 964 panic("failed to parse hex number 0x" + hex) 965 } 966 return ret 967} 968 969func addBasicTests() { 970 basicTests := []testCase{ 971 { 972 name: "BadRSASignature", 973 config: Config{ 974 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 975 Bugs: ProtocolBugs{ 976 InvalidSKXSignature: true, 977 }, 978 }, 979 shouldFail: true, 980 expectedError: ":BAD_SIGNATURE:", 981 }, 982 { 983 name: "BadECDSASignature", 984 config: Config{ 985 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 986 Bugs: ProtocolBugs{ 987 InvalidSKXSignature: true, 988 }, 989 Certificates: []Certificate{getECDSACertificate()}, 990 }, 991 shouldFail: true, 992 expectedError: ":BAD_SIGNATURE:", 993 }, 994 { 995 testType: serverTest, 996 name: "BadRSASignature-ClientAuth", 997 config: Config{ 998 Bugs: ProtocolBugs{ 999 InvalidCertVerifySignature: true, 1000 }, 1001 Certificates: []Certificate{getRSACertificate()}, 1002 }, 1003 shouldFail: true, 1004 expectedError: ":BAD_SIGNATURE:", 1005 flags: []string{"-require-any-client-certificate"}, 1006 }, 1007 { 1008 testType: serverTest, 1009 name: "BadECDSASignature-ClientAuth", 1010 config: Config{ 1011 Bugs: ProtocolBugs{ 1012 InvalidCertVerifySignature: true, 1013 }, 1014 Certificates: []Certificate{getECDSACertificate()}, 1015 }, 1016 shouldFail: true, 1017 expectedError: ":BAD_SIGNATURE:", 1018 flags: []string{"-require-any-client-certificate"}, 1019 }, 1020 { 1021 name: "BadECDSACurve", 1022 config: Config{ 1023 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 1024 Bugs: ProtocolBugs{ 1025 InvalidSKXCurve: true, 1026 }, 1027 Certificates: []Certificate{getECDSACertificate()}, 1028 }, 1029 shouldFail: true, 1030 expectedError: ":WRONG_CURVE:", 1031 }, 1032 { 1033 name: "NoFallbackSCSV", 1034 config: Config{ 1035 Bugs: ProtocolBugs{ 1036 FailIfNotFallbackSCSV: true, 1037 }, 1038 }, 1039 shouldFail: true, 1040 expectedLocalError: "no fallback SCSV found", 1041 }, 1042 { 1043 name: "SendFallbackSCSV", 1044 config: Config{ 1045 Bugs: ProtocolBugs{ 1046 FailIfNotFallbackSCSV: true, 1047 }, 1048 }, 1049 flags: []string{"-fallback-scsv"}, 1050 }, 1051 { 1052 name: "ClientCertificateTypes", 1053 config: Config{ 1054 ClientAuth: RequestClientCert, 1055 ClientCertificateTypes: []byte{ 1056 CertTypeDSSSign, 1057 CertTypeRSASign, 1058 CertTypeECDSASign, 1059 }, 1060 }, 1061 flags: []string{ 1062 "-expect-certificate-types", 1063 base64.StdEncoding.EncodeToString([]byte{ 1064 CertTypeDSSSign, 1065 CertTypeRSASign, 1066 CertTypeECDSASign, 1067 }), 1068 }, 1069 }, 1070 { 1071 name: "NoClientCertificate", 1072 config: Config{ 1073 ClientAuth: RequireAnyClientCert, 1074 }, 1075 shouldFail: true, 1076 expectedLocalError: "client didn't provide a certificate", 1077 }, 1078 { 1079 name: "UnauthenticatedECDH", 1080 config: Config{ 1081 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1082 Bugs: ProtocolBugs{ 1083 UnauthenticatedECDH: true, 1084 }, 1085 }, 1086 shouldFail: true, 1087 expectedError: ":UNEXPECTED_MESSAGE:", 1088 }, 1089 { 1090 name: "SkipCertificateStatus", 1091 config: Config{ 1092 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1093 Bugs: ProtocolBugs{ 1094 SkipCertificateStatus: true, 1095 }, 1096 }, 1097 flags: []string{ 1098 "-enable-ocsp-stapling", 1099 }, 1100 }, 1101 { 1102 name: "SkipServerKeyExchange", 1103 config: Config{ 1104 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1105 Bugs: ProtocolBugs{ 1106 SkipServerKeyExchange: true, 1107 }, 1108 }, 1109 shouldFail: true, 1110 expectedError: ":UNEXPECTED_MESSAGE:", 1111 }, 1112 { 1113 name: "SkipChangeCipherSpec-Client", 1114 config: Config{ 1115 Bugs: ProtocolBugs{ 1116 SkipChangeCipherSpec: true, 1117 }, 1118 }, 1119 shouldFail: true, 1120 expectedError: ":UNEXPECTED_RECORD:", 1121 }, 1122 { 1123 testType: serverTest, 1124 name: "SkipChangeCipherSpec-Server", 1125 config: Config{ 1126 Bugs: ProtocolBugs{ 1127 SkipChangeCipherSpec: true, 1128 }, 1129 }, 1130 shouldFail: true, 1131 expectedError: ":UNEXPECTED_RECORD:", 1132 }, 1133 { 1134 testType: serverTest, 1135 name: "SkipChangeCipherSpec-Server-NPN", 1136 config: Config{ 1137 NextProtos: []string{"bar"}, 1138 Bugs: ProtocolBugs{ 1139 SkipChangeCipherSpec: true, 1140 }, 1141 }, 1142 flags: []string{ 1143 "-advertise-npn", "\x03foo\x03bar\x03baz", 1144 }, 1145 shouldFail: true, 1146 expectedError: ":UNEXPECTED_RECORD:", 1147 }, 1148 { 1149 name: "FragmentAcrossChangeCipherSpec-Client", 1150 config: Config{ 1151 Bugs: ProtocolBugs{ 1152 FragmentAcrossChangeCipherSpec: true, 1153 }, 1154 }, 1155 shouldFail: true, 1156 expectedError: ":UNEXPECTED_RECORD:", 1157 }, 1158 { 1159 testType: serverTest, 1160 name: "FragmentAcrossChangeCipherSpec-Server", 1161 config: Config{ 1162 Bugs: ProtocolBugs{ 1163 FragmentAcrossChangeCipherSpec: true, 1164 }, 1165 }, 1166 shouldFail: true, 1167 expectedError: ":UNEXPECTED_RECORD:", 1168 }, 1169 { 1170 testType: serverTest, 1171 name: "FragmentAcrossChangeCipherSpec-Server-NPN", 1172 config: Config{ 1173 NextProtos: []string{"bar"}, 1174 Bugs: ProtocolBugs{ 1175 FragmentAcrossChangeCipherSpec: true, 1176 }, 1177 }, 1178 flags: []string{ 1179 "-advertise-npn", "\x03foo\x03bar\x03baz", 1180 }, 1181 shouldFail: true, 1182 expectedError: ":UNEXPECTED_RECORD:", 1183 }, 1184 { 1185 testType: serverTest, 1186 name: "Alert", 1187 config: Config{ 1188 Bugs: ProtocolBugs{ 1189 SendSpuriousAlert: alertRecordOverflow, 1190 }, 1191 }, 1192 shouldFail: true, 1193 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 1194 }, 1195 { 1196 protocol: dtls, 1197 testType: serverTest, 1198 name: "Alert-DTLS", 1199 config: Config{ 1200 Bugs: ProtocolBugs{ 1201 SendSpuriousAlert: alertRecordOverflow, 1202 }, 1203 }, 1204 shouldFail: true, 1205 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 1206 }, 1207 { 1208 testType: serverTest, 1209 name: "FragmentAlert", 1210 config: Config{ 1211 Bugs: ProtocolBugs{ 1212 FragmentAlert: true, 1213 SendSpuriousAlert: alertRecordOverflow, 1214 }, 1215 }, 1216 shouldFail: true, 1217 expectedError: ":BAD_ALERT:", 1218 }, 1219 { 1220 protocol: dtls, 1221 testType: serverTest, 1222 name: "FragmentAlert-DTLS", 1223 config: Config{ 1224 Bugs: ProtocolBugs{ 1225 FragmentAlert: true, 1226 SendSpuriousAlert: alertRecordOverflow, 1227 }, 1228 }, 1229 shouldFail: true, 1230 expectedError: ":BAD_ALERT:", 1231 }, 1232 { 1233 testType: serverTest, 1234 name: "DoubleAlert", 1235 config: Config{ 1236 Bugs: ProtocolBugs{ 1237 DoubleAlert: true, 1238 SendSpuriousAlert: alertRecordOverflow, 1239 }, 1240 }, 1241 shouldFail: true, 1242 expectedError: ":BAD_ALERT:", 1243 }, 1244 { 1245 protocol: dtls, 1246 testType: serverTest, 1247 name: "DoubleAlert-DTLS", 1248 config: Config{ 1249 Bugs: ProtocolBugs{ 1250 DoubleAlert: true, 1251 SendSpuriousAlert: alertRecordOverflow, 1252 }, 1253 }, 1254 shouldFail: true, 1255 expectedError: ":BAD_ALERT:", 1256 }, 1257 { 1258 testType: serverTest, 1259 name: "EarlyChangeCipherSpec-server-1", 1260 config: Config{ 1261 Bugs: ProtocolBugs{ 1262 EarlyChangeCipherSpec: 1, 1263 }, 1264 }, 1265 shouldFail: true, 1266 expectedError: ":UNEXPECTED_RECORD:", 1267 }, 1268 { 1269 testType: serverTest, 1270 name: "EarlyChangeCipherSpec-server-2", 1271 config: Config{ 1272 Bugs: ProtocolBugs{ 1273 EarlyChangeCipherSpec: 2, 1274 }, 1275 }, 1276 shouldFail: true, 1277 expectedError: ":UNEXPECTED_RECORD:", 1278 }, 1279 { 1280 name: "SkipNewSessionTicket", 1281 config: Config{ 1282 Bugs: ProtocolBugs{ 1283 SkipNewSessionTicket: true, 1284 }, 1285 }, 1286 shouldFail: true, 1287 expectedError: ":UNEXPECTED_RECORD:", 1288 }, 1289 { 1290 testType: serverTest, 1291 name: "FallbackSCSV", 1292 config: Config{ 1293 MaxVersion: VersionTLS11, 1294 Bugs: ProtocolBugs{ 1295 SendFallbackSCSV: true, 1296 }, 1297 }, 1298 shouldFail: true, 1299 expectedError: ":INAPPROPRIATE_FALLBACK:", 1300 }, 1301 { 1302 testType: serverTest, 1303 name: "FallbackSCSV-VersionMatch", 1304 config: Config{ 1305 Bugs: ProtocolBugs{ 1306 SendFallbackSCSV: true, 1307 }, 1308 }, 1309 }, 1310 { 1311 testType: serverTest, 1312 name: "FragmentedClientVersion", 1313 config: Config{ 1314 Bugs: ProtocolBugs{ 1315 MaxHandshakeRecordLength: 1, 1316 FragmentClientVersion: true, 1317 }, 1318 }, 1319 expectedVersion: VersionTLS12, 1320 }, 1321 { 1322 testType: serverTest, 1323 name: "MinorVersionTolerance", 1324 config: Config{ 1325 Bugs: ProtocolBugs{ 1326 SendClientVersion: 0x03ff, 1327 }, 1328 }, 1329 expectedVersion: VersionTLS12, 1330 }, 1331 { 1332 testType: serverTest, 1333 name: "MajorVersionTolerance", 1334 config: Config{ 1335 Bugs: ProtocolBugs{ 1336 SendClientVersion: 0x0400, 1337 }, 1338 }, 1339 expectedVersion: VersionTLS12, 1340 }, 1341 { 1342 testType: serverTest, 1343 name: "VersionTooLow", 1344 config: Config{ 1345 Bugs: ProtocolBugs{ 1346 SendClientVersion: 0x0200, 1347 }, 1348 }, 1349 shouldFail: true, 1350 expectedError: ":UNSUPPORTED_PROTOCOL:", 1351 }, 1352 { 1353 testType: serverTest, 1354 name: "HttpGET", 1355 sendPrefix: "GET / HTTP/1.0\n", 1356 shouldFail: true, 1357 expectedError: ":HTTP_REQUEST:", 1358 }, 1359 { 1360 testType: serverTest, 1361 name: "HttpPOST", 1362 sendPrefix: "POST / HTTP/1.0\n", 1363 shouldFail: true, 1364 expectedError: ":HTTP_REQUEST:", 1365 }, 1366 { 1367 testType: serverTest, 1368 name: "HttpHEAD", 1369 sendPrefix: "HEAD / HTTP/1.0\n", 1370 shouldFail: true, 1371 expectedError: ":HTTP_REQUEST:", 1372 }, 1373 { 1374 testType: serverTest, 1375 name: "HttpPUT", 1376 sendPrefix: "PUT / HTTP/1.0\n", 1377 shouldFail: true, 1378 expectedError: ":HTTP_REQUEST:", 1379 }, 1380 { 1381 testType: serverTest, 1382 name: "HttpCONNECT", 1383 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n", 1384 shouldFail: true, 1385 expectedError: ":HTTPS_PROXY_REQUEST:", 1386 }, 1387 { 1388 testType: serverTest, 1389 name: "Garbage", 1390 sendPrefix: "blah", 1391 shouldFail: true, 1392 expectedError: ":WRONG_VERSION_NUMBER:", 1393 }, 1394 { 1395 name: "SkipCipherVersionCheck", 1396 config: Config{ 1397 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 1398 MaxVersion: VersionTLS11, 1399 Bugs: ProtocolBugs{ 1400 SkipCipherVersionCheck: true, 1401 }, 1402 }, 1403 shouldFail: true, 1404 expectedError: ":WRONG_CIPHER_RETURNED:", 1405 }, 1406 { 1407 name: "RSAEphemeralKey", 1408 config: Config{ 1409 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 1410 Bugs: ProtocolBugs{ 1411 RSAEphemeralKey: true, 1412 }, 1413 }, 1414 shouldFail: true, 1415 expectedError: ":UNEXPECTED_MESSAGE:", 1416 }, 1417 { 1418 name: "DisableEverything", 1419 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"}, 1420 shouldFail: true, 1421 expectedError: ":WRONG_SSL_VERSION:", 1422 }, 1423 { 1424 protocol: dtls, 1425 name: "DisableEverything-DTLS", 1426 flags: []string{"-no-tls12", "-no-tls1"}, 1427 shouldFail: true, 1428 expectedError: ":WRONG_SSL_VERSION:", 1429 }, 1430 { 1431 name: "NoSharedCipher", 1432 config: Config{ 1433 CipherSuites: []uint16{}, 1434 }, 1435 shouldFail: true, 1436 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 1437 }, 1438 { 1439 protocol: dtls, 1440 testType: serverTest, 1441 name: "MTU", 1442 config: Config{ 1443 Bugs: ProtocolBugs{ 1444 MaxPacketLength: 256, 1445 }, 1446 }, 1447 flags: []string{"-mtu", "256"}, 1448 }, 1449 { 1450 protocol: dtls, 1451 testType: serverTest, 1452 name: "MTUExceeded", 1453 config: Config{ 1454 Bugs: ProtocolBugs{ 1455 MaxPacketLength: 255, 1456 }, 1457 }, 1458 flags: []string{"-mtu", "256"}, 1459 shouldFail: true, 1460 expectedLocalError: "dtls: exceeded maximum packet length", 1461 }, 1462 { 1463 name: "CertMismatchRSA", 1464 config: Config{ 1465 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 1466 Certificates: []Certificate{getECDSACertificate()}, 1467 Bugs: ProtocolBugs{ 1468 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1469 }, 1470 }, 1471 shouldFail: true, 1472 expectedError: ":WRONG_CERTIFICATE_TYPE:", 1473 }, 1474 { 1475 name: "CertMismatchECDSA", 1476 config: Config{ 1477 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1478 Certificates: []Certificate{getRSACertificate()}, 1479 Bugs: ProtocolBugs{ 1480 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 1481 }, 1482 }, 1483 shouldFail: true, 1484 expectedError: ":WRONG_CERTIFICATE_TYPE:", 1485 }, 1486 { 1487 name: "EmptyCertificateList", 1488 config: Config{ 1489 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1490 Bugs: ProtocolBugs{ 1491 EmptyCertificateList: true, 1492 }, 1493 }, 1494 shouldFail: true, 1495 expectedError: ":DECODE_ERROR:", 1496 }, 1497 { 1498 name: "TLSFatalBadPackets", 1499 damageFirstWrite: true, 1500 shouldFail: true, 1501 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 1502 }, 1503 { 1504 protocol: dtls, 1505 name: "DTLSIgnoreBadPackets", 1506 damageFirstWrite: true, 1507 }, 1508 { 1509 protocol: dtls, 1510 name: "DTLSIgnoreBadPackets-Async", 1511 damageFirstWrite: true, 1512 flags: []string{"-async"}, 1513 }, 1514 { 1515 name: "AppDataBeforeHandshake", 1516 config: Config{ 1517 Bugs: ProtocolBugs{ 1518 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 1519 }, 1520 }, 1521 shouldFail: true, 1522 expectedError: ":UNEXPECTED_RECORD:", 1523 }, 1524 { 1525 name: "AppDataBeforeHandshake-Empty", 1526 config: Config{ 1527 Bugs: ProtocolBugs{ 1528 AppDataBeforeHandshake: []byte{}, 1529 }, 1530 }, 1531 shouldFail: true, 1532 expectedError: ":UNEXPECTED_RECORD:", 1533 }, 1534 { 1535 protocol: dtls, 1536 name: "AppDataBeforeHandshake-DTLS", 1537 config: Config{ 1538 Bugs: ProtocolBugs{ 1539 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 1540 }, 1541 }, 1542 shouldFail: true, 1543 expectedError: ":UNEXPECTED_RECORD:", 1544 }, 1545 { 1546 protocol: dtls, 1547 name: "AppDataBeforeHandshake-DTLS-Empty", 1548 config: Config{ 1549 Bugs: ProtocolBugs{ 1550 AppDataBeforeHandshake: []byte{}, 1551 }, 1552 }, 1553 shouldFail: true, 1554 expectedError: ":UNEXPECTED_RECORD:", 1555 }, 1556 { 1557 name: "AppDataAfterChangeCipherSpec", 1558 config: Config{ 1559 Bugs: ProtocolBugs{ 1560 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 1561 }, 1562 }, 1563 shouldFail: true, 1564 expectedError: ":UNEXPECTED_RECORD:", 1565 }, 1566 { 1567 name: "AppDataAfterChangeCipherSpec-Empty", 1568 config: Config{ 1569 Bugs: ProtocolBugs{ 1570 AppDataAfterChangeCipherSpec: []byte{}, 1571 }, 1572 }, 1573 shouldFail: true, 1574 expectedError: ":UNEXPECTED_RECORD:", 1575 }, 1576 { 1577 protocol: dtls, 1578 name: "AppDataAfterChangeCipherSpec-DTLS", 1579 config: Config{ 1580 Bugs: ProtocolBugs{ 1581 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 1582 }, 1583 }, 1584 // BoringSSL's DTLS implementation will drop the out-of-order 1585 // application data. 1586 }, 1587 { 1588 protocol: dtls, 1589 name: "AppDataAfterChangeCipherSpec-DTLS-Empty", 1590 config: Config{ 1591 Bugs: ProtocolBugs{ 1592 AppDataAfterChangeCipherSpec: []byte{}, 1593 }, 1594 }, 1595 // BoringSSL's DTLS implementation will drop the out-of-order 1596 // application data. 1597 }, 1598 { 1599 name: "AlertAfterChangeCipherSpec", 1600 config: Config{ 1601 Bugs: ProtocolBugs{ 1602 AlertAfterChangeCipherSpec: alertRecordOverflow, 1603 }, 1604 }, 1605 shouldFail: true, 1606 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 1607 }, 1608 { 1609 protocol: dtls, 1610 name: "AlertAfterChangeCipherSpec-DTLS", 1611 config: Config{ 1612 Bugs: ProtocolBugs{ 1613 AlertAfterChangeCipherSpec: alertRecordOverflow, 1614 }, 1615 }, 1616 shouldFail: true, 1617 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 1618 }, 1619 { 1620 protocol: dtls, 1621 name: "ReorderHandshakeFragments-Small-DTLS", 1622 config: Config{ 1623 Bugs: ProtocolBugs{ 1624 ReorderHandshakeFragments: true, 1625 // Small enough that every handshake message is 1626 // fragmented. 1627 MaxHandshakeRecordLength: 2, 1628 }, 1629 }, 1630 }, 1631 { 1632 protocol: dtls, 1633 name: "ReorderHandshakeFragments-Large-DTLS", 1634 config: Config{ 1635 Bugs: ProtocolBugs{ 1636 ReorderHandshakeFragments: true, 1637 // Large enough that no handshake message is 1638 // fragmented. 1639 MaxHandshakeRecordLength: 2048, 1640 }, 1641 }, 1642 }, 1643 { 1644 protocol: dtls, 1645 name: "MixCompleteMessageWithFragments-DTLS", 1646 config: Config{ 1647 Bugs: ProtocolBugs{ 1648 ReorderHandshakeFragments: true, 1649 MixCompleteMessageWithFragments: true, 1650 MaxHandshakeRecordLength: 2, 1651 }, 1652 }, 1653 }, 1654 { 1655 name: "SendInvalidRecordType", 1656 config: Config{ 1657 Bugs: ProtocolBugs{ 1658 SendInvalidRecordType: true, 1659 }, 1660 }, 1661 shouldFail: true, 1662 expectedError: ":UNEXPECTED_RECORD:", 1663 }, 1664 { 1665 protocol: dtls, 1666 name: "SendInvalidRecordType-DTLS", 1667 config: Config{ 1668 Bugs: ProtocolBugs{ 1669 SendInvalidRecordType: true, 1670 }, 1671 }, 1672 shouldFail: true, 1673 expectedError: ":UNEXPECTED_RECORD:", 1674 }, 1675 { 1676 name: "FalseStart-SkipServerSecondLeg", 1677 config: Config{ 1678 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1679 NextProtos: []string{"foo"}, 1680 Bugs: ProtocolBugs{ 1681 SkipNewSessionTicket: true, 1682 SkipChangeCipherSpec: true, 1683 SkipFinished: true, 1684 ExpectFalseStart: true, 1685 }, 1686 }, 1687 flags: []string{ 1688 "-false-start", 1689 "-handshake-never-done", 1690 "-advertise-alpn", "\x03foo", 1691 }, 1692 shimWritesFirst: true, 1693 shouldFail: true, 1694 expectedError: ":UNEXPECTED_RECORD:", 1695 }, 1696 { 1697 name: "FalseStart-SkipServerSecondLeg-Implicit", 1698 config: Config{ 1699 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1700 NextProtos: []string{"foo"}, 1701 Bugs: ProtocolBugs{ 1702 SkipNewSessionTicket: true, 1703 SkipChangeCipherSpec: true, 1704 SkipFinished: true, 1705 }, 1706 }, 1707 flags: []string{ 1708 "-implicit-handshake", 1709 "-false-start", 1710 "-handshake-never-done", 1711 "-advertise-alpn", "\x03foo", 1712 }, 1713 shouldFail: true, 1714 expectedError: ":UNEXPECTED_RECORD:", 1715 }, 1716 { 1717 testType: serverTest, 1718 name: "FailEarlyCallback", 1719 flags: []string{"-fail-early-callback"}, 1720 shouldFail: true, 1721 expectedError: ":CONNECTION_REJECTED:", 1722 expectedLocalError: "remote error: access denied", 1723 }, 1724 { 1725 name: "WrongMessageType", 1726 config: Config{ 1727 Bugs: ProtocolBugs{ 1728 WrongCertificateMessageType: true, 1729 }, 1730 }, 1731 shouldFail: true, 1732 expectedError: ":UNEXPECTED_MESSAGE:", 1733 expectedLocalError: "remote error: unexpected message", 1734 }, 1735 { 1736 protocol: dtls, 1737 name: "WrongMessageType-DTLS", 1738 config: Config{ 1739 Bugs: ProtocolBugs{ 1740 WrongCertificateMessageType: true, 1741 }, 1742 }, 1743 shouldFail: true, 1744 expectedError: ":UNEXPECTED_MESSAGE:", 1745 expectedLocalError: "remote error: unexpected message", 1746 }, 1747 { 1748 protocol: dtls, 1749 name: "FragmentMessageTypeMismatch-DTLS", 1750 config: Config{ 1751 Bugs: ProtocolBugs{ 1752 MaxHandshakeRecordLength: 2, 1753 FragmentMessageTypeMismatch: true, 1754 }, 1755 }, 1756 shouldFail: true, 1757 expectedError: ":FRAGMENT_MISMATCH:", 1758 }, 1759 { 1760 protocol: dtls, 1761 name: "FragmentMessageLengthMismatch-DTLS", 1762 config: Config{ 1763 Bugs: ProtocolBugs{ 1764 MaxHandshakeRecordLength: 2, 1765 FragmentMessageLengthMismatch: true, 1766 }, 1767 }, 1768 shouldFail: true, 1769 expectedError: ":FRAGMENT_MISMATCH:", 1770 }, 1771 { 1772 protocol: dtls, 1773 name: "SplitFragments-Header-DTLS", 1774 config: Config{ 1775 Bugs: ProtocolBugs{ 1776 SplitFragments: 2, 1777 }, 1778 }, 1779 shouldFail: true, 1780 expectedError: ":BAD_HANDSHAKE_RECORD:", 1781 }, 1782 { 1783 protocol: dtls, 1784 name: "SplitFragments-Boundary-DTLS", 1785 config: Config{ 1786 Bugs: ProtocolBugs{ 1787 SplitFragments: dtlsRecordHeaderLen, 1788 }, 1789 }, 1790 shouldFail: true, 1791 expectedError: ":BAD_HANDSHAKE_RECORD:", 1792 }, 1793 { 1794 protocol: dtls, 1795 name: "SplitFragments-Body-DTLS", 1796 config: Config{ 1797 Bugs: ProtocolBugs{ 1798 SplitFragments: dtlsRecordHeaderLen + 1, 1799 }, 1800 }, 1801 shouldFail: true, 1802 expectedError: ":BAD_HANDSHAKE_RECORD:", 1803 }, 1804 { 1805 protocol: dtls, 1806 name: "SendEmptyFragments-DTLS", 1807 config: Config{ 1808 Bugs: ProtocolBugs{ 1809 SendEmptyFragments: true, 1810 }, 1811 }, 1812 }, 1813 { 1814 name: "UnsupportedCipherSuite", 1815 config: Config{ 1816 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 1817 Bugs: ProtocolBugs{ 1818 IgnorePeerCipherPreferences: true, 1819 }, 1820 }, 1821 flags: []string{"-cipher", "DEFAULT:!RC4"}, 1822 shouldFail: true, 1823 expectedError: ":WRONG_CIPHER_RETURNED:", 1824 }, 1825 { 1826 name: "UnsupportedCurve", 1827 config: Config{ 1828 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1829 CurvePreferences: []CurveID{CurveP256}, 1830 Bugs: ProtocolBugs{ 1831 IgnorePeerCurvePreferences: true, 1832 }, 1833 }, 1834 flags: []string{"-p384-only"}, 1835 shouldFail: true, 1836 expectedError: ":WRONG_CURVE:", 1837 }, 1838 { 1839 name: "BadFinished-Client", 1840 config: Config{ 1841 Bugs: ProtocolBugs{ 1842 BadFinished: true, 1843 }, 1844 }, 1845 shouldFail: true, 1846 expectedError: ":DIGEST_CHECK_FAILED:", 1847 }, 1848 { 1849 testType: serverTest, 1850 name: "BadFinished-Server", 1851 config: Config{ 1852 Bugs: ProtocolBugs{ 1853 BadFinished: true, 1854 }, 1855 }, 1856 shouldFail: true, 1857 expectedError: ":DIGEST_CHECK_FAILED:", 1858 }, 1859 { 1860 name: "FalseStart-BadFinished", 1861 config: Config{ 1862 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1863 NextProtos: []string{"foo"}, 1864 Bugs: ProtocolBugs{ 1865 BadFinished: true, 1866 ExpectFalseStart: true, 1867 }, 1868 }, 1869 flags: []string{ 1870 "-false-start", 1871 "-handshake-never-done", 1872 "-advertise-alpn", "\x03foo", 1873 }, 1874 shimWritesFirst: true, 1875 shouldFail: true, 1876 expectedError: ":DIGEST_CHECK_FAILED:", 1877 }, 1878 { 1879 name: "NoFalseStart-NoALPN", 1880 config: Config{ 1881 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1882 Bugs: ProtocolBugs{ 1883 ExpectFalseStart: true, 1884 AlertBeforeFalseStartTest: alertAccessDenied, 1885 }, 1886 }, 1887 flags: []string{ 1888 "-false-start", 1889 }, 1890 shimWritesFirst: true, 1891 shouldFail: true, 1892 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 1893 expectedLocalError: "tls: peer did not false start: EOF", 1894 }, 1895 { 1896 name: "NoFalseStart-NoAEAD", 1897 config: Config{ 1898 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 1899 NextProtos: []string{"foo"}, 1900 Bugs: ProtocolBugs{ 1901 ExpectFalseStart: true, 1902 AlertBeforeFalseStartTest: alertAccessDenied, 1903 }, 1904 }, 1905 flags: []string{ 1906 "-false-start", 1907 "-advertise-alpn", "\x03foo", 1908 }, 1909 shimWritesFirst: true, 1910 shouldFail: true, 1911 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 1912 expectedLocalError: "tls: peer did not false start: EOF", 1913 }, 1914 { 1915 name: "NoFalseStart-RSA", 1916 config: Config{ 1917 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 1918 NextProtos: []string{"foo"}, 1919 Bugs: ProtocolBugs{ 1920 ExpectFalseStart: true, 1921 AlertBeforeFalseStartTest: alertAccessDenied, 1922 }, 1923 }, 1924 flags: []string{ 1925 "-false-start", 1926 "-advertise-alpn", "\x03foo", 1927 }, 1928 shimWritesFirst: true, 1929 shouldFail: true, 1930 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 1931 expectedLocalError: "tls: peer did not false start: EOF", 1932 }, 1933 { 1934 name: "NoFalseStart-DHE_RSA", 1935 config: Config{ 1936 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 1937 NextProtos: []string{"foo"}, 1938 Bugs: ProtocolBugs{ 1939 ExpectFalseStart: true, 1940 AlertBeforeFalseStartTest: alertAccessDenied, 1941 }, 1942 }, 1943 flags: []string{ 1944 "-false-start", 1945 "-advertise-alpn", "\x03foo", 1946 }, 1947 shimWritesFirst: true, 1948 shouldFail: true, 1949 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 1950 expectedLocalError: "tls: peer did not false start: EOF", 1951 }, 1952 { 1953 testType: serverTest, 1954 name: "NoSupportedCurves", 1955 config: Config{ 1956 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1957 Bugs: ProtocolBugs{ 1958 NoSupportedCurves: true, 1959 }, 1960 }, 1961 shouldFail: true, 1962 expectedError: ":NO_SHARED_CIPHER:", 1963 }, 1964 { 1965 testType: serverTest, 1966 name: "NoCommonCurves", 1967 config: Config{ 1968 CipherSuites: []uint16{ 1969 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1970 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 1971 }, 1972 CurvePreferences: []CurveID{CurveP224}, 1973 }, 1974 expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 1975 }, 1976 { 1977 protocol: dtls, 1978 name: "SendSplitAlert-Sync", 1979 config: Config{ 1980 Bugs: ProtocolBugs{ 1981 SendSplitAlert: true, 1982 }, 1983 }, 1984 }, 1985 { 1986 protocol: dtls, 1987 name: "SendSplitAlert-Async", 1988 config: Config{ 1989 Bugs: ProtocolBugs{ 1990 SendSplitAlert: true, 1991 }, 1992 }, 1993 flags: []string{"-async"}, 1994 }, 1995 { 1996 protocol: dtls, 1997 name: "PackDTLSHandshake", 1998 config: Config{ 1999 Bugs: ProtocolBugs{ 2000 MaxHandshakeRecordLength: 2, 2001 PackHandshakeFragments: 20, 2002 PackHandshakeRecords: 200, 2003 }, 2004 }, 2005 }, 2006 { 2007 testType: serverTest, 2008 protocol: dtls, 2009 name: "NoRC4-DTLS", 2010 config: Config{ 2011 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}, 2012 Bugs: ProtocolBugs{ 2013 EnableAllCiphersInDTLS: true, 2014 }, 2015 }, 2016 shouldFail: true, 2017 expectedError: ":NO_SHARED_CIPHER:", 2018 }, 2019 { 2020 name: "SendEmptyRecords-Pass", 2021 sendEmptyRecords: 32, 2022 }, 2023 { 2024 name: "SendEmptyRecords", 2025 sendEmptyRecords: 33, 2026 shouldFail: true, 2027 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2028 }, 2029 { 2030 name: "SendEmptyRecords-Async", 2031 sendEmptyRecords: 33, 2032 flags: []string{"-async"}, 2033 shouldFail: true, 2034 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2035 }, 2036 { 2037 name: "SendWarningAlerts-Pass", 2038 sendWarningAlerts: 4, 2039 }, 2040 { 2041 protocol: dtls, 2042 name: "SendWarningAlerts-DTLS-Pass", 2043 sendWarningAlerts: 4, 2044 }, 2045 { 2046 name: "SendWarningAlerts", 2047 sendWarningAlerts: 5, 2048 shouldFail: true, 2049 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2050 }, 2051 { 2052 name: "SendWarningAlerts-Async", 2053 sendWarningAlerts: 5, 2054 flags: []string{"-async"}, 2055 shouldFail: true, 2056 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2057 }, 2058 { 2059 name: "EmptySessionID", 2060 config: Config{ 2061 SessionTicketsDisabled: true, 2062 }, 2063 noSessionCache: true, 2064 flags: []string{"-expect-no-session"}, 2065 }, 2066 { 2067 name: "Unclean-Shutdown", 2068 config: Config{ 2069 Bugs: ProtocolBugs{ 2070 NoCloseNotify: true, 2071 ExpectCloseNotify: true, 2072 }, 2073 }, 2074 shimShutsDown: true, 2075 flags: []string{"-check-close-notify"}, 2076 shouldFail: true, 2077 expectedError: "Unexpected SSL_shutdown result: -1 != 1", 2078 }, 2079 { 2080 name: "Unclean-Shutdown-Ignored", 2081 config: Config{ 2082 Bugs: ProtocolBugs{ 2083 NoCloseNotify: true, 2084 }, 2085 }, 2086 shimShutsDown: true, 2087 }, 2088 { 2089 name: "Unclean-Shutdown-Alert", 2090 config: Config{ 2091 Bugs: ProtocolBugs{ 2092 SendAlertOnShutdown: alertDecompressionFailure, 2093 ExpectCloseNotify: true, 2094 }, 2095 }, 2096 shimShutsDown: true, 2097 flags: []string{"-check-close-notify"}, 2098 shouldFail: true, 2099 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:", 2100 }, 2101 { 2102 name: "LargePlaintext", 2103 config: Config{ 2104 Bugs: ProtocolBugs{ 2105 SendLargeRecords: true, 2106 }, 2107 }, 2108 messageLen: maxPlaintext + 1, 2109 shouldFail: true, 2110 expectedError: ":DATA_LENGTH_TOO_LONG:", 2111 }, 2112 { 2113 protocol: dtls, 2114 name: "LargePlaintext-DTLS", 2115 config: Config{ 2116 Bugs: ProtocolBugs{ 2117 SendLargeRecords: true, 2118 }, 2119 }, 2120 messageLen: maxPlaintext + 1, 2121 shouldFail: true, 2122 expectedError: ":DATA_LENGTH_TOO_LONG:", 2123 }, 2124 { 2125 name: "LargeCiphertext", 2126 config: Config{ 2127 Bugs: ProtocolBugs{ 2128 SendLargeRecords: true, 2129 }, 2130 }, 2131 messageLen: maxPlaintext * 2, 2132 shouldFail: true, 2133 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:", 2134 }, 2135 { 2136 protocol: dtls, 2137 name: "LargeCiphertext-DTLS", 2138 config: Config{ 2139 Bugs: ProtocolBugs{ 2140 SendLargeRecords: true, 2141 }, 2142 }, 2143 messageLen: maxPlaintext * 2, 2144 // Unlike the other four cases, DTLS drops records which 2145 // are invalid before authentication, so the connection 2146 // does not fail. 2147 expectMessageDropped: true, 2148 }, 2149 { 2150 name: "SendEmptySessionTicket", 2151 config: Config{ 2152 Bugs: ProtocolBugs{ 2153 SendEmptySessionTicket: true, 2154 FailIfSessionOffered: true, 2155 }, 2156 }, 2157 flags: []string{"-expect-no-session"}, 2158 resumeSession: true, 2159 expectResumeRejected: true, 2160 }, 2161 { 2162 name: "CheckLeafCurve", 2163 config: Config{ 2164 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 2165 Certificates: []Certificate{getECDSACertificate()}, 2166 }, 2167 flags: []string{"-p384-only"}, 2168 shouldFail: true, 2169 expectedError: ":BAD_ECC_CERT:", 2170 }, 2171 { 2172 name: "BadChangeCipherSpec-1", 2173 config: Config{ 2174 Bugs: ProtocolBugs{ 2175 BadChangeCipherSpec: []byte{2}, 2176 }, 2177 }, 2178 shouldFail: true, 2179 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 2180 }, 2181 { 2182 name: "BadChangeCipherSpec-2", 2183 config: Config{ 2184 Bugs: ProtocolBugs{ 2185 BadChangeCipherSpec: []byte{1, 1}, 2186 }, 2187 }, 2188 shouldFail: true, 2189 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 2190 }, 2191 { 2192 protocol: dtls, 2193 name: "BadChangeCipherSpec-DTLS-1", 2194 config: Config{ 2195 Bugs: ProtocolBugs{ 2196 BadChangeCipherSpec: []byte{2}, 2197 }, 2198 }, 2199 shouldFail: true, 2200 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 2201 }, 2202 { 2203 protocol: dtls, 2204 name: "BadChangeCipherSpec-DTLS-2", 2205 config: Config{ 2206 Bugs: ProtocolBugs{ 2207 BadChangeCipherSpec: []byte{1, 1}, 2208 }, 2209 }, 2210 shouldFail: true, 2211 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 2212 }, 2213 { 2214 name: "BadHelloRequest-1", 2215 renegotiate: 1, 2216 config: Config{ 2217 Bugs: ProtocolBugs{ 2218 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1}, 2219 }, 2220 }, 2221 flags: []string{ 2222 "-renegotiate-freely", 2223 "-expect-total-renegotiations", "1", 2224 }, 2225 shouldFail: true, 2226 expectedError: ":BAD_HELLO_REQUEST:", 2227 }, 2228 { 2229 name: "BadHelloRequest-2", 2230 renegotiate: 1, 2231 config: Config{ 2232 Bugs: ProtocolBugs{ 2233 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0}, 2234 }, 2235 }, 2236 flags: []string{ 2237 "-renegotiate-freely", 2238 "-expect-total-renegotiations", "1", 2239 }, 2240 shouldFail: true, 2241 expectedError: ":BAD_HELLO_REQUEST:", 2242 }, 2243 { 2244 testType: serverTest, 2245 name: "SupportTicketsWithSessionID", 2246 config: Config{ 2247 SessionTicketsDisabled: true, 2248 }, 2249 resumeConfig: &Config{}, 2250 resumeSession: true, 2251 }, 2252 { 2253 name: "InvalidECDHPoint-Client", 2254 config: Config{ 2255 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2256 CurvePreferences: []CurveID{CurveP256}, 2257 Bugs: ProtocolBugs{ 2258 InvalidECDHPoint: true, 2259 }, 2260 }, 2261 shouldFail: true, 2262 expectedError: ":INVALID_ENCODING:", 2263 }, 2264 { 2265 testType: serverTest, 2266 name: "InvalidECDHPoint-Server", 2267 config: Config{ 2268 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2269 CurvePreferences: []CurveID{CurveP256}, 2270 Bugs: ProtocolBugs{ 2271 InvalidECDHPoint: true, 2272 }, 2273 }, 2274 shouldFail: true, 2275 expectedError: ":INVALID_ENCODING:", 2276 }, 2277 } 2278 testCases = append(testCases, basicTests...) 2279} 2280 2281func addCipherSuiteTests() { 2282 for _, suite := range testCipherSuites { 2283 const psk = "12345" 2284 const pskIdentity = "luggage combo" 2285 2286 var cert Certificate 2287 var certFile string 2288 var keyFile string 2289 if hasComponent(suite.name, "ECDSA") { 2290 cert = getECDSACertificate() 2291 certFile = ecdsaCertificateFile 2292 keyFile = ecdsaKeyFile 2293 } else { 2294 cert = getRSACertificate() 2295 certFile = rsaCertificateFile 2296 keyFile = rsaKeyFile 2297 } 2298 2299 var flags []string 2300 if hasComponent(suite.name, "PSK") { 2301 flags = append(flags, 2302 "-psk", psk, 2303 "-psk-identity", pskIdentity) 2304 } 2305 if hasComponent(suite.name, "NULL") { 2306 // NULL ciphers must be explicitly enabled. 2307 flags = append(flags, "-cipher", "DEFAULT:NULL-SHA") 2308 } 2309 if hasComponent(suite.name, "CECPQ1") { 2310 // CECPQ1 ciphers must be explicitly enabled. 2311 flags = append(flags, "-cipher", "DEFAULT:kCECPQ1") 2312 } 2313 2314 for _, ver := range tlsVersions { 2315 if ver.version < VersionTLS12 && isTLS12Only(suite.name) { 2316 continue 2317 } 2318 2319 shouldFail := isTLSOnly(suite.name) && ver.version == VersionSSL30 2320 2321 expectedError := "" 2322 if shouldFail { 2323 expectedError = ":NO_SHARED_CIPHER:" 2324 } 2325 2326 testCases = append(testCases, testCase{ 2327 testType: serverTest, 2328 name: ver.name + "-" + suite.name + "-server", 2329 config: Config{ 2330 MinVersion: ver.version, 2331 MaxVersion: ver.version, 2332 CipherSuites: []uint16{suite.id}, 2333 Certificates: []Certificate{cert}, 2334 PreSharedKey: []byte(psk), 2335 PreSharedKeyIdentity: pskIdentity, 2336 }, 2337 certFile: certFile, 2338 keyFile: keyFile, 2339 flags: flags, 2340 resumeSession: true, 2341 shouldFail: shouldFail, 2342 expectedError: expectedError, 2343 }) 2344 2345 if shouldFail { 2346 continue 2347 } 2348 2349 testCases = append(testCases, testCase{ 2350 testType: clientTest, 2351 name: ver.name + "-" + suite.name + "-client", 2352 config: Config{ 2353 MinVersion: ver.version, 2354 MaxVersion: ver.version, 2355 CipherSuites: []uint16{suite.id}, 2356 Certificates: []Certificate{cert}, 2357 PreSharedKey: []byte(psk), 2358 PreSharedKeyIdentity: pskIdentity, 2359 }, 2360 flags: flags, 2361 resumeSession: true, 2362 }) 2363 2364 if ver.hasDTLS && isDTLSCipher(suite.name) { 2365 testCases = append(testCases, testCase{ 2366 testType: clientTest, 2367 protocol: dtls, 2368 name: "D" + ver.name + "-" + suite.name + "-client", 2369 config: Config{ 2370 MinVersion: ver.version, 2371 MaxVersion: ver.version, 2372 CipherSuites: []uint16{suite.id}, 2373 Certificates: []Certificate{cert}, 2374 PreSharedKey: []byte(psk), 2375 PreSharedKeyIdentity: pskIdentity, 2376 }, 2377 flags: flags, 2378 resumeSession: true, 2379 }) 2380 testCases = append(testCases, testCase{ 2381 testType: serverTest, 2382 protocol: dtls, 2383 name: "D" + ver.name + "-" + suite.name + "-server", 2384 config: Config{ 2385 MinVersion: ver.version, 2386 MaxVersion: ver.version, 2387 CipherSuites: []uint16{suite.id}, 2388 Certificates: []Certificate{cert}, 2389 PreSharedKey: []byte(psk), 2390 PreSharedKeyIdentity: pskIdentity, 2391 }, 2392 certFile: certFile, 2393 keyFile: keyFile, 2394 flags: flags, 2395 resumeSession: true, 2396 }) 2397 } 2398 } 2399 2400 // Ensure both TLS and DTLS accept their maximum record sizes. 2401 testCases = append(testCases, testCase{ 2402 name: suite.name + "-LargeRecord", 2403 config: Config{ 2404 CipherSuites: []uint16{suite.id}, 2405 Certificates: []Certificate{cert}, 2406 PreSharedKey: []byte(psk), 2407 PreSharedKeyIdentity: pskIdentity, 2408 }, 2409 flags: flags, 2410 messageLen: maxPlaintext, 2411 }) 2412 if isDTLSCipher(suite.name) { 2413 testCases = append(testCases, testCase{ 2414 protocol: dtls, 2415 name: suite.name + "-LargeRecord-DTLS", 2416 config: Config{ 2417 CipherSuites: []uint16{suite.id}, 2418 Certificates: []Certificate{cert}, 2419 PreSharedKey: []byte(psk), 2420 PreSharedKeyIdentity: pskIdentity, 2421 }, 2422 flags: flags, 2423 messageLen: maxPlaintext, 2424 }) 2425 } 2426 } 2427 2428 testCases = append(testCases, testCase{ 2429 name: "WeakDH", 2430 config: Config{ 2431 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 2432 Bugs: ProtocolBugs{ 2433 // This is a 1023-bit prime number, generated 2434 // with: 2435 // openssl gendh 1023 | openssl asn1parse -i 2436 DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"), 2437 }, 2438 }, 2439 shouldFail: true, 2440 expectedError: ":BAD_DH_P_LENGTH:", 2441 }) 2442 2443 testCases = append(testCases, testCase{ 2444 name: "SillyDH", 2445 config: Config{ 2446 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 2447 Bugs: ProtocolBugs{ 2448 // This is a 4097-bit prime number, generated 2449 // with: 2450 // openssl gendh 4097 | openssl asn1parse -i 2451 DHGroupPrime: bigFromHex("01D366FA64A47419B0CD4A45918E8D8C8430F674621956A9F52B0CA592BC104C6E38D60C58F2CA66792A2B7EBDC6F8FFE75AB7D6862C261F34E96A2AEEF53AB7C21365C2E8FB0582F71EB57B1C227C0E55AE859E9904A25EFECD7B435C4D4357BD840B03649D4A1F8037D89EA4E1967DBEEF1CC17A6111C48F12E9615FFF336D3F07064CB17C0B765A012C850B9E3AA7A6984B96D8C867DDC6D0F4AB52042572244796B7ECFF681CD3B3E2E29AAECA391A775BEE94E502FB15881B0F4AC60314EA947C0C82541C3D16FD8C0E09BB7F8F786582032859D9C13187CE6C0CB6F2D3EE6C3C9727C15F14B21D3CD2E02BDB9D119959B0E03DC9E5A91E2578762300B1517D2352FC1D0BB934A4C3E1B20CE9327DB102E89A6C64A8C3148EDFC5A94913933853442FA84451B31FD21E492F92DD5488E0D871AEBFE335A4B92431DEC69591548010E76A5B365D346786E9A2D3E589867D796AA5E25211201D757560D318A87DFB27F3E625BC373DB48BF94A63161C674C3D4265CB737418441B7650EABC209CF675A439BEB3E9D1AA1B79F67198A40CEFD1C89144F7D8BAF61D6AD36F466DA546B4174A0E0CAF5BD788C8243C7C2DDDCC3DB6FC89F12F17D19FBD9B0BC76FE92891CD6BA07BEA3B66EF12D0D85E788FD58675C1B0FBD16029DCC4D34E7A1A41471BDEDF78BF591A8B4E96D88BEC8EDC093E616292BFC096E69A916E8D624B"), 2452 }, 2453 }, 2454 shouldFail: true, 2455 expectedError: ":DH_P_TOO_LONG:", 2456 }) 2457 2458 // This test ensures that Diffie-Hellman public values are padded with 2459 // zeros so that they're the same length as the prime. This is to avoid 2460 // hitting a bug in yaSSL. 2461 testCases = append(testCases, testCase{ 2462 testType: serverTest, 2463 name: "DHPublicValuePadded", 2464 config: Config{ 2465 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 2466 Bugs: ProtocolBugs{ 2467 RequireDHPublicValueLen: (1025 + 7) / 8, 2468 }, 2469 }, 2470 flags: []string{"-use-sparse-dh-prime"}, 2471 }) 2472 2473 // The server must be tolerant to bogus ciphers. 2474 const bogusCipher = 0x1234 2475 testCases = append(testCases, testCase{ 2476 testType: serverTest, 2477 name: "UnknownCipher", 2478 config: Config{ 2479 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2480 }, 2481 }) 2482 2483 // versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS 2484 // 1.1 specific cipher suite settings. A server is setup with the given 2485 // cipher lists and then a connection is made for each member of 2486 // expectations. The cipher suite that the server selects must match 2487 // the specified one. 2488 var versionSpecificCiphersTest = []struct { 2489 ciphersDefault, ciphersTLS10, ciphersTLS11 string 2490 // expectations is a map from TLS version to cipher suite id. 2491 expectations map[uint16]uint16 2492 }{ 2493 { 2494 // Test that the null case (where no version-specific ciphers are set) 2495 // works as expected. 2496 "RC4-SHA:AES128-SHA", // default ciphers 2497 "", // no ciphers specifically for TLS ≥ 1.0 2498 "", // no ciphers specifically for TLS ≥ 1.1 2499 map[uint16]uint16{ 2500 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA, 2501 VersionTLS10: TLS_RSA_WITH_RC4_128_SHA, 2502 VersionTLS11: TLS_RSA_WITH_RC4_128_SHA, 2503 VersionTLS12: TLS_RSA_WITH_RC4_128_SHA, 2504 }, 2505 }, 2506 { 2507 // With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different 2508 // cipher. 2509 "RC4-SHA:AES128-SHA", // default 2510 "AES128-SHA", // these ciphers for TLS ≥ 1.0 2511 "", // no ciphers specifically for TLS ≥ 1.1 2512 map[uint16]uint16{ 2513 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA, 2514 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA, 2515 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA, 2516 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA, 2517 }, 2518 }, 2519 { 2520 // With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different 2521 // cipher. 2522 "RC4-SHA:AES128-SHA", // default 2523 "", // no ciphers specifically for TLS ≥ 1.0 2524 "AES128-SHA", // these ciphers for TLS ≥ 1.1 2525 map[uint16]uint16{ 2526 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA, 2527 VersionTLS10: TLS_RSA_WITH_RC4_128_SHA, 2528 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA, 2529 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA, 2530 }, 2531 }, 2532 { 2533 // With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should 2534 // mask ciphers_tls10 for TLS 1.1 and 1.2. 2535 "RC4-SHA:AES128-SHA", // default 2536 "AES128-SHA", // these ciphers for TLS ≥ 1.0 2537 "AES256-SHA", // these ciphers for TLS ≥ 1.1 2538 map[uint16]uint16{ 2539 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA, 2540 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA, 2541 VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA, 2542 VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA, 2543 }, 2544 }, 2545 } 2546 2547 for i, test := range versionSpecificCiphersTest { 2548 for version, expectedCipherSuite := range test.expectations { 2549 flags := []string{"-cipher", test.ciphersDefault} 2550 if len(test.ciphersTLS10) > 0 { 2551 flags = append(flags, "-cipher-tls10", test.ciphersTLS10) 2552 } 2553 if len(test.ciphersTLS11) > 0 { 2554 flags = append(flags, "-cipher-tls11", test.ciphersTLS11) 2555 } 2556 2557 testCases = append(testCases, testCase{ 2558 testType: serverTest, 2559 name: fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version), 2560 config: Config{ 2561 MaxVersion: version, 2562 MinVersion: version, 2563 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA}, 2564 }, 2565 flags: flags, 2566 expectedCipher: expectedCipherSuite, 2567 }) 2568 } 2569 } 2570} 2571 2572func addBadECDSASignatureTests() { 2573 for badR := BadValue(1); badR < NumBadValues; badR++ { 2574 for badS := BadValue(1); badS < NumBadValues; badS++ { 2575 testCases = append(testCases, testCase{ 2576 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS), 2577 config: Config{ 2578 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 2579 Certificates: []Certificate{getECDSACertificate()}, 2580 Bugs: ProtocolBugs{ 2581 BadECDSAR: badR, 2582 BadECDSAS: badS, 2583 }, 2584 }, 2585 shouldFail: true, 2586 expectedError: ":BAD_SIGNATURE:", 2587 }) 2588 } 2589 } 2590} 2591 2592func addCBCPaddingTests() { 2593 testCases = append(testCases, testCase{ 2594 name: "MaxCBCPadding", 2595 config: Config{ 2596 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2597 Bugs: ProtocolBugs{ 2598 MaxPadding: true, 2599 }, 2600 }, 2601 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 2602 }) 2603 testCases = append(testCases, testCase{ 2604 name: "BadCBCPadding", 2605 config: Config{ 2606 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2607 Bugs: ProtocolBugs{ 2608 PaddingFirstByteBad: true, 2609 }, 2610 }, 2611 shouldFail: true, 2612 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 2613 }) 2614 // OpenSSL previously had an issue where the first byte of padding in 2615 // 255 bytes of padding wasn't checked. 2616 testCases = append(testCases, testCase{ 2617 name: "BadCBCPadding255", 2618 config: Config{ 2619 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2620 Bugs: ProtocolBugs{ 2621 MaxPadding: true, 2622 PaddingFirstByteBadIf255: true, 2623 }, 2624 }, 2625 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 2626 shouldFail: true, 2627 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 2628 }) 2629} 2630 2631func addCBCSplittingTests() { 2632 testCases = append(testCases, testCase{ 2633 name: "CBCRecordSplitting", 2634 config: Config{ 2635 MaxVersion: VersionTLS10, 2636 MinVersion: VersionTLS10, 2637 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2638 }, 2639 messageLen: -1, // read until EOF 2640 resumeSession: true, 2641 flags: []string{ 2642 "-async", 2643 "-write-different-record-sizes", 2644 "-cbc-record-splitting", 2645 }, 2646 }) 2647 testCases = append(testCases, testCase{ 2648 name: "CBCRecordSplittingPartialWrite", 2649 config: Config{ 2650 MaxVersion: VersionTLS10, 2651 MinVersion: VersionTLS10, 2652 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2653 }, 2654 messageLen: -1, // read until EOF 2655 flags: []string{ 2656 "-async", 2657 "-write-different-record-sizes", 2658 "-cbc-record-splitting", 2659 "-partial-write", 2660 }, 2661 }) 2662} 2663 2664func addClientAuthTests() { 2665 // Add a dummy cert pool to stress certificate authority parsing. 2666 // TODO(davidben): Add tests that those values parse out correctly. 2667 certPool := x509.NewCertPool() 2668 cert, err := x509.ParseCertificate(rsaCertificate.Certificate[0]) 2669 if err != nil { 2670 panic(err) 2671 } 2672 certPool.AddCert(cert) 2673 2674 for _, ver := range tlsVersions { 2675 testCases = append(testCases, testCase{ 2676 testType: clientTest, 2677 name: ver.name + "-Client-ClientAuth-RSA", 2678 config: Config{ 2679 MinVersion: ver.version, 2680 MaxVersion: ver.version, 2681 ClientAuth: RequireAnyClientCert, 2682 ClientCAs: certPool, 2683 }, 2684 flags: []string{ 2685 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 2686 "-key-file", path.Join(*resourceDir, rsaKeyFile), 2687 }, 2688 }) 2689 testCases = append(testCases, testCase{ 2690 testType: serverTest, 2691 name: ver.name + "-Server-ClientAuth-RSA", 2692 config: Config{ 2693 MinVersion: ver.version, 2694 MaxVersion: ver.version, 2695 Certificates: []Certificate{rsaCertificate}, 2696 }, 2697 flags: []string{"-require-any-client-certificate"}, 2698 }) 2699 if ver.version != VersionSSL30 { 2700 testCases = append(testCases, testCase{ 2701 testType: serverTest, 2702 name: ver.name + "-Server-ClientAuth-ECDSA", 2703 config: Config{ 2704 MinVersion: ver.version, 2705 MaxVersion: ver.version, 2706 Certificates: []Certificate{ecdsaCertificate}, 2707 }, 2708 flags: []string{"-require-any-client-certificate"}, 2709 }) 2710 testCases = append(testCases, testCase{ 2711 testType: clientTest, 2712 name: ver.name + "-Client-ClientAuth-ECDSA", 2713 config: Config{ 2714 MinVersion: ver.version, 2715 MaxVersion: ver.version, 2716 ClientAuth: RequireAnyClientCert, 2717 ClientCAs: certPool, 2718 }, 2719 flags: []string{ 2720 "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile), 2721 "-key-file", path.Join(*resourceDir, ecdsaKeyFile), 2722 }, 2723 }) 2724 } 2725 } 2726 2727 testCases = append(testCases, testCase{ 2728 testType: serverTest, 2729 name: "RequireAnyClientCertificate", 2730 flags: []string{"-require-any-client-certificate"}, 2731 shouldFail: true, 2732 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 2733 }) 2734 2735 testCases = append(testCases, testCase{ 2736 testType: serverTest, 2737 name: "RequireAnyClientCertificate-SSL3", 2738 config: Config{ 2739 MaxVersion: VersionSSL30, 2740 }, 2741 flags: []string{"-require-any-client-certificate"}, 2742 shouldFail: true, 2743 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 2744 }) 2745 2746 testCases = append(testCases, testCase{ 2747 testType: serverTest, 2748 name: "SkipClientCertificate", 2749 config: Config{ 2750 Bugs: ProtocolBugs{ 2751 SkipClientCertificate: true, 2752 }, 2753 }, 2754 // Setting SSL_VERIFY_PEER allows anonymous clients. 2755 flags: []string{"-verify-peer"}, 2756 shouldFail: true, 2757 expectedError: ":UNEXPECTED_MESSAGE:", 2758 }) 2759 2760 // Client auth is only legal in certificate-based ciphers. 2761 testCases = append(testCases, testCase{ 2762 testType: clientTest, 2763 name: "ClientAuth-PSK", 2764 config: Config{ 2765 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 2766 PreSharedKey: []byte("secret"), 2767 ClientAuth: RequireAnyClientCert, 2768 }, 2769 flags: []string{ 2770 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 2771 "-key-file", path.Join(*resourceDir, rsaKeyFile), 2772 "-psk", "secret", 2773 }, 2774 shouldFail: true, 2775 expectedError: ":UNEXPECTED_MESSAGE:", 2776 }) 2777 testCases = append(testCases, testCase{ 2778 testType: clientTest, 2779 name: "ClientAuth-ECDHE_PSK", 2780 config: Config{ 2781 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 2782 PreSharedKey: []byte("secret"), 2783 ClientAuth: RequireAnyClientCert, 2784 }, 2785 flags: []string{ 2786 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 2787 "-key-file", path.Join(*resourceDir, rsaKeyFile), 2788 "-psk", "secret", 2789 }, 2790 shouldFail: true, 2791 expectedError: ":UNEXPECTED_MESSAGE:", 2792 }) 2793} 2794 2795func addExtendedMasterSecretTests() { 2796 const expectEMSFlag = "-expect-extended-master-secret" 2797 2798 for _, with := range []bool{false, true} { 2799 prefix := "No" 2800 var flags []string 2801 if with { 2802 prefix = "" 2803 flags = []string{expectEMSFlag} 2804 } 2805 2806 for _, isClient := range []bool{false, true} { 2807 suffix := "-Server" 2808 testType := serverTest 2809 if isClient { 2810 suffix = "-Client" 2811 testType = clientTest 2812 } 2813 2814 for _, ver := range tlsVersions { 2815 test := testCase{ 2816 testType: testType, 2817 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix, 2818 config: Config{ 2819 MinVersion: ver.version, 2820 MaxVersion: ver.version, 2821 Bugs: ProtocolBugs{ 2822 NoExtendedMasterSecret: !with, 2823 RequireExtendedMasterSecret: with, 2824 }, 2825 }, 2826 flags: flags, 2827 shouldFail: ver.version == VersionSSL30 && with, 2828 } 2829 if test.shouldFail { 2830 test.expectedLocalError = "extended master secret required but not supported by peer" 2831 } 2832 testCases = append(testCases, test) 2833 } 2834 } 2835 } 2836 2837 for _, isClient := range []bool{false, true} { 2838 for _, supportedInFirstConnection := range []bool{false, true} { 2839 for _, supportedInResumeConnection := range []bool{false, true} { 2840 boolToWord := func(b bool) string { 2841 if b { 2842 return "Yes" 2843 } 2844 return "No" 2845 } 2846 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-" 2847 if isClient { 2848 suffix += "Client" 2849 } else { 2850 suffix += "Server" 2851 } 2852 2853 supportedConfig := Config{ 2854 Bugs: ProtocolBugs{ 2855 RequireExtendedMasterSecret: true, 2856 }, 2857 } 2858 2859 noSupportConfig := Config{ 2860 Bugs: ProtocolBugs{ 2861 NoExtendedMasterSecret: true, 2862 }, 2863 } 2864 2865 test := testCase{ 2866 name: "ExtendedMasterSecret-" + suffix, 2867 resumeSession: true, 2868 } 2869 2870 if !isClient { 2871 test.testType = serverTest 2872 } 2873 2874 if supportedInFirstConnection { 2875 test.config = supportedConfig 2876 } else { 2877 test.config = noSupportConfig 2878 } 2879 2880 if supportedInResumeConnection { 2881 test.resumeConfig = &supportedConfig 2882 } else { 2883 test.resumeConfig = &noSupportConfig 2884 } 2885 2886 switch suffix { 2887 case "YesToYes-Client", "YesToYes-Server": 2888 // When a session is resumed, it should 2889 // still be aware that its master 2890 // secret was generated via EMS and 2891 // thus it's safe to use tls-unique. 2892 test.flags = []string{expectEMSFlag} 2893 case "NoToYes-Server": 2894 // If an original connection did not 2895 // contain EMS, but a resumption 2896 // handshake does, then a server should 2897 // not resume the session. 2898 test.expectResumeRejected = true 2899 case "YesToNo-Server": 2900 // Resuming an EMS session without the 2901 // EMS extension should cause the 2902 // server to abort the connection. 2903 test.shouldFail = true 2904 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 2905 case "NoToYes-Client": 2906 // A client should abort a connection 2907 // where the server resumed a non-EMS 2908 // session but echoed the EMS 2909 // extension. 2910 test.shouldFail = true 2911 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:" 2912 case "YesToNo-Client": 2913 // A client should abort a connection 2914 // where the server didn't echo EMS 2915 // when the session used it. 2916 test.shouldFail = true 2917 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 2918 } 2919 2920 testCases = append(testCases, test) 2921 } 2922 } 2923 } 2924} 2925 2926// Adds tests that try to cover the range of the handshake state machine, under 2927// various conditions. Some of these are redundant with other tests, but they 2928// only cover the synchronous case. 2929func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) { 2930 var tests []testCase 2931 2932 // Basic handshake, with resumption. Client and server, 2933 // session ID and session ticket. 2934 tests = append(tests, testCase{ 2935 name: "Basic-Client", 2936 resumeSession: true, 2937 // Ensure session tickets are used, not session IDs. 2938 noSessionCache: true, 2939 }) 2940 tests = append(tests, testCase{ 2941 name: "Basic-Client-RenewTicket", 2942 config: Config{ 2943 Bugs: ProtocolBugs{ 2944 RenewTicketOnResume: true, 2945 }, 2946 }, 2947 flags: []string{"-expect-ticket-renewal"}, 2948 resumeSession: true, 2949 }) 2950 tests = append(tests, testCase{ 2951 name: "Basic-Client-NoTicket", 2952 config: Config{ 2953 SessionTicketsDisabled: true, 2954 }, 2955 resumeSession: true, 2956 }) 2957 tests = append(tests, testCase{ 2958 name: "Basic-Client-Implicit", 2959 flags: []string{"-implicit-handshake"}, 2960 resumeSession: true, 2961 }) 2962 tests = append(tests, testCase{ 2963 testType: serverTest, 2964 name: "Basic-Server", 2965 config: Config{ 2966 Bugs: ProtocolBugs{ 2967 RequireSessionTickets: true, 2968 }, 2969 }, 2970 resumeSession: true, 2971 }) 2972 tests = append(tests, testCase{ 2973 testType: serverTest, 2974 name: "Basic-Server-NoTickets", 2975 config: Config{ 2976 SessionTicketsDisabled: true, 2977 }, 2978 resumeSession: true, 2979 }) 2980 tests = append(tests, testCase{ 2981 testType: serverTest, 2982 name: "Basic-Server-Implicit", 2983 flags: []string{"-implicit-handshake"}, 2984 resumeSession: true, 2985 }) 2986 tests = append(tests, testCase{ 2987 testType: serverTest, 2988 name: "Basic-Server-EarlyCallback", 2989 flags: []string{"-use-early-callback"}, 2990 resumeSession: true, 2991 }) 2992 2993 // TLS client auth. 2994 tests = append(tests, testCase{ 2995 testType: clientTest, 2996 name: "ClientAuth-NoCertificate-Client", 2997 config: Config{ 2998 ClientAuth: RequestClientCert, 2999 }, 3000 }) 3001 tests = append(tests, testCase{ 3002 testType: serverTest, 3003 name: "ClientAuth-NoCertificate-Server", 3004 // Setting SSL_VERIFY_PEER allows anonymous clients. 3005 flags: []string{"-verify-peer"}, 3006 }) 3007 if protocol == tls { 3008 tests = append(tests, testCase{ 3009 testType: clientTest, 3010 name: "ClientAuth-NoCertificate-Client-SSL3", 3011 config: Config{ 3012 MaxVersion: VersionSSL30, 3013 ClientAuth: RequestClientCert, 3014 }, 3015 }) 3016 tests = append(tests, testCase{ 3017 testType: serverTest, 3018 name: "ClientAuth-NoCertificate-Server-SSL3", 3019 config: Config{ 3020 MaxVersion: VersionSSL30, 3021 }, 3022 // Setting SSL_VERIFY_PEER allows anonymous clients. 3023 flags: []string{"-verify-peer"}, 3024 }) 3025 } 3026 tests = append(tests, testCase{ 3027 testType: clientTest, 3028 name: "ClientAuth-NoCertificate-OldCallback", 3029 config: Config{ 3030 ClientAuth: RequestClientCert, 3031 }, 3032 flags: []string{"-use-old-client-cert-callback"}, 3033 }) 3034 tests = append(tests, testCase{ 3035 testType: clientTest, 3036 name: "ClientAuth-RSA-Client", 3037 config: Config{ 3038 ClientAuth: RequireAnyClientCert, 3039 }, 3040 flags: []string{ 3041 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 3042 "-key-file", path.Join(*resourceDir, rsaKeyFile), 3043 }, 3044 }) 3045 tests = append(tests, testCase{ 3046 testType: clientTest, 3047 name: "ClientAuth-ECDSA-Client", 3048 config: Config{ 3049 ClientAuth: RequireAnyClientCert, 3050 }, 3051 flags: []string{ 3052 "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile), 3053 "-key-file", path.Join(*resourceDir, ecdsaKeyFile), 3054 }, 3055 }) 3056 tests = append(tests, testCase{ 3057 testType: clientTest, 3058 name: "ClientAuth-OldCallback", 3059 config: Config{ 3060 ClientAuth: RequireAnyClientCert, 3061 }, 3062 flags: []string{ 3063 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 3064 "-key-file", path.Join(*resourceDir, rsaKeyFile), 3065 "-use-old-client-cert-callback", 3066 }, 3067 }) 3068 3069 if async { 3070 // Test async keys against each key exchange. 3071 tests = append(tests, testCase{ 3072 testType: serverTest, 3073 name: "Basic-Server-RSA", 3074 config: Config{ 3075 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 3076 }, 3077 flags: []string{ 3078 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 3079 "-key-file", path.Join(*resourceDir, rsaKeyFile), 3080 }, 3081 }) 3082 tests = append(tests, testCase{ 3083 testType: serverTest, 3084 name: "Basic-Server-ECDHE-RSA", 3085 config: Config{ 3086 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3087 }, 3088 flags: []string{ 3089 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 3090 "-key-file", path.Join(*resourceDir, rsaKeyFile), 3091 }, 3092 }) 3093 tests = append(tests, testCase{ 3094 testType: serverTest, 3095 name: "Basic-Server-ECDHE-ECDSA", 3096 config: Config{ 3097 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3098 }, 3099 flags: []string{ 3100 "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile), 3101 "-key-file", path.Join(*resourceDir, ecdsaKeyFile), 3102 }, 3103 }) 3104 } 3105 tests = append(tests, testCase{ 3106 testType: serverTest, 3107 name: "ClientAuth-Server", 3108 config: Config{ 3109 Certificates: []Certificate{rsaCertificate}, 3110 }, 3111 flags: []string{"-require-any-client-certificate"}, 3112 }) 3113 3114 // No session ticket support; server doesn't send NewSessionTicket. 3115 tests = append(tests, testCase{ 3116 name: "SessionTicketsDisabled-Client", 3117 config: Config{ 3118 SessionTicketsDisabled: true, 3119 }, 3120 }) 3121 tests = append(tests, testCase{ 3122 testType: serverTest, 3123 name: "SessionTicketsDisabled-Server", 3124 config: Config{ 3125 SessionTicketsDisabled: true, 3126 }, 3127 }) 3128 3129 // Skip ServerKeyExchange in PSK key exchange if there's no 3130 // identity hint. 3131 tests = append(tests, testCase{ 3132 name: "EmptyPSKHint-Client", 3133 config: Config{ 3134 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 3135 PreSharedKey: []byte("secret"), 3136 }, 3137 flags: []string{"-psk", "secret"}, 3138 }) 3139 tests = append(tests, testCase{ 3140 testType: serverTest, 3141 name: "EmptyPSKHint-Server", 3142 config: Config{ 3143 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 3144 PreSharedKey: []byte("secret"), 3145 }, 3146 flags: []string{"-psk", "secret"}, 3147 }) 3148 3149 tests = append(tests, testCase{ 3150 testType: clientTest, 3151 name: "OCSPStapling-Client", 3152 flags: []string{ 3153 "-enable-ocsp-stapling", 3154 "-expect-ocsp-response", 3155 base64.StdEncoding.EncodeToString(testOCSPResponse), 3156 "-verify-peer", 3157 }, 3158 resumeSession: true, 3159 }) 3160 3161 tests = append(tests, testCase{ 3162 testType: serverTest, 3163 name: "OCSPStapling-Server", 3164 expectedOCSPResponse: testOCSPResponse, 3165 flags: []string{ 3166 "-ocsp-response", 3167 base64.StdEncoding.EncodeToString(testOCSPResponse), 3168 }, 3169 resumeSession: true, 3170 }) 3171 3172 tests = append(tests, testCase{ 3173 testType: clientTest, 3174 name: "CertificateVerificationSucceed", 3175 flags: []string{ 3176 "-verify-peer", 3177 }, 3178 }) 3179 3180 tests = append(tests, testCase{ 3181 testType: clientTest, 3182 name: "CertificateVerificationFail", 3183 flags: []string{ 3184 "-verify-fail", 3185 "-verify-peer", 3186 }, 3187 shouldFail: true, 3188 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 3189 }) 3190 3191 tests = append(tests, testCase{ 3192 testType: clientTest, 3193 name: "CertificateVerificationSoftFail", 3194 flags: []string{ 3195 "-verify-fail", 3196 "-expect-verify-result", 3197 }, 3198 }) 3199 3200 if protocol == tls { 3201 tests = append(tests, testCase{ 3202 name: "Renegotiate-Client", 3203 renegotiate: 1, 3204 flags: []string{ 3205 "-renegotiate-freely", 3206 "-expect-total-renegotiations", "1", 3207 }, 3208 }) 3209 // NPN on client and server; results in post-handshake message. 3210 tests = append(tests, testCase{ 3211 name: "NPN-Client", 3212 config: Config{ 3213 NextProtos: []string{"foo"}, 3214 }, 3215 flags: []string{"-select-next-proto", "foo"}, 3216 resumeSession: true, 3217 expectedNextProto: "foo", 3218 expectedNextProtoType: npn, 3219 }) 3220 tests = append(tests, testCase{ 3221 testType: serverTest, 3222 name: "NPN-Server", 3223 config: Config{ 3224 NextProtos: []string{"bar"}, 3225 }, 3226 flags: []string{ 3227 "-advertise-npn", "\x03foo\x03bar\x03baz", 3228 "-expect-next-proto", "bar", 3229 }, 3230 resumeSession: true, 3231 expectedNextProto: "bar", 3232 expectedNextProtoType: npn, 3233 }) 3234 3235 // TODO(davidben): Add tests for when False Start doesn't trigger. 3236 3237 // Client does False Start and negotiates NPN. 3238 tests = append(tests, testCase{ 3239 name: "FalseStart", 3240 config: Config{ 3241 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3242 NextProtos: []string{"foo"}, 3243 Bugs: ProtocolBugs{ 3244 ExpectFalseStart: true, 3245 }, 3246 }, 3247 flags: []string{ 3248 "-false-start", 3249 "-select-next-proto", "foo", 3250 }, 3251 shimWritesFirst: true, 3252 resumeSession: true, 3253 }) 3254 3255 // Client does False Start and negotiates ALPN. 3256 tests = append(tests, testCase{ 3257 name: "FalseStart-ALPN", 3258 config: Config{ 3259 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3260 NextProtos: []string{"foo"}, 3261 Bugs: ProtocolBugs{ 3262 ExpectFalseStart: true, 3263 }, 3264 }, 3265 flags: []string{ 3266 "-false-start", 3267 "-advertise-alpn", "\x03foo", 3268 }, 3269 shimWritesFirst: true, 3270 resumeSession: true, 3271 }) 3272 3273 // Client does False Start but doesn't explicitly call 3274 // SSL_connect. 3275 tests = append(tests, testCase{ 3276 name: "FalseStart-Implicit", 3277 config: Config{ 3278 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3279 NextProtos: []string{"foo"}, 3280 }, 3281 flags: []string{ 3282 "-implicit-handshake", 3283 "-false-start", 3284 "-advertise-alpn", "\x03foo", 3285 }, 3286 }) 3287 3288 // False Start without session tickets. 3289 tests = append(tests, testCase{ 3290 name: "FalseStart-SessionTicketsDisabled", 3291 config: Config{ 3292 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3293 NextProtos: []string{"foo"}, 3294 SessionTicketsDisabled: true, 3295 Bugs: ProtocolBugs{ 3296 ExpectFalseStart: true, 3297 }, 3298 }, 3299 flags: []string{ 3300 "-false-start", 3301 "-select-next-proto", "foo", 3302 }, 3303 shimWritesFirst: true, 3304 }) 3305 3306 // Server parses a V2ClientHello. 3307 tests = append(tests, testCase{ 3308 testType: serverTest, 3309 name: "SendV2ClientHello", 3310 config: Config{ 3311 // Choose a cipher suite that does not involve 3312 // elliptic curves, so no extensions are 3313 // involved. 3314 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 3315 Bugs: ProtocolBugs{ 3316 SendV2ClientHello: true, 3317 }, 3318 }, 3319 }) 3320 3321 // Client sends a Channel ID. 3322 tests = append(tests, testCase{ 3323 name: "ChannelID-Client", 3324 config: Config{ 3325 RequestChannelID: true, 3326 }, 3327 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)}, 3328 resumeSession: true, 3329 expectChannelID: true, 3330 }) 3331 3332 // Server accepts a Channel ID. 3333 tests = append(tests, testCase{ 3334 testType: serverTest, 3335 name: "ChannelID-Server", 3336 config: Config{ 3337 ChannelID: channelIDKey, 3338 }, 3339 flags: []string{ 3340 "-expect-channel-id", 3341 base64.StdEncoding.EncodeToString(channelIDBytes), 3342 }, 3343 resumeSession: true, 3344 expectChannelID: true, 3345 }) 3346 3347 // Channel ID and NPN at the same time, to ensure their relative 3348 // ordering is correct. 3349 tests = append(tests, testCase{ 3350 name: "ChannelID-NPN-Client", 3351 config: Config{ 3352 RequestChannelID: true, 3353 NextProtos: []string{"foo"}, 3354 }, 3355 flags: []string{ 3356 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 3357 "-select-next-proto", "foo", 3358 }, 3359 resumeSession: true, 3360 expectChannelID: true, 3361 expectedNextProto: "foo", 3362 expectedNextProtoType: npn, 3363 }) 3364 tests = append(tests, testCase{ 3365 testType: serverTest, 3366 name: "ChannelID-NPN-Server", 3367 config: Config{ 3368 ChannelID: channelIDKey, 3369 NextProtos: []string{"bar"}, 3370 }, 3371 flags: []string{ 3372 "-expect-channel-id", 3373 base64.StdEncoding.EncodeToString(channelIDBytes), 3374 "-advertise-npn", "\x03foo\x03bar\x03baz", 3375 "-expect-next-proto", "bar", 3376 }, 3377 resumeSession: true, 3378 expectChannelID: true, 3379 expectedNextProto: "bar", 3380 expectedNextProtoType: npn, 3381 }) 3382 3383 // Bidirectional shutdown with the runner initiating. 3384 tests = append(tests, testCase{ 3385 name: "Shutdown-Runner", 3386 config: Config{ 3387 Bugs: ProtocolBugs{ 3388 ExpectCloseNotify: true, 3389 }, 3390 }, 3391 flags: []string{"-check-close-notify"}, 3392 }) 3393 3394 // Bidirectional shutdown with the shim initiating. The runner, 3395 // in the meantime, sends garbage before the close_notify which 3396 // the shim must ignore. 3397 tests = append(tests, testCase{ 3398 name: "Shutdown-Shim", 3399 config: Config{ 3400 Bugs: ProtocolBugs{ 3401 ExpectCloseNotify: true, 3402 }, 3403 }, 3404 shimShutsDown: true, 3405 sendEmptyRecords: 1, 3406 sendWarningAlerts: 1, 3407 flags: []string{"-check-close-notify"}, 3408 }) 3409 } else { 3410 tests = append(tests, testCase{ 3411 name: "SkipHelloVerifyRequest", 3412 config: Config{ 3413 Bugs: ProtocolBugs{ 3414 SkipHelloVerifyRequest: true, 3415 }, 3416 }, 3417 }) 3418 } 3419 3420 for _, test := range tests { 3421 test.protocol = protocol 3422 if protocol == dtls { 3423 test.name += "-DTLS" 3424 } 3425 if async { 3426 test.name += "-Async" 3427 test.flags = append(test.flags, "-async") 3428 } else { 3429 test.name += "-Sync" 3430 } 3431 if splitHandshake { 3432 test.name += "-SplitHandshakeRecords" 3433 test.config.Bugs.MaxHandshakeRecordLength = 1 3434 if protocol == dtls { 3435 test.config.Bugs.MaxPacketLength = 256 3436 test.flags = append(test.flags, "-mtu", "256") 3437 } 3438 } 3439 testCases = append(testCases, test) 3440 } 3441} 3442 3443func addDDoSCallbackTests() { 3444 // DDoS callback. 3445 3446 for _, resume := range []bool{false, true} { 3447 suffix := "Resume" 3448 if resume { 3449 suffix = "No" + suffix 3450 } 3451 3452 testCases = append(testCases, testCase{ 3453 testType: serverTest, 3454 name: "Server-DDoS-OK-" + suffix, 3455 flags: []string{"-install-ddos-callback"}, 3456 resumeSession: resume, 3457 }) 3458 3459 failFlag := "-fail-ddos-callback" 3460 if resume { 3461 failFlag = "-fail-second-ddos-callback" 3462 } 3463 testCases = append(testCases, testCase{ 3464 testType: serverTest, 3465 name: "Server-DDoS-Reject-" + suffix, 3466 flags: []string{"-install-ddos-callback", failFlag}, 3467 resumeSession: resume, 3468 shouldFail: true, 3469 expectedError: ":CONNECTION_REJECTED:", 3470 }) 3471 } 3472} 3473 3474func addVersionNegotiationTests() { 3475 for i, shimVers := range tlsVersions { 3476 // Assemble flags to disable all newer versions on the shim. 3477 var flags []string 3478 for _, vers := range tlsVersions[i+1:] { 3479 flags = append(flags, vers.flag) 3480 } 3481 3482 for _, runnerVers := range tlsVersions { 3483 protocols := []protocol{tls} 3484 if runnerVers.hasDTLS && shimVers.hasDTLS { 3485 protocols = append(protocols, dtls) 3486 } 3487 for _, protocol := range protocols { 3488 expectedVersion := shimVers.version 3489 if runnerVers.version < shimVers.version { 3490 expectedVersion = runnerVers.version 3491 } 3492 3493 suffix := shimVers.name + "-" + runnerVers.name 3494 if protocol == dtls { 3495 suffix += "-DTLS" 3496 } 3497 3498 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls))) 3499 3500 clientVers := shimVers.version 3501 if clientVers > VersionTLS10 { 3502 clientVers = VersionTLS10 3503 } 3504 testCases = append(testCases, testCase{ 3505 protocol: protocol, 3506 testType: clientTest, 3507 name: "VersionNegotiation-Client-" + suffix, 3508 config: Config{ 3509 MaxVersion: runnerVers.version, 3510 Bugs: ProtocolBugs{ 3511 ExpectInitialRecordVersion: clientVers, 3512 }, 3513 }, 3514 flags: flags, 3515 expectedVersion: expectedVersion, 3516 }) 3517 testCases = append(testCases, testCase{ 3518 protocol: protocol, 3519 testType: clientTest, 3520 name: "VersionNegotiation-Client2-" + suffix, 3521 config: Config{ 3522 MaxVersion: runnerVers.version, 3523 Bugs: ProtocolBugs{ 3524 ExpectInitialRecordVersion: clientVers, 3525 }, 3526 }, 3527 flags: []string{"-max-version", shimVersFlag}, 3528 expectedVersion: expectedVersion, 3529 }) 3530 3531 testCases = append(testCases, testCase{ 3532 protocol: protocol, 3533 testType: serverTest, 3534 name: "VersionNegotiation-Server-" + suffix, 3535 config: Config{ 3536 MaxVersion: runnerVers.version, 3537 Bugs: ProtocolBugs{ 3538 ExpectInitialRecordVersion: expectedVersion, 3539 }, 3540 }, 3541 flags: flags, 3542 expectedVersion: expectedVersion, 3543 }) 3544 testCases = append(testCases, testCase{ 3545 protocol: protocol, 3546 testType: serverTest, 3547 name: "VersionNegotiation-Server2-" + suffix, 3548 config: Config{ 3549 MaxVersion: runnerVers.version, 3550 Bugs: ProtocolBugs{ 3551 ExpectInitialRecordVersion: expectedVersion, 3552 }, 3553 }, 3554 flags: []string{"-max-version", shimVersFlag}, 3555 expectedVersion: expectedVersion, 3556 }) 3557 } 3558 } 3559 } 3560} 3561 3562func addMinimumVersionTests() { 3563 for i, shimVers := range tlsVersions { 3564 // Assemble flags to disable all older versions on the shim. 3565 var flags []string 3566 for _, vers := range tlsVersions[:i] { 3567 flags = append(flags, vers.flag) 3568 } 3569 3570 for _, runnerVers := range tlsVersions { 3571 protocols := []protocol{tls} 3572 if runnerVers.hasDTLS && shimVers.hasDTLS { 3573 protocols = append(protocols, dtls) 3574 } 3575 for _, protocol := range protocols { 3576 suffix := shimVers.name + "-" + runnerVers.name 3577 if protocol == dtls { 3578 suffix += "-DTLS" 3579 } 3580 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls))) 3581 3582 var expectedVersion uint16 3583 var shouldFail bool 3584 var expectedError string 3585 var expectedLocalError string 3586 if runnerVers.version >= shimVers.version { 3587 expectedVersion = runnerVers.version 3588 } else { 3589 shouldFail = true 3590 expectedError = ":UNSUPPORTED_PROTOCOL:" 3591 expectedLocalError = "remote error: protocol version not supported" 3592 } 3593 3594 testCases = append(testCases, testCase{ 3595 protocol: protocol, 3596 testType: clientTest, 3597 name: "MinimumVersion-Client-" + suffix, 3598 config: Config{ 3599 MaxVersion: runnerVers.version, 3600 }, 3601 flags: flags, 3602 expectedVersion: expectedVersion, 3603 shouldFail: shouldFail, 3604 expectedError: expectedError, 3605 expectedLocalError: expectedLocalError, 3606 }) 3607 testCases = append(testCases, testCase{ 3608 protocol: protocol, 3609 testType: clientTest, 3610 name: "MinimumVersion-Client2-" + suffix, 3611 config: Config{ 3612 MaxVersion: runnerVers.version, 3613 }, 3614 flags: []string{"-min-version", shimVersFlag}, 3615 expectedVersion: expectedVersion, 3616 shouldFail: shouldFail, 3617 expectedError: expectedError, 3618 expectedLocalError: expectedLocalError, 3619 }) 3620 3621 testCases = append(testCases, testCase{ 3622 protocol: protocol, 3623 testType: serverTest, 3624 name: "MinimumVersion-Server-" + suffix, 3625 config: Config{ 3626 MaxVersion: runnerVers.version, 3627 }, 3628 flags: flags, 3629 expectedVersion: expectedVersion, 3630 shouldFail: shouldFail, 3631 expectedError: expectedError, 3632 expectedLocalError: expectedLocalError, 3633 }) 3634 testCases = append(testCases, testCase{ 3635 protocol: protocol, 3636 testType: serverTest, 3637 name: "MinimumVersion-Server2-" + suffix, 3638 config: Config{ 3639 MaxVersion: runnerVers.version, 3640 }, 3641 flags: []string{"-min-version", shimVersFlag}, 3642 expectedVersion: expectedVersion, 3643 shouldFail: shouldFail, 3644 expectedError: expectedError, 3645 expectedLocalError: expectedLocalError, 3646 }) 3647 } 3648 } 3649 } 3650} 3651 3652func addExtensionTests() { 3653 testCases = append(testCases, testCase{ 3654 testType: clientTest, 3655 name: "DuplicateExtensionClient", 3656 config: Config{ 3657 Bugs: ProtocolBugs{ 3658 DuplicateExtension: true, 3659 }, 3660 }, 3661 shouldFail: true, 3662 expectedLocalError: "remote error: error decoding message", 3663 }) 3664 testCases = append(testCases, testCase{ 3665 testType: serverTest, 3666 name: "DuplicateExtensionServer", 3667 config: Config{ 3668 Bugs: ProtocolBugs{ 3669 DuplicateExtension: true, 3670 }, 3671 }, 3672 shouldFail: true, 3673 expectedLocalError: "remote error: error decoding message", 3674 }) 3675 testCases = append(testCases, testCase{ 3676 testType: clientTest, 3677 name: "ServerNameExtensionClient", 3678 config: Config{ 3679 Bugs: ProtocolBugs{ 3680 ExpectServerName: "example.com", 3681 }, 3682 }, 3683 flags: []string{"-host-name", "example.com"}, 3684 }) 3685 testCases = append(testCases, testCase{ 3686 testType: clientTest, 3687 name: "ServerNameExtensionClientMismatch", 3688 config: Config{ 3689 Bugs: ProtocolBugs{ 3690 ExpectServerName: "mismatch.com", 3691 }, 3692 }, 3693 flags: []string{"-host-name", "example.com"}, 3694 shouldFail: true, 3695 expectedLocalError: "tls: unexpected server name", 3696 }) 3697 testCases = append(testCases, testCase{ 3698 testType: clientTest, 3699 name: "ServerNameExtensionClientMissing", 3700 config: Config{ 3701 Bugs: ProtocolBugs{ 3702 ExpectServerName: "missing.com", 3703 }, 3704 }, 3705 shouldFail: true, 3706 expectedLocalError: "tls: unexpected server name", 3707 }) 3708 testCases = append(testCases, testCase{ 3709 testType: serverTest, 3710 name: "ServerNameExtensionServer", 3711 config: Config{ 3712 ServerName: "example.com", 3713 }, 3714 flags: []string{"-expect-server-name", "example.com"}, 3715 resumeSession: true, 3716 }) 3717 testCases = append(testCases, testCase{ 3718 testType: clientTest, 3719 name: "ALPNClient", 3720 config: Config{ 3721 NextProtos: []string{"foo"}, 3722 }, 3723 flags: []string{ 3724 "-advertise-alpn", "\x03foo\x03bar\x03baz", 3725 "-expect-alpn", "foo", 3726 }, 3727 expectedNextProto: "foo", 3728 expectedNextProtoType: alpn, 3729 resumeSession: true, 3730 }) 3731 testCases = append(testCases, testCase{ 3732 testType: serverTest, 3733 name: "ALPNServer", 3734 config: Config{ 3735 NextProtos: []string{"foo", "bar", "baz"}, 3736 }, 3737 flags: []string{ 3738 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 3739 "-select-alpn", "foo", 3740 }, 3741 expectedNextProto: "foo", 3742 expectedNextProtoType: alpn, 3743 resumeSession: true, 3744 }) 3745 testCases = append(testCases, testCase{ 3746 testType: serverTest, 3747 name: "ALPNServer-Decline", 3748 config: Config{ 3749 NextProtos: []string{"foo", "bar", "baz"}, 3750 }, 3751 flags: []string{"-decline-alpn"}, 3752 expectNoNextProto: true, 3753 resumeSession: true, 3754 }) 3755 // Test that the server prefers ALPN over NPN. 3756 testCases = append(testCases, testCase{ 3757 testType: serverTest, 3758 name: "ALPNServer-Preferred", 3759 config: Config{ 3760 NextProtos: []string{"foo", "bar", "baz"}, 3761 }, 3762 flags: []string{ 3763 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 3764 "-select-alpn", "foo", 3765 "-advertise-npn", "\x03foo\x03bar\x03baz", 3766 }, 3767 expectedNextProto: "foo", 3768 expectedNextProtoType: alpn, 3769 resumeSession: true, 3770 }) 3771 testCases = append(testCases, testCase{ 3772 testType: serverTest, 3773 name: "ALPNServer-Preferred-Swapped", 3774 config: Config{ 3775 NextProtos: []string{"foo", "bar", "baz"}, 3776 Bugs: ProtocolBugs{ 3777 SwapNPNAndALPN: true, 3778 }, 3779 }, 3780 flags: []string{ 3781 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 3782 "-select-alpn", "foo", 3783 "-advertise-npn", "\x03foo\x03bar\x03baz", 3784 }, 3785 expectedNextProto: "foo", 3786 expectedNextProtoType: alpn, 3787 resumeSession: true, 3788 }) 3789 var emptyString string 3790 testCases = append(testCases, testCase{ 3791 testType: clientTest, 3792 name: "ALPNClient-EmptyProtocolName", 3793 config: Config{ 3794 NextProtos: []string{""}, 3795 Bugs: ProtocolBugs{ 3796 // A server returning an empty ALPN protocol 3797 // should be rejected. 3798 ALPNProtocol: &emptyString, 3799 }, 3800 }, 3801 flags: []string{ 3802 "-advertise-alpn", "\x03foo", 3803 }, 3804 shouldFail: true, 3805 expectedError: ":PARSE_TLSEXT:", 3806 }) 3807 testCases = append(testCases, testCase{ 3808 testType: serverTest, 3809 name: "ALPNServer-EmptyProtocolName", 3810 config: Config{ 3811 // A ClientHello containing an empty ALPN protocol 3812 // should be rejected. 3813 NextProtos: []string{"foo", "", "baz"}, 3814 }, 3815 flags: []string{ 3816 "-select-alpn", "foo", 3817 }, 3818 shouldFail: true, 3819 expectedError: ":PARSE_TLSEXT:", 3820 }) 3821 // Test that negotiating both NPN and ALPN is forbidden. 3822 testCases = append(testCases, testCase{ 3823 name: "NegotiateALPNAndNPN", 3824 config: Config{ 3825 NextProtos: []string{"foo", "bar", "baz"}, 3826 Bugs: ProtocolBugs{ 3827 NegotiateALPNAndNPN: true, 3828 }, 3829 }, 3830 flags: []string{ 3831 "-advertise-alpn", "\x03foo", 3832 "-select-next-proto", "foo", 3833 }, 3834 shouldFail: true, 3835 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 3836 }) 3837 testCases = append(testCases, testCase{ 3838 name: "NegotiateALPNAndNPN-Swapped", 3839 config: Config{ 3840 NextProtos: []string{"foo", "bar", "baz"}, 3841 Bugs: ProtocolBugs{ 3842 NegotiateALPNAndNPN: true, 3843 SwapNPNAndALPN: true, 3844 }, 3845 }, 3846 flags: []string{ 3847 "-advertise-alpn", "\x03foo", 3848 "-select-next-proto", "foo", 3849 }, 3850 shouldFail: true, 3851 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 3852 }) 3853 // Test that NPN can be disabled with SSL_OP_DISABLE_NPN. 3854 testCases = append(testCases, testCase{ 3855 name: "DisableNPN", 3856 config: Config{ 3857 NextProtos: []string{"foo"}, 3858 }, 3859 flags: []string{ 3860 "-select-next-proto", "foo", 3861 "-disable-npn", 3862 }, 3863 expectNoNextProto: true, 3864 }) 3865 // Resume with a corrupt ticket. 3866 testCases = append(testCases, testCase{ 3867 testType: serverTest, 3868 name: "CorruptTicket", 3869 config: Config{ 3870 Bugs: ProtocolBugs{ 3871 CorruptTicket: true, 3872 }, 3873 }, 3874 resumeSession: true, 3875 expectResumeRejected: true, 3876 }) 3877 // Test the ticket callback, with and without renewal. 3878 testCases = append(testCases, testCase{ 3879 testType: serverTest, 3880 name: "TicketCallback", 3881 resumeSession: true, 3882 flags: []string{"-use-ticket-callback"}, 3883 }) 3884 testCases = append(testCases, testCase{ 3885 testType: serverTest, 3886 name: "TicketCallback-Renew", 3887 config: Config{ 3888 Bugs: ProtocolBugs{ 3889 ExpectNewTicket: true, 3890 }, 3891 }, 3892 flags: []string{"-use-ticket-callback", "-renew-ticket"}, 3893 resumeSession: true, 3894 }) 3895 // Resume with an oversized session id. 3896 testCases = append(testCases, testCase{ 3897 testType: serverTest, 3898 name: "OversizedSessionId", 3899 config: Config{ 3900 Bugs: ProtocolBugs{ 3901 OversizedSessionId: true, 3902 }, 3903 }, 3904 resumeSession: true, 3905 shouldFail: true, 3906 expectedError: ":DECODE_ERROR:", 3907 }) 3908 // Basic DTLS-SRTP tests. Include fake profiles to ensure they 3909 // are ignored. 3910 testCases = append(testCases, testCase{ 3911 protocol: dtls, 3912 name: "SRTP-Client", 3913 config: Config{ 3914 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 3915 }, 3916 flags: []string{ 3917 "-srtp-profiles", 3918 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 3919 }, 3920 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 3921 }) 3922 testCases = append(testCases, testCase{ 3923 protocol: dtls, 3924 testType: serverTest, 3925 name: "SRTP-Server", 3926 config: Config{ 3927 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 3928 }, 3929 flags: []string{ 3930 "-srtp-profiles", 3931 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 3932 }, 3933 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 3934 }) 3935 // Test that the MKI is ignored. 3936 testCases = append(testCases, testCase{ 3937 protocol: dtls, 3938 testType: serverTest, 3939 name: "SRTP-Server-IgnoreMKI", 3940 config: Config{ 3941 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80}, 3942 Bugs: ProtocolBugs{ 3943 SRTPMasterKeyIdentifer: "bogus", 3944 }, 3945 }, 3946 flags: []string{ 3947 "-srtp-profiles", 3948 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 3949 }, 3950 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 3951 }) 3952 // Test that SRTP isn't negotiated on the server if there were 3953 // no matching profiles. 3954 testCases = append(testCases, testCase{ 3955 protocol: dtls, 3956 testType: serverTest, 3957 name: "SRTP-Server-NoMatch", 3958 config: Config{ 3959 SRTPProtectionProfiles: []uint16{100, 101, 102}, 3960 }, 3961 flags: []string{ 3962 "-srtp-profiles", 3963 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 3964 }, 3965 expectedSRTPProtectionProfile: 0, 3966 }) 3967 // Test that the server returning an invalid SRTP profile is 3968 // flagged as an error by the client. 3969 testCases = append(testCases, testCase{ 3970 protocol: dtls, 3971 name: "SRTP-Client-NoMatch", 3972 config: Config{ 3973 Bugs: ProtocolBugs{ 3974 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32, 3975 }, 3976 }, 3977 flags: []string{ 3978 "-srtp-profiles", 3979 "SRTP_AES128_CM_SHA1_80", 3980 }, 3981 shouldFail: true, 3982 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:", 3983 }) 3984 // Test SCT list. 3985 testCases = append(testCases, testCase{ 3986 name: "SignedCertificateTimestampList-Client", 3987 testType: clientTest, 3988 flags: []string{ 3989 "-enable-signed-cert-timestamps", 3990 "-expect-signed-cert-timestamps", 3991 base64.StdEncoding.EncodeToString(testSCTList), 3992 }, 3993 resumeSession: true, 3994 }) 3995 testCases = append(testCases, testCase{ 3996 name: "SendSCTListOnResume", 3997 config: Config{ 3998 Bugs: ProtocolBugs{ 3999 SendSCTListOnResume: []byte("bogus"), 4000 }, 4001 }, 4002 flags: []string{ 4003 "-enable-signed-cert-timestamps", 4004 "-expect-signed-cert-timestamps", 4005 base64.StdEncoding.EncodeToString(testSCTList), 4006 }, 4007 resumeSession: true, 4008 }) 4009 testCases = append(testCases, testCase{ 4010 name: "SignedCertificateTimestampList-Server", 4011 testType: serverTest, 4012 flags: []string{ 4013 "-signed-cert-timestamps", 4014 base64.StdEncoding.EncodeToString(testSCTList), 4015 }, 4016 expectedSCTList: testSCTList, 4017 resumeSession: true, 4018 }) 4019 testCases = append(testCases, testCase{ 4020 testType: clientTest, 4021 name: "ClientHelloPadding", 4022 config: Config{ 4023 Bugs: ProtocolBugs{ 4024 RequireClientHelloSize: 512, 4025 }, 4026 }, 4027 // This hostname just needs to be long enough to push the 4028 // ClientHello into F5's danger zone between 256 and 511 bytes 4029 // long. 4030 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"}, 4031 }) 4032 4033 // Extensions should not function in SSL 3.0. 4034 testCases = append(testCases, testCase{ 4035 testType: serverTest, 4036 name: "SSLv3Extensions-NoALPN", 4037 config: Config{ 4038 MaxVersion: VersionSSL30, 4039 NextProtos: []string{"foo", "bar", "baz"}, 4040 }, 4041 flags: []string{ 4042 "-select-alpn", "foo", 4043 }, 4044 expectNoNextProto: true, 4045 }) 4046 4047 // Test session tickets separately as they follow a different codepath. 4048 testCases = append(testCases, testCase{ 4049 testType: serverTest, 4050 name: "SSLv3Extensions-NoTickets", 4051 config: Config{ 4052 MaxVersion: VersionSSL30, 4053 Bugs: ProtocolBugs{ 4054 // Historically, session tickets in SSL 3.0 4055 // failed in different ways depending on whether 4056 // the client supported renegotiation_info. 4057 NoRenegotiationInfo: true, 4058 }, 4059 }, 4060 resumeSession: true, 4061 }) 4062 testCases = append(testCases, testCase{ 4063 testType: serverTest, 4064 name: "SSLv3Extensions-NoTickets2", 4065 config: Config{ 4066 MaxVersion: VersionSSL30, 4067 }, 4068 resumeSession: true, 4069 }) 4070 4071 // But SSL 3.0 does send and process renegotiation_info. 4072 testCases = append(testCases, testCase{ 4073 testType: serverTest, 4074 name: "SSLv3Extensions-RenegotiationInfo", 4075 config: Config{ 4076 MaxVersion: VersionSSL30, 4077 Bugs: ProtocolBugs{ 4078 RequireRenegotiationInfo: true, 4079 }, 4080 }, 4081 }) 4082 testCases = append(testCases, testCase{ 4083 testType: serverTest, 4084 name: "SSLv3Extensions-RenegotiationInfo-SCSV", 4085 config: Config{ 4086 MaxVersion: VersionSSL30, 4087 Bugs: ProtocolBugs{ 4088 NoRenegotiationInfo: true, 4089 SendRenegotiationSCSV: true, 4090 RequireRenegotiationInfo: true, 4091 }, 4092 }, 4093 }) 4094} 4095 4096func addResumptionVersionTests() { 4097 for _, sessionVers := range tlsVersions { 4098 for _, resumeVers := range tlsVersions { 4099 protocols := []protocol{tls} 4100 if sessionVers.hasDTLS && resumeVers.hasDTLS { 4101 protocols = append(protocols, dtls) 4102 } 4103 for _, protocol := range protocols { 4104 suffix := "-" + sessionVers.name + "-" + resumeVers.name 4105 if protocol == dtls { 4106 suffix += "-DTLS" 4107 } 4108 4109 if sessionVers.version == resumeVers.version { 4110 testCases = append(testCases, testCase{ 4111 protocol: protocol, 4112 name: "Resume-Client" + suffix, 4113 resumeSession: true, 4114 config: Config{ 4115 MaxVersion: sessionVers.version, 4116 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4117 }, 4118 expectedVersion: sessionVers.version, 4119 expectedResumeVersion: resumeVers.version, 4120 }) 4121 } else { 4122 testCases = append(testCases, testCase{ 4123 protocol: protocol, 4124 name: "Resume-Client-Mismatch" + suffix, 4125 resumeSession: true, 4126 config: Config{ 4127 MaxVersion: sessionVers.version, 4128 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4129 }, 4130 expectedVersion: sessionVers.version, 4131 resumeConfig: &Config{ 4132 MaxVersion: resumeVers.version, 4133 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4134 Bugs: ProtocolBugs{ 4135 AllowSessionVersionMismatch: true, 4136 }, 4137 }, 4138 expectedResumeVersion: resumeVers.version, 4139 shouldFail: true, 4140 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:", 4141 }) 4142 } 4143 4144 testCases = append(testCases, testCase{ 4145 protocol: protocol, 4146 name: "Resume-Client-NoResume" + suffix, 4147 resumeSession: true, 4148 config: Config{ 4149 MaxVersion: sessionVers.version, 4150 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4151 }, 4152 expectedVersion: sessionVers.version, 4153 resumeConfig: &Config{ 4154 MaxVersion: resumeVers.version, 4155 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4156 }, 4157 newSessionsOnResume: true, 4158 expectResumeRejected: true, 4159 expectedResumeVersion: resumeVers.version, 4160 }) 4161 4162 testCases = append(testCases, testCase{ 4163 protocol: protocol, 4164 testType: serverTest, 4165 name: "Resume-Server" + suffix, 4166 resumeSession: true, 4167 config: Config{ 4168 MaxVersion: sessionVers.version, 4169 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4170 }, 4171 expectedVersion: sessionVers.version, 4172 expectResumeRejected: sessionVers.version != resumeVers.version, 4173 resumeConfig: &Config{ 4174 MaxVersion: resumeVers.version, 4175 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 4176 }, 4177 expectedResumeVersion: resumeVers.version, 4178 }) 4179 } 4180 } 4181 } 4182 4183 testCases = append(testCases, testCase{ 4184 name: "Resume-Client-CipherMismatch", 4185 resumeSession: true, 4186 config: Config{ 4187 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 4188 }, 4189 resumeConfig: &Config{ 4190 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 4191 Bugs: ProtocolBugs{ 4192 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA, 4193 }, 4194 }, 4195 shouldFail: true, 4196 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:", 4197 }) 4198} 4199 4200func addRenegotiationTests() { 4201 // Servers cannot renegotiate. 4202 testCases = append(testCases, testCase{ 4203 testType: serverTest, 4204 name: "Renegotiate-Server-Forbidden", 4205 renegotiate: 1, 4206 shouldFail: true, 4207 expectedError: ":NO_RENEGOTIATION:", 4208 expectedLocalError: "remote error: no renegotiation", 4209 }) 4210 // The server shouldn't echo the renegotiation extension unless 4211 // requested by the client. 4212 testCases = append(testCases, testCase{ 4213 testType: serverTest, 4214 name: "Renegotiate-Server-NoExt", 4215 config: Config{ 4216 Bugs: ProtocolBugs{ 4217 NoRenegotiationInfo: true, 4218 RequireRenegotiationInfo: true, 4219 }, 4220 }, 4221 shouldFail: true, 4222 expectedLocalError: "renegotiation extension missing", 4223 }) 4224 // The renegotiation SCSV should be sufficient for the server to echo 4225 // the extension. 4226 testCases = append(testCases, testCase{ 4227 testType: serverTest, 4228 name: "Renegotiate-Server-NoExt-SCSV", 4229 config: Config{ 4230 Bugs: ProtocolBugs{ 4231 NoRenegotiationInfo: true, 4232 SendRenegotiationSCSV: true, 4233 RequireRenegotiationInfo: true, 4234 }, 4235 }, 4236 }) 4237 testCases = append(testCases, testCase{ 4238 name: "Renegotiate-Client", 4239 config: Config{ 4240 Bugs: ProtocolBugs{ 4241 FailIfResumeOnRenego: true, 4242 }, 4243 }, 4244 renegotiate: 1, 4245 flags: []string{ 4246 "-renegotiate-freely", 4247 "-expect-total-renegotiations", "1", 4248 }, 4249 }) 4250 testCases = append(testCases, testCase{ 4251 name: "Renegotiate-Client-EmptyExt", 4252 renegotiate: 1, 4253 config: Config{ 4254 Bugs: ProtocolBugs{ 4255 EmptyRenegotiationInfo: true, 4256 }, 4257 }, 4258 flags: []string{"-renegotiate-freely"}, 4259 shouldFail: true, 4260 expectedError: ":RENEGOTIATION_MISMATCH:", 4261 }) 4262 testCases = append(testCases, testCase{ 4263 name: "Renegotiate-Client-BadExt", 4264 renegotiate: 1, 4265 config: Config{ 4266 Bugs: ProtocolBugs{ 4267 BadRenegotiationInfo: true, 4268 }, 4269 }, 4270 flags: []string{"-renegotiate-freely"}, 4271 shouldFail: true, 4272 expectedError: ":RENEGOTIATION_MISMATCH:", 4273 }) 4274 testCases = append(testCases, testCase{ 4275 name: "Renegotiate-Client-Downgrade", 4276 renegotiate: 1, 4277 config: Config{ 4278 Bugs: ProtocolBugs{ 4279 NoRenegotiationInfoAfterInitial: true, 4280 }, 4281 }, 4282 flags: []string{"-renegotiate-freely"}, 4283 shouldFail: true, 4284 expectedError: ":RENEGOTIATION_MISMATCH:", 4285 }) 4286 testCases = append(testCases, testCase{ 4287 name: "Renegotiate-Client-Upgrade", 4288 renegotiate: 1, 4289 config: Config{ 4290 Bugs: ProtocolBugs{ 4291 NoRenegotiationInfoInInitial: true, 4292 }, 4293 }, 4294 flags: []string{"-renegotiate-freely"}, 4295 shouldFail: true, 4296 expectedError: ":RENEGOTIATION_MISMATCH:", 4297 }) 4298 testCases = append(testCases, testCase{ 4299 name: "Renegotiate-Client-NoExt-Allowed", 4300 renegotiate: 1, 4301 config: Config{ 4302 Bugs: ProtocolBugs{ 4303 NoRenegotiationInfo: true, 4304 }, 4305 }, 4306 flags: []string{ 4307 "-renegotiate-freely", 4308 "-expect-total-renegotiations", "1", 4309 }, 4310 }) 4311 testCases = append(testCases, testCase{ 4312 name: "Renegotiate-Client-SwitchCiphers", 4313 renegotiate: 1, 4314 config: Config{ 4315 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 4316 }, 4317 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4318 flags: []string{ 4319 "-renegotiate-freely", 4320 "-expect-total-renegotiations", "1", 4321 }, 4322 }) 4323 testCases = append(testCases, testCase{ 4324 name: "Renegotiate-Client-SwitchCiphers2", 4325 renegotiate: 1, 4326 config: Config{ 4327 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4328 }, 4329 renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 4330 flags: []string{ 4331 "-renegotiate-freely", 4332 "-expect-total-renegotiations", "1", 4333 }, 4334 }) 4335 testCases = append(testCases, testCase{ 4336 name: "Renegotiate-SameClientVersion", 4337 renegotiate: 1, 4338 config: Config{ 4339 MaxVersion: VersionTLS10, 4340 Bugs: ProtocolBugs{ 4341 RequireSameRenegoClientVersion: true, 4342 }, 4343 }, 4344 flags: []string{ 4345 "-renegotiate-freely", 4346 "-expect-total-renegotiations", "1", 4347 }, 4348 }) 4349 testCases = append(testCases, testCase{ 4350 name: "Renegotiate-FalseStart", 4351 renegotiate: 1, 4352 config: Config{ 4353 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4354 NextProtos: []string{"foo"}, 4355 }, 4356 flags: []string{ 4357 "-false-start", 4358 "-select-next-proto", "foo", 4359 "-renegotiate-freely", 4360 "-expect-total-renegotiations", "1", 4361 }, 4362 shimWritesFirst: true, 4363 }) 4364 4365 // Client-side renegotiation controls. 4366 testCases = append(testCases, testCase{ 4367 name: "Renegotiate-Client-Forbidden-1", 4368 renegotiate: 1, 4369 shouldFail: true, 4370 expectedError: ":NO_RENEGOTIATION:", 4371 expectedLocalError: "remote error: no renegotiation", 4372 }) 4373 testCases = append(testCases, testCase{ 4374 name: "Renegotiate-Client-Once-1", 4375 renegotiate: 1, 4376 flags: []string{ 4377 "-renegotiate-once", 4378 "-expect-total-renegotiations", "1", 4379 }, 4380 }) 4381 testCases = append(testCases, testCase{ 4382 name: "Renegotiate-Client-Freely-1", 4383 renegotiate: 1, 4384 flags: []string{ 4385 "-renegotiate-freely", 4386 "-expect-total-renegotiations", "1", 4387 }, 4388 }) 4389 testCases = append(testCases, testCase{ 4390 name: "Renegotiate-Client-Once-2", 4391 renegotiate: 2, 4392 flags: []string{"-renegotiate-once"}, 4393 shouldFail: true, 4394 expectedError: ":NO_RENEGOTIATION:", 4395 expectedLocalError: "remote error: no renegotiation", 4396 }) 4397 testCases = append(testCases, testCase{ 4398 name: "Renegotiate-Client-Freely-2", 4399 renegotiate: 2, 4400 flags: []string{ 4401 "-renegotiate-freely", 4402 "-expect-total-renegotiations", "2", 4403 }, 4404 }) 4405 testCases = append(testCases, testCase{ 4406 name: "Renegotiate-Client-NoIgnore", 4407 config: Config{ 4408 Bugs: ProtocolBugs{ 4409 SendHelloRequestBeforeEveryAppDataRecord: true, 4410 }, 4411 }, 4412 shouldFail: true, 4413 expectedError: ":NO_RENEGOTIATION:", 4414 }) 4415 testCases = append(testCases, testCase{ 4416 name: "Renegotiate-Client-Ignore", 4417 config: Config{ 4418 Bugs: ProtocolBugs{ 4419 SendHelloRequestBeforeEveryAppDataRecord: true, 4420 }, 4421 }, 4422 flags: []string{ 4423 "-renegotiate-ignore", 4424 "-expect-total-renegotiations", "0", 4425 }, 4426 }) 4427} 4428 4429func addDTLSReplayTests() { 4430 // Test that sequence number replays are detected. 4431 testCases = append(testCases, testCase{ 4432 protocol: dtls, 4433 name: "DTLS-Replay", 4434 messageCount: 200, 4435 replayWrites: true, 4436 }) 4437 4438 // Test the incoming sequence number skipping by values larger 4439 // than the retransmit window. 4440 testCases = append(testCases, testCase{ 4441 protocol: dtls, 4442 name: "DTLS-Replay-LargeGaps", 4443 config: Config{ 4444 Bugs: ProtocolBugs{ 4445 SequenceNumberMapping: func(in uint64) uint64 { 4446 return in * 127 4447 }, 4448 }, 4449 }, 4450 messageCount: 200, 4451 replayWrites: true, 4452 }) 4453 4454 // Test the incoming sequence number changing non-monotonically. 4455 testCases = append(testCases, testCase{ 4456 protocol: dtls, 4457 name: "DTLS-Replay-NonMonotonic", 4458 config: Config{ 4459 Bugs: ProtocolBugs{ 4460 SequenceNumberMapping: func(in uint64) uint64 { 4461 return in ^ 31 4462 }, 4463 }, 4464 }, 4465 messageCount: 200, 4466 replayWrites: true, 4467 }) 4468} 4469 4470var testHashes = []struct { 4471 name string 4472 id uint8 4473}{ 4474 {"SHA1", hashSHA1}, 4475 {"SHA256", hashSHA256}, 4476 {"SHA384", hashSHA384}, 4477 {"SHA512", hashSHA512}, 4478} 4479 4480func addSigningHashTests() { 4481 // Make sure each hash works. Include some fake hashes in the list and 4482 // ensure they're ignored. 4483 for _, hash := range testHashes { 4484 testCases = append(testCases, testCase{ 4485 name: "SigningHash-ClientAuth-" + hash.name, 4486 config: Config{ 4487 ClientAuth: RequireAnyClientCert, 4488 SignatureAndHashes: []signatureAndHash{ 4489 {signatureRSA, 42}, 4490 {signatureRSA, hash.id}, 4491 {signatureRSA, 255}, 4492 }, 4493 }, 4494 flags: []string{ 4495 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4496 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4497 }, 4498 }) 4499 4500 testCases = append(testCases, testCase{ 4501 testType: serverTest, 4502 name: "SigningHash-ServerKeyExchange-Sign-" + hash.name, 4503 config: Config{ 4504 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4505 SignatureAndHashes: []signatureAndHash{ 4506 {signatureRSA, 42}, 4507 {signatureRSA, hash.id}, 4508 {signatureRSA, 255}, 4509 }, 4510 }, 4511 }) 4512 4513 testCases = append(testCases, testCase{ 4514 name: "SigningHash-ServerKeyExchange-Verify-" + hash.name, 4515 config: Config{ 4516 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4517 SignatureAndHashes: []signatureAndHash{ 4518 {signatureRSA, 42}, 4519 {signatureRSA, hash.id}, 4520 {signatureRSA, 255}, 4521 }, 4522 }, 4523 flags: []string{"-expect-server-key-exchange-hash", strconv.Itoa(int(hash.id))}, 4524 }) 4525 } 4526 4527 // Test that hash resolution takes the signature type into account. 4528 testCases = append(testCases, testCase{ 4529 name: "SigningHash-ClientAuth-SignatureType", 4530 config: Config{ 4531 ClientAuth: RequireAnyClientCert, 4532 SignatureAndHashes: []signatureAndHash{ 4533 {signatureECDSA, hashSHA512}, 4534 {signatureRSA, hashSHA384}, 4535 {signatureECDSA, hashSHA1}, 4536 }, 4537 }, 4538 flags: []string{ 4539 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4540 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4541 }, 4542 }) 4543 4544 testCases = append(testCases, testCase{ 4545 testType: serverTest, 4546 name: "SigningHash-ServerKeyExchange-SignatureType", 4547 config: Config{ 4548 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4549 SignatureAndHashes: []signatureAndHash{ 4550 {signatureECDSA, hashSHA512}, 4551 {signatureRSA, hashSHA384}, 4552 {signatureECDSA, hashSHA1}, 4553 }, 4554 }, 4555 }) 4556 4557 // Test that, if the list is missing, the peer falls back to SHA-1. 4558 testCases = append(testCases, testCase{ 4559 name: "SigningHash-ClientAuth-Fallback", 4560 config: Config{ 4561 ClientAuth: RequireAnyClientCert, 4562 SignatureAndHashes: []signatureAndHash{ 4563 {signatureRSA, hashSHA1}, 4564 }, 4565 Bugs: ProtocolBugs{ 4566 NoSignatureAndHashes: true, 4567 }, 4568 }, 4569 flags: []string{ 4570 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4571 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4572 }, 4573 }) 4574 4575 testCases = append(testCases, testCase{ 4576 testType: serverTest, 4577 name: "SigningHash-ServerKeyExchange-Fallback", 4578 config: Config{ 4579 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4580 SignatureAndHashes: []signatureAndHash{ 4581 {signatureRSA, hashSHA1}, 4582 }, 4583 Bugs: ProtocolBugs{ 4584 NoSignatureAndHashes: true, 4585 }, 4586 }, 4587 }) 4588 4589 // Test that hash preferences are enforced. BoringSSL defaults to 4590 // rejecting MD5 signatures. 4591 testCases = append(testCases, testCase{ 4592 testType: serverTest, 4593 name: "SigningHash-ClientAuth-Enforced", 4594 config: Config{ 4595 Certificates: []Certificate{rsaCertificate}, 4596 SignatureAndHashes: []signatureAndHash{ 4597 {signatureRSA, hashMD5}, 4598 // Advertise SHA-1 so the handshake will 4599 // proceed, but the shim's preferences will be 4600 // ignored in CertificateVerify generation, so 4601 // MD5 will be chosen. 4602 {signatureRSA, hashSHA1}, 4603 }, 4604 Bugs: ProtocolBugs{ 4605 IgnorePeerSignatureAlgorithmPreferences: true, 4606 }, 4607 }, 4608 flags: []string{"-require-any-client-certificate"}, 4609 shouldFail: true, 4610 expectedError: ":WRONG_SIGNATURE_TYPE:", 4611 }) 4612 4613 testCases = append(testCases, testCase{ 4614 name: "SigningHash-ServerKeyExchange-Enforced", 4615 config: Config{ 4616 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4617 SignatureAndHashes: []signatureAndHash{ 4618 {signatureRSA, hashMD5}, 4619 }, 4620 Bugs: ProtocolBugs{ 4621 IgnorePeerSignatureAlgorithmPreferences: true, 4622 }, 4623 }, 4624 shouldFail: true, 4625 expectedError: ":WRONG_SIGNATURE_TYPE:", 4626 }) 4627 4628 // Test that the agreed upon digest respects the client preferences and 4629 // the server digests. 4630 testCases = append(testCases, testCase{ 4631 name: "Agree-Digest-Fallback", 4632 config: Config{ 4633 ClientAuth: RequireAnyClientCert, 4634 SignatureAndHashes: []signatureAndHash{ 4635 {signatureRSA, hashSHA512}, 4636 {signatureRSA, hashSHA1}, 4637 }, 4638 }, 4639 flags: []string{ 4640 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4641 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4642 }, 4643 digestPrefs: "SHA256", 4644 expectedClientCertSignatureHash: hashSHA1, 4645 }) 4646 testCases = append(testCases, testCase{ 4647 name: "Agree-Digest-SHA256", 4648 config: Config{ 4649 ClientAuth: RequireAnyClientCert, 4650 SignatureAndHashes: []signatureAndHash{ 4651 {signatureRSA, hashSHA1}, 4652 {signatureRSA, hashSHA256}, 4653 }, 4654 }, 4655 flags: []string{ 4656 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4657 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4658 }, 4659 digestPrefs: "SHA256,SHA1", 4660 expectedClientCertSignatureHash: hashSHA256, 4661 }) 4662 testCases = append(testCases, testCase{ 4663 name: "Agree-Digest-SHA1", 4664 config: Config{ 4665 ClientAuth: RequireAnyClientCert, 4666 SignatureAndHashes: []signatureAndHash{ 4667 {signatureRSA, hashSHA1}, 4668 }, 4669 }, 4670 flags: []string{ 4671 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4672 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4673 }, 4674 digestPrefs: "SHA512,SHA256,SHA1", 4675 expectedClientCertSignatureHash: hashSHA1, 4676 }) 4677 testCases = append(testCases, testCase{ 4678 name: "Agree-Digest-Default", 4679 config: Config{ 4680 ClientAuth: RequireAnyClientCert, 4681 SignatureAndHashes: []signatureAndHash{ 4682 {signatureRSA, hashSHA256}, 4683 {signatureECDSA, hashSHA256}, 4684 {signatureRSA, hashSHA1}, 4685 {signatureECDSA, hashSHA1}, 4686 }, 4687 }, 4688 flags: []string{ 4689 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4690 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4691 }, 4692 expectedClientCertSignatureHash: hashSHA256, 4693 }) 4694} 4695 4696// timeouts is the retransmit schedule for BoringSSL. It doubles and 4697// caps at 60 seconds. On the 13th timeout, it gives up. 4698var timeouts = []time.Duration{ 4699 1 * time.Second, 4700 2 * time.Second, 4701 4 * time.Second, 4702 8 * time.Second, 4703 16 * time.Second, 4704 32 * time.Second, 4705 60 * time.Second, 4706 60 * time.Second, 4707 60 * time.Second, 4708 60 * time.Second, 4709 60 * time.Second, 4710 60 * time.Second, 4711 60 * time.Second, 4712} 4713 4714// shortTimeouts is an alternate set of timeouts which would occur if the 4715// initial timeout duration was set to 250ms. 4716var shortTimeouts = []time.Duration{ 4717 250 * time.Millisecond, 4718 500 * time.Millisecond, 4719 1 * time.Second, 4720 2 * time.Second, 4721 4 * time.Second, 4722 8 * time.Second, 4723 16 * time.Second, 4724 32 * time.Second, 4725 60 * time.Second, 4726 60 * time.Second, 4727 60 * time.Second, 4728 60 * time.Second, 4729 60 * time.Second, 4730} 4731 4732func addDTLSRetransmitTests() { 4733 // These tests work by coordinating some behavior on both the shim and 4734 // the runner. 4735 // 4736 // TimeoutSchedule configures the runner to send a series of timeout 4737 // opcodes to the shim (see packetAdaptor) immediately before reading 4738 // each peer handshake flight N. The timeout opcode both simulates a 4739 // timeout in the shim and acts as a synchronization point to help the 4740 // runner bracket each handshake flight. 4741 // 4742 // We assume the shim does not read from the channel eagerly. It must 4743 // first wait until it has sent flight N and is ready to receive 4744 // handshake flight N+1. At this point, it will process the timeout 4745 // opcode. It must then immediately respond with a timeout ACK and act 4746 // as if the shim was idle for the specified amount of time. 4747 // 4748 // The runner then drops all packets received before the ACK and 4749 // continues waiting for flight N. This ordering results in one attempt 4750 // at sending flight N to be dropped. For the test to complete, the 4751 // shim must send flight N again, testing that the shim implements DTLS 4752 // retransmit on a timeout. 4753 4754 for _, async := range []bool{true, false} { 4755 var tests []testCase 4756 4757 // Test that this is indeed the timeout schedule. Stress all 4758 // four patterns of handshake. 4759 for i := 1; i < len(timeouts); i++ { 4760 number := strconv.Itoa(i) 4761 tests = append(tests, testCase{ 4762 protocol: dtls, 4763 name: "DTLS-Retransmit-Client-" + number, 4764 config: Config{ 4765 Bugs: ProtocolBugs{ 4766 TimeoutSchedule: timeouts[:i], 4767 }, 4768 }, 4769 resumeSession: true, 4770 }) 4771 tests = append(tests, testCase{ 4772 protocol: dtls, 4773 testType: serverTest, 4774 name: "DTLS-Retransmit-Server-" + number, 4775 config: Config{ 4776 Bugs: ProtocolBugs{ 4777 TimeoutSchedule: timeouts[:i], 4778 }, 4779 }, 4780 resumeSession: true, 4781 }) 4782 } 4783 4784 // Test that exceeding the timeout schedule hits a read 4785 // timeout. 4786 tests = append(tests, testCase{ 4787 protocol: dtls, 4788 name: "DTLS-Retransmit-Timeout", 4789 config: Config{ 4790 Bugs: ProtocolBugs{ 4791 TimeoutSchedule: timeouts, 4792 }, 4793 }, 4794 resumeSession: true, 4795 shouldFail: true, 4796 expectedError: ":READ_TIMEOUT_EXPIRED:", 4797 }) 4798 4799 if async { 4800 // Test that timeout handling has a fudge factor, due to API 4801 // problems. 4802 tests = append(tests, testCase{ 4803 protocol: dtls, 4804 name: "DTLS-Retransmit-Fudge", 4805 config: Config{ 4806 Bugs: ProtocolBugs{ 4807 TimeoutSchedule: []time.Duration{ 4808 timeouts[0] - 10*time.Millisecond, 4809 }, 4810 }, 4811 }, 4812 resumeSession: true, 4813 }) 4814 } 4815 4816 // Test that the final Finished retransmitting isn't 4817 // duplicated if the peer badly fragments everything. 4818 tests = append(tests, testCase{ 4819 testType: serverTest, 4820 protocol: dtls, 4821 name: "DTLS-Retransmit-Fragmented", 4822 config: Config{ 4823 Bugs: ProtocolBugs{ 4824 TimeoutSchedule: []time.Duration{timeouts[0]}, 4825 MaxHandshakeRecordLength: 2, 4826 }, 4827 }, 4828 }) 4829 4830 // Test the timeout schedule when a shorter initial timeout duration is set. 4831 tests = append(tests, testCase{ 4832 protocol: dtls, 4833 name: "DTLS-Retransmit-Short-Client", 4834 config: Config{ 4835 Bugs: ProtocolBugs{ 4836 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 4837 }, 4838 }, 4839 resumeSession: true, 4840 flags: []string{"-initial-timeout-duration-ms", "250"}, 4841 }) 4842 tests = append(tests, testCase{ 4843 protocol: dtls, 4844 testType: serverTest, 4845 name: "DTLS-Retransmit-Short-Server", 4846 config: Config{ 4847 Bugs: ProtocolBugs{ 4848 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 4849 }, 4850 }, 4851 resumeSession: true, 4852 flags: []string{"-initial-timeout-duration-ms", "250"}, 4853 }) 4854 4855 for _, test := range tests { 4856 if async { 4857 test.name += "-Async" 4858 test.flags = append(test.flags, "-async") 4859 } 4860 4861 testCases = append(testCases, test) 4862 } 4863 } 4864} 4865 4866func addExportKeyingMaterialTests() { 4867 for _, vers := range tlsVersions { 4868 if vers.version == VersionSSL30 { 4869 continue 4870 } 4871 testCases = append(testCases, testCase{ 4872 name: "ExportKeyingMaterial-" + vers.name, 4873 config: Config{ 4874 MaxVersion: vers.version, 4875 }, 4876 exportKeyingMaterial: 1024, 4877 exportLabel: "label", 4878 exportContext: "context", 4879 useExportContext: true, 4880 }) 4881 testCases = append(testCases, testCase{ 4882 name: "ExportKeyingMaterial-NoContext-" + vers.name, 4883 config: Config{ 4884 MaxVersion: vers.version, 4885 }, 4886 exportKeyingMaterial: 1024, 4887 }) 4888 testCases = append(testCases, testCase{ 4889 name: "ExportKeyingMaterial-EmptyContext-" + vers.name, 4890 config: Config{ 4891 MaxVersion: vers.version, 4892 }, 4893 exportKeyingMaterial: 1024, 4894 useExportContext: true, 4895 }) 4896 testCases = append(testCases, testCase{ 4897 name: "ExportKeyingMaterial-Small-" + vers.name, 4898 config: Config{ 4899 MaxVersion: vers.version, 4900 }, 4901 exportKeyingMaterial: 1, 4902 exportLabel: "label", 4903 exportContext: "context", 4904 useExportContext: true, 4905 }) 4906 } 4907 testCases = append(testCases, testCase{ 4908 name: "ExportKeyingMaterial-SSL3", 4909 config: Config{ 4910 MaxVersion: VersionSSL30, 4911 }, 4912 exportKeyingMaterial: 1024, 4913 exportLabel: "label", 4914 exportContext: "context", 4915 useExportContext: true, 4916 shouldFail: true, 4917 expectedError: "failed to export keying material", 4918 }) 4919} 4920 4921func addTLSUniqueTests() { 4922 for _, isClient := range []bool{false, true} { 4923 for _, isResumption := range []bool{false, true} { 4924 for _, hasEMS := range []bool{false, true} { 4925 var suffix string 4926 if isResumption { 4927 suffix = "Resume-" 4928 } else { 4929 suffix = "Full-" 4930 } 4931 4932 if hasEMS { 4933 suffix += "EMS-" 4934 } else { 4935 suffix += "NoEMS-" 4936 } 4937 4938 if isClient { 4939 suffix += "Client" 4940 } else { 4941 suffix += "Server" 4942 } 4943 4944 test := testCase{ 4945 name: "TLSUnique-" + suffix, 4946 testTLSUnique: true, 4947 config: Config{ 4948 Bugs: ProtocolBugs{ 4949 NoExtendedMasterSecret: !hasEMS, 4950 }, 4951 }, 4952 } 4953 4954 if isResumption { 4955 test.resumeSession = true 4956 test.resumeConfig = &Config{ 4957 Bugs: ProtocolBugs{ 4958 NoExtendedMasterSecret: !hasEMS, 4959 }, 4960 } 4961 } 4962 4963 if isResumption && !hasEMS { 4964 test.shouldFail = true 4965 test.expectedError = "failed to get tls-unique" 4966 } 4967 4968 testCases = append(testCases, test) 4969 } 4970 } 4971 } 4972} 4973 4974func addCustomExtensionTests() { 4975 expectedContents := "custom extension" 4976 emptyString := "" 4977 4978 for _, isClient := range []bool{false, true} { 4979 suffix := "Server" 4980 flag := "-enable-server-custom-extension" 4981 testType := serverTest 4982 if isClient { 4983 suffix = "Client" 4984 flag = "-enable-client-custom-extension" 4985 testType = clientTest 4986 } 4987 4988 testCases = append(testCases, testCase{ 4989 testType: testType, 4990 name: "CustomExtensions-" + suffix, 4991 config: Config{ 4992 Bugs: ProtocolBugs{ 4993 CustomExtension: expectedContents, 4994 ExpectedCustomExtension: &expectedContents, 4995 }, 4996 }, 4997 flags: []string{flag}, 4998 }) 4999 5000 // If the parse callback fails, the handshake should also fail. 5001 testCases = append(testCases, testCase{ 5002 testType: testType, 5003 name: "CustomExtensions-ParseError-" + suffix, 5004 config: Config{ 5005 Bugs: ProtocolBugs{ 5006 CustomExtension: expectedContents + "foo", 5007 ExpectedCustomExtension: &expectedContents, 5008 }, 5009 }, 5010 flags: []string{flag}, 5011 shouldFail: true, 5012 expectedError: ":CUSTOM_EXTENSION_ERROR:", 5013 }) 5014 5015 // If the add callback fails, the handshake should also fail. 5016 testCases = append(testCases, testCase{ 5017 testType: testType, 5018 name: "CustomExtensions-FailAdd-" + suffix, 5019 config: Config{ 5020 Bugs: ProtocolBugs{ 5021 CustomExtension: expectedContents, 5022 ExpectedCustomExtension: &expectedContents, 5023 }, 5024 }, 5025 flags: []string{flag, "-custom-extension-fail-add"}, 5026 shouldFail: true, 5027 expectedError: ":CUSTOM_EXTENSION_ERROR:", 5028 }) 5029 5030 // If the add callback returns zero, no extension should be 5031 // added. 5032 skipCustomExtension := expectedContents 5033 if isClient { 5034 // For the case where the client skips sending the 5035 // custom extension, the server must not “echo” it. 5036 skipCustomExtension = "" 5037 } 5038 testCases = append(testCases, testCase{ 5039 testType: testType, 5040 name: "CustomExtensions-Skip-" + suffix, 5041 config: Config{ 5042 Bugs: ProtocolBugs{ 5043 CustomExtension: skipCustomExtension, 5044 ExpectedCustomExtension: &emptyString, 5045 }, 5046 }, 5047 flags: []string{flag, "-custom-extension-skip"}, 5048 }) 5049 } 5050 5051 // The custom extension add callback should not be called if the client 5052 // doesn't send the extension. 5053 testCases = append(testCases, testCase{ 5054 testType: serverTest, 5055 name: "CustomExtensions-NotCalled-Server", 5056 config: Config{ 5057 Bugs: ProtocolBugs{ 5058 ExpectedCustomExtension: &emptyString, 5059 }, 5060 }, 5061 flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"}, 5062 }) 5063 5064 // Test an unknown extension from the server. 5065 testCases = append(testCases, testCase{ 5066 testType: clientTest, 5067 name: "UnknownExtension-Client", 5068 config: Config{ 5069 Bugs: ProtocolBugs{ 5070 CustomExtension: expectedContents, 5071 }, 5072 }, 5073 shouldFail: true, 5074 expectedError: ":UNEXPECTED_EXTENSION:", 5075 }) 5076} 5077 5078func addRSAClientKeyExchangeTests() { 5079 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ { 5080 testCases = append(testCases, testCase{ 5081 testType: serverTest, 5082 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad), 5083 config: Config{ 5084 // Ensure the ClientHello version and final 5085 // version are different, to detect if the 5086 // server uses the wrong one. 5087 MaxVersion: VersionTLS11, 5088 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, 5089 Bugs: ProtocolBugs{ 5090 BadRSAClientKeyExchange: bad, 5091 }, 5092 }, 5093 shouldFail: true, 5094 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 5095 }) 5096 } 5097} 5098 5099var testCurves = []struct { 5100 name string 5101 id CurveID 5102}{ 5103 {"P-256", CurveP256}, 5104 {"P-384", CurveP384}, 5105 {"P-521", CurveP521}, 5106 {"X25519", CurveX25519}, 5107} 5108 5109func addCurveTests() { 5110 for _, curve := range testCurves { 5111 testCases = append(testCases, testCase{ 5112 name: "CurveTest-Client-" + curve.name, 5113 config: Config{ 5114 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5115 CurvePreferences: []CurveID{curve.id}, 5116 }, 5117 flags: []string{"-enable-all-curves"}, 5118 }) 5119 testCases = append(testCases, testCase{ 5120 testType: serverTest, 5121 name: "CurveTest-Server-" + curve.name, 5122 config: Config{ 5123 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5124 CurvePreferences: []CurveID{curve.id}, 5125 }, 5126 flags: []string{"-enable-all-curves"}, 5127 }) 5128 } 5129 5130 // The server must be tolerant to bogus curves. 5131 const bogusCurve = 0x1234 5132 testCases = append(testCases, testCase{ 5133 testType: serverTest, 5134 name: "UnknownCurve", 5135 config: Config{ 5136 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5137 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 5138 }, 5139 }) 5140} 5141 5142func addCECPQ1Tests() { 5143 testCases = append(testCases, testCase{ 5144 testType: clientTest, 5145 name: "CECPQ1-Client-BadX25519Part", 5146 config: Config{ 5147 MinVersion: VersionTLS12, 5148 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, 5149 Bugs: ProtocolBugs{ 5150 CECPQ1BadX25519Part: true, 5151 }, 5152 }, 5153 flags: []string{"-cipher", "kCECPQ1"}, 5154 shouldFail: true, 5155 expectedLocalError: "local error: bad record MAC", 5156 }) 5157 testCases = append(testCases, testCase{ 5158 testType: clientTest, 5159 name: "CECPQ1-Client-BadNewhopePart", 5160 config: Config{ 5161 MinVersion: VersionTLS12, 5162 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, 5163 Bugs: ProtocolBugs{ 5164 CECPQ1BadNewhopePart: true, 5165 }, 5166 }, 5167 flags: []string{"-cipher", "kCECPQ1"}, 5168 shouldFail: true, 5169 expectedLocalError: "local error: bad record MAC", 5170 }) 5171 testCases = append(testCases, testCase{ 5172 testType: serverTest, 5173 name: "CECPQ1-Server-BadX25519Part", 5174 config: Config{ 5175 MinVersion: VersionTLS12, 5176 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, 5177 Bugs: ProtocolBugs{ 5178 CECPQ1BadX25519Part: true, 5179 }, 5180 }, 5181 flags: []string{"-cipher", "kCECPQ1"}, 5182 shouldFail: true, 5183 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 5184 }) 5185 testCases = append(testCases, testCase{ 5186 testType: serverTest, 5187 name: "CECPQ1-Server-BadNewhopePart", 5188 config: Config{ 5189 MinVersion: VersionTLS12, 5190 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, 5191 Bugs: ProtocolBugs{ 5192 CECPQ1BadNewhopePart: true, 5193 }, 5194 }, 5195 flags: []string{"-cipher", "kCECPQ1"}, 5196 shouldFail: true, 5197 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 5198 }) 5199} 5200 5201func addKeyExchangeInfoTests() { 5202 testCases = append(testCases, testCase{ 5203 name: "KeyExchangeInfo-RSA-Client", 5204 config: Config{ 5205 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 5206 }, 5207 // key.pem is a 1024-bit RSA key. 5208 flags: []string{"-expect-key-exchange-info", "1024"}, 5209 }) 5210 // TODO(davidben): key_exchange_info doesn't work for plain RSA on the 5211 // server. Either fix this or change the API as it's not very useful in 5212 // this case. 5213 5214 testCases = append(testCases, testCase{ 5215 name: "KeyExchangeInfo-DHE-Client", 5216 config: Config{ 5217 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 5218 Bugs: ProtocolBugs{ 5219 // This is a 1234-bit prime number, generated 5220 // with: 5221 // openssl gendh 1234 | openssl asn1parse -i 5222 DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"), 5223 }, 5224 }, 5225 flags: []string{"-expect-key-exchange-info", "1234"}, 5226 }) 5227 testCases = append(testCases, testCase{ 5228 testType: serverTest, 5229 name: "KeyExchangeInfo-DHE-Server", 5230 config: Config{ 5231 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, 5232 }, 5233 // bssl_shim as a server configures a 2048-bit DHE group. 5234 flags: []string{"-expect-key-exchange-info", "2048"}, 5235 }) 5236 5237 testCases = append(testCases, testCase{ 5238 name: "KeyExchangeInfo-ECDHE-Client", 5239 config: Config{ 5240 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5241 CurvePreferences: []CurveID{CurveX25519}, 5242 }, 5243 flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"}, 5244 }) 5245 testCases = append(testCases, testCase{ 5246 testType: serverTest, 5247 name: "KeyExchangeInfo-ECDHE-Server", 5248 config: Config{ 5249 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5250 CurvePreferences: []CurveID{CurveX25519}, 5251 }, 5252 flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"}, 5253 }) 5254} 5255 5256func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { 5257 defer wg.Done() 5258 5259 for test := range c { 5260 var err error 5261 5262 if *mallocTest < 0 { 5263 statusChan <- statusMsg{test: test, started: true} 5264 err = runTest(test, shimPath, -1) 5265 } else { 5266 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ { 5267 statusChan <- statusMsg{test: test, started: true} 5268 if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs { 5269 if err != nil { 5270 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err) 5271 } 5272 break 5273 } 5274 } 5275 } 5276 statusChan <- statusMsg{test: test, err: err} 5277 } 5278} 5279 5280type statusMsg struct { 5281 test *testCase 5282 started bool 5283 err error 5284} 5285 5286func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total int) { 5287 var started, done, failed, lineLen int 5288 5289 testOutput := newTestOutput() 5290 for msg := range statusChan { 5291 if !*pipe { 5292 // Erase the previous status line. 5293 var erase string 5294 for i := 0; i < lineLen; i++ { 5295 erase += "\b \b" 5296 } 5297 fmt.Print(erase) 5298 } 5299 5300 if msg.started { 5301 started++ 5302 } else { 5303 done++ 5304 5305 if msg.err != nil { 5306 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err) 5307 failed++ 5308 testOutput.addResult(msg.test.name, "FAIL") 5309 } else { 5310 if *pipe { 5311 // Print each test instead of a status line. 5312 fmt.Printf("PASSED (%s)\n", msg.test.name) 5313 } 5314 testOutput.addResult(msg.test.name, "PASS") 5315 } 5316 } 5317 5318 if !*pipe { 5319 // Print a new status line. 5320 line := fmt.Sprintf("%d/%d/%d/%d", failed, done, started, total) 5321 lineLen = len(line) 5322 os.Stdout.WriteString(line) 5323 } 5324 } 5325 5326 doneChan <- testOutput 5327} 5328 5329func main() { 5330 flag.Parse() 5331 *resourceDir = path.Clean(*resourceDir) 5332 5333 addBasicTests() 5334 addCipherSuiteTests() 5335 addBadECDSASignatureTests() 5336 addCBCPaddingTests() 5337 addCBCSplittingTests() 5338 addClientAuthTests() 5339 addDDoSCallbackTests() 5340 addVersionNegotiationTests() 5341 addMinimumVersionTests() 5342 addExtensionTests() 5343 addResumptionVersionTests() 5344 addExtendedMasterSecretTests() 5345 addRenegotiationTests() 5346 addDTLSReplayTests() 5347 addSigningHashTests() 5348 addDTLSRetransmitTests() 5349 addExportKeyingMaterialTests() 5350 addTLSUniqueTests() 5351 addCustomExtensionTests() 5352 addRSAClientKeyExchangeTests() 5353 addCurveTests() 5354 addCECPQ1Tests() 5355 addKeyExchangeInfoTests() 5356 for _, async := range []bool{false, true} { 5357 for _, splitHandshake := range []bool{false, true} { 5358 for _, protocol := range []protocol{tls, dtls} { 5359 addStateMachineCoverageTests(async, splitHandshake, protocol) 5360 } 5361 } 5362 } 5363 5364 var wg sync.WaitGroup 5365 5366 statusChan := make(chan statusMsg, *numWorkers) 5367 testChan := make(chan *testCase, *numWorkers) 5368 doneChan := make(chan *testOutput) 5369 5370 go statusPrinter(doneChan, statusChan, len(testCases)) 5371 5372 for i := 0; i < *numWorkers; i++ { 5373 wg.Add(1) 5374 go worker(statusChan, testChan, *shimPath, &wg) 5375 } 5376 5377 var foundTest bool 5378 for i := range testCases { 5379 if len(*testToRun) == 0 || *testToRun == testCases[i].name { 5380 foundTest = true 5381 testChan <- &testCases[i] 5382 } 5383 } 5384 if !foundTest { 5385 fmt.Fprintf(os.Stderr, "No test named '%s'\n", *testToRun) 5386 os.Exit(1) 5387 } 5388 5389 close(testChan) 5390 wg.Wait() 5391 close(statusChan) 5392 testOutput := <-doneChan 5393 5394 fmt.Printf("\n") 5395 5396 if *jsonOutput != "" { 5397 if err := testOutput.writeTo(*jsonOutput); err != nil { 5398 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 5399 } 5400 } 5401 5402 if !testOutput.allPassed { 5403 os.Exit(1) 5404 } 5405} 5406