blob: 0ede7bb06402cca037a746022edae33349744ec7 [file] [log] [blame]
Adam Langley7fcfd3b2016-05-20 11:02:50 -07001// Copyright (c) 2016, Google Inc.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
Adam Langleydc7e9c42015-09-29 15:21:04 -070015package runner
Adam Langley95c29f32014-06-20 12:00:00 -070016
17import (
18 "bytes"
David Benjamina08e49d2014-08-24 01:46:07 -040019 "crypto/ecdsa"
20 "crypto/elliptic"
David Benjamin407a10c2014-07-16 12:58:59 -040021 "crypto/x509"
David Benjamin2561dc32014-08-24 01:25:27 -040022 "encoding/base64"
David Benjamina08e49d2014-08-24 01:46:07 -040023 "encoding/pem"
Adam Langley95c29f32014-06-20 12:00:00 -070024 "flag"
25 "fmt"
26 "io"
Kenny Root7fdeaf12014-08-05 15:23:37 -070027 "io/ioutil"
Adam Langleya7997f12015-05-14 17:38:50 -070028 "math/big"
Adam Langley95c29f32014-06-20 12:00:00 -070029 "net"
30 "os"
31 "os/exec"
David Benjamin884fdf12014-08-02 15:28:23 -040032 "path"
David Benjamin2bc8e6f2014-08-02 15:22:37 -040033 "runtime"
Adam Langley69a01602014-11-17 17:26:55 -080034 "strconv"
Adam Langley95c29f32014-06-20 12:00:00 -070035 "strings"
36 "sync"
37 "syscall"
David Benjamin83f90402015-01-27 01:09:43 -050038 "time"
Adam Langley95c29f32014-06-20 12:00:00 -070039)
40
Adam Langley69a01602014-11-17 17:26:55 -080041var (
David Benjamin5f237bc2015-02-11 17:14:15 -050042 useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
43 useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
David Benjamind16bf342015-12-18 00:53:12 -050044 useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb")
David Benjamin5f237bc2015-02-11 17:14:15 -050045 flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection")
46 mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
47 mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
48 jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
49 pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
Adam Langley7c803a62015-06-15 15:35:05 -070050 testToRun = flag.String("test", "", "The name of a test to run, or empty to run all tests")
51 numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
52 shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
53 resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
David Benjaminf2b83632016-03-01 22:57:46 -050054 fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.")
David Benjamin9867b7d2016-03-01 23:25:48 -050055 transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.")
David Benjamin01784b42016-06-07 18:00:52 -040056 idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.")
David Benjamin2e045a92016-06-08 13:09:56 -040057 deterministic = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.")
Adam Langley69a01602014-11-17 17:26:55 -080058)
Adam Langley95c29f32014-06-20 12:00:00 -070059
David Benjamin025b3d32014-07-01 19:53:04 -040060const (
61 rsaCertificateFile = "cert.pem"
62 ecdsaCertificateFile = "ecdsa_cert.pem"
63)
64
65const (
David Benjamina08e49d2014-08-24 01:46:07 -040066 rsaKeyFile = "key.pem"
67 ecdsaKeyFile = "ecdsa_key.pem"
68 channelIDKeyFile = "channel_id_key.pem"
David Benjamin025b3d32014-07-01 19:53:04 -040069)
70
Adam Langley95c29f32014-06-20 12:00:00 -070071var rsaCertificate, ecdsaCertificate Certificate
David Benjamina08e49d2014-08-24 01:46:07 -040072var channelIDKey *ecdsa.PrivateKey
73var channelIDBytes []byte
Adam Langley95c29f32014-06-20 12:00:00 -070074
David Benjamin61f95272014-11-25 01:55:35 -050075var testOCSPResponse = []byte{1, 2, 3, 4}
76var testSCTList = []byte{5, 6, 7, 8}
77
Adam Langley95c29f32014-06-20 12:00:00 -070078func initCertificates() {
79 var err error
Adam Langley7c803a62015-06-15 15:35:05 -070080 rsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, rsaCertificateFile), path.Join(*resourceDir, rsaKeyFile))
Adam Langley95c29f32014-06-20 12:00:00 -070081 if err != nil {
82 panic(err)
83 }
David Benjamin61f95272014-11-25 01:55:35 -050084 rsaCertificate.OCSPStaple = testOCSPResponse
85 rsaCertificate.SignedCertificateTimestampList = testSCTList
Adam Langley95c29f32014-06-20 12:00:00 -070086
Adam Langley7c803a62015-06-15 15:35:05 -070087 ecdsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, ecdsaCertificateFile), path.Join(*resourceDir, ecdsaKeyFile))
Adam Langley95c29f32014-06-20 12:00:00 -070088 if err != nil {
89 panic(err)
90 }
David Benjamin61f95272014-11-25 01:55:35 -050091 ecdsaCertificate.OCSPStaple = testOCSPResponse
92 ecdsaCertificate.SignedCertificateTimestampList = testSCTList
David Benjamina08e49d2014-08-24 01:46:07 -040093
Adam Langley7c803a62015-06-15 15:35:05 -070094 channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
David Benjamina08e49d2014-08-24 01:46:07 -040095 if err != nil {
96 panic(err)
97 }
98 channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock)
99 if channelIDDERBlock.Type != "EC PRIVATE KEY" {
100 panic("bad key type")
101 }
102 channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes)
103 if err != nil {
104 panic(err)
105 }
106 if channelIDKey.Curve != elliptic.P256() {
107 panic("bad curve")
108 }
109
110 channelIDBytes = make([]byte, 64)
111 writeIntPadded(channelIDBytes[:32], channelIDKey.X)
112 writeIntPadded(channelIDBytes[32:], channelIDKey.Y)
Adam Langley95c29f32014-06-20 12:00:00 -0700113}
114
115var certificateOnce sync.Once
116
117func getRSACertificate() Certificate {
118 certificateOnce.Do(initCertificates)
119 return rsaCertificate
120}
121
122func getECDSACertificate() Certificate {
123 certificateOnce.Do(initCertificates)
124 return ecdsaCertificate
125}
126
David Benjamin025b3d32014-07-01 19:53:04 -0400127type testType int
128
129const (
130 clientTest testType = iota
131 serverTest
132)
133
David Benjamin6fd297b2014-08-11 18:43:38 -0400134type protocol int
135
136const (
137 tls protocol = iota
138 dtls
139)
140
David Benjaminfc7b0862014-09-06 13:21:53 -0400141const (
142 alpn = 1
143 npn = 2
144)
145
Adam Langley95c29f32014-06-20 12:00:00 -0700146type testCase struct {
David Benjamin025b3d32014-07-01 19:53:04 -0400147 testType testType
David Benjamin6fd297b2014-08-11 18:43:38 -0400148 protocol protocol
Adam Langley95c29f32014-06-20 12:00:00 -0700149 name string
150 config Config
151 shouldFail bool
152 expectedError string
Adam Langleyac61fa32014-06-23 12:03:11 -0700153 // expectedLocalError, if not empty, contains a substring that must be
154 // found in the local error.
155 expectedLocalError string
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400156 // expectedVersion, if non-zero, specifies the TLS version that must be
157 // negotiated.
158 expectedVersion uint16
David Benjamin01fe8202014-09-24 15:21:44 -0400159 // expectedResumeVersion, if non-zero, specifies the TLS version that
160 // must be negotiated on resumption. If zero, expectedVersion is used.
161 expectedResumeVersion uint16
David Benjamin90da8c82015-04-20 14:57:57 -0400162 // expectedCipher, if non-zero, specifies the TLS cipher suite that
163 // should be negotiated.
164 expectedCipher uint16
David Benjamina08e49d2014-08-24 01:46:07 -0400165 // expectChannelID controls whether the connection should have
166 // negotiated a Channel ID with channelIDKey.
167 expectChannelID bool
David Benjaminae2888f2014-09-06 12:58:58 -0400168 // expectedNextProto controls whether the connection should
169 // negotiate a next protocol via NPN or ALPN.
170 expectedNextProto string
David Benjaminc7ce9772015-10-09 19:32:41 -0400171 // expectNoNextProto, if true, means that no next protocol should be
172 // negotiated.
173 expectNoNextProto bool
David Benjaminfc7b0862014-09-06 13:21:53 -0400174 // expectedNextProtoType, if non-zero, is the expected next
175 // protocol negotiation mechanism.
176 expectedNextProtoType int
David Benjaminca6c8262014-11-15 19:06:08 -0500177 // expectedSRTPProtectionProfile is the DTLS-SRTP profile that
178 // should be negotiated. If zero, none should be negotiated.
179 expectedSRTPProtectionProfile uint16
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100180 // expectedOCSPResponse, if not nil, is the expected OCSP response to be received.
181 expectedOCSPResponse []uint8
Paul Lietar4fac72e2015-09-09 13:44:55 +0100182 // expectedSCTList, if not nil, is the expected SCT list to be received.
183 expectedSCTList []uint8
Steven Valdez0d62f262015-09-04 12:41:04 -0400184 // expectedClientCertSignatureHash, if not zero, is the TLS id of the
185 // hash function that the client should have used when signing the
186 // handshake with a client certificate.
187 expectedClientCertSignatureHash uint8
Adam Langley80842bd2014-06-20 12:00:00 -0700188 // messageLen is the length, in bytes, of the test message that will be
189 // sent.
190 messageLen int
David Benjamin8e6db492015-07-25 18:29:23 -0400191 // messageCount is the number of test messages that will be sent.
192 messageCount int
Steven Valdez0d62f262015-09-04 12:41:04 -0400193 // digestPrefs is the list of digest preferences from the client.
194 digestPrefs string
David Benjamin025b3d32014-07-01 19:53:04 -0400195 // certFile is the path to the certificate to use for the server.
196 certFile string
197 // keyFile is the path to the private key to use for the server.
198 keyFile string
David Benjamin1d5c83e2014-07-22 19:20:02 -0400199 // resumeSession controls whether a second connection should be tested
David Benjamin01fe8202014-09-24 15:21:44 -0400200 // which attempts to resume the first session.
David Benjamin1d5c83e2014-07-22 19:20:02 -0400201 resumeSession bool
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700202 // expectResumeRejected, if true, specifies that the attempted
203 // resumption must be rejected by the client. This is only valid for a
204 // serverTest.
205 expectResumeRejected bool
David Benjamin01fe8202014-09-24 15:21:44 -0400206 // resumeConfig, if not nil, points to a Config to be used on
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500207 // resumption. Unless newSessionsOnResume is set,
208 // SessionTicketKey, ServerSessionCache, and
209 // ClientSessionCache are copied from the initial connection's
210 // config. If nil, the initial connection's config is used.
David Benjamin01fe8202014-09-24 15:21:44 -0400211 resumeConfig *Config
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500212 // newSessionsOnResume, if true, will cause resumeConfig to
213 // use a different session resumption context.
214 newSessionsOnResume bool
David Benjaminba4594a2015-06-18 18:36:15 -0400215 // noSessionCache, if true, will cause the server to run without a
216 // session cache.
217 noSessionCache bool
David Benjamin98e882e2014-08-08 13:24:34 -0400218 // sendPrefix sends a prefix on the socket before actually performing a
219 // handshake.
220 sendPrefix string
David Benjamine58c4f52014-08-24 03:47:07 -0400221 // shimWritesFirst controls whether the shim sends an initial "hello"
222 // message before doing a roundtrip with the runner.
223 shimWritesFirst bool
David Benjamin30789da2015-08-29 22:56:45 -0400224 // shimShutsDown, if true, runs a test where the shim shuts down the
225 // connection immediately after the handshake rather than echoing
226 // messages from the runner.
227 shimShutsDown bool
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400228 // renegotiate indicates the number of times the connection should be
229 // renegotiated during the exchange.
230 renegotiate int
Adam Langleycf2d4f42014-10-28 19:06:14 -0700231 // renegotiateCiphers is a list of ciphersuite ids that will be
232 // switched in just before renegotiation.
233 renegotiateCiphers []uint16
David Benjamin5e961c12014-11-07 01:48:35 -0500234 // replayWrites, if true, configures the underlying transport
235 // to replay every write it makes in DTLS tests.
236 replayWrites bool
David Benjamin5fa3eba2015-01-22 16:35:40 -0500237 // damageFirstWrite, if true, configures the underlying transport to
238 // damage the final byte of the first application data write.
239 damageFirstWrite bool
David Benjaminc565ebb2015-04-03 04:06:36 -0400240 // exportKeyingMaterial, if non-zero, configures the test to exchange
241 // keying material and verify they match.
242 exportKeyingMaterial int
243 exportLabel string
244 exportContext string
245 useExportContext bool
David Benjamin325b5c32014-07-01 19:40:31 -0400246 // flags, if not empty, contains a list of command-line flags that will
247 // be passed to the shim program.
248 flags []string
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700249 // testTLSUnique, if true, causes the shim to send the tls-unique value
250 // which will be compared against the expected value.
251 testTLSUnique bool
David Benjamina8ebe222015-06-06 03:04:39 -0400252 // sendEmptyRecords is the number of consecutive empty records to send
253 // before and after the test message.
254 sendEmptyRecords int
David Benjamin24f346d2015-06-06 03:28:08 -0400255 // sendWarningAlerts is the number of consecutive warning alerts to send
256 // before and after the test message.
257 sendWarningAlerts int
David Benjamin4f75aaf2015-09-01 16:53:10 -0400258 // expectMessageDropped, if true, means the test message is expected to
259 // be dropped by the client rather than echoed back.
260 expectMessageDropped bool
Adam Langley95c29f32014-06-20 12:00:00 -0700261}
262
Adam Langley7c803a62015-06-15 15:35:05 -0700263var testCases []testCase
Adam Langley95c29f32014-06-20 12:00:00 -0700264
David Benjamin9867b7d2016-03-01 23:25:48 -0500265func writeTranscript(test *testCase, isResume bool, data []byte) {
266 if len(data) == 0 {
267 return
268 }
269
270 protocol := "tls"
271 if test.protocol == dtls {
272 protocol = "dtls"
273 }
274
275 side := "client"
276 if test.testType == serverTest {
277 side = "server"
278 }
279
280 dir := path.Join(*transcriptDir, protocol, side)
281 if err := os.MkdirAll(dir, 0755); err != nil {
282 fmt.Fprintf(os.Stderr, "Error making %s: %s\n", dir, err)
283 return
284 }
285
286 name := test.name
287 if isResume {
288 name += "-Resume"
289 } else {
290 name += "-Normal"
291 }
292
293 if err := ioutil.WriteFile(path.Join(dir, name), data, 0644); err != nil {
294 fmt.Fprintf(os.Stderr, "Error writing %s: %s\n", name, err)
295 }
296}
297
David Benjamin3ed59772016-03-08 12:50:21 -0500298// A timeoutConn implements an idle timeout on each Read and Write operation.
299type timeoutConn struct {
300 net.Conn
301 timeout time.Duration
302}
303
304func (t *timeoutConn) Read(b []byte) (int, error) {
305 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil {
306 return 0, err
307 }
308 return t.Conn.Read(b)
309}
310
311func (t *timeoutConn) Write(b []byte) (int, error) {
312 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil {
313 return 0, err
314 }
315 return t.Conn.Write(b)
316}
317
David Benjamin8e6db492015-07-25 18:29:23 -0400318func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
David Benjamin01784b42016-06-07 18:00:52 -0400319 conn = &timeoutConn{conn, *idleTimeout}
David Benjamin65ea8ff2014-11-23 03:01:00 -0500320
David Benjamin6fd297b2014-08-11 18:43:38 -0400321 if test.protocol == dtls {
David Benjamin83f90402015-01-27 01:09:43 -0500322 config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
323 conn = config.Bugs.PacketAdaptor
David Benjaminebda9b32015-11-02 15:33:18 -0500324 }
325
David Benjamin9867b7d2016-03-01 23:25:48 -0500326 if *flagDebug || len(*transcriptDir) != 0 {
David Benjaminebda9b32015-11-02 15:33:18 -0500327 local, peer := "client", "server"
328 if test.testType == clientTest {
329 local, peer = peer, local
David Benjamin5e961c12014-11-07 01:48:35 -0500330 }
David Benjaminebda9b32015-11-02 15:33:18 -0500331 connDebug := &recordingConn{
332 Conn: conn,
333 isDatagram: test.protocol == dtls,
334 local: local,
335 peer: peer,
336 }
337 conn = connDebug
David Benjamin9867b7d2016-03-01 23:25:48 -0500338 if *flagDebug {
339 defer connDebug.WriteTo(os.Stdout)
340 }
341 if len(*transcriptDir) != 0 {
342 defer func() {
343 writeTranscript(test, isResume, connDebug.Transcript())
344 }()
345 }
David Benjaminebda9b32015-11-02 15:33:18 -0500346
347 if config.Bugs.PacketAdaptor != nil {
348 config.Bugs.PacketAdaptor.debug = connDebug
349 }
350 }
351
352 if test.replayWrites {
353 conn = newReplayAdaptor(conn)
David Benjamin6fd297b2014-08-11 18:43:38 -0400354 }
355
David Benjamin3ed59772016-03-08 12:50:21 -0500356 var connDamage *damageAdaptor
David Benjamin5fa3eba2015-01-22 16:35:40 -0500357 if test.damageFirstWrite {
358 connDamage = newDamageAdaptor(conn)
359 conn = connDamage
360 }
361
David Benjamin6fd297b2014-08-11 18:43:38 -0400362 if test.sendPrefix != "" {
363 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil {
364 return err
365 }
David Benjamin98e882e2014-08-08 13:24:34 -0400366 }
367
David Benjamin1d5c83e2014-07-22 19:20:02 -0400368 var tlsConn *Conn
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400369 if test.testType == clientTest {
David Benjamin6fd297b2014-08-11 18:43:38 -0400370 if test.protocol == dtls {
371 tlsConn = DTLSServer(conn, config)
372 } else {
373 tlsConn = Server(conn, config)
374 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400375 } else {
376 config.InsecureSkipVerify = true
David Benjamin6fd297b2014-08-11 18:43:38 -0400377 if test.protocol == dtls {
378 tlsConn = DTLSClient(conn, config)
379 } else {
380 tlsConn = Client(conn, config)
381 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400382 }
David Benjamin30789da2015-08-29 22:56:45 -0400383 defer tlsConn.Close()
David Benjamin1d5c83e2014-07-22 19:20:02 -0400384
Adam Langley95c29f32014-06-20 12:00:00 -0700385 if err := tlsConn.Handshake(); err != nil {
386 return err
387 }
Kenny Root7fdeaf12014-08-05 15:23:37 -0700388
David Benjamin01fe8202014-09-24 15:21:44 -0400389 // TODO(davidben): move all per-connection expectations into a dedicated
390 // expectations struct that can be specified separately for the two
391 // legs.
392 expectedVersion := test.expectedVersion
393 if isResume && test.expectedResumeVersion != 0 {
394 expectedVersion = test.expectedResumeVersion
395 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700396 connState := tlsConn.ConnectionState()
397 if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion {
David Benjamin01fe8202014-09-24 15:21:44 -0400398 return fmt.Errorf("got version %x, expected %x", vers, expectedVersion)
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400399 }
400
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700401 if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
David Benjamin90da8c82015-04-20 14:57:57 -0400402 return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher)
403 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700404 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
405 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
406 }
David Benjamin90da8c82015-04-20 14:57:57 -0400407
David Benjamina08e49d2014-08-24 01:46:07 -0400408 if test.expectChannelID {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700409 channelID := connState.ChannelID
David Benjamina08e49d2014-08-24 01:46:07 -0400410 if channelID == nil {
411 return fmt.Errorf("no channel ID negotiated")
412 }
413 if channelID.Curve != channelIDKey.Curve ||
414 channelIDKey.X.Cmp(channelIDKey.X) != 0 ||
415 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 {
416 return fmt.Errorf("incorrect channel ID")
417 }
418 }
419
David Benjaminae2888f2014-09-06 12:58:58 -0400420 if expected := test.expectedNextProto; expected != "" {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700421 if actual := connState.NegotiatedProtocol; actual != expected {
David Benjaminae2888f2014-09-06 12:58:58 -0400422 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
423 }
424 }
425
David Benjaminc7ce9772015-10-09 19:32:41 -0400426 if test.expectNoNextProto {
427 if actual := connState.NegotiatedProtocol; actual != "" {
428 return fmt.Errorf("got unexpected next proto %s", actual)
429 }
430 }
431
David Benjaminfc7b0862014-09-06 13:21:53 -0400432 if test.expectedNextProtoType != 0 {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700433 if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
David Benjaminfc7b0862014-09-06 13:21:53 -0400434 return fmt.Errorf("next proto type mismatch")
435 }
436 }
437
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700438 if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
David Benjaminca6c8262014-11-15 19:06:08 -0500439 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
440 }
441
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100442 if test.expectedOCSPResponse != nil && !bytes.Equal(test.expectedOCSPResponse, tlsConn.OCSPResponse()) {
443 return fmt.Errorf("OCSP Response mismatch")
444 }
445
Paul Lietar4fac72e2015-09-09 13:44:55 +0100446 if test.expectedSCTList != nil && !bytes.Equal(test.expectedSCTList, connState.SCTList) {
447 return fmt.Errorf("SCT list mismatch")
448 }
449
Steven Valdez0d62f262015-09-04 12:41:04 -0400450 if expected := test.expectedClientCertSignatureHash; expected != 0 && expected != connState.ClientCertSignatureHash {
451 return fmt.Errorf("expected client to sign handshake with hash %d, but got %d", expected, connState.ClientCertSignatureHash)
452 }
453
David Benjaminc565ebb2015-04-03 04:06:36 -0400454 if test.exportKeyingMaterial > 0 {
455 actual := make([]byte, test.exportKeyingMaterial)
456 if _, err := io.ReadFull(tlsConn, actual); err != nil {
457 return err
458 }
459 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext)
460 if err != nil {
461 return err
462 }
463 if !bytes.Equal(actual, expected) {
464 return fmt.Errorf("keying material mismatch")
465 }
466 }
467
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700468 if test.testTLSUnique {
469 var peersValue [12]byte
470 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
471 return err
472 }
473 expected := tlsConn.ConnectionState().TLSUnique
474 if !bytes.Equal(peersValue[:], expected) {
475 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
476 }
477 }
478
David Benjamine58c4f52014-08-24 03:47:07 -0400479 if test.shimWritesFirst {
480 var buf [5]byte
481 _, err := io.ReadFull(tlsConn, buf[:])
482 if err != nil {
483 return err
484 }
485 if string(buf[:]) != "hello" {
486 return fmt.Errorf("bad initial message")
487 }
488 }
489
David Benjamina8ebe222015-06-06 03:04:39 -0400490 for i := 0; i < test.sendEmptyRecords; i++ {
491 tlsConn.Write(nil)
492 }
493
David Benjamin24f346d2015-06-06 03:28:08 -0400494 for i := 0; i < test.sendWarningAlerts; i++ {
495 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
496 }
497
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400498 if test.renegotiate > 0 {
Adam Langleycf2d4f42014-10-28 19:06:14 -0700499 if test.renegotiateCiphers != nil {
500 config.CipherSuites = test.renegotiateCiphers
501 }
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400502 for i := 0; i < test.renegotiate; i++ {
503 if err := tlsConn.Renegotiate(); err != nil {
504 return err
505 }
Adam Langleycf2d4f42014-10-28 19:06:14 -0700506 }
507 } else if test.renegotiateCiphers != nil {
508 panic("renegotiateCiphers without renegotiate")
509 }
510
David Benjamin5fa3eba2015-01-22 16:35:40 -0500511 if test.damageFirstWrite {
512 connDamage.setDamage(true)
513 tlsConn.Write([]byte("DAMAGED WRITE"))
514 connDamage.setDamage(false)
515 }
516
David Benjamin8e6db492015-07-25 18:29:23 -0400517 messageLen := test.messageLen
Kenny Root7fdeaf12014-08-05 15:23:37 -0700518 if messageLen < 0 {
David Benjamin6fd297b2014-08-11 18:43:38 -0400519 if test.protocol == dtls {
520 return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
521 }
Kenny Root7fdeaf12014-08-05 15:23:37 -0700522 // Read until EOF.
523 _, err := io.Copy(ioutil.Discard, tlsConn)
524 return err
525 }
David Benjamin4417d052015-04-05 04:17:25 -0400526 if messageLen == 0 {
527 messageLen = 32
Adam Langley80842bd2014-06-20 12:00:00 -0700528 }
Adam Langley95c29f32014-06-20 12:00:00 -0700529
David Benjamin8e6db492015-07-25 18:29:23 -0400530 messageCount := test.messageCount
531 if messageCount == 0 {
532 messageCount = 1
David Benjamina8ebe222015-06-06 03:04:39 -0400533 }
534
David Benjamin8e6db492015-07-25 18:29:23 -0400535 for j := 0; j < messageCount; j++ {
536 testMessage := make([]byte, messageLen)
537 for i := range testMessage {
538 testMessage[i] = 0x42 ^ byte(j)
David Benjamin6fd297b2014-08-11 18:43:38 -0400539 }
David Benjamin8e6db492015-07-25 18:29:23 -0400540 tlsConn.Write(testMessage)
Adam Langley95c29f32014-06-20 12:00:00 -0700541
David Benjamin8e6db492015-07-25 18:29:23 -0400542 for i := 0; i < test.sendEmptyRecords; i++ {
543 tlsConn.Write(nil)
544 }
545
546 for i := 0; i < test.sendWarningAlerts; i++ {
547 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
548 }
549
David Benjamin4f75aaf2015-09-01 16:53:10 -0400550 if test.shimShutsDown || test.expectMessageDropped {
David Benjamin30789da2015-08-29 22:56:45 -0400551 // The shim will not respond.
552 continue
553 }
554
David Benjamin8e6db492015-07-25 18:29:23 -0400555 buf := make([]byte, len(testMessage))
556 if test.protocol == dtls {
557 bufTmp := make([]byte, len(buf)+1)
558 n, err := tlsConn.Read(bufTmp)
559 if err != nil {
560 return err
561 }
562 if n != len(buf) {
563 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
564 }
565 copy(buf, bufTmp)
566 } else {
567 _, err := io.ReadFull(tlsConn, buf)
568 if err != nil {
569 return err
570 }
571 }
572
573 for i, v := range buf {
574 if v != testMessage[i]^0xff {
575 return fmt.Errorf("bad reply contents at byte %d", i)
576 }
Adam Langley95c29f32014-06-20 12:00:00 -0700577 }
578 }
579
580 return nil
581}
582
David Benjamin325b5c32014-07-01 19:40:31 -0400583func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
584 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full"}
Adam Langley95c29f32014-06-20 12:00:00 -0700585 if dbAttach {
David Benjamin325b5c32014-07-01 19:40:31 -0400586 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p")
Adam Langley95c29f32014-06-20 12:00:00 -0700587 }
David Benjamin325b5c32014-07-01 19:40:31 -0400588 valgrindArgs = append(valgrindArgs, path)
589 valgrindArgs = append(valgrindArgs, args...)
Adam Langley95c29f32014-06-20 12:00:00 -0700590
David Benjamin325b5c32014-07-01 19:40:31 -0400591 return exec.Command("valgrind", valgrindArgs...)
Adam Langley95c29f32014-06-20 12:00:00 -0700592}
593
David Benjamin325b5c32014-07-01 19:40:31 -0400594func gdbOf(path string, args ...string) *exec.Cmd {
595 xtermArgs := []string{"-e", "gdb", "--args"}
596 xtermArgs = append(xtermArgs, path)
597 xtermArgs = append(xtermArgs, args...)
Adam Langley95c29f32014-06-20 12:00:00 -0700598
David Benjamin325b5c32014-07-01 19:40:31 -0400599 return exec.Command("xterm", xtermArgs...)
Adam Langley95c29f32014-06-20 12:00:00 -0700600}
601
David Benjamind16bf342015-12-18 00:53:12 -0500602func lldbOf(path string, args ...string) *exec.Cmd {
603 xtermArgs := []string{"-e", "lldb", "--"}
604 xtermArgs = append(xtermArgs, path)
605 xtermArgs = append(xtermArgs, args...)
606
607 return exec.Command("xterm", xtermArgs...)
608}
609
Adam Langley69a01602014-11-17 17:26:55 -0800610type moreMallocsError struct{}
611
612func (moreMallocsError) Error() string {
613 return "child process did not exhaust all allocation calls"
614}
615
616var errMoreMallocs = moreMallocsError{}
617
David Benjamin87c8a642015-02-21 01:54:29 -0500618// accept accepts a connection from listener, unless waitChan signals a process
619// exit first.
620func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error) {
621 type connOrError struct {
622 conn net.Conn
623 err error
624 }
625 connChan := make(chan connOrError, 1)
626 go func() {
627 conn, err := listener.Accept()
628 connChan <- connOrError{conn, err}
629 close(connChan)
630 }()
631 select {
632 case result := <-connChan:
633 return result.conn, result.err
634 case childErr := <-waitChan:
635 waitChan <- childErr
636 return nil, fmt.Errorf("child exited early: %s", childErr)
637 }
638}
639
Adam Langley7c803a62015-06-15 15:35:05 -0700640func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
Adam Langley38311732014-10-16 19:04:35 -0700641 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
642 panic("Error expected without shouldFail in " + test.name)
643 }
644
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700645 if test.expectResumeRejected && !test.resumeSession {
646 panic("expectResumeRejected without resumeSession in " + test.name)
647 }
648
Steven Valdez0d62f262015-09-04 12:41:04 -0400649 if test.testType != clientTest && test.expectedClientCertSignatureHash != 0 {
650 panic("expectedClientCertSignatureHash non-zero with serverTest in " + test.name)
651 }
652
David Benjamin87c8a642015-02-21 01:54:29 -0500653 listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
654 if err != nil {
655 panic(err)
656 }
657 defer func() {
658 if listener != nil {
659 listener.Close()
660 }
661 }()
Adam Langley95c29f32014-06-20 12:00:00 -0700662
David Benjamin87c8a642015-02-21 01:54:29 -0500663 flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
David Benjamin1d5c83e2014-07-22 19:20:02 -0400664 if test.testType == serverTest {
David Benjamin5a593af2014-08-11 19:51:50 -0400665 flags = append(flags, "-server")
666
David Benjamin025b3d32014-07-01 19:53:04 -0400667 flags = append(flags, "-key-file")
668 if test.keyFile == "" {
Adam Langley7c803a62015-06-15 15:35:05 -0700669 flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400670 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700671 flags = append(flags, path.Join(*resourceDir, test.keyFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400672 }
673
674 flags = append(flags, "-cert-file")
675 if test.certFile == "" {
Adam Langley7c803a62015-06-15 15:35:05 -0700676 flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400677 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700678 flags = append(flags, path.Join(*resourceDir, test.certFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400679 }
680 }
David Benjamin5a593af2014-08-11 19:51:50 -0400681
Steven Valdez0d62f262015-09-04 12:41:04 -0400682 if test.digestPrefs != "" {
683 flags = append(flags, "-digest-prefs")
684 flags = append(flags, test.digestPrefs)
685 }
686
David Benjamin6fd297b2014-08-11 18:43:38 -0400687 if test.protocol == dtls {
688 flags = append(flags, "-dtls")
689 }
690
David Benjamin5a593af2014-08-11 19:51:50 -0400691 if test.resumeSession {
692 flags = append(flags, "-resume")
693 }
694
David Benjamine58c4f52014-08-24 03:47:07 -0400695 if test.shimWritesFirst {
696 flags = append(flags, "-shim-writes-first")
697 }
698
David Benjamin30789da2015-08-29 22:56:45 -0400699 if test.shimShutsDown {
700 flags = append(flags, "-shim-shuts-down")
701 }
702
David Benjaminc565ebb2015-04-03 04:06:36 -0400703 if test.exportKeyingMaterial > 0 {
704 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
705 flags = append(flags, "-export-label", test.exportLabel)
706 flags = append(flags, "-export-context", test.exportContext)
707 if test.useExportContext {
708 flags = append(flags, "-use-export-context")
709 }
710 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700711 if test.expectResumeRejected {
712 flags = append(flags, "-expect-session-miss")
713 }
David Benjaminc565ebb2015-04-03 04:06:36 -0400714
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700715 if test.testTLSUnique {
716 flags = append(flags, "-tls-unique")
717 }
718
David Benjamin025b3d32014-07-01 19:53:04 -0400719 flags = append(flags, test.flags...)
720
721 var shim *exec.Cmd
722 if *useValgrind {
Adam Langley7c803a62015-06-15 15:35:05 -0700723 shim = valgrindOf(false, shimPath, flags...)
Adam Langley75712922014-10-10 16:23:43 -0700724 } else if *useGDB {
Adam Langley7c803a62015-06-15 15:35:05 -0700725 shim = gdbOf(shimPath, flags...)
David Benjamind16bf342015-12-18 00:53:12 -0500726 } else if *useLLDB {
727 shim = lldbOf(shimPath, flags...)
David Benjamin025b3d32014-07-01 19:53:04 -0400728 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700729 shim = exec.Command(shimPath, flags...)
David Benjamin025b3d32014-07-01 19:53:04 -0400730 }
David Benjamin025b3d32014-07-01 19:53:04 -0400731 shim.Stdin = os.Stdin
732 var stdoutBuf, stderrBuf bytes.Buffer
733 shim.Stdout = &stdoutBuf
734 shim.Stderr = &stderrBuf
Adam Langley69a01602014-11-17 17:26:55 -0800735 if mallocNumToFail >= 0 {
David Benjamin9e128b02015-02-09 13:13:09 -0500736 shim.Env = os.Environ()
737 shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
Adam Langley69a01602014-11-17 17:26:55 -0800738 if *mallocTestDebug {
David Benjamin184494d2015-06-12 18:23:47 -0400739 shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
Adam Langley69a01602014-11-17 17:26:55 -0800740 }
741 shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
742 }
David Benjamin025b3d32014-07-01 19:53:04 -0400743
744 if err := shim.Start(); err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700745 panic(err)
746 }
David Benjamin87c8a642015-02-21 01:54:29 -0500747 waitChan := make(chan error, 1)
748 go func() { waitChan <- shim.Wait() }()
Adam Langley95c29f32014-06-20 12:00:00 -0700749
750 config := test.config
David Benjaminba4594a2015-06-18 18:36:15 -0400751 if !test.noSessionCache {
752 config.ClientSessionCache = NewLRUClientSessionCache(1)
753 config.ServerSessionCache = NewLRUServerSessionCache(1)
754 }
David Benjamin025b3d32014-07-01 19:53:04 -0400755 if test.testType == clientTest {
756 if len(config.Certificates) == 0 {
757 config.Certificates = []Certificate{getRSACertificate()}
758 }
David Benjamin87c8a642015-02-21 01:54:29 -0500759 } else {
760 // Supply a ServerName to ensure a constant session cache key,
761 // rather than falling back to net.Conn.RemoteAddr.
762 if len(config.ServerName) == 0 {
763 config.ServerName = "test"
764 }
David Benjamin025b3d32014-07-01 19:53:04 -0400765 }
David Benjaminf2b83632016-03-01 22:57:46 -0500766 if *fuzzer {
767 config.Bugs.NullAllCiphers = true
768 }
David Benjamin2e045a92016-06-08 13:09:56 -0400769 if *deterministic {
770 config.Rand = &deterministicRand{}
771 }
Adam Langley95c29f32014-06-20 12:00:00 -0700772
David Benjamin87c8a642015-02-21 01:54:29 -0500773 conn, err := acceptOrWait(listener, waitChan)
774 if err == nil {
David Benjamin8e6db492015-07-25 18:29:23 -0400775 err = doExchange(test, &config, conn, false /* not a resumption */)
David Benjamin87c8a642015-02-21 01:54:29 -0500776 conn.Close()
777 }
David Benjamin65ea8ff2014-11-23 03:01:00 -0500778
David Benjamin1d5c83e2014-07-22 19:20:02 -0400779 if err == nil && test.resumeSession {
David Benjamin01fe8202014-09-24 15:21:44 -0400780 var resumeConfig Config
781 if test.resumeConfig != nil {
782 resumeConfig = *test.resumeConfig
David Benjamin87c8a642015-02-21 01:54:29 -0500783 if len(resumeConfig.ServerName) == 0 {
784 resumeConfig.ServerName = config.ServerName
785 }
David Benjamin01fe8202014-09-24 15:21:44 -0400786 if len(resumeConfig.Certificates) == 0 {
787 resumeConfig.Certificates = []Certificate{getRSACertificate()}
788 }
David Benjaminba4594a2015-06-18 18:36:15 -0400789 if test.newSessionsOnResume {
790 if !test.noSessionCache {
791 resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
792 resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
793 }
794 } else {
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500795 resumeConfig.SessionTicketKey = config.SessionTicketKey
796 resumeConfig.ClientSessionCache = config.ClientSessionCache
797 resumeConfig.ServerSessionCache = config.ServerSessionCache
798 }
David Benjaminf2b83632016-03-01 22:57:46 -0500799 if *fuzzer {
800 resumeConfig.Bugs.NullAllCiphers = true
801 }
David Benjamin2e045a92016-06-08 13:09:56 -0400802 resumeConfig.Rand = config.Rand
David Benjamin01fe8202014-09-24 15:21:44 -0400803 } else {
804 resumeConfig = config
805 }
David Benjamin87c8a642015-02-21 01:54:29 -0500806 var connResume net.Conn
807 connResume, err = acceptOrWait(listener, waitChan)
808 if err == nil {
David Benjamin8e6db492015-07-25 18:29:23 -0400809 err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
David Benjamin87c8a642015-02-21 01:54:29 -0500810 connResume.Close()
811 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400812 }
813
David Benjamin87c8a642015-02-21 01:54:29 -0500814 // Close the listener now. This is to avoid hangs should the shim try to
815 // open more connections than expected.
816 listener.Close()
817 listener = nil
818
819 childErr := <-waitChan
Adam Langley69a01602014-11-17 17:26:55 -0800820 if exitError, ok := childErr.(*exec.ExitError); ok {
821 if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 {
822 return errMoreMallocs
823 }
824 }
Adam Langley95c29f32014-06-20 12:00:00 -0700825
David Benjamin9bea3492016-03-02 10:59:16 -0500826 // Account for Windows line endings.
827 stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1)
828 stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1)
David Benjaminff3a1492016-03-02 10:12:06 -0500829
830 // Separate the errors from the shim and those from tools like
831 // AddressSanitizer.
832 var extraStderr string
833 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 {
834 stderr = stderrParts[0]
835 extraStderr = stderrParts[1]
836 }
837
Adam Langley95c29f32014-06-20 12:00:00 -0700838 failed := err != nil || childErr != nil
David Benjaminc565ebb2015-04-03 04:06:36 -0400839 correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError)
Adam Langleyac61fa32014-06-23 12:03:11 -0700840 localError := "none"
841 if err != nil {
842 localError = err.Error()
843 }
844 if len(test.expectedLocalError) != 0 {
845 correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
846 }
Adam Langley95c29f32014-06-20 12:00:00 -0700847
848 if failed != test.shouldFail || failed && !correctFailure {
Adam Langley95c29f32014-06-20 12:00:00 -0700849 childError := "none"
Adam Langley95c29f32014-06-20 12:00:00 -0700850 if childErr != nil {
851 childError = childErr.Error()
852 }
853
854 var msg string
855 switch {
856 case failed && !test.shouldFail:
857 msg = "unexpected failure"
858 case !failed && test.shouldFail:
859 msg = "unexpected success"
860 case failed && !correctFailure:
Adam Langleyac61fa32014-06-23 12:03:11 -0700861 msg = "bad error (wanted '" + test.expectedError + "' / '" + test.expectedLocalError + "')"
Adam Langley95c29f32014-06-20 12:00:00 -0700862 default:
863 panic("internal error")
864 }
865
David Benjaminc565ebb2015-04-03 04:06:36 -0400866 return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, stdout, stderr)
Adam Langley95c29f32014-06-20 12:00:00 -0700867 }
868
David Benjaminff3a1492016-03-02 10:12:06 -0500869 if !*useValgrind && (len(extraStderr) > 0 || (!failed && len(stderr) > 0)) {
870 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr)
Adam Langley95c29f32014-06-20 12:00:00 -0700871 }
872
873 return nil
874}
875
876var tlsVersions = []struct {
877 name string
878 version uint16
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400879 flag string
David Benjamin8b8c0062014-11-23 02:47:52 -0500880 hasDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -0700881}{
David Benjamin8b8c0062014-11-23 02:47:52 -0500882 {"SSL3", VersionSSL30, "-no-ssl3", false},
883 {"TLS1", VersionTLS10, "-no-tls1", true},
884 {"TLS11", VersionTLS11, "-no-tls11", false},
885 {"TLS12", VersionTLS12, "-no-tls12", true},
Nick Harper1fd39d82016-06-14 18:14:35 -0700886 // TODO(nharper): Once we have a real implementation of TLS 1.3, update the name here.
887 {"FakeTLS13", VersionTLS13, "-no-tls13", false},
Adam Langley95c29f32014-06-20 12:00:00 -0700888}
889
890var testCipherSuites = []struct {
891 name string
892 id uint16
893}{
894 {"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400895 {"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -0700896 {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400897 {"AES128-SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400898 {"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -0700899 {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400900 {"AES256-SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400901 {"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
902 {"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400903 {"DHE-RSA-AES128-SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400904 {"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
905 {"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400906 {"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -0700907 {"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
908 {"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400909 {"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
910 {"ECDHE-ECDSA-AES256-GCM", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -0700911 {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400912 {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
David Benjamin13414b32015-12-09 23:02:39 -0500913 {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
David Benjamine3203922015-12-09 21:21:31 -0500914 {"ECDHE-ECDSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
Adam Langley95c29f32014-06-20 12:00:00 -0700915 {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -0700916 {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -0700917 {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400918 {"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400919 {"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -0700920 {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400921 {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
David Benjamin13414b32015-12-09 23:02:39 -0500922 {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
David Benjamine3203922015-12-09 21:21:31 -0500923 {"ECDHE-RSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
Adam Langley95c29f32014-06-20 12:00:00 -0700924 {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
Matt Braithwaite053931e2016-05-25 12:06:05 -0700925 {"CECPQ1-RSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256},
926 {"CECPQ1-ECDSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
927 {"CECPQ1-RSA-AES256-GCM-SHA384", TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
928 {"CECPQ1-ECDSA-AES256-GCM-SHA384", TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384},
David Benjamin48cae082014-10-27 01:06:24 -0400929 {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
930 {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
Adam Langley85bc5602015-06-09 09:54:04 -0700931 {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
932 {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
David Benjamin13414b32015-12-09 23:02:39 -0500933 {"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
Steven Valdez3084e7b2016-06-02 12:07:20 -0400934 {"ECDHE-PSK-AES128-GCM-SHA256", TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256},
935 {"ECDHE-PSK-AES256-GCM-SHA384", TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384},
David Benjamin48cae082014-10-27 01:06:24 -0400936 {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -0700937 {"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400938 {"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700939 {"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -0700940}
941
David Benjamin8b8c0062014-11-23 02:47:52 -0500942func hasComponent(suiteName, component string) bool {
943 return strings.Contains("-"+suiteName+"-", "-"+component+"-")
944}
945
David Benjaminf7768e42014-08-31 02:06:47 -0400946func isTLS12Only(suiteName string) bool {
David Benjamin8b8c0062014-11-23 02:47:52 -0500947 return hasComponent(suiteName, "GCM") ||
948 hasComponent(suiteName, "SHA256") ||
David Benjamine9a80ff2015-04-07 00:46:46 -0400949 hasComponent(suiteName, "SHA384") ||
950 hasComponent(suiteName, "POLY1305")
David Benjamin8b8c0062014-11-23 02:47:52 -0500951}
952
Nick Harper1fd39d82016-06-14 18:14:35 -0700953func isTLS13Suite(suiteName string) bool {
954 return (hasComponent(suiteName, "GCM") || hasComponent(suiteName, "POLY1305")) && hasComponent(suiteName, "ECDHE") && !hasComponent(suiteName, "OLD")
955}
956
David Benjamin8b8c0062014-11-23 02:47:52 -0500957func isDTLSCipher(suiteName string) bool {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700958 return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL")
David Benjaminf7768e42014-08-31 02:06:47 -0400959}
960
Adam Langleya7997f12015-05-14 17:38:50 -0700961func bigFromHex(hex string) *big.Int {
962 ret, ok := new(big.Int).SetString(hex, 16)
963 if !ok {
964 panic("failed to parse hex number 0x" + hex)
965 }
966 return ret
967}
968
Adam Langley7c803a62015-06-15 15:35:05 -0700969func addBasicTests() {
970 basicTests := []testCase{
971 {
972 name: "BadRSASignature",
973 config: Config{
974 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
975 Bugs: ProtocolBugs{
976 InvalidSKXSignature: true,
977 },
978 },
979 shouldFail: true,
980 expectedError: ":BAD_SIGNATURE:",
981 },
982 {
983 name: "BadECDSASignature",
984 config: Config{
985 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
986 Bugs: ProtocolBugs{
987 InvalidSKXSignature: true,
988 },
989 Certificates: []Certificate{getECDSACertificate()},
990 },
991 shouldFail: true,
992 expectedError: ":BAD_SIGNATURE:",
993 },
994 {
David Benjamin6de0e532015-07-28 22:43:19 -0400995 testType: serverTest,
996 name: "BadRSASignature-ClientAuth",
997 config: Config{
998 Bugs: ProtocolBugs{
999 InvalidCertVerifySignature: true,
1000 },
1001 Certificates: []Certificate{getRSACertificate()},
1002 },
1003 shouldFail: true,
1004 expectedError: ":BAD_SIGNATURE:",
1005 flags: []string{"-require-any-client-certificate"},
1006 },
1007 {
1008 testType: serverTest,
1009 name: "BadECDSASignature-ClientAuth",
1010 config: Config{
1011 Bugs: ProtocolBugs{
1012 InvalidCertVerifySignature: true,
1013 },
1014 Certificates: []Certificate{getECDSACertificate()},
1015 },
1016 shouldFail: true,
1017 expectedError: ":BAD_SIGNATURE:",
1018 flags: []string{"-require-any-client-certificate"},
1019 },
1020 {
Adam Langley7c803a62015-06-15 15:35:05 -07001021 name: "BadECDSACurve",
1022 config: Config{
1023 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
1024 Bugs: ProtocolBugs{
1025 InvalidSKXCurve: true,
1026 },
1027 Certificates: []Certificate{getECDSACertificate()},
1028 },
1029 shouldFail: true,
1030 expectedError: ":WRONG_CURVE:",
1031 },
1032 {
Adam Langley7c803a62015-06-15 15:35:05 -07001033 name: "NoFallbackSCSV",
1034 config: Config{
1035 Bugs: ProtocolBugs{
1036 FailIfNotFallbackSCSV: true,
1037 },
1038 },
1039 shouldFail: true,
1040 expectedLocalError: "no fallback SCSV found",
1041 },
1042 {
1043 name: "SendFallbackSCSV",
1044 config: Config{
1045 Bugs: ProtocolBugs{
1046 FailIfNotFallbackSCSV: true,
1047 },
1048 },
1049 flags: []string{"-fallback-scsv"},
1050 },
1051 {
1052 name: "ClientCertificateTypes",
1053 config: Config{
1054 ClientAuth: RequestClientCert,
1055 ClientCertificateTypes: []byte{
1056 CertTypeDSSSign,
1057 CertTypeRSASign,
1058 CertTypeECDSASign,
1059 },
1060 },
1061 flags: []string{
1062 "-expect-certificate-types",
1063 base64.StdEncoding.EncodeToString([]byte{
1064 CertTypeDSSSign,
1065 CertTypeRSASign,
1066 CertTypeECDSASign,
1067 }),
1068 },
1069 },
1070 {
1071 name: "NoClientCertificate",
1072 config: Config{
1073 ClientAuth: RequireAnyClientCert,
1074 },
1075 shouldFail: true,
1076 expectedLocalError: "client didn't provide a certificate",
1077 },
1078 {
1079 name: "UnauthenticatedECDH",
1080 config: Config{
1081 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1082 Bugs: ProtocolBugs{
1083 UnauthenticatedECDH: true,
1084 },
1085 },
1086 shouldFail: true,
1087 expectedError: ":UNEXPECTED_MESSAGE:",
1088 },
1089 {
1090 name: "SkipCertificateStatus",
1091 config: Config{
1092 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1093 Bugs: ProtocolBugs{
1094 SkipCertificateStatus: true,
1095 },
1096 },
1097 flags: []string{
1098 "-enable-ocsp-stapling",
1099 },
1100 },
1101 {
1102 name: "SkipServerKeyExchange",
1103 config: Config{
1104 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1105 Bugs: ProtocolBugs{
1106 SkipServerKeyExchange: true,
1107 },
1108 },
1109 shouldFail: true,
1110 expectedError: ":UNEXPECTED_MESSAGE:",
1111 },
1112 {
1113 name: "SkipChangeCipherSpec-Client",
1114 config: Config{
1115 Bugs: ProtocolBugs{
1116 SkipChangeCipherSpec: true,
1117 },
1118 },
1119 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001120 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001121 },
1122 {
1123 testType: serverTest,
1124 name: "SkipChangeCipherSpec-Server",
1125 config: Config{
1126 Bugs: ProtocolBugs{
1127 SkipChangeCipherSpec: true,
1128 },
1129 },
1130 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001131 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001132 },
1133 {
1134 testType: serverTest,
1135 name: "SkipChangeCipherSpec-Server-NPN",
1136 config: Config{
1137 NextProtos: []string{"bar"},
1138 Bugs: ProtocolBugs{
1139 SkipChangeCipherSpec: true,
1140 },
1141 },
1142 flags: []string{
1143 "-advertise-npn", "\x03foo\x03bar\x03baz",
1144 },
1145 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001146 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001147 },
1148 {
1149 name: "FragmentAcrossChangeCipherSpec-Client",
1150 config: Config{
1151 Bugs: ProtocolBugs{
1152 FragmentAcrossChangeCipherSpec: true,
1153 },
1154 },
1155 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001156 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001157 },
1158 {
1159 testType: serverTest,
1160 name: "FragmentAcrossChangeCipherSpec-Server",
1161 config: Config{
1162 Bugs: ProtocolBugs{
1163 FragmentAcrossChangeCipherSpec: true,
1164 },
1165 },
1166 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001167 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001168 },
1169 {
1170 testType: serverTest,
1171 name: "FragmentAcrossChangeCipherSpec-Server-NPN",
1172 config: Config{
1173 NextProtos: []string{"bar"},
1174 Bugs: ProtocolBugs{
1175 FragmentAcrossChangeCipherSpec: true,
1176 },
1177 },
1178 flags: []string{
1179 "-advertise-npn", "\x03foo\x03bar\x03baz",
1180 },
1181 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001182 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001183 },
1184 {
1185 testType: serverTest,
1186 name: "Alert",
1187 config: Config{
1188 Bugs: ProtocolBugs{
1189 SendSpuriousAlert: alertRecordOverflow,
1190 },
1191 },
1192 shouldFail: true,
1193 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1194 },
1195 {
1196 protocol: dtls,
1197 testType: serverTest,
1198 name: "Alert-DTLS",
1199 config: Config{
1200 Bugs: ProtocolBugs{
1201 SendSpuriousAlert: alertRecordOverflow,
1202 },
1203 },
1204 shouldFail: true,
1205 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1206 },
1207 {
1208 testType: serverTest,
1209 name: "FragmentAlert",
1210 config: Config{
1211 Bugs: ProtocolBugs{
1212 FragmentAlert: true,
1213 SendSpuriousAlert: alertRecordOverflow,
1214 },
1215 },
1216 shouldFail: true,
1217 expectedError: ":BAD_ALERT:",
1218 },
1219 {
1220 protocol: dtls,
1221 testType: serverTest,
1222 name: "FragmentAlert-DTLS",
1223 config: Config{
1224 Bugs: ProtocolBugs{
1225 FragmentAlert: true,
1226 SendSpuriousAlert: alertRecordOverflow,
1227 },
1228 },
1229 shouldFail: true,
1230 expectedError: ":BAD_ALERT:",
1231 },
1232 {
1233 testType: serverTest,
David Benjamin0d3a8c62016-03-11 22:25:18 -05001234 name: "DoubleAlert",
1235 config: Config{
1236 Bugs: ProtocolBugs{
1237 DoubleAlert: true,
1238 SendSpuriousAlert: alertRecordOverflow,
1239 },
1240 },
1241 shouldFail: true,
1242 expectedError: ":BAD_ALERT:",
1243 },
1244 {
1245 protocol: dtls,
1246 testType: serverTest,
1247 name: "DoubleAlert-DTLS",
1248 config: Config{
1249 Bugs: ProtocolBugs{
1250 DoubleAlert: true,
1251 SendSpuriousAlert: alertRecordOverflow,
1252 },
1253 },
1254 shouldFail: true,
1255 expectedError: ":BAD_ALERT:",
1256 },
1257 {
1258 testType: serverTest,
Adam Langley7c803a62015-06-15 15:35:05 -07001259 name: "EarlyChangeCipherSpec-server-1",
1260 config: Config{
1261 Bugs: ProtocolBugs{
1262 EarlyChangeCipherSpec: 1,
1263 },
1264 },
1265 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001266 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001267 },
1268 {
1269 testType: serverTest,
1270 name: "EarlyChangeCipherSpec-server-2",
1271 config: Config{
1272 Bugs: ProtocolBugs{
1273 EarlyChangeCipherSpec: 2,
1274 },
1275 },
1276 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001277 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001278 },
1279 {
David Benjamin8144f992016-06-22 17:05:13 -04001280 protocol: dtls,
1281 name: "StrayChangeCipherSpec",
1282 config: Config{
1283 Bugs: ProtocolBugs{
1284 StrayChangeCipherSpec: true,
1285 },
1286 },
1287 },
1288 {
Adam Langley7c803a62015-06-15 15:35:05 -07001289 name: "SkipNewSessionTicket",
1290 config: Config{
1291 Bugs: ProtocolBugs{
1292 SkipNewSessionTicket: true,
1293 },
1294 },
1295 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001296 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001297 },
1298 {
1299 testType: serverTest,
1300 name: "FallbackSCSV",
1301 config: Config{
1302 MaxVersion: VersionTLS11,
1303 Bugs: ProtocolBugs{
1304 SendFallbackSCSV: true,
1305 },
1306 },
1307 shouldFail: true,
1308 expectedError: ":INAPPROPRIATE_FALLBACK:",
1309 },
1310 {
1311 testType: serverTest,
1312 name: "FallbackSCSV-VersionMatch",
1313 config: Config{
1314 Bugs: ProtocolBugs{
1315 SendFallbackSCSV: true,
1316 },
1317 },
1318 },
1319 {
1320 testType: serverTest,
1321 name: "FragmentedClientVersion",
1322 config: Config{
1323 Bugs: ProtocolBugs{
1324 MaxHandshakeRecordLength: 1,
1325 FragmentClientVersion: true,
1326 },
1327 },
Nick Harper1fd39d82016-06-14 18:14:35 -07001328 expectedVersion: VersionTLS13,
Adam Langley7c803a62015-06-15 15:35:05 -07001329 },
1330 {
1331 testType: serverTest,
1332 name: "MinorVersionTolerance",
1333 config: Config{
1334 Bugs: ProtocolBugs{
1335 SendClientVersion: 0x03ff,
1336 },
1337 },
Nick Harper1fd39d82016-06-14 18:14:35 -07001338 expectedVersion: VersionTLS13,
Adam Langley7c803a62015-06-15 15:35:05 -07001339 },
1340 {
1341 testType: serverTest,
1342 name: "MajorVersionTolerance",
1343 config: Config{
1344 Bugs: ProtocolBugs{
1345 SendClientVersion: 0x0400,
1346 },
1347 },
Nick Harper1fd39d82016-06-14 18:14:35 -07001348 expectedVersion: VersionTLS13,
Adam Langley7c803a62015-06-15 15:35:05 -07001349 },
1350 {
1351 testType: serverTest,
1352 name: "VersionTooLow",
1353 config: Config{
1354 Bugs: ProtocolBugs{
1355 SendClientVersion: 0x0200,
1356 },
1357 },
1358 shouldFail: true,
1359 expectedError: ":UNSUPPORTED_PROTOCOL:",
1360 },
1361 {
1362 testType: serverTest,
1363 name: "HttpGET",
1364 sendPrefix: "GET / HTTP/1.0\n",
1365 shouldFail: true,
1366 expectedError: ":HTTP_REQUEST:",
1367 },
1368 {
1369 testType: serverTest,
1370 name: "HttpPOST",
1371 sendPrefix: "POST / HTTP/1.0\n",
1372 shouldFail: true,
1373 expectedError: ":HTTP_REQUEST:",
1374 },
1375 {
1376 testType: serverTest,
1377 name: "HttpHEAD",
1378 sendPrefix: "HEAD / HTTP/1.0\n",
1379 shouldFail: true,
1380 expectedError: ":HTTP_REQUEST:",
1381 },
1382 {
1383 testType: serverTest,
1384 name: "HttpPUT",
1385 sendPrefix: "PUT / HTTP/1.0\n",
1386 shouldFail: true,
1387 expectedError: ":HTTP_REQUEST:",
1388 },
1389 {
1390 testType: serverTest,
1391 name: "HttpCONNECT",
1392 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
1393 shouldFail: true,
1394 expectedError: ":HTTPS_PROXY_REQUEST:",
1395 },
1396 {
1397 testType: serverTest,
1398 name: "Garbage",
1399 sendPrefix: "blah",
1400 shouldFail: true,
David Benjamin97760d52015-07-24 23:02:49 -04001401 expectedError: ":WRONG_VERSION_NUMBER:",
Adam Langley7c803a62015-06-15 15:35:05 -07001402 },
1403 {
Adam Langley7c803a62015-06-15 15:35:05 -07001404 name: "RSAEphemeralKey",
1405 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001406 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001407 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
1408 Bugs: ProtocolBugs{
1409 RSAEphemeralKey: true,
1410 },
1411 },
1412 shouldFail: true,
1413 expectedError: ":UNEXPECTED_MESSAGE:",
1414 },
1415 {
1416 name: "DisableEverything",
Steven Valdez4f94b1c2016-05-24 12:31:07 -04001417 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
Adam Langley7c803a62015-06-15 15:35:05 -07001418 shouldFail: true,
1419 expectedError: ":WRONG_SSL_VERSION:",
1420 },
1421 {
1422 protocol: dtls,
1423 name: "DisableEverything-DTLS",
1424 flags: []string{"-no-tls12", "-no-tls1"},
1425 shouldFail: true,
1426 expectedError: ":WRONG_SSL_VERSION:",
1427 },
1428 {
1429 name: "NoSharedCipher",
1430 config: Config{
1431 CipherSuites: []uint16{},
1432 },
1433 shouldFail: true,
1434 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
1435 },
1436 {
1437 protocol: dtls,
1438 testType: serverTest,
1439 name: "MTU",
1440 config: Config{
1441 Bugs: ProtocolBugs{
1442 MaxPacketLength: 256,
1443 },
1444 },
1445 flags: []string{"-mtu", "256"},
1446 },
1447 {
1448 protocol: dtls,
1449 testType: serverTest,
1450 name: "MTUExceeded",
1451 config: Config{
1452 Bugs: ProtocolBugs{
1453 MaxPacketLength: 255,
1454 },
1455 },
1456 flags: []string{"-mtu", "256"},
1457 shouldFail: true,
1458 expectedLocalError: "dtls: exceeded maximum packet length",
1459 },
1460 {
1461 name: "CertMismatchRSA",
1462 config: Config{
1463 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
1464 Certificates: []Certificate{getECDSACertificate()},
1465 Bugs: ProtocolBugs{
1466 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1467 },
1468 },
1469 shouldFail: true,
1470 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1471 },
1472 {
1473 name: "CertMismatchECDSA",
1474 config: Config{
1475 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1476 Certificates: []Certificate{getRSACertificate()},
1477 Bugs: ProtocolBugs{
1478 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1479 },
1480 },
1481 shouldFail: true,
1482 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1483 },
1484 {
1485 name: "EmptyCertificateList",
1486 config: Config{
1487 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1488 Bugs: ProtocolBugs{
1489 EmptyCertificateList: true,
1490 },
1491 },
1492 shouldFail: true,
1493 expectedError: ":DECODE_ERROR:",
1494 },
1495 {
1496 name: "TLSFatalBadPackets",
1497 damageFirstWrite: true,
1498 shouldFail: true,
1499 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
1500 },
1501 {
1502 protocol: dtls,
1503 name: "DTLSIgnoreBadPackets",
1504 damageFirstWrite: true,
1505 },
1506 {
1507 protocol: dtls,
1508 name: "DTLSIgnoreBadPackets-Async",
1509 damageFirstWrite: true,
1510 flags: []string{"-async"},
1511 },
1512 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001513 name: "AppDataBeforeHandshake",
1514 config: Config{
1515 Bugs: ProtocolBugs{
1516 AppDataBeforeHandshake: []byte("TEST MESSAGE"),
1517 },
1518 },
1519 shouldFail: true,
1520 expectedError: ":UNEXPECTED_RECORD:",
1521 },
1522 {
1523 name: "AppDataBeforeHandshake-Empty",
1524 config: Config{
1525 Bugs: ProtocolBugs{
1526 AppDataBeforeHandshake: []byte{},
1527 },
1528 },
1529 shouldFail: true,
1530 expectedError: ":UNEXPECTED_RECORD:",
1531 },
1532 {
1533 protocol: dtls,
1534 name: "AppDataBeforeHandshake-DTLS",
1535 config: Config{
1536 Bugs: ProtocolBugs{
1537 AppDataBeforeHandshake: []byte("TEST MESSAGE"),
1538 },
1539 },
1540 shouldFail: true,
1541 expectedError: ":UNEXPECTED_RECORD:",
1542 },
1543 {
1544 protocol: dtls,
1545 name: "AppDataBeforeHandshake-DTLS-Empty",
1546 config: Config{
1547 Bugs: ProtocolBugs{
1548 AppDataBeforeHandshake: []byte{},
1549 },
1550 },
1551 shouldFail: true,
1552 expectedError: ":UNEXPECTED_RECORD:",
1553 },
1554 {
Adam Langley7c803a62015-06-15 15:35:05 -07001555 name: "AppDataAfterChangeCipherSpec",
1556 config: Config{
1557 Bugs: ProtocolBugs{
1558 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
1559 },
1560 },
1561 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001562 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001563 },
1564 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001565 name: "AppDataAfterChangeCipherSpec-Empty",
1566 config: Config{
1567 Bugs: ProtocolBugs{
1568 AppDataAfterChangeCipherSpec: []byte{},
1569 },
1570 },
1571 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001572 expectedError: ":UNEXPECTED_RECORD:",
David Benjamin4cf369b2015-08-22 01:35:43 -04001573 },
1574 {
Adam Langley7c803a62015-06-15 15:35:05 -07001575 protocol: dtls,
1576 name: "AppDataAfterChangeCipherSpec-DTLS",
1577 config: Config{
1578 Bugs: ProtocolBugs{
1579 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
1580 },
1581 },
1582 // BoringSSL's DTLS implementation will drop the out-of-order
1583 // application data.
1584 },
1585 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001586 protocol: dtls,
1587 name: "AppDataAfterChangeCipherSpec-DTLS-Empty",
1588 config: Config{
1589 Bugs: ProtocolBugs{
1590 AppDataAfterChangeCipherSpec: []byte{},
1591 },
1592 },
1593 // BoringSSL's DTLS implementation will drop the out-of-order
1594 // application data.
1595 },
1596 {
Adam Langley7c803a62015-06-15 15:35:05 -07001597 name: "AlertAfterChangeCipherSpec",
1598 config: Config{
1599 Bugs: ProtocolBugs{
1600 AlertAfterChangeCipherSpec: alertRecordOverflow,
1601 },
1602 },
1603 shouldFail: true,
1604 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1605 },
1606 {
1607 protocol: dtls,
1608 name: "AlertAfterChangeCipherSpec-DTLS",
1609 config: Config{
1610 Bugs: ProtocolBugs{
1611 AlertAfterChangeCipherSpec: alertRecordOverflow,
1612 },
1613 },
1614 shouldFail: true,
1615 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1616 },
1617 {
1618 protocol: dtls,
1619 name: "ReorderHandshakeFragments-Small-DTLS",
1620 config: Config{
1621 Bugs: ProtocolBugs{
1622 ReorderHandshakeFragments: true,
1623 // Small enough that every handshake message is
1624 // fragmented.
1625 MaxHandshakeRecordLength: 2,
1626 },
1627 },
1628 },
1629 {
1630 protocol: dtls,
1631 name: "ReorderHandshakeFragments-Large-DTLS",
1632 config: Config{
1633 Bugs: ProtocolBugs{
1634 ReorderHandshakeFragments: true,
1635 // Large enough that no handshake message is
1636 // fragmented.
1637 MaxHandshakeRecordLength: 2048,
1638 },
1639 },
1640 },
1641 {
1642 protocol: dtls,
1643 name: "MixCompleteMessageWithFragments-DTLS",
1644 config: Config{
1645 Bugs: ProtocolBugs{
1646 ReorderHandshakeFragments: true,
1647 MixCompleteMessageWithFragments: true,
1648 MaxHandshakeRecordLength: 2,
1649 },
1650 },
1651 },
1652 {
1653 name: "SendInvalidRecordType",
1654 config: Config{
1655 Bugs: ProtocolBugs{
1656 SendInvalidRecordType: true,
1657 },
1658 },
1659 shouldFail: true,
1660 expectedError: ":UNEXPECTED_RECORD:",
1661 },
1662 {
1663 protocol: dtls,
1664 name: "SendInvalidRecordType-DTLS",
1665 config: Config{
1666 Bugs: ProtocolBugs{
1667 SendInvalidRecordType: true,
1668 },
1669 },
1670 shouldFail: true,
1671 expectedError: ":UNEXPECTED_RECORD:",
1672 },
1673 {
1674 name: "FalseStart-SkipServerSecondLeg",
1675 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001676 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001677 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1678 NextProtos: []string{"foo"},
1679 Bugs: ProtocolBugs{
1680 SkipNewSessionTicket: true,
1681 SkipChangeCipherSpec: true,
1682 SkipFinished: true,
1683 ExpectFalseStart: true,
1684 },
1685 },
1686 flags: []string{
1687 "-false-start",
1688 "-handshake-never-done",
1689 "-advertise-alpn", "\x03foo",
1690 },
1691 shimWritesFirst: true,
1692 shouldFail: true,
1693 expectedError: ":UNEXPECTED_RECORD:",
1694 },
1695 {
1696 name: "FalseStart-SkipServerSecondLeg-Implicit",
1697 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001698 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001699 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1700 NextProtos: []string{"foo"},
1701 Bugs: ProtocolBugs{
1702 SkipNewSessionTicket: true,
1703 SkipChangeCipherSpec: true,
1704 SkipFinished: true,
1705 },
1706 },
1707 flags: []string{
1708 "-implicit-handshake",
1709 "-false-start",
1710 "-handshake-never-done",
1711 "-advertise-alpn", "\x03foo",
1712 },
1713 shouldFail: true,
1714 expectedError: ":UNEXPECTED_RECORD:",
1715 },
1716 {
1717 testType: serverTest,
1718 name: "FailEarlyCallback",
1719 flags: []string{"-fail-early-callback"},
1720 shouldFail: true,
1721 expectedError: ":CONNECTION_REJECTED:",
1722 expectedLocalError: "remote error: access denied",
1723 },
1724 {
1725 name: "WrongMessageType",
1726 config: Config{
1727 Bugs: ProtocolBugs{
1728 WrongCertificateMessageType: true,
1729 },
1730 },
1731 shouldFail: true,
1732 expectedError: ":UNEXPECTED_MESSAGE:",
1733 expectedLocalError: "remote error: unexpected message",
1734 },
1735 {
1736 protocol: dtls,
1737 name: "WrongMessageType-DTLS",
1738 config: Config{
1739 Bugs: ProtocolBugs{
1740 WrongCertificateMessageType: true,
1741 },
1742 },
1743 shouldFail: true,
1744 expectedError: ":UNEXPECTED_MESSAGE:",
1745 expectedLocalError: "remote error: unexpected message",
1746 },
1747 {
1748 protocol: dtls,
1749 name: "FragmentMessageTypeMismatch-DTLS",
1750 config: Config{
1751 Bugs: ProtocolBugs{
1752 MaxHandshakeRecordLength: 2,
1753 FragmentMessageTypeMismatch: true,
1754 },
1755 },
1756 shouldFail: true,
1757 expectedError: ":FRAGMENT_MISMATCH:",
1758 },
1759 {
1760 protocol: dtls,
1761 name: "FragmentMessageLengthMismatch-DTLS",
1762 config: Config{
1763 Bugs: ProtocolBugs{
1764 MaxHandshakeRecordLength: 2,
1765 FragmentMessageLengthMismatch: true,
1766 },
1767 },
1768 shouldFail: true,
1769 expectedError: ":FRAGMENT_MISMATCH:",
1770 },
1771 {
1772 protocol: dtls,
1773 name: "SplitFragments-Header-DTLS",
1774 config: Config{
1775 Bugs: ProtocolBugs{
1776 SplitFragments: 2,
1777 },
1778 },
1779 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001780 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001781 },
1782 {
1783 protocol: dtls,
1784 name: "SplitFragments-Boundary-DTLS",
1785 config: Config{
1786 Bugs: ProtocolBugs{
1787 SplitFragments: dtlsRecordHeaderLen,
1788 },
1789 },
1790 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001791 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001792 },
1793 {
1794 protocol: dtls,
1795 name: "SplitFragments-Body-DTLS",
1796 config: Config{
1797 Bugs: ProtocolBugs{
1798 SplitFragments: dtlsRecordHeaderLen + 1,
1799 },
1800 },
1801 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001802 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001803 },
1804 {
1805 protocol: dtls,
1806 name: "SendEmptyFragments-DTLS",
1807 config: Config{
1808 Bugs: ProtocolBugs{
1809 SendEmptyFragments: true,
1810 },
1811 },
1812 },
1813 {
1814 name: "UnsupportedCipherSuite",
1815 config: Config{
1816 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
1817 Bugs: ProtocolBugs{
1818 IgnorePeerCipherPreferences: true,
1819 },
1820 },
1821 flags: []string{"-cipher", "DEFAULT:!RC4"},
1822 shouldFail: true,
1823 expectedError: ":WRONG_CIPHER_RETURNED:",
1824 },
1825 {
1826 name: "UnsupportedCurve",
1827 config: Config{
David Benjamin64d92502015-12-19 02:20:57 -05001828 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1829 CurvePreferences: []CurveID{CurveP256},
Adam Langley7c803a62015-06-15 15:35:05 -07001830 Bugs: ProtocolBugs{
1831 IgnorePeerCurvePreferences: true,
1832 },
1833 },
David Benjamin64d92502015-12-19 02:20:57 -05001834 flags: []string{"-p384-only"},
Adam Langley7c803a62015-06-15 15:35:05 -07001835 shouldFail: true,
1836 expectedError: ":WRONG_CURVE:",
1837 },
1838 {
David Benjaminbf82aed2016-03-01 22:57:40 -05001839 name: "BadFinished-Client",
1840 config: Config{
1841 Bugs: ProtocolBugs{
1842 BadFinished: true,
1843 },
1844 },
1845 shouldFail: true,
1846 expectedError: ":DIGEST_CHECK_FAILED:",
1847 },
1848 {
1849 testType: serverTest,
1850 name: "BadFinished-Server",
Adam Langley7c803a62015-06-15 15:35:05 -07001851 config: Config{
1852 Bugs: ProtocolBugs{
1853 BadFinished: true,
1854 },
1855 },
1856 shouldFail: true,
1857 expectedError: ":DIGEST_CHECK_FAILED:",
1858 },
1859 {
1860 name: "FalseStart-BadFinished",
1861 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001862 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001863 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1864 NextProtos: []string{"foo"},
1865 Bugs: ProtocolBugs{
1866 BadFinished: true,
1867 ExpectFalseStart: true,
1868 },
1869 },
1870 flags: []string{
1871 "-false-start",
1872 "-handshake-never-done",
1873 "-advertise-alpn", "\x03foo",
1874 },
1875 shimWritesFirst: true,
1876 shouldFail: true,
1877 expectedError: ":DIGEST_CHECK_FAILED:",
1878 },
1879 {
1880 name: "NoFalseStart-NoALPN",
1881 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001882 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001883 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1884 Bugs: ProtocolBugs{
1885 ExpectFalseStart: true,
1886 AlertBeforeFalseStartTest: alertAccessDenied,
1887 },
1888 },
1889 flags: []string{
1890 "-false-start",
1891 },
1892 shimWritesFirst: true,
1893 shouldFail: true,
1894 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1895 expectedLocalError: "tls: peer did not false start: EOF",
1896 },
1897 {
1898 name: "NoFalseStart-NoAEAD",
1899 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001900 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001901 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
1902 NextProtos: []string{"foo"},
1903 Bugs: ProtocolBugs{
1904 ExpectFalseStart: true,
1905 AlertBeforeFalseStartTest: alertAccessDenied,
1906 },
1907 },
1908 flags: []string{
1909 "-false-start",
1910 "-advertise-alpn", "\x03foo",
1911 },
1912 shimWritesFirst: true,
1913 shouldFail: true,
1914 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1915 expectedLocalError: "tls: peer did not false start: EOF",
1916 },
1917 {
1918 name: "NoFalseStart-RSA",
1919 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001920 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001921 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
1922 NextProtos: []string{"foo"},
1923 Bugs: ProtocolBugs{
1924 ExpectFalseStart: true,
1925 AlertBeforeFalseStartTest: alertAccessDenied,
1926 },
1927 },
1928 flags: []string{
1929 "-false-start",
1930 "-advertise-alpn", "\x03foo",
1931 },
1932 shimWritesFirst: true,
1933 shouldFail: true,
1934 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1935 expectedLocalError: "tls: peer did not false start: EOF",
1936 },
1937 {
1938 name: "NoFalseStart-DHE_RSA",
1939 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001940 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001941 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
1942 NextProtos: []string{"foo"},
1943 Bugs: ProtocolBugs{
1944 ExpectFalseStart: true,
1945 AlertBeforeFalseStartTest: alertAccessDenied,
1946 },
1947 },
1948 flags: []string{
1949 "-false-start",
1950 "-advertise-alpn", "\x03foo",
1951 },
1952 shimWritesFirst: true,
1953 shouldFail: true,
1954 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1955 expectedLocalError: "tls: peer did not false start: EOF",
1956 },
1957 {
1958 testType: serverTest,
1959 name: "NoSupportedCurves",
1960 config: Config{
1961 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1962 Bugs: ProtocolBugs{
1963 NoSupportedCurves: true,
1964 },
1965 },
David Benjamin4298d772015-12-19 00:18:25 -05001966 shouldFail: true,
1967 expectedError: ":NO_SHARED_CIPHER:",
Adam Langley7c803a62015-06-15 15:35:05 -07001968 },
1969 {
1970 testType: serverTest,
1971 name: "NoCommonCurves",
1972 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001973 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001974 CipherSuites: []uint16{
1975 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1976 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
1977 },
1978 CurvePreferences: []CurveID{CurveP224},
1979 },
1980 expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
1981 },
1982 {
1983 protocol: dtls,
1984 name: "SendSplitAlert-Sync",
1985 config: Config{
1986 Bugs: ProtocolBugs{
1987 SendSplitAlert: true,
1988 },
1989 },
1990 },
1991 {
1992 protocol: dtls,
1993 name: "SendSplitAlert-Async",
1994 config: Config{
1995 Bugs: ProtocolBugs{
1996 SendSplitAlert: true,
1997 },
1998 },
1999 flags: []string{"-async"},
2000 },
2001 {
2002 protocol: dtls,
2003 name: "PackDTLSHandshake",
2004 config: Config{
2005 Bugs: ProtocolBugs{
2006 MaxHandshakeRecordLength: 2,
2007 PackHandshakeFragments: 20,
2008 PackHandshakeRecords: 200,
2009 },
2010 },
2011 },
2012 {
Adam Langley7c803a62015-06-15 15:35:05 -07002013 name: "SendEmptyRecords-Pass",
2014 sendEmptyRecords: 32,
2015 },
2016 {
2017 name: "SendEmptyRecords",
2018 sendEmptyRecords: 33,
2019 shouldFail: true,
2020 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
2021 },
2022 {
2023 name: "SendEmptyRecords-Async",
2024 sendEmptyRecords: 33,
2025 flags: []string{"-async"},
2026 shouldFail: true,
2027 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
2028 },
2029 {
2030 name: "SendWarningAlerts-Pass",
2031 sendWarningAlerts: 4,
2032 },
2033 {
2034 protocol: dtls,
2035 name: "SendWarningAlerts-DTLS-Pass",
2036 sendWarningAlerts: 4,
2037 },
2038 {
2039 name: "SendWarningAlerts",
2040 sendWarningAlerts: 5,
2041 shouldFail: true,
2042 expectedError: ":TOO_MANY_WARNING_ALERTS:",
2043 },
2044 {
2045 name: "SendWarningAlerts-Async",
2046 sendWarningAlerts: 5,
2047 flags: []string{"-async"},
2048 shouldFail: true,
2049 expectedError: ":TOO_MANY_WARNING_ALERTS:",
2050 },
David Benjaminba4594a2015-06-18 18:36:15 -04002051 {
2052 name: "EmptySessionID",
2053 config: Config{
2054 SessionTicketsDisabled: true,
2055 },
2056 noSessionCache: true,
2057 flags: []string{"-expect-no-session"},
2058 },
David Benjamin30789da2015-08-29 22:56:45 -04002059 {
2060 name: "Unclean-Shutdown",
2061 config: Config{
2062 Bugs: ProtocolBugs{
2063 NoCloseNotify: true,
2064 ExpectCloseNotify: true,
2065 },
2066 },
2067 shimShutsDown: true,
2068 flags: []string{"-check-close-notify"},
2069 shouldFail: true,
2070 expectedError: "Unexpected SSL_shutdown result: -1 != 1",
2071 },
2072 {
2073 name: "Unclean-Shutdown-Ignored",
2074 config: Config{
2075 Bugs: ProtocolBugs{
2076 NoCloseNotify: true,
2077 },
2078 },
2079 shimShutsDown: true,
2080 },
David Benjamin4f75aaf2015-09-01 16:53:10 -04002081 {
David Benjaminfa214e42016-05-10 17:03:10 -04002082 name: "Unclean-Shutdown-Alert",
2083 config: Config{
2084 Bugs: ProtocolBugs{
2085 SendAlertOnShutdown: alertDecompressionFailure,
2086 ExpectCloseNotify: true,
2087 },
2088 },
2089 shimShutsDown: true,
2090 flags: []string{"-check-close-notify"},
2091 shouldFail: true,
2092 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:",
2093 },
2094 {
David Benjamin4f75aaf2015-09-01 16:53:10 -04002095 name: "LargePlaintext",
2096 config: Config{
2097 Bugs: ProtocolBugs{
2098 SendLargeRecords: true,
2099 },
2100 },
2101 messageLen: maxPlaintext + 1,
2102 shouldFail: true,
2103 expectedError: ":DATA_LENGTH_TOO_LONG:",
2104 },
2105 {
2106 protocol: dtls,
2107 name: "LargePlaintext-DTLS",
2108 config: Config{
2109 Bugs: ProtocolBugs{
2110 SendLargeRecords: true,
2111 },
2112 },
2113 messageLen: maxPlaintext + 1,
2114 shouldFail: true,
2115 expectedError: ":DATA_LENGTH_TOO_LONG:",
2116 },
2117 {
2118 name: "LargeCiphertext",
2119 config: Config{
2120 Bugs: ProtocolBugs{
2121 SendLargeRecords: true,
2122 },
2123 },
2124 messageLen: maxPlaintext * 2,
2125 shouldFail: true,
2126 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
2127 },
2128 {
2129 protocol: dtls,
2130 name: "LargeCiphertext-DTLS",
2131 config: Config{
2132 Bugs: ProtocolBugs{
2133 SendLargeRecords: true,
2134 },
2135 },
2136 messageLen: maxPlaintext * 2,
2137 // Unlike the other four cases, DTLS drops records which
2138 // are invalid before authentication, so the connection
2139 // does not fail.
2140 expectMessageDropped: true,
2141 },
David Benjamindd6fed92015-10-23 17:41:12 -04002142 {
2143 name: "SendEmptySessionTicket",
2144 config: Config{
2145 Bugs: ProtocolBugs{
2146 SendEmptySessionTicket: true,
2147 FailIfSessionOffered: true,
2148 },
2149 },
2150 flags: []string{"-expect-no-session"},
2151 resumeSession: true,
2152 expectResumeRejected: true,
2153 },
David Benjamin99fdfb92015-11-02 12:11:35 -05002154 {
2155 name: "CheckLeafCurve",
2156 config: Config{
2157 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
2158 Certificates: []Certificate{getECDSACertificate()},
2159 },
2160 flags: []string{"-p384-only"},
2161 shouldFail: true,
2162 expectedError: ":BAD_ECC_CERT:",
2163 },
David Benjamin8411b242015-11-26 12:07:28 -05002164 {
2165 name: "BadChangeCipherSpec-1",
2166 config: Config{
2167 Bugs: ProtocolBugs{
2168 BadChangeCipherSpec: []byte{2},
2169 },
2170 },
2171 shouldFail: true,
2172 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
2173 },
2174 {
2175 name: "BadChangeCipherSpec-2",
2176 config: Config{
2177 Bugs: ProtocolBugs{
2178 BadChangeCipherSpec: []byte{1, 1},
2179 },
2180 },
2181 shouldFail: true,
2182 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
2183 },
2184 {
2185 protocol: dtls,
2186 name: "BadChangeCipherSpec-DTLS-1",
2187 config: Config{
2188 Bugs: ProtocolBugs{
2189 BadChangeCipherSpec: []byte{2},
2190 },
2191 },
2192 shouldFail: true,
2193 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
2194 },
2195 {
2196 protocol: dtls,
2197 name: "BadChangeCipherSpec-DTLS-2",
2198 config: Config{
2199 Bugs: ProtocolBugs{
2200 BadChangeCipherSpec: []byte{1, 1},
2201 },
2202 },
2203 shouldFail: true,
2204 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
2205 },
David Benjaminef5dfd22015-12-06 13:17:07 -05002206 {
2207 name: "BadHelloRequest-1",
2208 renegotiate: 1,
2209 config: Config{
2210 Bugs: ProtocolBugs{
2211 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1},
2212 },
2213 },
2214 flags: []string{
2215 "-renegotiate-freely",
2216 "-expect-total-renegotiations", "1",
2217 },
2218 shouldFail: true,
2219 expectedError: ":BAD_HELLO_REQUEST:",
2220 },
2221 {
2222 name: "BadHelloRequest-2",
2223 renegotiate: 1,
2224 config: Config{
2225 Bugs: ProtocolBugs{
2226 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0},
2227 },
2228 },
2229 flags: []string{
2230 "-renegotiate-freely",
2231 "-expect-total-renegotiations", "1",
2232 },
2233 shouldFail: true,
2234 expectedError: ":BAD_HELLO_REQUEST:",
2235 },
David Benjaminef1b0092015-11-21 14:05:44 -05002236 {
2237 testType: serverTest,
2238 name: "SupportTicketsWithSessionID",
2239 config: Config{
2240 SessionTicketsDisabled: true,
2241 },
2242 resumeConfig: &Config{},
2243 resumeSession: true,
2244 },
David Benjamin2b07fa42016-03-02 00:23:57 -05002245 {
2246 name: "InvalidECDHPoint-Client",
2247 config: Config{
2248 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2249 CurvePreferences: []CurveID{CurveP256},
2250 Bugs: ProtocolBugs{
2251 InvalidECDHPoint: true,
2252 },
2253 },
2254 shouldFail: true,
2255 expectedError: ":INVALID_ENCODING:",
2256 },
2257 {
2258 testType: serverTest,
2259 name: "InvalidECDHPoint-Server",
2260 config: Config{
2261 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2262 CurvePreferences: []CurveID{CurveP256},
2263 Bugs: ProtocolBugs{
2264 InvalidECDHPoint: true,
2265 },
2266 },
2267 shouldFail: true,
2268 expectedError: ":INVALID_ENCODING:",
2269 },
Adam Langley7c803a62015-06-15 15:35:05 -07002270 }
Adam Langley7c803a62015-06-15 15:35:05 -07002271 testCases = append(testCases, basicTests...)
2272}
2273
Adam Langley95c29f32014-06-20 12:00:00 -07002274func addCipherSuiteTests() {
2275 for _, suite := range testCipherSuites {
David Benjamin48cae082014-10-27 01:06:24 -04002276 const psk = "12345"
2277 const pskIdentity = "luggage combo"
2278
Adam Langley95c29f32014-06-20 12:00:00 -07002279 var cert Certificate
David Benjamin025b3d32014-07-01 19:53:04 -04002280 var certFile string
2281 var keyFile string
David Benjamin8b8c0062014-11-23 02:47:52 -05002282 if hasComponent(suite.name, "ECDSA") {
Adam Langley95c29f32014-06-20 12:00:00 -07002283 cert = getECDSACertificate()
David Benjamin025b3d32014-07-01 19:53:04 -04002284 certFile = ecdsaCertificateFile
2285 keyFile = ecdsaKeyFile
Adam Langley95c29f32014-06-20 12:00:00 -07002286 } else {
2287 cert = getRSACertificate()
David Benjamin025b3d32014-07-01 19:53:04 -04002288 certFile = rsaCertificateFile
2289 keyFile = rsaKeyFile
Adam Langley95c29f32014-06-20 12:00:00 -07002290 }
2291
David Benjamin48cae082014-10-27 01:06:24 -04002292 var flags []string
David Benjamin8b8c0062014-11-23 02:47:52 -05002293 if hasComponent(suite.name, "PSK") {
David Benjamin48cae082014-10-27 01:06:24 -04002294 flags = append(flags,
2295 "-psk", psk,
2296 "-psk-identity", pskIdentity)
2297 }
Matt Braithwaiteaf096752015-09-02 19:48:16 -07002298 if hasComponent(suite.name, "NULL") {
2299 // NULL ciphers must be explicitly enabled.
2300 flags = append(flags, "-cipher", "DEFAULT:NULL-SHA")
2301 }
Matt Braithwaite053931e2016-05-25 12:06:05 -07002302 if hasComponent(suite.name, "CECPQ1") {
2303 // CECPQ1 ciphers must be explicitly enabled.
2304 flags = append(flags, "-cipher", "DEFAULT:kCECPQ1")
2305 }
David Benjamin48cae082014-10-27 01:06:24 -04002306
Adam Langley95c29f32014-06-20 12:00:00 -07002307 for _, ver := range tlsVersions {
David Benjamin0407e762016-06-17 16:41:18 -04002308 for _, protocol := range []protocol{tls, dtls} {
2309 var prefix string
2310 if protocol == dtls {
2311 if !ver.hasDTLS {
2312 continue
2313 }
2314 prefix = "D"
2315 }
Adam Langley95c29f32014-06-20 12:00:00 -07002316
David Benjamin0407e762016-06-17 16:41:18 -04002317 var shouldServerFail, shouldClientFail bool
2318 if hasComponent(suite.name, "ECDHE") && ver.version == VersionSSL30 {
2319 // BoringSSL clients accept ECDHE on SSLv3, but
2320 // a BoringSSL server will never select it
2321 // because the extension is missing.
2322 shouldServerFail = true
2323 }
2324 if isTLS12Only(suite.name) && ver.version < VersionTLS12 {
2325 shouldClientFail = true
2326 shouldServerFail = true
2327 }
Nick Harper1fd39d82016-06-14 18:14:35 -07002328 if !isTLS13Suite(suite.name) && ver.version == VersionTLS13 {
2329 shouldClientFail = true
2330 shouldServerFail = true
2331 }
David Benjamin0407e762016-06-17 16:41:18 -04002332 if !isDTLSCipher(suite.name) && protocol == dtls {
2333 shouldClientFail = true
2334 shouldServerFail = true
2335 }
David Benjamin4298d772015-12-19 00:18:25 -05002336
David Benjamin0407e762016-06-17 16:41:18 -04002337 var expectedServerError, expectedClientError string
2338 if shouldServerFail {
2339 expectedServerError = ":NO_SHARED_CIPHER:"
2340 }
2341 if shouldClientFail {
2342 expectedClientError = ":WRONG_CIPHER_RETURNED:"
2343 }
David Benjamin025b3d32014-07-01 19:53:04 -04002344
David Benjamin6fd297b2014-08-11 18:43:38 -04002345 testCases = append(testCases, testCase{
2346 testType: serverTest,
David Benjamin0407e762016-06-17 16:41:18 -04002347 protocol: protocol,
2348
2349 name: prefix + ver.name + "-" + suite.name + "-server",
David Benjamin6fd297b2014-08-11 18:43:38 -04002350 config: Config{
David Benjamin48cae082014-10-27 01:06:24 -04002351 MinVersion: ver.version,
2352 MaxVersion: ver.version,
2353 CipherSuites: []uint16{suite.id},
2354 Certificates: []Certificate{cert},
2355 PreSharedKey: []byte(psk),
2356 PreSharedKeyIdentity: pskIdentity,
David Benjamin0407e762016-06-17 16:41:18 -04002357 Bugs: ProtocolBugs{
David Benjamin9acf0ca2016-06-25 00:01:28 -04002358 EnableAllCiphers: shouldServerFail,
2359 IgnorePeerCipherPreferences: shouldServerFail,
David Benjamin0407e762016-06-17 16:41:18 -04002360 },
David Benjamin6fd297b2014-08-11 18:43:38 -04002361 },
2362 certFile: certFile,
2363 keyFile: keyFile,
David Benjamin48cae082014-10-27 01:06:24 -04002364 flags: flags,
David Benjaminfe8eb9a2014-11-17 03:19:02 -05002365 resumeSession: true,
David Benjamin0407e762016-06-17 16:41:18 -04002366 shouldFail: shouldServerFail,
2367 expectedError: expectedServerError,
2368 })
2369
2370 testCases = append(testCases, testCase{
2371 testType: clientTest,
2372 protocol: protocol,
2373 name: prefix + ver.name + "-" + suite.name + "-client",
2374 config: Config{
2375 MinVersion: ver.version,
2376 MaxVersion: ver.version,
2377 CipherSuites: []uint16{suite.id},
2378 Certificates: []Certificate{cert},
2379 PreSharedKey: []byte(psk),
2380 PreSharedKeyIdentity: pskIdentity,
2381 Bugs: ProtocolBugs{
David Benjamin9acf0ca2016-06-25 00:01:28 -04002382 EnableAllCiphers: shouldClientFail,
2383 IgnorePeerCipherPreferences: shouldClientFail,
David Benjamin0407e762016-06-17 16:41:18 -04002384 },
2385 },
2386 flags: flags,
2387 resumeSession: true,
2388 shouldFail: shouldClientFail,
2389 expectedError: expectedClientError,
David Benjamin6fd297b2014-08-11 18:43:38 -04002390 })
David Benjamin2c99d282015-09-01 10:23:00 -04002391
Nick Harper1fd39d82016-06-14 18:14:35 -07002392 if !shouldClientFail {
2393 // Ensure the maximum record size is accepted.
2394 testCases = append(testCases, testCase{
2395 name: prefix + ver.name + "-" + suite.name + "-LargeRecord",
2396 config: Config{
2397 MinVersion: ver.version,
2398 MaxVersion: ver.version,
2399 CipherSuites: []uint16{suite.id},
2400 Certificates: []Certificate{cert},
2401 PreSharedKey: []byte(psk),
2402 PreSharedKeyIdentity: pskIdentity,
2403 },
2404 flags: flags,
2405 messageLen: maxPlaintext,
2406 })
2407 }
2408 }
David Benjamin2c99d282015-09-01 10:23:00 -04002409 }
Adam Langley95c29f32014-06-20 12:00:00 -07002410 }
Adam Langleya7997f12015-05-14 17:38:50 -07002411
2412 testCases = append(testCases, testCase{
2413 name: "WeakDH",
2414 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002415 MaxVersion: VersionTLS12,
Adam Langleya7997f12015-05-14 17:38:50 -07002416 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2417 Bugs: ProtocolBugs{
2418 // This is a 1023-bit prime number, generated
2419 // with:
2420 // openssl gendh 1023 | openssl asn1parse -i
2421 DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"),
2422 },
2423 },
2424 shouldFail: true,
David Benjamincd24a392015-11-11 13:23:05 -08002425 expectedError: ":BAD_DH_P_LENGTH:",
Adam Langleya7997f12015-05-14 17:38:50 -07002426 })
Adam Langleycef75832015-09-03 14:51:12 -07002427
David Benjamincd24a392015-11-11 13:23:05 -08002428 testCases = append(testCases, testCase{
2429 name: "SillyDH",
2430 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002431 MaxVersion: VersionTLS12,
David Benjamincd24a392015-11-11 13:23:05 -08002432 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2433 Bugs: ProtocolBugs{
2434 // This is a 4097-bit prime number, generated
2435 // with:
2436 // openssl gendh 4097 | openssl asn1parse -i
2437 DHGroupPrime: bigFromHex("01D366FA64A47419B0CD4A45918E8D8C8430F674621956A9F52B0CA592BC104C6E38D60C58F2CA66792A2B7EBDC6F8FFE75AB7D6862C261F34E96A2AEEF53AB7C21365C2E8FB0582F71EB57B1C227C0E55AE859E9904A25EFECD7B435C4D4357BD840B03649D4A1F8037D89EA4E1967DBEEF1CC17A6111C48F12E9615FFF336D3F07064CB17C0B765A012C850B9E3AA7A6984B96D8C867DDC6D0F4AB52042572244796B7ECFF681CD3B3E2E29AAECA391A775BEE94E502FB15881B0F4AC60314EA947C0C82541C3D16FD8C0E09BB7F8F786582032859D9C13187CE6C0CB6F2D3EE6C3C9727C15F14B21D3CD2E02BDB9D119959B0E03DC9E5A91E2578762300B1517D2352FC1D0BB934A4C3E1B20CE9327DB102E89A6C64A8C3148EDFC5A94913933853442FA84451B31FD21E492F92DD5488E0D871AEBFE335A4B92431DEC69591548010E76A5B365D346786E9A2D3E589867D796AA5E25211201D757560D318A87DFB27F3E625BC373DB48BF94A63161C674C3D4265CB737418441B7650EABC209CF675A439BEB3E9D1AA1B79F67198A40CEFD1C89144F7D8BAF61D6AD36F466DA546B4174A0E0CAF5BD788C8243C7C2DDDCC3DB6FC89F12F17D19FBD9B0BC76FE92891CD6BA07BEA3B66EF12D0D85E788FD58675C1B0FBD16029DCC4D34E7A1A41471BDEDF78BF591A8B4E96D88BEC8EDC093E616292BFC096E69A916E8D624B"),
2438 },
2439 },
2440 shouldFail: true,
2441 expectedError: ":DH_P_TOO_LONG:",
2442 })
2443
Adam Langleyc4f25ce2015-11-26 16:39:08 -08002444 // This test ensures that Diffie-Hellman public values are padded with
2445 // zeros so that they're the same length as the prime. This is to avoid
2446 // hitting a bug in yaSSL.
2447 testCases = append(testCases, testCase{
2448 testType: serverTest,
2449 name: "DHPublicValuePadded",
2450 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002451 MaxVersion: VersionTLS12,
Adam Langleyc4f25ce2015-11-26 16:39:08 -08002452 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2453 Bugs: ProtocolBugs{
2454 RequireDHPublicValueLen: (1025 + 7) / 8,
2455 },
2456 },
2457 flags: []string{"-use-sparse-dh-prime"},
2458 })
David Benjamincd24a392015-11-11 13:23:05 -08002459
David Benjamin241ae832016-01-15 03:04:54 -05002460 // The server must be tolerant to bogus ciphers.
2461 const bogusCipher = 0x1234
2462 testCases = append(testCases, testCase{
2463 testType: serverTest,
2464 name: "UnknownCipher",
2465 config: Config{
2466 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2467 },
2468 })
2469
Adam Langleycef75832015-09-03 14:51:12 -07002470 // versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
2471 // 1.1 specific cipher suite settings. A server is setup with the given
2472 // cipher lists and then a connection is made for each member of
2473 // expectations. The cipher suite that the server selects must match
2474 // the specified one.
2475 var versionSpecificCiphersTest = []struct {
2476 ciphersDefault, ciphersTLS10, ciphersTLS11 string
2477 // expectations is a map from TLS version to cipher suite id.
2478 expectations map[uint16]uint16
2479 }{
2480 {
2481 // Test that the null case (where no version-specific ciphers are set)
2482 // works as expected.
2483 "RC4-SHA:AES128-SHA", // default ciphers
2484 "", // no ciphers specifically for TLS ≥ 1.0
2485 "", // no ciphers specifically for TLS ≥ 1.1
2486 map[uint16]uint16{
2487 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2488 VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
2489 VersionTLS11: TLS_RSA_WITH_RC4_128_SHA,
2490 VersionTLS12: TLS_RSA_WITH_RC4_128_SHA,
2491 },
2492 },
2493 {
2494 // With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
2495 // cipher.
2496 "RC4-SHA:AES128-SHA", // default
2497 "AES128-SHA", // these ciphers for TLS ≥ 1.0
2498 "", // no ciphers specifically for TLS ≥ 1.1
2499 map[uint16]uint16{
2500 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2501 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
2502 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
2503 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
2504 },
2505 },
2506 {
2507 // With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
2508 // cipher.
2509 "RC4-SHA:AES128-SHA", // default
2510 "", // no ciphers specifically for TLS ≥ 1.0
2511 "AES128-SHA", // these ciphers for TLS ≥ 1.1
2512 map[uint16]uint16{
2513 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2514 VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
2515 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
2516 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
2517 },
2518 },
2519 {
2520 // With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
2521 // mask ciphers_tls10 for TLS 1.1 and 1.2.
2522 "RC4-SHA:AES128-SHA", // default
2523 "AES128-SHA", // these ciphers for TLS ≥ 1.0
2524 "AES256-SHA", // these ciphers for TLS ≥ 1.1
2525 map[uint16]uint16{
2526 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2527 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
2528 VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
2529 VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
2530 },
2531 },
2532 }
2533
2534 for i, test := range versionSpecificCiphersTest {
2535 for version, expectedCipherSuite := range test.expectations {
2536 flags := []string{"-cipher", test.ciphersDefault}
2537 if len(test.ciphersTLS10) > 0 {
2538 flags = append(flags, "-cipher-tls10", test.ciphersTLS10)
2539 }
2540 if len(test.ciphersTLS11) > 0 {
2541 flags = append(flags, "-cipher-tls11", test.ciphersTLS11)
2542 }
2543
2544 testCases = append(testCases, testCase{
2545 testType: serverTest,
2546 name: fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version),
2547 config: Config{
2548 MaxVersion: version,
2549 MinVersion: version,
2550 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
2551 },
2552 flags: flags,
2553 expectedCipher: expectedCipherSuite,
2554 })
2555 }
2556 }
Adam Langley95c29f32014-06-20 12:00:00 -07002557}
2558
2559func addBadECDSASignatureTests() {
2560 for badR := BadValue(1); badR < NumBadValues; badR++ {
2561 for badS := BadValue(1); badS < NumBadValues; badS++ {
David Benjamin025b3d32014-07-01 19:53:04 -04002562 testCases = append(testCases, testCase{
Adam Langley95c29f32014-06-20 12:00:00 -07002563 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
2564 config: Config{
2565 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
2566 Certificates: []Certificate{getECDSACertificate()},
2567 Bugs: ProtocolBugs{
2568 BadECDSAR: badR,
2569 BadECDSAS: badS,
2570 },
2571 },
2572 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002573 expectedError: ":BAD_SIGNATURE:",
Adam Langley95c29f32014-06-20 12:00:00 -07002574 })
2575 }
2576 }
2577}
2578
Adam Langley80842bd2014-06-20 12:00:00 -07002579func addCBCPaddingTests() {
David Benjamin025b3d32014-07-01 19:53:04 -04002580 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002581 name: "MaxCBCPadding",
2582 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002583 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002584 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2585 Bugs: ProtocolBugs{
2586 MaxPadding: true,
2587 },
2588 },
2589 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
2590 })
David Benjamin025b3d32014-07-01 19:53:04 -04002591 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002592 name: "BadCBCPadding",
2593 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002594 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002595 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2596 Bugs: ProtocolBugs{
2597 PaddingFirstByteBad: true,
2598 },
2599 },
2600 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002601 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
Adam Langley80842bd2014-06-20 12:00:00 -07002602 })
2603 // OpenSSL previously had an issue where the first byte of padding in
2604 // 255 bytes of padding wasn't checked.
David Benjamin025b3d32014-07-01 19:53:04 -04002605 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002606 name: "BadCBCPadding255",
2607 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002608 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002609 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2610 Bugs: ProtocolBugs{
2611 MaxPadding: true,
2612 PaddingFirstByteBadIf255: true,
2613 },
2614 },
2615 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
2616 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002617 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
Adam Langley80842bd2014-06-20 12:00:00 -07002618 })
2619}
2620
Kenny Root7fdeaf12014-08-05 15:23:37 -07002621func addCBCSplittingTests() {
2622 testCases = append(testCases, testCase{
2623 name: "CBCRecordSplitting",
2624 config: Config{
2625 MaxVersion: VersionTLS10,
2626 MinVersion: VersionTLS10,
2627 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2628 },
David Benjaminac8302a2015-09-01 17:18:15 -04002629 messageLen: -1, // read until EOF
2630 resumeSession: true,
Kenny Root7fdeaf12014-08-05 15:23:37 -07002631 flags: []string{
2632 "-async",
2633 "-write-different-record-sizes",
2634 "-cbc-record-splitting",
2635 },
David Benjamina8e3e0e2014-08-06 22:11:10 -04002636 })
2637 testCases = append(testCases, testCase{
Kenny Root7fdeaf12014-08-05 15:23:37 -07002638 name: "CBCRecordSplittingPartialWrite",
2639 config: Config{
2640 MaxVersion: VersionTLS10,
2641 MinVersion: VersionTLS10,
2642 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2643 },
2644 messageLen: -1, // read until EOF
2645 flags: []string{
2646 "-async",
2647 "-write-different-record-sizes",
2648 "-cbc-record-splitting",
2649 "-partial-write",
2650 },
2651 })
2652}
2653
David Benjamin636293b2014-07-08 17:59:18 -04002654func addClientAuthTests() {
David Benjamin407a10c2014-07-16 12:58:59 -04002655 // Add a dummy cert pool to stress certificate authority parsing.
2656 // TODO(davidben): Add tests that those values parse out correctly.
2657 certPool := x509.NewCertPool()
2658 cert, err := x509.ParseCertificate(rsaCertificate.Certificate[0])
2659 if err != nil {
2660 panic(err)
2661 }
2662 certPool.AddCert(cert)
2663
David Benjamin636293b2014-07-08 17:59:18 -04002664 for _, ver := range tlsVersions {
David Benjamin636293b2014-07-08 17:59:18 -04002665 testCases = append(testCases, testCase{
2666 testType: clientTest,
David Benjamin67666e72014-07-12 15:47:52 -04002667 name: ver.name + "-Client-ClientAuth-RSA",
David Benjamin636293b2014-07-08 17:59:18 -04002668 config: Config{
David Benjamine098ec22014-08-27 23:13:20 -04002669 MinVersion: ver.version,
2670 MaxVersion: ver.version,
2671 ClientAuth: RequireAnyClientCert,
2672 ClientCAs: certPool,
David Benjamin636293b2014-07-08 17:59:18 -04002673 },
2674 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07002675 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2676 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin636293b2014-07-08 17:59:18 -04002677 },
2678 })
2679 testCases = append(testCases, testCase{
David Benjamin67666e72014-07-12 15:47:52 -04002680 testType: serverTest,
2681 name: ver.name + "-Server-ClientAuth-RSA",
2682 config: Config{
David Benjamine098ec22014-08-27 23:13:20 -04002683 MinVersion: ver.version,
2684 MaxVersion: ver.version,
David Benjamin67666e72014-07-12 15:47:52 -04002685 Certificates: []Certificate{rsaCertificate},
2686 },
2687 flags: []string{"-require-any-client-certificate"},
2688 })
David Benjamine098ec22014-08-27 23:13:20 -04002689 if ver.version != VersionSSL30 {
2690 testCases = append(testCases, testCase{
2691 testType: serverTest,
2692 name: ver.name + "-Server-ClientAuth-ECDSA",
2693 config: Config{
2694 MinVersion: ver.version,
2695 MaxVersion: ver.version,
2696 Certificates: []Certificate{ecdsaCertificate},
2697 },
2698 flags: []string{"-require-any-client-certificate"},
2699 })
2700 testCases = append(testCases, testCase{
2701 testType: clientTest,
2702 name: ver.name + "-Client-ClientAuth-ECDSA",
2703 config: Config{
2704 MinVersion: ver.version,
2705 MaxVersion: ver.version,
2706 ClientAuth: RequireAnyClientCert,
2707 ClientCAs: certPool,
2708 },
2709 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07002710 "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
2711 "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
David Benjamine098ec22014-08-27 23:13:20 -04002712 },
2713 })
2714 }
David Benjamin636293b2014-07-08 17:59:18 -04002715 }
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002716
Nick Harper1fd39d82016-06-14 18:14:35 -07002717 // TODO(davidben): These tests will need TLS 1.3 versions when the
2718 // handshake is separate.
2719
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002720 testCases = append(testCases, testCase{
Nick Harper1fd39d82016-06-14 18:14:35 -07002721 testType: serverTest,
2722 name: "RequireAnyClientCertificate",
2723 config: Config{
2724 MaxVersion: VersionTLS12,
2725 },
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002726 flags: []string{"-require-any-client-certificate"},
2727 shouldFail: true,
2728 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
2729 })
2730
2731 testCases = append(testCases, testCase{
2732 testType: serverTest,
David Benjamindf28c3a2016-03-10 16:11:51 -05002733 name: "RequireAnyClientCertificate-SSL3",
2734 config: Config{
2735 MaxVersion: VersionSSL30,
2736 },
2737 flags: []string{"-require-any-client-certificate"},
2738 shouldFail: true,
2739 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
2740 })
2741
2742 testCases = append(testCases, testCase{
2743 testType: serverTest,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002744 name: "SkipClientCertificate",
2745 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002746 MaxVersion: VersionTLS12,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002747 Bugs: ProtocolBugs{
2748 SkipClientCertificate: true,
2749 },
2750 },
2751 // Setting SSL_VERIFY_PEER allows anonymous clients.
2752 flags: []string{"-verify-peer"},
2753 shouldFail: true,
David Benjamindf28c3a2016-03-10 16:11:51 -05002754 expectedError: ":UNEXPECTED_MESSAGE:",
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002755 })
David Benjaminc032dfa2016-05-12 14:54:57 -04002756
2757 // Client auth is only legal in certificate-based ciphers.
2758 testCases = append(testCases, testCase{
2759 testType: clientTest,
2760 name: "ClientAuth-PSK",
2761 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002762 MaxVersion: VersionTLS12,
David Benjaminc032dfa2016-05-12 14:54:57 -04002763 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
2764 PreSharedKey: []byte("secret"),
2765 ClientAuth: RequireAnyClientCert,
2766 },
2767 flags: []string{
2768 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2769 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2770 "-psk", "secret",
2771 },
2772 shouldFail: true,
2773 expectedError: ":UNEXPECTED_MESSAGE:",
2774 })
2775 testCases = append(testCases, testCase{
2776 testType: clientTest,
2777 name: "ClientAuth-ECDHE_PSK",
2778 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002779 MaxVersion: VersionTLS12,
David Benjaminc032dfa2016-05-12 14:54:57 -04002780 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
2781 PreSharedKey: []byte("secret"),
2782 ClientAuth: RequireAnyClientCert,
2783 },
2784 flags: []string{
2785 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2786 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2787 "-psk", "secret",
2788 },
2789 shouldFail: true,
2790 expectedError: ":UNEXPECTED_MESSAGE:",
2791 })
David Benjamin636293b2014-07-08 17:59:18 -04002792}
2793
Adam Langley75712922014-10-10 16:23:43 -07002794func addExtendedMasterSecretTests() {
2795 const expectEMSFlag = "-expect-extended-master-secret"
2796
2797 for _, with := range []bool{false, true} {
2798 prefix := "No"
2799 var flags []string
2800 if with {
2801 prefix = ""
2802 flags = []string{expectEMSFlag}
2803 }
2804
2805 for _, isClient := range []bool{false, true} {
2806 suffix := "-Server"
2807 testType := serverTest
2808 if isClient {
2809 suffix = "-Client"
2810 testType = clientTest
2811 }
2812
2813 for _, ver := range tlsVersions {
2814 test := testCase{
2815 testType: testType,
2816 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix,
2817 config: Config{
2818 MinVersion: ver.version,
2819 MaxVersion: ver.version,
2820 Bugs: ProtocolBugs{
2821 NoExtendedMasterSecret: !with,
2822 RequireExtendedMasterSecret: with,
2823 },
2824 },
David Benjamin48cae082014-10-27 01:06:24 -04002825 flags: flags,
2826 shouldFail: ver.version == VersionSSL30 && with,
Adam Langley75712922014-10-10 16:23:43 -07002827 }
2828 if test.shouldFail {
2829 test.expectedLocalError = "extended master secret required but not supported by peer"
2830 }
2831 testCases = append(testCases, test)
2832 }
2833 }
2834 }
2835
Adam Langleyba5934b2015-06-02 10:50:35 -07002836 for _, isClient := range []bool{false, true} {
2837 for _, supportedInFirstConnection := range []bool{false, true} {
2838 for _, supportedInResumeConnection := range []bool{false, true} {
2839 boolToWord := func(b bool) string {
2840 if b {
2841 return "Yes"
2842 }
2843 return "No"
2844 }
2845 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
2846 if isClient {
2847 suffix += "Client"
2848 } else {
2849 suffix += "Server"
2850 }
2851
2852 supportedConfig := Config{
2853 Bugs: ProtocolBugs{
2854 RequireExtendedMasterSecret: true,
2855 },
2856 }
2857
2858 noSupportConfig := Config{
2859 Bugs: ProtocolBugs{
2860 NoExtendedMasterSecret: true,
2861 },
2862 }
2863
2864 test := testCase{
2865 name: "ExtendedMasterSecret-" + suffix,
2866 resumeSession: true,
2867 }
2868
2869 if !isClient {
2870 test.testType = serverTest
2871 }
2872
2873 if supportedInFirstConnection {
2874 test.config = supportedConfig
2875 } else {
2876 test.config = noSupportConfig
2877 }
2878
2879 if supportedInResumeConnection {
2880 test.resumeConfig = &supportedConfig
2881 } else {
2882 test.resumeConfig = &noSupportConfig
2883 }
2884
2885 switch suffix {
2886 case "YesToYes-Client", "YesToYes-Server":
2887 // When a session is resumed, it should
2888 // still be aware that its master
2889 // secret was generated via EMS and
2890 // thus it's safe to use tls-unique.
2891 test.flags = []string{expectEMSFlag}
2892 case "NoToYes-Server":
2893 // If an original connection did not
2894 // contain EMS, but a resumption
2895 // handshake does, then a server should
2896 // not resume the session.
2897 test.expectResumeRejected = true
2898 case "YesToNo-Server":
2899 // Resuming an EMS session without the
2900 // EMS extension should cause the
2901 // server to abort the connection.
2902 test.shouldFail = true
2903 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
2904 case "NoToYes-Client":
2905 // A client should abort a connection
2906 // where the server resumed a non-EMS
2907 // session but echoed the EMS
2908 // extension.
2909 test.shouldFail = true
2910 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
2911 case "YesToNo-Client":
2912 // A client should abort a connection
2913 // where the server didn't echo EMS
2914 // when the session used it.
2915 test.shouldFail = true
2916 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
2917 }
2918
2919 testCases = append(testCases, test)
2920 }
2921 }
2922 }
Adam Langley75712922014-10-10 16:23:43 -07002923}
2924
David Benjamin43ec06f2014-08-05 02:28:57 -04002925// Adds tests that try to cover the range of the handshake state machine, under
2926// various conditions. Some of these are redundant with other tests, but they
2927// only cover the synchronous case.
David Benjamin6fd297b2014-08-11 18:43:38 -04002928func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) {
David Benjamin760b1dd2015-05-15 23:33:48 -04002929 var tests []testCase
2930
Nick Harper1fd39d82016-06-14 18:14:35 -07002931 // TODO(davidben): These tests will need both TLS 1.2 and TLS 1.3
2932 // versions when the handshake becomes completely different.
2933
David Benjamin760b1dd2015-05-15 23:33:48 -04002934 // Basic handshake, with resumption. Client and server,
2935 // session ID and session ticket.
2936 tests = append(tests, testCase{
2937 name: "Basic-Client",
2938 resumeSession: true,
David Benjaminef1b0092015-11-21 14:05:44 -05002939 // Ensure session tickets are used, not session IDs.
2940 noSessionCache: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04002941 })
2942 tests = append(tests, testCase{
2943 name: "Basic-Client-RenewTicket",
2944 config: Config{
2945 Bugs: ProtocolBugs{
2946 RenewTicketOnResume: true,
2947 },
2948 },
David Benjaminba4594a2015-06-18 18:36:15 -04002949 flags: []string{"-expect-ticket-renewal"},
David Benjamin760b1dd2015-05-15 23:33:48 -04002950 resumeSession: true,
2951 })
2952 tests = append(tests, testCase{
2953 name: "Basic-Client-NoTicket",
2954 config: Config{
2955 SessionTicketsDisabled: true,
2956 },
2957 resumeSession: true,
2958 })
2959 tests = append(tests, testCase{
2960 name: "Basic-Client-Implicit",
2961 flags: []string{"-implicit-handshake"},
2962 resumeSession: true,
2963 })
2964 tests = append(tests, testCase{
David Benjaminef1b0092015-11-21 14:05:44 -05002965 testType: serverTest,
2966 name: "Basic-Server",
2967 config: Config{
2968 Bugs: ProtocolBugs{
2969 RequireSessionTickets: true,
2970 },
2971 },
David Benjamin760b1dd2015-05-15 23:33:48 -04002972 resumeSession: true,
2973 })
2974 tests = append(tests, testCase{
2975 testType: serverTest,
2976 name: "Basic-Server-NoTickets",
2977 config: Config{
2978 SessionTicketsDisabled: true,
2979 },
2980 resumeSession: true,
2981 })
2982 tests = append(tests, testCase{
2983 testType: serverTest,
2984 name: "Basic-Server-Implicit",
2985 flags: []string{"-implicit-handshake"},
2986 resumeSession: true,
2987 })
2988 tests = append(tests, testCase{
2989 testType: serverTest,
2990 name: "Basic-Server-EarlyCallback",
2991 flags: []string{"-use-early-callback"},
2992 resumeSession: true,
2993 })
2994
2995 // TLS client auth.
2996 tests = append(tests, testCase{
2997 testType: clientTest,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002998 name: "ClientAuth-NoCertificate-Client",
David Benjaminacb6dcc2016-03-10 09:15:01 -05002999 config: Config{
3000 ClientAuth: RequestClientCert,
3001 },
3002 })
3003 tests = append(tests, testCase{
David Benjamin0b7ca7d2016-03-10 15:44:22 -05003004 testType: serverTest,
3005 name: "ClientAuth-NoCertificate-Server",
3006 // Setting SSL_VERIFY_PEER allows anonymous clients.
3007 flags: []string{"-verify-peer"},
3008 })
3009 if protocol == tls {
3010 tests = append(tests, testCase{
3011 testType: clientTest,
3012 name: "ClientAuth-NoCertificate-Client-SSL3",
3013 config: Config{
3014 MaxVersion: VersionSSL30,
3015 ClientAuth: RequestClientCert,
3016 },
3017 })
3018 tests = append(tests, testCase{
3019 testType: serverTest,
3020 name: "ClientAuth-NoCertificate-Server-SSL3",
3021 config: Config{
3022 MaxVersion: VersionSSL30,
3023 },
3024 // Setting SSL_VERIFY_PEER allows anonymous clients.
3025 flags: []string{"-verify-peer"},
3026 })
3027 }
3028 tests = append(tests, testCase{
David Benjaminacb6dcc2016-03-10 09:15:01 -05003029 testType: clientTest,
3030 name: "ClientAuth-NoCertificate-OldCallback",
3031 config: Config{
3032 ClientAuth: RequestClientCert,
3033 },
3034 flags: []string{"-use-old-client-cert-callback"},
3035 })
3036 tests = append(tests, testCase{
3037 testType: clientTest,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003038 name: "ClientAuth-RSA-Client",
David Benjamin760b1dd2015-05-15 23:33:48 -04003039 config: Config{
3040 ClientAuth: RequireAnyClientCert,
3041 },
3042 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07003043 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3044 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin760b1dd2015-05-15 23:33:48 -04003045 },
3046 })
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003047 tests = append(tests, testCase{
3048 testType: clientTest,
3049 name: "ClientAuth-ECDSA-Client",
3050 config: Config{
3051 ClientAuth: RequireAnyClientCert,
3052 },
3053 flags: []string{
3054 "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
3055 "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
3056 },
3057 })
David Benjaminacb6dcc2016-03-10 09:15:01 -05003058 tests = append(tests, testCase{
3059 testType: clientTest,
3060 name: "ClientAuth-OldCallback",
3061 config: Config{
3062 ClientAuth: RequireAnyClientCert,
3063 },
3064 flags: []string{
3065 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3066 "-key-file", path.Join(*resourceDir, rsaKeyFile),
3067 "-use-old-client-cert-callback",
3068 },
3069 })
3070
David Benjaminb4d65fd2015-05-29 17:11:21 -04003071 if async {
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003072 // Test async keys against each key exchange.
David Benjaminb4d65fd2015-05-29 17:11:21 -04003073 tests = append(tests, testCase{
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003074 testType: serverTest,
3075 name: "Basic-Server-RSA",
David Benjaminb4d65fd2015-05-29 17:11:21 -04003076 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003077 MaxVersion: VersionTLS12,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003078 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
David Benjaminb4d65fd2015-05-29 17:11:21 -04003079 },
3080 flags: []string{
Adam Langley288d8d52015-06-18 16:24:31 -07003081 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3082 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminb4d65fd2015-05-29 17:11:21 -04003083 },
3084 })
nagendra modadugu601448a2015-07-24 09:31:31 -07003085 tests = append(tests, testCase{
3086 testType: serverTest,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003087 name: "Basic-Server-ECDHE-RSA",
3088 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003089 MaxVersion: VersionTLS12,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003090 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3091 },
nagendra modadugu601448a2015-07-24 09:31:31 -07003092 flags: []string{
3093 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3094 "-key-file", path.Join(*resourceDir, rsaKeyFile),
nagendra modadugu601448a2015-07-24 09:31:31 -07003095 },
3096 })
3097 tests = append(tests, testCase{
3098 testType: serverTest,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003099 name: "Basic-Server-ECDHE-ECDSA",
3100 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003101 MaxVersion: VersionTLS12,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003102 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
3103 },
nagendra modadugu601448a2015-07-24 09:31:31 -07003104 flags: []string{
3105 "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
3106 "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
nagendra modadugu601448a2015-07-24 09:31:31 -07003107 },
3108 })
David Benjaminb4d65fd2015-05-29 17:11:21 -04003109 }
David Benjamin760b1dd2015-05-15 23:33:48 -04003110 tests = append(tests, testCase{
3111 testType: serverTest,
3112 name: "ClientAuth-Server",
3113 config: Config{
3114 Certificates: []Certificate{rsaCertificate},
3115 },
3116 flags: []string{"-require-any-client-certificate"},
3117 })
3118
3119 // No session ticket support; server doesn't send NewSessionTicket.
3120 tests = append(tests, testCase{
3121 name: "SessionTicketsDisabled-Client",
3122 config: Config{
3123 SessionTicketsDisabled: true,
3124 },
3125 })
3126 tests = append(tests, testCase{
3127 testType: serverTest,
3128 name: "SessionTicketsDisabled-Server",
3129 config: Config{
3130 SessionTicketsDisabled: true,
3131 },
3132 })
3133
3134 // Skip ServerKeyExchange in PSK key exchange if there's no
3135 // identity hint.
3136 tests = append(tests, testCase{
3137 name: "EmptyPSKHint-Client",
3138 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003139 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003140 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3141 PreSharedKey: []byte("secret"),
3142 },
3143 flags: []string{"-psk", "secret"},
3144 })
3145 tests = append(tests, testCase{
3146 testType: serverTest,
3147 name: "EmptyPSKHint-Server",
3148 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003149 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003150 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3151 PreSharedKey: []byte("secret"),
3152 },
3153 flags: []string{"-psk", "secret"},
3154 })
3155
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003156 tests = append(tests, testCase{
3157 testType: clientTest,
3158 name: "OCSPStapling-Client",
3159 flags: []string{
3160 "-enable-ocsp-stapling",
3161 "-expect-ocsp-response",
3162 base64.StdEncoding.EncodeToString(testOCSPResponse),
Paul Lietar8f1c2682015-08-18 12:21:54 +01003163 "-verify-peer",
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003164 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01003165 resumeSession: true,
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003166 })
3167
3168 tests = append(tests, testCase{
David Benjaminec435342015-08-21 13:44:06 -04003169 testType: serverTest,
3170 name: "OCSPStapling-Server",
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003171 expectedOCSPResponse: testOCSPResponse,
3172 flags: []string{
3173 "-ocsp-response",
3174 base64.StdEncoding.EncodeToString(testOCSPResponse),
3175 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01003176 resumeSession: true,
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003177 })
3178
Paul Lietar8f1c2682015-08-18 12:21:54 +01003179 tests = append(tests, testCase{
3180 testType: clientTest,
3181 name: "CertificateVerificationSucceed",
3182 flags: []string{
3183 "-verify-peer",
3184 },
3185 })
3186
3187 tests = append(tests, testCase{
3188 testType: clientTest,
3189 name: "CertificateVerificationFail",
3190 flags: []string{
3191 "-verify-fail",
3192 "-verify-peer",
3193 },
3194 shouldFail: true,
3195 expectedError: ":CERTIFICATE_VERIFY_FAILED:",
3196 })
3197
3198 tests = append(tests, testCase{
3199 testType: clientTest,
3200 name: "CertificateVerificationSoftFail",
3201 flags: []string{
3202 "-verify-fail",
3203 "-expect-verify-result",
3204 },
3205 })
3206
David Benjamin760b1dd2015-05-15 23:33:48 -04003207 if protocol == tls {
3208 tests = append(tests, testCase{
3209 name: "Renegotiate-Client",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04003210 renegotiate: 1,
3211 flags: []string{
3212 "-renegotiate-freely",
3213 "-expect-total-renegotiations", "1",
3214 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003215 })
3216 // NPN on client and server; results in post-handshake message.
3217 tests = append(tests, testCase{
3218 name: "NPN-Client",
3219 config: Config{
3220 NextProtos: []string{"foo"},
3221 },
3222 flags: []string{"-select-next-proto", "foo"},
David Benjaminf8fcdf32016-06-08 15:56:13 -04003223 resumeSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003224 expectedNextProto: "foo",
3225 expectedNextProtoType: npn,
3226 })
3227 tests = append(tests, testCase{
3228 testType: serverTest,
3229 name: "NPN-Server",
3230 config: Config{
3231 NextProtos: []string{"bar"},
3232 },
3233 flags: []string{
3234 "-advertise-npn", "\x03foo\x03bar\x03baz",
3235 "-expect-next-proto", "bar",
3236 },
David Benjaminf8fcdf32016-06-08 15:56:13 -04003237 resumeSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003238 expectedNextProto: "bar",
3239 expectedNextProtoType: npn,
3240 })
3241
3242 // TODO(davidben): Add tests for when False Start doesn't trigger.
3243
3244 // Client does False Start and negotiates NPN.
3245 tests = append(tests, testCase{
3246 name: "FalseStart",
3247 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003248 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003249 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3250 NextProtos: []string{"foo"},
3251 Bugs: ProtocolBugs{
3252 ExpectFalseStart: true,
3253 },
3254 },
3255 flags: []string{
3256 "-false-start",
3257 "-select-next-proto", "foo",
3258 },
3259 shimWritesFirst: true,
3260 resumeSession: true,
3261 })
3262
3263 // Client does False Start and negotiates ALPN.
3264 tests = append(tests, testCase{
3265 name: "FalseStart-ALPN",
3266 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003267 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003268 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3269 NextProtos: []string{"foo"},
3270 Bugs: ProtocolBugs{
3271 ExpectFalseStart: true,
3272 },
3273 },
3274 flags: []string{
3275 "-false-start",
3276 "-advertise-alpn", "\x03foo",
3277 },
3278 shimWritesFirst: true,
3279 resumeSession: true,
3280 })
3281
3282 // Client does False Start but doesn't explicitly call
3283 // SSL_connect.
3284 tests = append(tests, testCase{
3285 name: "FalseStart-Implicit",
3286 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003287 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003288 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3289 NextProtos: []string{"foo"},
3290 },
3291 flags: []string{
3292 "-implicit-handshake",
3293 "-false-start",
3294 "-advertise-alpn", "\x03foo",
3295 },
3296 })
3297
3298 // False Start without session tickets.
3299 tests = append(tests, testCase{
3300 name: "FalseStart-SessionTicketsDisabled",
3301 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003302 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003303 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3304 NextProtos: []string{"foo"},
3305 SessionTicketsDisabled: true,
3306 Bugs: ProtocolBugs{
3307 ExpectFalseStart: true,
3308 },
3309 },
3310 flags: []string{
3311 "-false-start",
3312 "-select-next-proto", "foo",
3313 },
3314 shimWritesFirst: true,
3315 })
3316
3317 // Server parses a V2ClientHello.
3318 tests = append(tests, testCase{
3319 testType: serverTest,
3320 name: "SendV2ClientHello",
3321 config: Config{
3322 // Choose a cipher suite that does not involve
3323 // elliptic curves, so no extensions are
3324 // involved.
Nick Harper1fd39d82016-06-14 18:14:35 -07003325 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003326 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
3327 Bugs: ProtocolBugs{
3328 SendV2ClientHello: true,
3329 },
3330 },
3331 })
3332
3333 // Client sends a Channel ID.
3334 tests = append(tests, testCase{
3335 name: "ChannelID-Client",
3336 config: Config{
3337 RequestChannelID: true,
3338 },
Adam Langley7c803a62015-06-15 15:35:05 -07003339 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
David Benjamin760b1dd2015-05-15 23:33:48 -04003340 resumeSession: true,
3341 expectChannelID: true,
3342 })
3343
3344 // Server accepts a Channel ID.
3345 tests = append(tests, testCase{
3346 testType: serverTest,
3347 name: "ChannelID-Server",
3348 config: Config{
3349 ChannelID: channelIDKey,
3350 },
3351 flags: []string{
3352 "-expect-channel-id",
3353 base64.StdEncoding.EncodeToString(channelIDBytes),
3354 },
3355 resumeSession: true,
3356 expectChannelID: true,
3357 })
David Benjamin30789da2015-08-29 22:56:45 -04003358
David Benjaminf8fcdf32016-06-08 15:56:13 -04003359 // Channel ID and NPN at the same time, to ensure their relative
3360 // ordering is correct.
3361 tests = append(tests, testCase{
3362 name: "ChannelID-NPN-Client",
3363 config: Config{
3364 RequestChannelID: true,
3365 NextProtos: []string{"foo"},
3366 },
3367 flags: []string{
3368 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
3369 "-select-next-proto", "foo",
3370 },
3371 resumeSession: true,
3372 expectChannelID: true,
3373 expectedNextProto: "foo",
3374 expectedNextProtoType: npn,
3375 })
3376 tests = append(tests, testCase{
3377 testType: serverTest,
3378 name: "ChannelID-NPN-Server",
3379 config: Config{
3380 ChannelID: channelIDKey,
3381 NextProtos: []string{"bar"},
3382 },
3383 flags: []string{
3384 "-expect-channel-id",
3385 base64.StdEncoding.EncodeToString(channelIDBytes),
3386 "-advertise-npn", "\x03foo\x03bar\x03baz",
3387 "-expect-next-proto", "bar",
3388 },
3389 resumeSession: true,
3390 expectChannelID: true,
3391 expectedNextProto: "bar",
3392 expectedNextProtoType: npn,
3393 })
3394
David Benjamin30789da2015-08-29 22:56:45 -04003395 // Bidirectional shutdown with the runner initiating.
3396 tests = append(tests, testCase{
3397 name: "Shutdown-Runner",
3398 config: Config{
3399 Bugs: ProtocolBugs{
3400 ExpectCloseNotify: true,
3401 },
3402 },
3403 flags: []string{"-check-close-notify"},
3404 })
3405
3406 // Bidirectional shutdown with the shim initiating. The runner,
3407 // in the meantime, sends garbage before the close_notify which
3408 // the shim must ignore.
3409 tests = append(tests, testCase{
3410 name: "Shutdown-Shim",
3411 config: Config{
3412 Bugs: ProtocolBugs{
3413 ExpectCloseNotify: true,
3414 },
3415 },
3416 shimShutsDown: true,
3417 sendEmptyRecords: 1,
3418 sendWarningAlerts: 1,
3419 flags: []string{"-check-close-notify"},
3420 })
David Benjamin760b1dd2015-05-15 23:33:48 -04003421 } else {
3422 tests = append(tests, testCase{
3423 name: "SkipHelloVerifyRequest",
3424 config: Config{
3425 Bugs: ProtocolBugs{
3426 SkipHelloVerifyRequest: true,
3427 },
3428 },
3429 })
3430 }
3431
David Benjamin760b1dd2015-05-15 23:33:48 -04003432 for _, test := range tests {
3433 test.protocol = protocol
David Benjamin16285ea2015-11-03 15:39:45 -05003434 if protocol == dtls {
3435 test.name += "-DTLS"
3436 }
3437 if async {
3438 test.name += "-Async"
3439 test.flags = append(test.flags, "-async")
3440 } else {
3441 test.name += "-Sync"
3442 }
3443 if splitHandshake {
3444 test.name += "-SplitHandshakeRecords"
3445 test.config.Bugs.MaxHandshakeRecordLength = 1
3446 if protocol == dtls {
3447 test.config.Bugs.MaxPacketLength = 256
3448 test.flags = append(test.flags, "-mtu", "256")
3449 }
3450 }
David Benjamin760b1dd2015-05-15 23:33:48 -04003451 testCases = append(testCases, test)
David Benjamin6fd297b2014-08-11 18:43:38 -04003452 }
David Benjamin43ec06f2014-08-05 02:28:57 -04003453}
3454
Adam Langley524e7172015-02-20 16:04:00 -08003455func addDDoSCallbackTests() {
3456 // DDoS callback.
3457
3458 for _, resume := range []bool{false, true} {
3459 suffix := "Resume"
3460 if resume {
3461 suffix = "No" + suffix
3462 }
3463
3464 testCases = append(testCases, testCase{
3465 testType: serverTest,
3466 name: "Server-DDoS-OK-" + suffix,
3467 flags: []string{"-install-ddos-callback"},
3468 resumeSession: resume,
3469 })
3470
3471 failFlag := "-fail-ddos-callback"
3472 if resume {
3473 failFlag = "-fail-second-ddos-callback"
3474 }
3475 testCases = append(testCases, testCase{
3476 testType: serverTest,
3477 name: "Server-DDoS-Reject-" + suffix,
3478 flags: []string{"-install-ddos-callback", failFlag},
3479 resumeSession: resume,
3480 shouldFail: true,
3481 expectedError: ":CONNECTION_REJECTED:",
3482 })
3483 }
3484}
3485
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003486func addVersionNegotiationTests() {
3487 for i, shimVers := range tlsVersions {
3488 // Assemble flags to disable all newer versions on the shim.
3489 var flags []string
3490 for _, vers := range tlsVersions[i+1:] {
3491 flags = append(flags, vers.flag)
3492 }
3493
3494 for _, runnerVers := range tlsVersions {
David Benjamin8b8c0062014-11-23 02:47:52 -05003495 protocols := []protocol{tls}
3496 if runnerVers.hasDTLS && shimVers.hasDTLS {
3497 protocols = append(protocols, dtls)
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003498 }
David Benjamin8b8c0062014-11-23 02:47:52 -05003499 for _, protocol := range protocols {
3500 expectedVersion := shimVers.version
3501 if runnerVers.version < shimVers.version {
3502 expectedVersion = runnerVers.version
3503 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003504
David Benjamin8b8c0062014-11-23 02:47:52 -05003505 suffix := shimVers.name + "-" + runnerVers.name
3506 if protocol == dtls {
3507 suffix += "-DTLS"
3508 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003509
David Benjamin1eb367c2014-12-12 18:17:51 -05003510 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
3511
David Benjamin1e29a6b2014-12-10 02:27:24 -05003512 clientVers := shimVers.version
3513 if clientVers > VersionTLS10 {
3514 clientVers = VersionTLS10
3515 }
Nick Harper1fd39d82016-06-14 18:14:35 -07003516 serverVers := expectedVersion
3517 if expectedVersion >= VersionTLS13 {
3518 serverVers = VersionTLS10
3519 }
David Benjamin8b8c0062014-11-23 02:47:52 -05003520 testCases = append(testCases, testCase{
3521 protocol: protocol,
3522 testType: clientTest,
3523 name: "VersionNegotiation-Client-" + suffix,
3524 config: Config{
3525 MaxVersion: runnerVers.version,
David Benjamin1e29a6b2014-12-10 02:27:24 -05003526 Bugs: ProtocolBugs{
3527 ExpectInitialRecordVersion: clientVers,
3528 },
David Benjamin8b8c0062014-11-23 02:47:52 -05003529 },
3530 flags: flags,
3531 expectedVersion: expectedVersion,
3532 })
David Benjamin1eb367c2014-12-12 18:17:51 -05003533 testCases = append(testCases, testCase{
3534 protocol: protocol,
3535 testType: clientTest,
3536 name: "VersionNegotiation-Client2-" + suffix,
3537 config: Config{
3538 MaxVersion: runnerVers.version,
3539 Bugs: ProtocolBugs{
3540 ExpectInitialRecordVersion: clientVers,
3541 },
3542 },
3543 flags: []string{"-max-version", shimVersFlag},
3544 expectedVersion: expectedVersion,
3545 })
David Benjamin8b8c0062014-11-23 02:47:52 -05003546
3547 testCases = append(testCases, testCase{
3548 protocol: protocol,
3549 testType: serverTest,
3550 name: "VersionNegotiation-Server-" + suffix,
3551 config: Config{
3552 MaxVersion: runnerVers.version,
David Benjamin1e29a6b2014-12-10 02:27:24 -05003553 Bugs: ProtocolBugs{
Nick Harper1fd39d82016-06-14 18:14:35 -07003554 ExpectInitialRecordVersion: serverVers,
David Benjamin1e29a6b2014-12-10 02:27:24 -05003555 },
David Benjamin8b8c0062014-11-23 02:47:52 -05003556 },
3557 flags: flags,
3558 expectedVersion: expectedVersion,
3559 })
David Benjamin1eb367c2014-12-12 18:17:51 -05003560 testCases = append(testCases, testCase{
3561 protocol: protocol,
3562 testType: serverTest,
3563 name: "VersionNegotiation-Server2-" + suffix,
3564 config: Config{
3565 MaxVersion: runnerVers.version,
3566 Bugs: ProtocolBugs{
Nick Harper1fd39d82016-06-14 18:14:35 -07003567 ExpectInitialRecordVersion: serverVers,
David Benjamin1eb367c2014-12-12 18:17:51 -05003568 },
3569 },
3570 flags: []string{"-max-version", shimVersFlag},
3571 expectedVersion: expectedVersion,
3572 })
David Benjamin8b8c0062014-11-23 02:47:52 -05003573 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003574 }
3575 }
3576}
3577
David Benjaminaccb4542014-12-12 23:44:33 -05003578func addMinimumVersionTests() {
3579 for i, shimVers := range tlsVersions {
3580 // Assemble flags to disable all older versions on the shim.
3581 var flags []string
3582 for _, vers := range tlsVersions[:i] {
3583 flags = append(flags, vers.flag)
3584 }
3585
3586 for _, runnerVers := range tlsVersions {
3587 protocols := []protocol{tls}
3588 if runnerVers.hasDTLS && shimVers.hasDTLS {
3589 protocols = append(protocols, dtls)
3590 }
3591 for _, protocol := range protocols {
3592 suffix := shimVers.name + "-" + runnerVers.name
3593 if protocol == dtls {
3594 suffix += "-DTLS"
3595 }
3596 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
3597
David Benjaminaccb4542014-12-12 23:44:33 -05003598 var expectedVersion uint16
3599 var shouldFail bool
David Benjamin929d4ee2016-06-24 23:55:58 -04003600 var expectedClientError, expectedServerError string
3601 var expectedClientLocalError, expectedServerLocalError string
David Benjaminaccb4542014-12-12 23:44:33 -05003602 if runnerVers.version >= shimVers.version {
3603 expectedVersion = runnerVers.version
3604 } else {
3605 shouldFail = true
David Benjamin929d4ee2016-06-24 23:55:58 -04003606 expectedServerError = ":UNSUPPORTED_PROTOCOL:"
3607 expectedServerLocalError = "remote error: protocol version not supported"
3608 if shimVers.version >= VersionTLS13 && runnerVers.version <= VersionTLS11 {
3609 // If the client's minimum version is TLS 1.3 and the runner's
3610 // maximum is below TLS 1.2, the runner will fail to select a
3611 // cipher before the shim rejects the selected version.
3612 expectedClientError = ":SSLV3_ALERT_HANDSHAKE_FAILURE:"
3613 expectedClientLocalError = "tls: no cipher suite supported by both client and server"
3614 } else {
3615 expectedClientError = expectedServerError
3616 expectedClientLocalError = expectedServerLocalError
3617 }
David Benjaminaccb4542014-12-12 23:44:33 -05003618 }
3619
3620 testCases = append(testCases, testCase{
3621 protocol: protocol,
3622 testType: clientTest,
3623 name: "MinimumVersion-Client-" + suffix,
3624 config: Config{
3625 MaxVersion: runnerVers.version,
3626 },
David Benjamin87909c02014-12-13 01:55:01 -05003627 flags: flags,
3628 expectedVersion: expectedVersion,
3629 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003630 expectedError: expectedClientError,
3631 expectedLocalError: expectedClientLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003632 })
3633 testCases = append(testCases, testCase{
3634 protocol: protocol,
3635 testType: clientTest,
3636 name: "MinimumVersion-Client2-" + suffix,
3637 config: Config{
3638 MaxVersion: runnerVers.version,
3639 },
David Benjamin87909c02014-12-13 01:55:01 -05003640 flags: []string{"-min-version", shimVersFlag},
3641 expectedVersion: expectedVersion,
3642 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003643 expectedError: expectedClientError,
3644 expectedLocalError: expectedClientLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003645 })
3646
3647 testCases = append(testCases, testCase{
3648 protocol: protocol,
3649 testType: serverTest,
3650 name: "MinimumVersion-Server-" + suffix,
3651 config: Config{
3652 MaxVersion: runnerVers.version,
3653 },
David Benjamin87909c02014-12-13 01:55:01 -05003654 flags: flags,
3655 expectedVersion: expectedVersion,
3656 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003657 expectedError: expectedServerError,
3658 expectedLocalError: expectedServerLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003659 })
3660 testCases = append(testCases, testCase{
3661 protocol: protocol,
3662 testType: serverTest,
3663 name: "MinimumVersion-Server2-" + suffix,
3664 config: Config{
3665 MaxVersion: runnerVers.version,
3666 },
David Benjamin87909c02014-12-13 01:55:01 -05003667 flags: []string{"-min-version", shimVersFlag},
3668 expectedVersion: expectedVersion,
3669 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003670 expectedError: expectedServerError,
3671 expectedLocalError: expectedServerLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003672 })
3673 }
3674 }
3675 }
3676}
3677
David Benjamine78bfde2014-09-06 12:45:15 -04003678func addExtensionTests() {
3679 testCases = append(testCases, testCase{
3680 testType: clientTest,
3681 name: "DuplicateExtensionClient",
3682 config: Config{
3683 Bugs: ProtocolBugs{
3684 DuplicateExtension: true,
3685 },
3686 },
3687 shouldFail: true,
3688 expectedLocalError: "remote error: error decoding message",
3689 })
3690 testCases = append(testCases, testCase{
3691 testType: serverTest,
3692 name: "DuplicateExtensionServer",
3693 config: Config{
3694 Bugs: ProtocolBugs{
3695 DuplicateExtension: true,
3696 },
3697 },
3698 shouldFail: true,
3699 expectedLocalError: "remote error: error decoding message",
3700 })
3701 testCases = append(testCases, testCase{
3702 testType: clientTest,
3703 name: "ServerNameExtensionClient",
3704 config: Config{
3705 Bugs: ProtocolBugs{
3706 ExpectServerName: "example.com",
3707 },
3708 },
3709 flags: []string{"-host-name", "example.com"},
3710 })
3711 testCases = append(testCases, testCase{
3712 testType: clientTest,
David Benjamin5f237bc2015-02-11 17:14:15 -05003713 name: "ServerNameExtensionClientMismatch",
David Benjamine78bfde2014-09-06 12:45:15 -04003714 config: Config{
3715 Bugs: ProtocolBugs{
3716 ExpectServerName: "mismatch.com",
3717 },
3718 },
3719 flags: []string{"-host-name", "example.com"},
3720 shouldFail: true,
3721 expectedLocalError: "tls: unexpected server name",
3722 })
3723 testCases = append(testCases, testCase{
3724 testType: clientTest,
David Benjamin5f237bc2015-02-11 17:14:15 -05003725 name: "ServerNameExtensionClientMissing",
David Benjamine78bfde2014-09-06 12:45:15 -04003726 config: Config{
3727 Bugs: ProtocolBugs{
3728 ExpectServerName: "missing.com",
3729 },
3730 },
3731 shouldFail: true,
3732 expectedLocalError: "tls: unexpected server name",
3733 })
3734 testCases = append(testCases, testCase{
3735 testType: serverTest,
3736 name: "ServerNameExtensionServer",
3737 config: Config{
3738 ServerName: "example.com",
3739 },
3740 flags: []string{"-expect-server-name", "example.com"},
3741 resumeSession: true,
3742 })
David Benjaminae2888f2014-09-06 12:58:58 -04003743 testCases = append(testCases, testCase{
3744 testType: clientTest,
3745 name: "ALPNClient",
3746 config: Config{
3747 NextProtos: []string{"foo"},
3748 },
3749 flags: []string{
3750 "-advertise-alpn", "\x03foo\x03bar\x03baz",
3751 "-expect-alpn", "foo",
3752 },
David Benjaminfc7b0862014-09-06 13:21:53 -04003753 expectedNextProto: "foo",
3754 expectedNextProtoType: alpn,
3755 resumeSession: true,
David Benjaminae2888f2014-09-06 12:58:58 -04003756 })
3757 testCases = append(testCases, testCase{
3758 testType: serverTest,
3759 name: "ALPNServer",
3760 config: Config{
3761 NextProtos: []string{"foo", "bar", "baz"},
3762 },
3763 flags: []string{
3764 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
3765 "-select-alpn", "foo",
3766 },
David Benjaminfc7b0862014-09-06 13:21:53 -04003767 expectedNextProto: "foo",
3768 expectedNextProtoType: alpn,
3769 resumeSession: true,
3770 })
David Benjamin594e7d22016-03-17 17:49:56 -04003771 testCases = append(testCases, testCase{
3772 testType: serverTest,
3773 name: "ALPNServer-Decline",
3774 config: Config{
3775 NextProtos: []string{"foo", "bar", "baz"},
3776 },
3777 flags: []string{"-decline-alpn"},
3778 expectNoNextProto: true,
3779 resumeSession: true,
3780 })
David Benjaminfc7b0862014-09-06 13:21:53 -04003781 // Test that the server prefers ALPN over NPN.
3782 testCases = append(testCases, testCase{
3783 testType: serverTest,
3784 name: "ALPNServer-Preferred",
3785 config: Config{
3786 NextProtos: []string{"foo", "bar", "baz"},
3787 },
3788 flags: []string{
3789 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
3790 "-select-alpn", "foo",
3791 "-advertise-npn", "\x03foo\x03bar\x03baz",
3792 },
3793 expectedNextProto: "foo",
3794 expectedNextProtoType: alpn,
3795 resumeSession: true,
3796 })
3797 testCases = append(testCases, testCase{
3798 testType: serverTest,
3799 name: "ALPNServer-Preferred-Swapped",
3800 config: Config{
3801 NextProtos: []string{"foo", "bar", "baz"},
3802 Bugs: ProtocolBugs{
3803 SwapNPNAndALPN: true,
3804 },
3805 },
3806 flags: []string{
3807 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
3808 "-select-alpn", "foo",
3809 "-advertise-npn", "\x03foo\x03bar\x03baz",
3810 },
3811 expectedNextProto: "foo",
3812 expectedNextProtoType: alpn,
3813 resumeSession: true,
David Benjaminae2888f2014-09-06 12:58:58 -04003814 })
Adam Langleyefb0e162015-07-09 11:35:04 -07003815 var emptyString string
3816 testCases = append(testCases, testCase{
3817 testType: clientTest,
3818 name: "ALPNClient-EmptyProtocolName",
3819 config: Config{
3820 NextProtos: []string{""},
3821 Bugs: ProtocolBugs{
3822 // A server returning an empty ALPN protocol
3823 // should be rejected.
3824 ALPNProtocol: &emptyString,
3825 },
3826 },
3827 flags: []string{
3828 "-advertise-alpn", "\x03foo",
3829 },
Doug Hoganecdf7f92015-07-09 18:27:28 -07003830 shouldFail: true,
Adam Langleyefb0e162015-07-09 11:35:04 -07003831 expectedError: ":PARSE_TLSEXT:",
3832 })
3833 testCases = append(testCases, testCase{
3834 testType: serverTest,
3835 name: "ALPNServer-EmptyProtocolName",
3836 config: Config{
3837 // A ClientHello containing an empty ALPN protocol
3838 // should be rejected.
3839 NextProtos: []string{"foo", "", "baz"},
3840 },
3841 flags: []string{
3842 "-select-alpn", "foo",
3843 },
Doug Hoganecdf7f92015-07-09 18:27:28 -07003844 shouldFail: true,
Adam Langleyefb0e162015-07-09 11:35:04 -07003845 expectedError: ":PARSE_TLSEXT:",
3846 })
David Benjamin76c2efc2015-08-31 14:24:29 -04003847 // Test that negotiating both NPN and ALPN is forbidden.
3848 testCases = append(testCases, testCase{
3849 name: "NegotiateALPNAndNPN",
3850 config: Config{
3851 NextProtos: []string{"foo", "bar", "baz"},
3852 Bugs: ProtocolBugs{
3853 NegotiateALPNAndNPN: true,
3854 },
3855 },
3856 flags: []string{
3857 "-advertise-alpn", "\x03foo",
3858 "-select-next-proto", "foo",
3859 },
3860 shouldFail: true,
3861 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
3862 })
3863 testCases = append(testCases, testCase{
3864 name: "NegotiateALPNAndNPN-Swapped",
3865 config: Config{
3866 NextProtos: []string{"foo", "bar", "baz"},
3867 Bugs: ProtocolBugs{
3868 NegotiateALPNAndNPN: true,
3869 SwapNPNAndALPN: true,
3870 },
3871 },
3872 flags: []string{
3873 "-advertise-alpn", "\x03foo",
3874 "-select-next-proto", "foo",
3875 },
3876 shouldFail: true,
3877 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
3878 })
David Benjamin091c4b92015-10-26 13:33:21 -04003879 // Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
3880 testCases = append(testCases, testCase{
3881 name: "DisableNPN",
3882 config: Config{
3883 NextProtos: []string{"foo"},
3884 },
3885 flags: []string{
3886 "-select-next-proto", "foo",
3887 "-disable-npn",
3888 },
3889 expectNoNextProto: true,
3890 })
Adam Langley38311732014-10-16 19:04:35 -07003891 // Resume with a corrupt ticket.
3892 testCases = append(testCases, testCase{
3893 testType: serverTest,
3894 name: "CorruptTicket",
3895 config: Config{
3896 Bugs: ProtocolBugs{
3897 CorruptTicket: true,
3898 },
3899 },
Adam Langleyb0eef0a2015-06-02 10:47:39 -07003900 resumeSession: true,
3901 expectResumeRejected: true,
Adam Langley38311732014-10-16 19:04:35 -07003902 })
David Benjamind98452d2015-06-16 14:16:23 -04003903 // Test the ticket callback, with and without renewal.
3904 testCases = append(testCases, testCase{
3905 testType: serverTest,
3906 name: "TicketCallback",
3907 resumeSession: true,
3908 flags: []string{"-use-ticket-callback"},
3909 })
3910 testCases = append(testCases, testCase{
3911 testType: serverTest,
3912 name: "TicketCallback-Renew",
3913 config: Config{
3914 Bugs: ProtocolBugs{
3915 ExpectNewTicket: true,
3916 },
3917 },
3918 flags: []string{"-use-ticket-callback", "-renew-ticket"},
3919 resumeSession: true,
3920 })
Adam Langley38311732014-10-16 19:04:35 -07003921 // Resume with an oversized session id.
3922 testCases = append(testCases, testCase{
3923 testType: serverTest,
3924 name: "OversizedSessionId",
3925 config: Config{
3926 Bugs: ProtocolBugs{
3927 OversizedSessionId: true,
3928 },
3929 },
3930 resumeSession: true,
Adam Langley75712922014-10-10 16:23:43 -07003931 shouldFail: true,
Adam Langley38311732014-10-16 19:04:35 -07003932 expectedError: ":DECODE_ERROR:",
3933 })
David Benjaminca6c8262014-11-15 19:06:08 -05003934 // Basic DTLS-SRTP tests. Include fake profiles to ensure they
3935 // are ignored.
3936 testCases = append(testCases, testCase{
3937 protocol: dtls,
3938 name: "SRTP-Client",
3939 config: Config{
3940 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
3941 },
3942 flags: []string{
3943 "-srtp-profiles",
3944 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
3945 },
3946 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
3947 })
3948 testCases = append(testCases, testCase{
3949 protocol: dtls,
3950 testType: serverTest,
3951 name: "SRTP-Server",
3952 config: Config{
3953 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
3954 },
3955 flags: []string{
3956 "-srtp-profiles",
3957 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
3958 },
3959 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
3960 })
3961 // Test that the MKI is ignored.
3962 testCases = append(testCases, testCase{
3963 protocol: dtls,
3964 testType: serverTest,
3965 name: "SRTP-Server-IgnoreMKI",
3966 config: Config{
3967 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80},
3968 Bugs: ProtocolBugs{
3969 SRTPMasterKeyIdentifer: "bogus",
3970 },
3971 },
3972 flags: []string{
3973 "-srtp-profiles",
3974 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
3975 },
3976 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
3977 })
3978 // Test that SRTP isn't negotiated on the server if there were
3979 // no matching profiles.
3980 testCases = append(testCases, testCase{
3981 protocol: dtls,
3982 testType: serverTest,
3983 name: "SRTP-Server-NoMatch",
3984 config: Config{
3985 SRTPProtectionProfiles: []uint16{100, 101, 102},
3986 },
3987 flags: []string{
3988 "-srtp-profiles",
3989 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
3990 },
3991 expectedSRTPProtectionProfile: 0,
3992 })
3993 // Test that the server returning an invalid SRTP profile is
3994 // flagged as an error by the client.
3995 testCases = append(testCases, testCase{
3996 protocol: dtls,
3997 name: "SRTP-Client-NoMatch",
3998 config: Config{
3999 Bugs: ProtocolBugs{
4000 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32,
4001 },
4002 },
4003 flags: []string{
4004 "-srtp-profiles",
4005 "SRTP_AES128_CM_SHA1_80",
4006 },
4007 shouldFail: true,
4008 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
4009 })
Paul Lietaraeeff2c2015-08-12 11:47:11 +01004010 // Test SCT list.
David Benjamin61f95272014-11-25 01:55:35 -05004011 testCases = append(testCases, testCase{
David Benjaminc0577622015-09-12 18:28:38 -04004012 name: "SignedCertificateTimestampList-Client",
Paul Lietar4fac72e2015-09-09 13:44:55 +01004013 testType: clientTest,
David Benjamin61f95272014-11-25 01:55:35 -05004014 flags: []string{
4015 "-enable-signed-cert-timestamps",
4016 "-expect-signed-cert-timestamps",
4017 base64.StdEncoding.EncodeToString(testSCTList),
4018 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01004019 resumeSession: true,
David Benjamin61f95272014-11-25 01:55:35 -05004020 })
Adam Langley33ad2b52015-07-20 17:43:53 -07004021 testCases = append(testCases, testCase{
David Benjamin80d1b352016-05-04 19:19:06 -04004022 name: "SendSCTListOnResume",
4023 config: Config{
4024 Bugs: ProtocolBugs{
4025 SendSCTListOnResume: []byte("bogus"),
4026 },
4027 },
4028 flags: []string{
4029 "-enable-signed-cert-timestamps",
4030 "-expect-signed-cert-timestamps",
4031 base64.StdEncoding.EncodeToString(testSCTList),
4032 },
4033 resumeSession: true,
4034 })
4035 testCases = append(testCases, testCase{
David Benjaminc0577622015-09-12 18:28:38 -04004036 name: "SignedCertificateTimestampList-Server",
Paul Lietar4fac72e2015-09-09 13:44:55 +01004037 testType: serverTest,
4038 flags: []string{
4039 "-signed-cert-timestamps",
4040 base64.StdEncoding.EncodeToString(testSCTList),
4041 },
4042 expectedSCTList: testSCTList,
Paul Lietar62be8ac2015-09-16 10:03:30 +01004043 resumeSession: true,
Paul Lietar4fac72e2015-09-09 13:44:55 +01004044 })
4045 testCases = append(testCases, testCase{
Adam Langley33ad2b52015-07-20 17:43:53 -07004046 testType: clientTest,
4047 name: "ClientHelloPadding",
4048 config: Config{
4049 Bugs: ProtocolBugs{
4050 RequireClientHelloSize: 512,
4051 },
4052 },
4053 // This hostname just needs to be long enough to push the
4054 // ClientHello into F5's danger zone between 256 and 511 bytes
4055 // long.
4056 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
4057 })
David Benjaminc7ce9772015-10-09 19:32:41 -04004058
4059 // Extensions should not function in SSL 3.0.
4060 testCases = append(testCases, testCase{
4061 testType: serverTest,
4062 name: "SSLv3Extensions-NoALPN",
4063 config: Config{
4064 MaxVersion: VersionSSL30,
4065 NextProtos: []string{"foo", "bar", "baz"},
4066 },
4067 flags: []string{
4068 "-select-alpn", "foo",
4069 },
4070 expectNoNextProto: true,
4071 })
4072
4073 // Test session tickets separately as they follow a different codepath.
4074 testCases = append(testCases, testCase{
4075 testType: serverTest,
4076 name: "SSLv3Extensions-NoTickets",
4077 config: Config{
4078 MaxVersion: VersionSSL30,
4079 Bugs: ProtocolBugs{
4080 // Historically, session tickets in SSL 3.0
4081 // failed in different ways depending on whether
4082 // the client supported renegotiation_info.
4083 NoRenegotiationInfo: true,
4084 },
4085 },
4086 resumeSession: true,
4087 })
4088 testCases = append(testCases, testCase{
4089 testType: serverTest,
4090 name: "SSLv3Extensions-NoTickets2",
4091 config: Config{
4092 MaxVersion: VersionSSL30,
4093 },
4094 resumeSession: true,
4095 })
4096
4097 // But SSL 3.0 does send and process renegotiation_info.
4098 testCases = append(testCases, testCase{
4099 testType: serverTest,
4100 name: "SSLv3Extensions-RenegotiationInfo",
4101 config: Config{
4102 MaxVersion: VersionSSL30,
4103 Bugs: ProtocolBugs{
4104 RequireRenegotiationInfo: true,
4105 },
4106 },
4107 })
4108 testCases = append(testCases, testCase{
4109 testType: serverTest,
4110 name: "SSLv3Extensions-RenegotiationInfo-SCSV",
4111 config: Config{
4112 MaxVersion: VersionSSL30,
4113 Bugs: ProtocolBugs{
4114 NoRenegotiationInfo: true,
4115 SendRenegotiationSCSV: true,
4116 RequireRenegotiationInfo: true,
4117 },
4118 },
4119 })
David Benjamine78bfde2014-09-06 12:45:15 -04004120}
4121
David Benjamin01fe8202014-09-24 15:21:44 -04004122func addResumptionVersionTests() {
David Benjamin01fe8202014-09-24 15:21:44 -04004123 for _, sessionVers := range tlsVersions {
David Benjamin01fe8202014-09-24 15:21:44 -04004124 for _, resumeVers := range tlsVersions {
Nick Harper1fd39d82016-06-14 18:14:35 -07004125 cipher := TLS_RSA_WITH_AES_128_CBC_SHA
4126 if sessionVers.version >= VersionTLS13 || resumeVers.version >= VersionTLS13 {
4127 // TLS 1.3 only shares ciphers with TLS 1.2, so
4128 // we skip certain combinations and use a
4129 // different cipher to test with.
4130 cipher = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
4131 if sessionVers.version < VersionTLS12 || resumeVers.version < VersionTLS12 {
4132 continue
4133 }
4134 }
4135
David Benjamin8b8c0062014-11-23 02:47:52 -05004136 protocols := []protocol{tls}
4137 if sessionVers.hasDTLS && resumeVers.hasDTLS {
4138 protocols = append(protocols, dtls)
David Benjaminbdf5e722014-11-11 00:52:15 -05004139 }
David Benjamin8b8c0062014-11-23 02:47:52 -05004140 for _, protocol := range protocols {
4141 suffix := "-" + sessionVers.name + "-" + resumeVers.name
4142 if protocol == dtls {
4143 suffix += "-DTLS"
4144 }
4145
David Benjaminece3de92015-03-16 18:02:20 -04004146 if sessionVers.version == resumeVers.version {
4147 testCases = append(testCases, testCase{
4148 protocol: protocol,
4149 name: "Resume-Client" + suffix,
4150 resumeSession: true,
4151 config: Config{
4152 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004153 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004154 },
David Benjaminece3de92015-03-16 18:02:20 -04004155 expectedVersion: sessionVers.version,
4156 expectedResumeVersion: resumeVers.version,
4157 })
4158 } else {
4159 testCases = append(testCases, testCase{
4160 protocol: protocol,
4161 name: "Resume-Client-Mismatch" + suffix,
4162 resumeSession: true,
4163 config: Config{
4164 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004165 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004166 },
David Benjaminece3de92015-03-16 18:02:20 -04004167 expectedVersion: sessionVers.version,
4168 resumeConfig: &Config{
4169 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004170 CipherSuites: []uint16{cipher},
David Benjaminece3de92015-03-16 18:02:20 -04004171 Bugs: ProtocolBugs{
4172 AllowSessionVersionMismatch: true,
4173 },
4174 },
4175 expectedResumeVersion: resumeVers.version,
4176 shouldFail: true,
4177 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:",
4178 })
4179 }
David Benjamin8b8c0062014-11-23 02:47:52 -05004180
4181 testCases = append(testCases, testCase{
4182 protocol: protocol,
4183 name: "Resume-Client-NoResume" + suffix,
David Benjamin8b8c0062014-11-23 02:47:52 -05004184 resumeSession: true,
4185 config: Config{
4186 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004187 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004188 },
4189 expectedVersion: sessionVers.version,
4190 resumeConfig: &Config{
4191 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004192 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004193 },
4194 newSessionsOnResume: true,
Adam Langleyb0eef0a2015-06-02 10:47:39 -07004195 expectResumeRejected: true,
David Benjamin8b8c0062014-11-23 02:47:52 -05004196 expectedResumeVersion: resumeVers.version,
4197 })
4198
David Benjamin8b8c0062014-11-23 02:47:52 -05004199 testCases = append(testCases, testCase{
4200 protocol: protocol,
4201 testType: serverTest,
4202 name: "Resume-Server" + suffix,
David Benjamin8b8c0062014-11-23 02:47:52 -05004203 resumeSession: true,
4204 config: Config{
4205 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004206 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004207 },
Adam Langleyb0eef0a2015-06-02 10:47:39 -07004208 expectedVersion: sessionVers.version,
4209 expectResumeRejected: sessionVers.version != resumeVers.version,
David Benjamin8b8c0062014-11-23 02:47:52 -05004210 resumeConfig: &Config{
4211 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004212 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004213 },
4214 expectedResumeVersion: resumeVers.version,
4215 })
4216 }
David Benjamin01fe8202014-09-24 15:21:44 -04004217 }
4218 }
David Benjaminece3de92015-03-16 18:02:20 -04004219
Nick Harper1fd39d82016-06-14 18:14:35 -07004220 // TODO(davidben): This test should have a TLS 1.3 variant later.
David Benjaminece3de92015-03-16 18:02:20 -04004221 testCases = append(testCases, testCase{
4222 name: "Resume-Client-CipherMismatch",
4223 resumeSession: true,
4224 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004225 MaxVersion: VersionTLS12,
David Benjaminece3de92015-03-16 18:02:20 -04004226 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
4227 },
4228 resumeConfig: &Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004229 MaxVersion: VersionTLS12,
David Benjaminece3de92015-03-16 18:02:20 -04004230 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
4231 Bugs: ProtocolBugs{
4232 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA,
4233 },
4234 },
4235 shouldFail: true,
4236 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
4237 })
David Benjamin01fe8202014-09-24 15:21:44 -04004238}
4239
Adam Langley2ae77d22014-10-28 17:29:33 -07004240func addRenegotiationTests() {
David Benjamin44d3eed2015-05-21 01:29:55 -04004241 // Servers cannot renegotiate.
David Benjaminb16346b2015-04-08 19:16:58 -04004242 testCases = append(testCases, testCase{
4243 testType: serverTest,
David Benjamin44d3eed2015-05-21 01:29:55 -04004244 name: "Renegotiate-Server-Forbidden",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004245 renegotiate: 1,
David Benjaminb16346b2015-04-08 19:16:58 -04004246 shouldFail: true,
4247 expectedError: ":NO_RENEGOTIATION:",
4248 expectedLocalError: "remote error: no renegotiation",
4249 })
Adam Langley5021b222015-06-12 18:27:58 -07004250 // The server shouldn't echo the renegotiation extension unless
4251 // requested by the client.
4252 testCases = append(testCases, testCase{
4253 testType: serverTest,
4254 name: "Renegotiate-Server-NoExt",
4255 config: Config{
4256 Bugs: ProtocolBugs{
4257 NoRenegotiationInfo: true,
4258 RequireRenegotiationInfo: true,
4259 },
4260 },
4261 shouldFail: true,
4262 expectedLocalError: "renegotiation extension missing",
4263 })
4264 // The renegotiation SCSV should be sufficient for the server to echo
4265 // the extension.
4266 testCases = append(testCases, testCase{
4267 testType: serverTest,
4268 name: "Renegotiate-Server-NoExt-SCSV",
4269 config: Config{
4270 Bugs: ProtocolBugs{
4271 NoRenegotiationInfo: true,
4272 SendRenegotiationSCSV: true,
4273 RequireRenegotiationInfo: true,
4274 },
4275 },
4276 })
Adam Langleycf2d4f42014-10-28 19:06:14 -07004277 testCases = append(testCases, testCase{
David Benjamin4b27d9f2015-05-12 22:42:52 -04004278 name: "Renegotiate-Client",
David Benjamincdea40c2015-03-19 14:09:43 -04004279 config: Config{
4280 Bugs: ProtocolBugs{
David Benjamin4b27d9f2015-05-12 22:42:52 -04004281 FailIfResumeOnRenego: true,
David Benjamincdea40c2015-03-19 14:09:43 -04004282 },
4283 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004284 renegotiate: 1,
4285 flags: []string{
4286 "-renegotiate-freely",
4287 "-expect-total-renegotiations", "1",
4288 },
David Benjamincdea40c2015-03-19 14:09:43 -04004289 })
4290 testCases = append(testCases, testCase{
Adam Langleycf2d4f42014-10-28 19:06:14 -07004291 name: "Renegotiate-Client-EmptyExt",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004292 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004293 config: Config{
4294 Bugs: ProtocolBugs{
4295 EmptyRenegotiationInfo: true,
4296 },
4297 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004298 flags: []string{"-renegotiate-freely"},
Adam Langleycf2d4f42014-10-28 19:06:14 -07004299 shouldFail: true,
4300 expectedError: ":RENEGOTIATION_MISMATCH:",
4301 })
4302 testCases = append(testCases, testCase{
4303 name: "Renegotiate-Client-BadExt",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004304 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004305 config: Config{
4306 Bugs: ProtocolBugs{
4307 BadRenegotiationInfo: true,
4308 },
4309 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004310 flags: []string{"-renegotiate-freely"},
Adam Langleycf2d4f42014-10-28 19:06:14 -07004311 shouldFail: true,
4312 expectedError: ":RENEGOTIATION_MISMATCH:",
4313 })
4314 testCases = append(testCases, testCase{
David Benjamin3e052de2015-11-25 20:10:31 -05004315 name: "Renegotiate-Client-Downgrade",
4316 renegotiate: 1,
4317 config: Config{
4318 Bugs: ProtocolBugs{
4319 NoRenegotiationInfoAfterInitial: true,
4320 },
4321 },
4322 flags: []string{"-renegotiate-freely"},
4323 shouldFail: true,
4324 expectedError: ":RENEGOTIATION_MISMATCH:",
4325 })
4326 testCases = append(testCases, testCase{
4327 name: "Renegotiate-Client-Upgrade",
4328 renegotiate: 1,
4329 config: Config{
4330 Bugs: ProtocolBugs{
4331 NoRenegotiationInfoInInitial: true,
4332 },
4333 },
4334 flags: []string{"-renegotiate-freely"},
4335 shouldFail: true,
4336 expectedError: ":RENEGOTIATION_MISMATCH:",
4337 })
4338 testCases = append(testCases, testCase{
David Benjamincff0b902015-05-15 23:09:47 -04004339 name: "Renegotiate-Client-NoExt-Allowed",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004340 renegotiate: 1,
David Benjamincff0b902015-05-15 23:09:47 -04004341 config: Config{
4342 Bugs: ProtocolBugs{
4343 NoRenegotiationInfo: true,
4344 },
4345 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004346 flags: []string{
4347 "-renegotiate-freely",
4348 "-expect-total-renegotiations", "1",
4349 },
David Benjamincff0b902015-05-15 23:09:47 -04004350 })
4351 testCases = append(testCases, testCase{
Adam Langleycf2d4f42014-10-28 19:06:14 -07004352 name: "Renegotiate-Client-SwitchCiphers",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004353 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004354 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004355 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004356 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
4357 },
4358 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004359 flags: []string{
4360 "-renegotiate-freely",
4361 "-expect-total-renegotiations", "1",
4362 },
Adam Langleycf2d4f42014-10-28 19:06:14 -07004363 })
4364 testCases = append(testCases, testCase{
4365 name: "Renegotiate-Client-SwitchCiphers2",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004366 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004367 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004368 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004369 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4370 },
4371 renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004372 flags: []string{
4373 "-renegotiate-freely",
4374 "-expect-total-renegotiations", "1",
4375 },
David Benjaminb16346b2015-04-08 19:16:58 -04004376 })
4377 testCases = append(testCases, testCase{
David Benjaminc44b1df2014-11-23 12:11:01 -05004378 name: "Renegotiate-SameClientVersion",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004379 renegotiate: 1,
David Benjaminc44b1df2014-11-23 12:11:01 -05004380 config: Config{
4381 MaxVersion: VersionTLS10,
4382 Bugs: ProtocolBugs{
4383 RequireSameRenegoClientVersion: true,
4384 },
4385 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004386 flags: []string{
4387 "-renegotiate-freely",
4388 "-expect-total-renegotiations", "1",
4389 },
David Benjaminc44b1df2014-11-23 12:11:01 -05004390 })
Adam Langleyb558c4c2015-07-08 12:16:38 -07004391 testCases = append(testCases, testCase{
4392 name: "Renegotiate-FalseStart",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004393 renegotiate: 1,
Adam Langleyb558c4c2015-07-08 12:16:38 -07004394 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004395 MaxVersion: VersionTLS12,
Adam Langleyb558c4c2015-07-08 12:16:38 -07004396 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4397 NextProtos: []string{"foo"},
4398 },
4399 flags: []string{
4400 "-false-start",
4401 "-select-next-proto", "foo",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004402 "-renegotiate-freely",
David Benjamin324dce42015-10-12 19:49:00 -04004403 "-expect-total-renegotiations", "1",
Adam Langleyb558c4c2015-07-08 12:16:38 -07004404 },
4405 shimWritesFirst: true,
4406 })
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004407
4408 // Client-side renegotiation controls.
4409 testCases = append(testCases, testCase{
4410 name: "Renegotiate-Client-Forbidden-1",
4411 renegotiate: 1,
4412 shouldFail: true,
4413 expectedError: ":NO_RENEGOTIATION:",
4414 expectedLocalError: "remote error: no renegotiation",
4415 })
4416 testCases = append(testCases, testCase{
4417 name: "Renegotiate-Client-Once-1",
4418 renegotiate: 1,
4419 flags: []string{
4420 "-renegotiate-once",
4421 "-expect-total-renegotiations", "1",
4422 },
4423 })
4424 testCases = append(testCases, testCase{
4425 name: "Renegotiate-Client-Freely-1",
4426 renegotiate: 1,
4427 flags: []string{
4428 "-renegotiate-freely",
4429 "-expect-total-renegotiations", "1",
4430 },
4431 })
4432 testCases = append(testCases, testCase{
4433 name: "Renegotiate-Client-Once-2",
4434 renegotiate: 2,
4435 flags: []string{"-renegotiate-once"},
4436 shouldFail: true,
4437 expectedError: ":NO_RENEGOTIATION:",
4438 expectedLocalError: "remote error: no renegotiation",
4439 })
4440 testCases = append(testCases, testCase{
4441 name: "Renegotiate-Client-Freely-2",
4442 renegotiate: 2,
4443 flags: []string{
4444 "-renegotiate-freely",
4445 "-expect-total-renegotiations", "2",
4446 },
4447 })
Adam Langley27a0d082015-11-03 13:34:10 -08004448 testCases = append(testCases, testCase{
4449 name: "Renegotiate-Client-NoIgnore",
4450 config: Config{
4451 Bugs: ProtocolBugs{
4452 SendHelloRequestBeforeEveryAppDataRecord: true,
4453 },
4454 },
4455 shouldFail: true,
4456 expectedError: ":NO_RENEGOTIATION:",
4457 })
4458 testCases = append(testCases, testCase{
4459 name: "Renegotiate-Client-Ignore",
4460 config: Config{
4461 Bugs: ProtocolBugs{
4462 SendHelloRequestBeforeEveryAppDataRecord: true,
4463 },
4464 },
4465 flags: []string{
4466 "-renegotiate-ignore",
4467 "-expect-total-renegotiations", "0",
4468 },
4469 })
Adam Langley2ae77d22014-10-28 17:29:33 -07004470}
4471
David Benjamin5e961c12014-11-07 01:48:35 -05004472func addDTLSReplayTests() {
4473 // Test that sequence number replays are detected.
4474 testCases = append(testCases, testCase{
4475 protocol: dtls,
4476 name: "DTLS-Replay",
David Benjamin8e6db492015-07-25 18:29:23 -04004477 messageCount: 200,
David Benjamin5e961c12014-11-07 01:48:35 -05004478 replayWrites: true,
4479 })
4480
David Benjamin8e6db492015-07-25 18:29:23 -04004481 // Test the incoming sequence number skipping by values larger
David Benjamin5e961c12014-11-07 01:48:35 -05004482 // than the retransmit window.
4483 testCases = append(testCases, testCase{
4484 protocol: dtls,
4485 name: "DTLS-Replay-LargeGaps",
4486 config: Config{
4487 Bugs: ProtocolBugs{
David Benjamin8e6db492015-07-25 18:29:23 -04004488 SequenceNumberMapping: func(in uint64) uint64 {
4489 return in * 127
4490 },
David Benjamin5e961c12014-11-07 01:48:35 -05004491 },
4492 },
David Benjamin8e6db492015-07-25 18:29:23 -04004493 messageCount: 200,
4494 replayWrites: true,
4495 })
4496
4497 // Test the incoming sequence number changing non-monotonically.
4498 testCases = append(testCases, testCase{
4499 protocol: dtls,
4500 name: "DTLS-Replay-NonMonotonic",
4501 config: Config{
4502 Bugs: ProtocolBugs{
4503 SequenceNumberMapping: func(in uint64) uint64 {
4504 return in ^ 31
4505 },
4506 },
4507 },
4508 messageCount: 200,
David Benjamin5e961c12014-11-07 01:48:35 -05004509 replayWrites: true,
4510 })
4511}
4512
David Benjamin000800a2014-11-14 01:43:59 -05004513var testHashes = []struct {
4514 name string
4515 id uint8
4516}{
4517 {"SHA1", hashSHA1},
David Benjamin000800a2014-11-14 01:43:59 -05004518 {"SHA256", hashSHA256},
4519 {"SHA384", hashSHA384},
4520 {"SHA512", hashSHA512},
4521}
4522
4523func addSigningHashTests() {
4524 // Make sure each hash works. Include some fake hashes in the list and
4525 // ensure they're ignored.
4526 for _, hash := range testHashes {
4527 testCases = append(testCases, testCase{
4528 name: "SigningHash-ClientAuth-" + hash.name,
4529 config: Config{
4530 ClientAuth: RequireAnyClientCert,
4531 SignatureAndHashes: []signatureAndHash{
4532 {signatureRSA, 42},
4533 {signatureRSA, hash.id},
4534 {signatureRSA, 255},
4535 },
4536 },
4537 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07004538 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4539 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05004540 },
4541 })
4542
4543 testCases = append(testCases, testCase{
4544 testType: serverTest,
4545 name: "SigningHash-ServerKeyExchange-Sign-" + hash.name,
4546 config: Config{
4547 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4548 SignatureAndHashes: []signatureAndHash{
4549 {signatureRSA, 42},
4550 {signatureRSA, hash.id},
4551 {signatureRSA, 255},
4552 },
4553 },
4554 })
David Benjamin6e807652015-11-02 12:02:20 -05004555
4556 testCases = append(testCases, testCase{
4557 name: "SigningHash-ServerKeyExchange-Verify-" + hash.name,
4558 config: Config{
4559 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4560 SignatureAndHashes: []signatureAndHash{
4561 {signatureRSA, 42},
4562 {signatureRSA, hash.id},
4563 {signatureRSA, 255},
4564 },
4565 },
4566 flags: []string{"-expect-server-key-exchange-hash", strconv.Itoa(int(hash.id))},
4567 })
David Benjamin000800a2014-11-14 01:43:59 -05004568 }
4569
4570 // Test that hash resolution takes the signature type into account.
4571 testCases = append(testCases, testCase{
4572 name: "SigningHash-ClientAuth-SignatureType",
4573 config: Config{
4574 ClientAuth: RequireAnyClientCert,
4575 SignatureAndHashes: []signatureAndHash{
4576 {signatureECDSA, hashSHA512},
4577 {signatureRSA, hashSHA384},
4578 {signatureECDSA, hashSHA1},
4579 },
4580 },
4581 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07004582 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4583 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05004584 },
4585 })
4586
4587 testCases = append(testCases, testCase{
4588 testType: serverTest,
4589 name: "SigningHash-ServerKeyExchange-SignatureType",
4590 config: Config{
4591 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4592 SignatureAndHashes: []signatureAndHash{
4593 {signatureECDSA, hashSHA512},
4594 {signatureRSA, hashSHA384},
4595 {signatureECDSA, hashSHA1},
4596 },
4597 },
4598 })
4599
4600 // Test that, if the list is missing, the peer falls back to SHA-1.
4601 testCases = append(testCases, testCase{
4602 name: "SigningHash-ClientAuth-Fallback",
4603 config: Config{
4604 ClientAuth: RequireAnyClientCert,
4605 SignatureAndHashes: []signatureAndHash{
4606 {signatureRSA, hashSHA1},
4607 },
4608 Bugs: ProtocolBugs{
4609 NoSignatureAndHashes: true,
4610 },
4611 },
4612 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07004613 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4614 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05004615 },
4616 })
4617
4618 testCases = append(testCases, testCase{
4619 testType: serverTest,
4620 name: "SigningHash-ServerKeyExchange-Fallback",
4621 config: Config{
4622 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4623 SignatureAndHashes: []signatureAndHash{
4624 {signatureRSA, hashSHA1},
4625 },
4626 Bugs: ProtocolBugs{
4627 NoSignatureAndHashes: true,
4628 },
4629 },
4630 })
David Benjamin72dc7832015-03-16 17:49:43 -04004631
4632 // Test that hash preferences are enforced. BoringSSL defaults to
4633 // rejecting MD5 signatures.
4634 testCases = append(testCases, testCase{
4635 testType: serverTest,
4636 name: "SigningHash-ClientAuth-Enforced",
4637 config: Config{
4638 Certificates: []Certificate{rsaCertificate},
4639 SignatureAndHashes: []signatureAndHash{
4640 {signatureRSA, hashMD5},
4641 // Advertise SHA-1 so the handshake will
4642 // proceed, but the shim's preferences will be
4643 // ignored in CertificateVerify generation, so
4644 // MD5 will be chosen.
4645 {signatureRSA, hashSHA1},
4646 },
4647 Bugs: ProtocolBugs{
4648 IgnorePeerSignatureAlgorithmPreferences: true,
4649 },
4650 },
4651 flags: []string{"-require-any-client-certificate"},
4652 shouldFail: true,
4653 expectedError: ":WRONG_SIGNATURE_TYPE:",
4654 })
4655
4656 testCases = append(testCases, testCase{
4657 name: "SigningHash-ServerKeyExchange-Enforced",
4658 config: Config{
4659 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4660 SignatureAndHashes: []signatureAndHash{
4661 {signatureRSA, hashMD5},
4662 },
4663 Bugs: ProtocolBugs{
4664 IgnorePeerSignatureAlgorithmPreferences: true,
4665 },
4666 },
4667 shouldFail: true,
4668 expectedError: ":WRONG_SIGNATURE_TYPE:",
4669 })
Steven Valdez0d62f262015-09-04 12:41:04 -04004670
4671 // Test that the agreed upon digest respects the client preferences and
4672 // the server digests.
4673 testCases = append(testCases, testCase{
4674 name: "Agree-Digest-Fallback",
4675 config: Config{
4676 ClientAuth: RequireAnyClientCert,
4677 SignatureAndHashes: []signatureAndHash{
4678 {signatureRSA, hashSHA512},
4679 {signatureRSA, hashSHA1},
4680 },
4681 },
4682 flags: []string{
4683 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4684 "-key-file", path.Join(*resourceDir, rsaKeyFile),
4685 },
4686 digestPrefs: "SHA256",
4687 expectedClientCertSignatureHash: hashSHA1,
4688 })
4689 testCases = append(testCases, testCase{
4690 name: "Agree-Digest-SHA256",
4691 config: Config{
4692 ClientAuth: RequireAnyClientCert,
4693 SignatureAndHashes: []signatureAndHash{
4694 {signatureRSA, hashSHA1},
4695 {signatureRSA, hashSHA256},
4696 },
4697 },
4698 flags: []string{
4699 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4700 "-key-file", path.Join(*resourceDir, rsaKeyFile),
4701 },
4702 digestPrefs: "SHA256,SHA1",
4703 expectedClientCertSignatureHash: hashSHA256,
4704 })
4705 testCases = append(testCases, testCase{
4706 name: "Agree-Digest-SHA1",
4707 config: Config{
4708 ClientAuth: RequireAnyClientCert,
4709 SignatureAndHashes: []signatureAndHash{
4710 {signatureRSA, hashSHA1},
4711 },
4712 },
4713 flags: []string{
4714 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4715 "-key-file", path.Join(*resourceDir, rsaKeyFile),
4716 },
4717 digestPrefs: "SHA512,SHA256,SHA1",
4718 expectedClientCertSignatureHash: hashSHA1,
4719 })
4720 testCases = append(testCases, testCase{
4721 name: "Agree-Digest-Default",
4722 config: Config{
4723 ClientAuth: RequireAnyClientCert,
4724 SignatureAndHashes: []signatureAndHash{
4725 {signatureRSA, hashSHA256},
4726 {signatureECDSA, hashSHA256},
4727 {signatureRSA, hashSHA1},
4728 {signatureECDSA, hashSHA1},
4729 },
4730 },
4731 flags: []string{
4732 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4733 "-key-file", path.Join(*resourceDir, rsaKeyFile),
4734 },
4735 expectedClientCertSignatureHash: hashSHA256,
4736 })
David Benjamin000800a2014-11-14 01:43:59 -05004737}
4738
David Benjamin83f90402015-01-27 01:09:43 -05004739// timeouts is the retransmit schedule for BoringSSL. It doubles and
4740// caps at 60 seconds. On the 13th timeout, it gives up.
4741var timeouts = []time.Duration{
4742 1 * time.Second,
4743 2 * time.Second,
4744 4 * time.Second,
4745 8 * time.Second,
4746 16 * time.Second,
4747 32 * time.Second,
4748 60 * time.Second,
4749 60 * time.Second,
4750 60 * time.Second,
4751 60 * time.Second,
4752 60 * time.Second,
4753 60 * time.Second,
4754 60 * time.Second,
4755}
4756
Taylor Brandstetter376a0fe2016-05-10 19:30:28 -07004757// shortTimeouts is an alternate set of timeouts which would occur if the
4758// initial timeout duration was set to 250ms.
4759var shortTimeouts = []time.Duration{
4760 250 * time.Millisecond,
4761 500 * time.Millisecond,
4762 1 * time.Second,
4763 2 * time.Second,
4764 4 * time.Second,
4765 8 * time.Second,
4766 16 * time.Second,
4767 32 * time.Second,
4768 60 * time.Second,
4769 60 * time.Second,
4770 60 * time.Second,
4771 60 * time.Second,
4772 60 * time.Second,
4773}
4774
David Benjamin83f90402015-01-27 01:09:43 -05004775func addDTLSRetransmitTests() {
David Benjamin585d7a42016-06-02 14:58:00 -04004776 // These tests work by coordinating some behavior on both the shim and
4777 // the runner.
4778 //
4779 // TimeoutSchedule configures the runner to send a series of timeout
4780 // opcodes to the shim (see packetAdaptor) immediately before reading
4781 // each peer handshake flight N. The timeout opcode both simulates a
4782 // timeout in the shim and acts as a synchronization point to help the
4783 // runner bracket each handshake flight.
4784 //
4785 // We assume the shim does not read from the channel eagerly. It must
4786 // first wait until it has sent flight N and is ready to receive
4787 // handshake flight N+1. At this point, it will process the timeout
4788 // opcode. It must then immediately respond with a timeout ACK and act
4789 // as if the shim was idle for the specified amount of time.
4790 //
4791 // The runner then drops all packets received before the ACK and
4792 // continues waiting for flight N. This ordering results in one attempt
4793 // at sending flight N to be dropped. For the test to complete, the
4794 // shim must send flight N again, testing that the shim implements DTLS
4795 // retransmit on a timeout.
4796
4797 for _, async := range []bool{true, false} {
4798 var tests []testCase
4799
4800 // Test that this is indeed the timeout schedule. Stress all
4801 // four patterns of handshake.
4802 for i := 1; i < len(timeouts); i++ {
4803 number := strconv.Itoa(i)
4804 tests = append(tests, testCase{
4805 protocol: dtls,
4806 name: "DTLS-Retransmit-Client-" + number,
4807 config: Config{
4808 Bugs: ProtocolBugs{
4809 TimeoutSchedule: timeouts[:i],
4810 },
4811 },
4812 resumeSession: true,
4813 })
4814 tests = append(tests, testCase{
4815 protocol: dtls,
4816 testType: serverTest,
4817 name: "DTLS-Retransmit-Server-" + number,
4818 config: Config{
4819 Bugs: ProtocolBugs{
4820 TimeoutSchedule: timeouts[:i],
4821 },
4822 },
4823 resumeSession: true,
4824 })
4825 }
4826
4827 // Test that exceeding the timeout schedule hits a read
4828 // timeout.
4829 tests = append(tests, testCase{
David Benjamin83f90402015-01-27 01:09:43 -05004830 protocol: dtls,
David Benjamin585d7a42016-06-02 14:58:00 -04004831 name: "DTLS-Retransmit-Timeout",
David Benjamin83f90402015-01-27 01:09:43 -05004832 config: Config{
4833 Bugs: ProtocolBugs{
David Benjamin585d7a42016-06-02 14:58:00 -04004834 TimeoutSchedule: timeouts,
David Benjamin83f90402015-01-27 01:09:43 -05004835 },
4836 },
4837 resumeSession: true,
David Benjamin585d7a42016-06-02 14:58:00 -04004838 shouldFail: true,
4839 expectedError: ":READ_TIMEOUT_EXPIRED:",
David Benjamin83f90402015-01-27 01:09:43 -05004840 })
David Benjamin585d7a42016-06-02 14:58:00 -04004841
4842 if async {
4843 // Test that timeout handling has a fudge factor, due to API
4844 // problems.
4845 tests = append(tests, testCase{
4846 protocol: dtls,
4847 name: "DTLS-Retransmit-Fudge",
4848 config: Config{
4849 Bugs: ProtocolBugs{
4850 TimeoutSchedule: []time.Duration{
4851 timeouts[0] - 10*time.Millisecond,
4852 },
4853 },
4854 },
4855 resumeSession: true,
4856 })
4857 }
4858
4859 // Test that the final Finished retransmitting isn't
4860 // duplicated if the peer badly fragments everything.
4861 tests = append(tests, testCase{
4862 testType: serverTest,
4863 protocol: dtls,
4864 name: "DTLS-Retransmit-Fragmented",
4865 config: Config{
4866 Bugs: ProtocolBugs{
4867 TimeoutSchedule: []time.Duration{timeouts[0]},
4868 MaxHandshakeRecordLength: 2,
4869 },
4870 },
4871 })
4872
4873 // Test the timeout schedule when a shorter initial timeout duration is set.
4874 tests = append(tests, testCase{
4875 protocol: dtls,
4876 name: "DTLS-Retransmit-Short-Client",
4877 config: Config{
4878 Bugs: ProtocolBugs{
4879 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
4880 },
4881 },
4882 resumeSession: true,
4883 flags: []string{"-initial-timeout-duration-ms", "250"},
4884 })
4885 tests = append(tests, testCase{
David Benjamin83f90402015-01-27 01:09:43 -05004886 protocol: dtls,
4887 testType: serverTest,
David Benjamin585d7a42016-06-02 14:58:00 -04004888 name: "DTLS-Retransmit-Short-Server",
David Benjamin83f90402015-01-27 01:09:43 -05004889 config: Config{
4890 Bugs: ProtocolBugs{
David Benjamin585d7a42016-06-02 14:58:00 -04004891 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
David Benjamin83f90402015-01-27 01:09:43 -05004892 },
4893 },
4894 resumeSession: true,
David Benjamin585d7a42016-06-02 14:58:00 -04004895 flags: []string{"-initial-timeout-duration-ms", "250"},
David Benjamin83f90402015-01-27 01:09:43 -05004896 })
David Benjamin585d7a42016-06-02 14:58:00 -04004897
4898 for _, test := range tests {
4899 if async {
4900 test.name += "-Async"
4901 test.flags = append(test.flags, "-async")
4902 }
4903
4904 testCases = append(testCases, test)
4905 }
David Benjamin83f90402015-01-27 01:09:43 -05004906 }
David Benjamin83f90402015-01-27 01:09:43 -05004907}
4908
David Benjaminc565ebb2015-04-03 04:06:36 -04004909func addExportKeyingMaterialTests() {
4910 for _, vers := range tlsVersions {
4911 if vers.version == VersionSSL30 {
4912 continue
4913 }
4914 testCases = append(testCases, testCase{
4915 name: "ExportKeyingMaterial-" + vers.name,
4916 config: Config{
4917 MaxVersion: vers.version,
4918 },
4919 exportKeyingMaterial: 1024,
4920 exportLabel: "label",
4921 exportContext: "context",
4922 useExportContext: true,
4923 })
4924 testCases = append(testCases, testCase{
4925 name: "ExportKeyingMaterial-NoContext-" + vers.name,
4926 config: Config{
4927 MaxVersion: vers.version,
4928 },
4929 exportKeyingMaterial: 1024,
4930 })
4931 testCases = append(testCases, testCase{
4932 name: "ExportKeyingMaterial-EmptyContext-" + vers.name,
4933 config: Config{
4934 MaxVersion: vers.version,
4935 },
4936 exportKeyingMaterial: 1024,
4937 useExportContext: true,
4938 })
4939 testCases = append(testCases, testCase{
4940 name: "ExportKeyingMaterial-Small-" + vers.name,
4941 config: Config{
4942 MaxVersion: vers.version,
4943 },
4944 exportKeyingMaterial: 1,
4945 exportLabel: "label",
4946 exportContext: "context",
4947 useExportContext: true,
4948 })
4949 }
4950 testCases = append(testCases, testCase{
4951 name: "ExportKeyingMaterial-SSL3",
4952 config: Config{
4953 MaxVersion: VersionSSL30,
4954 },
4955 exportKeyingMaterial: 1024,
4956 exportLabel: "label",
4957 exportContext: "context",
4958 useExportContext: true,
4959 shouldFail: true,
4960 expectedError: "failed to export keying material",
4961 })
4962}
4963
Adam Langleyaf0e32c2015-06-03 09:57:23 -07004964func addTLSUniqueTests() {
4965 for _, isClient := range []bool{false, true} {
4966 for _, isResumption := range []bool{false, true} {
4967 for _, hasEMS := range []bool{false, true} {
4968 var suffix string
4969 if isResumption {
4970 suffix = "Resume-"
4971 } else {
4972 suffix = "Full-"
4973 }
4974
4975 if hasEMS {
4976 suffix += "EMS-"
4977 } else {
4978 suffix += "NoEMS-"
4979 }
4980
4981 if isClient {
4982 suffix += "Client"
4983 } else {
4984 suffix += "Server"
4985 }
4986
4987 test := testCase{
4988 name: "TLSUnique-" + suffix,
4989 testTLSUnique: true,
4990 config: Config{
4991 Bugs: ProtocolBugs{
4992 NoExtendedMasterSecret: !hasEMS,
4993 },
4994 },
4995 }
4996
4997 if isResumption {
4998 test.resumeSession = true
4999 test.resumeConfig = &Config{
5000 Bugs: ProtocolBugs{
5001 NoExtendedMasterSecret: !hasEMS,
5002 },
5003 }
5004 }
5005
5006 if isResumption && !hasEMS {
5007 test.shouldFail = true
5008 test.expectedError = "failed to get tls-unique"
5009 }
5010
5011 testCases = append(testCases, test)
5012 }
5013 }
5014 }
5015}
5016
Adam Langley09505632015-07-30 18:10:13 -07005017func addCustomExtensionTests() {
5018 expectedContents := "custom extension"
5019 emptyString := ""
5020
5021 for _, isClient := range []bool{false, true} {
5022 suffix := "Server"
5023 flag := "-enable-server-custom-extension"
5024 testType := serverTest
5025 if isClient {
5026 suffix = "Client"
5027 flag = "-enable-client-custom-extension"
5028 testType = clientTest
5029 }
5030
5031 testCases = append(testCases, testCase{
5032 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005033 name: "CustomExtensions-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005034 config: Config{
David Benjamin399e7c92015-07-30 23:01:27 -04005035 Bugs: ProtocolBugs{
5036 CustomExtension: expectedContents,
Adam Langley09505632015-07-30 18:10:13 -07005037 ExpectedCustomExtension: &expectedContents,
5038 },
5039 },
5040 flags: []string{flag},
5041 })
5042
5043 // If the parse callback fails, the handshake should also fail.
5044 testCases = append(testCases, testCase{
5045 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005046 name: "CustomExtensions-ParseError-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005047 config: Config{
David Benjamin399e7c92015-07-30 23:01:27 -04005048 Bugs: ProtocolBugs{
5049 CustomExtension: expectedContents + "foo",
Adam Langley09505632015-07-30 18:10:13 -07005050 ExpectedCustomExtension: &expectedContents,
5051 },
5052 },
David Benjamin399e7c92015-07-30 23:01:27 -04005053 flags: []string{flag},
5054 shouldFail: true,
Adam Langley09505632015-07-30 18:10:13 -07005055 expectedError: ":CUSTOM_EXTENSION_ERROR:",
5056 })
5057
5058 // If the add callback fails, the handshake should also fail.
5059 testCases = append(testCases, testCase{
5060 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005061 name: "CustomExtensions-FailAdd-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005062 config: Config{
David Benjamin399e7c92015-07-30 23:01:27 -04005063 Bugs: ProtocolBugs{
5064 CustomExtension: expectedContents,
Adam Langley09505632015-07-30 18:10:13 -07005065 ExpectedCustomExtension: &expectedContents,
5066 },
5067 },
David Benjamin399e7c92015-07-30 23:01:27 -04005068 flags: []string{flag, "-custom-extension-fail-add"},
5069 shouldFail: true,
Adam Langley09505632015-07-30 18:10:13 -07005070 expectedError: ":CUSTOM_EXTENSION_ERROR:",
5071 })
5072
5073 // If the add callback returns zero, no extension should be
5074 // added.
5075 skipCustomExtension := expectedContents
5076 if isClient {
5077 // For the case where the client skips sending the
5078 // custom extension, the server must not “echo” it.
5079 skipCustomExtension = ""
5080 }
5081 testCases = append(testCases, testCase{
5082 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005083 name: "CustomExtensions-Skip-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005084 config: Config{
David Benjamin399e7c92015-07-30 23:01:27 -04005085 Bugs: ProtocolBugs{
5086 CustomExtension: skipCustomExtension,
Adam Langley09505632015-07-30 18:10:13 -07005087 ExpectedCustomExtension: &emptyString,
5088 },
5089 },
5090 flags: []string{flag, "-custom-extension-skip"},
5091 })
5092 }
5093
5094 // The custom extension add callback should not be called if the client
5095 // doesn't send the extension.
5096 testCases = append(testCases, testCase{
5097 testType: serverTest,
David Benjamin399e7c92015-07-30 23:01:27 -04005098 name: "CustomExtensions-NotCalled-Server",
Adam Langley09505632015-07-30 18:10:13 -07005099 config: Config{
David Benjamin399e7c92015-07-30 23:01:27 -04005100 Bugs: ProtocolBugs{
Adam Langley09505632015-07-30 18:10:13 -07005101 ExpectedCustomExtension: &emptyString,
5102 },
5103 },
5104 flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
5105 })
Adam Langley2deb9842015-08-07 11:15:37 -07005106
5107 // Test an unknown extension from the server.
5108 testCases = append(testCases, testCase{
5109 testType: clientTest,
5110 name: "UnknownExtension-Client",
5111 config: Config{
5112 Bugs: ProtocolBugs{
5113 CustomExtension: expectedContents,
5114 },
5115 },
5116 shouldFail: true,
5117 expectedError: ":UNEXPECTED_EXTENSION:",
5118 })
Adam Langley09505632015-07-30 18:10:13 -07005119}
5120
David Benjaminb36a3952015-12-01 18:53:13 -05005121func addRSAClientKeyExchangeTests() {
5122 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ {
5123 testCases = append(testCases, testCase{
5124 testType: serverTest,
5125 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad),
5126 config: Config{
5127 // Ensure the ClientHello version and final
5128 // version are different, to detect if the
5129 // server uses the wrong one.
5130 MaxVersion: VersionTLS11,
5131 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
5132 Bugs: ProtocolBugs{
5133 BadRSAClientKeyExchange: bad,
5134 },
5135 },
5136 shouldFail: true,
5137 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5138 })
5139 }
5140}
5141
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005142var testCurves = []struct {
5143 name string
5144 id CurveID
5145}{
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005146 {"P-256", CurveP256},
5147 {"P-384", CurveP384},
5148 {"P-521", CurveP521},
David Benjamin4298d772015-12-19 00:18:25 -05005149 {"X25519", CurveX25519},
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005150}
5151
5152func addCurveTests() {
5153 for _, curve := range testCurves {
5154 testCases = append(testCases, testCase{
5155 name: "CurveTest-Client-" + curve.name,
5156 config: Config{
5157 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5158 CurvePreferences: []CurveID{curve.id},
5159 },
5160 flags: []string{"-enable-all-curves"},
5161 })
5162 testCases = append(testCases, testCase{
5163 testType: serverTest,
5164 name: "CurveTest-Server-" + curve.name,
5165 config: Config{
5166 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5167 CurvePreferences: []CurveID{curve.id},
5168 },
5169 flags: []string{"-enable-all-curves"},
5170 })
5171 }
David Benjamin241ae832016-01-15 03:04:54 -05005172
5173 // The server must be tolerant to bogus curves.
5174 const bogusCurve = 0x1234
5175 testCases = append(testCases, testCase{
5176 testType: serverTest,
5177 name: "UnknownCurve",
5178 config: Config{
5179 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5180 CurvePreferences: []CurveID{bogusCurve, CurveP256},
5181 },
5182 })
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005183}
5184
Matt Braithwaite54217e42016-06-13 13:03:47 -07005185func addCECPQ1Tests() {
5186 testCases = append(testCases, testCase{
5187 testType: clientTest,
5188 name: "CECPQ1-Client-BadX25519Part",
5189 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005190 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005191 MinVersion: VersionTLS12,
5192 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5193 Bugs: ProtocolBugs{
5194 CECPQ1BadX25519Part: true,
5195 },
5196 },
5197 flags: []string{"-cipher", "kCECPQ1"},
5198 shouldFail: true,
5199 expectedLocalError: "local error: bad record MAC",
5200 })
5201 testCases = append(testCases, testCase{
5202 testType: clientTest,
5203 name: "CECPQ1-Client-BadNewhopePart",
5204 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005205 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005206 MinVersion: VersionTLS12,
5207 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5208 Bugs: ProtocolBugs{
5209 CECPQ1BadNewhopePart: true,
5210 },
5211 },
5212 flags: []string{"-cipher", "kCECPQ1"},
5213 shouldFail: true,
5214 expectedLocalError: "local error: bad record MAC",
5215 })
5216 testCases = append(testCases, testCase{
5217 testType: serverTest,
5218 name: "CECPQ1-Server-BadX25519Part",
5219 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005220 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005221 MinVersion: VersionTLS12,
5222 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5223 Bugs: ProtocolBugs{
5224 CECPQ1BadX25519Part: true,
5225 },
5226 },
5227 flags: []string{"-cipher", "kCECPQ1"},
5228 shouldFail: true,
5229 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5230 })
5231 testCases = append(testCases, testCase{
5232 testType: serverTest,
5233 name: "CECPQ1-Server-BadNewhopePart",
5234 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005235 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005236 MinVersion: VersionTLS12,
5237 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5238 Bugs: ProtocolBugs{
5239 CECPQ1BadNewhopePart: true,
5240 },
5241 },
5242 flags: []string{"-cipher", "kCECPQ1"},
5243 shouldFail: true,
5244 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5245 })
5246}
5247
David Benjamin4cc36ad2015-12-19 14:23:26 -05005248func addKeyExchangeInfoTests() {
5249 testCases = append(testCases, testCase{
David Benjamin4cc36ad2015-12-19 14:23:26 -05005250 name: "KeyExchangeInfo-DHE-Client",
5251 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005252 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05005253 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
5254 Bugs: ProtocolBugs{
5255 // This is a 1234-bit prime number, generated
5256 // with:
5257 // openssl gendh 1234 | openssl asn1parse -i
5258 DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"),
5259 },
5260 },
David Benjamin9e68f192016-06-30 14:55:33 -04005261 flags: []string{"-expect-dhe-group-size", "1234"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05005262 })
5263 testCases = append(testCases, testCase{
5264 testType: serverTest,
5265 name: "KeyExchangeInfo-DHE-Server",
5266 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005267 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05005268 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
5269 },
5270 // bssl_shim as a server configures a 2048-bit DHE group.
David Benjamin9e68f192016-06-30 14:55:33 -04005271 flags: []string{"-expect-dhe-group-size", "2048"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05005272 })
5273
Nick Harper1fd39d82016-06-14 18:14:35 -07005274 // TODO(davidben): Add TLS 1.3 versions of these tests once the
5275 // handshake is separate.
5276
David Benjamin4cc36ad2015-12-19 14:23:26 -05005277 testCases = append(testCases, testCase{
5278 name: "KeyExchangeInfo-ECDHE-Client",
5279 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005280 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05005281 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5282 CurvePreferences: []CurveID{CurveX25519},
5283 },
David Benjamin9e68f192016-06-30 14:55:33 -04005284 flags: []string{"-expect-curve-id", "29", "-enable-all-curves"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05005285 })
5286 testCases = append(testCases, testCase{
5287 testType: serverTest,
5288 name: "KeyExchangeInfo-ECDHE-Server",
5289 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005290 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05005291 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5292 CurvePreferences: []CurveID{CurveX25519},
5293 },
David Benjamin9e68f192016-06-30 14:55:33 -04005294 flags: []string{"-expect-curve-id", "29", "-enable-all-curves"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05005295 })
5296}
5297
David Benjaminc9ae27c2016-06-24 22:56:37 -04005298func addTLS13RecordTests() {
5299 testCases = append(testCases, testCase{
5300 name: "TLS13-RecordPadding",
5301 config: Config{
5302 MaxVersion: VersionTLS13,
5303 MinVersion: VersionTLS13,
5304 Bugs: ProtocolBugs{
5305 RecordPadding: 10,
5306 },
5307 },
5308 })
5309
5310 testCases = append(testCases, testCase{
5311 name: "TLS13-EmptyRecords",
5312 config: Config{
5313 MaxVersion: VersionTLS13,
5314 MinVersion: VersionTLS13,
5315 Bugs: ProtocolBugs{
5316 OmitRecordContents: true,
5317 },
5318 },
5319 shouldFail: true,
5320 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5321 })
5322
5323 testCases = append(testCases, testCase{
5324 name: "TLS13-OnlyPadding",
5325 config: Config{
5326 MaxVersion: VersionTLS13,
5327 MinVersion: VersionTLS13,
5328 Bugs: ProtocolBugs{
5329 OmitRecordContents: true,
5330 RecordPadding: 10,
5331 },
5332 },
5333 shouldFail: true,
5334 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5335 })
5336
5337 testCases = append(testCases, testCase{
5338 name: "TLS13-WrongOuterRecord",
5339 config: Config{
5340 MaxVersion: VersionTLS13,
5341 MinVersion: VersionTLS13,
5342 Bugs: ProtocolBugs{
5343 OuterRecordType: recordTypeHandshake,
5344 },
5345 },
5346 shouldFail: true,
5347 expectedError: ":INVALID_OUTER_RECORD_TYPE:",
5348 })
5349}
5350
Adam Langley7c803a62015-06-15 15:35:05 -07005351func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
Adam Langley95c29f32014-06-20 12:00:00 -07005352 defer wg.Done()
5353
5354 for test := range c {
Adam Langley69a01602014-11-17 17:26:55 -08005355 var err error
5356
5357 if *mallocTest < 0 {
5358 statusChan <- statusMsg{test: test, started: true}
Adam Langley7c803a62015-06-15 15:35:05 -07005359 err = runTest(test, shimPath, -1)
Adam Langley69a01602014-11-17 17:26:55 -08005360 } else {
5361 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
5362 statusChan <- statusMsg{test: test, started: true}
Adam Langley7c803a62015-06-15 15:35:05 -07005363 if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
Adam Langley69a01602014-11-17 17:26:55 -08005364 if err != nil {
5365 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
5366 }
5367 break
5368 }
5369 }
5370 }
Adam Langley95c29f32014-06-20 12:00:00 -07005371 statusChan <- statusMsg{test: test, err: err}
5372 }
5373}
5374
5375type statusMsg struct {
5376 test *testCase
5377 started bool
5378 err error
5379}
5380
David Benjamin5f237bc2015-02-11 17:14:15 -05005381func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total int) {
Adam Langley95c29f32014-06-20 12:00:00 -07005382 var started, done, failed, lineLen int
Adam Langley95c29f32014-06-20 12:00:00 -07005383
David Benjamin5f237bc2015-02-11 17:14:15 -05005384 testOutput := newTestOutput()
Adam Langley95c29f32014-06-20 12:00:00 -07005385 for msg := range statusChan {
David Benjamin5f237bc2015-02-11 17:14:15 -05005386 if !*pipe {
5387 // Erase the previous status line.
David Benjamin87c8a642015-02-21 01:54:29 -05005388 var erase string
5389 for i := 0; i < lineLen; i++ {
5390 erase += "\b \b"
5391 }
5392 fmt.Print(erase)
David Benjamin5f237bc2015-02-11 17:14:15 -05005393 }
5394
Adam Langley95c29f32014-06-20 12:00:00 -07005395 if msg.started {
5396 started++
5397 } else {
5398 done++
David Benjamin5f237bc2015-02-11 17:14:15 -05005399
5400 if msg.err != nil {
5401 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
5402 failed++
5403 testOutput.addResult(msg.test.name, "FAIL")
5404 } else {
5405 if *pipe {
5406 // Print each test instead of a status line.
5407 fmt.Printf("PASSED (%s)\n", msg.test.name)
5408 }
5409 testOutput.addResult(msg.test.name, "PASS")
5410 }
Adam Langley95c29f32014-06-20 12:00:00 -07005411 }
5412
David Benjamin5f237bc2015-02-11 17:14:15 -05005413 if !*pipe {
5414 // Print a new status line.
5415 line := fmt.Sprintf("%d/%d/%d/%d", failed, done, started, total)
5416 lineLen = len(line)
5417 os.Stdout.WriteString(line)
Adam Langley95c29f32014-06-20 12:00:00 -07005418 }
Adam Langley95c29f32014-06-20 12:00:00 -07005419 }
David Benjamin5f237bc2015-02-11 17:14:15 -05005420
5421 doneChan <- testOutput
Adam Langley95c29f32014-06-20 12:00:00 -07005422}
5423
5424func main() {
Adam Langley95c29f32014-06-20 12:00:00 -07005425 flag.Parse()
Adam Langley7c803a62015-06-15 15:35:05 -07005426 *resourceDir = path.Clean(*resourceDir)
Adam Langley95c29f32014-06-20 12:00:00 -07005427
Adam Langley7c803a62015-06-15 15:35:05 -07005428 addBasicTests()
Adam Langley95c29f32014-06-20 12:00:00 -07005429 addCipherSuiteTests()
5430 addBadECDSASignatureTests()
Adam Langley80842bd2014-06-20 12:00:00 -07005431 addCBCPaddingTests()
Kenny Root7fdeaf12014-08-05 15:23:37 -07005432 addCBCSplittingTests()
David Benjamin636293b2014-07-08 17:59:18 -04005433 addClientAuthTests()
Adam Langley524e7172015-02-20 16:04:00 -08005434 addDDoSCallbackTests()
David Benjamin7e2e6cf2014-08-07 17:44:24 -04005435 addVersionNegotiationTests()
David Benjaminaccb4542014-12-12 23:44:33 -05005436 addMinimumVersionTests()
David Benjamine78bfde2014-09-06 12:45:15 -04005437 addExtensionTests()
David Benjamin01fe8202014-09-24 15:21:44 -04005438 addResumptionVersionTests()
Adam Langley75712922014-10-10 16:23:43 -07005439 addExtendedMasterSecretTests()
Adam Langley2ae77d22014-10-28 17:29:33 -07005440 addRenegotiationTests()
David Benjamin5e961c12014-11-07 01:48:35 -05005441 addDTLSReplayTests()
David Benjamin000800a2014-11-14 01:43:59 -05005442 addSigningHashTests()
David Benjamin83f90402015-01-27 01:09:43 -05005443 addDTLSRetransmitTests()
David Benjaminc565ebb2015-04-03 04:06:36 -04005444 addExportKeyingMaterialTests()
Adam Langleyaf0e32c2015-06-03 09:57:23 -07005445 addTLSUniqueTests()
Adam Langley09505632015-07-30 18:10:13 -07005446 addCustomExtensionTests()
David Benjaminb36a3952015-12-01 18:53:13 -05005447 addRSAClientKeyExchangeTests()
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005448 addCurveTests()
Matt Braithwaite54217e42016-06-13 13:03:47 -07005449 addCECPQ1Tests()
David Benjamin4cc36ad2015-12-19 14:23:26 -05005450 addKeyExchangeInfoTests()
David Benjaminc9ae27c2016-06-24 22:56:37 -04005451 addTLS13RecordTests()
David Benjamin43ec06f2014-08-05 02:28:57 -04005452 for _, async := range []bool{false, true} {
5453 for _, splitHandshake := range []bool{false, true} {
David Benjamin6fd297b2014-08-11 18:43:38 -04005454 for _, protocol := range []protocol{tls, dtls} {
5455 addStateMachineCoverageTests(async, splitHandshake, protocol)
5456 }
David Benjamin43ec06f2014-08-05 02:28:57 -04005457 }
5458 }
Adam Langley95c29f32014-06-20 12:00:00 -07005459
5460 var wg sync.WaitGroup
5461
Adam Langley7c803a62015-06-15 15:35:05 -07005462 statusChan := make(chan statusMsg, *numWorkers)
5463 testChan := make(chan *testCase, *numWorkers)
David Benjamin5f237bc2015-02-11 17:14:15 -05005464 doneChan := make(chan *testOutput)
Adam Langley95c29f32014-06-20 12:00:00 -07005465
David Benjamin025b3d32014-07-01 19:53:04 -04005466 go statusPrinter(doneChan, statusChan, len(testCases))
Adam Langley95c29f32014-06-20 12:00:00 -07005467
Adam Langley7c803a62015-06-15 15:35:05 -07005468 for i := 0; i < *numWorkers; i++ {
Adam Langley95c29f32014-06-20 12:00:00 -07005469 wg.Add(1)
Adam Langley7c803a62015-06-15 15:35:05 -07005470 go worker(statusChan, testChan, *shimPath, &wg)
Adam Langley95c29f32014-06-20 12:00:00 -07005471 }
5472
David Benjamin270f0a72016-03-17 14:41:36 -04005473 var foundTest bool
David Benjamin025b3d32014-07-01 19:53:04 -04005474 for i := range testCases {
Adam Langley7c803a62015-06-15 15:35:05 -07005475 if len(*testToRun) == 0 || *testToRun == testCases[i].name {
David Benjamin270f0a72016-03-17 14:41:36 -04005476 foundTest = true
David Benjamin025b3d32014-07-01 19:53:04 -04005477 testChan <- &testCases[i]
Adam Langley95c29f32014-06-20 12:00:00 -07005478 }
5479 }
David Benjamin270f0a72016-03-17 14:41:36 -04005480 if !foundTest {
5481 fmt.Fprintf(os.Stderr, "No test named '%s'\n", *testToRun)
5482 os.Exit(1)
5483 }
Adam Langley95c29f32014-06-20 12:00:00 -07005484
5485 close(testChan)
5486 wg.Wait()
5487 close(statusChan)
David Benjamin5f237bc2015-02-11 17:14:15 -05005488 testOutput := <-doneChan
Adam Langley95c29f32014-06-20 12:00:00 -07005489
5490 fmt.Printf("\n")
David Benjamin5f237bc2015-02-11 17:14:15 -05005491
5492 if *jsonOutput != "" {
5493 if err := testOutput.writeTo(*jsonOutput); err != nil {
5494 fmt.Fprintf(os.Stderr, "Error: %s\n", err)
5495 }
5496 }
David Benjamin2ab7a862015-04-04 17:02:18 -04005497
5498 if !testOutput.allPassed {
5499 os.Exit(1)
5500 }
Adam Langley95c29f32014-06-20 12:00:00 -07005501}