blob: a0edf77b126b59248bd1a018c23735b4a82571a6 [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 Benjamin33863262016-07-08 17:20:12 -070060type testCert int
61
David Benjamin025b3d32014-07-01 19:53:04 -040062const (
David Benjamin33863262016-07-08 17:20:12 -070063 testCertRSA testCert = iota
David Benjamin7944a9f2016-07-12 22:27:01 -040064 testCertRSA1024
David Benjamin33863262016-07-08 17:20:12 -070065 testCertECDSAP256
66 testCertECDSAP384
67 testCertECDSAP521
68)
69
70const (
71 rsaCertificateFile = "cert.pem"
David Benjamin7944a9f2016-07-12 22:27:01 -040072 rsa1024CertificateFile = "rsa_1024_cert.pem"
David Benjamin33863262016-07-08 17:20:12 -070073 ecdsaP256CertificateFile = "ecdsa_p256_cert.pem"
74 ecdsaP384CertificateFile = "ecdsa_p384_cert.pem"
75 ecdsaP521CertificateFile = "ecdsa_p521_cert.pem"
David Benjamin025b3d32014-07-01 19:53:04 -040076)
77
78const (
David Benjamina08e49d2014-08-24 01:46:07 -040079 rsaKeyFile = "key.pem"
David Benjamin7944a9f2016-07-12 22:27:01 -040080 rsa1024KeyFile = "rsa_1024_key.pem"
David Benjamin33863262016-07-08 17:20:12 -070081 ecdsaP256KeyFile = "ecdsa_p256_key.pem"
82 ecdsaP384KeyFile = "ecdsa_p384_key.pem"
83 ecdsaP521KeyFile = "ecdsa_p521_key.pem"
David Benjamina08e49d2014-08-24 01:46:07 -040084 channelIDKeyFile = "channel_id_key.pem"
David Benjamin025b3d32014-07-01 19:53:04 -040085)
86
David Benjamin7944a9f2016-07-12 22:27:01 -040087var (
88 rsaCertificate Certificate
89 rsa1024Certificate Certificate
90 ecdsaP256Certificate Certificate
91 ecdsaP384Certificate Certificate
92 ecdsaP521Certificate Certificate
93)
David Benjamin33863262016-07-08 17:20:12 -070094
95var testCerts = []struct {
96 id testCert
97 certFile, keyFile string
98 cert *Certificate
99}{
100 {
101 id: testCertRSA,
102 certFile: rsaCertificateFile,
103 keyFile: rsaKeyFile,
104 cert: &rsaCertificate,
105 },
106 {
David Benjamin7944a9f2016-07-12 22:27:01 -0400107 id: testCertRSA1024,
108 certFile: rsa1024CertificateFile,
109 keyFile: rsa1024KeyFile,
110 cert: &rsa1024Certificate,
111 },
112 {
David Benjamin33863262016-07-08 17:20:12 -0700113 id: testCertECDSAP256,
114 certFile: ecdsaP256CertificateFile,
115 keyFile: ecdsaP256KeyFile,
116 cert: &ecdsaP256Certificate,
117 },
118 {
119 id: testCertECDSAP384,
120 certFile: ecdsaP384CertificateFile,
121 keyFile: ecdsaP384KeyFile,
122 cert: &ecdsaP384Certificate,
123 },
124 {
125 id: testCertECDSAP521,
126 certFile: ecdsaP521CertificateFile,
127 keyFile: ecdsaP521KeyFile,
128 cert: &ecdsaP521Certificate,
129 },
130}
131
David Benjamina08e49d2014-08-24 01:46:07 -0400132var channelIDKey *ecdsa.PrivateKey
133var channelIDBytes []byte
Adam Langley95c29f32014-06-20 12:00:00 -0700134
David Benjamin61f95272014-11-25 01:55:35 -0500135var testOCSPResponse = []byte{1, 2, 3, 4}
136var testSCTList = []byte{5, 6, 7, 8}
137
Adam Langley95c29f32014-06-20 12:00:00 -0700138func initCertificates() {
David Benjamin33863262016-07-08 17:20:12 -0700139 for i := range testCerts {
140 cert, err := LoadX509KeyPair(path.Join(*resourceDir, testCerts[i].certFile), path.Join(*resourceDir, testCerts[i].keyFile))
141 if err != nil {
142 panic(err)
143 }
144 cert.OCSPStaple = testOCSPResponse
145 cert.SignedCertificateTimestampList = testSCTList
146 *testCerts[i].cert = cert
Adam Langley95c29f32014-06-20 12:00:00 -0700147 }
David Benjamina08e49d2014-08-24 01:46:07 -0400148
Adam Langley7c803a62015-06-15 15:35:05 -0700149 channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
David Benjamina08e49d2014-08-24 01:46:07 -0400150 if err != nil {
151 panic(err)
152 }
153 channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock)
154 if channelIDDERBlock.Type != "EC PRIVATE KEY" {
155 panic("bad key type")
156 }
157 channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes)
158 if err != nil {
159 panic(err)
160 }
161 if channelIDKey.Curve != elliptic.P256() {
162 panic("bad curve")
163 }
164
165 channelIDBytes = make([]byte, 64)
166 writeIntPadded(channelIDBytes[:32], channelIDKey.X)
167 writeIntPadded(channelIDBytes[32:], channelIDKey.Y)
Adam Langley95c29f32014-06-20 12:00:00 -0700168}
169
David Benjamin33863262016-07-08 17:20:12 -0700170func getRunnerCertificate(t testCert) Certificate {
171 for _, cert := range testCerts {
172 if cert.id == t {
173 return *cert.cert
174 }
175 }
176 panic("Unknown test certificate")
Adam Langley95c29f32014-06-20 12:00:00 -0700177}
178
David Benjamin33863262016-07-08 17:20:12 -0700179func getShimCertificate(t testCert) string {
180 for _, cert := range testCerts {
181 if cert.id == t {
182 return cert.certFile
183 }
184 }
185 panic("Unknown test certificate")
186}
187
188func getShimKey(t testCert) string {
189 for _, cert := range testCerts {
190 if cert.id == t {
191 return cert.keyFile
192 }
193 }
194 panic("Unknown test certificate")
Adam Langley95c29f32014-06-20 12:00:00 -0700195}
196
David Benjamin025b3d32014-07-01 19:53:04 -0400197type testType int
198
199const (
200 clientTest testType = iota
201 serverTest
202)
203
David Benjamin6fd297b2014-08-11 18:43:38 -0400204type protocol int
205
206const (
207 tls protocol = iota
208 dtls
209)
210
David Benjaminfc7b0862014-09-06 13:21:53 -0400211const (
212 alpn = 1
213 npn = 2
214)
215
Adam Langley95c29f32014-06-20 12:00:00 -0700216type testCase struct {
David Benjamin025b3d32014-07-01 19:53:04 -0400217 testType testType
David Benjamin6fd297b2014-08-11 18:43:38 -0400218 protocol protocol
Adam Langley95c29f32014-06-20 12:00:00 -0700219 name string
220 config Config
221 shouldFail bool
222 expectedError string
Adam Langleyac61fa32014-06-23 12:03:11 -0700223 // expectedLocalError, if not empty, contains a substring that must be
224 // found in the local error.
225 expectedLocalError string
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400226 // expectedVersion, if non-zero, specifies the TLS version that must be
227 // negotiated.
228 expectedVersion uint16
David Benjamin01fe8202014-09-24 15:21:44 -0400229 // expectedResumeVersion, if non-zero, specifies the TLS version that
230 // must be negotiated on resumption. If zero, expectedVersion is used.
231 expectedResumeVersion uint16
David Benjamin90da8c82015-04-20 14:57:57 -0400232 // expectedCipher, if non-zero, specifies the TLS cipher suite that
233 // should be negotiated.
234 expectedCipher uint16
David Benjamina08e49d2014-08-24 01:46:07 -0400235 // expectChannelID controls whether the connection should have
236 // negotiated a Channel ID with channelIDKey.
237 expectChannelID bool
David Benjaminae2888f2014-09-06 12:58:58 -0400238 // expectedNextProto controls whether the connection should
239 // negotiate a next protocol via NPN or ALPN.
240 expectedNextProto string
David Benjaminc7ce9772015-10-09 19:32:41 -0400241 // expectNoNextProto, if true, means that no next protocol should be
242 // negotiated.
243 expectNoNextProto bool
David Benjaminfc7b0862014-09-06 13:21:53 -0400244 // expectedNextProtoType, if non-zero, is the expected next
245 // protocol negotiation mechanism.
246 expectedNextProtoType int
David Benjaminca6c8262014-11-15 19:06:08 -0500247 // expectedSRTPProtectionProfile is the DTLS-SRTP profile that
248 // should be negotiated. If zero, none should be negotiated.
249 expectedSRTPProtectionProfile uint16
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100250 // expectedOCSPResponse, if not nil, is the expected OCSP response to be received.
251 expectedOCSPResponse []uint8
Paul Lietar4fac72e2015-09-09 13:44:55 +0100252 // expectedSCTList, if not nil, is the expected SCT list to be received.
253 expectedSCTList []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700254 // expectedPeerSignatureAlgorithm, if not zero, is the signature
255 // algorithm that the peer should have used in the handshake.
256 expectedPeerSignatureAlgorithm signatureAlgorithm
Adam Langley80842bd2014-06-20 12:00:00 -0700257 // messageLen is the length, in bytes, of the test message that will be
258 // sent.
259 messageLen int
David Benjamin8e6db492015-07-25 18:29:23 -0400260 // messageCount is the number of test messages that will be sent.
261 messageCount int
David Benjamin025b3d32014-07-01 19:53:04 -0400262 // certFile is the path to the certificate to use for the server.
263 certFile string
264 // keyFile is the path to the private key to use for the server.
265 keyFile string
David Benjamin1d5c83e2014-07-22 19:20:02 -0400266 // resumeSession controls whether a second connection should be tested
David Benjamin01fe8202014-09-24 15:21:44 -0400267 // which attempts to resume the first session.
David Benjamin1d5c83e2014-07-22 19:20:02 -0400268 resumeSession bool
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700269 // expectResumeRejected, if true, specifies that the attempted
270 // resumption must be rejected by the client. This is only valid for a
271 // serverTest.
272 expectResumeRejected bool
David Benjamin01fe8202014-09-24 15:21:44 -0400273 // resumeConfig, if not nil, points to a Config to be used on
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500274 // resumption. Unless newSessionsOnResume is set,
275 // SessionTicketKey, ServerSessionCache, and
276 // ClientSessionCache are copied from the initial connection's
277 // config. If nil, the initial connection's config is used.
David Benjamin01fe8202014-09-24 15:21:44 -0400278 resumeConfig *Config
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500279 // newSessionsOnResume, if true, will cause resumeConfig to
280 // use a different session resumption context.
281 newSessionsOnResume bool
David Benjaminba4594a2015-06-18 18:36:15 -0400282 // noSessionCache, if true, will cause the server to run without a
283 // session cache.
284 noSessionCache bool
David Benjamin98e882e2014-08-08 13:24:34 -0400285 // sendPrefix sends a prefix on the socket before actually performing a
286 // handshake.
287 sendPrefix string
David Benjamine58c4f52014-08-24 03:47:07 -0400288 // shimWritesFirst controls whether the shim sends an initial "hello"
289 // message before doing a roundtrip with the runner.
290 shimWritesFirst bool
David Benjamin30789da2015-08-29 22:56:45 -0400291 // shimShutsDown, if true, runs a test where the shim shuts down the
292 // connection immediately after the handshake rather than echoing
293 // messages from the runner.
294 shimShutsDown bool
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400295 // renegotiate indicates the number of times the connection should be
296 // renegotiated during the exchange.
297 renegotiate int
Adam Langleycf2d4f42014-10-28 19:06:14 -0700298 // renegotiateCiphers is a list of ciphersuite ids that will be
299 // switched in just before renegotiation.
300 renegotiateCiphers []uint16
David Benjamin5e961c12014-11-07 01:48:35 -0500301 // replayWrites, if true, configures the underlying transport
302 // to replay every write it makes in DTLS tests.
303 replayWrites bool
David Benjamin5fa3eba2015-01-22 16:35:40 -0500304 // damageFirstWrite, if true, configures the underlying transport to
305 // damage the final byte of the first application data write.
306 damageFirstWrite bool
David Benjaminc565ebb2015-04-03 04:06:36 -0400307 // exportKeyingMaterial, if non-zero, configures the test to exchange
308 // keying material and verify they match.
309 exportKeyingMaterial int
310 exportLabel string
311 exportContext string
312 useExportContext bool
David Benjamin325b5c32014-07-01 19:40:31 -0400313 // flags, if not empty, contains a list of command-line flags that will
314 // be passed to the shim program.
315 flags []string
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700316 // testTLSUnique, if true, causes the shim to send the tls-unique value
317 // which will be compared against the expected value.
318 testTLSUnique bool
David Benjamina8ebe222015-06-06 03:04:39 -0400319 // sendEmptyRecords is the number of consecutive empty records to send
320 // before and after the test message.
321 sendEmptyRecords int
David Benjamin24f346d2015-06-06 03:28:08 -0400322 // sendWarningAlerts is the number of consecutive warning alerts to send
323 // before and after the test message.
324 sendWarningAlerts int
David Benjamin4f75aaf2015-09-01 16:53:10 -0400325 // expectMessageDropped, if true, means the test message is expected to
326 // be dropped by the client rather than echoed back.
327 expectMessageDropped bool
Adam Langley95c29f32014-06-20 12:00:00 -0700328}
329
Adam Langley7c803a62015-06-15 15:35:05 -0700330var testCases []testCase
Adam Langley95c29f32014-06-20 12:00:00 -0700331
David Benjamin9867b7d2016-03-01 23:25:48 -0500332func writeTranscript(test *testCase, isResume bool, data []byte) {
333 if len(data) == 0 {
334 return
335 }
336
337 protocol := "tls"
338 if test.protocol == dtls {
339 protocol = "dtls"
340 }
341
342 side := "client"
343 if test.testType == serverTest {
344 side = "server"
345 }
346
347 dir := path.Join(*transcriptDir, protocol, side)
348 if err := os.MkdirAll(dir, 0755); err != nil {
349 fmt.Fprintf(os.Stderr, "Error making %s: %s\n", dir, err)
350 return
351 }
352
353 name := test.name
354 if isResume {
355 name += "-Resume"
356 } else {
357 name += "-Normal"
358 }
359
360 if err := ioutil.WriteFile(path.Join(dir, name), data, 0644); err != nil {
361 fmt.Fprintf(os.Stderr, "Error writing %s: %s\n", name, err)
362 }
363}
364
David Benjamin3ed59772016-03-08 12:50:21 -0500365// A timeoutConn implements an idle timeout on each Read and Write operation.
366type timeoutConn struct {
367 net.Conn
368 timeout time.Duration
369}
370
371func (t *timeoutConn) Read(b []byte) (int, error) {
372 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil {
373 return 0, err
374 }
375 return t.Conn.Read(b)
376}
377
378func (t *timeoutConn) Write(b []byte) (int, error) {
379 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil {
380 return 0, err
381 }
382 return t.Conn.Write(b)
383}
384
David Benjamin8e6db492015-07-25 18:29:23 -0400385func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
David Benjamin01784b42016-06-07 18:00:52 -0400386 conn = &timeoutConn{conn, *idleTimeout}
David Benjamin65ea8ff2014-11-23 03:01:00 -0500387
David Benjamin6fd297b2014-08-11 18:43:38 -0400388 if test.protocol == dtls {
David Benjamin83f90402015-01-27 01:09:43 -0500389 config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
390 conn = config.Bugs.PacketAdaptor
David Benjaminebda9b32015-11-02 15:33:18 -0500391 }
392
David Benjamin9867b7d2016-03-01 23:25:48 -0500393 if *flagDebug || len(*transcriptDir) != 0 {
David Benjaminebda9b32015-11-02 15:33:18 -0500394 local, peer := "client", "server"
395 if test.testType == clientTest {
396 local, peer = peer, local
David Benjamin5e961c12014-11-07 01:48:35 -0500397 }
David Benjaminebda9b32015-11-02 15:33:18 -0500398 connDebug := &recordingConn{
399 Conn: conn,
400 isDatagram: test.protocol == dtls,
401 local: local,
402 peer: peer,
403 }
404 conn = connDebug
David Benjamin9867b7d2016-03-01 23:25:48 -0500405 if *flagDebug {
406 defer connDebug.WriteTo(os.Stdout)
407 }
408 if len(*transcriptDir) != 0 {
409 defer func() {
410 writeTranscript(test, isResume, connDebug.Transcript())
411 }()
412 }
David Benjaminebda9b32015-11-02 15:33:18 -0500413
414 if config.Bugs.PacketAdaptor != nil {
415 config.Bugs.PacketAdaptor.debug = connDebug
416 }
417 }
418
419 if test.replayWrites {
420 conn = newReplayAdaptor(conn)
David Benjamin6fd297b2014-08-11 18:43:38 -0400421 }
422
David Benjamin3ed59772016-03-08 12:50:21 -0500423 var connDamage *damageAdaptor
David Benjamin5fa3eba2015-01-22 16:35:40 -0500424 if test.damageFirstWrite {
425 connDamage = newDamageAdaptor(conn)
426 conn = connDamage
427 }
428
David Benjamin6fd297b2014-08-11 18:43:38 -0400429 if test.sendPrefix != "" {
430 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil {
431 return err
432 }
David Benjamin98e882e2014-08-08 13:24:34 -0400433 }
434
David Benjamin1d5c83e2014-07-22 19:20:02 -0400435 var tlsConn *Conn
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400436 if test.testType == clientTest {
David Benjamin6fd297b2014-08-11 18:43:38 -0400437 if test.protocol == dtls {
438 tlsConn = DTLSServer(conn, config)
439 } else {
440 tlsConn = Server(conn, config)
441 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400442 } else {
443 config.InsecureSkipVerify = true
David Benjamin6fd297b2014-08-11 18:43:38 -0400444 if test.protocol == dtls {
445 tlsConn = DTLSClient(conn, config)
446 } else {
447 tlsConn = Client(conn, config)
448 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400449 }
David Benjamin30789da2015-08-29 22:56:45 -0400450 defer tlsConn.Close()
David Benjamin1d5c83e2014-07-22 19:20:02 -0400451
Adam Langley95c29f32014-06-20 12:00:00 -0700452 if err := tlsConn.Handshake(); err != nil {
453 return err
454 }
Kenny Root7fdeaf12014-08-05 15:23:37 -0700455
David Benjamin01fe8202014-09-24 15:21:44 -0400456 // TODO(davidben): move all per-connection expectations into a dedicated
457 // expectations struct that can be specified separately for the two
458 // legs.
459 expectedVersion := test.expectedVersion
460 if isResume && test.expectedResumeVersion != 0 {
461 expectedVersion = test.expectedResumeVersion
462 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700463 connState := tlsConn.ConnectionState()
464 if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion {
David Benjamin01fe8202014-09-24 15:21:44 -0400465 return fmt.Errorf("got version %x, expected %x", vers, expectedVersion)
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400466 }
467
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700468 if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
David Benjamin90da8c82015-04-20 14:57:57 -0400469 return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher)
470 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700471 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
472 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
473 }
David Benjamin90da8c82015-04-20 14:57:57 -0400474
David Benjamina08e49d2014-08-24 01:46:07 -0400475 if test.expectChannelID {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700476 channelID := connState.ChannelID
David Benjamina08e49d2014-08-24 01:46:07 -0400477 if channelID == nil {
478 return fmt.Errorf("no channel ID negotiated")
479 }
480 if channelID.Curve != channelIDKey.Curve ||
481 channelIDKey.X.Cmp(channelIDKey.X) != 0 ||
482 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 {
483 return fmt.Errorf("incorrect channel ID")
484 }
485 }
486
David Benjaminae2888f2014-09-06 12:58:58 -0400487 if expected := test.expectedNextProto; expected != "" {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700488 if actual := connState.NegotiatedProtocol; actual != expected {
David Benjaminae2888f2014-09-06 12:58:58 -0400489 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
490 }
491 }
492
David Benjaminc7ce9772015-10-09 19:32:41 -0400493 if test.expectNoNextProto {
494 if actual := connState.NegotiatedProtocol; actual != "" {
495 return fmt.Errorf("got unexpected next proto %s", actual)
496 }
497 }
498
David Benjaminfc7b0862014-09-06 13:21:53 -0400499 if test.expectedNextProtoType != 0 {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700500 if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
David Benjaminfc7b0862014-09-06 13:21:53 -0400501 return fmt.Errorf("next proto type mismatch")
502 }
503 }
504
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700505 if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
David Benjaminca6c8262014-11-15 19:06:08 -0500506 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
507 }
508
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100509 if test.expectedOCSPResponse != nil && !bytes.Equal(test.expectedOCSPResponse, tlsConn.OCSPResponse()) {
510 return fmt.Errorf("OCSP Response mismatch")
511 }
512
Paul Lietar4fac72e2015-09-09 13:44:55 +0100513 if test.expectedSCTList != nil && !bytes.Equal(test.expectedSCTList, connState.SCTList) {
514 return fmt.Errorf("SCT list mismatch")
515 }
516
Nick Harper60edffd2016-06-21 15:19:24 -0700517 if expected := test.expectedPeerSignatureAlgorithm; expected != 0 && expected != connState.PeerSignatureAlgorithm {
518 return fmt.Errorf("expected peer to use signature algorithm %04x, but got %04x", expected, connState.PeerSignatureAlgorithm)
Steven Valdez0d62f262015-09-04 12:41:04 -0400519 }
520
David Benjaminc565ebb2015-04-03 04:06:36 -0400521 if test.exportKeyingMaterial > 0 {
522 actual := make([]byte, test.exportKeyingMaterial)
523 if _, err := io.ReadFull(tlsConn, actual); err != nil {
524 return err
525 }
526 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext)
527 if err != nil {
528 return err
529 }
530 if !bytes.Equal(actual, expected) {
531 return fmt.Errorf("keying material mismatch")
532 }
533 }
534
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700535 if test.testTLSUnique {
536 var peersValue [12]byte
537 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
538 return err
539 }
540 expected := tlsConn.ConnectionState().TLSUnique
541 if !bytes.Equal(peersValue[:], expected) {
542 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
543 }
544 }
545
David Benjamine58c4f52014-08-24 03:47:07 -0400546 if test.shimWritesFirst {
547 var buf [5]byte
548 _, err := io.ReadFull(tlsConn, buf[:])
549 if err != nil {
550 return err
551 }
552 if string(buf[:]) != "hello" {
553 return fmt.Errorf("bad initial message")
554 }
555 }
556
David Benjamina8ebe222015-06-06 03:04:39 -0400557 for i := 0; i < test.sendEmptyRecords; i++ {
558 tlsConn.Write(nil)
559 }
560
David Benjamin24f346d2015-06-06 03:28:08 -0400561 for i := 0; i < test.sendWarningAlerts; i++ {
562 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
563 }
564
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400565 if test.renegotiate > 0 {
Adam Langleycf2d4f42014-10-28 19:06:14 -0700566 if test.renegotiateCiphers != nil {
567 config.CipherSuites = test.renegotiateCiphers
568 }
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400569 for i := 0; i < test.renegotiate; i++ {
570 if err := tlsConn.Renegotiate(); err != nil {
571 return err
572 }
Adam Langleycf2d4f42014-10-28 19:06:14 -0700573 }
574 } else if test.renegotiateCiphers != nil {
575 panic("renegotiateCiphers without renegotiate")
576 }
577
David Benjamin5fa3eba2015-01-22 16:35:40 -0500578 if test.damageFirstWrite {
579 connDamage.setDamage(true)
580 tlsConn.Write([]byte("DAMAGED WRITE"))
581 connDamage.setDamage(false)
582 }
583
David Benjamin8e6db492015-07-25 18:29:23 -0400584 messageLen := test.messageLen
Kenny Root7fdeaf12014-08-05 15:23:37 -0700585 if messageLen < 0 {
David Benjamin6fd297b2014-08-11 18:43:38 -0400586 if test.protocol == dtls {
587 return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
588 }
Kenny Root7fdeaf12014-08-05 15:23:37 -0700589 // Read until EOF.
590 _, err := io.Copy(ioutil.Discard, tlsConn)
591 return err
592 }
David Benjamin4417d052015-04-05 04:17:25 -0400593 if messageLen == 0 {
594 messageLen = 32
Adam Langley80842bd2014-06-20 12:00:00 -0700595 }
Adam Langley95c29f32014-06-20 12:00:00 -0700596
David Benjamin8e6db492015-07-25 18:29:23 -0400597 messageCount := test.messageCount
598 if messageCount == 0 {
599 messageCount = 1
David Benjamina8ebe222015-06-06 03:04:39 -0400600 }
601
David Benjamin8e6db492015-07-25 18:29:23 -0400602 for j := 0; j < messageCount; j++ {
603 testMessage := make([]byte, messageLen)
604 for i := range testMessage {
605 testMessage[i] = 0x42 ^ byte(j)
David Benjamin6fd297b2014-08-11 18:43:38 -0400606 }
David Benjamin8e6db492015-07-25 18:29:23 -0400607 tlsConn.Write(testMessage)
Adam Langley95c29f32014-06-20 12:00:00 -0700608
David Benjamin8e6db492015-07-25 18:29:23 -0400609 for i := 0; i < test.sendEmptyRecords; i++ {
610 tlsConn.Write(nil)
611 }
612
613 for i := 0; i < test.sendWarningAlerts; i++ {
614 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
615 }
616
David Benjamin4f75aaf2015-09-01 16:53:10 -0400617 if test.shimShutsDown || test.expectMessageDropped {
David Benjamin30789da2015-08-29 22:56:45 -0400618 // The shim will not respond.
619 continue
620 }
621
David Benjamin8e6db492015-07-25 18:29:23 -0400622 buf := make([]byte, len(testMessage))
623 if test.protocol == dtls {
624 bufTmp := make([]byte, len(buf)+1)
625 n, err := tlsConn.Read(bufTmp)
626 if err != nil {
627 return err
628 }
629 if n != len(buf) {
630 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
631 }
632 copy(buf, bufTmp)
633 } else {
634 _, err := io.ReadFull(tlsConn, buf)
635 if err != nil {
636 return err
637 }
638 }
639
640 for i, v := range buf {
641 if v != testMessage[i]^0xff {
642 return fmt.Errorf("bad reply contents at byte %d", i)
643 }
Adam Langley95c29f32014-06-20 12:00:00 -0700644 }
645 }
646
647 return nil
648}
649
David Benjamin325b5c32014-07-01 19:40:31 -0400650func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
651 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full"}
Adam Langley95c29f32014-06-20 12:00:00 -0700652 if dbAttach {
David Benjamin325b5c32014-07-01 19:40:31 -0400653 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p")
Adam Langley95c29f32014-06-20 12:00:00 -0700654 }
David Benjamin325b5c32014-07-01 19:40:31 -0400655 valgrindArgs = append(valgrindArgs, path)
656 valgrindArgs = append(valgrindArgs, args...)
Adam Langley95c29f32014-06-20 12:00:00 -0700657
David Benjamin325b5c32014-07-01 19:40:31 -0400658 return exec.Command("valgrind", valgrindArgs...)
Adam Langley95c29f32014-06-20 12:00:00 -0700659}
660
David Benjamin325b5c32014-07-01 19:40:31 -0400661func gdbOf(path string, args ...string) *exec.Cmd {
662 xtermArgs := []string{"-e", "gdb", "--args"}
663 xtermArgs = append(xtermArgs, path)
664 xtermArgs = append(xtermArgs, args...)
Adam Langley95c29f32014-06-20 12:00:00 -0700665
David Benjamin325b5c32014-07-01 19:40:31 -0400666 return exec.Command("xterm", xtermArgs...)
Adam Langley95c29f32014-06-20 12:00:00 -0700667}
668
David Benjamind16bf342015-12-18 00:53:12 -0500669func lldbOf(path string, args ...string) *exec.Cmd {
670 xtermArgs := []string{"-e", "lldb", "--"}
671 xtermArgs = append(xtermArgs, path)
672 xtermArgs = append(xtermArgs, args...)
673
674 return exec.Command("xterm", xtermArgs...)
675}
676
Adam Langley69a01602014-11-17 17:26:55 -0800677type moreMallocsError struct{}
678
679func (moreMallocsError) Error() string {
680 return "child process did not exhaust all allocation calls"
681}
682
683var errMoreMallocs = moreMallocsError{}
684
David Benjamin87c8a642015-02-21 01:54:29 -0500685// accept accepts a connection from listener, unless waitChan signals a process
686// exit first.
687func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error) {
688 type connOrError struct {
689 conn net.Conn
690 err error
691 }
692 connChan := make(chan connOrError, 1)
693 go func() {
694 conn, err := listener.Accept()
695 connChan <- connOrError{conn, err}
696 close(connChan)
697 }()
698 select {
699 case result := <-connChan:
700 return result.conn, result.err
701 case childErr := <-waitChan:
702 waitChan <- childErr
703 return nil, fmt.Errorf("child exited early: %s", childErr)
704 }
705}
706
Adam Langley7c803a62015-06-15 15:35:05 -0700707func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
Adam Langley38311732014-10-16 19:04:35 -0700708 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
709 panic("Error expected without shouldFail in " + test.name)
710 }
711
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700712 if test.expectResumeRejected && !test.resumeSession {
713 panic("expectResumeRejected without resumeSession in " + test.name)
714 }
715
David Benjamin87c8a642015-02-21 01:54:29 -0500716 listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
717 if err != nil {
718 panic(err)
719 }
720 defer func() {
721 if listener != nil {
722 listener.Close()
723 }
724 }()
Adam Langley95c29f32014-06-20 12:00:00 -0700725
David Benjamin87c8a642015-02-21 01:54:29 -0500726 flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
David Benjamin1d5c83e2014-07-22 19:20:02 -0400727 if test.testType == serverTest {
David Benjamin5a593af2014-08-11 19:51:50 -0400728 flags = append(flags, "-server")
729
David Benjamin025b3d32014-07-01 19:53:04 -0400730 flags = append(flags, "-key-file")
731 if test.keyFile == "" {
Adam Langley7c803a62015-06-15 15:35:05 -0700732 flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400733 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700734 flags = append(flags, path.Join(*resourceDir, test.keyFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400735 }
736
737 flags = append(flags, "-cert-file")
738 if test.certFile == "" {
Adam Langley7c803a62015-06-15 15:35:05 -0700739 flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400740 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700741 flags = append(flags, path.Join(*resourceDir, test.certFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400742 }
743 }
David Benjamin5a593af2014-08-11 19:51:50 -0400744
David Benjamin6fd297b2014-08-11 18:43:38 -0400745 if test.protocol == dtls {
746 flags = append(flags, "-dtls")
747 }
748
David Benjamin5a593af2014-08-11 19:51:50 -0400749 if test.resumeSession {
750 flags = append(flags, "-resume")
751 }
752
David Benjamine58c4f52014-08-24 03:47:07 -0400753 if test.shimWritesFirst {
754 flags = append(flags, "-shim-writes-first")
755 }
756
David Benjamin30789da2015-08-29 22:56:45 -0400757 if test.shimShutsDown {
758 flags = append(flags, "-shim-shuts-down")
759 }
760
David Benjaminc565ebb2015-04-03 04:06:36 -0400761 if test.exportKeyingMaterial > 0 {
762 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
763 flags = append(flags, "-export-label", test.exportLabel)
764 flags = append(flags, "-export-context", test.exportContext)
765 if test.useExportContext {
766 flags = append(flags, "-use-export-context")
767 }
768 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700769 if test.expectResumeRejected {
770 flags = append(flags, "-expect-session-miss")
771 }
David Benjaminc565ebb2015-04-03 04:06:36 -0400772
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700773 if test.testTLSUnique {
774 flags = append(flags, "-tls-unique")
775 }
776
David Benjamin025b3d32014-07-01 19:53:04 -0400777 flags = append(flags, test.flags...)
778
779 var shim *exec.Cmd
780 if *useValgrind {
Adam Langley7c803a62015-06-15 15:35:05 -0700781 shim = valgrindOf(false, shimPath, flags...)
Adam Langley75712922014-10-10 16:23:43 -0700782 } else if *useGDB {
Adam Langley7c803a62015-06-15 15:35:05 -0700783 shim = gdbOf(shimPath, flags...)
David Benjamind16bf342015-12-18 00:53:12 -0500784 } else if *useLLDB {
785 shim = lldbOf(shimPath, flags...)
David Benjamin025b3d32014-07-01 19:53:04 -0400786 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700787 shim = exec.Command(shimPath, flags...)
David Benjamin025b3d32014-07-01 19:53:04 -0400788 }
David Benjamin025b3d32014-07-01 19:53:04 -0400789 shim.Stdin = os.Stdin
790 var stdoutBuf, stderrBuf bytes.Buffer
791 shim.Stdout = &stdoutBuf
792 shim.Stderr = &stderrBuf
Adam Langley69a01602014-11-17 17:26:55 -0800793 if mallocNumToFail >= 0 {
David Benjamin9e128b02015-02-09 13:13:09 -0500794 shim.Env = os.Environ()
795 shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
Adam Langley69a01602014-11-17 17:26:55 -0800796 if *mallocTestDebug {
David Benjamin184494d2015-06-12 18:23:47 -0400797 shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
Adam Langley69a01602014-11-17 17:26:55 -0800798 }
799 shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
800 }
David Benjamin025b3d32014-07-01 19:53:04 -0400801
802 if err := shim.Start(); err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700803 panic(err)
804 }
David Benjamin87c8a642015-02-21 01:54:29 -0500805 waitChan := make(chan error, 1)
806 go func() { waitChan <- shim.Wait() }()
Adam Langley95c29f32014-06-20 12:00:00 -0700807
808 config := test.config
David Benjaminba4594a2015-06-18 18:36:15 -0400809 if !test.noSessionCache {
810 config.ClientSessionCache = NewLRUClientSessionCache(1)
811 config.ServerSessionCache = NewLRUServerSessionCache(1)
812 }
David Benjamin025b3d32014-07-01 19:53:04 -0400813 if test.testType == clientTest {
814 if len(config.Certificates) == 0 {
David Benjamin33863262016-07-08 17:20:12 -0700815 config.Certificates = []Certificate{rsaCertificate}
David Benjamin025b3d32014-07-01 19:53:04 -0400816 }
David Benjamin87c8a642015-02-21 01:54:29 -0500817 } else {
818 // Supply a ServerName to ensure a constant session cache key,
819 // rather than falling back to net.Conn.RemoteAddr.
820 if len(config.ServerName) == 0 {
821 config.ServerName = "test"
822 }
David Benjamin025b3d32014-07-01 19:53:04 -0400823 }
David Benjaminf2b83632016-03-01 22:57:46 -0500824 if *fuzzer {
825 config.Bugs.NullAllCiphers = true
826 }
David Benjamin2e045a92016-06-08 13:09:56 -0400827 if *deterministic {
828 config.Rand = &deterministicRand{}
829 }
Adam Langley95c29f32014-06-20 12:00:00 -0700830
David Benjamin87c8a642015-02-21 01:54:29 -0500831 conn, err := acceptOrWait(listener, waitChan)
832 if err == nil {
David Benjamin8e6db492015-07-25 18:29:23 -0400833 err = doExchange(test, &config, conn, false /* not a resumption */)
David Benjamin87c8a642015-02-21 01:54:29 -0500834 conn.Close()
835 }
David Benjamin65ea8ff2014-11-23 03:01:00 -0500836
David Benjamin1d5c83e2014-07-22 19:20:02 -0400837 if err == nil && test.resumeSession {
David Benjamin01fe8202014-09-24 15:21:44 -0400838 var resumeConfig Config
839 if test.resumeConfig != nil {
840 resumeConfig = *test.resumeConfig
David Benjamin87c8a642015-02-21 01:54:29 -0500841 if len(resumeConfig.ServerName) == 0 {
842 resumeConfig.ServerName = config.ServerName
843 }
David Benjamin01fe8202014-09-24 15:21:44 -0400844 if len(resumeConfig.Certificates) == 0 {
David Benjamin33863262016-07-08 17:20:12 -0700845 resumeConfig.Certificates = []Certificate{rsaCertificate}
David Benjamin01fe8202014-09-24 15:21:44 -0400846 }
David Benjaminba4594a2015-06-18 18:36:15 -0400847 if test.newSessionsOnResume {
848 if !test.noSessionCache {
849 resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
850 resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
851 }
852 } else {
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500853 resumeConfig.SessionTicketKey = config.SessionTicketKey
854 resumeConfig.ClientSessionCache = config.ClientSessionCache
855 resumeConfig.ServerSessionCache = config.ServerSessionCache
856 }
David Benjaminf2b83632016-03-01 22:57:46 -0500857 if *fuzzer {
858 resumeConfig.Bugs.NullAllCiphers = true
859 }
David Benjamin2e045a92016-06-08 13:09:56 -0400860 resumeConfig.Rand = config.Rand
David Benjamin01fe8202014-09-24 15:21:44 -0400861 } else {
862 resumeConfig = config
863 }
David Benjamin87c8a642015-02-21 01:54:29 -0500864 var connResume net.Conn
865 connResume, err = acceptOrWait(listener, waitChan)
866 if err == nil {
David Benjamin8e6db492015-07-25 18:29:23 -0400867 err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
David Benjamin87c8a642015-02-21 01:54:29 -0500868 connResume.Close()
869 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400870 }
871
David Benjamin87c8a642015-02-21 01:54:29 -0500872 // Close the listener now. This is to avoid hangs should the shim try to
873 // open more connections than expected.
874 listener.Close()
875 listener = nil
876
877 childErr := <-waitChan
Adam Langley69a01602014-11-17 17:26:55 -0800878 if exitError, ok := childErr.(*exec.ExitError); ok {
879 if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 {
880 return errMoreMallocs
881 }
882 }
Adam Langley95c29f32014-06-20 12:00:00 -0700883
David Benjamin9bea3492016-03-02 10:59:16 -0500884 // Account for Windows line endings.
885 stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1)
886 stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1)
David Benjaminff3a1492016-03-02 10:12:06 -0500887
888 // Separate the errors from the shim and those from tools like
889 // AddressSanitizer.
890 var extraStderr string
891 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 {
892 stderr = stderrParts[0]
893 extraStderr = stderrParts[1]
894 }
895
Adam Langley95c29f32014-06-20 12:00:00 -0700896 failed := err != nil || childErr != nil
David Benjaminc565ebb2015-04-03 04:06:36 -0400897 correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError)
Adam Langleyac61fa32014-06-23 12:03:11 -0700898 localError := "none"
899 if err != nil {
900 localError = err.Error()
901 }
902 if len(test.expectedLocalError) != 0 {
903 correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
904 }
Adam Langley95c29f32014-06-20 12:00:00 -0700905
906 if failed != test.shouldFail || failed && !correctFailure {
Adam Langley95c29f32014-06-20 12:00:00 -0700907 childError := "none"
Adam Langley95c29f32014-06-20 12:00:00 -0700908 if childErr != nil {
909 childError = childErr.Error()
910 }
911
912 var msg string
913 switch {
914 case failed && !test.shouldFail:
915 msg = "unexpected failure"
916 case !failed && test.shouldFail:
917 msg = "unexpected success"
918 case failed && !correctFailure:
Adam Langleyac61fa32014-06-23 12:03:11 -0700919 msg = "bad error (wanted '" + test.expectedError + "' / '" + test.expectedLocalError + "')"
Adam Langley95c29f32014-06-20 12:00:00 -0700920 default:
921 panic("internal error")
922 }
923
David Benjaminc565ebb2015-04-03 04:06:36 -0400924 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 -0700925 }
926
David Benjaminff3a1492016-03-02 10:12:06 -0500927 if !*useValgrind && (len(extraStderr) > 0 || (!failed && len(stderr) > 0)) {
928 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr)
Adam Langley95c29f32014-06-20 12:00:00 -0700929 }
930
931 return nil
932}
933
934var tlsVersions = []struct {
935 name string
936 version uint16
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400937 flag string
David Benjamin8b8c0062014-11-23 02:47:52 -0500938 hasDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -0700939}{
David Benjamin8b8c0062014-11-23 02:47:52 -0500940 {"SSL3", VersionSSL30, "-no-ssl3", false},
941 {"TLS1", VersionTLS10, "-no-tls1", true},
942 {"TLS11", VersionTLS11, "-no-tls11", false},
943 {"TLS12", VersionTLS12, "-no-tls12", true},
Nick Harper1fd39d82016-06-14 18:14:35 -0700944 // TODO(nharper): Once we have a real implementation of TLS 1.3, update the name here.
945 {"FakeTLS13", VersionTLS13, "-no-tls13", false},
Adam Langley95c29f32014-06-20 12:00:00 -0700946}
947
948var testCipherSuites = []struct {
949 name string
950 id uint16
951}{
952 {"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400953 {"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -0700954 {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400955 {"AES128-SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400956 {"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -0700957 {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400958 {"AES256-SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400959 {"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
960 {"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400961 {"DHE-RSA-AES128-SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400962 {"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
963 {"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400964 {"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -0700965 {"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
966 {"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400967 {"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
968 {"ECDHE-ECDSA-AES256-GCM", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -0700969 {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400970 {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
David Benjamin13414b32015-12-09 23:02:39 -0500971 {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
David Benjamine3203922015-12-09 21:21:31 -0500972 {"ECDHE-ECDSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
Adam Langley95c29f32014-06-20 12:00:00 -0700973 {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -0700974 {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -0700975 {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400976 {"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400977 {"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -0700978 {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -0400979 {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
David Benjamin13414b32015-12-09 23:02:39 -0500980 {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
David Benjamine3203922015-12-09 21:21:31 -0500981 {"ECDHE-RSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
Adam Langley95c29f32014-06-20 12:00:00 -0700982 {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
Matt Braithwaite053931e2016-05-25 12:06:05 -0700983 {"CECPQ1-RSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256},
984 {"CECPQ1-ECDSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
985 {"CECPQ1-RSA-AES256-GCM-SHA384", TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
986 {"CECPQ1-ECDSA-AES256-GCM-SHA384", TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384},
David Benjamin48cae082014-10-27 01:06:24 -0400987 {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
988 {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
Adam Langley85bc5602015-06-09 09:54:04 -0700989 {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
990 {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
David Benjamin13414b32015-12-09 23:02:39 -0500991 {"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
Steven Valdez3084e7b2016-06-02 12:07:20 -0400992 {"ECDHE-PSK-AES128-GCM-SHA256", TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256},
993 {"ECDHE-PSK-AES256-GCM-SHA384", TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384},
David Benjamin48cae082014-10-27 01:06:24 -0400994 {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -0700995 {"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
David Benjaminf4e5c4e2014-08-02 17:35:45 -0400996 {"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700997 {"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -0700998}
999
David Benjamin8b8c0062014-11-23 02:47:52 -05001000func hasComponent(suiteName, component string) bool {
1001 return strings.Contains("-"+suiteName+"-", "-"+component+"-")
1002}
1003
David Benjaminf7768e42014-08-31 02:06:47 -04001004func isTLS12Only(suiteName string) bool {
David Benjamin8b8c0062014-11-23 02:47:52 -05001005 return hasComponent(suiteName, "GCM") ||
1006 hasComponent(suiteName, "SHA256") ||
David Benjamine9a80ff2015-04-07 00:46:46 -04001007 hasComponent(suiteName, "SHA384") ||
1008 hasComponent(suiteName, "POLY1305")
David Benjamin8b8c0062014-11-23 02:47:52 -05001009}
1010
Nick Harper1fd39d82016-06-14 18:14:35 -07001011func isTLS13Suite(suiteName string) bool {
David Benjamin54c217c2016-07-13 12:35:25 -04001012 // Only AEADs.
1013 if !hasComponent(suiteName, "GCM") && !hasComponent(suiteName, "POLY1305") {
1014 return false
1015 }
1016 // No old CHACHA20_POLY1305.
1017 if hasComponent(suiteName, "CHACHA20-POLY1305-OLD") {
1018 return false
1019 }
1020 // Must have ECDHE.
1021 // TODO(davidben,svaldez): Add pure PSK support.
1022 if !hasComponent(suiteName, "ECDHE") {
1023 return false
1024 }
1025 // TODO(davidben,svaldez): Add PSK support.
1026 if hasComponent(suiteName, "PSK") {
1027 return false
1028 }
1029 return true
Nick Harper1fd39d82016-06-14 18:14:35 -07001030}
1031
David Benjamin8b8c0062014-11-23 02:47:52 -05001032func isDTLSCipher(suiteName string) bool {
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001033 return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL")
David Benjaminf7768e42014-08-31 02:06:47 -04001034}
1035
Adam Langleya7997f12015-05-14 17:38:50 -07001036func bigFromHex(hex string) *big.Int {
1037 ret, ok := new(big.Int).SetString(hex, 16)
1038 if !ok {
1039 panic("failed to parse hex number 0x" + hex)
1040 }
1041 return ret
1042}
1043
Adam Langley7c803a62015-06-15 15:35:05 -07001044func addBasicTests() {
1045 basicTests := []testCase{
1046 {
Adam Langley7c803a62015-06-15 15:35:05 -07001047 name: "NoFallbackSCSV",
1048 config: Config{
1049 Bugs: ProtocolBugs{
1050 FailIfNotFallbackSCSV: true,
1051 },
1052 },
1053 shouldFail: true,
1054 expectedLocalError: "no fallback SCSV found",
1055 },
1056 {
1057 name: "SendFallbackSCSV",
1058 config: Config{
1059 Bugs: ProtocolBugs{
1060 FailIfNotFallbackSCSV: true,
1061 },
1062 },
1063 flags: []string{"-fallback-scsv"},
1064 },
1065 {
1066 name: "ClientCertificateTypes",
1067 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001068 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001069 ClientAuth: RequestClientCert,
1070 ClientCertificateTypes: []byte{
1071 CertTypeDSSSign,
1072 CertTypeRSASign,
1073 CertTypeECDSASign,
1074 },
1075 },
1076 flags: []string{
1077 "-expect-certificate-types",
1078 base64.StdEncoding.EncodeToString([]byte{
1079 CertTypeDSSSign,
1080 CertTypeRSASign,
1081 CertTypeECDSASign,
1082 }),
1083 },
1084 },
1085 {
Adam Langley7c803a62015-06-15 15:35:05 -07001086 name: "UnauthenticatedECDH",
1087 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001088 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001089 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1090 Bugs: ProtocolBugs{
1091 UnauthenticatedECDH: true,
1092 },
1093 },
1094 shouldFail: true,
1095 expectedError: ":UNEXPECTED_MESSAGE:",
1096 },
1097 {
1098 name: "SkipCertificateStatus",
1099 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001100 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001101 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1102 Bugs: ProtocolBugs{
1103 SkipCertificateStatus: true,
1104 },
1105 },
1106 flags: []string{
1107 "-enable-ocsp-stapling",
1108 },
1109 },
1110 {
1111 name: "SkipServerKeyExchange",
1112 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001113 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001114 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1115 Bugs: ProtocolBugs{
1116 SkipServerKeyExchange: true,
1117 },
1118 },
1119 shouldFail: true,
1120 expectedError: ":UNEXPECTED_MESSAGE:",
1121 },
1122 {
Adam Langley7c803a62015-06-15 15:35:05 -07001123 testType: serverTest,
1124 name: "Alert",
1125 config: Config{
1126 Bugs: ProtocolBugs{
1127 SendSpuriousAlert: alertRecordOverflow,
1128 },
1129 },
1130 shouldFail: true,
1131 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1132 },
1133 {
1134 protocol: dtls,
1135 testType: serverTest,
1136 name: "Alert-DTLS",
1137 config: Config{
1138 Bugs: ProtocolBugs{
1139 SendSpuriousAlert: alertRecordOverflow,
1140 },
1141 },
1142 shouldFail: true,
1143 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1144 },
1145 {
1146 testType: serverTest,
1147 name: "FragmentAlert",
1148 config: Config{
1149 Bugs: ProtocolBugs{
1150 FragmentAlert: true,
1151 SendSpuriousAlert: alertRecordOverflow,
1152 },
1153 },
1154 shouldFail: true,
1155 expectedError: ":BAD_ALERT:",
1156 },
1157 {
1158 protocol: dtls,
1159 testType: serverTest,
1160 name: "FragmentAlert-DTLS",
1161 config: Config{
1162 Bugs: ProtocolBugs{
1163 FragmentAlert: true,
1164 SendSpuriousAlert: alertRecordOverflow,
1165 },
1166 },
1167 shouldFail: true,
1168 expectedError: ":BAD_ALERT:",
1169 },
1170 {
1171 testType: serverTest,
David Benjamin0d3a8c62016-03-11 22:25:18 -05001172 name: "DoubleAlert",
1173 config: Config{
1174 Bugs: ProtocolBugs{
1175 DoubleAlert: true,
1176 SendSpuriousAlert: alertRecordOverflow,
1177 },
1178 },
1179 shouldFail: true,
1180 expectedError: ":BAD_ALERT:",
1181 },
1182 {
1183 protocol: dtls,
1184 testType: serverTest,
1185 name: "DoubleAlert-DTLS",
1186 config: Config{
1187 Bugs: ProtocolBugs{
1188 DoubleAlert: true,
1189 SendSpuriousAlert: alertRecordOverflow,
1190 },
1191 },
1192 shouldFail: true,
1193 expectedError: ":BAD_ALERT:",
1194 },
1195 {
Adam Langley7c803a62015-06-15 15:35:05 -07001196 name: "SkipNewSessionTicket",
1197 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001198 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001199 Bugs: ProtocolBugs{
1200 SkipNewSessionTicket: true,
1201 },
1202 },
1203 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001204 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001205 },
1206 {
1207 testType: serverTest,
1208 name: "FallbackSCSV",
1209 config: Config{
1210 MaxVersion: VersionTLS11,
1211 Bugs: ProtocolBugs{
1212 SendFallbackSCSV: true,
1213 },
1214 },
1215 shouldFail: true,
1216 expectedError: ":INAPPROPRIATE_FALLBACK:",
1217 },
1218 {
1219 testType: serverTest,
1220 name: "FallbackSCSV-VersionMatch",
1221 config: Config{
1222 Bugs: ProtocolBugs{
1223 SendFallbackSCSV: true,
1224 },
1225 },
1226 },
1227 {
1228 testType: serverTest,
David Benjamin4c3ddf72016-06-29 18:13:53 -04001229 name: "FallbackSCSV-VersionMatch-TLS12",
1230 config: Config{
1231 MaxVersion: VersionTLS12,
1232 Bugs: ProtocolBugs{
1233 SendFallbackSCSV: true,
1234 },
1235 },
1236 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
1237 },
1238 {
1239 testType: serverTest,
Adam Langley7c803a62015-06-15 15:35:05 -07001240 name: "FragmentedClientVersion",
1241 config: Config{
1242 Bugs: ProtocolBugs{
1243 MaxHandshakeRecordLength: 1,
1244 FragmentClientVersion: true,
1245 },
1246 },
Nick Harper1fd39d82016-06-14 18:14:35 -07001247 expectedVersion: VersionTLS13,
Adam Langley7c803a62015-06-15 15:35:05 -07001248 },
1249 {
Adam Langley7c803a62015-06-15 15:35:05 -07001250 testType: serverTest,
1251 name: "HttpGET",
1252 sendPrefix: "GET / HTTP/1.0\n",
1253 shouldFail: true,
1254 expectedError: ":HTTP_REQUEST:",
1255 },
1256 {
1257 testType: serverTest,
1258 name: "HttpPOST",
1259 sendPrefix: "POST / HTTP/1.0\n",
1260 shouldFail: true,
1261 expectedError: ":HTTP_REQUEST:",
1262 },
1263 {
1264 testType: serverTest,
1265 name: "HttpHEAD",
1266 sendPrefix: "HEAD / HTTP/1.0\n",
1267 shouldFail: true,
1268 expectedError: ":HTTP_REQUEST:",
1269 },
1270 {
1271 testType: serverTest,
1272 name: "HttpPUT",
1273 sendPrefix: "PUT / HTTP/1.0\n",
1274 shouldFail: true,
1275 expectedError: ":HTTP_REQUEST:",
1276 },
1277 {
1278 testType: serverTest,
1279 name: "HttpCONNECT",
1280 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
1281 shouldFail: true,
1282 expectedError: ":HTTPS_PROXY_REQUEST:",
1283 },
1284 {
1285 testType: serverTest,
1286 name: "Garbage",
1287 sendPrefix: "blah",
1288 shouldFail: true,
David Benjamin97760d52015-07-24 23:02:49 -04001289 expectedError: ":WRONG_VERSION_NUMBER:",
Adam Langley7c803a62015-06-15 15:35:05 -07001290 },
1291 {
Adam Langley7c803a62015-06-15 15:35:05 -07001292 name: "RSAEphemeralKey",
1293 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001294 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001295 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
1296 Bugs: ProtocolBugs{
1297 RSAEphemeralKey: true,
1298 },
1299 },
1300 shouldFail: true,
1301 expectedError: ":UNEXPECTED_MESSAGE:",
1302 },
1303 {
1304 name: "DisableEverything",
Steven Valdez4f94b1c2016-05-24 12:31:07 -04001305 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
Adam Langley7c803a62015-06-15 15:35:05 -07001306 shouldFail: true,
1307 expectedError: ":WRONG_SSL_VERSION:",
1308 },
1309 {
1310 protocol: dtls,
1311 name: "DisableEverything-DTLS",
1312 flags: []string{"-no-tls12", "-no-tls1"},
1313 shouldFail: true,
1314 expectedError: ":WRONG_SSL_VERSION:",
1315 },
1316 {
Adam Langley7c803a62015-06-15 15:35:05 -07001317 protocol: dtls,
1318 testType: serverTest,
1319 name: "MTU",
1320 config: Config{
1321 Bugs: ProtocolBugs{
1322 MaxPacketLength: 256,
1323 },
1324 },
1325 flags: []string{"-mtu", "256"},
1326 },
1327 {
1328 protocol: dtls,
1329 testType: serverTest,
1330 name: "MTUExceeded",
1331 config: Config{
1332 Bugs: ProtocolBugs{
1333 MaxPacketLength: 255,
1334 },
1335 },
1336 flags: []string{"-mtu", "256"},
1337 shouldFail: true,
1338 expectedLocalError: "dtls: exceeded maximum packet length",
1339 },
1340 {
1341 name: "CertMismatchRSA",
1342 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001343 // TODO(davidben): Add a TLS 1.3 version of this test.
1344 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001345 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07001346 Certificates: []Certificate{ecdsaP256Certificate},
Adam Langley7c803a62015-06-15 15:35:05 -07001347 Bugs: ProtocolBugs{
1348 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1349 },
1350 },
1351 shouldFail: true,
1352 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1353 },
1354 {
1355 name: "CertMismatchECDSA",
1356 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001357 // TODO(davidben): Add a TLS 1.3 version of this test.
1358 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001359 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07001360 Certificates: []Certificate{rsaCertificate},
Adam Langley7c803a62015-06-15 15:35:05 -07001361 Bugs: ProtocolBugs{
1362 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1363 },
1364 },
1365 shouldFail: true,
1366 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1367 },
1368 {
1369 name: "EmptyCertificateList",
1370 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001371 // TODO(davidben): Add a TLS 1.3 version of this test.
1372 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001373 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1374 Bugs: ProtocolBugs{
1375 EmptyCertificateList: true,
1376 },
1377 },
1378 shouldFail: true,
1379 expectedError: ":DECODE_ERROR:",
1380 },
1381 {
David Benjamin9ec1c752016-07-14 12:45:01 -04001382 name: "EmptyCertificateList-TLS13",
1383 config: Config{
1384 MaxVersion: VersionTLS13,
1385 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1386 Bugs: ProtocolBugs{
1387 EmptyCertificateList: true,
1388 },
1389 },
1390 shouldFail: true,
1391 expectedError: ":DECODE_ERROR:",
1392 },
1393 {
Adam Langley7c803a62015-06-15 15:35:05 -07001394 name: "TLSFatalBadPackets",
1395 damageFirstWrite: true,
1396 shouldFail: true,
1397 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
1398 },
1399 {
1400 protocol: dtls,
1401 name: "DTLSIgnoreBadPackets",
1402 damageFirstWrite: true,
1403 },
1404 {
1405 protocol: dtls,
1406 name: "DTLSIgnoreBadPackets-Async",
1407 damageFirstWrite: true,
1408 flags: []string{"-async"},
1409 },
1410 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001411 name: "AppDataBeforeHandshake",
1412 config: Config{
1413 Bugs: ProtocolBugs{
1414 AppDataBeforeHandshake: []byte("TEST MESSAGE"),
1415 },
1416 },
1417 shouldFail: true,
1418 expectedError: ":UNEXPECTED_RECORD:",
1419 },
1420 {
1421 name: "AppDataBeforeHandshake-Empty",
1422 config: Config{
1423 Bugs: ProtocolBugs{
1424 AppDataBeforeHandshake: []byte{},
1425 },
1426 },
1427 shouldFail: true,
1428 expectedError: ":UNEXPECTED_RECORD:",
1429 },
1430 {
1431 protocol: dtls,
1432 name: "AppDataBeforeHandshake-DTLS",
1433 config: Config{
1434 Bugs: ProtocolBugs{
1435 AppDataBeforeHandshake: []byte("TEST MESSAGE"),
1436 },
1437 },
1438 shouldFail: true,
1439 expectedError: ":UNEXPECTED_RECORD:",
1440 },
1441 {
1442 protocol: dtls,
1443 name: "AppDataBeforeHandshake-DTLS-Empty",
1444 config: Config{
1445 Bugs: ProtocolBugs{
1446 AppDataBeforeHandshake: []byte{},
1447 },
1448 },
1449 shouldFail: true,
1450 expectedError: ":UNEXPECTED_RECORD:",
1451 },
1452 {
Adam Langley7c803a62015-06-15 15:35:05 -07001453 name: "AppDataAfterChangeCipherSpec",
1454 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001455 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001456 Bugs: ProtocolBugs{
1457 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
1458 },
1459 },
1460 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001461 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001462 },
1463 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001464 name: "AppDataAfterChangeCipherSpec-Empty",
1465 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001466 MaxVersion: VersionTLS12,
David Benjamin4cf369b2015-08-22 01:35:43 -04001467 Bugs: ProtocolBugs{
1468 AppDataAfterChangeCipherSpec: []byte{},
1469 },
1470 },
1471 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001472 expectedError: ":UNEXPECTED_RECORD:",
David Benjamin4cf369b2015-08-22 01:35:43 -04001473 },
1474 {
Adam Langley7c803a62015-06-15 15:35:05 -07001475 protocol: dtls,
1476 name: "AppDataAfterChangeCipherSpec-DTLS",
1477 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001478 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001479 Bugs: ProtocolBugs{
1480 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
1481 },
1482 },
1483 // BoringSSL's DTLS implementation will drop the out-of-order
1484 // application data.
1485 },
1486 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001487 protocol: dtls,
1488 name: "AppDataAfterChangeCipherSpec-DTLS-Empty",
1489 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001490 MaxVersion: VersionTLS12,
David Benjamin4cf369b2015-08-22 01:35:43 -04001491 Bugs: ProtocolBugs{
1492 AppDataAfterChangeCipherSpec: []byte{},
1493 },
1494 },
1495 // BoringSSL's DTLS implementation will drop the out-of-order
1496 // application data.
1497 },
1498 {
Adam Langley7c803a62015-06-15 15:35:05 -07001499 name: "AlertAfterChangeCipherSpec",
1500 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001501 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001502 Bugs: ProtocolBugs{
1503 AlertAfterChangeCipherSpec: alertRecordOverflow,
1504 },
1505 },
1506 shouldFail: true,
1507 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1508 },
1509 {
1510 protocol: dtls,
1511 name: "AlertAfterChangeCipherSpec-DTLS",
1512 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001513 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001514 Bugs: ProtocolBugs{
1515 AlertAfterChangeCipherSpec: alertRecordOverflow,
1516 },
1517 },
1518 shouldFail: true,
1519 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1520 },
1521 {
1522 protocol: dtls,
1523 name: "ReorderHandshakeFragments-Small-DTLS",
1524 config: Config{
1525 Bugs: ProtocolBugs{
1526 ReorderHandshakeFragments: true,
1527 // Small enough that every handshake message is
1528 // fragmented.
1529 MaxHandshakeRecordLength: 2,
1530 },
1531 },
1532 },
1533 {
1534 protocol: dtls,
1535 name: "ReorderHandshakeFragments-Large-DTLS",
1536 config: Config{
1537 Bugs: ProtocolBugs{
1538 ReorderHandshakeFragments: true,
1539 // Large enough that no handshake message is
1540 // fragmented.
1541 MaxHandshakeRecordLength: 2048,
1542 },
1543 },
1544 },
1545 {
1546 protocol: dtls,
1547 name: "MixCompleteMessageWithFragments-DTLS",
1548 config: Config{
1549 Bugs: ProtocolBugs{
1550 ReorderHandshakeFragments: true,
1551 MixCompleteMessageWithFragments: true,
1552 MaxHandshakeRecordLength: 2,
1553 },
1554 },
1555 },
1556 {
1557 name: "SendInvalidRecordType",
1558 config: Config{
1559 Bugs: ProtocolBugs{
1560 SendInvalidRecordType: true,
1561 },
1562 },
1563 shouldFail: true,
1564 expectedError: ":UNEXPECTED_RECORD:",
1565 },
1566 {
1567 protocol: dtls,
1568 name: "SendInvalidRecordType-DTLS",
1569 config: Config{
1570 Bugs: ProtocolBugs{
1571 SendInvalidRecordType: true,
1572 },
1573 },
1574 shouldFail: true,
1575 expectedError: ":UNEXPECTED_RECORD:",
1576 },
1577 {
1578 name: "FalseStart-SkipServerSecondLeg",
1579 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001580 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001581 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1582 NextProtos: []string{"foo"},
1583 Bugs: ProtocolBugs{
1584 SkipNewSessionTicket: true,
1585 SkipChangeCipherSpec: true,
1586 SkipFinished: true,
1587 ExpectFalseStart: true,
1588 },
1589 },
1590 flags: []string{
1591 "-false-start",
1592 "-handshake-never-done",
1593 "-advertise-alpn", "\x03foo",
1594 },
1595 shimWritesFirst: true,
1596 shouldFail: true,
1597 expectedError: ":UNEXPECTED_RECORD:",
1598 },
1599 {
1600 name: "FalseStart-SkipServerSecondLeg-Implicit",
1601 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001602 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001603 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1604 NextProtos: []string{"foo"},
1605 Bugs: ProtocolBugs{
1606 SkipNewSessionTicket: true,
1607 SkipChangeCipherSpec: true,
1608 SkipFinished: true,
1609 },
1610 },
1611 flags: []string{
1612 "-implicit-handshake",
1613 "-false-start",
1614 "-handshake-never-done",
1615 "-advertise-alpn", "\x03foo",
1616 },
1617 shouldFail: true,
1618 expectedError: ":UNEXPECTED_RECORD:",
1619 },
1620 {
1621 testType: serverTest,
1622 name: "FailEarlyCallback",
1623 flags: []string{"-fail-early-callback"},
1624 shouldFail: true,
1625 expectedError: ":CONNECTION_REJECTED:",
1626 expectedLocalError: "remote error: access denied",
1627 },
1628 {
Adam Langley7c803a62015-06-15 15:35:05 -07001629 protocol: dtls,
1630 name: "FragmentMessageTypeMismatch-DTLS",
1631 config: Config{
1632 Bugs: ProtocolBugs{
1633 MaxHandshakeRecordLength: 2,
1634 FragmentMessageTypeMismatch: true,
1635 },
1636 },
1637 shouldFail: true,
1638 expectedError: ":FRAGMENT_MISMATCH:",
1639 },
1640 {
1641 protocol: dtls,
1642 name: "FragmentMessageLengthMismatch-DTLS",
1643 config: Config{
1644 Bugs: ProtocolBugs{
1645 MaxHandshakeRecordLength: 2,
1646 FragmentMessageLengthMismatch: true,
1647 },
1648 },
1649 shouldFail: true,
1650 expectedError: ":FRAGMENT_MISMATCH:",
1651 },
1652 {
1653 protocol: dtls,
1654 name: "SplitFragments-Header-DTLS",
1655 config: Config{
1656 Bugs: ProtocolBugs{
1657 SplitFragments: 2,
1658 },
1659 },
1660 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001661 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001662 },
1663 {
1664 protocol: dtls,
1665 name: "SplitFragments-Boundary-DTLS",
1666 config: Config{
1667 Bugs: ProtocolBugs{
1668 SplitFragments: dtlsRecordHeaderLen,
1669 },
1670 },
1671 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001672 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001673 },
1674 {
1675 protocol: dtls,
1676 name: "SplitFragments-Body-DTLS",
1677 config: Config{
1678 Bugs: ProtocolBugs{
1679 SplitFragments: dtlsRecordHeaderLen + 1,
1680 },
1681 },
1682 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001683 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001684 },
1685 {
1686 protocol: dtls,
1687 name: "SendEmptyFragments-DTLS",
1688 config: Config{
1689 Bugs: ProtocolBugs{
1690 SendEmptyFragments: true,
1691 },
1692 },
1693 },
1694 {
David Benjaminbf82aed2016-03-01 22:57:40 -05001695 name: "BadFinished-Client",
1696 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001697 // TODO(davidben): Add a TLS 1.3 version of this.
1698 MaxVersion: VersionTLS12,
David Benjaminbf82aed2016-03-01 22:57:40 -05001699 Bugs: ProtocolBugs{
1700 BadFinished: true,
1701 },
1702 },
1703 shouldFail: true,
1704 expectedError: ":DIGEST_CHECK_FAILED:",
1705 },
1706 {
1707 testType: serverTest,
1708 name: "BadFinished-Server",
Adam Langley7c803a62015-06-15 15:35:05 -07001709 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001710 // TODO(davidben): Add a TLS 1.3 version of this.
1711 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001712 Bugs: ProtocolBugs{
1713 BadFinished: true,
1714 },
1715 },
1716 shouldFail: true,
1717 expectedError: ":DIGEST_CHECK_FAILED:",
1718 },
1719 {
1720 name: "FalseStart-BadFinished",
1721 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001722 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001723 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1724 NextProtos: []string{"foo"},
1725 Bugs: ProtocolBugs{
1726 BadFinished: true,
1727 ExpectFalseStart: true,
1728 },
1729 },
1730 flags: []string{
1731 "-false-start",
1732 "-handshake-never-done",
1733 "-advertise-alpn", "\x03foo",
1734 },
1735 shimWritesFirst: true,
1736 shouldFail: true,
1737 expectedError: ":DIGEST_CHECK_FAILED:",
1738 },
1739 {
1740 name: "NoFalseStart-NoALPN",
1741 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001742 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001743 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1744 Bugs: ProtocolBugs{
1745 ExpectFalseStart: true,
1746 AlertBeforeFalseStartTest: alertAccessDenied,
1747 },
1748 },
1749 flags: []string{
1750 "-false-start",
1751 },
1752 shimWritesFirst: true,
1753 shouldFail: true,
1754 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1755 expectedLocalError: "tls: peer did not false start: EOF",
1756 },
1757 {
1758 name: "NoFalseStart-NoAEAD",
1759 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001760 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001761 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
1762 NextProtos: []string{"foo"},
1763 Bugs: ProtocolBugs{
1764 ExpectFalseStart: true,
1765 AlertBeforeFalseStartTest: alertAccessDenied,
1766 },
1767 },
1768 flags: []string{
1769 "-false-start",
1770 "-advertise-alpn", "\x03foo",
1771 },
1772 shimWritesFirst: true,
1773 shouldFail: true,
1774 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1775 expectedLocalError: "tls: peer did not false start: EOF",
1776 },
1777 {
1778 name: "NoFalseStart-RSA",
1779 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001780 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001781 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
1782 NextProtos: []string{"foo"},
1783 Bugs: ProtocolBugs{
1784 ExpectFalseStart: true,
1785 AlertBeforeFalseStartTest: alertAccessDenied,
1786 },
1787 },
1788 flags: []string{
1789 "-false-start",
1790 "-advertise-alpn", "\x03foo",
1791 },
1792 shimWritesFirst: true,
1793 shouldFail: true,
1794 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1795 expectedLocalError: "tls: peer did not false start: EOF",
1796 },
1797 {
1798 name: "NoFalseStart-DHE_RSA",
1799 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001800 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001801 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
1802 NextProtos: []string{"foo"},
1803 Bugs: ProtocolBugs{
1804 ExpectFalseStart: true,
1805 AlertBeforeFalseStartTest: alertAccessDenied,
1806 },
1807 },
1808 flags: []string{
1809 "-false-start",
1810 "-advertise-alpn", "\x03foo",
1811 },
1812 shimWritesFirst: true,
1813 shouldFail: true,
1814 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1815 expectedLocalError: "tls: peer did not false start: EOF",
1816 },
1817 {
Adam Langley7c803a62015-06-15 15:35:05 -07001818 protocol: dtls,
1819 name: "SendSplitAlert-Sync",
1820 config: Config{
1821 Bugs: ProtocolBugs{
1822 SendSplitAlert: true,
1823 },
1824 },
1825 },
1826 {
1827 protocol: dtls,
1828 name: "SendSplitAlert-Async",
1829 config: Config{
1830 Bugs: ProtocolBugs{
1831 SendSplitAlert: true,
1832 },
1833 },
1834 flags: []string{"-async"},
1835 },
1836 {
1837 protocol: dtls,
1838 name: "PackDTLSHandshake",
1839 config: Config{
1840 Bugs: ProtocolBugs{
1841 MaxHandshakeRecordLength: 2,
1842 PackHandshakeFragments: 20,
1843 PackHandshakeRecords: 200,
1844 },
1845 },
1846 },
1847 {
Adam Langley7c803a62015-06-15 15:35:05 -07001848 name: "SendEmptyRecords-Pass",
1849 sendEmptyRecords: 32,
1850 },
1851 {
1852 name: "SendEmptyRecords",
1853 sendEmptyRecords: 33,
1854 shouldFail: true,
1855 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
1856 },
1857 {
1858 name: "SendEmptyRecords-Async",
1859 sendEmptyRecords: 33,
1860 flags: []string{"-async"},
1861 shouldFail: true,
1862 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
1863 },
1864 {
1865 name: "SendWarningAlerts-Pass",
1866 sendWarningAlerts: 4,
1867 },
1868 {
1869 protocol: dtls,
1870 name: "SendWarningAlerts-DTLS-Pass",
1871 sendWarningAlerts: 4,
1872 },
1873 {
1874 name: "SendWarningAlerts",
1875 sendWarningAlerts: 5,
1876 shouldFail: true,
1877 expectedError: ":TOO_MANY_WARNING_ALERTS:",
1878 },
1879 {
1880 name: "SendWarningAlerts-Async",
1881 sendWarningAlerts: 5,
1882 flags: []string{"-async"},
1883 shouldFail: true,
1884 expectedError: ":TOO_MANY_WARNING_ALERTS:",
1885 },
David Benjaminba4594a2015-06-18 18:36:15 -04001886 {
1887 name: "EmptySessionID",
1888 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001889 MaxVersion: VersionTLS12,
David Benjaminba4594a2015-06-18 18:36:15 -04001890 SessionTicketsDisabled: true,
1891 },
1892 noSessionCache: true,
1893 flags: []string{"-expect-no-session"},
1894 },
David Benjamin30789da2015-08-29 22:56:45 -04001895 {
1896 name: "Unclean-Shutdown",
1897 config: Config{
1898 Bugs: ProtocolBugs{
1899 NoCloseNotify: true,
1900 ExpectCloseNotify: true,
1901 },
1902 },
1903 shimShutsDown: true,
1904 flags: []string{"-check-close-notify"},
1905 shouldFail: true,
1906 expectedError: "Unexpected SSL_shutdown result: -1 != 1",
1907 },
1908 {
1909 name: "Unclean-Shutdown-Ignored",
1910 config: Config{
1911 Bugs: ProtocolBugs{
1912 NoCloseNotify: true,
1913 },
1914 },
1915 shimShutsDown: true,
1916 },
David Benjamin4f75aaf2015-09-01 16:53:10 -04001917 {
David Benjaminfa214e42016-05-10 17:03:10 -04001918 name: "Unclean-Shutdown-Alert",
1919 config: Config{
1920 Bugs: ProtocolBugs{
1921 SendAlertOnShutdown: alertDecompressionFailure,
1922 ExpectCloseNotify: true,
1923 },
1924 },
1925 shimShutsDown: true,
1926 flags: []string{"-check-close-notify"},
1927 shouldFail: true,
1928 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:",
1929 },
1930 {
David Benjamin4f75aaf2015-09-01 16:53:10 -04001931 name: "LargePlaintext",
1932 config: Config{
1933 Bugs: ProtocolBugs{
1934 SendLargeRecords: true,
1935 },
1936 },
1937 messageLen: maxPlaintext + 1,
1938 shouldFail: true,
1939 expectedError: ":DATA_LENGTH_TOO_LONG:",
1940 },
1941 {
1942 protocol: dtls,
1943 name: "LargePlaintext-DTLS",
1944 config: Config{
1945 Bugs: ProtocolBugs{
1946 SendLargeRecords: true,
1947 },
1948 },
1949 messageLen: maxPlaintext + 1,
1950 shouldFail: true,
1951 expectedError: ":DATA_LENGTH_TOO_LONG:",
1952 },
1953 {
1954 name: "LargeCiphertext",
1955 config: Config{
1956 Bugs: ProtocolBugs{
1957 SendLargeRecords: true,
1958 },
1959 },
1960 messageLen: maxPlaintext * 2,
1961 shouldFail: true,
1962 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
1963 },
1964 {
1965 protocol: dtls,
1966 name: "LargeCiphertext-DTLS",
1967 config: Config{
1968 Bugs: ProtocolBugs{
1969 SendLargeRecords: true,
1970 },
1971 },
1972 messageLen: maxPlaintext * 2,
1973 // Unlike the other four cases, DTLS drops records which
1974 // are invalid before authentication, so the connection
1975 // does not fail.
1976 expectMessageDropped: true,
1977 },
David Benjamindd6fed92015-10-23 17:41:12 -04001978 {
David Benjamin4c3ddf72016-06-29 18:13:53 -04001979 // In TLS 1.2 and below, empty NewSessionTicket messages
1980 // mean the server changed its mind on sending a ticket.
David Benjamindd6fed92015-10-23 17:41:12 -04001981 name: "SendEmptySessionTicket",
1982 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001983 MaxVersion: VersionTLS12,
David Benjamindd6fed92015-10-23 17:41:12 -04001984 Bugs: ProtocolBugs{
1985 SendEmptySessionTicket: true,
1986 FailIfSessionOffered: true,
1987 },
1988 },
1989 flags: []string{"-expect-no-session"},
1990 resumeSession: true,
1991 expectResumeRejected: true,
1992 },
David Benjamin99fdfb92015-11-02 12:11:35 -05001993 {
David Benjaminef5dfd22015-12-06 13:17:07 -05001994 name: "BadHelloRequest-1",
1995 renegotiate: 1,
1996 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001997 MaxVersion: VersionTLS12,
David Benjaminef5dfd22015-12-06 13:17:07 -05001998 Bugs: ProtocolBugs{
1999 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1},
2000 },
2001 },
2002 flags: []string{
2003 "-renegotiate-freely",
2004 "-expect-total-renegotiations", "1",
2005 },
2006 shouldFail: true,
2007 expectedError: ":BAD_HELLO_REQUEST:",
2008 },
2009 {
2010 name: "BadHelloRequest-2",
2011 renegotiate: 1,
2012 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002013 MaxVersion: VersionTLS12,
David Benjaminef5dfd22015-12-06 13:17:07 -05002014 Bugs: ProtocolBugs{
2015 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0},
2016 },
2017 },
2018 flags: []string{
2019 "-renegotiate-freely",
2020 "-expect-total-renegotiations", "1",
2021 },
2022 shouldFail: true,
2023 expectedError: ":BAD_HELLO_REQUEST:",
2024 },
David Benjaminef1b0092015-11-21 14:05:44 -05002025 {
2026 testType: serverTest,
2027 name: "SupportTicketsWithSessionID",
2028 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002029 MaxVersion: VersionTLS12,
David Benjaminef1b0092015-11-21 14:05:44 -05002030 SessionTicketsDisabled: true,
2031 },
David Benjamin4c3ddf72016-06-29 18:13:53 -04002032 resumeConfig: &Config{
2033 MaxVersion: VersionTLS12,
2034 },
David Benjaminef1b0092015-11-21 14:05:44 -05002035 resumeSession: true,
2036 },
Adam Langley7c803a62015-06-15 15:35:05 -07002037 }
Adam Langley7c803a62015-06-15 15:35:05 -07002038 testCases = append(testCases, basicTests...)
2039}
2040
Adam Langley95c29f32014-06-20 12:00:00 -07002041func addCipherSuiteTests() {
2042 for _, suite := range testCipherSuites {
David Benjamin48cae082014-10-27 01:06:24 -04002043 const psk = "12345"
2044 const pskIdentity = "luggage combo"
2045
Adam Langley95c29f32014-06-20 12:00:00 -07002046 var cert Certificate
David Benjamin025b3d32014-07-01 19:53:04 -04002047 var certFile string
2048 var keyFile string
David Benjamin8b8c0062014-11-23 02:47:52 -05002049 if hasComponent(suite.name, "ECDSA") {
David Benjamin33863262016-07-08 17:20:12 -07002050 cert = ecdsaP256Certificate
2051 certFile = ecdsaP256CertificateFile
2052 keyFile = ecdsaP256KeyFile
Adam Langley95c29f32014-06-20 12:00:00 -07002053 } else {
David Benjamin33863262016-07-08 17:20:12 -07002054 cert = rsaCertificate
David Benjamin025b3d32014-07-01 19:53:04 -04002055 certFile = rsaCertificateFile
2056 keyFile = rsaKeyFile
Adam Langley95c29f32014-06-20 12:00:00 -07002057 }
2058
David Benjamin48cae082014-10-27 01:06:24 -04002059 var flags []string
David Benjamin8b8c0062014-11-23 02:47:52 -05002060 if hasComponent(suite.name, "PSK") {
David Benjamin48cae082014-10-27 01:06:24 -04002061 flags = append(flags,
2062 "-psk", psk,
2063 "-psk-identity", pskIdentity)
2064 }
Matt Braithwaiteaf096752015-09-02 19:48:16 -07002065 if hasComponent(suite.name, "NULL") {
2066 // NULL ciphers must be explicitly enabled.
2067 flags = append(flags, "-cipher", "DEFAULT:NULL-SHA")
2068 }
Matt Braithwaite053931e2016-05-25 12:06:05 -07002069 if hasComponent(suite.name, "CECPQ1") {
2070 // CECPQ1 ciphers must be explicitly enabled.
2071 flags = append(flags, "-cipher", "DEFAULT:kCECPQ1")
2072 }
David Benjamin48cae082014-10-27 01:06:24 -04002073
Adam Langley95c29f32014-06-20 12:00:00 -07002074 for _, ver := range tlsVersions {
David Benjamin0407e762016-06-17 16:41:18 -04002075 for _, protocol := range []protocol{tls, dtls} {
2076 var prefix string
2077 if protocol == dtls {
2078 if !ver.hasDTLS {
2079 continue
2080 }
2081 prefix = "D"
2082 }
Adam Langley95c29f32014-06-20 12:00:00 -07002083
David Benjamin0407e762016-06-17 16:41:18 -04002084 var shouldServerFail, shouldClientFail bool
2085 if hasComponent(suite.name, "ECDHE") && ver.version == VersionSSL30 {
2086 // BoringSSL clients accept ECDHE on SSLv3, but
2087 // a BoringSSL server will never select it
2088 // because the extension is missing.
2089 shouldServerFail = true
2090 }
2091 if isTLS12Only(suite.name) && ver.version < VersionTLS12 {
2092 shouldClientFail = true
2093 shouldServerFail = true
2094 }
David Benjamin54c217c2016-07-13 12:35:25 -04002095 if !isTLS13Suite(suite.name) && ver.version >= VersionTLS13 {
Nick Harper1fd39d82016-06-14 18:14:35 -07002096 shouldClientFail = true
2097 shouldServerFail = true
2098 }
David Benjamin0407e762016-06-17 16:41:18 -04002099 if !isDTLSCipher(suite.name) && protocol == dtls {
2100 shouldClientFail = true
2101 shouldServerFail = true
2102 }
David Benjamin4298d772015-12-19 00:18:25 -05002103
David Benjamin0407e762016-06-17 16:41:18 -04002104 var expectedServerError, expectedClientError string
2105 if shouldServerFail {
2106 expectedServerError = ":NO_SHARED_CIPHER:"
2107 }
2108 if shouldClientFail {
2109 expectedClientError = ":WRONG_CIPHER_RETURNED:"
2110 }
David Benjamin025b3d32014-07-01 19:53:04 -04002111
David Benjamin9deb1172016-07-13 17:13:49 -04002112 // TODO(davidben,svaldez): Implement resumption for TLS 1.3.
2113 resumeSession := ver.version < VersionTLS13
2114
David Benjamin6fd297b2014-08-11 18:43:38 -04002115 testCases = append(testCases, testCase{
2116 testType: serverTest,
David Benjamin0407e762016-06-17 16:41:18 -04002117 protocol: protocol,
2118
2119 name: prefix + ver.name + "-" + suite.name + "-server",
David Benjamin6fd297b2014-08-11 18:43:38 -04002120 config: Config{
David Benjamin48cae082014-10-27 01:06:24 -04002121 MinVersion: ver.version,
2122 MaxVersion: ver.version,
2123 CipherSuites: []uint16{suite.id},
2124 Certificates: []Certificate{cert},
2125 PreSharedKey: []byte(psk),
2126 PreSharedKeyIdentity: pskIdentity,
David Benjamin0407e762016-06-17 16:41:18 -04002127 Bugs: ProtocolBugs{
David Benjamin9acf0ca2016-06-25 00:01:28 -04002128 EnableAllCiphers: shouldServerFail,
2129 IgnorePeerCipherPreferences: shouldServerFail,
David Benjamin0407e762016-06-17 16:41:18 -04002130 },
David Benjamin6fd297b2014-08-11 18:43:38 -04002131 },
2132 certFile: certFile,
2133 keyFile: keyFile,
David Benjamin48cae082014-10-27 01:06:24 -04002134 flags: flags,
David Benjamin9deb1172016-07-13 17:13:49 -04002135 resumeSession: resumeSession,
David Benjamin0407e762016-06-17 16:41:18 -04002136 shouldFail: shouldServerFail,
2137 expectedError: expectedServerError,
2138 })
2139
2140 testCases = append(testCases, testCase{
2141 testType: clientTest,
2142 protocol: protocol,
2143 name: prefix + ver.name + "-" + suite.name + "-client",
2144 config: Config{
2145 MinVersion: ver.version,
2146 MaxVersion: ver.version,
2147 CipherSuites: []uint16{suite.id},
2148 Certificates: []Certificate{cert},
2149 PreSharedKey: []byte(psk),
2150 PreSharedKeyIdentity: pskIdentity,
2151 Bugs: ProtocolBugs{
David Benjamin9acf0ca2016-06-25 00:01:28 -04002152 EnableAllCiphers: shouldClientFail,
2153 IgnorePeerCipherPreferences: shouldClientFail,
David Benjamin0407e762016-06-17 16:41:18 -04002154 },
2155 },
2156 flags: flags,
David Benjamin9deb1172016-07-13 17:13:49 -04002157 resumeSession: resumeSession,
David Benjamin0407e762016-06-17 16:41:18 -04002158 shouldFail: shouldClientFail,
2159 expectedError: expectedClientError,
David Benjamin6fd297b2014-08-11 18:43:38 -04002160 })
David Benjamin2c99d282015-09-01 10:23:00 -04002161
Nick Harper1fd39d82016-06-14 18:14:35 -07002162 if !shouldClientFail {
2163 // Ensure the maximum record size is accepted.
2164 testCases = append(testCases, testCase{
2165 name: prefix + ver.name + "-" + suite.name + "-LargeRecord",
2166 config: Config{
2167 MinVersion: ver.version,
2168 MaxVersion: ver.version,
2169 CipherSuites: []uint16{suite.id},
2170 Certificates: []Certificate{cert},
2171 PreSharedKey: []byte(psk),
2172 PreSharedKeyIdentity: pskIdentity,
2173 },
2174 flags: flags,
2175 messageLen: maxPlaintext,
2176 })
2177 }
2178 }
David Benjamin2c99d282015-09-01 10:23:00 -04002179 }
Adam Langley95c29f32014-06-20 12:00:00 -07002180 }
Adam Langleya7997f12015-05-14 17:38:50 -07002181
2182 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002183 name: "NoSharedCipher",
2184 config: Config{
2185 // TODO(davidben): Add a TLS 1.3 version of this test.
2186 MaxVersion: VersionTLS12,
2187 CipherSuites: []uint16{},
2188 },
2189 shouldFail: true,
2190 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
2191 })
2192
2193 testCases = append(testCases, testCase{
2194 name: "UnsupportedCipherSuite",
2195 config: Config{
2196 MaxVersion: VersionTLS12,
2197 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
2198 Bugs: ProtocolBugs{
2199 IgnorePeerCipherPreferences: true,
2200 },
2201 },
2202 flags: []string{"-cipher", "DEFAULT:!RC4"},
2203 shouldFail: true,
2204 expectedError: ":WRONG_CIPHER_RETURNED:",
2205 })
2206
2207 testCases = append(testCases, testCase{
Adam Langleya7997f12015-05-14 17:38:50 -07002208 name: "WeakDH",
2209 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002210 MaxVersion: VersionTLS12,
Adam Langleya7997f12015-05-14 17:38:50 -07002211 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2212 Bugs: ProtocolBugs{
2213 // This is a 1023-bit prime number, generated
2214 // with:
2215 // openssl gendh 1023 | openssl asn1parse -i
2216 DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"),
2217 },
2218 },
2219 shouldFail: true,
David Benjamincd24a392015-11-11 13:23:05 -08002220 expectedError: ":BAD_DH_P_LENGTH:",
Adam Langleya7997f12015-05-14 17:38:50 -07002221 })
Adam Langleycef75832015-09-03 14:51:12 -07002222
David Benjamincd24a392015-11-11 13:23:05 -08002223 testCases = append(testCases, testCase{
2224 name: "SillyDH",
2225 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002226 MaxVersion: VersionTLS12,
David Benjamincd24a392015-11-11 13:23:05 -08002227 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2228 Bugs: ProtocolBugs{
2229 // This is a 4097-bit prime number, generated
2230 // with:
2231 // openssl gendh 4097 | openssl asn1parse -i
2232 DHGroupPrime: bigFromHex("01D366FA64A47419B0CD4A45918E8D8C8430F674621956A9F52B0CA592BC104C6E38D60C58F2CA66792A2B7EBDC6F8FFE75AB7D6862C261F34E96A2AEEF53AB7C21365C2E8FB0582F71EB57B1C227C0E55AE859E9904A25EFECD7B435C4D4357BD840B03649D4A1F8037D89EA4E1967DBEEF1CC17A6111C48F12E9615FFF336D3F07064CB17C0B765A012C850B9E3AA7A6984B96D8C867DDC6D0F4AB52042572244796B7ECFF681CD3B3E2E29AAECA391A775BEE94E502FB15881B0F4AC60314EA947C0C82541C3D16FD8C0E09BB7F8F786582032859D9C13187CE6C0CB6F2D3EE6C3C9727C15F14B21D3CD2E02BDB9D119959B0E03DC9E5A91E2578762300B1517D2352FC1D0BB934A4C3E1B20CE9327DB102E89A6C64A8C3148EDFC5A94913933853442FA84451B31FD21E492F92DD5488E0D871AEBFE335A4B92431DEC69591548010E76A5B365D346786E9A2D3E589867D796AA5E25211201D757560D318A87DFB27F3E625BC373DB48BF94A63161C674C3D4265CB737418441B7650EABC209CF675A439BEB3E9D1AA1B79F67198A40CEFD1C89144F7D8BAF61D6AD36F466DA546B4174A0E0CAF5BD788C8243C7C2DDDCC3DB6FC89F12F17D19FBD9B0BC76FE92891CD6BA07BEA3B66EF12D0D85E788FD58675C1B0FBD16029DCC4D34E7A1A41471BDEDF78BF591A8B4E96D88BEC8EDC093E616292BFC096E69A916E8D624B"),
2233 },
2234 },
2235 shouldFail: true,
2236 expectedError: ":DH_P_TOO_LONG:",
2237 })
2238
Adam Langleyc4f25ce2015-11-26 16:39:08 -08002239 // This test ensures that Diffie-Hellman public values are padded with
2240 // zeros so that they're the same length as the prime. This is to avoid
2241 // hitting a bug in yaSSL.
2242 testCases = append(testCases, testCase{
2243 testType: serverTest,
2244 name: "DHPublicValuePadded",
2245 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002246 MaxVersion: VersionTLS12,
Adam Langleyc4f25ce2015-11-26 16:39:08 -08002247 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2248 Bugs: ProtocolBugs{
2249 RequireDHPublicValueLen: (1025 + 7) / 8,
2250 },
2251 },
2252 flags: []string{"-use-sparse-dh-prime"},
2253 })
David Benjamincd24a392015-11-11 13:23:05 -08002254
David Benjamin241ae832016-01-15 03:04:54 -05002255 // The server must be tolerant to bogus ciphers.
2256 const bogusCipher = 0x1234
2257 testCases = append(testCases, testCase{
2258 testType: serverTest,
2259 name: "UnknownCipher",
2260 config: Config{
2261 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2262 },
2263 })
2264
Adam Langleycef75832015-09-03 14:51:12 -07002265 // versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
2266 // 1.1 specific cipher suite settings. A server is setup with the given
2267 // cipher lists and then a connection is made for each member of
2268 // expectations. The cipher suite that the server selects must match
2269 // the specified one.
2270 var versionSpecificCiphersTest = []struct {
2271 ciphersDefault, ciphersTLS10, ciphersTLS11 string
2272 // expectations is a map from TLS version to cipher suite id.
2273 expectations map[uint16]uint16
2274 }{
2275 {
2276 // Test that the null case (where no version-specific ciphers are set)
2277 // works as expected.
2278 "RC4-SHA:AES128-SHA", // default ciphers
2279 "", // no ciphers specifically for TLS ≥ 1.0
2280 "", // no ciphers specifically for TLS ≥ 1.1
2281 map[uint16]uint16{
2282 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2283 VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
2284 VersionTLS11: TLS_RSA_WITH_RC4_128_SHA,
2285 VersionTLS12: TLS_RSA_WITH_RC4_128_SHA,
2286 },
2287 },
2288 {
2289 // With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
2290 // cipher.
2291 "RC4-SHA:AES128-SHA", // default
2292 "AES128-SHA", // these ciphers for TLS ≥ 1.0
2293 "", // no ciphers specifically for TLS ≥ 1.1
2294 map[uint16]uint16{
2295 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2296 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
2297 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
2298 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
2299 },
2300 },
2301 {
2302 // With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
2303 // cipher.
2304 "RC4-SHA:AES128-SHA", // default
2305 "", // no ciphers specifically for TLS ≥ 1.0
2306 "AES128-SHA", // these ciphers for TLS ≥ 1.1
2307 map[uint16]uint16{
2308 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2309 VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
2310 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
2311 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
2312 },
2313 },
2314 {
2315 // With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
2316 // mask ciphers_tls10 for TLS 1.1 and 1.2.
2317 "RC4-SHA:AES128-SHA", // default
2318 "AES128-SHA", // these ciphers for TLS ≥ 1.0
2319 "AES256-SHA", // these ciphers for TLS ≥ 1.1
2320 map[uint16]uint16{
2321 VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
2322 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
2323 VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
2324 VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
2325 },
2326 },
2327 }
2328
2329 for i, test := range versionSpecificCiphersTest {
2330 for version, expectedCipherSuite := range test.expectations {
2331 flags := []string{"-cipher", test.ciphersDefault}
2332 if len(test.ciphersTLS10) > 0 {
2333 flags = append(flags, "-cipher-tls10", test.ciphersTLS10)
2334 }
2335 if len(test.ciphersTLS11) > 0 {
2336 flags = append(flags, "-cipher-tls11", test.ciphersTLS11)
2337 }
2338
2339 testCases = append(testCases, testCase{
2340 testType: serverTest,
2341 name: fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version),
2342 config: Config{
2343 MaxVersion: version,
2344 MinVersion: version,
2345 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
2346 },
2347 flags: flags,
2348 expectedCipher: expectedCipherSuite,
2349 })
2350 }
2351 }
Adam Langley95c29f32014-06-20 12:00:00 -07002352}
2353
2354func addBadECDSASignatureTests() {
2355 for badR := BadValue(1); badR < NumBadValues; badR++ {
2356 for badS := BadValue(1); badS < NumBadValues; badS++ {
David Benjamin025b3d32014-07-01 19:53:04 -04002357 testCases = append(testCases, testCase{
Adam Langley95c29f32014-06-20 12:00:00 -07002358 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
2359 config: Config{
2360 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07002361 Certificates: []Certificate{ecdsaP256Certificate},
Adam Langley95c29f32014-06-20 12:00:00 -07002362 Bugs: ProtocolBugs{
2363 BadECDSAR: badR,
2364 BadECDSAS: badS,
2365 },
2366 },
2367 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002368 expectedError: ":BAD_SIGNATURE:",
Adam Langley95c29f32014-06-20 12:00:00 -07002369 })
2370 }
2371 }
2372}
2373
Adam Langley80842bd2014-06-20 12:00:00 -07002374func addCBCPaddingTests() {
David Benjamin025b3d32014-07-01 19:53:04 -04002375 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002376 name: "MaxCBCPadding",
2377 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002378 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002379 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2380 Bugs: ProtocolBugs{
2381 MaxPadding: true,
2382 },
2383 },
2384 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
2385 })
David Benjamin025b3d32014-07-01 19:53:04 -04002386 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002387 name: "BadCBCPadding",
2388 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002389 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002390 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2391 Bugs: ProtocolBugs{
2392 PaddingFirstByteBad: true,
2393 },
2394 },
2395 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002396 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
Adam Langley80842bd2014-06-20 12:00:00 -07002397 })
2398 // OpenSSL previously had an issue where the first byte of padding in
2399 // 255 bytes of padding wasn't checked.
David Benjamin025b3d32014-07-01 19:53:04 -04002400 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002401 name: "BadCBCPadding255",
2402 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002403 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002404 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2405 Bugs: ProtocolBugs{
2406 MaxPadding: true,
2407 PaddingFirstByteBadIf255: true,
2408 },
2409 },
2410 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
2411 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002412 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
Adam Langley80842bd2014-06-20 12:00:00 -07002413 })
2414}
2415
Kenny Root7fdeaf12014-08-05 15:23:37 -07002416func addCBCSplittingTests() {
2417 testCases = append(testCases, testCase{
2418 name: "CBCRecordSplitting",
2419 config: Config{
2420 MaxVersion: VersionTLS10,
2421 MinVersion: VersionTLS10,
2422 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2423 },
David Benjaminac8302a2015-09-01 17:18:15 -04002424 messageLen: -1, // read until EOF
2425 resumeSession: true,
Kenny Root7fdeaf12014-08-05 15:23:37 -07002426 flags: []string{
2427 "-async",
2428 "-write-different-record-sizes",
2429 "-cbc-record-splitting",
2430 },
David Benjamina8e3e0e2014-08-06 22:11:10 -04002431 })
2432 testCases = append(testCases, testCase{
Kenny Root7fdeaf12014-08-05 15:23:37 -07002433 name: "CBCRecordSplittingPartialWrite",
2434 config: Config{
2435 MaxVersion: VersionTLS10,
2436 MinVersion: VersionTLS10,
2437 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2438 },
2439 messageLen: -1, // read until EOF
2440 flags: []string{
2441 "-async",
2442 "-write-different-record-sizes",
2443 "-cbc-record-splitting",
2444 "-partial-write",
2445 },
2446 })
2447}
2448
David Benjamin636293b2014-07-08 17:59:18 -04002449func addClientAuthTests() {
David Benjamin407a10c2014-07-16 12:58:59 -04002450 // Add a dummy cert pool to stress certificate authority parsing.
2451 // TODO(davidben): Add tests that those values parse out correctly.
2452 certPool := x509.NewCertPool()
2453 cert, err := x509.ParseCertificate(rsaCertificate.Certificate[0])
2454 if err != nil {
2455 panic(err)
2456 }
2457 certPool.AddCert(cert)
2458
David Benjamin636293b2014-07-08 17:59:18 -04002459 for _, ver := range tlsVersions {
David Benjamin636293b2014-07-08 17:59:18 -04002460 testCases = append(testCases, testCase{
2461 testType: clientTest,
David Benjamin67666e72014-07-12 15:47:52 -04002462 name: ver.name + "-Client-ClientAuth-RSA",
David Benjamin636293b2014-07-08 17:59:18 -04002463 config: Config{
David Benjamine098ec22014-08-27 23:13:20 -04002464 MinVersion: ver.version,
2465 MaxVersion: ver.version,
2466 ClientAuth: RequireAnyClientCert,
2467 ClientCAs: certPool,
David Benjamin636293b2014-07-08 17:59:18 -04002468 },
2469 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07002470 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2471 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin636293b2014-07-08 17:59:18 -04002472 },
2473 })
2474 testCases = append(testCases, testCase{
David Benjamin67666e72014-07-12 15:47:52 -04002475 testType: serverTest,
2476 name: ver.name + "-Server-ClientAuth-RSA",
2477 config: Config{
David Benjamine098ec22014-08-27 23:13:20 -04002478 MinVersion: ver.version,
2479 MaxVersion: ver.version,
David Benjamin67666e72014-07-12 15:47:52 -04002480 Certificates: []Certificate{rsaCertificate},
2481 },
2482 flags: []string{"-require-any-client-certificate"},
2483 })
David Benjamine098ec22014-08-27 23:13:20 -04002484 if ver.version != VersionSSL30 {
2485 testCases = append(testCases, testCase{
2486 testType: serverTest,
2487 name: ver.name + "-Server-ClientAuth-ECDSA",
2488 config: Config{
2489 MinVersion: ver.version,
2490 MaxVersion: ver.version,
David Benjamin33863262016-07-08 17:20:12 -07002491 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamine098ec22014-08-27 23:13:20 -04002492 },
2493 flags: []string{"-require-any-client-certificate"},
2494 })
2495 testCases = append(testCases, testCase{
2496 testType: clientTest,
2497 name: ver.name + "-Client-ClientAuth-ECDSA",
2498 config: Config{
2499 MinVersion: ver.version,
2500 MaxVersion: ver.version,
2501 ClientAuth: RequireAnyClientCert,
2502 ClientCAs: certPool,
2503 },
2504 flags: []string{
David Benjamin33863262016-07-08 17:20:12 -07002505 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
2506 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
David Benjamine098ec22014-08-27 23:13:20 -04002507 },
2508 })
2509 }
David Benjamin636293b2014-07-08 17:59:18 -04002510 }
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002511
Nick Harper1fd39d82016-06-14 18:14:35 -07002512 // TODO(davidben): These tests will need TLS 1.3 versions when the
2513 // handshake is separate.
2514
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002515 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002516 name: "NoClientCertificate",
2517 config: Config{
2518 MaxVersion: VersionTLS12,
2519 ClientAuth: RequireAnyClientCert,
2520 },
2521 shouldFail: true,
2522 expectedLocalError: "client didn't provide a certificate",
2523 })
2524
2525 testCases = append(testCases, testCase{
Nick Harper1fd39d82016-06-14 18:14:35 -07002526 testType: serverTest,
2527 name: "RequireAnyClientCertificate",
2528 config: Config{
2529 MaxVersion: VersionTLS12,
2530 },
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002531 flags: []string{"-require-any-client-certificate"},
2532 shouldFail: true,
2533 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
2534 })
2535
2536 testCases = append(testCases, testCase{
2537 testType: serverTest,
David Benjamindf28c3a2016-03-10 16:11:51 -05002538 name: "RequireAnyClientCertificate-SSL3",
2539 config: Config{
2540 MaxVersion: VersionSSL30,
2541 },
2542 flags: []string{"-require-any-client-certificate"},
2543 shouldFail: true,
2544 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
2545 })
2546
2547 testCases = append(testCases, testCase{
2548 testType: serverTest,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002549 name: "SkipClientCertificate",
2550 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002551 MaxVersion: VersionTLS12,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002552 Bugs: ProtocolBugs{
2553 SkipClientCertificate: true,
2554 },
2555 },
2556 // Setting SSL_VERIFY_PEER allows anonymous clients.
2557 flags: []string{"-verify-peer"},
2558 shouldFail: true,
David Benjamindf28c3a2016-03-10 16:11:51 -05002559 expectedError: ":UNEXPECTED_MESSAGE:",
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002560 })
David Benjaminc032dfa2016-05-12 14:54:57 -04002561
2562 // Client auth is only legal in certificate-based ciphers.
2563 testCases = append(testCases, testCase{
2564 testType: clientTest,
2565 name: "ClientAuth-PSK",
2566 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002567 MaxVersion: VersionTLS12,
David Benjaminc032dfa2016-05-12 14:54:57 -04002568 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
2569 PreSharedKey: []byte("secret"),
2570 ClientAuth: RequireAnyClientCert,
2571 },
2572 flags: []string{
2573 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2574 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2575 "-psk", "secret",
2576 },
2577 shouldFail: true,
2578 expectedError: ":UNEXPECTED_MESSAGE:",
2579 })
2580 testCases = append(testCases, testCase{
2581 testType: clientTest,
2582 name: "ClientAuth-ECDHE_PSK",
2583 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002584 MaxVersion: VersionTLS12,
David Benjaminc032dfa2016-05-12 14:54:57 -04002585 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
2586 PreSharedKey: []byte("secret"),
2587 ClientAuth: RequireAnyClientCert,
2588 },
2589 flags: []string{
2590 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2591 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2592 "-psk", "secret",
2593 },
2594 shouldFail: true,
2595 expectedError: ":UNEXPECTED_MESSAGE:",
2596 })
David Benjamin2f8935d2016-07-13 19:47:39 -04002597
2598 // Regression test for a bug where the client CA list, if explicitly
2599 // set to NULL, was mis-encoded.
2600 testCases = append(testCases, testCase{
2601 testType: serverTest,
2602 name: "Null-Client-CA-List",
2603 config: Config{
2604 MaxVersion: VersionTLS12,
2605 Certificates: []Certificate{rsaCertificate},
2606 },
2607 flags: []string{
2608 "-require-any-client-certificate",
2609 "-use-null-client-ca-list",
2610 },
2611 })
David Benjamin636293b2014-07-08 17:59:18 -04002612}
2613
Adam Langley75712922014-10-10 16:23:43 -07002614func addExtendedMasterSecretTests() {
2615 const expectEMSFlag = "-expect-extended-master-secret"
2616
2617 for _, with := range []bool{false, true} {
2618 prefix := "No"
2619 var flags []string
2620 if with {
2621 prefix = ""
2622 flags = []string{expectEMSFlag}
2623 }
2624
2625 for _, isClient := range []bool{false, true} {
2626 suffix := "-Server"
2627 testType := serverTest
2628 if isClient {
2629 suffix = "-Client"
2630 testType = clientTest
2631 }
2632
David Benjamin4c3ddf72016-06-29 18:13:53 -04002633 // TODO(davidben): Once the new TLS 1.3 handshake is in,
2634 // test that the extension is irrelevant, but the API
2635 // acts as if it is enabled.
Adam Langley75712922014-10-10 16:23:43 -07002636 for _, ver := range tlsVersions {
2637 test := testCase{
2638 testType: testType,
2639 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix,
2640 config: Config{
2641 MinVersion: ver.version,
2642 MaxVersion: ver.version,
2643 Bugs: ProtocolBugs{
2644 NoExtendedMasterSecret: !with,
2645 RequireExtendedMasterSecret: with,
2646 },
2647 },
David Benjamin48cae082014-10-27 01:06:24 -04002648 flags: flags,
2649 shouldFail: ver.version == VersionSSL30 && with,
Adam Langley75712922014-10-10 16:23:43 -07002650 }
2651 if test.shouldFail {
2652 test.expectedLocalError = "extended master secret required but not supported by peer"
2653 }
2654 testCases = append(testCases, test)
2655 }
2656 }
2657 }
2658
Adam Langleyba5934b2015-06-02 10:50:35 -07002659 for _, isClient := range []bool{false, true} {
2660 for _, supportedInFirstConnection := range []bool{false, true} {
2661 for _, supportedInResumeConnection := range []bool{false, true} {
2662 boolToWord := func(b bool) string {
2663 if b {
2664 return "Yes"
2665 }
2666 return "No"
2667 }
2668 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
2669 if isClient {
2670 suffix += "Client"
2671 } else {
2672 suffix += "Server"
2673 }
2674
2675 supportedConfig := Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002676 MaxVersion: VersionTLS12,
Adam Langleyba5934b2015-06-02 10:50:35 -07002677 Bugs: ProtocolBugs{
2678 RequireExtendedMasterSecret: true,
2679 },
2680 }
2681
2682 noSupportConfig := Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002683 MaxVersion: VersionTLS12,
Adam Langleyba5934b2015-06-02 10:50:35 -07002684 Bugs: ProtocolBugs{
2685 NoExtendedMasterSecret: true,
2686 },
2687 }
2688
2689 test := testCase{
2690 name: "ExtendedMasterSecret-" + suffix,
2691 resumeSession: true,
2692 }
2693
2694 if !isClient {
2695 test.testType = serverTest
2696 }
2697
2698 if supportedInFirstConnection {
2699 test.config = supportedConfig
2700 } else {
2701 test.config = noSupportConfig
2702 }
2703
2704 if supportedInResumeConnection {
2705 test.resumeConfig = &supportedConfig
2706 } else {
2707 test.resumeConfig = &noSupportConfig
2708 }
2709
2710 switch suffix {
2711 case "YesToYes-Client", "YesToYes-Server":
2712 // When a session is resumed, it should
2713 // still be aware that its master
2714 // secret was generated via EMS and
2715 // thus it's safe to use tls-unique.
2716 test.flags = []string{expectEMSFlag}
2717 case "NoToYes-Server":
2718 // If an original connection did not
2719 // contain EMS, but a resumption
2720 // handshake does, then a server should
2721 // not resume the session.
2722 test.expectResumeRejected = true
2723 case "YesToNo-Server":
2724 // Resuming an EMS session without the
2725 // EMS extension should cause the
2726 // server to abort the connection.
2727 test.shouldFail = true
2728 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
2729 case "NoToYes-Client":
2730 // A client should abort a connection
2731 // where the server resumed a non-EMS
2732 // session but echoed the EMS
2733 // extension.
2734 test.shouldFail = true
2735 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
2736 case "YesToNo-Client":
2737 // A client should abort a connection
2738 // where the server didn't echo EMS
2739 // when the session used it.
2740 test.shouldFail = true
2741 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
2742 }
2743
2744 testCases = append(testCases, test)
2745 }
2746 }
2747 }
Adam Langley75712922014-10-10 16:23:43 -07002748}
2749
David Benjamin582ba042016-07-07 12:33:25 -07002750type stateMachineTestConfig struct {
2751 protocol protocol
2752 async bool
2753 splitHandshake, packHandshakeFlight bool
2754}
2755
David Benjamin43ec06f2014-08-05 02:28:57 -04002756// Adds tests that try to cover the range of the handshake state machine, under
2757// various conditions. Some of these are redundant with other tests, but they
2758// only cover the synchronous case.
David Benjamin582ba042016-07-07 12:33:25 -07002759func addAllStateMachineCoverageTests() {
2760 for _, async := range []bool{false, true} {
2761 for _, protocol := range []protocol{tls, dtls} {
2762 addStateMachineCoverageTests(stateMachineTestConfig{
2763 protocol: protocol,
2764 async: async,
2765 })
2766 addStateMachineCoverageTests(stateMachineTestConfig{
2767 protocol: protocol,
2768 async: async,
2769 splitHandshake: true,
2770 })
2771 if protocol == tls {
2772 addStateMachineCoverageTests(stateMachineTestConfig{
2773 protocol: protocol,
2774 async: async,
2775 packHandshakeFlight: true,
2776 })
2777 }
2778 }
2779 }
2780}
2781
2782func addStateMachineCoverageTests(config stateMachineTestConfig) {
David Benjamin760b1dd2015-05-15 23:33:48 -04002783 var tests []testCase
2784
2785 // Basic handshake, with resumption. Client and server,
2786 // session ID and session ticket.
David Benjamin4c3ddf72016-06-29 18:13:53 -04002787 //
2788 // TODO(davidben): Add TLS 1.3 tests for all of its different handshake
2789 // shapes.
David Benjamin760b1dd2015-05-15 23:33:48 -04002790 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002791 name: "Basic-Client",
2792 config: Config{
2793 MaxVersion: VersionTLS12,
2794 },
David Benjamin760b1dd2015-05-15 23:33:48 -04002795 resumeSession: true,
David Benjaminef1b0092015-11-21 14:05:44 -05002796 // Ensure session tickets are used, not session IDs.
2797 noSessionCache: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04002798 })
2799 tests = append(tests, testCase{
2800 name: "Basic-Client-RenewTicket",
2801 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002802 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04002803 Bugs: ProtocolBugs{
2804 RenewTicketOnResume: true,
2805 },
2806 },
David Benjaminba4594a2015-06-18 18:36:15 -04002807 flags: []string{"-expect-ticket-renewal"},
David Benjamin760b1dd2015-05-15 23:33:48 -04002808 resumeSession: true,
2809 })
2810 tests = append(tests, testCase{
2811 name: "Basic-Client-NoTicket",
2812 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002813 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04002814 SessionTicketsDisabled: true,
2815 },
2816 resumeSession: true,
2817 })
2818 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002819 name: "Basic-Client-Implicit",
2820 config: Config{
2821 MaxVersion: VersionTLS12,
2822 },
David Benjamin760b1dd2015-05-15 23:33:48 -04002823 flags: []string{"-implicit-handshake"},
2824 resumeSession: true,
2825 })
2826 tests = append(tests, testCase{
David Benjaminef1b0092015-11-21 14:05:44 -05002827 testType: serverTest,
2828 name: "Basic-Server",
2829 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002830 MaxVersion: VersionTLS12,
David Benjaminef1b0092015-11-21 14:05:44 -05002831 Bugs: ProtocolBugs{
2832 RequireSessionTickets: true,
2833 },
2834 },
David Benjamin760b1dd2015-05-15 23:33:48 -04002835 resumeSession: true,
2836 })
2837 tests = append(tests, testCase{
2838 testType: serverTest,
2839 name: "Basic-Server-NoTickets",
2840 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002841 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04002842 SessionTicketsDisabled: true,
2843 },
2844 resumeSession: true,
2845 })
2846 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002847 testType: serverTest,
2848 name: "Basic-Server-Implicit",
2849 config: Config{
2850 MaxVersion: VersionTLS12,
2851 },
David Benjamin760b1dd2015-05-15 23:33:48 -04002852 flags: []string{"-implicit-handshake"},
2853 resumeSession: true,
2854 })
2855 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002856 testType: serverTest,
2857 name: "Basic-Server-EarlyCallback",
2858 config: Config{
2859 MaxVersion: VersionTLS12,
2860 },
David Benjamin760b1dd2015-05-15 23:33:48 -04002861 flags: []string{"-use-early-callback"},
2862 resumeSession: true,
2863 })
2864
2865 // TLS client auth.
David Benjamin4c3ddf72016-06-29 18:13:53 -04002866 //
2867 // TODO(davidben): Add TLS 1.3 client auth tests.
David Benjamin760b1dd2015-05-15 23:33:48 -04002868 tests = append(tests, testCase{
2869 testType: clientTest,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002870 name: "ClientAuth-NoCertificate-Client",
David Benjaminacb6dcc2016-03-10 09:15:01 -05002871 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002872 MaxVersion: VersionTLS12,
David Benjaminacb6dcc2016-03-10 09:15:01 -05002873 ClientAuth: RequestClientCert,
2874 },
2875 })
2876 tests = append(tests, testCase{
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002877 testType: serverTest,
2878 name: "ClientAuth-NoCertificate-Server",
David Benjamin4c3ddf72016-06-29 18:13:53 -04002879 config: Config{
2880 MaxVersion: VersionTLS12,
2881 },
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002882 // Setting SSL_VERIFY_PEER allows anonymous clients.
2883 flags: []string{"-verify-peer"},
2884 })
David Benjamin582ba042016-07-07 12:33:25 -07002885 if config.protocol == tls {
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002886 tests = append(tests, testCase{
2887 testType: clientTest,
2888 name: "ClientAuth-NoCertificate-Client-SSL3",
2889 config: Config{
2890 MaxVersion: VersionSSL30,
2891 ClientAuth: RequestClientCert,
2892 },
2893 })
2894 tests = append(tests, testCase{
2895 testType: serverTest,
2896 name: "ClientAuth-NoCertificate-Server-SSL3",
2897 config: Config{
2898 MaxVersion: VersionSSL30,
2899 },
2900 // Setting SSL_VERIFY_PEER allows anonymous clients.
2901 flags: []string{"-verify-peer"},
2902 })
2903 }
2904 tests = append(tests, testCase{
David Benjaminacb6dcc2016-03-10 09:15:01 -05002905 testType: clientTest,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07002906 name: "ClientAuth-RSA-Client",
David Benjamin760b1dd2015-05-15 23:33:48 -04002907 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002908 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04002909 ClientAuth: RequireAnyClientCert,
2910 },
2911 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07002912 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2913 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin760b1dd2015-05-15 23:33:48 -04002914 },
2915 })
nagendra modadugu3398dbf2015-08-07 14:07:52 -07002916 tests = append(tests, testCase{
2917 testType: clientTest,
2918 name: "ClientAuth-ECDSA-Client",
2919 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002920 MaxVersion: VersionTLS12,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07002921 ClientAuth: RequireAnyClientCert,
2922 },
2923 flags: []string{
David Benjamin33863262016-07-08 17:20:12 -07002924 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
2925 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
nagendra modadugu3398dbf2015-08-07 14:07:52 -07002926 },
2927 })
David Benjaminacb6dcc2016-03-10 09:15:01 -05002928 tests = append(tests, testCase{
2929 testType: clientTest,
David Benjamin4c3ddf72016-06-29 18:13:53 -04002930 name: "ClientAuth-NoCertificate-OldCallback",
2931 config: Config{
2932 MaxVersion: VersionTLS12,
2933 ClientAuth: RequestClientCert,
2934 },
2935 flags: []string{"-use-old-client-cert-callback"},
2936 })
2937 tests = append(tests, testCase{
2938 testType: clientTest,
David Benjaminacb6dcc2016-03-10 09:15:01 -05002939 name: "ClientAuth-OldCallback",
2940 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002941 MaxVersion: VersionTLS12,
David Benjaminacb6dcc2016-03-10 09:15:01 -05002942 ClientAuth: RequireAnyClientCert,
2943 },
2944 flags: []string{
2945 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2946 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2947 "-use-old-client-cert-callback",
2948 },
2949 })
David Benjamin760b1dd2015-05-15 23:33:48 -04002950 tests = append(tests, testCase{
2951 testType: serverTest,
2952 name: "ClientAuth-Server",
2953 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002954 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04002955 Certificates: []Certificate{rsaCertificate},
2956 },
2957 flags: []string{"-require-any-client-certificate"},
2958 })
2959
David Benjamin4c3ddf72016-06-29 18:13:53 -04002960 // Test each key exchange on the server side for async keys.
2961 //
2962 // TODO(davidben): Add TLS 1.3 versions of these.
2963 tests = append(tests, testCase{
2964 testType: serverTest,
2965 name: "Basic-Server-RSA",
2966 config: Config{
2967 MaxVersion: VersionTLS12,
2968 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
2969 },
2970 flags: []string{
2971 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2972 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2973 },
2974 })
2975 tests = append(tests, testCase{
2976 testType: serverTest,
2977 name: "Basic-Server-ECDHE-RSA",
2978 config: Config{
2979 MaxVersion: VersionTLS12,
2980 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2981 },
2982 flags: []string{
2983 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2984 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2985 },
2986 })
2987 tests = append(tests, testCase{
2988 testType: serverTest,
2989 name: "Basic-Server-ECDHE-ECDSA",
2990 config: Config{
2991 MaxVersion: VersionTLS12,
2992 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
2993 },
2994 flags: []string{
David Benjamin33863262016-07-08 17:20:12 -07002995 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
2996 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
David Benjamin4c3ddf72016-06-29 18:13:53 -04002997 },
2998 })
2999
David Benjamin760b1dd2015-05-15 23:33:48 -04003000 // No session ticket support; server doesn't send NewSessionTicket.
3001 tests = append(tests, testCase{
3002 name: "SessionTicketsDisabled-Client",
3003 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003004 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003005 SessionTicketsDisabled: true,
3006 },
3007 })
3008 tests = append(tests, testCase{
3009 testType: serverTest,
3010 name: "SessionTicketsDisabled-Server",
3011 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003012 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003013 SessionTicketsDisabled: true,
3014 },
3015 })
3016
3017 // Skip ServerKeyExchange in PSK key exchange if there's no
3018 // identity hint.
3019 tests = append(tests, testCase{
3020 name: "EmptyPSKHint-Client",
3021 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003022 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003023 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3024 PreSharedKey: []byte("secret"),
3025 },
3026 flags: []string{"-psk", "secret"},
3027 })
3028 tests = append(tests, testCase{
3029 testType: serverTest,
3030 name: "EmptyPSKHint-Server",
3031 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003032 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003033 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3034 PreSharedKey: []byte("secret"),
3035 },
3036 flags: []string{"-psk", "secret"},
3037 })
3038
David Benjamin4c3ddf72016-06-29 18:13:53 -04003039 // OCSP stapling tests.
3040 //
3041 // TODO(davidben): Test the TLS 1.3 version of OCSP stapling.
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003042 tests = append(tests, testCase{
3043 testType: clientTest,
3044 name: "OCSPStapling-Client",
David Benjamin4c3ddf72016-06-29 18:13:53 -04003045 config: Config{
3046 MaxVersion: VersionTLS12,
3047 },
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003048 flags: []string{
3049 "-enable-ocsp-stapling",
3050 "-expect-ocsp-response",
3051 base64.StdEncoding.EncodeToString(testOCSPResponse),
Paul Lietar8f1c2682015-08-18 12:21:54 +01003052 "-verify-peer",
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003053 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01003054 resumeSession: true,
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003055 })
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003056 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003057 testType: serverTest,
3058 name: "OCSPStapling-Server",
3059 config: Config{
3060 MaxVersion: VersionTLS12,
3061 },
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003062 expectedOCSPResponse: testOCSPResponse,
3063 flags: []string{
3064 "-ocsp-response",
3065 base64.StdEncoding.EncodeToString(testOCSPResponse),
3066 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01003067 resumeSession: true,
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003068 })
3069
David Benjamin4c3ddf72016-06-29 18:13:53 -04003070 // Certificate verification tests.
3071 //
3072 // TODO(davidben): Test the TLS 1.3 version.
Paul Lietar8f1c2682015-08-18 12:21:54 +01003073 tests = append(tests, testCase{
3074 testType: clientTest,
3075 name: "CertificateVerificationSucceed",
David Benjamin4c3ddf72016-06-29 18:13:53 -04003076 config: Config{
3077 MaxVersion: VersionTLS12,
3078 },
Paul Lietar8f1c2682015-08-18 12:21:54 +01003079 flags: []string{
3080 "-verify-peer",
3081 },
3082 })
Paul Lietar8f1c2682015-08-18 12:21:54 +01003083 tests = append(tests, testCase{
3084 testType: clientTest,
3085 name: "CertificateVerificationFail",
David Benjamin4c3ddf72016-06-29 18:13:53 -04003086 config: Config{
3087 MaxVersion: VersionTLS12,
3088 },
Paul Lietar8f1c2682015-08-18 12:21:54 +01003089 flags: []string{
3090 "-verify-fail",
3091 "-verify-peer",
3092 },
3093 shouldFail: true,
3094 expectedError: ":CERTIFICATE_VERIFY_FAILED:",
3095 })
Paul Lietar8f1c2682015-08-18 12:21:54 +01003096 tests = append(tests, testCase{
3097 testType: clientTest,
3098 name: "CertificateVerificationSoftFail",
David Benjamin4c3ddf72016-06-29 18:13:53 -04003099 config: Config{
3100 MaxVersion: VersionTLS12,
3101 },
Paul Lietar8f1c2682015-08-18 12:21:54 +01003102 flags: []string{
3103 "-verify-fail",
3104 "-expect-verify-result",
3105 },
3106 })
3107
David Benjamin582ba042016-07-07 12:33:25 -07003108 if config.protocol == tls {
David Benjamin760b1dd2015-05-15 23:33:48 -04003109 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003110 name: "Renegotiate-Client",
3111 config: Config{
3112 MaxVersion: VersionTLS12,
3113 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04003114 renegotiate: 1,
3115 flags: []string{
3116 "-renegotiate-freely",
3117 "-expect-total-renegotiations", "1",
3118 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003119 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04003120
David Benjamin760b1dd2015-05-15 23:33:48 -04003121 // NPN on client and server; results in post-handshake message.
3122 tests = append(tests, testCase{
3123 name: "NPN-Client",
3124 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003125 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003126 NextProtos: []string{"foo"},
3127 },
3128 flags: []string{"-select-next-proto", "foo"},
David Benjaminf8fcdf32016-06-08 15:56:13 -04003129 resumeSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003130 expectedNextProto: "foo",
3131 expectedNextProtoType: npn,
3132 })
3133 tests = append(tests, testCase{
3134 testType: serverTest,
3135 name: "NPN-Server",
3136 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003137 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003138 NextProtos: []string{"bar"},
3139 },
3140 flags: []string{
3141 "-advertise-npn", "\x03foo\x03bar\x03baz",
3142 "-expect-next-proto", "bar",
3143 },
David Benjaminf8fcdf32016-06-08 15:56:13 -04003144 resumeSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003145 expectedNextProto: "bar",
3146 expectedNextProtoType: npn,
3147 })
3148
3149 // TODO(davidben): Add tests for when False Start doesn't trigger.
3150
3151 // Client does False Start and negotiates NPN.
3152 tests = append(tests, testCase{
3153 name: "FalseStart",
3154 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003155 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003156 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3157 NextProtos: []string{"foo"},
3158 Bugs: ProtocolBugs{
3159 ExpectFalseStart: true,
3160 },
3161 },
3162 flags: []string{
3163 "-false-start",
3164 "-select-next-proto", "foo",
3165 },
3166 shimWritesFirst: true,
3167 resumeSession: true,
3168 })
3169
3170 // Client does False Start and negotiates ALPN.
3171 tests = append(tests, testCase{
3172 name: "FalseStart-ALPN",
3173 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003174 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003175 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3176 NextProtos: []string{"foo"},
3177 Bugs: ProtocolBugs{
3178 ExpectFalseStart: true,
3179 },
3180 },
3181 flags: []string{
3182 "-false-start",
3183 "-advertise-alpn", "\x03foo",
3184 },
3185 shimWritesFirst: true,
3186 resumeSession: true,
3187 })
3188
3189 // Client does False Start but doesn't explicitly call
3190 // SSL_connect.
3191 tests = append(tests, testCase{
3192 name: "FalseStart-Implicit",
3193 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003194 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003195 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3196 NextProtos: []string{"foo"},
3197 },
3198 flags: []string{
3199 "-implicit-handshake",
3200 "-false-start",
3201 "-advertise-alpn", "\x03foo",
3202 },
3203 })
3204
3205 // False Start without session tickets.
3206 tests = append(tests, testCase{
3207 name: "FalseStart-SessionTicketsDisabled",
3208 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003209 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003210 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3211 NextProtos: []string{"foo"},
3212 SessionTicketsDisabled: true,
3213 Bugs: ProtocolBugs{
3214 ExpectFalseStart: true,
3215 },
3216 },
3217 flags: []string{
3218 "-false-start",
3219 "-select-next-proto", "foo",
3220 },
3221 shimWritesFirst: true,
3222 })
3223
Adam Langleydf759b52016-07-11 15:24:37 -07003224 tests = append(tests, testCase{
3225 name: "FalseStart-CECPQ1",
3226 config: Config{
3227 MaxVersion: VersionTLS12,
3228 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
3229 NextProtos: []string{"foo"},
3230 Bugs: ProtocolBugs{
3231 ExpectFalseStart: true,
3232 },
3233 },
3234 flags: []string{
3235 "-false-start",
3236 "-cipher", "DEFAULT:kCECPQ1",
3237 "-select-next-proto", "foo",
3238 },
3239 shimWritesFirst: true,
3240 resumeSession: true,
3241 })
3242
David Benjamin760b1dd2015-05-15 23:33:48 -04003243 // Server parses a V2ClientHello.
3244 tests = append(tests, testCase{
3245 testType: serverTest,
3246 name: "SendV2ClientHello",
3247 config: Config{
3248 // Choose a cipher suite that does not involve
3249 // elliptic curves, so no extensions are
3250 // involved.
Nick Harper1fd39d82016-06-14 18:14:35 -07003251 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003252 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
3253 Bugs: ProtocolBugs{
3254 SendV2ClientHello: true,
3255 },
3256 },
3257 })
3258
3259 // Client sends a Channel ID.
3260 tests = append(tests, testCase{
3261 name: "ChannelID-Client",
3262 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003263 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003264 RequestChannelID: true,
3265 },
Adam Langley7c803a62015-06-15 15:35:05 -07003266 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
David Benjamin760b1dd2015-05-15 23:33:48 -04003267 resumeSession: true,
3268 expectChannelID: true,
3269 })
3270
3271 // Server accepts a Channel ID.
3272 tests = append(tests, testCase{
3273 testType: serverTest,
3274 name: "ChannelID-Server",
3275 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003276 MaxVersion: VersionTLS12,
3277 ChannelID: channelIDKey,
David Benjamin760b1dd2015-05-15 23:33:48 -04003278 },
3279 flags: []string{
3280 "-expect-channel-id",
3281 base64.StdEncoding.EncodeToString(channelIDBytes),
3282 },
3283 resumeSession: true,
3284 expectChannelID: true,
3285 })
David Benjamin30789da2015-08-29 22:56:45 -04003286
David Benjaminf8fcdf32016-06-08 15:56:13 -04003287 // Channel ID and NPN at the same time, to ensure their relative
3288 // ordering is correct.
3289 tests = append(tests, testCase{
3290 name: "ChannelID-NPN-Client",
3291 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003292 MaxVersion: VersionTLS12,
David Benjaminf8fcdf32016-06-08 15:56:13 -04003293 RequestChannelID: true,
3294 NextProtos: []string{"foo"},
3295 },
3296 flags: []string{
3297 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
3298 "-select-next-proto", "foo",
3299 },
3300 resumeSession: true,
3301 expectChannelID: true,
3302 expectedNextProto: "foo",
3303 expectedNextProtoType: npn,
3304 })
3305 tests = append(tests, testCase{
3306 testType: serverTest,
3307 name: "ChannelID-NPN-Server",
3308 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003309 MaxVersion: VersionTLS12,
David Benjaminf8fcdf32016-06-08 15:56:13 -04003310 ChannelID: channelIDKey,
3311 NextProtos: []string{"bar"},
3312 },
3313 flags: []string{
3314 "-expect-channel-id",
3315 base64.StdEncoding.EncodeToString(channelIDBytes),
3316 "-advertise-npn", "\x03foo\x03bar\x03baz",
3317 "-expect-next-proto", "bar",
3318 },
3319 resumeSession: true,
3320 expectChannelID: true,
3321 expectedNextProto: "bar",
3322 expectedNextProtoType: npn,
3323 })
3324
David Benjamin30789da2015-08-29 22:56:45 -04003325 // Bidirectional shutdown with the runner initiating.
3326 tests = append(tests, testCase{
3327 name: "Shutdown-Runner",
3328 config: Config{
3329 Bugs: ProtocolBugs{
3330 ExpectCloseNotify: true,
3331 },
3332 },
3333 flags: []string{"-check-close-notify"},
3334 })
3335
3336 // Bidirectional shutdown with the shim initiating. The runner,
3337 // in the meantime, sends garbage before the close_notify which
3338 // the shim must ignore.
3339 tests = append(tests, testCase{
3340 name: "Shutdown-Shim",
3341 config: Config{
3342 Bugs: ProtocolBugs{
3343 ExpectCloseNotify: true,
3344 },
3345 },
3346 shimShutsDown: true,
3347 sendEmptyRecords: 1,
3348 sendWarningAlerts: 1,
3349 flags: []string{"-check-close-notify"},
3350 })
David Benjamin760b1dd2015-05-15 23:33:48 -04003351 } else {
David Benjamin4c3ddf72016-06-29 18:13:53 -04003352 // TODO(davidben): DTLS 1.3 will want a similar thing for
3353 // HelloRetryRequest.
David Benjamin760b1dd2015-05-15 23:33:48 -04003354 tests = append(tests, testCase{
3355 name: "SkipHelloVerifyRequest",
3356 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003357 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003358 Bugs: ProtocolBugs{
3359 SkipHelloVerifyRequest: true,
3360 },
3361 },
3362 })
3363 }
3364
David Benjamin760b1dd2015-05-15 23:33:48 -04003365 for _, test := range tests {
David Benjamin582ba042016-07-07 12:33:25 -07003366 test.protocol = config.protocol
3367 if config.protocol == dtls {
David Benjamin16285ea2015-11-03 15:39:45 -05003368 test.name += "-DTLS"
3369 }
David Benjamin582ba042016-07-07 12:33:25 -07003370 if config.async {
David Benjamin16285ea2015-11-03 15:39:45 -05003371 test.name += "-Async"
3372 test.flags = append(test.flags, "-async")
3373 } else {
3374 test.name += "-Sync"
3375 }
David Benjamin582ba042016-07-07 12:33:25 -07003376 if config.splitHandshake {
David Benjamin16285ea2015-11-03 15:39:45 -05003377 test.name += "-SplitHandshakeRecords"
3378 test.config.Bugs.MaxHandshakeRecordLength = 1
David Benjamin582ba042016-07-07 12:33:25 -07003379 if config.protocol == dtls {
David Benjamin16285ea2015-11-03 15:39:45 -05003380 test.config.Bugs.MaxPacketLength = 256
3381 test.flags = append(test.flags, "-mtu", "256")
3382 }
3383 }
David Benjamin582ba042016-07-07 12:33:25 -07003384 if config.packHandshakeFlight {
3385 test.name += "-PackHandshakeFlight"
3386 test.config.Bugs.PackHandshakeFlight = true
3387 }
David Benjamin760b1dd2015-05-15 23:33:48 -04003388 testCases = append(testCases, test)
David Benjamin6fd297b2014-08-11 18:43:38 -04003389 }
David Benjamin43ec06f2014-08-05 02:28:57 -04003390}
3391
Adam Langley524e7172015-02-20 16:04:00 -08003392func addDDoSCallbackTests() {
3393 // DDoS callback.
3394
3395 for _, resume := range []bool{false, true} {
3396 suffix := "Resume"
3397 if resume {
3398 suffix = "No" + suffix
3399 }
3400
David Benjamin4c3ddf72016-06-29 18:13:53 -04003401 // TODO(davidben): Test TLS 1.3's version of the DDoS callback.
3402
Adam Langley524e7172015-02-20 16:04:00 -08003403 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003404 testType: serverTest,
3405 name: "Server-DDoS-OK-" + suffix,
3406 config: Config{
3407 MaxVersion: VersionTLS12,
3408 },
Adam Langley524e7172015-02-20 16:04:00 -08003409 flags: []string{"-install-ddos-callback"},
3410 resumeSession: resume,
3411 })
3412
3413 failFlag := "-fail-ddos-callback"
3414 if resume {
3415 failFlag = "-fail-second-ddos-callback"
3416 }
3417 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003418 testType: serverTest,
3419 name: "Server-DDoS-Reject-" + suffix,
3420 config: Config{
3421 MaxVersion: VersionTLS12,
3422 },
Adam Langley524e7172015-02-20 16:04:00 -08003423 flags: []string{"-install-ddos-callback", failFlag},
3424 resumeSession: resume,
3425 shouldFail: true,
3426 expectedError: ":CONNECTION_REJECTED:",
3427 })
3428 }
3429}
3430
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003431func addVersionNegotiationTests() {
3432 for i, shimVers := range tlsVersions {
3433 // Assemble flags to disable all newer versions on the shim.
3434 var flags []string
3435 for _, vers := range tlsVersions[i+1:] {
3436 flags = append(flags, vers.flag)
3437 }
3438
3439 for _, runnerVers := range tlsVersions {
David Benjamin8b8c0062014-11-23 02:47:52 -05003440 protocols := []protocol{tls}
3441 if runnerVers.hasDTLS && shimVers.hasDTLS {
3442 protocols = append(protocols, dtls)
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003443 }
David Benjamin8b8c0062014-11-23 02:47:52 -05003444 for _, protocol := range protocols {
3445 expectedVersion := shimVers.version
3446 if runnerVers.version < shimVers.version {
3447 expectedVersion = runnerVers.version
3448 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003449
David Benjamin8b8c0062014-11-23 02:47:52 -05003450 suffix := shimVers.name + "-" + runnerVers.name
3451 if protocol == dtls {
3452 suffix += "-DTLS"
3453 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003454
David Benjamin1eb367c2014-12-12 18:17:51 -05003455 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
3456
David Benjamin1e29a6b2014-12-10 02:27:24 -05003457 clientVers := shimVers.version
3458 if clientVers > VersionTLS10 {
3459 clientVers = VersionTLS10
3460 }
Nick Harper1fd39d82016-06-14 18:14:35 -07003461 serverVers := expectedVersion
3462 if expectedVersion >= VersionTLS13 {
3463 serverVers = VersionTLS10
3464 }
David Benjamin8b8c0062014-11-23 02:47:52 -05003465 testCases = append(testCases, testCase{
3466 protocol: protocol,
3467 testType: clientTest,
3468 name: "VersionNegotiation-Client-" + suffix,
3469 config: Config{
3470 MaxVersion: runnerVers.version,
David Benjamin1e29a6b2014-12-10 02:27:24 -05003471 Bugs: ProtocolBugs{
3472 ExpectInitialRecordVersion: clientVers,
3473 },
David Benjamin8b8c0062014-11-23 02:47:52 -05003474 },
3475 flags: flags,
3476 expectedVersion: expectedVersion,
3477 })
David Benjamin1eb367c2014-12-12 18:17:51 -05003478 testCases = append(testCases, testCase{
3479 protocol: protocol,
3480 testType: clientTest,
3481 name: "VersionNegotiation-Client2-" + suffix,
3482 config: Config{
3483 MaxVersion: runnerVers.version,
3484 Bugs: ProtocolBugs{
3485 ExpectInitialRecordVersion: clientVers,
3486 },
3487 },
3488 flags: []string{"-max-version", shimVersFlag},
3489 expectedVersion: expectedVersion,
3490 })
David Benjamin8b8c0062014-11-23 02:47:52 -05003491
3492 testCases = append(testCases, testCase{
3493 protocol: protocol,
3494 testType: serverTest,
3495 name: "VersionNegotiation-Server-" + suffix,
3496 config: Config{
3497 MaxVersion: runnerVers.version,
David Benjamin1e29a6b2014-12-10 02:27:24 -05003498 Bugs: ProtocolBugs{
Nick Harper1fd39d82016-06-14 18:14:35 -07003499 ExpectInitialRecordVersion: serverVers,
David Benjamin1e29a6b2014-12-10 02:27:24 -05003500 },
David Benjamin8b8c0062014-11-23 02:47:52 -05003501 },
3502 flags: flags,
3503 expectedVersion: expectedVersion,
3504 })
David Benjamin1eb367c2014-12-12 18:17:51 -05003505 testCases = append(testCases, testCase{
3506 protocol: protocol,
3507 testType: serverTest,
3508 name: "VersionNegotiation-Server2-" + suffix,
3509 config: Config{
3510 MaxVersion: runnerVers.version,
3511 Bugs: ProtocolBugs{
Nick Harper1fd39d82016-06-14 18:14:35 -07003512 ExpectInitialRecordVersion: serverVers,
David Benjamin1eb367c2014-12-12 18:17:51 -05003513 },
3514 },
3515 flags: []string{"-max-version", shimVersFlag},
3516 expectedVersion: expectedVersion,
3517 })
David Benjamin8b8c0062014-11-23 02:47:52 -05003518 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003519 }
3520 }
David Benjamin95c69562016-06-29 18:15:03 -04003521
3522 // Test for version tolerance.
3523 testCases = append(testCases, testCase{
3524 testType: serverTest,
3525 name: "MinorVersionTolerance",
3526 config: Config{
3527 Bugs: ProtocolBugs{
3528 SendClientVersion: 0x03ff,
3529 },
3530 },
3531 expectedVersion: VersionTLS13,
3532 })
3533 testCases = append(testCases, testCase{
3534 testType: serverTest,
3535 name: "MajorVersionTolerance",
3536 config: Config{
3537 Bugs: ProtocolBugs{
3538 SendClientVersion: 0x0400,
3539 },
3540 },
3541 expectedVersion: VersionTLS13,
3542 })
3543 testCases = append(testCases, testCase{
3544 protocol: dtls,
3545 testType: serverTest,
3546 name: "MinorVersionTolerance-DTLS",
3547 config: Config{
3548 Bugs: ProtocolBugs{
3549 SendClientVersion: 0x03ff,
3550 },
3551 },
3552 expectedVersion: VersionTLS12,
3553 })
3554 testCases = append(testCases, testCase{
3555 protocol: dtls,
3556 testType: serverTest,
3557 name: "MajorVersionTolerance-DTLS",
3558 config: Config{
3559 Bugs: ProtocolBugs{
3560 SendClientVersion: 0x0400,
3561 },
3562 },
3563 expectedVersion: VersionTLS12,
3564 })
3565
3566 // Test that versions below 3.0 are rejected.
3567 testCases = append(testCases, testCase{
3568 testType: serverTest,
3569 name: "VersionTooLow",
3570 config: Config{
3571 Bugs: ProtocolBugs{
3572 SendClientVersion: 0x0200,
3573 },
3574 },
3575 shouldFail: true,
3576 expectedError: ":UNSUPPORTED_PROTOCOL:",
3577 })
3578 testCases = append(testCases, testCase{
3579 protocol: dtls,
3580 testType: serverTest,
3581 name: "VersionTooLow-DTLS",
3582 config: Config{
3583 Bugs: ProtocolBugs{
3584 // 0x0201 is the lowest version expressable in
3585 // DTLS.
3586 SendClientVersion: 0x0201,
3587 },
3588 },
3589 shouldFail: true,
3590 expectedError: ":UNSUPPORTED_PROTOCOL:",
3591 })
David Benjamin1f61f0d2016-07-10 12:20:35 -04003592
3593 // Test TLS 1.3's downgrade signal.
3594 testCases = append(testCases, testCase{
3595 name: "Downgrade-TLS12-Client",
3596 config: Config{
3597 Bugs: ProtocolBugs{
3598 NegotiateVersion: VersionTLS12,
3599 },
3600 },
3601 shouldFail: true,
3602 expectedError: ":DOWNGRADE_DETECTED:",
3603 })
3604 testCases = append(testCases, testCase{
3605 testType: serverTest,
3606 name: "Downgrade-TLS12-Server",
3607 config: Config{
3608 Bugs: ProtocolBugs{
3609 SendClientVersion: VersionTLS12,
3610 },
3611 },
3612 shouldFail: true,
3613 expectedLocalError: "tls: downgrade from TLS 1.3 detected",
3614 })
David Benjamin7e2e6cf2014-08-07 17:44:24 -04003615}
3616
David Benjaminaccb4542014-12-12 23:44:33 -05003617func addMinimumVersionTests() {
3618 for i, shimVers := range tlsVersions {
3619 // Assemble flags to disable all older versions on the shim.
3620 var flags []string
3621 for _, vers := range tlsVersions[:i] {
3622 flags = append(flags, vers.flag)
3623 }
3624
3625 for _, runnerVers := range tlsVersions {
3626 protocols := []protocol{tls}
3627 if runnerVers.hasDTLS && shimVers.hasDTLS {
3628 protocols = append(protocols, dtls)
3629 }
3630 for _, protocol := range protocols {
3631 suffix := shimVers.name + "-" + runnerVers.name
3632 if protocol == dtls {
3633 suffix += "-DTLS"
3634 }
3635 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
3636
David Benjaminaccb4542014-12-12 23:44:33 -05003637 var expectedVersion uint16
3638 var shouldFail bool
David Benjamin929d4ee2016-06-24 23:55:58 -04003639 var expectedClientError, expectedServerError string
3640 var expectedClientLocalError, expectedServerLocalError string
David Benjaminaccb4542014-12-12 23:44:33 -05003641 if runnerVers.version >= shimVers.version {
3642 expectedVersion = runnerVers.version
3643 } else {
3644 shouldFail = true
David Benjamin929d4ee2016-06-24 23:55:58 -04003645 expectedServerError = ":UNSUPPORTED_PROTOCOL:"
3646 expectedServerLocalError = "remote error: protocol version not supported"
3647 if shimVers.version >= VersionTLS13 && runnerVers.version <= VersionTLS11 {
3648 // If the client's minimum version is TLS 1.3 and the runner's
3649 // maximum is below TLS 1.2, the runner will fail to select a
3650 // cipher before the shim rejects the selected version.
3651 expectedClientError = ":SSLV3_ALERT_HANDSHAKE_FAILURE:"
3652 expectedClientLocalError = "tls: no cipher suite supported by both client and server"
3653 } else {
3654 expectedClientError = expectedServerError
3655 expectedClientLocalError = expectedServerLocalError
3656 }
David Benjaminaccb4542014-12-12 23:44:33 -05003657 }
3658
3659 testCases = append(testCases, testCase{
3660 protocol: protocol,
3661 testType: clientTest,
3662 name: "MinimumVersion-Client-" + suffix,
3663 config: Config{
3664 MaxVersion: runnerVers.version,
3665 },
David Benjamin87909c02014-12-13 01:55:01 -05003666 flags: flags,
3667 expectedVersion: expectedVersion,
3668 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003669 expectedError: expectedClientError,
3670 expectedLocalError: expectedClientLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003671 })
3672 testCases = append(testCases, testCase{
3673 protocol: protocol,
3674 testType: clientTest,
3675 name: "MinimumVersion-Client2-" + suffix,
3676 config: Config{
3677 MaxVersion: runnerVers.version,
3678 },
David Benjamin87909c02014-12-13 01:55:01 -05003679 flags: []string{"-min-version", shimVersFlag},
3680 expectedVersion: expectedVersion,
3681 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003682 expectedError: expectedClientError,
3683 expectedLocalError: expectedClientLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003684 })
3685
3686 testCases = append(testCases, testCase{
3687 protocol: protocol,
3688 testType: serverTest,
3689 name: "MinimumVersion-Server-" + suffix,
3690 config: Config{
3691 MaxVersion: runnerVers.version,
3692 },
David Benjamin87909c02014-12-13 01:55:01 -05003693 flags: flags,
3694 expectedVersion: expectedVersion,
3695 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003696 expectedError: expectedServerError,
3697 expectedLocalError: expectedServerLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003698 })
3699 testCases = append(testCases, testCase{
3700 protocol: protocol,
3701 testType: serverTest,
3702 name: "MinimumVersion-Server2-" + suffix,
3703 config: Config{
3704 MaxVersion: runnerVers.version,
3705 },
David Benjamin87909c02014-12-13 01:55:01 -05003706 flags: []string{"-min-version", shimVersFlag},
3707 expectedVersion: expectedVersion,
3708 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04003709 expectedError: expectedServerError,
3710 expectedLocalError: expectedServerLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05003711 })
3712 }
3713 }
3714 }
3715}
3716
David Benjamine78bfde2014-09-06 12:45:15 -04003717func addExtensionTests() {
David Benjamin4c3ddf72016-06-29 18:13:53 -04003718 // TODO(davidben): Extensions, where applicable, all move their server
3719 // halves to EncryptedExtensions in TLS 1.3. Duplicate each of these
3720 // tests for both. Also test interaction with 0-RTT when implemented.
3721
David Benjamin97d17d92016-07-14 16:12:00 -04003722 // Repeat extensions tests all versions except SSL 3.0.
3723 for _, ver := range tlsVersions {
3724 if ver.version == VersionSSL30 {
3725 continue
3726 }
3727
3728 // TODO(davidben): Implement resumption in TLS 1.3.
3729 resumeSession := ver.version < VersionTLS13
3730
3731 // Test that duplicate extensions are rejected.
3732 testCases = append(testCases, testCase{
3733 testType: clientTest,
3734 name: "DuplicateExtensionClient-" + ver.name,
3735 config: Config{
3736 MaxVersion: ver.version,
3737 Bugs: ProtocolBugs{
3738 DuplicateExtension: true,
3739 },
David Benjamine78bfde2014-09-06 12:45:15 -04003740 },
David Benjamin97d17d92016-07-14 16:12:00 -04003741 shouldFail: true,
3742 expectedLocalError: "remote error: error decoding message",
3743 })
3744 testCases = append(testCases, testCase{
3745 testType: serverTest,
3746 name: "DuplicateExtensionServer-" + ver.name,
3747 config: Config{
3748 MaxVersion: ver.version,
3749 Bugs: ProtocolBugs{
3750 DuplicateExtension: true,
3751 },
David Benjamine78bfde2014-09-06 12:45:15 -04003752 },
David Benjamin97d17d92016-07-14 16:12:00 -04003753 shouldFail: true,
3754 expectedLocalError: "remote error: error decoding message",
3755 })
3756
3757 // Test SNI.
3758 testCases = append(testCases, testCase{
3759 testType: clientTest,
3760 name: "ServerNameExtensionClient-" + ver.name,
3761 config: Config{
3762 MaxVersion: ver.version,
3763 Bugs: ProtocolBugs{
3764 ExpectServerName: "example.com",
3765 },
David Benjamine78bfde2014-09-06 12:45:15 -04003766 },
David Benjamin97d17d92016-07-14 16:12:00 -04003767 flags: []string{"-host-name", "example.com"},
3768 })
3769 testCases = append(testCases, testCase{
3770 testType: clientTest,
3771 name: "ServerNameExtensionClientMismatch-" + ver.name,
3772 config: Config{
3773 MaxVersion: ver.version,
3774 Bugs: ProtocolBugs{
3775 ExpectServerName: "mismatch.com",
3776 },
David Benjamine78bfde2014-09-06 12:45:15 -04003777 },
David Benjamin97d17d92016-07-14 16:12:00 -04003778 flags: []string{"-host-name", "example.com"},
3779 shouldFail: true,
3780 expectedLocalError: "tls: unexpected server name",
3781 })
3782 testCases = append(testCases, testCase{
3783 testType: clientTest,
3784 name: "ServerNameExtensionClientMissing-" + ver.name,
3785 config: Config{
3786 MaxVersion: ver.version,
3787 Bugs: ProtocolBugs{
3788 ExpectServerName: "missing.com",
3789 },
David Benjamine78bfde2014-09-06 12:45:15 -04003790 },
David Benjamin97d17d92016-07-14 16:12:00 -04003791 shouldFail: true,
3792 expectedLocalError: "tls: unexpected server name",
3793 })
3794 testCases = append(testCases, testCase{
3795 testType: serverTest,
3796 name: "ServerNameExtensionServer-" + ver.name,
3797 config: Config{
3798 MaxVersion: ver.version,
3799 ServerName: "example.com",
David Benjaminfc7b0862014-09-06 13:21:53 -04003800 },
David Benjamin97d17d92016-07-14 16:12:00 -04003801 flags: []string{"-expect-server-name", "example.com"},
3802 resumeSession: resumeSession,
3803 })
3804
3805 // Test ALPN.
3806 testCases = append(testCases, testCase{
3807 testType: clientTest,
3808 name: "ALPNClient-" + ver.name,
3809 config: Config{
3810 MaxVersion: ver.version,
3811 NextProtos: []string{"foo"},
3812 },
3813 flags: []string{
3814 "-advertise-alpn", "\x03foo\x03bar\x03baz",
3815 "-expect-alpn", "foo",
3816 },
3817 expectedNextProto: "foo",
3818 expectedNextProtoType: alpn,
3819 resumeSession: resumeSession,
3820 })
3821 testCases = append(testCases, testCase{
3822 testType: serverTest,
3823 name: "ALPNServer-" + ver.name,
3824 config: Config{
3825 MaxVersion: ver.version,
3826 NextProtos: []string{"foo", "bar", "baz"},
3827 },
3828 flags: []string{
3829 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
3830 "-select-alpn", "foo",
3831 },
3832 expectedNextProto: "foo",
3833 expectedNextProtoType: alpn,
3834 resumeSession: resumeSession,
3835 })
3836 testCases = append(testCases, testCase{
3837 testType: serverTest,
3838 name: "ALPNServer-Decline-" + ver.name,
3839 config: Config{
3840 MaxVersion: ver.version,
3841 NextProtos: []string{"foo", "bar", "baz"},
3842 },
3843 flags: []string{"-decline-alpn"},
3844 expectNoNextProto: true,
3845 resumeSession: resumeSession,
3846 })
3847
3848 var emptyString string
3849 testCases = append(testCases, testCase{
3850 testType: clientTest,
3851 name: "ALPNClient-EmptyProtocolName-" + ver.name,
3852 config: Config{
3853 MaxVersion: ver.version,
3854 NextProtos: []string{""},
3855 Bugs: ProtocolBugs{
3856 // A server returning an empty ALPN protocol
3857 // should be rejected.
3858 ALPNProtocol: &emptyString,
3859 },
3860 },
3861 flags: []string{
3862 "-advertise-alpn", "\x03foo",
3863 },
3864 shouldFail: true,
3865 expectedError: ":PARSE_TLSEXT:",
3866 })
3867 testCases = append(testCases, testCase{
3868 testType: serverTest,
3869 name: "ALPNServer-EmptyProtocolName-" + ver.name,
3870 config: Config{
3871 MaxVersion: ver.version,
3872 // A ClientHello containing an empty ALPN protocol
Adam Langleyefb0e162015-07-09 11:35:04 -07003873 // should be rejected.
David Benjamin97d17d92016-07-14 16:12:00 -04003874 NextProtos: []string{"foo", "", "baz"},
Adam Langleyefb0e162015-07-09 11:35:04 -07003875 },
David Benjamin97d17d92016-07-14 16:12:00 -04003876 flags: []string{
3877 "-select-alpn", "foo",
David Benjamin76c2efc2015-08-31 14:24:29 -04003878 },
David Benjamin97d17d92016-07-14 16:12:00 -04003879 shouldFail: true,
3880 expectedError: ":PARSE_TLSEXT:",
3881 })
3882
3883 // Test NPN and the interaction with ALPN.
3884 if ver.version < VersionTLS13 {
3885 // Test that the server prefers ALPN over NPN.
3886 testCases = append(testCases, testCase{
3887 testType: serverTest,
3888 name: "ALPNServer-Preferred-" + ver.name,
3889 config: Config{
3890 MaxVersion: ver.version,
3891 NextProtos: []string{"foo", "bar", "baz"},
3892 },
3893 flags: []string{
3894 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
3895 "-select-alpn", "foo",
3896 "-advertise-npn", "\x03foo\x03bar\x03baz",
3897 },
3898 expectedNextProto: "foo",
3899 expectedNextProtoType: alpn,
3900 resumeSession: resumeSession,
3901 })
3902 testCases = append(testCases, testCase{
3903 testType: serverTest,
3904 name: "ALPNServer-Preferred-Swapped-" + ver.name,
3905 config: Config{
3906 MaxVersion: ver.version,
3907 NextProtos: []string{"foo", "bar", "baz"},
3908 Bugs: ProtocolBugs{
3909 SwapNPNAndALPN: true,
3910 },
3911 },
3912 flags: []string{
3913 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
3914 "-select-alpn", "foo",
3915 "-advertise-npn", "\x03foo\x03bar\x03baz",
3916 },
3917 expectedNextProto: "foo",
3918 expectedNextProtoType: alpn,
3919 resumeSession: resumeSession,
3920 })
3921
3922 // Test that negotiating both NPN and ALPN is forbidden.
3923 testCases = append(testCases, testCase{
3924 name: "NegotiateALPNAndNPN-" + ver.name,
3925 config: Config{
3926 MaxVersion: ver.version,
3927 NextProtos: []string{"foo", "bar", "baz"},
3928 Bugs: ProtocolBugs{
3929 NegotiateALPNAndNPN: true,
3930 },
3931 },
3932 flags: []string{
3933 "-advertise-alpn", "\x03foo",
3934 "-select-next-proto", "foo",
3935 },
3936 shouldFail: true,
3937 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
3938 })
3939 testCases = append(testCases, testCase{
3940 name: "NegotiateALPNAndNPN-Swapped-" + ver.name,
3941 config: Config{
3942 MaxVersion: ver.version,
3943 NextProtos: []string{"foo", "bar", "baz"},
3944 Bugs: ProtocolBugs{
3945 NegotiateALPNAndNPN: true,
3946 SwapNPNAndALPN: true,
3947 },
3948 },
3949 flags: []string{
3950 "-advertise-alpn", "\x03foo",
3951 "-select-next-proto", "foo",
3952 },
3953 shouldFail: true,
3954 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
3955 })
3956
3957 // Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
3958 testCases = append(testCases, testCase{
3959 name: "DisableNPN-" + ver.name,
3960 config: Config{
3961 MaxVersion: ver.version,
3962 NextProtos: []string{"foo"},
3963 },
3964 flags: []string{
3965 "-select-next-proto", "foo",
3966 "-disable-npn",
3967 },
3968 expectNoNextProto: true,
3969 })
3970 }
3971
3972 // Test ticket behavior.
3973 //
3974 // TODO(davidben): Add TLS 1.3 versions of these.
3975 if ver.version < VersionTLS13 {
3976 // Resume with a corrupt ticket.
3977 testCases = append(testCases, testCase{
3978 testType: serverTest,
3979 name: "CorruptTicket-" + ver.name,
3980 config: Config{
3981 MaxVersion: ver.version,
3982 Bugs: ProtocolBugs{
3983 CorruptTicket: true,
3984 },
3985 },
3986 resumeSession: true,
3987 expectResumeRejected: true,
3988 })
3989 // Test the ticket callback, with and without renewal.
3990 testCases = append(testCases, testCase{
3991 testType: serverTest,
3992 name: "TicketCallback-" + ver.name,
3993 config: Config{
3994 MaxVersion: ver.version,
3995 },
3996 resumeSession: true,
3997 flags: []string{"-use-ticket-callback"},
3998 })
3999 testCases = append(testCases, testCase{
4000 testType: serverTest,
4001 name: "TicketCallback-Renew-" + ver.name,
4002 config: Config{
4003 MaxVersion: ver.version,
4004 Bugs: ProtocolBugs{
4005 ExpectNewTicket: true,
4006 },
4007 },
4008 flags: []string{"-use-ticket-callback", "-renew-ticket"},
4009 resumeSession: true,
4010 })
4011
4012 // Resume with an oversized session id.
4013 testCases = append(testCases, testCase{
4014 testType: serverTest,
4015 name: "OversizedSessionId-" + ver.name,
4016 config: Config{
4017 MaxVersion: ver.version,
4018 Bugs: ProtocolBugs{
4019 OversizedSessionId: true,
4020 },
4021 },
4022 resumeSession: true,
4023 shouldFail: true,
4024 expectedError: ":DECODE_ERROR:",
4025 })
4026 }
4027
4028 // Basic DTLS-SRTP tests. Include fake profiles to ensure they
4029 // are ignored.
4030 if ver.hasDTLS {
4031 testCases = append(testCases, testCase{
4032 protocol: dtls,
4033 name: "SRTP-Client-" + ver.name,
4034 config: Config{
4035 MaxVersion: ver.version,
4036 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
4037 },
4038 flags: []string{
4039 "-srtp-profiles",
4040 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4041 },
4042 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
4043 })
4044 testCases = append(testCases, testCase{
4045 protocol: dtls,
4046 testType: serverTest,
4047 name: "SRTP-Server-" + ver.name,
4048 config: Config{
4049 MaxVersion: ver.version,
4050 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
4051 },
4052 flags: []string{
4053 "-srtp-profiles",
4054 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4055 },
4056 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
4057 })
4058 // Test that the MKI is ignored.
4059 testCases = append(testCases, testCase{
4060 protocol: dtls,
4061 testType: serverTest,
4062 name: "SRTP-Server-IgnoreMKI-" + ver.name,
4063 config: Config{
4064 MaxVersion: ver.version,
4065 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80},
4066 Bugs: ProtocolBugs{
4067 SRTPMasterKeyIdentifer: "bogus",
4068 },
4069 },
4070 flags: []string{
4071 "-srtp-profiles",
4072 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4073 },
4074 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
4075 })
4076 // Test that SRTP isn't negotiated on the server if there were
4077 // no matching profiles.
4078 testCases = append(testCases, testCase{
4079 protocol: dtls,
4080 testType: serverTest,
4081 name: "SRTP-Server-NoMatch-" + ver.name,
4082 config: Config{
4083 MaxVersion: ver.version,
4084 SRTPProtectionProfiles: []uint16{100, 101, 102},
4085 },
4086 flags: []string{
4087 "-srtp-profiles",
4088 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4089 },
4090 expectedSRTPProtectionProfile: 0,
4091 })
4092 // Test that the server returning an invalid SRTP profile is
4093 // flagged as an error by the client.
4094 testCases = append(testCases, testCase{
4095 protocol: dtls,
4096 name: "SRTP-Client-NoMatch-" + ver.name,
4097 config: Config{
4098 MaxVersion: ver.version,
4099 Bugs: ProtocolBugs{
4100 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32,
4101 },
4102 },
4103 flags: []string{
4104 "-srtp-profiles",
4105 "SRTP_AES128_CM_SHA1_80",
4106 },
4107 shouldFail: true,
4108 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
4109 })
4110 }
4111
4112 // Test SCT list.
4113 testCases = append(testCases, testCase{
4114 name: "SignedCertificateTimestampList-Client-" + ver.name,
4115 testType: clientTest,
4116 config: Config{
4117 MaxVersion: ver.version,
David Benjamin76c2efc2015-08-31 14:24:29 -04004118 },
David Benjamin97d17d92016-07-14 16:12:00 -04004119 flags: []string{
4120 "-enable-signed-cert-timestamps",
4121 "-expect-signed-cert-timestamps",
4122 base64.StdEncoding.EncodeToString(testSCTList),
Adam Langley38311732014-10-16 19:04:35 -07004123 },
David Benjamin97d17d92016-07-14 16:12:00 -04004124 resumeSession: resumeSession,
4125 })
4126 testCases = append(testCases, testCase{
4127 name: "SendSCTListOnResume-" + ver.name,
4128 config: Config{
4129 MaxVersion: ver.version,
4130 Bugs: ProtocolBugs{
4131 SendSCTListOnResume: []byte("bogus"),
4132 },
David Benjamind98452d2015-06-16 14:16:23 -04004133 },
David Benjamin97d17d92016-07-14 16:12:00 -04004134 flags: []string{
4135 "-enable-signed-cert-timestamps",
4136 "-expect-signed-cert-timestamps",
4137 base64.StdEncoding.EncodeToString(testSCTList),
Adam Langley38311732014-10-16 19:04:35 -07004138 },
David Benjamin97d17d92016-07-14 16:12:00 -04004139 resumeSession: resumeSession,
4140 })
4141 testCases = append(testCases, testCase{
4142 name: "SignedCertificateTimestampList-Server-" + ver.name,
4143 testType: serverTest,
4144 config: Config{
4145 MaxVersion: ver.version,
David Benjaminca6c8262014-11-15 19:06:08 -05004146 },
David Benjamin97d17d92016-07-14 16:12:00 -04004147 flags: []string{
4148 "-signed-cert-timestamps",
4149 base64.StdEncoding.EncodeToString(testSCTList),
David Benjaminca6c8262014-11-15 19:06:08 -05004150 },
David Benjamin97d17d92016-07-14 16:12:00 -04004151 expectedSCTList: testSCTList,
4152 resumeSession: resumeSession,
4153 })
4154 }
David Benjamin4c3ddf72016-06-29 18:13:53 -04004155
Paul Lietar4fac72e2015-09-09 13:44:55 +01004156 testCases = append(testCases, testCase{
Adam Langley33ad2b52015-07-20 17:43:53 -07004157 testType: clientTest,
4158 name: "ClientHelloPadding",
4159 config: Config{
4160 Bugs: ProtocolBugs{
4161 RequireClientHelloSize: 512,
4162 },
4163 },
4164 // This hostname just needs to be long enough to push the
4165 // ClientHello into F5's danger zone between 256 and 511 bytes
4166 // long.
4167 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
4168 })
David Benjaminc7ce9772015-10-09 19:32:41 -04004169
4170 // Extensions should not function in SSL 3.0.
4171 testCases = append(testCases, testCase{
4172 testType: serverTest,
4173 name: "SSLv3Extensions-NoALPN",
4174 config: Config{
4175 MaxVersion: VersionSSL30,
4176 NextProtos: []string{"foo", "bar", "baz"},
4177 },
4178 flags: []string{
4179 "-select-alpn", "foo",
4180 },
4181 expectNoNextProto: true,
4182 })
4183
4184 // Test session tickets separately as they follow a different codepath.
4185 testCases = append(testCases, testCase{
4186 testType: serverTest,
4187 name: "SSLv3Extensions-NoTickets",
4188 config: Config{
4189 MaxVersion: VersionSSL30,
4190 Bugs: ProtocolBugs{
4191 // Historically, session tickets in SSL 3.0
4192 // failed in different ways depending on whether
4193 // the client supported renegotiation_info.
4194 NoRenegotiationInfo: true,
4195 },
4196 },
4197 resumeSession: true,
4198 })
4199 testCases = append(testCases, testCase{
4200 testType: serverTest,
4201 name: "SSLv3Extensions-NoTickets2",
4202 config: Config{
4203 MaxVersion: VersionSSL30,
4204 },
4205 resumeSession: true,
4206 })
4207
4208 // But SSL 3.0 does send and process renegotiation_info.
4209 testCases = append(testCases, testCase{
4210 testType: serverTest,
4211 name: "SSLv3Extensions-RenegotiationInfo",
4212 config: Config{
4213 MaxVersion: VersionSSL30,
4214 Bugs: ProtocolBugs{
4215 RequireRenegotiationInfo: true,
4216 },
4217 },
4218 })
4219 testCases = append(testCases, testCase{
4220 testType: serverTest,
4221 name: "SSLv3Extensions-RenegotiationInfo-SCSV",
4222 config: Config{
4223 MaxVersion: VersionSSL30,
4224 Bugs: ProtocolBugs{
4225 NoRenegotiationInfo: true,
4226 SendRenegotiationSCSV: true,
4227 RequireRenegotiationInfo: true,
4228 },
4229 },
4230 })
David Benjamine78bfde2014-09-06 12:45:15 -04004231}
4232
David Benjamin01fe8202014-09-24 15:21:44 -04004233func addResumptionVersionTests() {
David Benjamin01fe8202014-09-24 15:21:44 -04004234 for _, sessionVers := range tlsVersions {
David Benjamin6e6abe12016-07-13 20:57:22 -04004235 // TODO(davidben,svaldez): Implement resumption in TLS 1.3.
4236 if sessionVers.version >= VersionTLS13 {
4237 continue
4238 }
David Benjamin01fe8202014-09-24 15:21:44 -04004239 for _, resumeVers := range tlsVersions {
David Benjamin6e6abe12016-07-13 20:57:22 -04004240 if resumeVers.version >= VersionTLS13 {
4241 continue
4242 }
Nick Harper1fd39d82016-06-14 18:14:35 -07004243 cipher := TLS_RSA_WITH_AES_128_CBC_SHA
4244 if sessionVers.version >= VersionTLS13 || resumeVers.version >= VersionTLS13 {
4245 // TLS 1.3 only shares ciphers with TLS 1.2, so
4246 // we skip certain combinations and use a
4247 // different cipher to test with.
4248 cipher = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
4249 if sessionVers.version < VersionTLS12 || resumeVers.version < VersionTLS12 {
4250 continue
4251 }
4252 }
4253
David Benjamin8b8c0062014-11-23 02:47:52 -05004254 protocols := []protocol{tls}
4255 if sessionVers.hasDTLS && resumeVers.hasDTLS {
4256 protocols = append(protocols, dtls)
David Benjaminbdf5e722014-11-11 00:52:15 -05004257 }
David Benjamin8b8c0062014-11-23 02:47:52 -05004258 for _, protocol := range protocols {
4259 suffix := "-" + sessionVers.name + "-" + resumeVers.name
4260 if protocol == dtls {
4261 suffix += "-DTLS"
4262 }
4263
David Benjaminece3de92015-03-16 18:02:20 -04004264 if sessionVers.version == resumeVers.version {
4265 testCases = append(testCases, testCase{
4266 protocol: protocol,
4267 name: "Resume-Client" + suffix,
4268 resumeSession: true,
4269 config: Config{
4270 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004271 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004272 },
David Benjaminece3de92015-03-16 18:02:20 -04004273 expectedVersion: sessionVers.version,
4274 expectedResumeVersion: resumeVers.version,
4275 })
4276 } else {
4277 testCases = append(testCases, testCase{
4278 protocol: protocol,
4279 name: "Resume-Client-Mismatch" + suffix,
4280 resumeSession: true,
4281 config: Config{
4282 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004283 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004284 },
David Benjaminece3de92015-03-16 18:02:20 -04004285 expectedVersion: sessionVers.version,
4286 resumeConfig: &Config{
4287 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004288 CipherSuites: []uint16{cipher},
David Benjaminece3de92015-03-16 18:02:20 -04004289 Bugs: ProtocolBugs{
4290 AllowSessionVersionMismatch: true,
4291 },
4292 },
4293 expectedResumeVersion: resumeVers.version,
4294 shouldFail: true,
4295 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:",
4296 })
4297 }
David Benjamin8b8c0062014-11-23 02:47:52 -05004298
4299 testCases = append(testCases, testCase{
4300 protocol: protocol,
4301 name: "Resume-Client-NoResume" + suffix,
David Benjamin8b8c0062014-11-23 02:47:52 -05004302 resumeSession: true,
4303 config: Config{
4304 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004305 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004306 },
4307 expectedVersion: sessionVers.version,
4308 resumeConfig: &Config{
4309 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004310 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004311 },
4312 newSessionsOnResume: true,
Adam Langleyb0eef0a2015-06-02 10:47:39 -07004313 expectResumeRejected: true,
David Benjamin8b8c0062014-11-23 02:47:52 -05004314 expectedResumeVersion: resumeVers.version,
4315 })
4316
David Benjamin8b8c0062014-11-23 02:47:52 -05004317 testCases = append(testCases, testCase{
4318 protocol: protocol,
4319 testType: serverTest,
4320 name: "Resume-Server" + suffix,
David Benjamin8b8c0062014-11-23 02:47:52 -05004321 resumeSession: true,
4322 config: Config{
4323 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004324 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004325 },
Adam Langleyb0eef0a2015-06-02 10:47:39 -07004326 expectedVersion: sessionVers.version,
4327 expectResumeRejected: sessionVers.version != resumeVers.version,
David Benjamin8b8c0062014-11-23 02:47:52 -05004328 resumeConfig: &Config{
4329 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07004330 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05004331 },
4332 expectedResumeVersion: resumeVers.version,
4333 })
4334 }
David Benjamin01fe8202014-09-24 15:21:44 -04004335 }
4336 }
David Benjaminece3de92015-03-16 18:02:20 -04004337
Nick Harper1fd39d82016-06-14 18:14:35 -07004338 // TODO(davidben): This test should have a TLS 1.3 variant later.
David Benjaminece3de92015-03-16 18:02:20 -04004339 testCases = append(testCases, testCase{
4340 name: "Resume-Client-CipherMismatch",
4341 resumeSession: true,
4342 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004343 MaxVersion: VersionTLS12,
David Benjaminece3de92015-03-16 18:02:20 -04004344 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
4345 },
4346 resumeConfig: &Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004347 MaxVersion: VersionTLS12,
David Benjaminece3de92015-03-16 18:02:20 -04004348 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
4349 Bugs: ProtocolBugs{
4350 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA,
4351 },
4352 },
4353 shouldFail: true,
4354 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
4355 })
David Benjamin01fe8202014-09-24 15:21:44 -04004356}
4357
Adam Langley2ae77d22014-10-28 17:29:33 -07004358func addRenegotiationTests() {
David Benjamin44d3eed2015-05-21 01:29:55 -04004359 // Servers cannot renegotiate.
David Benjaminb16346b2015-04-08 19:16:58 -04004360 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004361 testType: serverTest,
4362 name: "Renegotiate-Server-Forbidden",
4363 config: Config{
4364 MaxVersion: VersionTLS12,
4365 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004366 renegotiate: 1,
David Benjaminb16346b2015-04-08 19:16:58 -04004367 shouldFail: true,
4368 expectedError: ":NO_RENEGOTIATION:",
4369 expectedLocalError: "remote error: no renegotiation",
4370 })
Adam Langley5021b222015-06-12 18:27:58 -07004371 // The server shouldn't echo the renegotiation extension unless
4372 // requested by the client.
4373 testCases = append(testCases, testCase{
4374 testType: serverTest,
4375 name: "Renegotiate-Server-NoExt",
4376 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004377 MaxVersion: VersionTLS12,
Adam Langley5021b222015-06-12 18:27:58 -07004378 Bugs: ProtocolBugs{
4379 NoRenegotiationInfo: true,
4380 RequireRenegotiationInfo: true,
4381 },
4382 },
4383 shouldFail: true,
4384 expectedLocalError: "renegotiation extension missing",
4385 })
4386 // The renegotiation SCSV should be sufficient for the server to echo
4387 // the extension.
4388 testCases = append(testCases, testCase{
4389 testType: serverTest,
4390 name: "Renegotiate-Server-NoExt-SCSV",
4391 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004392 MaxVersion: VersionTLS12,
Adam Langley5021b222015-06-12 18:27:58 -07004393 Bugs: ProtocolBugs{
4394 NoRenegotiationInfo: true,
4395 SendRenegotiationSCSV: true,
4396 RequireRenegotiationInfo: true,
4397 },
4398 },
4399 })
Adam Langleycf2d4f42014-10-28 19:06:14 -07004400 testCases = append(testCases, testCase{
David Benjamin4b27d9f2015-05-12 22:42:52 -04004401 name: "Renegotiate-Client",
David Benjamincdea40c2015-03-19 14:09:43 -04004402 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004403 MaxVersion: VersionTLS12,
David Benjamincdea40c2015-03-19 14:09:43 -04004404 Bugs: ProtocolBugs{
David Benjamin4b27d9f2015-05-12 22:42:52 -04004405 FailIfResumeOnRenego: true,
David Benjamincdea40c2015-03-19 14:09:43 -04004406 },
4407 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004408 renegotiate: 1,
4409 flags: []string{
4410 "-renegotiate-freely",
4411 "-expect-total-renegotiations", "1",
4412 },
David Benjamincdea40c2015-03-19 14:09:43 -04004413 })
4414 testCases = append(testCases, testCase{
Adam Langleycf2d4f42014-10-28 19:06:14 -07004415 name: "Renegotiate-Client-EmptyExt",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004416 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004417 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004418 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004419 Bugs: ProtocolBugs{
4420 EmptyRenegotiationInfo: true,
4421 },
4422 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004423 flags: []string{"-renegotiate-freely"},
Adam Langleycf2d4f42014-10-28 19:06:14 -07004424 shouldFail: true,
4425 expectedError: ":RENEGOTIATION_MISMATCH:",
4426 })
4427 testCases = append(testCases, testCase{
4428 name: "Renegotiate-Client-BadExt",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004429 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004430 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004431 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004432 Bugs: ProtocolBugs{
4433 BadRenegotiationInfo: true,
4434 },
4435 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004436 flags: []string{"-renegotiate-freely"},
Adam Langleycf2d4f42014-10-28 19:06:14 -07004437 shouldFail: true,
4438 expectedError: ":RENEGOTIATION_MISMATCH:",
4439 })
4440 testCases = append(testCases, testCase{
David Benjamin3e052de2015-11-25 20:10:31 -05004441 name: "Renegotiate-Client-Downgrade",
4442 renegotiate: 1,
4443 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004444 MaxVersion: VersionTLS12,
David Benjamin3e052de2015-11-25 20:10:31 -05004445 Bugs: ProtocolBugs{
4446 NoRenegotiationInfoAfterInitial: true,
4447 },
4448 },
4449 flags: []string{"-renegotiate-freely"},
4450 shouldFail: true,
4451 expectedError: ":RENEGOTIATION_MISMATCH:",
4452 })
4453 testCases = append(testCases, testCase{
4454 name: "Renegotiate-Client-Upgrade",
4455 renegotiate: 1,
4456 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004457 MaxVersion: VersionTLS12,
David Benjamin3e052de2015-11-25 20:10:31 -05004458 Bugs: ProtocolBugs{
4459 NoRenegotiationInfoInInitial: true,
4460 },
4461 },
4462 flags: []string{"-renegotiate-freely"},
4463 shouldFail: true,
4464 expectedError: ":RENEGOTIATION_MISMATCH:",
4465 })
4466 testCases = append(testCases, testCase{
David Benjamincff0b902015-05-15 23:09:47 -04004467 name: "Renegotiate-Client-NoExt-Allowed",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004468 renegotiate: 1,
David Benjamincff0b902015-05-15 23:09:47 -04004469 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004470 MaxVersion: VersionTLS12,
David Benjamincff0b902015-05-15 23:09:47 -04004471 Bugs: ProtocolBugs{
4472 NoRenegotiationInfo: true,
4473 },
4474 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004475 flags: []string{
4476 "-renegotiate-freely",
4477 "-expect-total-renegotiations", "1",
4478 },
David Benjamincff0b902015-05-15 23:09:47 -04004479 })
4480 testCases = append(testCases, testCase{
Adam Langleycf2d4f42014-10-28 19:06:14 -07004481 name: "Renegotiate-Client-SwitchCiphers",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004482 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004483 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004484 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004485 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
4486 },
4487 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004488 flags: []string{
4489 "-renegotiate-freely",
4490 "-expect-total-renegotiations", "1",
4491 },
Adam Langleycf2d4f42014-10-28 19:06:14 -07004492 })
4493 testCases = append(testCases, testCase{
4494 name: "Renegotiate-Client-SwitchCiphers2",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004495 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004496 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004497 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07004498 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4499 },
4500 renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004501 flags: []string{
4502 "-renegotiate-freely",
4503 "-expect-total-renegotiations", "1",
4504 },
David Benjaminb16346b2015-04-08 19:16:58 -04004505 })
4506 testCases = append(testCases, testCase{
David Benjaminc44b1df2014-11-23 12:11:01 -05004507 name: "Renegotiate-SameClientVersion",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004508 renegotiate: 1,
David Benjaminc44b1df2014-11-23 12:11:01 -05004509 config: Config{
4510 MaxVersion: VersionTLS10,
4511 Bugs: ProtocolBugs{
4512 RequireSameRenegoClientVersion: true,
4513 },
4514 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004515 flags: []string{
4516 "-renegotiate-freely",
4517 "-expect-total-renegotiations", "1",
4518 },
David Benjaminc44b1df2014-11-23 12:11:01 -05004519 })
Adam Langleyb558c4c2015-07-08 12:16:38 -07004520 testCases = append(testCases, testCase{
4521 name: "Renegotiate-FalseStart",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004522 renegotiate: 1,
Adam Langleyb558c4c2015-07-08 12:16:38 -07004523 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07004524 MaxVersion: VersionTLS12,
Adam Langleyb558c4c2015-07-08 12:16:38 -07004525 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
4526 NextProtos: []string{"foo"},
4527 },
4528 flags: []string{
4529 "-false-start",
4530 "-select-next-proto", "foo",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004531 "-renegotiate-freely",
David Benjamin324dce42015-10-12 19:49:00 -04004532 "-expect-total-renegotiations", "1",
Adam Langleyb558c4c2015-07-08 12:16:38 -07004533 },
4534 shimWritesFirst: true,
4535 })
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004536
4537 // Client-side renegotiation controls.
4538 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004539 name: "Renegotiate-Client-Forbidden-1",
4540 config: Config{
4541 MaxVersion: VersionTLS12,
4542 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004543 renegotiate: 1,
4544 shouldFail: true,
4545 expectedError: ":NO_RENEGOTIATION:",
4546 expectedLocalError: "remote error: no renegotiation",
4547 })
4548 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004549 name: "Renegotiate-Client-Once-1",
4550 config: Config{
4551 MaxVersion: VersionTLS12,
4552 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004553 renegotiate: 1,
4554 flags: []string{
4555 "-renegotiate-once",
4556 "-expect-total-renegotiations", "1",
4557 },
4558 })
4559 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004560 name: "Renegotiate-Client-Freely-1",
4561 config: Config{
4562 MaxVersion: VersionTLS12,
4563 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004564 renegotiate: 1,
4565 flags: []string{
4566 "-renegotiate-freely",
4567 "-expect-total-renegotiations", "1",
4568 },
4569 })
4570 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004571 name: "Renegotiate-Client-Once-2",
4572 config: Config{
4573 MaxVersion: VersionTLS12,
4574 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004575 renegotiate: 2,
4576 flags: []string{"-renegotiate-once"},
4577 shouldFail: true,
4578 expectedError: ":NO_RENEGOTIATION:",
4579 expectedLocalError: "remote error: no renegotiation",
4580 })
4581 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004582 name: "Renegotiate-Client-Freely-2",
4583 config: Config{
4584 MaxVersion: VersionTLS12,
4585 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04004586 renegotiate: 2,
4587 flags: []string{
4588 "-renegotiate-freely",
4589 "-expect-total-renegotiations", "2",
4590 },
4591 })
Adam Langley27a0d082015-11-03 13:34:10 -08004592 testCases = append(testCases, testCase{
4593 name: "Renegotiate-Client-NoIgnore",
4594 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004595 MaxVersion: VersionTLS12,
Adam Langley27a0d082015-11-03 13:34:10 -08004596 Bugs: ProtocolBugs{
4597 SendHelloRequestBeforeEveryAppDataRecord: true,
4598 },
4599 },
4600 shouldFail: true,
4601 expectedError: ":NO_RENEGOTIATION:",
4602 })
4603 testCases = append(testCases, testCase{
4604 name: "Renegotiate-Client-Ignore",
4605 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004606 MaxVersion: VersionTLS12,
Adam Langley27a0d082015-11-03 13:34:10 -08004607 Bugs: ProtocolBugs{
4608 SendHelloRequestBeforeEveryAppDataRecord: true,
4609 },
4610 },
4611 flags: []string{
4612 "-renegotiate-ignore",
4613 "-expect-total-renegotiations", "0",
4614 },
4615 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04004616
David Benjamin397c8e62016-07-08 14:14:36 -07004617 // Stray HelloRequests during the handshake are ignored in TLS 1.2.
David Benjamin71dd6662016-07-08 14:10:48 -07004618 testCases = append(testCases, testCase{
4619 name: "StrayHelloRequest",
4620 config: Config{
4621 MaxVersion: VersionTLS12,
4622 Bugs: ProtocolBugs{
4623 SendHelloRequestBeforeEveryHandshakeMessage: true,
4624 },
4625 },
4626 })
4627 testCases = append(testCases, testCase{
4628 name: "StrayHelloRequest-Packed",
4629 config: Config{
4630 MaxVersion: VersionTLS12,
4631 Bugs: ProtocolBugs{
4632 PackHandshakeFlight: true,
4633 SendHelloRequestBeforeEveryHandshakeMessage: true,
4634 },
4635 },
4636 })
4637
David Benjamin397c8e62016-07-08 14:14:36 -07004638 // Renegotiation is forbidden in TLS 1.3.
4639 testCases = append(testCases, testCase{
4640 name: "Renegotiate-Client-TLS13",
4641 config: Config{
4642 MaxVersion: VersionTLS13,
4643 },
4644 renegotiate: 1,
4645 flags: []string{
4646 "-renegotiate-freely",
4647 },
4648 shouldFail: true,
4649 expectedError: ":NO_RENEGOTIATION:",
4650 })
4651
4652 // Stray HelloRequests during the handshake are forbidden in TLS 1.3.
4653 testCases = append(testCases, testCase{
4654 name: "StrayHelloRequest-TLS13",
4655 config: Config{
4656 MaxVersion: VersionTLS13,
4657 Bugs: ProtocolBugs{
4658 SendHelloRequestBeforeEveryHandshakeMessage: true,
4659 },
4660 },
4661 shouldFail: true,
4662 expectedError: ":UNEXPECTED_MESSAGE:",
4663 })
Adam Langley2ae77d22014-10-28 17:29:33 -07004664}
4665
David Benjamin5e961c12014-11-07 01:48:35 -05004666func addDTLSReplayTests() {
4667 // Test that sequence number replays are detected.
4668 testCases = append(testCases, testCase{
4669 protocol: dtls,
4670 name: "DTLS-Replay",
David Benjamin8e6db492015-07-25 18:29:23 -04004671 messageCount: 200,
David Benjamin5e961c12014-11-07 01:48:35 -05004672 replayWrites: true,
4673 })
4674
David Benjamin8e6db492015-07-25 18:29:23 -04004675 // Test the incoming sequence number skipping by values larger
David Benjamin5e961c12014-11-07 01:48:35 -05004676 // than the retransmit window.
4677 testCases = append(testCases, testCase{
4678 protocol: dtls,
4679 name: "DTLS-Replay-LargeGaps",
4680 config: Config{
4681 Bugs: ProtocolBugs{
David Benjamin8e6db492015-07-25 18:29:23 -04004682 SequenceNumberMapping: func(in uint64) uint64 {
4683 return in * 127
4684 },
David Benjamin5e961c12014-11-07 01:48:35 -05004685 },
4686 },
David Benjamin8e6db492015-07-25 18:29:23 -04004687 messageCount: 200,
4688 replayWrites: true,
4689 })
4690
4691 // Test the incoming sequence number changing non-monotonically.
4692 testCases = append(testCases, testCase{
4693 protocol: dtls,
4694 name: "DTLS-Replay-NonMonotonic",
4695 config: Config{
4696 Bugs: ProtocolBugs{
4697 SequenceNumberMapping: func(in uint64) uint64 {
4698 return in ^ 31
4699 },
4700 },
4701 },
4702 messageCount: 200,
David Benjamin5e961c12014-11-07 01:48:35 -05004703 replayWrites: true,
4704 })
4705}
4706
Nick Harper60edffd2016-06-21 15:19:24 -07004707var testSignatureAlgorithms = []struct {
David Benjamin000800a2014-11-14 01:43:59 -05004708 name string
Nick Harper60edffd2016-06-21 15:19:24 -07004709 id signatureAlgorithm
4710 cert testCert
David Benjamin000800a2014-11-14 01:43:59 -05004711}{
Nick Harper60edffd2016-06-21 15:19:24 -07004712 {"RSA-PKCS1-SHA1", signatureRSAPKCS1WithSHA1, testCertRSA},
4713 {"RSA-PKCS1-SHA256", signatureRSAPKCS1WithSHA256, testCertRSA},
4714 {"RSA-PKCS1-SHA384", signatureRSAPKCS1WithSHA384, testCertRSA},
4715 {"RSA-PKCS1-SHA512", signatureRSAPKCS1WithSHA512, testCertRSA},
David Benjamin33863262016-07-08 17:20:12 -07004716 {"ECDSA-SHA1", signatureECDSAWithSHA1, testCertECDSAP256},
David Benjamin33863262016-07-08 17:20:12 -07004717 {"ECDSA-P256-SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256},
4718 {"ECDSA-P384-SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384},
4719 {"ECDSA-P521-SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521},
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004720 {"RSA-PSS-SHA256", signatureRSAPSSWithSHA256, testCertRSA},
4721 {"RSA-PSS-SHA384", signatureRSAPSSWithSHA384, testCertRSA},
4722 {"RSA-PSS-SHA512", signatureRSAPSSWithSHA512, testCertRSA},
David Benjamin5208fd42016-07-13 21:43:25 -04004723 // Tests for key types prior to TLS 1.2.
4724 {"RSA", 0, testCertRSA},
4725 {"ECDSA", 0, testCertECDSAP256},
David Benjamin000800a2014-11-14 01:43:59 -05004726}
4727
Nick Harper60edffd2016-06-21 15:19:24 -07004728const fakeSigAlg1 signatureAlgorithm = 0x2a01
4729const fakeSigAlg2 signatureAlgorithm = 0xff01
4730
4731func addSignatureAlgorithmTests() {
David Benjamin5208fd42016-07-13 21:43:25 -04004732 // Not all ciphers involve a signature. Advertise a list which gives all
4733 // versions a signing cipher.
4734 signingCiphers := []uint16{
4735 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
4736 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
4737 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
4738 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
4739 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
4740 }
4741
David Benjaminca3d5452016-07-14 12:51:01 -04004742 var allAlgorithms []signatureAlgorithm
4743 for _, alg := range testSignatureAlgorithms {
4744 if alg.id != 0 {
4745 allAlgorithms = append(allAlgorithms, alg.id)
4746 }
4747 }
4748
Nick Harper60edffd2016-06-21 15:19:24 -07004749 // Make sure each signature algorithm works. Include some fake values in
4750 // the list and ensure they're ignored.
4751 for _, alg := range testSignatureAlgorithms {
David Benjamin1fb125c2016-07-08 18:52:12 -07004752 for _, ver := range tlsVersions {
David Benjamin5208fd42016-07-13 21:43:25 -04004753 if (ver.version < VersionTLS12) != (alg.id == 0) {
4754 continue
4755 }
4756
4757 // TODO(davidben): Support ECDSA in SSL 3.0 in Go for testing
4758 // or remove it in C.
4759 if ver.version == VersionSSL30 && alg.cert != testCertRSA {
David Benjamin1fb125c2016-07-08 18:52:12 -07004760 continue
4761 }
Nick Harper60edffd2016-06-21 15:19:24 -07004762
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004763 var shouldFail bool
David Benjamin1fb125c2016-07-08 18:52:12 -07004764 // ecdsa_sha1 does not exist in TLS 1.3.
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004765 if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 {
4766 shouldFail = true
4767 }
4768 // RSA-PSS does not exist in TLS 1.2.
4769 if ver.version == VersionTLS12 && hasComponent(alg.name, "PSS") {
4770 shouldFail = true
4771 }
4772
4773 var signError, verifyError string
4774 if shouldFail {
4775 signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:"
4776 verifyError = ":WRONG_SIGNATURE_TYPE:"
David Benjamin1fb125c2016-07-08 18:52:12 -07004777 }
David Benjamin000800a2014-11-14 01:43:59 -05004778
David Benjamin1fb125c2016-07-08 18:52:12 -07004779 suffix := "-" + alg.name + "-" + ver.name
David Benjamin6e807652015-11-02 12:02:20 -05004780
David Benjamin7a41d372016-07-09 11:21:54 -07004781 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04004782 name: "ClientAuth-Sign" + suffix,
David Benjamin7a41d372016-07-09 11:21:54 -07004783 config: Config{
4784 MaxVersion: ver.version,
4785 ClientAuth: RequireAnyClientCert,
4786 VerifySignatureAlgorithms: []signatureAlgorithm{
4787 fakeSigAlg1,
4788 alg.id,
4789 fakeSigAlg2,
David Benjamin1fb125c2016-07-08 18:52:12 -07004790 },
David Benjamin7a41d372016-07-09 11:21:54 -07004791 },
4792 flags: []string{
4793 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
4794 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
4795 "-enable-all-curves",
4796 },
4797 shouldFail: shouldFail,
4798 expectedError: signError,
4799 expectedPeerSignatureAlgorithm: alg.id,
4800 })
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004801
David Benjamin7a41d372016-07-09 11:21:54 -07004802 testCases = append(testCases, testCase{
4803 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04004804 name: "ClientAuth-Verify" + suffix,
David Benjamin7a41d372016-07-09 11:21:54 -07004805 config: Config{
4806 MaxVersion: ver.version,
4807 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
4808 SignSignatureAlgorithms: []signatureAlgorithm{
4809 alg.id,
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004810 },
David Benjamin7a41d372016-07-09 11:21:54 -07004811 Bugs: ProtocolBugs{
4812 SkipECDSACurveCheck: shouldFail,
4813 IgnoreSignatureVersionChecks: shouldFail,
4814 // The client won't advertise 1.3-only algorithms after
4815 // version negotiation.
4816 IgnorePeerSignatureAlgorithmPreferences: shouldFail,
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004817 },
David Benjamin7a41d372016-07-09 11:21:54 -07004818 },
4819 flags: []string{
4820 "-require-any-client-certificate",
4821 "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
4822 "-enable-all-curves",
4823 },
4824 shouldFail: shouldFail,
4825 expectedError: verifyError,
4826 })
David Benjamin1fb125c2016-07-08 18:52:12 -07004827
4828 testCases = append(testCases, testCase{
4829 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04004830 name: "ServerAuth-Sign" + suffix,
David Benjamin1fb125c2016-07-08 18:52:12 -07004831 config: Config{
David Benjamin5208fd42016-07-13 21:43:25 -04004832 MaxVersion: ver.version,
4833 CipherSuites: signingCiphers,
David Benjamin7a41d372016-07-09 11:21:54 -07004834 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07004835 fakeSigAlg1,
4836 alg.id,
4837 fakeSigAlg2,
4838 },
4839 },
4840 flags: []string{
4841 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
4842 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
4843 "-enable-all-curves",
4844 },
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004845 shouldFail: shouldFail,
4846 expectedError: signError,
David Benjamin1fb125c2016-07-08 18:52:12 -07004847 expectedPeerSignatureAlgorithm: alg.id,
4848 })
4849
4850 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04004851 name: "ServerAuth-Verify" + suffix,
David Benjamin1fb125c2016-07-08 18:52:12 -07004852 config: Config{
4853 MaxVersion: ver.version,
4854 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
David Benjamin5208fd42016-07-13 21:43:25 -04004855 CipherSuites: signingCiphers,
David Benjamin7a41d372016-07-09 11:21:54 -07004856 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07004857 alg.id,
4858 },
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004859 Bugs: ProtocolBugs{
4860 SkipECDSACurveCheck: shouldFail,
4861 IgnoreSignatureVersionChecks: shouldFail,
4862 },
David Benjamin1fb125c2016-07-08 18:52:12 -07004863 },
4864 flags: []string{
4865 "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
4866 "-enable-all-curves",
4867 },
Steven Valdezeff1e8d2016-07-06 14:24:47 -04004868 shouldFail: shouldFail,
4869 expectedError: verifyError,
David Benjamin1fb125c2016-07-08 18:52:12 -07004870 })
David Benjamin5208fd42016-07-13 21:43:25 -04004871
4872 if !shouldFail {
4873 testCases = append(testCases, testCase{
4874 testType: serverTest,
4875 name: "ClientAuth-InvalidSignature" + suffix,
4876 config: Config{
4877 MaxVersion: ver.version,
4878 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
4879 SignSignatureAlgorithms: []signatureAlgorithm{
4880 alg.id,
4881 },
4882 Bugs: ProtocolBugs{
4883 InvalidSignature: true,
4884 },
4885 },
4886 flags: []string{
4887 "-require-any-client-certificate",
4888 "-enable-all-curves",
4889 },
4890 shouldFail: true,
4891 expectedError: ":BAD_SIGNATURE:",
4892 })
4893
4894 testCases = append(testCases, testCase{
4895 name: "ServerAuth-InvalidSignature" + suffix,
4896 config: Config{
4897 MaxVersion: ver.version,
4898 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
4899 CipherSuites: signingCiphers,
4900 SignSignatureAlgorithms: []signatureAlgorithm{
4901 alg.id,
4902 },
4903 Bugs: ProtocolBugs{
4904 InvalidSignature: true,
4905 },
4906 },
4907 flags: []string{"-enable-all-curves"},
4908 shouldFail: true,
4909 expectedError: ":BAD_SIGNATURE:",
4910 })
4911 }
David Benjaminca3d5452016-07-14 12:51:01 -04004912
4913 if ver.version >= VersionTLS12 && !shouldFail {
4914 testCases = append(testCases, testCase{
4915 name: "ClientAuth-Sign-Negotiate" + suffix,
4916 config: Config{
4917 MaxVersion: ver.version,
4918 ClientAuth: RequireAnyClientCert,
4919 VerifySignatureAlgorithms: allAlgorithms,
4920 },
4921 flags: []string{
4922 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
4923 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
4924 "-enable-all-curves",
4925 "-signing-prefs", strconv.Itoa(int(alg.id)),
4926 },
4927 expectedPeerSignatureAlgorithm: alg.id,
4928 })
4929
4930 testCases = append(testCases, testCase{
4931 testType: serverTest,
4932 name: "ServerAuth-Sign-Negotiate" + suffix,
4933 config: Config{
4934 MaxVersion: ver.version,
4935 CipherSuites: signingCiphers,
4936 VerifySignatureAlgorithms: allAlgorithms,
4937 },
4938 flags: []string{
4939 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
4940 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
4941 "-enable-all-curves",
4942 "-signing-prefs", strconv.Itoa(int(alg.id)),
4943 },
4944 expectedPeerSignatureAlgorithm: alg.id,
4945 })
4946 }
David Benjamin1fb125c2016-07-08 18:52:12 -07004947 }
David Benjamin000800a2014-11-14 01:43:59 -05004948 }
4949
Nick Harper60edffd2016-06-21 15:19:24 -07004950 // Test that algorithm selection takes the key type into account.
David Benjamin4c3ddf72016-06-29 18:13:53 -04004951 //
4952 // TODO(davidben): Test this in TLS 1.3.
David Benjamin000800a2014-11-14 01:43:59 -05004953 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04004954 name: "ClientAuth-SignatureType",
David Benjamin000800a2014-11-14 01:43:59 -05004955 config: Config{
4956 ClientAuth: RequireAnyClientCert,
David Benjamin4c3ddf72016-06-29 18:13:53 -04004957 MaxVersion: VersionTLS12,
David Benjamin7a41d372016-07-09 11:21:54 -07004958 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07004959 signatureECDSAWithP521AndSHA512,
4960 signatureRSAPKCS1WithSHA384,
4961 signatureECDSAWithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05004962 },
4963 },
4964 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07004965 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4966 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05004967 },
Nick Harper60edffd2016-06-21 15:19:24 -07004968 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA384,
David Benjamin000800a2014-11-14 01:43:59 -05004969 })
4970
4971 testCases = append(testCases, testCase{
4972 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04004973 name: "ServerAuth-SignatureType",
David Benjamin000800a2014-11-14 01:43:59 -05004974 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004975 MaxVersion: VersionTLS12,
David Benjamin000800a2014-11-14 01:43:59 -05004976 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07004977 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07004978 signatureECDSAWithP521AndSHA512,
4979 signatureRSAPKCS1WithSHA384,
4980 signatureECDSAWithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05004981 },
4982 },
Nick Harper60edffd2016-06-21 15:19:24 -07004983 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA384,
David Benjamin000800a2014-11-14 01:43:59 -05004984 })
4985
David Benjamina95e9f32016-07-08 16:28:04 -07004986 // Test that signature verification takes the key type into account.
4987 //
4988 // TODO(davidben): Test this in TLS 1.3.
4989 testCases = append(testCases, testCase{
4990 testType: serverTest,
4991 name: "Verify-ClientAuth-SignatureType",
4992 config: Config{
4993 MaxVersion: VersionTLS12,
4994 Certificates: []Certificate{rsaCertificate},
David Benjamin7a41d372016-07-09 11:21:54 -07004995 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamina95e9f32016-07-08 16:28:04 -07004996 signatureRSAPKCS1WithSHA256,
4997 },
4998 Bugs: ProtocolBugs{
4999 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5000 },
5001 },
5002 flags: []string{
5003 "-require-any-client-certificate",
5004 },
5005 shouldFail: true,
5006 expectedError: ":WRONG_SIGNATURE_TYPE:",
5007 })
5008
5009 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005010 name: "Verify-ServerAuth-SignatureType",
David Benjamina95e9f32016-07-08 16:28:04 -07005011 config: Config{
5012 MaxVersion: VersionTLS12,
5013 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005014 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamina95e9f32016-07-08 16:28:04 -07005015 signatureRSAPKCS1WithSHA256,
5016 },
5017 Bugs: ProtocolBugs{
5018 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5019 },
5020 },
5021 shouldFail: true,
5022 expectedError: ":WRONG_SIGNATURE_TYPE:",
5023 })
5024
David Benjamin51dd7d62016-07-08 16:07:01 -07005025 // Test that, if the list is missing, the peer falls back to SHA-1 in
5026 // TLS 1.2, but not TLS 1.3.
David Benjamin000800a2014-11-14 01:43:59 -05005027 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005028 name: "ClientAuth-SHA1-Fallback",
David Benjamin000800a2014-11-14 01:43:59 -05005029 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005030 MaxVersion: VersionTLS12,
David Benjamin000800a2014-11-14 01:43:59 -05005031 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005032 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005033 signatureRSAPKCS1WithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05005034 },
5035 Bugs: ProtocolBugs{
Nick Harper60edffd2016-06-21 15:19:24 -07005036 NoSignatureAlgorithms: true,
David Benjamin000800a2014-11-14 01:43:59 -05005037 },
5038 },
5039 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07005040 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5041 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05005042 },
5043 })
5044
5045 testCases = append(testCases, testCase{
5046 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04005047 name: "ServerAuth-SHA1-Fallback",
David Benjamin000800a2014-11-14 01:43:59 -05005048 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005049 MaxVersion: VersionTLS12,
David Benjamin000800a2014-11-14 01:43:59 -05005050 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005051 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005052 signatureRSAPKCS1WithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05005053 },
5054 Bugs: ProtocolBugs{
Nick Harper60edffd2016-06-21 15:19:24 -07005055 NoSignatureAlgorithms: true,
David Benjamin000800a2014-11-14 01:43:59 -05005056 },
5057 },
5058 })
David Benjamin72dc7832015-03-16 17:49:43 -04005059
David Benjamin51dd7d62016-07-08 16:07:01 -07005060 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005061 name: "ClientAuth-NoFallback-TLS13",
David Benjamin51dd7d62016-07-08 16:07:01 -07005062 config: Config{
5063 MaxVersion: VersionTLS13,
5064 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005065 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin51dd7d62016-07-08 16:07:01 -07005066 signatureRSAPKCS1WithSHA1,
5067 },
5068 Bugs: ProtocolBugs{
5069 NoSignatureAlgorithms: true,
5070 },
5071 },
5072 flags: []string{
5073 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5074 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5075 },
5076 shouldFail: true,
5077 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
5078 })
5079
5080 testCases = append(testCases, testCase{
5081 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04005082 name: "ServerAuth-NoFallback-TLS13",
David Benjamin51dd7d62016-07-08 16:07:01 -07005083 config: Config{
5084 MaxVersion: VersionTLS13,
5085 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005086 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin51dd7d62016-07-08 16:07:01 -07005087 signatureRSAPKCS1WithSHA1,
5088 },
5089 Bugs: ProtocolBugs{
5090 NoSignatureAlgorithms: true,
5091 },
5092 },
5093 shouldFail: true,
5094 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
5095 })
5096
David Benjamin72dc7832015-03-16 17:49:43 -04005097 // Test that hash preferences are enforced. BoringSSL defaults to
5098 // rejecting MD5 signatures.
5099 testCases = append(testCases, testCase{
5100 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04005101 name: "ClientAuth-Enforced",
David Benjamin72dc7832015-03-16 17:49:43 -04005102 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005103 MaxVersion: VersionTLS12,
David Benjamin72dc7832015-03-16 17:49:43 -04005104 Certificates: []Certificate{rsaCertificate},
David Benjamin7a41d372016-07-09 11:21:54 -07005105 SignSignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005106 signatureRSAPKCS1WithMD5,
David Benjamin72dc7832015-03-16 17:49:43 -04005107 // Advertise SHA-1 so the handshake will
5108 // proceed, but the shim's preferences will be
5109 // ignored in CertificateVerify generation, so
5110 // MD5 will be chosen.
Nick Harper60edffd2016-06-21 15:19:24 -07005111 signatureRSAPKCS1WithSHA1,
David Benjamin72dc7832015-03-16 17:49:43 -04005112 },
5113 Bugs: ProtocolBugs{
5114 IgnorePeerSignatureAlgorithmPreferences: true,
5115 },
5116 },
5117 flags: []string{"-require-any-client-certificate"},
5118 shouldFail: true,
5119 expectedError: ":WRONG_SIGNATURE_TYPE:",
5120 })
5121
5122 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005123 name: "ServerAuth-Enforced",
David Benjamin72dc7832015-03-16 17:49:43 -04005124 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005125 MaxVersion: VersionTLS12,
David Benjamin72dc7832015-03-16 17:49:43 -04005126 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005127 SignSignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005128 signatureRSAPKCS1WithMD5,
David Benjamin72dc7832015-03-16 17:49:43 -04005129 },
5130 Bugs: ProtocolBugs{
5131 IgnorePeerSignatureAlgorithmPreferences: true,
5132 },
5133 },
5134 shouldFail: true,
5135 expectedError: ":WRONG_SIGNATURE_TYPE:",
5136 })
Steven Valdez0d62f262015-09-04 12:41:04 -04005137
5138 // Test that the agreed upon digest respects the client preferences and
5139 // the server digests.
David Benjamin4c3ddf72016-06-29 18:13:53 -04005140 //
5141 // TODO(davidben): Add TLS 1.3 versions of these.
Steven Valdez0d62f262015-09-04 12:41:04 -04005142 testCases = append(testCases, testCase{
David Benjaminca3d5452016-07-14 12:51:01 -04005143 name: "NoCommonAlgorithms-Digests",
5144 config: Config{
5145 MaxVersion: VersionTLS12,
5146 ClientAuth: RequireAnyClientCert,
5147 VerifySignatureAlgorithms: []signatureAlgorithm{
5148 signatureRSAPKCS1WithSHA512,
5149 signatureRSAPKCS1WithSHA1,
5150 },
5151 },
5152 flags: []string{
5153 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5154 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5155 "-digest-prefs", "SHA256",
5156 },
5157 shouldFail: true,
5158 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
5159 })
5160 testCases = append(testCases, testCase{
David Benjaminea9a0d52016-07-08 15:52:59 -07005161 name: "NoCommonAlgorithms",
Steven Valdez0d62f262015-09-04 12:41:04 -04005162 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005163 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04005164 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005165 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005166 signatureRSAPKCS1WithSHA512,
5167 signatureRSAPKCS1WithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04005168 },
5169 },
5170 flags: []string{
5171 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5172 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminca3d5452016-07-14 12:51:01 -04005173 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
Steven Valdez0d62f262015-09-04 12:41:04 -04005174 },
David Benjaminca3d5452016-07-14 12:51:01 -04005175 shouldFail: true,
5176 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
5177 })
5178 testCases = append(testCases, testCase{
5179 name: "NoCommonAlgorithms-TLS13",
5180 config: Config{
5181 MaxVersion: VersionTLS13,
5182 ClientAuth: RequireAnyClientCert,
5183 VerifySignatureAlgorithms: []signatureAlgorithm{
5184 signatureRSAPSSWithSHA512,
5185 signatureRSAPSSWithSHA384,
5186 },
5187 },
5188 flags: []string{
5189 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5190 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5191 "-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)),
5192 },
David Benjaminea9a0d52016-07-08 15:52:59 -07005193 shouldFail: true,
5194 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
Steven Valdez0d62f262015-09-04 12:41:04 -04005195 })
5196 testCases = append(testCases, testCase{
5197 name: "Agree-Digest-SHA256",
5198 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005199 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04005200 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005201 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005202 signatureRSAPKCS1WithSHA1,
5203 signatureRSAPKCS1WithSHA256,
Steven Valdez0d62f262015-09-04 12:41:04 -04005204 },
5205 },
5206 flags: []string{
5207 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5208 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminca3d5452016-07-14 12:51:01 -04005209 "-digest-prefs", "SHA256,SHA1",
Steven Valdez0d62f262015-09-04 12:41:04 -04005210 },
Nick Harper60edffd2016-06-21 15:19:24 -07005211 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
Steven Valdez0d62f262015-09-04 12:41:04 -04005212 })
5213 testCases = append(testCases, testCase{
5214 name: "Agree-Digest-SHA1",
5215 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005216 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04005217 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005218 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005219 signatureRSAPKCS1WithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04005220 },
5221 },
5222 flags: []string{
5223 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5224 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminca3d5452016-07-14 12:51:01 -04005225 "-digest-prefs", "SHA512,SHA256,SHA1",
Steven Valdez0d62f262015-09-04 12:41:04 -04005226 },
Nick Harper60edffd2016-06-21 15:19:24 -07005227 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04005228 })
5229 testCases = append(testCases, testCase{
5230 name: "Agree-Digest-Default",
5231 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005232 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04005233 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005234 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005235 signatureRSAPKCS1WithSHA256,
5236 signatureECDSAWithP256AndSHA256,
5237 signatureRSAPKCS1WithSHA1,
5238 signatureECDSAWithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04005239 },
5240 },
5241 flags: []string{
5242 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5243 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5244 },
Nick Harper60edffd2016-06-21 15:19:24 -07005245 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
Steven Valdez0d62f262015-09-04 12:41:04 -04005246 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04005247
David Benjaminca3d5452016-07-14 12:51:01 -04005248 // Test that the signing preference list may include extra algorithms
5249 // without negotiation problems.
5250 testCases = append(testCases, testCase{
5251 testType: serverTest,
5252 name: "FilterExtraAlgorithms",
5253 config: Config{
5254 MaxVersion: VersionTLS12,
5255 VerifySignatureAlgorithms: []signatureAlgorithm{
5256 signatureRSAPKCS1WithSHA256,
5257 },
5258 },
5259 flags: []string{
5260 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5261 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5262 "-signing-prefs", strconv.Itoa(int(fakeSigAlg1)),
5263 "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)),
5264 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
5265 "-signing-prefs", strconv.Itoa(int(fakeSigAlg2)),
5266 },
5267 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
5268 })
5269
David Benjamin4c3ddf72016-06-29 18:13:53 -04005270 // In TLS 1.2 and below, ECDSA uses the curve list rather than the
5271 // signature algorithms.
David Benjamin4c3ddf72016-06-29 18:13:53 -04005272 testCases = append(testCases, testCase{
5273 name: "CheckLeafCurve",
5274 config: Config{
5275 MaxVersion: VersionTLS12,
5276 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07005277 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamin4c3ddf72016-06-29 18:13:53 -04005278 },
5279 flags: []string{"-p384-only"},
5280 shouldFail: true,
5281 expectedError: ":BAD_ECC_CERT:",
5282 })
David Benjamin75ea5bb2016-07-08 17:43:29 -07005283
5284 // In TLS 1.3, ECDSA does not use the ECDHE curve list.
5285 testCases = append(testCases, testCase{
5286 name: "CheckLeafCurve-TLS13",
5287 config: Config{
5288 MaxVersion: VersionTLS13,
5289 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
5290 Certificates: []Certificate{ecdsaP256Certificate},
5291 },
5292 flags: []string{"-p384-only"},
5293 })
David Benjamin1fb125c2016-07-08 18:52:12 -07005294
5295 // In TLS 1.2, the ECDSA curve is not in the signature algorithm.
5296 testCases = append(testCases, testCase{
5297 name: "ECDSACurveMismatch-Verify-TLS12",
5298 config: Config{
5299 MaxVersion: VersionTLS12,
5300 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
5301 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamin7a41d372016-07-09 11:21:54 -07005302 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07005303 signatureECDSAWithP384AndSHA384,
5304 },
5305 },
5306 })
5307
5308 // In TLS 1.3, the ECDSA curve comes from the signature algorithm.
5309 testCases = append(testCases, testCase{
5310 name: "ECDSACurveMismatch-Verify-TLS13",
5311 config: Config{
5312 MaxVersion: VersionTLS13,
5313 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
5314 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamin7a41d372016-07-09 11:21:54 -07005315 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07005316 signatureECDSAWithP384AndSHA384,
5317 },
5318 Bugs: ProtocolBugs{
5319 SkipECDSACurveCheck: true,
5320 },
5321 },
5322 shouldFail: true,
5323 expectedError: ":WRONG_SIGNATURE_TYPE:",
5324 })
5325
5326 // Signature algorithm selection in TLS 1.3 should take the curve into
5327 // account.
5328 testCases = append(testCases, testCase{
5329 testType: serverTest,
5330 name: "ECDSACurveMismatch-Sign-TLS13",
5331 config: Config{
5332 MaxVersion: VersionTLS13,
5333 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005334 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07005335 signatureECDSAWithP384AndSHA384,
5336 signatureECDSAWithP256AndSHA256,
5337 },
5338 },
5339 flags: []string{
5340 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
5341 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
5342 },
5343 expectedPeerSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5344 })
David Benjamin7944a9f2016-07-12 22:27:01 -04005345
5346 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the
5347 // server does not attempt to sign in that case.
5348 testCases = append(testCases, testCase{
5349 testType: serverTest,
5350 name: "RSA-PSS-Large",
5351 config: Config{
5352 MaxVersion: VersionTLS13,
5353 VerifySignatureAlgorithms: []signatureAlgorithm{
5354 signatureRSAPSSWithSHA512,
5355 },
5356 },
5357 flags: []string{
5358 "-cert-file", path.Join(*resourceDir, rsa1024CertificateFile),
5359 "-key-file", path.Join(*resourceDir, rsa1024KeyFile),
5360 },
5361 shouldFail: true,
5362 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
5363 })
David Benjamin000800a2014-11-14 01:43:59 -05005364}
5365
David Benjamin83f90402015-01-27 01:09:43 -05005366// timeouts is the retransmit schedule for BoringSSL. It doubles and
5367// caps at 60 seconds. On the 13th timeout, it gives up.
5368var timeouts = []time.Duration{
5369 1 * time.Second,
5370 2 * time.Second,
5371 4 * time.Second,
5372 8 * time.Second,
5373 16 * time.Second,
5374 32 * time.Second,
5375 60 * time.Second,
5376 60 * time.Second,
5377 60 * time.Second,
5378 60 * time.Second,
5379 60 * time.Second,
5380 60 * time.Second,
5381 60 * time.Second,
5382}
5383
Taylor Brandstetter376a0fe2016-05-10 19:30:28 -07005384// shortTimeouts is an alternate set of timeouts which would occur if the
5385// initial timeout duration was set to 250ms.
5386var shortTimeouts = []time.Duration{
5387 250 * time.Millisecond,
5388 500 * time.Millisecond,
5389 1 * time.Second,
5390 2 * time.Second,
5391 4 * time.Second,
5392 8 * time.Second,
5393 16 * time.Second,
5394 32 * time.Second,
5395 60 * time.Second,
5396 60 * time.Second,
5397 60 * time.Second,
5398 60 * time.Second,
5399 60 * time.Second,
5400}
5401
David Benjamin83f90402015-01-27 01:09:43 -05005402func addDTLSRetransmitTests() {
David Benjamin585d7a42016-06-02 14:58:00 -04005403 // These tests work by coordinating some behavior on both the shim and
5404 // the runner.
5405 //
5406 // TimeoutSchedule configures the runner to send a series of timeout
5407 // opcodes to the shim (see packetAdaptor) immediately before reading
5408 // each peer handshake flight N. The timeout opcode both simulates a
5409 // timeout in the shim and acts as a synchronization point to help the
5410 // runner bracket each handshake flight.
5411 //
5412 // We assume the shim does not read from the channel eagerly. It must
5413 // first wait until it has sent flight N and is ready to receive
5414 // handshake flight N+1. At this point, it will process the timeout
5415 // opcode. It must then immediately respond with a timeout ACK and act
5416 // as if the shim was idle for the specified amount of time.
5417 //
5418 // The runner then drops all packets received before the ACK and
5419 // continues waiting for flight N. This ordering results in one attempt
5420 // at sending flight N to be dropped. For the test to complete, the
5421 // shim must send flight N again, testing that the shim implements DTLS
5422 // retransmit on a timeout.
5423
David Benjamin4c3ddf72016-06-29 18:13:53 -04005424 // TODO(davidben): Add TLS 1.3 versions of these tests. There will
5425 // likely be more epochs to cross and the final message's retransmit may
5426 // be more complex.
5427
David Benjamin585d7a42016-06-02 14:58:00 -04005428 for _, async := range []bool{true, false} {
5429 var tests []testCase
5430
5431 // Test that this is indeed the timeout schedule. Stress all
5432 // four patterns of handshake.
5433 for i := 1; i < len(timeouts); i++ {
5434 number := strconv.Itoa(i)
5435 tests = append(tests, testCase{
5436 protocol: dtls,
5437 name: "DTLS-Retransmit-Client-" + number,
5438 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005439 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04005440 Bugs: ProtocolBugs{
5441 TimeoutSchedule: timeouts[:i],
5442 },
5443 },
5444 resumeSession: true,
5445 })
5446 tests = append(tests, testCase{
5447 protocol: dtls,
5448 testType: serverTest,
5449 name: "DTLS-Retransmit-Server-" + number,
5450 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005451 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04005452 Bugs: ProtocolBugs{
5453 TimeoutSchedule: timeouts[:i],
5454 },
5455 },
5456 resumeSession: true,
5457 })
5458 }
5459
5460 // Test that exceeding the timeout schedule hits a read
5461 // timeout.
5462 tests = append(tests, testCase{
David Benjamin83f90402015-01-27 01:09:43 -05005463 protocol: dtls,
David Benjamin585d7a42016-06-02 14:58:00 -04005464 name: "DTLS-Retransmit-Timeout",
David Benjamin83f90402015-01-27 01:09:43 -05005465 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005466 MaxVersion: VersionTLS12,
David Benjamin83f90402015-01-27 01:09:43 -05005467 Bugs: ProtocolBugs{
David Benjamin585d7a42016-06-02 14:58:00 -04005468 TimeoutSchedule: timeouts,
David Benjamin83f90402015-01-27 01:09:43 -05005469 },
5470 },
5471 resumeSession: true,
David Benjamin585d7a42016-06-02 14:58:00 -04005472 shouldFail: true,
5473 expectedError: ":READ_TIMEOUT_EXPIRED:",
David Benjamin83f90402015-01-27 01:09:43 -05005474 })
David Benjamin585d7a42016-06-02 14:58:00 -04005475
5476 if async {
5477 // Test that timeout handling has a fudge factor, due to API
5478 // problems.
5479 tests = append(tests, testCase{
5480 protocol: dtls,
5481 name: "DTLS-Retransmit-Fudge",
5482 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005483 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04005484 Bugs: ProtocolBugs{
5485 TimeoutSchedule: []time.Duration{
5486 timeouts[0] - 10*time.Millisecond,
5487 },
5488 },
5489 },
5490 resumeSession: true,
5491 })
5492 }
5493
5494 // Test that the final Finished retransmitting isn't
5495 // duplicated if the peer badly fragments everything.
5496 tests = append(tests, testCase{
5497 testType: serverTest,
5498 protocol: dtls,
5499 name: "DTLS-Retransmit-Fragmented",
5500 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005501 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04005502 Bugs: ProtocolBugs{
5503 TimeoutSchedule: []time.Duration{timeouts[0]},
5504 MaxHandshakeRecordLength: 2,
5505 },
5506 },
5507 })
5508
5509 // Test the timeout schedule when a shorter initial timeout duration is set.
5510 tests = append(tests, testCase{
5511 protocol: dtls,
5512 name: "DTLS-Retransmit-Short-Client",
5513 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005514 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04005515 Bugs: ProtocolBugs{
5516 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
5517 },
5518 },
5519 resumeSession: true,
5520 flags: []string{"-initial-timeout-duration-ms", "250"},
5521 })
5522 tests = append(tests, testCase{
David Benjamin83f90402015-01-27 01:09:43 -05005523 protocol: dtls,
5524 testType: serverTest,
David Benjamin585d7a42016-06-02 14:58:00 -04005525 name: "DTLS-Retransmit-Short-Server",
David Benjamin83f90402015-01-27 01:09:43 -05005526 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005527 MaxVersion: VersionTLS12,
David Benjamin83f90402015-01-27 01:09:43 -05005528 Bugs: ProtocolBugs{
David Benjamin585d7a42016-06-02 14:58:00 -04005529 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
David Benjamin83f90402015-01-27 01:09:43 -05005530 },
5531 },
5532 resumeSession: true,
David Benjamin585d7a42016-06-02 14:58:00 -04005533 flags: []string{"-initial-timeout-duration-ms", "250"},
David Benjamin83f90402015-01-27 01:09:43 -05005534 })
David Benjamin585d7a42016-06-02 14:58:00 -04005535
5536 for _, test := range tests {
5537 if async {
5538 test.name += "-Async"
5539 test.flags = append(test.flags, "-async")
5540 }
5541
5542 testCases = append(testCases, test)
5543 }
David Benjamin83f90402015-01-27 01:09:43 -05005544 }
David Benjamin83f90402015-01-27 01:09:43 -05005545}
5546
David Benjaminc565ebb2015-04-03 04:06:36 -04005547func addExportKeyingMaterialTests() {
5548 for _, vers := range tlsVersions {
5549 if vers.version == VersionSSL30 {
5550 continue
5551 }
5552 testCases = append(testCases, testCase{
5553 name: "ExportKeyingMaterial-" + vers.name,
5554 config: Config{
5555 MaxVersion: vers.version,
5556 },
5557 exportKeyingMaterial: 1024,
5558 exportLabel: "label",
5559 exportContext: "context",
5560 useExportContext: true,
5561 })
5562 testCases = append(testCases, testCase{
5563 name: "ExportKeyingMaterial-NoContext-" + vers.name,
5564 config: Config{
5565 MaxVersion: vers.version,
5566 },
5567 exportKeyingMaterial: 1024,
5568 })
5569 testCases = append(testCases, testCase{
5570 name: "ExportKeyingMaterial-EmptyContext-" + vers.name,
5571 config: Config{
5572 MaxVersion: vers.version,
5573 },
5574 exportKeyingMaterial: 1024,
5575 useExportContext: true,
5576 })
5577 testCases = append(testCases, testCase{
5578 name: "ExportKeyingMaterial-Small-" + vers.name,
5579 config: Config{
5580 MaxVersion: vers.version,
5581 },
5582 exportKeyingMaterial: 1,
5583 exportLabel: "label",
5584 exportContext: "context",
5585 useExportContext: true,
5586 })
5587 }
5588 testCases = append(testCases, testCase{
5589 name: "ExportKeyingMaterial-SSL3",
5590 config: Config{
5591 MaxVersion: VersionSSL30,
5592 },
5593 exportKeyingMaterial: 1024,
5594 exportLabel: "label",
5595 exportContext: "context",
5596 useExportContext: true,
5597 shouldFail: true,
5598 expectedError: "failed to export keying material",
5599 })
5600}
5601
Adam Langleyaf0e32c2015-06-03 09:57:23 -07005602func addTLSUniqueTests() {
5603 for _, isClient := range []bool{false, true} {
5604 for _, isResumption := range []bool{false, true} {
5605 for _, hasEMS := range []bool{false, true} {
5606 var suffix string
5607 if isResumption {
5608 suffix = "Resume-"
5609 } else {
5610 suffix = "Full-"
5611 }
5612
5613 if hasEMS {
5614 suffix += "EMS-"
5615 } else {
5616 suffix += "NoEMS-"
5617 }
5618
5619 if isClient {
5620 suffix += "Client"
5621 } else {
5622 suffix += "Server"
5623 }
5624
5625 test := testCase{
5626 name: "TLSUnique-" + suffix,
5627 testTLSUnique: true,
5628 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005629 MaxVersion: VersionTLS12,
Adam Langleyaf0e32c2015-06-03 09:57:23 -07005630 Bugs: ProtocolBugs{
5631 NoExtendedMasterSecret: !hasEMS,
5632 },
5633 },
5634 }
5635
5636 if isResumption {
5637 test.resumeSession = true
5638 test.resumeConfig = &Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005639 MaxVersion: VersionTLS12,
Adam Langleyaf0e32c2015-06-03 09:57:23 -07005640 Bugs: ProtocolBugs{
5641 NoExtendedMasterSecret: !hasEMS,
5642 },
5643 }
5644 }
5645
5646 if isResumption && !hasEMS {
5647 test.shouldFail = true
5648 test.expectedError = "failed to get tls-unique"
5649 }
5650
5651 testCases = append(testCases, test)
5652 }
5653 }
5654 }
5655}
5656
Adam Langley09505632015-07-30 18:10:13 -07005657func addCustomExtensionTests() {
5658 expectedContents := "custom extension"
5659 emptyString := ""
5660
David Benjamin4c3ddf72016-06-29 18:13:53 -04005661 // TODO(davidben): Add TLS 1.3 versions of these tests.
Adam Langley09505632015-07-30 18:10:13 -07005662 for _, isClient := range []bool{false, true} {
5663 suffix := "Server"
5664 flag := "-enable-server-custom-extension"
5665 testType := serverTest
5666 if isClient {
5667 suffix = "Client"
5668 flag = "-enable-client-custom-extension"
5669 testType = clientTest
5670 }
5671
5672 testCases = append(testCases, testCase{
5673 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005674 name: "CustomExtensions-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005675 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005676 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04005677 Bugs: ProtocolBugs{
5678 CustomExtension: expectedContents,
Adam Langley09505632015-07-30 18:10:13 -07005679 ExpectedCustomExtension: &expectedContents,
5680 },
5681 },
5682 flags: []string{flag},
5683 })
5684
5685 // If the parse callback fails, the handshake should also fail.
5686 testCases = append(testCases, testCase{
5687 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005688 name: "CustomExtensions-ParseError-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005689 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005690 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04005691 Bugs: ProtocolBugs{
5692 CustomExtension: expectedContents + "foo",
Adam Langley09505632015-07-30 18:10:13 -07005693 ExpectedCustomExtension: &expectedContents,
5694 },
5695 },
David Benjamin399e7c92015-07-30 23:01:27 -04005696 flags: []string{flag},
5697 shouldFail: true,
Adam Langley09505632015-07-30 18:10:13 -07005698 expectedError: ":CUSTOM_EXTENSION_ERROR:",
5699 })
5700
5701 // If the add callback fails, the handshake should also fail.
5702 testCases = append(testCases, testCase{
5703 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005704 name: "CustomExtensions-FailAdd-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005705 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005706 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04005707 Bugs: ProtocolBugs{
5708 CustomExtension: expectedContents,
Adam Langley09505632015-07-30 18:10:13 -07005709 ExpectedCustomExtension: &expectedContents,
5710 },
5711 },
David Benjamin399e7c92015-07-30 23:01:27 -04005712 flags: []string{flag, "-custom-extension-fail-add"},
5713 shouldFail: true,
Adam Langley09505632015-07-30 18:10:13 -07005714 expectedError: ":CUSTOM_EXTENSION_ERROR:",
5715 })
5716
5717 // If the add callback returns zero, no extension should be
5718 // added.
5719 skipCustomExtension := expectedContents
5720 if isClient {
5721 // For the case where the client skips sending the
5722 // custom extension, the server must not “echo” it.
5723 skipCustomExtension = ""
5724 }
5725 testCases = append(testCases, testCase{
5726 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04005727 name: "CustomExtensions-Skip-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07005728 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005729 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04005730 Bugs: ProtocolBugs{
5731 CustomExtension: skipCustomExtension,
Adam Langley09505632015-07-30 18:10:13 -07005732 ExpectedCustomExtension: &emptyString,
5733 },
5734 },
5735 flags: []string{flag, "-custom-extension-skip"},
5736 })
5737 }
5738
5739 // The custom extension add callback should not be called if the client
5740 // doesn't send the extension.
5741 testCases = append(testCases, testCase{
5742 testType: serverTest,
David Benjamin399e7c92015-07-30 23:01:27 -04005743 name: "CustomExtensions-NotCalled-Server",
Adam Langley09505632015-07-30 18:10:13 -07005744 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005745 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04005746 Bugs: ProtocolBugs{
Adam Langley09505632015-07-30 18:10:13 -07005747 ExpectedCustomExtension: &emptyString,
5748 },
5749 },
5750 flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
5751 })
Adam Langley2deb9842015-08-07 11:15:37 -07005752
5753 // Test an unknown extension from the server.
5754 testCases = append(testCases, testCase{
5755 testType: clientTest,
5756 name: "UnknownExtension-Client",
5757 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005758 MaxVersion: VersionTLS12,
Adam Langley2deb9842015-08-07 11:15:37 -07005759 Bugs: ProtocolBugs{
5760 CustomExtension: expectedContents,
5761 },
5762 },
5763 shouldFail: true,
5764 expectedError: ":UNEXPECTED_EXTENSION:",
5765 })
Adam Langley09505632015-07-30 18:10:13 -07005766}
5767
David Benjaminb36a3952015-12-01 18:53:13 -05005768func addRSAClientKeyExchangeTests() {
5769 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ {
5770 testCases = append(testCases, testCase{
5771 testType: serverTest,
5772 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad),
5773 config: Config{
5774 // Ensure the ClientHello version and final
5775 // version are different, to detect if the
5776 // server uses the wrong one.
5777 MaxVersion: VersionTLS11,
5778 CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
5779 Bugs: ProtocolBugs{
5780 BadRSAClientKeyExchange: bad,
5781 },
5782 },
5783 shouldFail: true,
5784 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5785 })
5786 }
5787}
5788
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005789var testCurves = []struct {
5790 name string
5791 id CurveID
5792}{
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005793 {"P-256", CurveP256},
5794 {"P-384", CurveP384},
5795 {"P-521", CurveP521},
David Benjamin4298d772015-12-19 00:18:25 -05005796 {"X25519", CurveX25519},
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005797}
5798
5799func addCurveTests() {
David Benjamin4c3ddf72016-06-29 18:13:53 -04005800 // TODO(davidben): Add a TLS 1.3 versions of these tests.
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005801 for _, curve := range testCurves {
5802 testCases = append(testCases, testCase{
5803 name: "CurveTest-Client-" + curve.name,
5804 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005805 MaxVersion: VersionTLS12,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005806 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5807 CurvePreferences: []CurveID{curve.id},
5808 },
5809 flags: []string{"-enable-all-curves"},
5810 })
5811 testCases = append(testCases, testCase{
5812 testType: serverTest,
5813 name: "CurveTest-Server-" + curve.name,
5814 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005815 MaxVersion: VersionTLS12,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005816 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5817 CurvePreferences: []CurveID{curve.id},
5818 },
5819 flags: []string{"-enable-all-curves"},
5820 })
5821 }
David Benjamin241ae832016-01-15 03:04:54 -05005822
5823 // The server must be tolerant to bogus curves.
5824 const bogusCurve = 0x1234
5825 testCases = append(testCases, testCase{
5826 testType: serverTest,
5827 name: "UnknownCurve",
5828 config: Config{
5829 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5830 CurvePreferences: []CurveID{bogusCurve, CurveP256},
5831 },
5832 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04005833
5834 // The server must not consider ECDHE ciphers when there are no
5835 // supported curves.
5836 testCases = append(testCases, testCase{
5837 testType: serverTest,
5838 name: "NoSupportedCurves",
5839 config: Config{
5840 // TODO(davidben): Add a TLS 1.3 version of this.
5841 MaxVersion: VersionTLS12,
5842 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5843 Bugs: ProtocolBugs{
5844 NoSupportedCurves: true,
5845 },
5846 },
5847 shouldFail: true,
5848 expectedError: ":NO_SHARED_CIPHER:",
5849 })
5850
5851 // The server must fall back to another cipher when there are no
5852 // supported curves.
5853 testCases = append(testCases, testCase{
5854 testType: serverTest,
5855 name: "NoCommonCurves",
5856 config: Config{
5857 MaxVersion: VersionTLS12,
5858 CipherSuites: []uint16{
5859 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
5860 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
5861 },
5862 CurvePreferences: []CurveID{CurveP224},
5863 },
5864 expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
5865 })
5866
5867 // The client must reject bogus curves and disabled curves.
5868 testCases = append(testCases, testCase{
5869 name: "BadECDHECurve",
5870 config: Config{
5871 // TODO(davidben): Add a TLS 1.3 version of this.
5872 MaxVersion: VersionTLS12,
5873 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5874 Bugs: ProtocolBugs{
5875 SendCurve: bogusCurve,
5876 },
5877 },
5878 shouldFail: true,
5879 expectedError: ":WRONG_CURVE:",
5880 })
5881
5882 testCases = append(testCases, testCase{
5883 name: "UnsupportedCurve",
5884 config: Config{
5885 // TODO(davidben): Add a TLS 1.3 version of this.
5886 MaxVersion: VersionTLS12,
5887 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5888 CurvePreferences: []CurveID{CurveP256},
5889 Bugs: ProtocolBugs{
5890 IgnorePeerCurvePreferences: true,
5891 },
5892 },
5893 flags: []string{"-p384-only"},
5894 shouldFail: true,
5895 expectedError: ":WRONG_CURVE:",
5896 })
5897
5898 // Test invalid curve points.
5899 testCases = append(testCases, testCase{
5900 name: "InvalidECDHPoint-Client",
5901 config: Config{
5902 // TODO(davidben): Add a TLS 1.3 version of this test.
5903 MaxVersion: VersionTLS12,
5904 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5905 CurvePreferences: []CurveID{CurveP256},
5906 Bugs: ProtocolBugs{
5907 InvalidECDHPoint: true,
5908 },
5909 },
5910 shouldFail: true,
5911 expectedError: ":INVALID_ENCODING:",
5912 })
5913 testCases = append(testCases, testCase{
5914 testType: serverTest,
5915 name: "InvalidECDHPoint-Server",
5916 config: Config{
5917 // TODO(davidben): Add a TLS 1.3 version of this test.
5918 MaxVersion: VersionTLS12,
5919 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5920 CurvePreferences: []CurveID{CurveP256},
5921 Bugs: ProtocolBugs{
5922 InvalidECDHPoint: true,
5923 },
5924 },
5925 shouldFail: true,
5926 expectedError: ":INVALID_ENCODING:",
5927 })
David Benjamin8c2b3bf2015-12-18 20:55:44 -05005928}
5929
Matt Braithwaite54217e42016-06-13 13:03:47 -07005930func addCECPQ1Tests() {
5931 testCases = append(testCases, testCase{
5932 testType: clientTest,
5933 name: "CECPQ1-Client-BadX25519Part",
5934 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005935 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005936 MinVersion: VersionTLS12,
5937 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5938 Bugs: ProtocolBugs{
5939 CECPQ1BadX25519Part: true,
5940 },
5941 },
5942 flags: []string{"-cipher", "kCECPQ1"},
5943 shouldFail: true,
5944 expectedLocalError: "local error: bad record MAC",
5945 })
5946 testCases = append(testCases, testCase{
5947 testType: clientTest,
5948 name: "CECPQ1-Client-BadNewhopePart",
5949 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005950 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005951 MinVersion: VersionTLS12,
5952 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5953 Bugs: ProtocolBugs{
5954 CECPQ1BadNewhopePart: true,
5955 },
5956 },
5957 flags: []string{"-cipher", "kCECPQ1"},
5958 shouldFail: true,
5959 expectedLocalError: "local error: bad record MAC",
5960 })
5961 testCases = append(testCases, testCase{
5962 testType: serverTest,
5963 name: "CECPQ1-Server-BadX25519Part",
5964 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005965 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005966 MinVersion: VersionTLS12,
5967 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5968 Bugs: ProtocolBugs{
5969 CECPQ1BadX25519Part: true,
5970 },
5971 },
5972 flags: []string{"-cipher", "kCECPQ1"},
5973 shouldFail: true,
5974 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5975 })
5976 testCases = append(testCases, testCase{
5977 testType: serverTest,
5978 name: "CECPQ1-Server-BadNewhopePart",
5979 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005980 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07005981 MinVersion: VersionTLS12,
5982 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
5983 Bugs: ProtocolBugs{
5984 CECPQ1BadNewhopePart: true,
5985 },
5986 },
5987 flags: []string{"-cipher", "kCECPQ1"},
5988 shouldFail: true,
5989 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
5990 })
5991}
5992
David Benjamin4cc36ad2015-12-19 14:23:26 -05005993func addKeyExchangeInfoTests() {
5994 testCases = append(testCases, testCase{
David Benjamin4cc36ad2015-12-19 14:23:26 -05005995 name: "KeyExchangeInfo-DHE-Client",
5996 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005997 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05005998 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
5999 Bugs: ProtocolBugs{
6000 // This is a 1234-bit prime number, generated
6001 // with:
6002 // openssl gendh 1234 | openssl asn1parse -i
6003 DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"),
6004 },
6005 },
David Benjamin9e68f192016-06-30 14:55:33 -04006006 flags: []string{"-expect-dhe-group-size", "1234"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05006007 })
6008 testCases = append(testCases, testCase{
6009 testType: serverTest,
6010 name: "KeyExchangeInfo-DHE-Server",
6011 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07006012 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05006013 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
6014 },
6015 // bssl_shim as a server configures a 2048-bit DHE group.
David Benjamin9e68f192016-06-30 14:55:33 -04006016 flags: []string{"-expect-dhe-group-size", "2048"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05006017 })
6018
Nick Harper1fd39d82016-06-14 18:14:35 -07006019 // TODO(davidben): Add TLS 1.3 versions of these tests once the
6020 // handshake is separate.
6021
David Benjamin4cc36ad2015-12-19 14:23:26 -05006022 testCases = append(testCases, testCase{
6023 name: "KeyExchangeInfo-ECDHE-Client",
6024 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07006025 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05006026 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6027 CurvePreferences: []CurveID{CurveX25519},
6028 },
David Benjamin9e68f192016-06-30 14:55:33 -04006029 flags: []string{"-expect-curve-id", "29", "-enable-all-curves"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05006030 })
6031 testCases = append(testCases, testCase{
6032 testType: serverTest,
6033 name: "KeyExchangeInfo-ECDHE-Server",
6034 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07006035 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05006036 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6037 CurvePreferences: []CurveID{CurveX25519},
6038 },
David Benjamin9e68f192016-06-30 14:55:33 -04006039 flags: []string{"-expect-curve-id", "29", "-enable-all-curves"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05006040 })
6041}
6042
David Benjaminc9ae27c2016-06-24 22:56:37 -04006043func addTLS13RecordTests() {
6044 testCases = append(testCases, testCase{
6045 name: "TLS13-RecordPadding",
6046 config: Config{
6047 MaxVersion: VersionTLS13,
6048 MinVersion: VersionTLS13,
6049 Bugs: ProtocolBugs{
6050 RecordPadding: 10,
6051 },
6052 },
6053 })
6054
6055 testCases = append(testCases, testCase{
6056 name: "TLS13-EmptyRecords",
6057 config: Config{
6058 MaxVersion: VersionTLS13,
6059 MinVersion: VersionTLS13,
6060 Bugs: ProtocolBugs{
6061 OmitRecordContents: true,
6062 },
6063 },
6064 shouldFail: true,
6065 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
6066 })
6067
6068 testCases = append(testCases, testCase{
6069 name: "TLS13-OnlyPadding",
6070 config: Config{
6071 MaxVersion: VersionTLS13,
6072 MinVersion: VersionTLS13,
6073 Bugs: ProtocolBugs{
6074 OmitRecordContents: true,
6075 RecordPadding: 10,
6076 },
6077 },
6078 shouldFail: true,
6079 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
6080 })
6081
6082 testCases = append(testCases, testCase{
6083 name: "TLS13-WrongOuterRecord",
6084 config: Config{
6085 MaxVersion: VersionTLS13,
6086 MinVersion: VersionTLS13,
6087 Bugs: ProtocolBugs{
6088 OuterRecordType: recordTypeHandshake,
6089 },
6090 },
6091 shouldFail: true,
6092 expectedError: ":INVALID_OUTER_RECORD_TYPE:",
6093 })
6094}
6095
David Benjamin82261be2016-07-07 14:32:50 -07006096func addChangeCipherSpecTests() {
6097 // Test missing ChangeCipherSpecs.
6098 testCases = append(testCases, testCase{
6099 name: "SkipChangeCipherSpec-Client",
6100 config: Config{
6101 MaxVersion: VersionTLS12,
6102 Bugs: ProtocolBugs{
6103 SkipChangeCipherSpec: true,
6104 },
6105 },
6106 shouldFail: true,
6107 expectedError: ":UNEXPECTED_RECORD:",
6108 })
6109 testCases = append(testCases, testCase{
6110 testType: serverTest,
6111 name: "SkipChangeCipherSpec-Server",
6112 config: Config{
6113 MaxVersion: VersionTLS12,
6114 Bugs: ProtocolBugs{
6115 SkipChangeCipherSpec: true,
6116 },
6117 },
6118 shouldFail: true,
6119 expectedError: ":UNEXPECTED_RECORD:",
6120 })
6121 testCases = append(testCases, testCase{
6122 testType: serverTest,
6123 name: "SkipChangeCipherSpec-Server-NPN",
6124 config: Config{
6125 MaxVersion: VersionTLS12,
6126 NextProtos: []string{"bar"},
6127 Bugs: ProtocolBugs{
6128 SkipChangeCipherSpec: true,
6129 },
6130 },
6131 flags: []string{
6132 "-advertise-npn", "\x03foo\x03bar\x03baz",
6133 },
6134 shouldFail: true,
6135 expectedError: ":UNEXPECTED_RECORD:",
6136 })
6137
6138 // Test synchronization between the handshake and ChangeCipherSpec.
6139 // Partial post-CCS handshake messages before ChangeCipherSpec should be
6140 // rejected. Test both with and without handshake packing to handle both
6141 // when the partial post-CCS message is in its own record and when it is
6142 // attached to the pre-CCS message.
David Benjamin82261be2016-07-07 14:32:50 -07006143 for _, packed := range []bool{false, true} {
6144 var suffix string
6145 if packed {
6146 suffix = "-Packed"
6147 }
6148
6149 testCases = append(testCases, testCase{
6150 name: "FragmentAcrossChangeCipherSpec-Client" + suffix,
6151 config: Config{
6152 MaxVersion: VersionTLS12,
6153 Bugs: ProtocolBugs{
6154 FragmentAcrossChangeCipherSpec: true,
6155 PackHandshakeFlight: packed,
6156 },
6157 },
6158 shouldFail: true,
6159 expectedError: ":UNEXPECTED_RECORD:",
6160 })
6161 testCases = append(testCases, testCase{
6162 name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix,
6163 config: Config{
6164 MaxVersion: VersionTLS12,
6165 },
6166 resumeSession: true,
6167 resumeConfig: &Config{
6168 MaxVersion: VersionTLS12,
6169 Bugs: ProtocolBugs{
6170 FragmentAcrossChangeCipherSpec: true,
6171 PackHandshakeFlight: packed,
6172 },
6173 },
6174 shouldFail: true,
6175 expectedError: ":UNEXPECTED_RECORD:",
6176 })
6177 testCases = append(testCases, testCase{
6178 testType: serverTest,
6179 name: "FragmentAcrossChangeCipherSpec-Server" + suffix,
6180 config: Config{
6181 MaxVersion: VersionTLS12,
6182 Bugs: ProtocolBugs{
6183 FragmentAcrossChangeCipherSpec: true,
6184 PackHandshakeFlight: packed,
6185 },
6186 },
6187 shouldFail: true,
6188 expectedError: ":UNEXPECTED_RECORD:",
6189 })
6190 testCases = append(testCases, testCase{
6191 testType: serverTest,
6192 name: "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix,
6193 config: Config{
6194 MaxVersion: VersionTLS12,
6195 },
6196 resumeSession: true,
6197 resumeConfig: &Config{
6198 MaxVersion: VersionTLS12,
6199 Bugs: ProtocolBugs{
6200 FragmentAcrossChangeCipherSpec: true,
6201 PackHandshakeFlight: packed,
6202 },
6203 },
6204 shouldFail: true,
6205 expectedError: ":UNEXPECTED_RECORD:",
6206 })
6207 testCases = append(testCases, testCase{
6208 testType: serverTest,
6209 name: "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix,
6210 config: Config{
6211 MaxVersion: VersionTLS12,
6212 NextProtos: []string{"bar"},
6213 Bugs: ProtocolBugs{
6214 FragmentAcrossChangeCipherSpec: true,
6215 PackHandshakeFlight: packed,
6216 },
6217 },
6218 flags: []string{
6219 "-advertise-npn", "\x03foo\x03bar\x03baz",
6220 },
6221 shouldFail: true,
6222 expectedError: ":UNEXPECTED_RECORD:",
6223 })
6224 }
6225
David Benjamin61672812016-07-14 23:10:43 -04006226 // Test that, in DTLS, ChangeCipherSpec is not allowed when there are
6227 // messages in the handshake queue. Do this by testing the server
6228 // reading the client Finished, reversing the flight so Finished comes
6229 // first.
6230 testCases = append(testCases, testCase{
6231 protocol: dtls,
6232 testType: serverTest,
6233 name: "SendUnencryptedFinished-DTLS",
6234 config: Config{
6235 MaxVersion: VersionTLS12,
6236 Bugs: ProtocolBugs{
6237 SendUnencryptedFinished: true,
6238 ReverseHandshakeFragments: true,
6239 },
6240 },
6241 shouldFail: true,
6242 expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:",
6243 })
6244
David Benjamin82261be2016-07-07 14:32:50 -07006245 // Test that early ChangeCipherSpecs are handled correctly.
6246 testCases = append(testCases, testCase{
6247 testType: serverTest,
6248 name: "EarlyChangeCipherSpec-server-1",
6249 config: Config{
6250 MaxVersion: VersionTLS12,
6251 Bugs: ProtocolBugs{
6252 EarlyChangeCipherSpec: 1,
6253 },
6254 },
6255 shouldFail: true,
6256 expectedError: ":UNEXPECTED_RECORD:",
6257 })
6258 testCases = append(testCases, testCase{
6259 testType: serverTest,
6260 name: "EarlyChangeCipherSpec-server-2",
6261 config: Config{
6262 MaxVersion: VersionTLS12,
6263 Bugs: ProtocolBugs{
6264 EarlyChangeCipherSpec: 2,
6265 },
6266 },
6267 shouldFail: true,
6268 expectedError: ":UNEXPECTED_RECORD:",
6269 })
6270 testCases = append(testCases, testCase{
6271 protocol: dtls,
6272 name: "StrayChangeCipherSpec",
6273 config: Config{
6274 // TODO(davidben): Once DTLS 1.3 exists, test
6275 // that stray ChangeCipherSpec messages are
6276 // rejected.
6277 MaxVersion: VersionTLS12,
6278 Bugs: ProtocolBugs{
6279 StrayChangeCipherSpec: true,
6280 },
6281 },
6282 })
6283
6284 // Test that the contents of ChangeCipherSpec are checked.
6285 testCases = append(testCases, testCase{
6286 name: "BadChangeCipherSpec-1",
6287 config: Config{
6288 MaxVersion: VersionTLS12,
6289 Bugs: ProtocolBugs{
6290 BadChangeCipherSpec: []byte{2},
6291 },
6292 },
6293 shouldFail: true,
6294 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
6295 })
6296 testCases = append(testCases, testCase{
6297 name: "BadChangeCipherSpec-2",
6298 config: Config{
6299 MaxVersion: VersionTLS12,
6300 Bugs: ProtocolBugs{
6301 BadChangeCipherSpec: []byte{1, 1},
6302 },
6303 },
6304 shouldFail: true,
6305 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
6306 })
6307 testCases = append(testCases, testCase{
6308 protocol: dtls,
6309 name: "BadChangeCipherSpec-DTLS-1",
6310 config: Config{
6311 MaxVersion: VersionTLS12,
6312 Bugs: ProtocolBugs{
6313 BadChangeCipherSpec: []byte{2},
6314 },
6315 },
6316 shouldFail: true,
6317 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
6318 })
6319 testCases = append(testCases, testCase{
6320 protocol: dtls,
6321 name: "BadChangeCipherSpec-DTLS-2",
6322 config: Config{
6323 MaxVersion: VersionTLS12,
6324 Bugs: ProtocolBugs{
6325 BadChangeCipherSpec: []byte{1, 1},
6326 },
6327 },
6328 shouldFail: true,
6329 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
6330 })
6331}
6332
David Benjamin0b8d5da2016-07-15 00:39:56 -04006333func addWrongMessageTypeTests() {
6334 for _, protocol := range []protocol{tls, dtls} {
6335 var suffix string
6336 if protocol == dtls {
6337 suffix = "-DTLS"
6338 }
6339
6340 testCases = append(testCases, testCase{
6341 protocol: protocol,
6342 testType: serverTest,
6343 name: "WrongMessageType-ClientHello" + suffix,
6344 config: Config{
6345 MaxVersion: VersionTLS12,
6346 Bugs: ProtocolBugs{
6347 SendWrongMessageType: typeClientHello,
6348 },
6349 },
6350 shouldFail: true,
6351 expectedError: ":UNEXPECTED_MESSAGE:",
6352 expectedLocalError: "remote error: unexpected message",
6353 })
6354
6355 if protocol == dtls {
6356 testCases = append(testCases, testCase{
6357 protocol: protocol,
6358 name: "WrongMessageType-HelloVerifyRequest" + suffix,
6359 config: Config{
6360 MaxVersion: VersionTLS12,
6361 Bugs: ProtocolBugs{
6362 SendWrongMessageType: typeHelloVerifyRequest,
6363 },
6364 },
6365 shouldFail: true,
6366 expectedError: ":UNEXPECTED_MESSAGE:",
6367 expectedLocalError: "remote error: unexpected message",
6368 })
6369 }
6370
6371 testCases = append(testCases, testCase{
6372 protocol: protocol,
6373 name: "WrongMessageType-ServerHello" + suffix,
6374 config: Config{
6375 MaxVersion: VersionTLS12,
6376 Bugs: ProtocolBugs{
6377 SendWrongMessageType: typeServerHello,
6378 },
6379 },
6380 shouldFail: true,
6381 expectedError: ":UNEXPECTED_MESSAGE:",
6382 expectedLocalError: "remote error: unexpected message",
6383 })
6384
6385 testCases = append(testCases, testCase{
6386 protocol: protocol,
6387 name: "WrongMessageType-ServerCertificate" + suffix,
6388 config: Config{
6389 MaxVersion: VersionTLS12,
6390 Bugs: ProtocolBugs{
6391 SendWrongMessageType: typeCertificate,
6392 },
6393 },
6394 shouldFail: true,
6395 expectedError: ":UNEXPECTED_MESSAGE:",
6396 expectedLocalError: "remote error: unexpected message",
6397 })
6398
6399 testCases = append(testCases, testCase{
6400 protocol: protocol,
6401 name: "WrongMessageType-CertificateStatus" + suffix,
6402 config: Config{
6403 MaxVersion: VersionTLS12,
6404 Bugs: ProtocolBugs{
6405 SendWrongMessageType: typeCertificateStatus,
6406 },
6407 },
6408 flags: []string{"-enable-ocsp-stapling"},
6409 shouldFail: true,
6410 expectedError: ":UNEXPECTED_MESSAGE:",
6411 expectedLocalError: "remote error: unexpected message",
6412 })
6413
6414 testCases = append(testCases, testCase{
6415 protocol: protocol,
6416 name: "WrongMessageType-ServerKeyExchange" + suffix,
6417 config: Config{
6418 MaxVersion: VersionTLS12,
6419 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6420 Bugs: ProtocolBugs{
6421 SendWrongMessageType: typeServerKeyExchange,
6422 },
6423 },
6424 shouldFail: true,
6425 expectedError: ":UNEXPECTED_MESSAGE:",
6426 expectedLocalError: "remote error: unexpected message",
6427 })
6428
6429 testCases = append(testCases, testCase{
6430 protocol: protocol,
6431 name: "WrongMessageType-CertificateRequest" + suffix,
6432 config: Config{
6433 MaxVersion: VersionTLS12,
6434 ClientAuth: RequireAnyClientCert,
6435 Bugs: ProtocolBugs{
6436 SendWrongMessageType: typeCertificateRequest,
6437 },
6438 },
6439 shouldFail: true,
6440 expectedError: ":UNEXPECTED_MESSAGE:",
6441 expectedLocalError: "remote error: unexpected message",
6442 })
6443
6444 testCases = append(testCases, testCase{
6445 protocol: protocol,
6446 name: "WrongMessageType-ServerHelloDone" + suffix,
6447 config: Config{
6448 MaxVersion: VersionTLS12,
6449 Bugs: ProtocolBugs{
6450 SendWrongMessageType: typeServerHelloDone,
6451 },
6452 },
6453 shouldFail: true,
6454 expectedError: ":UNEXPECTED_MESSAGE:",
6455 expectedLocalError: "remote error: unexpected message",
6456 })
6457
6458 testCases = append(testCases, testCase{
6459 testType: serverTest,
6460 protocol: protocol,
6461 name: "WrongMessageType-ClientCertificate" + suffix,
6462 config: Config{
6463 Certificates: []Certificate{rsaCertificate},
6464 MaxVersion: VersionTLS12,
6465 Bugs: ProtocolBugs{
6466 SendWrongMessageType: typeCertificate,
6467 },
6468 },
6469 flags: []string{"-require-any-client-certificate"},
6470 shouldFail: true,
6471 expectedError: ":UNEXPECTED_MESSAGE:",
6472 expectedLocalError: "remote error: unexpected message",
6473 })
6474
6475 testCases = append(testCases, testCase{
6476 testType: serverTest,
6477 protocol: protocol,
6478 name: "WrongMessageType-CertificateVerify" + suffix,
6479 config: Config{
6480 Certificates: []Certificate{rsaCertificate},
6481 MaxVersion: VersionTLS12,
6482 Bugs: ProtocolBugs{
6483 SendWrongMessageType: typeCertificateVerify,
6484 },
6485 },
6486 flags: []string{"-require-any-client-certificate"},
6487 shouldFail: true,
6488 expectedError: ":UNEXPECTED_MESSAGE:",
6489 expectedLocalError: "remote error: unexpected message",
6490 })
6491
6492 testCases = append(testCases, testCase{
6493 testType: serverTest,
6494 protocol: protocol,
6495 name: "WrongMessageType-ClientKeyExchange" + suffix,
6496 config: Config{
6497 MaxVersion: VersionTLS12,
6498 Bugs: ProtocolBugs{
6499 SendWrongMessageType: typeClientKeyExchange,
6500 },
6501 },
6502 shouldFail: true,
6503 expectedError: ":UNEXPECTED_MESSAGE:",
6504 expectedLocalError: "remote error: unexpected message",
6505 })
6506
6507 if protocol != dtls {
6508 testCases = append(testCases, testCase{
6509 testType: serverTest,
6510 protocol: protocol,
6511 name: "WrongMessageType-NextProtocol" + suffix,
6512 config: Config{
6513 MaxVersion: VersionTLS12,
6514 NextProtos: []string{"bar"},
6515 Bugs: ProtocolBugs{
6516 SendWrongMessageType: typeNextProtocol,
6517 },
6518 },
6519 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"},
6520 shouldFail: true,
6521 expectedError: ":UNEXPECTED_MESSAGE:",
6522 expectedLocalError: "remote error: unexpected message",
6523 })
6524
6525 testCases = append(testCases, testCase{
6526 testType: serverTest,
6527 protocol: protocol,
6528 name: "WrongMessageType-ChannelID" + suffix,
6529 config: Config{
6530 MaxVersion: VersionTLS12,
6531 ChannelID: channelIDKey,
6532 Bugs: ProtocolBugs{
6533 SendWrongMessageType: typeChannelID,
6534 },
6535 },
6536 flags: []string{
6537 "-expect-channel-id",
6538 base64.StdEncoding.EncodeToString(channelIDBytes),
6539 },
6540 shouldFail: true,
6541 expectedError: ":UNEXPECTED_MESSAGE:",
6542 expectedLocalError: "remote error: unexpected message",
6543 })
6544 }
6545
6546 testCases = append(testCases, testCase{
6547 testType: serverTest,
6548 protocol: protocol,
6549 name: "WrongMessageType-ClientFinished" + suffix,
6550 config: Config{
6551 MaxVersion: VersionTLS12,
6552 Bugs: ProtocolBugs{
6553 SendWrongMessageType: typeFinished,
6554 },
6555 },
6556 shouldFail: true,
6557 expectedError: ":UNEXPECTED_MESSAGE:",
6558 expectedLocalError: "remote error: unexpected message",
6559 })
6560
6561 testCases = append(testCases, testCase{
6562 protocol: protocol,
6563 name: "WrongMessageType-NewSessionTicket" + suffix,
6564 config: Config{
6565 MaxVersion: VersionTLS12,
6566 Bugs: ProtocolBugs{
6567 SendWrongMessageType: typeNewSessionTicket,
6568 },
6569 },
6570 shouldFail: true,
6571 expectedError: ":UNEXPECTED_MESSAGE:",
6572 expectedLocalError: "remote error: unexpected message",
6573 })
6574
6575 testCases = append(testCases, testCase{
6576 protocol: protocol,
6577 name: "WrongMessageType-ServerFinished" + suffix,
6578 config: Config{
6579 MaxVersion: VersionTLS12,
6580 Bugs: ProtocolBugs{
6581 SendWrongMessageType: typeFinished,
6582 },
6583 },
6584 shouldFail: true,
6585 expectedError: ":UNEXPECTED_MESSAGE:",
6586 expectedLocalError: "remote error: unexpected message",
6587 })
6588
6589 }
6590}
6591
Adam Langley7c803a62015-06-15 15:35:05 -07006592func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
Adam Langley95c29f32014-06-20 12:00:00 -07006593 defer wg.Done()
6594
6595 for test := range c {
Adam Langley69a01602014-11-17 17:26:55 -08006596 var err error
6597
6598 if *mallocTest < 0 {
6599 statusChan <- statusMsg{test: test, started: true}
Adam Langley7c803a62015-06-15 15:35:05 -07006600 err = runTest(test, shimPath, -1)
Adam Langley69a01602014-11-17 17:26:55 -08006601 } else {
6602 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
6603 statusChan <- statusMsg{test: test, started: true}
Adam Langley7c803a62015-06-15 15:35:05 -07006604 if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
Adam Langley69a01602014-11-17 17:26:55 -08006605 if err != nil {
6606 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
6607 }
6608 break
6609 }
6610 }
6611 }
Adam Langley95c29f32014-06-20 12:00:00 -07006612 statusChan <- statusMsg{test: test, err: err}
6613 }
6614}
6615
6616type statusMsg struct {
6617 test *testCase
6618 started bool
6619 err error
6620}
6621
David Benjamin5f237bc2015-02-11 17:14:15 -05006622func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total int) {
Adam Langley95c29f32014-06-20 12:00:00 -07006623 var started, done, failed, lineLen int
Adam Langley95c29f32014-06-20 12:00:00 -07006624
David Benjamin5f237bc2015-02-11 17:14:15 -05006625 testOutput := newTestOutput()
Adam Langley95c29f32014-06-20 12:00:00 -07006626 for msg := range statusChan {
David Benjamin5f237bc2015-02-11 17:14:15 -05006627 if !*pipe {
6628 // Erase the previous status line.
David Benjamin87c8a642015-02-21 01:54:29 -05006629 var erase string
6630 for i := 0; i < lineLen; i++ {
6631 erase += "\b \b"
6632 }
6633 fmt.Print(erase)
David Benjamin5f237bc2015-02-11 17:14:15 -05006634 }
6635
Adam Langley95c29f32014-06-20 12:00:00 -07006636 if msg.started {
6637 started++
6638 } else {
6639 done++
David Benjamin5f237bc2015-02-11 17:14:15 -05006640
6641 if msg.err != nil {
6642 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
6643 failed++
6644 testOutput.addResult(msg.test.name, "FAIL")
6645 } else {
6646 if *pipe {
6647 // Print each test instead of a status line.
6648 fmt.Printf("PASSED (%s)\n", msg.test.name)
6649 }
6650 testOutput.addResult(msg.test.name, "PASS")
6651 }
Adam Langley95c29f32014-06-20 12:00:00 -07006652 }
6653
David Benjamin5f237bc2015-02-11 17:14:15 -05006654 if !*pipe {
6655 // Print a new status line.
6656 line := fmt.Sprintf("%d/%d/%d/%d", failed, done, started, total)
6657 lineLen = len(line)
6658 os.Stdout.WriteString(line)
Adam Langley95c29f32014-06-20 12:00:00 -07006659 }
Adam Langley95c29f32014-06-20 12:00:00 -07006660 }
David Benjamin5f237bc2015-02-11 17:14:15 -05006661
6662 doneChan <- testOutput
Adam Langley95c29f32014-06-20 12:00:00 -07006663}
6664
6665func main() {
Adam Langley95c29f32014-06-20 12:00:00 -07006666 flag.Parse()
Adam Langley7c803a62015-06-15 15:35:05 -07006667 *resourceDir = path.Clean(*resourceDir)
David Benjamin33863262016-07-08 17:20:12 -07006668 initCertificates()
Adam Langley95c29f32014-06-20 12:00:00 -07006669
Adam Langley7c803a62015-06-15 15:35:05 -07006670 addBasicTests()
Adam Langley95c29f32014-06-20 12:00:00 -07006671 addCipherSuiteTests()
6672 addBadECDSASignatureTests()
Adam Langley80842bd2014-06-20 12:00:00 -07006673 addCBCPaddingTests()
Kenny Root7fdeaf12014-08-05 15:23:37 -07006674 addCBCSplittingTests()
David Benjamin636293b2014-07-08 17:59:18 -04006675 addClientAuthTests()
Adam Langley524e7172015-02-20 16:04:00 -08006676 addDDoSCallbackTests()
David Benjamin7e2e6cf2014-08-07 17:44:24 -04006677 addVersionNegotiationTests()
David Benjaminaccb4542014-12-12 23:44:33 -05006678 addMinimumVersionTests()
David Benjamine78bfde2014-09-06 12:45:15 -04006679 addExtensionTests()
David Benjamin01fe8202014-09-24 15:21:44 -04006680 addResumptionVersionTests()
Adam Langley75712922014-10-10 16:23:43 -07006681 addExtendedMasterSecretTests()
Adam Langley2ae77d22014-10-28 17:29:33 -07006682 addRenegotiationTests()
David Benjamin5e961c12014-11-07 01:48:35 -05006683 addDTLSReplayTests()
Nick Harper60edffd2016-06-21 15:19:24 -07006684 addSignatureAlgorithmTests()
David Benjamin83f90402015-01-27 01:09:43 -05006685 addDTLSRetransmitTests()
David Benjaminc565ebb2015-04-03 04:06:36 -04006686 addExportKeyingMaterialTests()
Adam Langleyaf0e32c2015-06-03 09:57:23 -07006687 addTLSUniqueTests()
Adam Langley09505632015-07-30 18:10:13 -07006688 addCustomExtensionTests()
David Benjaminb36a3952015-12-01 18:53:13 -05006689 addRSAClientKeyExchangeTests()
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006690 addCurveTests()
Matt Braithwaite54217e42016-06-13 13:03:47 -07006691 addCECPQ1Tests()
David Benjamin4cc36ad2015-12-19 14:23:26 -05006692 addKeyExchangeInfoTests()
David Benjaminc9ae27c2016-06-24 22:56:37 -04006693 addTLS13RecordTests()
David Benjamin582ba042016-07-07 12:33:25 -07006694 addAllStateMachineCoverageTests()
David Benjamin82261be2016-07-07 14:32:50 -07006695 addChangeCipherSpecTests()
David Benjamin0b8d5da2016-07-15 00:39:56 -04006696 addWrongMessageTypeTests()
Adam Langley95c29f32014-06-20 12:00:00 -07006697
6698 var wg sync.WaitGroup
6699
Adam Langley7c803a62015-06-15 15:35:05 -07006700 statusChan := make(chan statusMsg, *numWorkers)
6701 testChan := make(chan *testCase, *numWorkers)
David Benjamin5f237bc2015-02-11 17:14:15 -05006702 doneChan := make(chan *testOutput)
Adam Langley95c29f32014-06-20 12:00:00 -07006703
David Benjamin025b3d32014-07-01 19:53:04 -04006704 go statusPrinter(doneChan, statusChan, len(testCases))
Adam Langley95c29f32014-06-20 12:00:00 -07006705
Adam Langley7c803a62015-06-15 15:35:05 -07006706 for i := 0; i < *numWorkers; i++ {
Adam Langley95c29f32014-06-20 12:00:00 -07006707 wg.Add(1)
Adam Langley7c803a62015-06-15 15:35:05 -07006708 go worker(statusChan, testChan, *shimPath, &wg)
Adam Langley95c29f32014-06-20 12:00:00 -07006709 }
6710
David Benjamin270f0a72016-03-17 14:41:36 -04006711 var foundTest bool
David Benjamin025b3d32014-07-01 19:53:04 -04006712 for i := range testCases {
Adam Langley7c803a62015-06-15 15:35:05 -07006713 if len(*testToRun) == 0 || *testToRun == testCases[i].name {
David Benjamin270f0a72016-03-17 14:41:36 -04006714 foundTest = true
David Benjamin025b3d32014-07-01 19:53:04 -04006715 testChan <- &testCases[i]
Adam Langley95c29f32014-06-20 12:00:00 -07006716 }
6717 }
David Benjamin270f0a72016-03-17 14:41:36 -04006718 if !foundTest {
6719 fmt.Fprintf(os.Stderr, "No test named '%s'\n", *testToRun)
6720 os.Exit(1)
6721 }
Adam Langley95c29f32014-06-20 12:00:00 -07006722
6723 close(testChan)
6724 wg.Wait()
6725 close(statusChan)
David Benjamin5f237bc2015-02-11 17:14:15 -05006726 testOutput := <-doneChan
Adam Langley95c29f32014-06-20 12:00:00 -07006727
6728 fmt.Printf("\n")
David Benjamin5f237bc2015-02-11 17:14:15 -05006729
6730 if *jsonOutput != "" {
6731 if err := testOutput.writeTo(*jsonOutput); err != nil {
6732 fmt.Fprintf(os.Stderr, "Error: %s\n", err)
6733 }
6734 }
David Benjamin2ab7a862015-04-04 17:02:18 -04006735
6736 if !testOutput.allPassed {
6737 os.Exit(1)
6738 }
Adam Langley95c29f32014-06-20 12:00:00 -07006739}