Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

3935 строки
102 KiB

  1. package main
  2. import (
  3. "bytes"
  4. "crypto/ecdsa"
  5. "crypto/elliptic"
  6. "crypto/x509"
  7. "encoding/base64"
  8. "encoding/pem"
  9. "flag"
  10. "fmt"
  11. "io"
  12. "io/ioutil"
  13. "math/big"
  14. "net"
  15. "os"
  16. "os/exec"
  17. "path"
  18. "runtime"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. "syscall"
  23. "time"
  24. )
  25. var (
  26. useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
  27. useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
  28. flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection")
  29. mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
  30. 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.")
  31. jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
  32. pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
  33. testToRun = flag.String("test", "", "The name of a test to run, or empty to run all tests")
  34. numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
  35. shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
  36. resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
  37. )
  38. const (
  39. rsaCertificateFile = "cert.pem"
  40. ecdsaCertificateFile = "ecdsa_cert.pem"
  41. )
  42. const (
  43. rsaKeyFile = "key.pem"
  44. ecdsaKeyFile = "ecdsa_key.pem"
  45. channelIDKeyFile = "channel_id_key.pem"
  46. )
  47. var rsaCertificate, ecdsaCertificate Certificate
  48. var channelIDKey *ecdsa.PrivateKey
  49. var channelIDBytes []byte
  50. var testOCSPResponse = []byte{1, 2, 3, 4}
  51. var testSCTList = []byte{5, 6, 7, 8}
  52. func initCertificates() {
  53. var err error
  54. rsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, rsaCertificateFile), path.Join(*resourceDir, rsaKeyFile))
  55. if err != nil {
  56. panic(err)
  57. }
  58. rsaCertificate.OCSPStaple = testOCSPResponse
  59. rsaCertificate.SignedCertificateTimestampList = testSCTList
  60. ecdsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, ecdsaCertificateFile), path.Join(*resourceDir, ecdsaKeyFile))
  61. if err != nil {
  62. panic(err)
  63. }
  64. ecdsaCertificate.OCSPStaple = testOCSPResponse
  65. ecdsaCertificate.SignedCertificateTimestampList = testSCTList
  66. channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
  67. if err != nil {
  68. panic(err)
  69. }
  70. channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock)
  71. if channelIDDERBlock.Type != "EC PRIVATE KEY" {
  72. panic("bad key type")
  73. }
  74. channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes)
  75. if err != nil {
  76. panic(err)
  77. }
  78. if channelIDKey.Curve != elliptic.P256() {
  79. panic("bad curve")
  80. }
  81. channelIDBytes = make([]byte, 64)
  82. writeIntPadded(channelIDBytes[:32], channelIDKey.X)
  83. writeIntPadded(channelIDBytes[32:], channelIDKey.Y)
  84. }
  85. var certificateOnce sync.Once
  86. func getRSACertificate() Certificate {
  87. certificateOnce.Do(initCertificates)
  88. return rsaCertificate
  89. }
  90. func getECDSACertificate() Certificate {
  91. certificateOnce.Do(initCertificates)
  92. return ecdsaCertificate
  93. }
  94. type testType int
  95. const (
  96. clientTest testType = iota
  97. serverTest
  98. )
  99. type protocol int
  100. const (
  101. tls protocol = iota
  102. dtls
  103. )
  104. const (
  105. alpn = 1
  106. npn = 2
  107. )
  108. type testCase struct {
  109. testType testType
  110. protocol protocol
  111. name string
  112. config Config
  113. shouldFail bool
  114. expectedError string
  115. // expectedLocalError, if not empty, contains a substring that must be
  116. // found in the local error.
  117. expectedLocalError string
  118. // expectedVersion, if non-zero, specifies the TLS version that must be
  119. // negotiated.
  120. expectedVersion uint16
  121. // expectedResumeVersion, if non-zero, specifies the TLS version that
  122. // must be negotiated on resumption. If zero, expectedVersion is used.
  123. expectedResumeVersion uint16
  124. // expectedCipher, if non-zero, specifies the TLS cipher suite that
  125. // should be negotiated.
  126. expectedCipher uint16
  127. // expectChannelID controls whether the connection should have
  128. // negotiated a Channel ID with channelIDKey.
  129. expectChannelID bool
  130. // expectedNextProto controls whether the connection should
  131. // negotiate a next protocol via NPN or ALPN.
  132. expectedNextProto string
  133. // expectedNextProtoType, if non-zero, is the expected next
  134. // protocol negotiation mechanism.
  135. expectedNextProtoType int
  136. // expectedSRTPProtectionProfile is the DTLS-SRTP profile that
  137. // should be negotiated. If zero, none should be negotiated.
  138. expectedSRTPProtectionProfile uint16
  139. // messageLen is the length, in bytes, of the test message that will be
  140. // sent.
  141. messageLen int
  142. // messageCount is the number of test messages that will be sent.
  143. messageCount int
  144. // certFile is the path to the certificate to use for the server.
  145. certFile string
  146. // keyFile is the path to the private key to use for the server.
  147. keyFile string
  148. // resumeSession controls whether a second connection should be tested
  149. // which attempts to resume the first session.
  150. resumeSession bool
  151. // expectResumeRejected, if true, specifies that the attempted
  152. // resumption must be rejected by the client. This is only valid for a
  153. // serverTest.
  154. expectResumeRejected bool
  155. // resumeConfig, if not nil, points to a Config to be used on
  156. // resumption. Unless newSessionsOnResume is set,
  157. // SessionTicketKey, ServerSessionCache, and
  158. // ClientSessionCache are copied from the initial connection's
  159. // config. If nil, the initial connection's config is used.
  160. resumeConfig *Config
  161. // newSessionsOnResume, if true, will cause resumeConfig to
  162. // use a different session resumption context.
  163. newSessionsOnResume bool
  164. // noSessionCache, if true, will cause the server to run without a
  165. // session cache.
  166. noSessionCache bool
  167. // sendPrefix sends a prefix on the socket before actually performing a
  168. // handshake.
  169. sendPrefix string
  170. // shimWritesFirst controls whether the shim sends an initial "hello"
  171. // message before doing a roundtrip with the runner.
  172. shimWritesFirst bool
  173. // renegotiate indicates the the connection should be renegotiated
  174. // during the exchange.
  175. renegotiate bool
  176. // renegotiateCiphers is a list of ciphersuite ids that will be
  177. // switched in just before renegotiation.
  178. renegotiateCiphers []uint16
  179. // replayWrites, if true, configures the underlying transport
  180. // to replay every write it makes in DTLS tests.
  181. replayWrites bool
  182. // damageFirstWrite, if true, configures the underlying transport to
  183. // damage the final byte of the first application data write.
  184. damageFirstWrite bool
  185. // exportKeyingMaterial, if non-zero, configures the test to exchange
  186. // keying material and verify they match.
  187. exportKeyingMaterial int
  188. exportLabel string
  189. exportContext string
  190. useExportContext bool
  191. // flags, if not empty, contains a list of command-line flags that will
  192. // be passed to the shim program.
  193. flags []string
  194. // testTLSUnique, if true, causes the shim to send the tls-unique value
  195. // which will be compared against the expected value.
  196. testTLSUnique bool
  197. // sendEmptyRecords is the number of consecutive empty records to send
  198. // before and after the test message.
  199. sendEmptyRecords int
  200. // sendWarningAlerts is the number of consecutive warning alerts to send
  201. // before and after the test message.
  202. sendWarningAlerts int
  203. }
  204. var testCases []testCase
  205. func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
  206. var connDebug *recordingConn
  207. var connDamage *damageAdaptor
  208. if *flagDebug {
  209. connDebug = &recordingConn{Conn: conn}
  210. conn = connDebug
  211. defer func() {
  212. connDebug.WriteTo(os.Stdout)
  213. }()
  214. }
  215. if test.protocol == dtls {
  216. config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
  217. conn = config.Bugs.PacketAdaptor
  218. if test.replayWrites {
  219. conn = newReplayAdaptor(conn)
  220. }
  221. }
  222. if test.damageFirstWrite {
  223. connDamage = newDamageAdaptor(conn)
  224. conn = connDamage
  225. }
  226. if test.sendPrefix != "" {
  227. if _, err := conn.Write([]byte(test.sendPrefix)); err != nil {
  228. return err
  229. }
  230. }
  231. var tlsConn *Conn
  232. if test.testType == clientTest {
  233. if test.protocol == dtls {
  234. tlsConn = DTLSServer(conn, config)
  235. } else {
  236. tlsConn = Server(conn, config)
  237. }
  238. } else {
  239. config.InsecureSkipVerify = true
  240. if test.protocol == dtls {
  241. tlsConn = DTLSClient(conn, config)
  242. } else {
  243. tlsConn = Client(conn, config)
  244. }
  245. }
  246. if err := tlsConn.Handshake(); err != nil {
  247. return err
  248. }
  249. // TODO(davidben): move all per-connection expectations into a dedicated
  250. // expectations struct that can be specified separately for the two
  251. // legs.
  252. expectedVersion := test.expectedVersion
  253. if isResume && test.expectedResumeVersion != 0 {
  254. expectedVersion = test.expectedResumeVersion
  255. }
  256. connState := tlsConn.ConnectionState()
  257. if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion {
  258. return fmt.Errorf("got version %x, expected %x", vers, expectedVersion)
  259. }
  260. if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
  261. return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher)
  262. }
  263. if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
  264. return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
  265. }
  266. if test.expectChannelID {
  267. channelID := connState.ChannelID
  268. if channelID == nil {
  269. return fmt.Errorf("no channel ID negotiated")
  270. }
  271. if channelID.Curve != channelIDKey.Curve ||
  272. channelIDKey.X.Cmp(channelIDKey.X) != 0 ||
  273. channelIDKey.Y.Cmp(channelIDKey.Y) != 0 {
  274. return fmt.Errorf("incorrect channel ID")
  275. }
  276. }
  277. if expected := test.expectedNextProto; expected != "" {
  278. if actual := connState.NegotiatedProtocol; actual != expected {
  279. return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
  280. }
  281. }
  282. if test.expectedNextProtoType != 0 {
  283. if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
  284. return fmt.Errorf("next proto type mismatch")
  285. }
  286. }
  287. if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
  288. return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
  289. }
  290. if test.exportKeyingMaterial > 0 {
  291. actual := make([]byte, test.exportKeyingMaterial)
  292. if _, err := io.ReadFull(tlsConn, actual); err != nil {
  293. return err
  294. }
  295. expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext)
  296. if err != nil {
  297. return err
  298. }
  299. if !bytes.Equal(actual, expected) {
  300. return fmt.Errorf("keying material mismatch")
  301. }
  302. }
  303. if test.testTLSUnique {
  304. var peersValue [12]byte
  305. if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
  306. return err
  307. }
  308. expected := tlsConn.ConnectionState().TLSUnique
  309. if !bytes.Equal(peersValue[:], expected) {
  310. return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
  311. }
  312. }
  313. if test.shimWritesFirst {
  314. var buf [5]byte
  315. _, err := io.ReadFull(tlsConn, buf[:])
  316. if err != nil {
  317. return err
  318. }
  319. if string(buf[:]) != "hello" {
  320. return fmt.Errorf("bad initial message")
  321. }
  322. }
  323. for i := 0; i < test.sendEmptyRecords; i++ {
  324. tlsConn.Write(nil)
  325. }
  326. for i := 0; i < test.sendWarningAlerts; i++ {
  327. tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
  328. }
  329. if test.renegotiate {
  330. if test.renegotiateCiphers != nil {
  331. config.CipherSuites = test.renegotiateCiphers
  332. }
  333. if err := tlsConn.Renegotiate(); err != nil {
  334. return err
  335. }
  336. } else if test.renegotiateCiphers != nil {
  337. panic("renegotiateCiphers without renegotiate")
  338. }
  339. if test.damageFirstWrite {
  340. connDamage.setDamage(true)
  341. tlsConn.Write([]byte("DAMAGED WRITE"))
  342. connDamage.setDamage(false)
  343. }
  344. messageLen := test.messageLen
  345. if messageLen < 0 {
  346. if test.protocol == dtls {
  347. return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
  348. }
  349. // Read until EOF.
  350. _, err := io.Copy(ioutil.Discard, tlsConn)
  351. return err
  352. }
  353. if messageLen == 0 {
  354. messageLen = 32
  355. }
  356. messageCount := test.messageCount
  357. if messageCount == 0 {
  358. messageCount = 1
  359. }
  360. for j := 0; j < messageCount; j++ {
  361. testMessage := make([]byte, messageLen)
  362. for i := range testMessage {
  363. testMessage[i] = 0x42 ^ byte(j)
  364. }
  365. tlsConn.Write(testMessage)
  366. for i := 0; i < test.sendEmptyRecords; i++ {
  367. tlsConn.Write(nil)
  368. }
  369. for i := 0; i < test.sendWarningAlerts; i++ {
  370. tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
  371. }
  372. buf := make([]byte, len(testMessage))
  373. if test.protocol == dtls {
  374. bufTmp := make([]byte, len(buf)+1)
  375. n, err := tlsConn.Read(bufTmp)
  376. if err != nil {
  377. return err
  378. }
  379. if n != len(buf) {
  380. return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
  381. }
  382. copy(buf, bufTmp)
  383. } else {
  384. _, err := io.ReadFull(tlsConn, buf)
  385. if err != nil {
  386. return err
  387. }
  388. }
  389. for i, v := range buf {
  390. if v != testMessage[i]^0xff {
  391. return fmt.Errorf("bad reply contents at byte %d", i)
  392. }
  393. }
  394. }
  395. return nil
  396. }
  397. func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
  398. valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full"}
  399. if dbAttach {
  400. valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p")
  401. }
  402. valgrindArgs = append(valgrindArgs, path)
  403. valgrindArgs = append(valgrindArgs, args...)
  404. return exec.Command("valgrind", valgrindArgs...)
  405. }
  406. func gdbOf(path string, args ...string) *exec.Cmd {
  407. xtermArgs := []string{"-e", "gdb", "--args"}
  408. xtermArgs = append(xtermArgs, path)
  409. xtermArgs = append(xtermArgs, args...)
  410. return exec.Command("xterm", xtermArgs...)
  411. }
  412. type moreMallocsError struct{}
  413. func (moreMallocsError) Error() string {
  414. return "child process did not exhaust all allocation calls"
  415. }
  416. var errMoreMallocs = moreMallocsError{}
  417. // accept accepts a connection from listener, unless waitChan signals a process
  418. // exit first.
  419. func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error) {
  420. type connOrError struct {
  421. conn net.Conn
  422. err error
  423. }
  424. connChan := make(chan connOrError, 1)
  425. go func() {
  426. conn, err := listener.Accept()
  427. connChan <- connOrError{conn, err}
  428. close(connChan)
  429. }()
  430. select {
  431. case result := <-connChan:
  432. return result.conn, result.err
  433. case childErr := <-waitChan:
  434. waitChan <- childErr
  435. return nil, fmt.Errorf("child exited early: %s", childErr)
  436. }
  437. }
  438. func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
  439. if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
  440. panic("Error expected without shouldFail in " + test.name)
  441. }
  442. if test.expectResumeRejected && !test.resumeSession {
  443. panic("expectResumeRejected without resumeSession in " + test.name)
  444. }
  445. listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
  446. if err != nil {
  447. panic(err)
  448. }
  449. defer func() {
  450. if listener != nil {
  451. listener.Close()
  452. }
  453. }()
  454. flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
  455. if test.testType == serverTest {
  456. flags = append(flags, "-server")
  457. flags = append(flags, "-key-file")
  458. if test.keyFile == "" {
  459. flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
  460. } else {
  461. flags = append(flags, path.Join(*resourceDir, test.keyFile))
  462. }
  463. flags = append(flags, "-cert-file")
  464. if test.certFile == "" {
  465. flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
  466. } else {
  467. flags = append(flags, path.Join(*resourceDir, test.certFile))
  468. }
  469. }
  470. if test.protocol == dtls {
  471. flags = append(flags, "-dtls")
  472. }
  473. if test.resumeSession {
  474. flags = append(flags, "-resume")
  475. }
  476. if test.shimWritesFirst {
  477. flags = append(flags, "-shim-writes-first")
  478. }
  479. if test.exportKeyingMaterial > 0 {
  480. flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
  481. flags = append(flags, "-export-label", test.exportLabel)
  482. flags = append(flags, "-export-context", test.exportContext)
  483. if test.useExportContext {
  484. flags = append(flags, "-use-export-context")
  485. }
  486. }
  487. if test.expectResumeRejected {
  488. flags = append(flags, "-expect-session-miss")
  489. }
  490. if test.testTLSUnique {
  491. flags = append(flags, "-tls-unique")
  492. }
  493. flags = append(flags, test.flags...)
  494. var shim *exec.Cmd
  495. if *useValgrind {
  496. shim = valgrindOf(false, shimPath, flags...)
  497. } else if *useGDB {
  498. shim = gdbOf(shimPath, flags...)
  499. } else {
  500. shim = exec.Command(shimPath, flags...)
  501. }
  502. shim.Stdin = os.Stdin
  503. var stdoutBuf, stderrBuf bytes.Buffer
  504. shim.Stdout = &stdoutBuf
  505. shim.Stderr = &stderrBuf
  506. if mallocNumToFail >= 0 {
  507. shim.Env = os.Environ()
  508. shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
  509. if *mallocTestDebug {
  510. shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
  511. }
  512. shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
  513. }
  514. if err := shim.Start(); err != nil {
  515. panic(err)
  516. }
  517. waitChan := make(chan error, 1)
  518. go func() { waitChan <- shim.Wait() }()
  519. config := test.config
  520. if !test.noSessionCache {
  521. config.ClientSessionCache = NewLRUClientSessionCache(1)
  522. config.ServerSessionCache = NewLRUServerSessionCache(1)
  523. }
  524. if test.testType == clientTest {
  525. if len(config.Certificates) == 0 {
  526. config.Certificates = []Certificate{getRSACertificate()}
  527. }
  528. } else {
  529. // Supply a ServerName to ensure a constant session cache key,
  530. // rather than falling back to net.Conn.RemoteAddr.
  531. if len(config.ServerName) == 0 {
  532. config.ServerName = "test"
  533. }
  534. }
  535. conn, err := acceptOrWait(listener, waitChan)
  536. if err == nil {
  537. err = doExchange(test, &config, conn, false /* not a resumption */)
  538. conn.Close()
  539. }
  540. if err == nil && test.resumeSession {
  541. var resumeConfig Config
  542. if test.resumeConfig != nil {
  543. resumeConfig = *test.resumeConfig
  544. if len(resumeConfig.ServerName) == 0 {
  545. resumeConfig.ServerName = config.ServerName
  546. }
  547. if len(resumeConfig.Certificates) == 0 {
  548. resumeConfig.Certificates = []Certificate{getRSACertificate()}
  549. }
  550. if test.newSessionsOnResume {
  551. if !test.noSessionCache {
  552. resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
  553. resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
  554. }
  555. } else {
  556. resumeConfig.SessionTicketKey = config.SessionTicketKey
  557. resumeConfig.ClientSessionCache = config.ClientSessionCache
  558. resumeConfig.ServerSessionCache = config.ServerSessionCache
  559. }
  560. } else {
  561. resumeConfig = config
  562. }
  563. var connResume net.Conn
  564. connResume, err = acceptOrWait(listener, waitChan)
  565. if err == nil {
  566. err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
  567. connResume.Close()
  568. }
  569. }
  570. // Close the listener now. This is to avoid hangs should the shim try to
  571. // open more connections than expected.
  572. listener.Close()
  573. listener = nil
  574. childErr := <-waitChan
  575. if exitError, ok := childErr.(*exec.ExitError); ok {
  576. if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 {
  577. return errMoreMallocs
  578. }
  579. }
  580. stdout := string(stdoutBuf.Bytes())
  581. stderr := string(stderrBuf.Bytes())
  582. failed := err != nil || childErr != nil
  583. correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError)
  584. localError := "none"
  585. if err != nil {
  586. localError = err.Error()
  587. }
  588. if len(test.expectedLocalError) != 0 {
  589. correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
  590. }
  591. if failed != test.shouldFail || failed && !correctFailure {
  592. childError := "none"
  593. if childErr != nil {
  594. childError = childErr.Error()
  595. }
  596. var msg string
  597. switch {
  598. case failed && !test.shouldFail:
  599. msg = "unexpected failure"
  600. case !failed && test.shouldFail:
  601. msg = "unexpected success"
  602. case failed && !correctFailure:
  603. msg = "bad error (wanted '" + test.expectedError + "' / '" + test.expectedLocalError + "')"
  604. default:
  605. panic("internal error")
  606. }
  607. return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, stdout, stderr)
  608. }
  609. if !*useValgrind && !failed && len(stderr) > 0 {
  610. println(stderr)
  611. }
  612. return nil
  613. }
  614. var tlsVersions = []struct {
  615. name string
  616. version uint16
  617. flag string
  618. hasDTLS bool
  619. }{
  620. {"SSL3", VersionSSL30, "-no-ssl3", false},
  621. {"TLS1", VersionTLS10, "-no-tls1", true},
  622. {"TLS11", VersionTLS11, "-no-tls11", false},
  623. {"TLS12", VersionTLS12, "-no-tls12", true},
  624. }
  625. var testCipherSuites = []struct {
  626. name string
  627. id uint16
  628. }{
  629. {"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
  630. {"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256},
  631. {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
  632. {"AES128-SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256},
  633. {"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384},
  634. {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
  635. {"AES256-SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256},
  636. {"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
  637. {"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
  638. {"DHE-RSA-AES128-SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
  639. {"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
  640. {"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
  641. {"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
  642. {"DHE-RSA-CHACHA20-POLY1305", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
  643. {"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  644. {"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
  645. {"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
  646. {"ECDHE-ECDSA-AES256-GCM", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
  647. {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
  648. {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
  649. {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
  650. {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
  651. {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  652. {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  653. {"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
  654. {"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
  655. {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
  656. {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
  657. {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
  658. {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
  659. {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
  660. {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
  661. {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
  662. {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
  663. {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
  664. {"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
  665. {"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
  666. }
  667. func hasComponent(suiteName, component string) bool {
  668. return strings.Contains("-"+suiteName+"-", "-"+component+"-")
  669. }
  670. func isTLS12Only(suiteName string) bool {
  671. return hasComponent(suiteName, "GCM") ||
  672. hasComponent(suiteName, "SHA256") ||
  673. hasComponent(suiteName, "SHA384") ||
  674. hasComponent(suiteName, "POLY1305")
  675. }
  676. func isDTLSCipher(suiteName string) bool {
  677. return !hasComponent(suiteName, "RC4")
  678. }
  679. func bigFromHex(hex string) *big.Int {
  680. ret, ok := new(big.Int).SetString(hex, 16)
  681. if !ok {
  682. panic("failed to parse hex number 0x" + hex)
  683. }
  684. return ret
  685. }
  686. func addBasicTests() {
  687. basicTests := []testCase{
  688. {
  689. name: "BadRSASignature",
  690. config: Config{
  691. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  692. Bugs: ProtocolBugs{
  693. InvalidSKXSignature: true,
  694. },
  695. },
  696. shouldFail: true,
  697. expectedError: ":BAD_SIGNATURE:",
  698. },
  699. {
  700. name: "BadECDSASignature",
  701. config: Config{
  702. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  703. Bugs: ProtocolBugs{
  704. InvalidSKXSignature: true,
  705. },
  706. Certificates: []Certificate{getECDSACertificate()},
  707. },
  708. shouldFail: true,
  709. expectedError: ":BAD_SIGNATURE:",
  710. },
  711. {
  712. testType: serverTest,
  713. name: "BadRSASignature-ClientAuth",
  714. config: Config{
  715. Bugs: ProtocolBugs{
  716. InvalidCertVerifySignature: true,
  717. },
  718. Certificates: []Certificate{getRSACertificate()},
  719. },
  720. shouldFail: true,
  721. expectedError: ":BAD_SIGNATURE:",
  722. flags: []string{"-require-any-client-certificate"},
  723. },
  724. {
  725. testType: serverTest,
  726. name: "BadECDSASignature-ClientAuth",
  727. config: Config{
  728. Bugs: ProtocolBugs{
  729. InvalidCertVerifySignature: true,
  730. },
  731. Certificates: []Certificate{getECDSACertificate()},
  732. },
  733. shouldFail: true,
  734. expectedError: ":BAD_SIGNATURE:",
  735. flags: []string{"-require-any-client-certificate"},
  736. },
  737. {
  738. name: "BadECDSACurve",
  739. config: Config{
  740. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  741. Bugs: ProtocolBugs{
  742. InvalidSKXCurve: true,
  743. },
  744. Certificates: []Certificate{getECDSACertificate()},
  745. },
  746. shouldFail: true,
  747. expectedError: ":WRONG_CURVE:",
  748. },
  749. {
  750. testType: serverTest,
  751. name: "BadRSAVersion",
  752. config: Config{
  753. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  754. Bugs: ProtocolBugs{
  755. RsaClientKeyExchangeVersion: VersionTLS11,
  756. },
  757. },
  758. shouldFail: true,
  759. expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
  760. },
  761. {
  762. name: "NoFallbackSCSV",
  763. config: Config{
  764. Bugs: ProtocolBugs{
  765. FailIfNotFallbackSCSV: true,
  766. },
  767. },
  768. shouldFail: true,
  769. expectedLocalError: "no fallback SCSV found",
  770. },
  771. {
  772. name: "SendFallbackSCSV",
  773. config: Config{
  774. Bugs: ProtocolBugs{
  775. FailIfNotFallbackSCSV: true,
  776. },
  777. },
  778. flags: []string{"-fallback-scsv"},
  779. },
  780. {
  781. name: "ClientCertificateTypes",
  782. config: Config{
  783. ClientAuth: RequestClientCert,
  784. ClientCertificateTypes: []byte{
  785. CertTypeDSSSign,
  786. CertTypeRSASign,
  787. CertTypeECDSASign,
  788. },
  789. },
  790. flags: []string{
  791. "-expect-certificate-types",
  792. base64.StdEncoding.EncodeToString([]byte{
  793. CertTypeDSSSign,
  794. CertTypeRSASign,
  795. CertTypeECDSASign,
  796. }),
  797. },
  798. },
  799. {
  800. name: "NoClientCertificate",
  801. config: Config{
  802. ClientAuth: RequireAnyClientCert,
  803. },
  804. shouldFail: true,
  805. expectedLocalError: "client didn't provide a certificate",
  806. },
  807. {
  808. name: "UnauthenticatedECDH",
  809. config: Config{
  810. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  811. Bugs: ProtocolBugs{
  812. UnauthenticatedECDH: true,
  813. },
  814. },
  815. shouldFail: true,
  816. expectedError: ":UNEXPECTED_MESSAGE:",
  817. },
  818. {
  819. name: "SkipCertificateStatus",
  820. config: Config{
  821. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  822. Bugs: ProtocolBugs{
  823. SkipCertificateStatus: true,
  824. },
  825. },
  826. flags: []string{
  827. "-enable-ocsp-stapling",
  828. },
  829. },
  830. {
  831. name: "SkipServerKeyExchange",
  832. config: Config{
  833. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  834. Bugs: ProtocolBugs{
  835. SkipServerKeyExchange: true,
  836. },
  837. },
  838. shouldFail: true,
  839. expectedError: ":UNEXPECTED_MESSAGE:",
  840. },
  841. {
  842. name: "SkipChangeCipherSpec-Client",
  843. config: Config{
  844. Bugs: ProtocolBugs{
  845. SkipChangeCipherSpec: true,
  846. },
  847. },
  848. shouldFail: true,
  849. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  850. },
  851. {
  852. testType: serverTest,
  853. name: "SkipChangeCipherSpec-Server",
  854. config: Config{
  855. Bugs: ProtocolBugs{
  856. SkipChangeCipherSpec: true,
  857. },
  858. },
  859. shouldFail: true,
  860. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  861. },
  862. {
  863. testType: serverTest,
  864. name: "SkipChangeCipherSpec-Server-NPN",
  865. config: Config{
  866. NextProtos: []string{"bar"},
  867. Bugs: ProtocolBugs{
  868. SkipChangeCipherSpec: true,
  869. },
  870. },
  871. flags: []string{
  872. "-advertise-npn", "\x03foo\x03bar\x03baz",
  873. },
  874. shouldFail: true,
  875. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  876. },
  877. {
  878. name: "FragmentAcrossChangeCipherSpec-Client",
  879. config: Config{
  880. Bugs: ProtocolBugs{
  881. FragmentAcrossChangeCipherSpec: true,
  882. },
  883. },
  884. shouldFail: true,
  885. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  886. },
  887. {
  888. testType: serverTest,
  889. name: "FragmentAcrossChangeCipherSpec-Server",
  890. config: Config{
  891. Bugs: ProtocolBugs{
  892. FragmentAcrossChangeCipherSpec: true,
  893. },
  894. },
  895. shouldFail: true,
  896. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  897. },
  898. {
  899. testType: serverTest,
  900. name: "FragmentAcrossChangeCipherSpec-Server-NPN",
  901. config: Config{
  902. NextProtos: []string{"bar"},
  903. Bugs: ProtocolBugs{
  904. FragmentAcrossChangeCipherSpec: true,
  905. },
  906. },
  907. flags: []string{
  908. "-advertise-npn", "\x03foo\x03bar\x03baz",
  909. },
  910. shouldFail: true,
  911. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  912. },
  913. {
  914. testType: serverTest,
  915. name: "Alert",
  916. config: Config{
  917. Bugs: ProtocolBugs{
  918. SendSpuriousAlert: alertRecordOverflow,
  919. },
  920. },
  921. shouldFail: true,
  922. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  923. },
  924. {
  925. protocol: dtls,
  926. testType: serverTest,
  927. name: "Alert-DTLS",
  928. config: Config{
  929. Bugs: ProtocolBugs{
  930. SendSpuriousAlert: alertRecordOverflow,
  931. },
  932. },
  933. shouldFail: true,
  934. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  935. },
  936. {
  937. testType: serverTest,
  938. name: "FragmentAlert",
  939. config: Config{
  940. Bugs: ProtocolBugs{
  941. FragmentAlert: true,
  942. SendSpuriousAlert: alertRecordOverflow,
  943. },
  944. },
  945. shouldFail: true,
  946. expectedError: ":BAD_ALERT:",
  947. },
  948. {
  949. protocol: dtls,
  950. testType: serverTest,
  951. name: "FragmentAlert-DTLS",
  952. config: Config{
  953. Bugs: ProtocolBugs{
  954. FragmentAlert: true,
  955. SendSpuriousAlert: alertRecordOverflow,
  956. },
  957. },
  958. shouldFail: true,
  959. expectedError: ":BAD_ALERT:",
  960. },
  961. {
  962. testType: serverTest,
  963. name: "EarlyChangeCipherSpec-server-1",
  964. config: Config{
  965. Bugs: ProtocolBugs{
  966. EarlyChangeCipherSpec: 1,
  967. },
  968. },
  969. shouldFail: true,
  970. expectedError: ":CCS_RECEIVED_EARLY:",
  971. },
  972. {
  973. testType: serverTest,
  974. name: "EarlyChangeCipherSpec-server-2",
  975. config: Config{
  976. Bugs: ProtocolBugs{
  977. EarlyChangeCipherSpec: 2,
  978. },
  979. },
  980. shouldFail: true,
  981. expectedError: ":CCS_RECEIVED_EARLY:",
  982. },
  983. {
  984. name: "SkipNewSessionTicket",
  985. config: Config{
  986. Bugs: ProtocolBugs{
  987. SkipNewSessionTicket: true,
  988. },
  989. },
  990. shouldFail: true,
  991. expectedError: ":CCS_RECEIVED_EARLY:",
  992. },
  993. {
  994. testType: serverTest,
  995. name: "FallbackSCSV",
  996. config: Config{
  997. MaxVersion: VersionTLS11,
  998. Bugs: ProtocolBugs{
  999. SendFallbackSCSV: true,
  1000. },
  1001. },
  1002. shouldFail: true,
  1003. expectedError: ":INAPPROPRIATE_FALLBACK:",
  1004. },
  1005. {
  1006. testType: serverTest,
  1007. name: "FallbackSCSV-VersionMatch",
  1008. config: Config{
  1009. Bugs: ProtocolBugs{
  1010. SendFallbackSCSV: true,
  1011. },
  1012. },
  1013. },
  1014. {
  1015. testType: serverTest,
  1016. name: "FragmentedClientVersion",
  1017. config: Config{
  1018. Bugs: ProtocolBugs{
  1019. MaxHandshakeRecordLength: 1,
  1020. FragmentClientVersion: true,
  1021. },
  1022. },
  1023. expectedVersion: VersionTLS12,
  1024. },
  1025. {
  1026. testType: serverTest,
  1027. name: "MinorVersionTolerance",
  1028. config: Config{
  1029. Bugs: ProtocolBugs{
  1030. SendClientVersion: 0x03ff,
  1031. },
  1032. },
  1033. expectedVersion: VersionTLS12,
  1034. },
  1035. {
  1036. testType: serverTest,
  1037. name: "MajorVersionTolerance",
  1038. config: Config{
  1039. Bugs: ProtocolBugs{
  1040. SendClientVersion: 0x0400,
  1041. },
  1042. },
  1043. expectedVersion: VersionTLS12,
  1044. },
  1045. {
  1046. testType: serverTest,
  1047. name: "VersionTooLow",
  1048. config: Config{
  1049. Bugs: ProtocolBugs{
  1050. SendClientVersion: 0x0200,
  1051. },
  1052. },
  1053. shouldFail: true,
  1054. expectedError: ":UNSUPPORTED_PROTOCOL:",
  1055. },
  1056. {
  1057. testType: serverTest,
  1058. name: "HttpGET",
  1059. sendPrefix: "GET / HTTP/1.0\n",
  1060. shouldFail: true,
  1061. expectedError: ":HTTP_REQUEST:",
  1062. },
  1063. {
  1064. testType: serverTest,
  1065. name: "HttpPOST",
  1066. sendPrefix: "POST / HTTP/1.0\n",
  1067. shouldFail: true,
  1068. expectedError: ":HTTP_REQUEST:",
  1069. },
  1070. {
  1071. testType: serverTest,
  1072. name: "HttpHEAD",
  1073. sendPrefix: "HEAD / HTTP/1.0\n",
  1074. shouldFail: true,
  1075. expectedError: ":HTTP_REQUEST:",
  1076. },
  1077. {
  1078. testType: serverTest,
  1079. name: "HttpPUT",
  1080. sendPrefix: "PUT / HTTP/1.0\n",
  1081. shouldFail: true,
  1082. expectedError: ":HTTP_REQUEST:",
  1083. },
  1084. {
  1085. testType: serverTest,
  1086. name: "HttpCONNECT",
  1087. sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
  1088. shouldFail: true,
  1089. expectedError: ":HTTPS_PROXY_REQUEST:",
  1090. },
  1091. {
  1092. testType: serverTest,
  1093. name: "Garbage",
  1094. sendPrefix: "blah",
  1095. shouldFail: true,
  1096. expectedError: ":UNKNOWN_PROTOCOL:",
  1097. },
  1098. {
  1099. name: "SkipCipherVersionCheck",
  1100. config: Config{
  1101. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  1102. MaxVersion: VersionTLS11,
  1103. Bugs: ProtocolBugs{
  1104. SkipCipherVersionCheck: true,
  1105. },
  1106. },
  1107. shouldFail: true,
  1108. expectedError: ":WRONG_CIPHER_RETURNED:",
  1109. },
  1110. {
  1111. name: "RSAEphemeralKey",
  1112. config: Config{
  1113. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  1114. Bugs: ProtocolBugs{
  1115. RSAEphemeralKey: true,
  1116. },
  1117. },
  1118. shouldFail: true,
  1119. expectedError: ":UNEXPECTED_MESSAGE:",
  1120. },
  1121. {
  1122. name: "DisableEverything",
  1123. flags: []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
  1124. shouldFail: true,
  1125. expectedError: ":WRONG_SSL_VERSION:",
  1126. },
  1127. {
  1128. protocol: dtls,
  1129. name: "DisableEverything-DTLS",
  1130. flags: []string{"-no-tls12", "-no-tls1"},
  1131. shouldFail: true,
  1132. expectedError: ":WRONG_SSL_VERSION:",
  1133. },
  1134. {
  1135. name: "NoSharedCipher",
  1136. config: Config{
  1137. CipherSuites: []uint16{},
  1138. },
  1139. shouldFail: true,
  1140. expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
  1141. },
  1142. {
  1143. protocol: dtls,
  1144. testType: serverTest,
  1145. name: "MTU",
  1146. config: Config{
  1147. Bugs: ProtocolBugs{
  1148. MaxPacketLength: 256,
  1149. },
  1150. },
  1151. flags: []string{"-mtu", "256"},
  1152. },
  1153. {
  1154. protocol: dtls,
  1155. testType: serverTest,
  1156. name: "MTUExceeded",
  1157. config: Config{
  1158. Bugs: ProtocolBugs{
  1159. MaxPacketLength: 255,
  1160. },
  1161. },
  1162. flags: []string{"-mtu", "256"},
  1163. shouldFail: true,
  1164. expectedLocalError: "dtls: exceeded maximum packet length",
  1165. },
  1166. {
  1167. name: "CertMismatchRSA",
  1168. config: Config{
  1169. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  1170. Certificates: []Certificate{getECDSACertificate()},
  1171. Bugs: ProtocolBugs{
  1172. SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  1173. },
  1174. },
  1175. shouldFail: true,
  1176. expectedError: ":WRONG_CERTIFICATE_TYPE:",
  1177. },
  1178. {
  1179. name: "CertMismatchECDSA",
  1180. config: Config{
  1181. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1182. Certificates: []Certificate{getRSACertificate()},
  1183. Bugs: ProtocolBugs{
  1184. SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1185. },
  1186. },
  1187. shouldFail: true,
  1188. expectedError: ":WRONG_CERTIFICATE_TYPE:",
  1189. },
  1190. {
  1191. name: "EmptyCertificateList",
  1192. config: Config{
  1193. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1194. Bugs: ProtocolBugs{
  1195. EmptyCertificateList: true,
  1196. },
  1197. },
  1198. shouldFail: true,
  1199. expectedError: ":DECODE_ERROR:",
  1200. },
  1201. {
  1202. name: "TLSFatalBadPackets",
  1203. damageFirstWrite: true,
  1204. shouldFail: true,
  1205. expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
  1206. },
  1207. {
  1208. protocol: dtls,
  1209. name: "DTLSIgnoreBadPackets",
  1210. damageFirstWrite: true,
  1211. },
  1212. {
  1213. protocol: dtls,
  1214. name: "DTLSIgnoreBadPackets-Async",
  1215. damageFirstWrite: true,
  1216. flags: []string{"-async"},
  1217. },
  1218. {
  1219. name: "AppDataAfterChangeCipherSpec",
  1220. config: Config{
  1221. Bugs: ProtocolBugs{
  1222. AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
  1223. },
  1224. },
  1225. shouldFail: true,
  1226. expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
  1227. },
  1228. {
  1229. protocol: dtls,
  1230. name: "AppDataAfterChangeCipherSpec-DTLS",
  1231. config: Config{
  1232. Bugs: ProtocolBugs{
  1233. AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
  1234. },
  1235. },
  1236. // BoringSSL's DTLS implementation will drop the out-of-order
  1237. // application data.
  1238. },
  1239. {
  1240. name: "AlertAfterChangeCipherSpec",
  1241. config: Config{
  1242. Bugs: ProtocolBugs{
  1243. AlertAfterChangeCipherSpec: alertRecordOverflow,
  1244. },
  1245. },
  1246. shouldFail: true,
  1247. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  1248. },
  1249. {
  1250. protocol: dtls,
  1251. name: "AlertAfterChangeCipherSpec-DTLS",
  1252. config: Config{
  1253. Bugs: ProtocolBugs{
  1254. AlertAfterChangeCipherSpec: alertRecordOverflow,
  1255. },
  1256. },
  1257. shouldFail: true,
  1258. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  1259. },
  1260. {
  1261. protocol: dtls,
  1262. name: "ReorderHandshakeFragments-Small-DTLS",
  1263. config: Config{
  1264. Bugs: ProtocolBugs{
  1265. ReorderHandshakeFragments: true,
  1266. // Small enough that every handshake message is
  1267. // fragmented.
  1268. MaxHandshakeRecordLength: 2,
  1269. },
  1270. },
  1271. },
  1272. {
  1273. protocol: dtls,
  1274. name: "ReorderHandshakeFragments-Large-DTLS",
  1275. config: Config{
  1276. Bugs: ProtocolBugs{
  1277. ReorderHandshakeFragments: true,
  1278. // Large enough that no handshake message is
  1279. // fragmented.
  1280. MaxHandshakeRecordLength: 2048,
  1281. },
  1282. },
  1283. },
  1284. {
  1285. protocol: dtls,
  1286. name: "MixCompleteMessageWithFragments-DTLS",
  1287. config: Config{
  1288. Bugs: ProtocolBugs{
  1289. ReorderHandshakeFragments: true,
  1290. MixCompleteMessageWithFragments: true,
  1291. MaxHandshakeRecordLength: 2,
  1292. },
  1293. },
  1294. },
  1295. {
  1296. name: "SendInvalidRecordType",
  1297. config: Config{
  1298. Bugs: ProtocolBugs{
  1299. SendInvalidRecordType: true,
  1300. },
  1301. },
  1302. shouldFail: true,
  1303. expectedError: ":UNEXPECTED_RECORD:",
  1304. },
  1305. {
  1306. protocol: dtls,
  1307. name: "SendInvalidRecordType-DTLS",
  1308. config: Config{
  1309. Bugs: ProtocolBugs{
  1310. SendInvalidRecordType: true,
  1311. },
  1312. },
  1313. shouldFail: true,
  1314. expectedError: ":UNEXPECTED_RECORD:",
  1315. },
  1316. {
  1317. name: "FalseStart-SkipServerSecondLeg",
  1318. config: Config{
  1319. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1320. NextProtos: []string{"foo"},
  1321. Bugs: ProtocolBugs{
  1322. SkipNewSessionTicket: true,
  1323. SkipChangeCipherSpec: true,
  1324. SkipFinished: true,
  1325. ExpectFalseStart: true,
  1326. },
  1327. },
  1328. flags: []string{
  1329. "-false-start",
  1330. "-handshake-never-done",
  1331. "-advertise-alpn", "\x03foo",
  1332. },
  1333. shimWritesFirst: true,
  1334. shouldFail: true,
  1335. expectedError: ":UNEXPECTED_RECORD:",
  1336. },
  1337. {
  1338. name: "FalseStart-SkipServerSecondLeg-Implicit",
  1339. config: Config{
  1340. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1341. NextProtos: []string{"foo"},
  1342. Bugs: ProtocolBugs{
  1343. SkipNewSessionTicket: true,
  1344. SkipChangeCipherSpec: true,
  1345. SkipFinished: true,
  1346. },
  1347. },
  1348. flags: []string{
  1349. "-implicit-handshake",
  1350. "-false-start",
  1351. "-handshake-never-done",
  1352. "-advertise-alpn", "\x03foo",
  1353. },
  1354. shouldFail: true,
  1355. expectedError: ":UNEXPECTED_RECORD:",
  1356. },
  1357. {
  1358. testType: serverTest,
  1359. name: "FailEarlyCallback",
  1360. flags: []string{"-fail-early-callback"},
  1361. shouldFail: true,
  1362. expectedError: ":CONNECTION_REJECTED:",
  1363. expectedLocalError: "remote error: access denied",
  1364. },
  1365. {
  1366. name: "WrongMessageType",
  1367. config: Config{
  1368. Bugs: ProtocolBugs{
  1369. WrongCertificateMessageType: true,
  1370. },
  1371. },
  1372. shouldFail: true,
  1373. expectedError: ":UNEXPECTED_MESSAGE:",
  1374. expectedLocalError: "remote error: unexpected message",
  1375. },
  1376. {
  1377. protocol: dtls,
  1378. name: "WrongMessageType-DTLS",
  1379. config: Config{
  1380. Bugs: ProtocolBugs{
  1381. WrongCertificateMessageType: true,
  1382. },
  1383. },
  1384. shouldFail: true,
  1385. expectedError: ":UNEXPECTED_MESSAGE:",
  1386. expectedLocalError: "remote error: unexpected message",
  1387. },
  1388. {
  1389. protocol: dtls,
  1390. name: "FragmentMessageTypeMismatch-DTLS",
  1391. config: Config{
  1392. Bugs: ProtocolBugs{
  1393. MaxHandshakeRecordLength: 2,
  1394. FragmentMessageTypeMismatch: true,
  1395. },
  1396. },
  1397. shouldFail: true,
  1398. expectedError: ":FRAGMENT_MISMATCH:",
  1399. },
  1400. {
  1401. protocol: dtls,
  1402. name: "FragmentMessageLengthMismatch-DTLS",
  1403. config: Config{
  1404. Bugs: ProtocolBugs{
  1405. MaxHandshakeRecordLength: 2,
  1406. FragmentMessageLengthMismatch: true,
  1407. },
  1408. },
  1409. shouldFail: true,
  1410. expectedError: ":FRAGMENT_MISMATCH:",
  1411. },
  1412. {
  1413. protocol: dtls,
  1414. name: "SplitFragments-Header-DTLS",
  1415. config: Config{
  1416. Bugs: ProtocolBugs{
  1417. SplitFragments: 2,
  1418. },
  1419. },
  1420. shouldFail: true,
  1421. expectedError: ":UNEXPECTED_MESSAGE:",
  1422. },
  1423. {
  1424. protocol: dtls,
  1425. name: "SplitFragments-Boundary-DTLS",
  1426. config: Config{
  1427. Bugs: ProtocolBugs{
  1428. SplitFragments: dtlsRecordHeaderLen,
  1429. },
  1430. },
  1431. shouldFail: true,
  1432. expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
  1433. },
  1434. {
  1435. protocol: dtls,
  1436. name: "SplitFragments-Body-DTLS",
  1437. config: Config{
  1438. Bugs: ProtocolBugs{
  1439. SplitFragments: dtlsRecordHeaderLen + 1,
  1440. },
  1441. },
  1442. shouldFail: true,
  1443. expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
  1444. },
  1445. {
  1446. protocol: dtls,
  1447. name: "SendEmptyFragments-DTLS",
  1448. config: Config{
  1449. Bugs: ProtocolBugs{
  1450. SendEmptyFragments: true,
  1451. },
  1452. },
  1453. },
  1454. {
  1455. name: "UnsupportedCipherSuite",
  1456. config: Config{
  1457. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  1458. Bugs: ProtocolBugs{
  1459. IgnorePeerCipherPreferences: true,
  1460. },
  1461. },
  1462. flags: []string{"-cipher", "DEFAULT:!RC4"},
  1463. shouldFail: true,
  1464. expectedError: ":WRONG_CIPHER_RETURNED:",
  1465. },
  1466. {
  1467. name: "UnsupportedCurve",
  1468. config: Config{
  1469. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1470. // BoringSSL implements P-224 but doesn't enable it by
  1471. // default.
  1472. CurvePreferences: []CurveID{CurveP224},
  1473. Bugs: ProtocolBugs{
  1474. IgnorePeerCurvePreferences: true,
  1475. },
  1476. },
  1477. shouldFail: true,
  1478. expectedError: ":WRONG_CURVE:",
  1479. },
  1480. {
  1481. name: "BadFinished",
  1482. config: Config{
  1483. Bugs: ProtocolBugs{
  1484. BadFinished: true,
  1485. },
  1486. },
  1487. shouldFail: true,
  1488. expectedError: ":DIGEST_CHECK_FAILED:",
  1489. },
  1490. {
  1491. name: "FalseStart-BadFinished",
  1492. config: Config{
  1493. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1494. NextProtos: []string{"foo"},
  1495. Bugs: ProtocolBugs{
  1496. BadFinished: true,
  1497. ExpectFalseStart: true,
  1498. },
  1499. },
  1500. flags: []string{
  1501. "-false-start",
  1502. "-handshake-never-done",
  1503. "-advertise-alpn", "\x03foo",
  1504. },
  1505. shimWritesFirst: true,
  1506. shouldFail: true,
  1507. expectedError: ":DIGEST_CHECK_FAILED:",
  1508. },
  1509. {
  1510. name: "NoFalseStart-NoALPN",
  1511. config: Config{
  1512. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1513. Bugs: ProtocolBugs{
  1514. ExpectFalseStart: true,
  1515. AlertBeforeFalseStartTest: alertAccessDenied,
  1516. },
  1517. },
  1518. flags: []string{
  1519. "-false-start",
  1520. },
  1521. shimWritesFirst: true,
  1522. shouldFail: true,
  1523. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1524. expectedLocalError: "tls: peer did not false start: EOF",
  1525. },
  1526. {
  1527. name: "NoFalseStart-NoAEAD",
  1528. config: Config{
  1529. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1530. NextProtos: []string{"foo"},
  1531. Bugs: ProtocolBugs{
  1532. ExpectFalseStart: true,
  1533. AlertBeforeFalseStartTest: alertAccessDenied,
  1534. },
  1535. },
  1536. flags: []string{
  1537. "-false-start",
  1538. "-advertise-alpn", "\x03foo",
  1539. },
  1540. shimWritesFirst: true,
  1541. shouldFail: true,
  1542. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1543. expectedLocalError: "tls: peer did not false start: EOF",
  1544. },
  1545. {
  1546. name: "NoFalseStart-RSA",
  1547. config: Config{
  1548. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  1549. NextProtos: []string{"foo"},
  1550. Bugs: ProtocolBugs{
  1551. ExpectFalseStart: true,
  1552. AlertBeforeFalseStartTest: alertAccessDenied,
  1553. },
  1554. },
  1555. flags: []string{
  1556. "-false-start",
  1557. "-advertise-alpn", "\x03foo",
  1558. },
  1559. shimWritesFirst: true,
  1560. shouldFail: true,
  1561. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1562. expectedLocalError: "tls: peer did not false start: EOF",
  1563. },
  1564. {
  1565. name: "NoFalseStart-DHE_RSA",
  1566. config: Config{
  1567. CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
  1568. NextProtos: []string{"foo"},
  1569. Bugs: ProtocolBugs{
  1570. ExpectFalseStart: true,
  1571. AlertBeforeFalseStartTest: alertAccessDenied,
  1572. },
  1573. },
  1574. flags: []string{
  1575. "-false-start",
  1576. "-advertise-alpn", "\x03foo",
  1577. },
  1578. shimWritesFirst: true,
  1579. shouldFail: true,
  1580. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1581. expectedLocalError: "tls: peer did not false start: EOF",
  1582. },
  1583. {
  1584. testType: serverTest,
  1585. name: "NoSupportedCurves",
  1586. config: Config{
  1587. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1588. Bugs: ProtocolBugs{
  1589. NoSupportedCurves: true,
  1590. },
  1591. },
  1592. },
  1593. {
  1594. testType: serverTest,
  1595. name: "NoCommonCurves",
  1596. config: Config{
  1597. CipherSuites: []uint16{
  1598. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  1599. TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
  1600. },
  1601. CurvePreferences: []CurveID{CurveP224},
  1602. },
  1603. expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
  1604. },
  1605. {
  1606. protocol: dtls,
  1607. name: "SendSplitAlert-Sync",
  1608. config: Config{
  1609. Bugs: ProtocolBugs{
  1610. SendSplitAlert: true,
  1611. },
  1612. },
  1613. },
  1614. {
  1615. protocol: dtls,
  1616. name: "SendSplitAlert-Async",
  1617. config: Config{
  1618. Bugs: ProtocolBugs{
  1619. SendSplitAlert: true,
  1620. },
  1621. },
  1622. flags: []string{"-async"},
  1623. },
  1624. {
  1625. protocol: dtls,
  1626. name: "PackDTLSHandshake",
  1627. config: Config{
  1628. Bugs: ProtocolBugs{
  1629. MaxHandshakeRecordLength: 2,
  1630. PackHandshakeFragments: 20,
  1631. PackHandshakeRecords: 200,
  1632. },
  1633. },
  1634. },
  1635. {
  1636. testType: serverTest,
  1637. protocol: dtls,
  1638. name: "NoRC4-DTLS",
  1639. config: Config{
  1640. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
  1641. Bugs: ProtocolBugs{
  1642. EnableAllCiphersInDTLS: true,
  1643. },
  1644. },
  1645. shouldFail: true,
  1646. expectedError: ":NO_SHARED_CIPHER:",
  1647. },
  1648. {
  1649. name: "SendEmptyRecords-Pass",
  1650. sendEmptyRecords: 32,
  1651. },
  1652. {
  1653. name: "SendEmptyRecords",
  1654. sendEmptyRecords: 33,
  1655. shouldFail: true,
  1656. expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
  1657. },
  1658. {
  1659. name: "SendEmptyRecords-Async",
  1660. sendEmptyRecords: 33,
  1661. flags: []string{"-async"},
  1662. shouldFail: true,
  1663. expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
  1664. },
  1665. {
  1666. name: "SendWarningAlerts-Pass",
  1667. sendWarningAlerts: 4,
  1668. },
  1669. {
  1670. protocol: dtls,
  1671. name: "SendWarningAlerts-DTLS-Pass",
  1672. sendWarningAlerts: 4,
  1673. },
  1674. {
  1675. name: "SendWarningAlerts",
  1676. sendWarningAlerts: 5,
  1677. shouldFail: true,
  1678. expectedError: ":TOO_MANY_WARNING_ALERTS:",
  1679. },
  1680. {
  1681. name: "SendWarningAlerts-Async",
  1682. sendWarningAlerts: 5,
  1683. flags: []string{"-async"},
  1684. shouldFail: true,
  1685. expectedError: ":TOO_MANY_WARNING_ALERTS:",
  1686. },
  1687. {
  1688. name: "EmptySessionID",
  1689. config: Config{
  1690. SessionTicketsDisabled: true,
  1691. },
  1692. noSessionCache: true,
  1693. flags: []string{"-expect-no-session"},
  1694. },
  1695. }
  1696. testCases = append(testCases, basicTests...)
  1697. }
  1698. func addCipherSuiteTests() {
  1699. for _, suite := range testCipherSuites {
  1700. const psk = "12345"
  1701. const pskIdentity = "luggage combo"
  1702. var cert Certificate
  1703. var certFile string
  1704. var keyFile string
  1705. if hasComponent(suite.name, "ECDSA") {
  1706. cert = getECDSACertificate()
  1707. certFile = ecdsaCertificateFile
  1708. keyFile = ecdsaKeyFile
  1709. } else {
  1710. cert = getRSACertificate()
  1711. certFile = rsaCertificateFile
  1712. keyFile = rsaKeyFile
  1713. }
  1714. var flags []string
  1715. if hasComponent(suite.name, "PSK") {
  1716. flags = append(flags,
  1717. "-psk", psk,
  1718. "-psk-identity", pskIdentity)
  1719. }
  1720. for _, ver := range tlsVersions {
  1721. if ver.version < VersionTLS12 && isTLS12Only(suite.name) {
  1722. continue
  1723. }
  1724. testCases = append(testCases, testCase{
  1725. testType: clientTest,
  1726. name: ver.name + "-" + suite.name + "-client",
  1727. config: Config{
  1728. MinVersion: ver.version,
  1729. MaxVersion: ver.version,
  1730. CipherSuites: []uint16{suite.id},
  1731. Certificates: []Certificate{cert},
  1732. PreSharedKey: []byte(psk),
  1733. PreSharedKeyIdentity: pskIdentity,
  1734. },
  1735. flags: flags,
  1736. resumeSession: true,
  1737. })
  1738. testCases = append(testCases, testCase{
  1739. testType: serverTest,
  1740. name: ver.name + "-" + suite.name + "-server",
  1741. config: Config{
  1742. MinVersion: ver.version,
  1743. MaxVersion: ver.version,
  1744. CipherSuites: []uint16{suite.id},
  1745. Certificates: []Certificate{cert},
  1746. PreSharedKey: []byte(psk),
  1747. PreSharedKeyIdentity: pskIdentity,
  1748. },
  1749. certFile: certFile,
  1750. keyFile: keyFile,
  1751. flags: flags,
  1752. resumeSession: true,
  1753. })
  1754. if ver.hasDTLS && isDTLSCipher(suite.name) {
  1755. testCases = append(testCases, testCase{
  1756. testType: clientTest,
  1757. protocol: dtls,
  1758. name: "D" + ver.name + "-" + suite.name + "-client",
  1759. config: Config{
  1760. MinVersion: ver.version,
  1761. MaxVersion: ver.version,
  1762. CipherSuites: []uint16{suite.id},
  1763. Certificates: []Certificate{cert},
  1764. PreSharedKey: []byte(psk),
  1765. PreSharedKeyIdentity: pskIdentity,
  1766. },
  1767. flags: flags,
  1768. resumeSession: true,
  1769. })
  1770. testCases = append(testCases, testCase{
  1771. testType: serverTest,
  1772. protocol: dtls,
  1773. name: "D" + ver.name + "-" + suite.name + "-server",
  1774. config: Config{
  1775. MinVersion: ver.version,
  1776. MaxVersion: ver.version,
  1777. CipherSuites: []uint16{suite.id},
  1778. Certificates: []Certificate{cert},
  1779. PreSharedKey: []byte(psk),
  1780. PreSharedKeyIdentity: pskIdentity,
  1781. },
  1782. certFile: certFile,
  1783. keyFile: keyFile,
  1784. flags: flags,
  1785. resumeSession: true,
  1786. })
  1787. }
  1788. }
  1789. }
  1790. testCases = append(testCases, testCase{
  1791. name: "WeakDH",
  1792. config: Config{
  1793. CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
  1794. Bugs: ProtocolBugs{
  1795. // This is a 1023-bit prime number, generated
  1796. // with:
  1797. // openssl gendh 1023 | openssl asn1parse -i
  1798. DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"),
  1799. },
  1800. },
  1801. shouldFail: true,
  1802. expectedError: "BAD_DH_P_LENGTH",
  1803. })
  1804. }
  1805. func addBadECDSASignatureTests() {
  1806. for badR := BadValue(1); badR < NumBadValues; badR++ {
  1807. for badS := BadValue(1); badS < NumBadValues; badS++ {
  1808. testCases = append(testCases, testCase{
  1809. name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
  1810. config: Config{
  1811. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  1812. Certificates: []Certificate{getECDSACertificate()},
  1813. Bugs: ProtocolBugs{
  1814. BadECDSAR: badR,
  1815. BadECDSAS: badS,
  1816. },
  1817. },
  1818. shouldFail: true,
  1819. expectedError: "SIGNATURE",
  1820. })
  1821. }
  1822. }
  1823. }
  1824. func addCBCPaddingTests() {
  1825. testCases = append(testCases, testCase{
  1826. name: "MaxCBCPadding",
  1827. config: Config{
  1828. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1829. Bugs: ProtocolBugs{
  1830. MaxPadding: true,
  1831. },
  1832. },
  1833. messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
  1834. })
  1835. testCases = append(testCases, testCase{
  1836. name: "BadCBCPadding",
  1837. config: Config{
  1838. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1839. Bugs: ProtocolBugs{
  1840. PaddingFirstByteBad: true,
  1841. },
  1842. },
  1843. shouldFail: true,
  1844. expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
  1845. })
  1846. // OpenSSL previously had an issue where the first byte of padding in
  1847. // 255 bytes of padding wasn't checked.
  1848. testCases = append(testCases, testCase{
  1849. name: "BadCBCPadding255",
  1850. config: Config{
  1851. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1852. Bugs: ProtocolBugs{
  1853. MaxPadding: true,
  1854. PaddingFirstByteBadIf255: true,
  1855. },
  1856. },
  1857. messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
  1858. shouldFail: true,
  1859. expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
  1860. })
  1861. }
  1862. func addCBCSplittingTests() {
  1863. testCases = append(testCases, testCase{
  1864. name: "CBCRecordSplitting",
  1865. config: Config{
  1866. MaxVersion: VersionTLS10,
  1867. MinVersion: VersionTLS10,
  1868. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1869. },
  1870. messageLen: -1, // read until EOF
  1871. flags: []string{
  1872. "-async",
  1873. "-write-different-record-sizes",
  1874. "-cbc-record-splitting",
  1875. },
  1876. })
  1877. testCases = append(testCases, testCase{
  1878. name: "CBCRecordSplittingPartialWrite",
  1879. config: Config{
  1880. MaxVersion: VersionTLS10,
  1881. MinVersion: VersionTLS10,
  1882. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1883. },
  1884. messageLen: -1, // read until EOF
  1885. flags: []string{
  1886. "-async",
  1887. "-write-different-record-sizes",
  1888. "-cbc-record-splitting",
  1889. "-partial-write",
  1890. },
  1891. })
  1892. }
  1893. func addClientAuthTests() {
  1894. // Add a dummy cert pool to stress certificate authority parsing.
  1895. // TODO(davidben): Add tests that those values parse out correctly.
  1896. certPool := x509.NewCertPool()
  1897. cert, err := x509.ParseCertificate(rsaCertificate.Certificate[0])
  1898. if err != nil {
  1899. panic(err)
  1900. }
  1901. certPool.AddCert(cert)
  1902. for _, ver := range tlsVersions {
  1903. testCases = append(testCases, testCase{
  1904. testType: clientTest,
  1905. name: ver.name + "-Client-ClientAuth-RSA",
  1906. config: Config{
  1907. MinVersion: ver.version,
  1908. MaxVersion: ver.version,
  1909. ClientAuth: RequireAnyClientCert,
  1910. ClientCAs: certPool,
  1911. },
  1912. flags: []string{
  1913. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  1914. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  1915. },
  1916. })
  1917. testCases = append(testCases, testCase{
  1918. testType: serverTest,
  1919. name: ver.name + "-Server-ClientAuth-RSA",
  1920. config: Config{
  1921. MinVersion: ver.version,
  1922. MaxVersion: ver.version,
  1923. Certificates: []Certificate{rsaCertificate},
  1924. },
  1925. flags: []string{"-require-any-client-certificate"},
  1926. })
  1927. if ver.version != VersionSSL30 {
  1928. testCases = append(testCases, testCase{
  1929. testType: serverTest,
  1930. name: ver.name + "-Server-ClientAuth-ECDSA",
  1931. config: Config{
  1932. MinVersion: ver.version,
  1933. MaxVersion: ver.version,
  1934. Certificates: []Certificate{ecdsaCertificate},
  1935. },
  1936. flags: []string{"-require-any-client-certificate"},
  1937. })
  1938. testCases = append(testCases, testCase{
  1939. testType: clientTest,
  1940. name: ver.name + "-Client-ClientAuth-ECDSA",
  1941. config: Config{
  1942. MinVersion: ver.version,
  1943. MaxVersion: ver.version,
  1944. ClientAuth: RequireAnyClientCert,
  1945. ClientCAs: certPool,
  1946. },
  1947. flags: []string{
  1948. "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
  1949. "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
  1950. },
  1951. })
  1952. }
  1953. }
  1954. }
  1955. func addExtendedMasterSecretTests() {
  1956. const expectEMSFlag = "-expect-extended-master-secret"
  1957. for _, with := range []bool{false, true} {
  1958. prefix := "No"
  1959. var flags []string
  1960. if with {
  1961. prefix = ""
  1962. flags = []string{expectEMSFlag}
  1963. }
  1964. for _, isClient := range []bool{false, true} {
  1965. suffix := "-Server"
  1966. testType := serverTest
  1967. if isClient {
  1968. suffix = "-Client"
  1969. testType = clientTest
  1970. }
  1971. for _, ver := range tlsVersions {
  1972. test := testCase{
  1973. testType: testType,
  1974. name: prefix + "ExtendedMasterSecret-" + ver.name + suffix,
  1975. config: Config{
  1976. MinVersion: ver.version,
  1977. MaxVersion: ver.version,
  1978. Bugs: ProtocolBugs{
  1979. NoExtendedMasterSecret: !with,
  1980. RequireExtendedMasterSecret: with,
  1981. },
  1982. },
  1983. flags: flags,
  1984. shouldFail: ver.version == VersionSSL30 && with,
  1985. }
  1986. if test.shouldFail {
  1987. test.expectedLocalError = "extended master secret required but not supported by peer"
  1988. }
  1989. testCases = append(testCases, test)
  1990. }
  1991. }
  1992. }
  1993. for _, isClient := range []bool{false, true} {
  1994. for _, supportedInFirstConnection := range []bool{false, true} {
  1995. for _, supportedInResumeConnection := range []bool{false, true} {
  1996. boolToWord := func(b bool) string {
  1997. if b {
  1998. return "Yes"
  1999. }
  2000. return "No"
  2001. }
  2002. suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
  2003. if isClient {
  2004. suffix += "Client"
  2005. } else {
  2006. suffix += "Server"
  2007. }
  2008. supportedConfig := Config{
  2009. Bugs: ProtocolBugs{
  2010. RequireExtendedMasterSecret: true,
  2011. },
  2012. }
  2013. noSupportConfig := Config{
  2014. Bugs: ProtocolBugs{
  2015. NoExtendedMasterSecret: true,
  2016. },
  2017. }
  2018. test := testCase{
  2019. name: "ExtendedMasterSecret-" + suffix,
  2020. resumeSession: true,
  2021. }
  2022. if !isClient {
  2023. test.testType = serverTest
  2024. }
  2025. if supportedInFirstConnection {
  2026. test.config = supportedConfig
  2027. } else {
  2028. test.config = noSupportConfig
  2029. }
  2030. if supportedInResumeConnection {
  2031. test.resumeConfig = &supportedConfig
  2032. } else {
  2033. test.resumeConfig = &noSupportConfig
  2034. }
  2035. switch suffix {
  2036. case "YesToYes-Client", "YesToYes-Server":
  2037. // When a session is resumed, it should
  2038. // still be aware that its master
  2039. // secret was generated via EMS and
  2040. // thus it's safe to use tls-unique.
  2041. test.flags = []string{expectEMSFlag}
  2042. case "NoToYes-Server":
  2043. // If an original connection did not
  2044. // contain EMS, but a resumption
  2045. // handshake does, then a server should
  2046. // not resume the session.
  2047. test.expectResumeRejected = true
  2048. case "YesToNo-Server":
  2049. // Resuming an EMS session without the
  2050. // EMS extension should cause the
  2051. // server to abort the connection.
  2052. test.shouldFail = true
  2053. test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
  2054. case "NoToYes-Client":
  2055. // A client should abort a connection
  2056. // where the server resumed a non-EMS
  2057. // session but echoed the EMS
  2058. // extension.
  2059. test.shouldFail = true
  2060. test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
  2061. case "YesToNo-Client":
  2062. // A client should abort a connection
  2063. // where the server didn't echo EMS
  2064. // when the session used it.
  2065. test.shouldFail = true
  2066. test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
  2067. }
  2068. testCases = append(testCases, test)
  2069. }
  2070. }
  2071. }
  2072. }
  2073. // Adds tests that try to cover the range of the handshake state machine, under
  2074. // various conditions. Some of these are redundant with other tests, but they
  2075. // only cover the synchronous case.
  2076. func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) {
  2077. var tests []testCase
  2078. // Basic handshake, with resumption. Client and server,
  2079. // session ID and session ticket.
  2080. tests = append(tests, testCase{
  2081. name: "Basic-Client",
  2082. resumeSession: true,
  2083. })
  2084. tests = append(tests, testCase{
  2085. name: "Basic-Client-RenewTicket",
  2086. config: Config{
  2087. Bugs: ProtocolBugs{
  2088. RenewTicketOnResume: true,
  2089. },
  2090. },
  2091. flags: []string{"-expect-ticket-renewal"},
  2092. resumeSession: true,
  2093. })
  2094. tests = append(tests, testCase{
  2095. name: "Basic-Client-NoTicket",
  2096. config: Config{
  2097. SessionTicketsDisabled: true,
  2098. },
  2099. resumeSession: true,
  2100. })
  2101. tests = append(tests, testCase{
  2102. name: "Basic-Client-Implicit",
  2103. flags: []string{"-implicit-handshake"},
  2104. resumeSession: true,
  2105. })
  2106. tests = append(tests, testCase{
  2107. testType: serverTest,
  2108. name: "Basic-Server",
  2109. resumeSession: true,
  2110. })
  2111. tests = append(tests, testCase{
  2112. testType: serverTest,
  2113. name: "Basic-Server-NoTickets",
  2114. config: Config{
  2115. SessionTicketsDisabled: true,
  2116. },
  2117. resumeSession: true,
  2118. })
  2119. tests = append(tests, testCase{
  2120. testType: serverTest,
  2121. name: "Basic-Server-Implicit",
  2122. flags: []string{"-implicit-handshake"},
  2123. resumeSession: true,
  2124. })
  2125. tests = append(tests, testCase{
  2126. testType: serverTest,
  2127. name: "Basic-Server-EarlyCallback",
  2128. flags: []string{"-use-early-callback"},
  2129. resumeSession: true,
  2130. })
  2131. // TLS client auth.
  2132. tests = append(tests, testCase{
  2133. testType: clientTest,
  2134. name: "ClientAuth-Client",
  2135. config: Config{
  2136. ClientAuth: RequireAnyClientCert,
  2137. },
  2138. flags: []string{
  2139. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  2140. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  2141. },
  2142. })
  2143. if async {
  2144. tests = append(tests, testCase{
  2145. testType: clientTest,
  2146. name: "ClientAuth-Client-AsyncKey",
  2147. config: Config{
  2148. ClientAuth: RequireAnyClientCert,
  2149. },
  2150. flags: []string{
  2151. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  2152. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  2153. "-use-async-private-key",
  2154. },
  2155. })
  2156. tests = append(tests, testCase{
  2157. testType: serverTest,
  2158. name: "Basic-Server-RSAAsyncKey",
  2159. flags: []string{
  2160. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  2161. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  2162. "-use-async-private-key",
  2163. },
  2164. })
  2165. tests = append(tests, testCase{
  2166. testType: serverTest,
  2167. name: "Basic-Server-ECDSAAsyncKey",
  2168. flags: []string{
  2169. "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
  2170. "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
  2171. "-use-async-private-key",
  2172. },
  2173. })
  2174. }
  2175. tests = append(tests, testCase{
  2176. testType: serverTest,
  2177. name: "ClientAuth-Server",
  2178. config: Config{
  2179. Certificates: []Certificate{rsaCertificate},
  2180. },
  2181. flags: []string{"-require-any-client-certificate"},
  2182. })
  2183. // No session ticket support; server doesn't send NewSessionTicket.
  2184. tests = append(tests, testCase{
  2185. name: "SessionTicketsDisabled-Client",
  2186. config: Config{
  2187. SessionTicketsDisabled: true,
  2188. },
  2189. })
  2190. tests = append(tests, testCase{
  2191. testType: serverTest,
  2192. name: "SessionTicketsDisabled-Server",
  2193. config: Config{
  2194. SessionTicketsDisabled: true,
  2195. },
  2196. })
  2197. // Skip ServerKeyExchange in PSK key exchange if there's no
  2198. // identity hint.
  2199. tests = append(tests, testCase{
  2200. name: "EmptyPSKHint-Client",
  2201. config: Config{
  2202. CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
  2203. PreSharedKey: []byte("secret"),
  2204. },
  2205. flags: []string{"-psk", "secret"},
  2206. })
  2207. tests = append(tests, testCase{
  2208. testType: serverTest,
  2209. name: "EmptyPSKHint-Server",
  2210. config: Config{
  2211. CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
  2212. PreSharedKey: []byte("secret"),
  2213. },
  2214. flags: []string{"-psk", "secret"},
  2215. })
  2216. if protocol == tls {
  2217. tests = append(tests, testCase{
  2218. name: "Renegotiate-Client",
  2219. renegotiate: true,
  2220. })
  2221. // NPN on client and server; results in post-handshake message.
  2222. tests = append(tests, testCase{
  2223. name: "NPN-Client",
  2224. config: Config{
  2225. NextProtos: []string{"foo"},
  2226. },
  2227. flags: []string{"-select-next-proto", "foo"},
  2228. expectedNextProto: "foo",
  2229. expectedNextProtoType: npn,
  2230. })
  2231. tests = append(tests, testCase{
  2232. testType: serverTest,
  2233. name: "NPN-Server",
  2234. config: Config{
  2235. NextProtos: []string{"bar"},
  2236. },
  2237. flags: []string{
  2238. "-advertise-npn", "\x03foo\x03bar\x03baz",
  2239. "-expect-next-proto", "bar",
  2240. },
  2241. expectedNextProto: "bar",
  2242. expectedNextProtoType: npn,
  2243. })
  2244. // TODO(davidben): Add tests for when False Start doesn't trigger.
  2245. // Client does False Start and negotiates NPN.
  2246. tests = append(tests, testCase{
  2247. name: "FalseStart",
  2248. config: Config{
  2249. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2250. NextProtos: []string{"foo"},
  2251. Bugs: ProtocolBugs{
  2252. ExpectFalseStart: true,
  2253. },
  2254. },
  2255. flags: []string{
  2256. "-false-start",
  2257. "-select-next-proto", "foo",
  2258. },
  2259. shimWritesFirst: true,
  2260. resumeSession: true,
  2261. })
  2262. // Client does False Start and negotiates ALPN.
  2263. tests = append(tests, testCase{
  2264. name: "FalseStart-ALPN",
  2265. config: Config{
  2266. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2267. NextProtos: []string{"foo"},
  2268. Bugs: ProtocolBugs{
  2269. ExpectFalseStart: true,
  2270. },
  2271. },
  2272. flags: []string{
  2273. "-false-start",
  2274. "-advertise-alpn", "\x03foo",
  2275. },
  2276. shimWritesFirst: true,
  2277. resumeSession: true,
  2278. })
  2279. // Client does False Start but doesn't explicitly call
  2280. // SSL_connect.
  2281. tests = append(tests, testCase{
  2282. name: "FalseStart-Implicit",
  2283. config: Config{
  2284. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2285. NextProtos: []string{"foo"},
  2286. },
  2287. flags: []string{
  2288. "-implicit-handshake",
  2289. "-false-start",
  2290. "-advertise-alpn", "\x03foo",
  2291. },
  2292. })
  2293. // False Start without session tickets.
  2294. tests = append(tests, testCase{
  2295. name: "FalseStart-SessionTicketsDisabled",
  2296. config: Config{
  2297. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2298. NextProtos: []string{"foo"},
  2299. SessionTicketsDisabled: true,
  2300. Bugs: ProtocolBugs{
  2301. ExpectFalseStart: true,
  2302. },
  2303. },
  2304. flags: []string{
  2305. "-false-start",
  2306. "-select-next-proto", "foo",
  2307. },
  2308. shimWritesFirst: true,
  2309. })
  2310. // Server parses a V2ClientHello.
  2311. tests = append(tests, testCase{
  2312. testType: serverTest,
  2313. name: "SendV2ClientHello",
  2314. config: Config{
  2315. // Choose a cipher suite that does not involve
  2316. // elliptic curves, so no extensions are
  2317. // involved.
  2318. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  2319. Bugs: ProtocolBugs{
  2320. SendV2ClientHello: true,
  2321. },
  2322. },
  2323. })
  2324. // Client sends a Channel ID.
  2325. tests = append(tests, testCase{
  2326. name: "ChannelID-Client",
  2327. config: Config{
  2328. RequestChannelID: true,
  2329. },
  2330. flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
  2331. resumeSession: true,
  2332. expectChannelID: true,
  2333. })
  2334. // Server accepts a Channel ID.
  2335. tests = append(tests, testCase{
  2336. testType: serverTest,
  2337. name: "ChannelID-Server",
  2338. config: Config{
  2339. ChannelID: channelIDKey,
  2340. },
  2341. flags: []string{
  2342. "-expect-channel-id",
  2343. base64.StdEncoding.EncodeToString(channelIDBytes),
  2344. },
  2345. resumeSession: true,
  2346. expectChannelID: true,
  2347. })
  2348. } else {
  2349. tests = append(tests, testCase{
  2350. name: "SkipHelloVerifyRequest",
  2351. config: Config{
  2352. Bugs: ProtocolBugs{
  2353. SkipHelloVerifyRequest: true,
  2354. },
  2355. },
  2356. })
  2357. }
  2358. var suffix string
  2359. var flags []string
  2360. var maxHandshakeRecordLength int
  2361. if protocol == dtls {
  2362. suffix = "-DTLS"
  2363. }
  2364. if async {
  2365. suffix += "-Async"
  2366. flags = append(flags, "-async")
  2367. } else {
  2368. suffix += "-Sync"
  2369. }
  2370. if splitHandshake {
  2371. suffix += "-SplitHandshakeRecords"
  2372. maxHandshakeRecordLength = 1
  2373. }
  2374. for _, test := range tests {
  2375. test.protocol = protocol
  2376. test.name += suffix
  2377. test.config.Bugs.MaxHandshakeRecordLength = maxHandshakeRecordLength
  2378. test.flags = append(test.flags, flags...)
  2379. testCases = append(testCases, test)
  2380. }
  2381. }
  2382. func addDDoSCallbackTests() {
  2383. // DDoS callback.
  2384. for _, resume := range []bool{false, true} {
  2385. suffix := "Resume"
  2386. if resume {
  2387. suffix = "No" + suffix
  2388. }
  2389. testCases = append(testCases, testCase{
  2390. testType: serverTest,
  2391. name: "Server-DDoS-OK-" + suffix,
  2392. flags: []string{"-install-ddos-callback"},
  2393. resumeSession: resume,
  2394. })
  2395. failFlag := "-fail-ddos-callback"
  2396. if resume {
  2397. failFlag = "-fail-second-ddos-callback"
  2398. }
  2399. testCases = append(testCases, testCase{
  2400. testType: serverTest,
  2401. name: "Server-DDoS-Reject-" + suffix,
  2402. flags: []string{"-install-ddos-callback", failFlag},
  2403. resumeSession: resume,
  2404. shouldFail: true,
  2405. expectedError: ":CONNECTION_REJECTED:",
  2406. })
  2407. }
  2408. }
  2409. func addVersionNegotiationTests() {
  2410. for i, shimVers := range tlsVersions {
  2411. // Assemble flags to disable all newer versions on the shim.
  2412. var flags []string
  2413. for _, vers := range tlsVersions[i+1:] {
  2414. flags = append(flags, vers.flag)
  2415. }
  2416. for _, runnerVers := range tlsVersions {
  2417. protocols := []protocol{tls}
  2418. if runnerVers.hasDTLS && shimVers.hasDTLS {
  2419. protocols = append(protocols, dtls)
  2420. }
  2421. for _, protocol := range protocols {
  2422. expectedVersion := shimVers.version
  2423. if runnerVers.version < shimVers.version {
  2424. expectedVersion = runnerVers.version
  2425. }
  2426. suffix := shimVers.name + "-" + runnerVers.name
  2427. if protocol == dtls {
  2428. suffix += "-DTLS"
  2429. }
  2430. shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
  2431. clientVers := shimVers.version
  2432. if clientVers > VersionTLS10 {
  2433. clientVers = VersionTLS10
  2434. }
  2435. testCases = append(testCases, testCase{
  2436. protocol: protocol,
  2437. testType: clientTest,
  2438. name: "VersionNegotiation-Client-" + suffix,
  2439. config: Config{
  2440. MaxVersion: runnerVers.version,
  2441. Bugs: ProtocolBugs{
  2442. ExpectInitialRecordVersion: clientVers,
  2443. },
  2444. },
  2445. flags: flags,
  2446. expectedVersion: expectedVersion,
  2447. })
  2448. testCases = append(testCases, testCase{
  2449. protocol: protocol,
  2450. testType: clientTest,
  2451. name: "VersionNegotiation-Client2-" + suffix,
  2452. config: Config{
  2453. MaxVersion: runnerVers.version,
  2454. Bugs: ProtocolBugs{
  2455. ExpectInitialRecordVersion: clientVers,
  2456. },
  2457. },
  2458. flags: []string{"-max-version", shimVersFlag},
  2459. expectedVersion: expectedVersion,
  2460. })
  2461. testCases = append(testCases, testCase{
  2462. protocol: protocol,
  2463. testType: serverTest,
  2464. name: "VersionNegotiation-Server-" + suffix,
  2465. config: Config{
  2466. MaxVersion: runnerVers.version,
  2467. Bugs: ProtocolBugs{
  2468. ExpectInitialRecordVersion: expectedVersion,
  2469. },
  2470. },
  2471. flags: flags,
  2472. expectedVersion: expectedVersion,
  2473. })
  2474. testCases = append(testCases, testCase{
  2475. protocol: protocol,
  2476. testType: serverTest,
  2477. name: "VersionNegotiation-Server2-" + suffix,
  2478. config: Config{
  2479. MaxVersion: runnerVers.version,
  2480. Bugs: ProtocolBugs{
  2481. ExpectInitialRecordVersion: expectedVersion,
  2482. },
  2483. },
  2484. flags: []string{"-max-version", shimVersFlag},
  2485. expectedVersion: expectedVersion,
  2486. })
  2487. }
  2488. }
  2489. }
  2490. }
  2491. func addMinimumVersionTests() {
  2492. for i, shimVers := range tlsVersions {
  2493. // Assemble flags to disable all older versions on the shim.
  2494. var flags []string
  2495. for _, vers := range tlsVersions[:i] {
  2496. flags = append(flags, vers.flag)
  2497. }
  2498. for _, runnerVers := range tlsVersions {
  2499. protocols := []protocol{tls}
  2500. if runnerVers.hasDTLS && shimVers.hasDTLS {
  2501. protocols = append(protocols, dtls)
  2502. }
  2503. for _, protocol := range protocols {
  2504. suffix := shimVers.name + "-" + runnerVers.name
  2505. if protocol == dtls {
  2506. suffix += "-DTLS"
  2507. }
  2508. shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
  2509. var expectedVersion uint16
  2510. var shouldFail bool
  2511. var expectedError string
  2512. var expectedLocalError string
  2513. if runnerVers.version >= shimVers.version {
  2514. expectedVersion = runnerVers.version
  2515. } else {
  2516. shouldFail = true
  2517. expectedError = ":UNSUPPORTED_PROTOCOL:"
  2518. if runnerVers.version > VersionSSL30 {
  2519. expectedLocalError = "remote error: protocol version not supported"
  2520. } else {
  2521. expectedLocalError = "remote error: handshake failure"
  2522. }
  2523. }
  2524. testCases = append(testCases, testCase{
  2525. protocol: protocol,
  2526. testType: clientTest,
  2527. name: "MinimumVersion-Client-" + suffix,
  2528. config: Config{
  2529. MaxVersion: runnerVers.version,
  2530. },
  2531. flags: flags,
  2532. expectedVersion: expectedVersion,
  2533. shouldFail: shouldFail,
  2534. expectedError: expectedError,
  2535. expectedLocalError: expectedLocalError,
  2536. })
  2537. testCases = append(testCases, testCase{
  2538. protocol: protocol,
  2539. testType: clientTest,
  2540. name: "MinimumVersion-Client2-" + suffix,
  2541. config: Config{
  2542. MaxVersion: runnerVers.version,
  2543. },
  2544. flags: []string{"-min-version", shimVersFlag},
  2545. expectedVersion: expectedVersion,
  2546. shouldFail: shouldFail,
  2547. expectedError: expectedError,
  2548. expectedLocalError: expectedLocalError,
  2549. })
  2550. testCases = append(testCases, testCase{
  2551. protocol: protocol,
  2552. testType: serverTest,
  2553. name: "MinimumVersion-Server-" + suffix,
  2554. config: Config{
  2555. MaxVersion: runnerVers.version,
  2556. },
  2557. flags: flags,
  2558. expectedVersion: expectedVersion,
  2559. shouldFail: shouldFail,
  2560. expectedError: expectedError,
  2561. expectedLocalError: expectedLocalError,
  2562. })
  2563. testCases = append(testCases, testCase{
  2564. protocol: protocol,
  2565. testType: serverTest,
  2566. name: "MinimumVersion-Server2-" + suffix,
  2567. config: Config{
  2568. MaxVersion: runnerVers.version,
  2569. },
  2570. flags: []string{"-min-version", shimVersFlag},
  2571. expectedVersion: expectedVersion,
  2572. shouldFail: shouldFail,
  2573. expectedError: expectedError,
  2574. expectedLocalError: expectedLocalError,
  2575. })
  2576. }
  2577. }
  2578. }
  2579. }
  2580. func addD5BugTests() {
  2581. testCases = append(testCases, testCase{
  2582. testType: serverTest,
  2583. name: "D5Bug-NoQuirk-Reject",
  2584. config: Config{
  2585. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  2586. Bugs: ProtocolBugs{
  2587. SSL3RSAKeyExchange: true,
  2588. },
  2589. },
  2590. shouldFail: true,
  2591. expectedError: ":TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG:",
  2592. })
  2593. testCases = append(testCases, testCase{
  2594. testType: serverTest,
  2595. name: "D5Bug-Quirk-Normal",
  2596. config: Config{
  2597. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  2598. },
  2599. flags: []string{"-tls-d5-bug"},
  2600. })
  2601. testCases = append(testCases, testCase{
  2602. testType: serverTest,
  2603. name: "D5Bug-Quirk-Bug",
  2604. config: Config{
  2605. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  2606. Bugs: ProtocolBugs{
  2607. SSL3RSAKeyExchange: true,
  2608. },
  2609. },
  2610. flags: []string{"-tls-d5-bug"},
  2611. })
  2612. }
  2613. func addExtensionTests() {
  2614. testCases = append(testCases, testCase{
  2615. testType: clientTest,
  2616. name: "DuplicateExtensionClient",
  2617. config: Config{
  2618. Bugs: ProtocolBugs{
  2619. DuplicateExtension: true,
  2620. },
  2621. },
  2622. shouldFail: true,
  2623. expectedLocalError: "remote error: error decoding message",
  2624. })
  2625. testCases = append(testCases, testCase{
  2626. testType: serverTest,
  2627. name: "DuplicateExtensionServer",
  2628. config: Config{
  2629. Bugs: ProtocolBugs{
  2630. DuplicateExtension: true,
  2631. },
  2632. },
  2633. shouldFail: true,
  2634. expectedLocalError: "remote error: error decoding message",
  2635. })
  2636. testCases = append(testCases, testCase{
  2637. testType: clientTest,
  2638. name: "ServerNameExtensionClient",
  2639. config: Config{
  2640. Bugs: ProtocolBugs{
  2641. ExpectServerName: "example.com",
  2642. },
  2643. },
  2644. flags: []string{"-host-name", "example.com"},
  2645. })
  2646. testCases = append(testCases, testCase{
  2647. testType: clientTest,
  2648. name: "ServerNameExtensionClientMismatch",
  2649. config: Config{
  2650. Bugs: ProtocolBugs{
  2651. ExpectServerName: "mismatch.com",
  2652. },
  2653. },
  2654. flags: []string{"-host-name", "example.com"},
  2655. shouldFail: true,
  2656. expectedLocalError: "tls: unexpected server name",
  2657. })
  2658. testCases = append(testCases, testCase{
  2659. testType: clientTest,
  2660. name: "ServerNameExtensionClientMissing",
  2661. config: Config{
  2662. Bugs: ProtocolBugs{
  2663. ExpectServerName: "missing.com",
  2664. },
  2665. },
  2666. shouldFail: true,
  2667. expectedLocalError: "tls: unexpected server name",
  2668. })
  2669. testCases = append(testCases, testCase{
  2670. testType: serverTest,
  2671. name: "ServerNameExtensionServer",
  2672. config: Config{
  2673. ServerName: "example.com",
  2674. },
  2675. flags: []string{"-expect-server-name", "example.com"},
  2676. resumeSession: true,
  2677. })
  2678. testCases = append(testCases, testCase{
  2679. testType: clientTest,
  2680. name: "ALPNClient",
  2681. config: Config{
  2682. NextProtos: []string{"foo"},
  2683. },
  2684. flags: []string{
  2685. "-advertise-alpn", "\x03foo\x03bar\x03baz",
  2686. "-expect-alpn", "foo",
  2687. },
  2688. expectedNextProto: "foo",
  2689. expectedNextProtoType: alpn,
  2690. resumeSession: true,
  2691. })
  2692. testCases = append(testCases, testCase{
  2693. testType: serverTest,
  2694. name: "ALPNServer",
  2695. config: Config{
  2696. NextProtos: []string{"foo", "bar", "baz"},
  2697. },
  2698. flags: []string{
  2699. "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
  2700. "-select-alpn", "foo",
  2701. },
  2702. expectedNextProto: "foo",
  2703. expectedNextProtoType: alpn,
  2704. resumeSession: true,
  2705. })
  2706. // Test that the server prefers ALPN over NPN.
  2707. testCases = append(testCases, testCase{
  2708. testType: serverTest,
  2709. name: "ALPNServer-Preferred",
  2710. config: Config{
  2711. NextProtos: []string{"foo", "bar", "baz"},
  2712. },
  2713. flags: []string{
  2714. "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
  2715. "-select-alpn", "foo",
  2716. "-advertise-npn", "\x03foo\x03bar\x03baz",
  2717. },
  2718. expectedNextProto: "foo",
  2719. expectedNextProtoType: alpn,
  2720. resumeSession: true,
  2721. })
  2722. testCases = append(testCases, testCase{
  2723. testType: serverTest,
  2724. name: "ALPNServer-Preferred-Swapped",
  2725. config: Config{
  2726. NextProtos: []string{"foo", "bar", "baz"},
  2727. Bugs: ProtocolBugs{
  2728. SwapNPNAndALPN: true,
  2729. },
  2730. },
  2731. flags: []string{
  2732. "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
  2733. "-select-alpn", "foo",
  2734. "-advertise-npn", "\x03foo\x03bar\x03baz",
  2735. },
  2736. expectedNextProto: "foo",
  2737. expectedNextProtoType: alpn,
  2738. resumeSession: true,
  2739. })
  2740. var emptyString string
  2741. testCases = append(testCases, testCase{
  2742. testType: clientTest,
  2743. name: "ALPNClient-EmptyProtocolName",
  2744. config: Config{
  2745. NextProtos: []string{""},
  2746. Bugs: ProtocolBugs{
  2747. // A server returning an empty ALPN protocol
  2748. // should be rejected.
  2749. ALPNProtocol: &emptyString,
  2750. },
  2751. },
  2752. flags: []string{
  2753. "-advertise-alpn", "\x03foo",
  2754. },
  2755. shouldFail: true,
  2756. expectedError: ":PARSE_TLSEXT:",
  2757. })
  2758. testCases = append(testCases, testCase{
  2759. testType: serverTest,
  2760. name: "ALPNServer-EmptyProtocolName",
  2761. config: Config{
  2762. // A ClientHello containing an empty ALPN protocol
  2763. // should be rejected.
  2764. NextProtos: []string{"foo", "", "baz"},
  2765. },
  2766. flags: []string{
  2767. "-select-alpn", "foo",
  2768. },
  2769. shouldFail: true,
  2770. expectedError: ":PARSE_TLSEXT:",
  2771. })
  2772. // Resume with a corrupt ticket.
  2773. testCases = append(testCases, testCase{
  2774. testType: serverTest,
  2775. name: "CorruptTicket",
  2776. config: Config{
  2777. Bugs: ProtocolBugs{
  2778. CorruptTicket: true,
  2779. },
  2780. },
  2781. resumeSession: true,
  2782. expectResumeRejected: true,
  2783. })
  2784. // Test the ticket callback, with and without renewal.
  2785. testCases = append(testCases, testCase{
  2786. testType: serverTest,
  2787. name: "TicketCallback",
  2788. resumeSession: true,
  2789. flags: []string{"-use-ticket-callback"},
  2790. })
  2791. testCases = append(testCases, testCase{
  2792. testType: serverTest,
  2793. name: "TicketCallback-Renew",
  2794. config: Config{
  2795. Bugs: ProtocolBugs{
  2796. ExpectNewTicket: true,
  2797. },
  2798. },
  2799. flags: []string{"-use-ticket-callback", "-renew-ticket"},
  2800. resumeSession: true,
  2801. })
  2802. // Resume with an oversized session id.
  2803. testCases = append(testCases, testCase{
  2804. testType: serverTest,
  2805. name: "OversizedSessionId",
  2806. config: Config{
  2807. Bugs: ProtocolBugs{
  2808. OversizedSessionId: true,
  2809. },
  2810. },
  2811. resumeSession: true,
  2812. shouldFail: true,
  2813. expectedError: ":DECODE_ERROR:",
  2814. })
  2815. // Basic DTLS-SRTP tests. Include fake profiles to ensure they
  2816. // are ignored.
  2817. testCases = append(testCases, testCase{
  2818. protocol: dtls,
  2819. name: "SRTP-Client",
  2820. config: Config{
  2821. SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
  2822. },
  2823. flags: []string{
  2824. "-srtp-profiles",
  2825. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2826. },
  2827. expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
  2828. })
  2829. testCases = append(testCases, testCase{
  2830. protocol: dtls,
  2831. testType: serverTest,
  2832. name: "SRTP-Server",
  2833. config: Config{
  2834. SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
  2835. },
  2836. flags: []string{
  2837. "-srtp-profiles",
  2838. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2839. },
  2840. expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
  2841. })
  2842. // Test that the MKI is ignored.
  2843. testCases = append(testCases, testCase{
  2844. protocol: dtls,
  2845. testType: serverTest,
  2846. name: "SRTP-Server-IgnoreMKI",
  2847. config: Config{
  2848. SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80},
  2849. Bugs: ProtocolBugs{
  2850. SRTPMasterKeyIdentifer: "bogus",
  2851. },
  2852. },
  2853. flags: []string{
  2854. "-srtp-profiles",
  2855. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2856. },
  2857. expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
  2858. })
  2859. // Test that SRTP isn't negotiated on the server if there were
  2860. // no matching profiles.
  2861. testCases = append(testCases, testCase{
  2862. protocol: dtls,
  2863. testType: serverTest,
  2864. name: "SRTP-Server-NoMatch",
  2865. config: Config{
  2866. SRTPProtectionProfiles: []uint16{100, 101, 102},
  2867. },
  2868. flags: []string{
  2869. "-srtp-profiles",
  2870. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2871. },
  2872. expectedSRTPProtectionProfile: 0,
  2873. })
  2874. // Test that the server returning an invalid SRTP profile is
  2875. // flagged as an error by the client.
  2876. testCases = append(testCases, testCase{
  2877. protocol: dtls,
  2878. name: "SRTP-Client-NoMatch",
  2879. config: Config{
  2880. Bugs: ProtocolBugs{
  2881. SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32,
  2882. },
  2883. },
  2884. flags: []string{
  2885. "-srtp-profiles",
  2886. "SRTP_AES128_CM_SHA1_80",
  2887. },
  2888. shouldFail: true,
  2889. expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
  2890. })
  2891. // Test OCSP stapling and SCT list.
  2892. testCases = append(testCases, testCase{
  2893. name: "OCSPStapling",
  2894. flags: []string{
  2895. "-enable-ocsp-stapling",
  2896. "-expect-ocsp-response",
  2897. base64.StdEncoding.EncodeToString(testOCSPResponse),
  2898. },
  2899. })
  2900. testCases = append(testCases, testCase{
  2901. name: "SignedCertificateTimestampList",
  2902. flags: []string{
  2903. "-enable-signed-cert-timestamps",
  2904. "-expect-signed-cert-timestamps",
  2905. base64.StdEncoding.EncodeToString(testSCTList),
  2906. },
  2907. })
  2908. testCases = append(testCases, testCase{
  2909. testType: clientTest,
  2910. name: "ClientHelloPadding",
  2911. config: Config{
  2912. Bugs: ProtocolBugs{
  2913. RequireClientHelloSize: 512,
  2914. },
  2915. },
  2916. // This hostname just needs to be long enough to push the
  2917. // ClientHello into F5's danger zone between 256 and 511 bytes
  2918. // long.
  2919. flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
  2920. })
  2921. }
  2922. func addResumptionVersionTests() {
  2923. for _, sessionVers := range tlsVersions {
  2924. for _, resumeVers := range tlsVersions {
  2925. protocols := []protocol{tls}
  2926. if sessionVers.hasDTLS && resumeVers.hasDTLS {
  2927. protocols = append(protocols, dtls)
  2928. }
  2929. for _, protocol := range protocols {
  2930. suffix := "-" + sessionVers.name + "-" + resumeVers.name
  2931. if protocol == dtls {
  2932. suffix += "-DTLS"
  2933. }
  2934. if sessionVers.version == resumeVers.version {
  2935. testCases = append(testCases, testCase{
  2936. protocol: protocol,
  2937. name: "Resume-Client" + suffix,
  2938. resumeSession: true,
  2939. config: Config{
  2940. MaxVersion: sessionVers.version,
  2941. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2942. },
  2943. expectedVersion: sessionVers.version,
  2944. expectedResumeVersion: resumeVers.version,
  2945. })
  2946. } else {
  2947. testCases = append(testCases, testCase{
  2948. protocol: protocol,
  2949. name: "Resume-Client-Mismatch" + suffix,
  2950. resumeSession: true,
  2951. config: Config{
  2952. MaxVersion: sessionVers.version,
  2953. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2954. },
  2955. expectedVersion: sessionVers.version,
  2956. resumeConfig: &Config{
  2957. MaxVersion: resumeVers.version,
  2958. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2959. Bugs: ProtocolBugs{
  2960. AllowSessionVersionMismatch: true,
  2961. },
  2962. },
  2963. expectedResumeVersion: resumeVers.version,
  2964. shouldFail: true,
  2965. expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:",
  2966. })
  2967. }
  2968. testCases = append(testCases, testCase{
  2969. protocol: protocol,
  2970. name: "Resume-Client-NoResume" + suffix,
  2971. resumeSession: true,
  2972. config: Config{
  2973. MaxVersion: sessionVers.version,
  2974. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2975. },
  2976. expectedVersion: sessionVers.version,
  2977. resumeConfig: &Config{
  2978. MaxVersion: resumeVers.version,
  2979. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2980. },
  2981. newSessionsOnResume: true,
  2982. expectResumeRejected: true,
  2983. expectedResumeVersion: resumeVers.version,
  2984. })
  2985. testCases = append(testCases, testCase{
  2986. protocol: protocol,
  2987. testType: serverTest,
  2988. name: "Resume-Server" + suffix,
  2989. resumeSession: true,
  2990. config: Config{
  2991. MaxVersion: sessionVers.version,
  2992. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2993. },
  2994. expectedVersion: sessionVers.version,
  2995. expectResumeRejected: sessionVers.version != resumeVers.version,
  2996. resumeConfig: &Config{
  2997. MaxVersion: resumeVers.version,
  2998. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2999. },
  3000. expectedResumeVersion: resumeVers.version,
  3001. })
  3002. }
  3003. }
  3004. }
  3005. testCases = append(testCases, testCase{
  3006. name: "Resume-Client-CipherMismatch",
  3007. resumeSession: true,
  3008. config: Config{
  3009. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  3010. },
  3011. resumeConfig: &Config{
  3012. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  3013. Bugs: ProtocolBugs{
  3014. SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA,
  3015. },
  3016. },
  3017. shouldFail: true,
  3018. expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
  3019. })
  3020. }
  3021. func addRenegotiationTests() {
  3022. // Servers cannot renegotiate.
  3023. testCases = append(testCases, testCase{
  3024. testType: serverTest,
  3025. name: "Renegotiate-Server-Forbidden",
  3026. renegotiate: true,
  3027. flags: []string{"-reject-peer-renegotiations"},
  3028. shouldFail: true,
  3029. expectedError: ":NO_RENEGOTIATION:",
  3030. expectedLocalError: "remote error: no renegotiation",
  3031. })
  3032. // The server shouldn't echo the renegotiation extension unless
  3033. // requested by the client.
  3034. testCases = append(testCases, testCase{
  3035. testType: serverTest,
  3036. name: "Renegotiate-Server-NoExt",
  3037. config: Config{
  3038. Bugs: ProtocolBugs{
  3039. NoRenegotiationInfo: true,
  3040. RequireRenegotiationInfo: true,
  3041. },
  3042. },
  3043. shouldFail: true,
  3044. expectedLocalError: "renegotiation extension missing",
  3045. })
  3046. // The renegotiation SCSV should be sufficient for the server to echo
  3047. // the extension.
  3048. testCases = append(testCases, testCase{
  3049. testType: serverTest,
  3050. name: "Renegotiate-Server-NoExt-SCSV",
  3051. config: Config{
  3052. Bugs: ProtocolBugs{
  3053. NoRenegotiationInfo: true,
  3054. SendRenegotiationSCSV: true,
  3055. RequireRenegotiationInfo: true,
  3056. },
  3057. },
  3058. })
  3059. testCases = append(testCases, testCase{
  3060. name: "Renegotiate-Client",
  3061. config: Config{
  3062. Bugs: ProtocolBugs{
  3063. FailIfResumeOnRenego: true,
  3064. },
  3065. },
  3066. renegotiate: true,
  3067. })
  3068. testCases = append(testCases, testCase{
  3069. name: "Renegotiate-Client-EmptyExt",
  3070. renegotiate: true,
  3071. config: Config{
  3072. Bugs: ProtocolBugs{
  3073. EmptyRenegotiationInfo: true,
  3074. },
  3075. },
  3076. shouldFail: true,
  3077. expectedError: ":RENEGOTIATION_MISMATCH:",
  3078. })
  3079. testCases = append(testCases, testCase{
  3080. name: "Renegotiate-Client-BadExt",
  3081. renegotiate: true,
  3082. config: Config{
  3083. Bugs: ProtocolBugs{
  3084. BadRenegotiationInfo: true,
  3085. },
  3086. },
  3087. shouldFail: true,
  3088. expectedError: ":RENEGOTIATION_MISMATCH:",
  3089. })
  3090. testCases = append(testCases, testCase{
  3091. name: "Renegotiate-Client-NoExt",
  3092. config: Config{
  3093. Bugs: ProtocolBugs{
  3094. NoRenegotiationInfo: true,
  3095. },
  3096. },
  3097. shouldFail: true,
  3098. expectedError: ":UNSAFE_LEGACY_RENEGOTIATION_DISABLED:",
  3099. flags: []string{"-no-legacy-server-connect"},
  3100. })
  3101. testCases = append(testCases, testCase{
  3102. name: "Renegotiate-Client-NoExt-Allowed",
  3103. renegotiate: true,
  3104. config: Config{
  3105. Bugs: ProtocolBugs{
  3106. NoRenegotiationInfo: true,
  3107. },
  3108. },
  3109. })
  3110. testCases = append(testCases, testCase{
  3111. name: "Renegotiate-Client-SwitchCiphers",
  3112. renegotiate: true,
  3113. config: Config{
  3114. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  3115. },
  3116. renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3117. })
  3118. testCases = append(testCases, testCase{
  3119. name: "Renegotiate-Client-SwitchCiphers2",
  3120. renegotiate: true,
  3121. config: Config{
  3122. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3123. },
  3124. renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  3125. })
  3126. testCases = append(testCases, testCase{
  3127. name: "Renegotiate-Client-Forbidden",
  3128. renegotiate: true,
  3129. flags: []string{"-reject-peer-renegotiations"},
  3130. shouldFail: true,
  3131. expectedError: ":NO_RENEGOTIATION:",
  3132. expectedLocalError: "remote error: no renegotiation",
  3133. })
  3134. testCases = append(testCases, testCase{
  3135. name: "Renegotiate-SameClientVersion",
  3136. renegotiate: true,
  3137. config: Config{
  3138. MaxVersion: VersionTLS10,
  3139. Bugs: ProtocolBugs{
  3140. RequireSameRenegoClientVersion: true,
  3141. },
  3142. },
  3143. })
  3144. testCases = append(testCases, testCase{
  3145. name: "Renegotiate-FalseStart",
  3146. renegotiate: true,
  3147. config: Config{
  3148. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3149. NextProtos: []string{"foo"},
  3150. },
  3151. flags: []string{
  3152. "-false-start",
  3153. "-select-next-proto", "foo",
  3154. },
  3155. shimWritesFirst: true,
  3156. })
  3157. }
  3158. func addDTLSReplayTests() {
  3159. // Test that sequence number replays are detected.
  3160. testCases = append(testCases, testCase{
  3161. protocol: dtls,
  3162. name: "DTLS-Replay",
  3163. messageCount: 200,
  3164. replayWrites: true,
  3165. })
  3166. // Test the incoming sequence number skipping by values larger
  3167. // than the retransmit window.
  3168. testCases = append(testCases, testCase{
  3169. protocol: dtls,
  3170. name: "DTLS-Replay-LargeGaps",
  3171. config: Config{
  3172. Bugs: ProtocolBugs{
  3173. SequenceNumberMapping: func(in uint64) uint64 {
  3174. return in * 127
  3175. },
  3176. },
  3177. },
  3178. messageCount: 200,
  3179. replayWrites: true,
  3180. })
  3181. // Test the incoming sequence number changing non-monotonically.
  3182. testCases = append(testCases, testCase{
  3183. protocol: dtls,
  3184. name: "DTLS-Replay-NonMonotonic",
  3185. config: Config{
  3186. Bugs: ProtocolBugs{
  3187. SequenceNumberMapping: func(in uint64) uint64 {
  3188. return in ^ 31
  3189. },
  3190. },
  3191. },
  3192. messageCount: 200,
  3193. replayWrites: true,
  3194. })
  3195. }
  3196. var testHashes = []struct {
  3197. name string
  3198. id uint8
  3199. }{
  3200. {"SHA1", hashSHA1},
  3201. {"SHA224", hashSHA224},
  3202. {"SHA256", hashSHA256},
  3203. {"SHA384", hashSHA384},
  3204. {"SHA512", hashSHA512},
  3205. }
  3206. func addSigningHashTests() {
  3207. // Make sure each hash works. Include some fake hashes in the list and
  3208. // ensure they're ignored.
  3209. for _, hash := range testHashes {
  3210. testCases = append(testCases, testCase{
  3211. name: "SigningHash-ClientAuth-" + hash.name,
  3212. config: Config{
  3213. ClientAuth: RequireAnyClientCert,
  3214. SignatureAndHashes: []signatureAndHash{
  3215. {signatureRSA, 42},
  3216. {signatureRSA, hash.id},
  3217. {signatureRSA, 255},
  3218. },
  3219. },
  3220. flags: []string{
  3221. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  3222. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  3223. },
  3224. })
  3225. testCases = append(testCases, testCase{
  3226. testType: serverTest,
  3227. name: "SigningHash-ServerKeyExchange-Sign-" + hash.name,
  3228. config: Config{
  3229. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3230. SignatureAndHashes: []signatureAndHash{
  3231. {signatureRSA, 42},
  3232. {signatureRSA, hash.id},
  3233. {signatureRSA, 255},
  3234. },
  3235. },
  3236. })
  3237. }
  3238. // Test that hash resolution takes the signature type into account.
  3239. testCases = append(testCases, testCase{
  3240. name: "SigningHash-ClientAuth-SignatureType",
  3241. config: Config{
  3242. ClientAuth: RequireAnyClientCert,
  3243. SignatureAndHashes: []signatureAndHash{
  3244. {signatureECDSA, hashSHA512},
  3245. {signatureRSA, hashSHA384},
  3246. {signatureECDSA, hashSHA1},
  3247. },
  3248. },
  3249. flags: []string{
  3250. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  3251. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  3252. },
  3253. })
  3254. testCases = append(testCases, testCase{
  3255. testType: serverTest,
  3256. name: "SigningHash-ServerKeyExchange-SignatureType",
  3257. config: Config{
  3258. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3259. SignatureAndHashes: []signatureAndHash{
  3260. {signatureECDSA, hashSHA512},
  3261. {signatureRSA, hashSHA384},
  3262. {signatureECDSA, hashSHA1},
  3263. },
  3264. },
  3265. })
  3266. // Test that, if the list is missing, the peer falls back to SHA-1.
  3267. testCases = append(testCases, testCase{
  3268. name: "SigningHash-ClientAuth-Fallback",
  3269. config: Config{
  3270. ClientAuth: RequireAnyClientCert,
  3271. SignatureAndHashes: []signatureAndHash{
  3272. {signatureRSA, hashSHA1},
  3273. },
  3274. Bugs: ProtocolBugs{
  3275. NoSignatureAndHashes: true,
  3276. },
  3277. },
  3278. flags: []string{
  3279. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  3280. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  3281. },
  3282. })
  3283. testCases = append(testCases, testCase{
  3284. testType: serverTest,
  3285. name: "SigningHash-ServerKeyExchange-Fallback",
  3286. config: Config{
  3287. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3288. SignatureAndHashes: []signatureAndHash{
  3289. {signatureRSA, hashSHA1},
  3290. },
  3291. Bugs: ProtocolBugs{
  3292. NoSignatureAndHashes: true,
  3293. },
  3294. },
  3295. })
  3296. // Test that hash preferences are enforced. BoringSSL defaults to
  3297. // rejecting MD5 signatures.
  3298. testCases = append(testCases, testCase{
  3299. testType: serverTest,
  3300. name: "SigningHash-ClientAuth-Enforced",
  3301. config: Config{
  3302. Certificates: []Certificate{rsaCertificate},
  3303. SignatureAndHashes: []signatureAndHash{
  3304. {signatureRSA, hashMD5},
  3305. // Advertise SHA-1 so the handshake will
  3306. // proceed, but the shim's preferences will be
  3307. // ignored in CertificateVerify generation, so
  3308. // MD5 will be chosen.
  3309. {signatureRSA, hashSHA1},
  3310. },
  3311. Bugs: ProtocolBugs{
  3312. IgnorePeerSignatureAlgorithmPreferences: true,
  3313. },
  3314. },
  3315. flags: []string{"-require-any-client-certificate"},
  3316. shouldFail: true,
  3317. expectedError: ":WRONG_SIGNATURE_TYPE:",
  3318. })
  3319. testCases = append(testCases, testCase{
  3320. name: "SigningHash-ServerKeyExchange-Enforced",
  3321. config: Config{
  3322. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3323. SignatureAndHashes: []signatureAndHash{
  3324. {signatureRSA, hashMD5},
  3325. },
  3326. Bugs: ProtocolBugs{
  3327. IgnorePeerSignatureAlgorithmPreferences: true,
  3328. },
  3329. },
  3330. shouldFail: true,
  3331. expectedError: ":WRONG_SIGNATURE_TYPE:",
  3332. })
  3333. }
  3334. // timeouts is the retransmit schedule for BoringSSL. It doubles and
  3335. // caps at 60 seconds. On the 13th timeout, it gives up.
  3336. var timeouts = []time.Duration{
  3337. 1 * time.Second,
  3338. 2 * time.Second,
  3339. 4 * time.Second,
  3340. 8 * time.Second,
  3341. 16 * time.Second,
  3342. 32 * time.Second,
  3343. 60 * time.Second,
  3344. 60 * time.Second,
  3345. 60 * time.Second,
  3346. 60 * time.Second,
  3347. 60 * time.Second,
  3348. 60 * time.Second,
  3349. 60 * time.Second,
  3350. }
  3351. func addDTLSRetransmitTests() {
  3352. // Test that this is indeed the timeout schedule. Stress all
  3353. // four patterns of handshake.
  3354. for i := 1; i < len(timeouts); i++ {
  3355. number := strconv.Itoa(i)
  3356. testCases = append(testCases, testCase{
  3357. protocol: dtls,
  3358. name: "DTLS-Retransmit-Client-" + number,
  3359. config: Config{
  3360. Bugs: ProtocolBugs{
  3361. TimeoutSchedule: timeouts[:i],
  3362. },
  3363. },
  3364. resumeSession: true,
  3365. flags: []string{"-async"},
  3366. })
  3367. testCases = append(testCases, testCase{
  3368. protocol: dtls,
  3369. testType: serverTest,
  3370. name: "DTLS-Retransmit-Server-" + number,
  3371. config: Config{
  3372. Bugs: ProtocolBugs{
  3373. TimeoutSchedule: timeouts[:i],
  3374. },
  3375. },
  3376. resumeSession: true,
  3377. flags: []string{"-async"},
  3378. })
  3379. }
  3380. // Test that exceeding the timeout schedule hits a read
  3381. // timeout.
  3382. testCases = append(testCases, testCase{
  3383. protocol: dtls,
  3384. name: "DTLS-Retransmit-Timeout",
  3385. config: Config{
  3386. Bugs: ProtocolBugs{
  3387. TimeoutSchedule: timeouts,
  3388. },
  3389. },
  3390. resumeSession: true,
  3391. flags: []string{"-async"},
  3392. shouldFail: true,
  3393. expectedError: ":READ_TIMEOUT_EXPIRED:",
  3394. })
  3395. // Test that timeout handling has a fudge factor, due to API
  3396. // problems.
  3397. testCases = append(testCases, testCase{
  3398. protocol: dtls,
  3399. name: "DTLS-Retransmit-Fudge",
  3400. config: Config{
  3401. Bugs: ProtocolBugs{
  3402. TimeoutSchedule: []time.Duration{
  3403. timeouts[0] - 10*time.Millisecond,
  3404. },
  3405. },
  3406. },
  3407. resumeSession: true,
  3408. flags: []string{"-async"},
  3409. })
  3410. // Test that the final Finished retransmitting isn't
  3411. // duplicated if the peer badly fragments everything.
  3412. testCases = append(testCases, testCase{
  3413. testType: serverTest,
  3414. protocol: dtls,
  3415. name: "DTLS-Retransmit-Fragmented",
  3416. config: Config{
  3417. Bugs: ProtocolBugs{
  3418. TimeoutSchedule: []time.Duration{timeouts[0]},
  3419. MaxHandshakeRecordLength: 2,
  3420. },
  3421. },
  3422. flags: []string{"-async"},
  3423. })
  3424. }
  3425. func addExportKeyingMaterialTests() {
  3426. for _, vers := range tlsVersions {
  3427. if vers.version == VersionSSL30 {
  3428. continue
  3429. }
  3430. testCases = append(testCases, testCase{
  3431. name: "ExportKeyingMaterial-" + vers.name,
  3432. config: Config{
  3433. MaxVersion: vers.version,
  3434. },
  3435. exportKeyingMaterial: 1024,
  3436. exportLabel: "label",
  3437. exportContext: "context",
  3438. useExportContext: true,
  3439. })
  3440. testCases = append(testCases, testCase{
  3441. name: "ExportKeyingMaterial-NoContext-" + vers.name,
  3442. config: Config{
  3443. MaxVersion: vers.version,
  3444. },
  3445. exportKeyingMaterial: 1024,
  3446. })
  3447. testCases = append(testCases, testCase{
  3448. name: "ExportKeyingMaterial-EmptyContext-" + vers.name,
  3449. config: Config{
  3450. MaxVersion: vers.version,
  3451. },
  3452. exportKeyingMaterial: 1024,
  3453. useExportContext: true,
  3454. })
  3455. testCases = append(testCases, testCase{
  3456. name: "ExportKeyingMaterial-Small-" + vers.name,
  3457. config: Config{
  3458. MaxVersion: vers.version,
  3459. },
  3460. exportKeyingMaterial: 1,
  3461. exportLabel: "label",
  3462. exportContext: "context",
  3463. useExportContext: true,
  3464. })
  3465. }
  3466. testCases = append(testCases, testCase{
  3467. name: "ExportKeyingMaterial-SSL3",
  3468. config: Config{
  3469. MaxVersion: VersionSSL30,
  3470. },
  3471. exportKeyingMaterial: 1024,
  3472. exportLabel: "label",
  3473. exportContext: "context",
  3474. useExportContext: true,
  3475. shouldFail: true,
  3476. expectedError: "failed to export keying material",
  3477. })
  3478. }
  3479. func addTLSUniqueTests() {
  3480. for _, isClient := range []bool{false, true} {
  3481. for _, isResumption := range []bool{false, true} {
  3482. for _, hasEMS := range []bool{false, true} {
  3483. var suffix string
  3484. if isResumption {
  3485. suffix = "Resume-"
  3486. } else {
  3487. suffix = "Full-"
  3488. }
  3489. if hasEMS {
  3490. suffix += "EMS-"
  3491. } else {
  3492. suffix += "NoEMS-"
  3493. }
  3494. if isClient {
  3495. suffix += "Client"
  3496. } else {
  3497. suffix += "Server"
  3498. }
  3499. test := testCase{
  3500. name: "TLSUnique-" + suffix,
  3501. testTLSUnique: true,
  3502. config: Config{
  3503. Bugs: ProtocolBugs{
  3504. NoExtendedMasterSecret: !hasEMS,
  3505. },
  3506. },
  3507. }
  3508. if isResumption {
  3509. test.resumeSession = true
  3510. test.resumeConfig = &Config{
  3511. Bugs: ProtocolBugs{
  3512. NoExtendedMasterSecret: !hasEMS,
  3513. },
  3514. }
  3515. }
  3516. if isResumption && !hasEMS {
  3517. test.shouldFail = true
  3518. test.expectedError = "failed to get tls-unique"
  3519. }
  3520. testCases = append(testCases, test)
  3521. }
  3522. }
  3523. }
  3524. }
  3525. func addCustomExtensionTests() {
  3526. expectedContents := "custom extension"
  3527. emptyString := ""
  3528. for _, isClient := range []bool{false, true} {
  3529. suffix := "Server"
  3530. flag := "-enable-server-custom-extension"
  3531. testType := serverTest
  3532. if isClient {
  3533. suffix = "Client"
  3534. flag = "-enable-client-custom-extension"
  3535. testType = clientTest
  3536. }
  3537. testCases = append(testCases, testCase{
  3538. testType: testType,
  3539. name: "CustomExtensions-" + suffix,
  3540. config: Config{
  3541. Bugs: ProtocolBugs{
  3542. CustomExtension: expectedContents,
  3543. ExpectedCustomExtension: &expectedContents,
  3544. },
  3545. },
  3546. flags: []string{flag},
  3547. })
  3548. // If the parse callback fails, the handshake should also fail.
  3549. testCases = append(testCases, testCase{
  3550. testType: testType,
  3551. name: "CustomExtensions-ParseError-" + suffix,
  3552. config: Config{
  3553. Bugs: ProtocolBugs{
  3554. CustomExtension: expectedContents + "foo",
  3555. ExpectedCustomExtension: &expectedContents,
  3556. },
  3557. },
  3558. flags: []string{flag},
  3559. shouldFail: true,
  3560. expectedError: ":CUSTOM_EXTENSION_ERROR:",
  3561. })
  3562. // If the add callback fails, the handshake should also fail.
  3563. testCases = append(testCases, testCase{
  3564. testType: testType,
  3565. name: "CustomExtensions-FailAdd-" + suffix,
  3566. config: Config{
  3567. Bugs: ProtocolBugs{
  3568. CustomExtension: expectedContents,
  3569. ExpectedCustomExtension: &expectedContents,
  3570. },
  3571. },
  3572. flags: []string{flag, "-custom-extension-fail-add"},
  3573. shouldFail: true,
  3574. expectedError: ":CUSTOM_EXTENSION_ERROR:",
  3575. })
  3576. // If the add callback returns zero, no extension should be
  3577. // added.
  3578. skipCustomExtension := expectedContents
  3579. if isClient {
  3580. // For the case where the client skips sending the
  3581. // custom extension, the server must not “echo” it.
  3582. skipCustomExtension = ""
  3583. }
  3584. testCases = append(testCases, testCase{
  3585. testType: testType,
  3586. name: "CustomExtensions-Skip-" + suffix,
  3587. config: Config{
  3588. Bugs: ProtocolBugs{
  3589. CustomExtension: skipCustomExtension,
  3590. ExpectedCustomExtension: &emptyString,
  3591. },
  3592. },
  3593. flags: []string{flag, "-custom-extension-skip"},
  3594. })
  3595. }
  3596. // The custom extension add callback should not be called if the client
  3597. // doesn't send the extension.
  3598. testCases = append(testCases, testCase{
  3599. testType: serverTest,
  3600. name: "CustomExtensions-NotCalled-Server",
  3601. config: Config{
  3602. Bugs: ProtocolBugs{
  3603. ExpectedCustomExtension: &emptyString,
  3604. },
  3605. },
  3606. flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
  3607. })
  3608. }
  3609. func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
  3610. defer wg.Done()
  3611. for test := range c {
  3612. var err error
  3613. if *mallocTest < 0 {
  3614. statusChan <- statusMsg{test: test, started: true}
  3615. err = runTest(test, shimPath, -1)
  3616. } else {
  3617. for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
  3618. statusChan <- statusMsg{test: test, started: true}
  3619. if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
  3620. if err != nil {
  3621. fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
  3622. }
  3623. break
  3624. }
  3625. }
  3626. }
  3627. statusChan <- statusMsg{test: test, err: err}
  3628. }
  3629. }
  3630. type statusMsg struct {
  3631. test *testCase
  3632. started bool
  3633. err error
  3634. }
  3635. func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total int) {
  3636. var started, done, failed, lineLen int
  3637. testOutput := newTestOutput()
  3638. for msg := range statusChan {
  3639. if !*pipe {
  3640. // Erase the previous status line.
  3641. var erase string
  3642. for i := 0; i < lineLen; i++ {
  3643. erase += "\b \b"
  3644. }
  3645. fmt.Print(erase)
  3646. }
  3647. if msg.started {
  3648. started++
  3649. } else {
  3650. done++
  3651. if msg.err != nil {
  3652. fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
  3653. failed++
  3654. testOutput.addResult(msg.test.name, "FAIL")
  3655. } else {
  3656. if *pipe {
  3657. // Print each test instead of a status line.
  3658. fmt.Printf("PASSED (%s)\n", msg.test.name)
  3659. }
  3660. testOutput.addResult(msg.test.name, "PASS")
  3661. }
  3662. }
  3663. if !*pipe {
  3664. // Print a new status line.
  3665. line := fmt.Sprintf("%d/%d/%d/%d", failed, done, started, total)
  3666. lineLen = len(line)
  3667. os.Stdout.WriteString(line)
  3668. }
  3669. }
  3670. doneChan <- testOutput
  3671. }
  3672. func main() {
  3673. flag.Parse()
  3674. *resourceDir = path.Clean(*resourceDir)
  3675. addBasicTests()
  3676. addCipherSuiteTests()
  3677. addBadECDSASignatureTests()
  3678. addCBCPaddingTests()
  3679. addCBCSplittingTests()
  3680. addClientAuthTests()
  3681. addDDoSCallbackTests()
  3682. addVersionNegotiationTests()
  3683. addMinimumVersionTests()
  3684. addD5BugTests()
  3685. addExtensionTests()
  3686. addResumptionVersionTests()
  3687. addExtendedMasterSecretTests()
  3688. addRenegotiationTests()
  3689. addDTLSReplayTests()
  3690. addSigningHashTests()
  3691. addDTLSRetransmitTests()
  3692. addExportKeyingMaterialTests()
  3693. addTLSUniqueTests()
  3694. addCustomExtensionTests()
  3695. for _, async := range []bool{false, true} {
  3696. for _, splitHandshake := range []bool{false, true} {
  3697. for _, protocol := range []protocol{tls, dtls} {
  3698. addStateMachineCoverageTests(async, splitHandshake, protocol)
  3699. }
  3700. }
  3701. }
  3702. var wg sync.WaitGroup
  3703. statusChan := make(chan statusMsg, *numWorkers)
  3704. testChan := make(chan *testCase, *numWorkers)
  3705. doneChan := make(chan *testOutput)
  3706. go statusPrinter(doneChan, statusChan, len(testCases))
  3707. for i := 0; i < *numWorkers; i++ {
  3708. wg.Add(1)
  3709. go worker(statusChan, testChan, *shimPath, &wg)
  3710. }
  3711. for i := range testCases {
  3712. if len(*testToRun) == 0 || *testToRun == testCases[i].name {
  3713. testChan <- &testCases[i]
  3714. }
  3715. }
  3716. close(testChan)
  3717. wg.Wait()
  3718. close(statusChan)
  3719. testOutput := <-doneChan
  3720. fmt.Printf("\n")
  3721. if *jsonOutput != "" {
  3722. if err := testOutput.writeTo(*jsonOutput); err != nil {
  3723. fmt.Fprintf(os.Stderr, "Error: %s\n", err)
  3724. }
  3725. }
  3726. if !testOutput.allPassed {
  3727. os.Exit(1)
  3728. }
  3729. }