You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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