blob: 162b15edcbc64442cf32271235745566cadf4e90 [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
David Benjamin0d1b0962016-08-01 09:50:57 -040013// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Adam Langley7fcfd3b2016-05-20 11:02:50 -070014
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"
EKRf71d7ed2016-08-06 13:25:12 -070023 "encoding/json"
David Benjamina08e49d2014-08-24 01:46:07 -040024 "encoding/pem"
EKR842ae6c2016-07-27 09:22:05 +020025 "errors"
Adam Langley95c29f32014-06-20 12:00:00 -070026 "flag"
27 "fmt"
28 "io"
Kenny Root7fdeaf12014-08-05 15:23:37 -070029 "io/ioutil"
Adam Langleya7997f12015-05-14 17:38:50 -070030 "math/big"
Adam Langley95c29f32014-06-20 12:00:00 -070031 "net"
32 "os"
33 "os/exec"
David Benjamin884fdf12014-08-02 15:28:23 -040034 "path"
David Benjamin17e12922016-07-28 18:04:43 -040035 "path/filepath"
David Benjamin2bc8e6f2014-08-02 15:22:37 -040036 "runtime"
Adam Langley69a01602014-11-17 17:26:55 -080037 "strconv"
Adam Langley95c29f32014-06-20 12:00:00 -070038 "strings"
39 "sync"
40 "syscall"
David Benjamin83f90402015-01-27 01:09:43 -050041 "time"
Adam Langley95c29f32014-06-20 12:00:00 -070042)
43
Adam Langley69a01602014-11-17 17:26:55 -080044var (
EKR842ae6c2016-07-27 09:22:05 +020045 useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
46 useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
47 useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb")
48 flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection")
49 mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
50 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.")
51 jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
52 pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
David Benjamin17e12922016-07-28 18:04:43 -040053 testToRun = flag.String("test", "", "The pattern to filter tests to run, or empty to run all tests")
EKR842ae6c2016-07-27 09:22:05 +020054 numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
55 shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
56 resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
57 fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.")
58 transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.")
59 idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.")
60 deterministic = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.")
61 allowUnimplemented = flag.Bool("allow-unimplemented", false, "If true, report pass even if some tests are unimplemented.")
EKR173bf932016-07-29 15:52:49 +020062 looseErrors = flag.Bool("loose-errors", false, "If true, allow shims to report an untranslated error code.")
EKRf71d7ed2016-08-06 13:25:12 -070063 shimConfigFile = flag.String("shim-config", "", "A config file to use to configure the tests for this shim.")
64 includeDisabled = flag.Bool("include-disabled", false, "If true, also runs disabled tests.")
Adam Langley69a01602014-11-17 17:26:55 -080065)
Adam Langley95c29f32014-06-20 12:00:00 -070066
EKRf71d7ed2016-08-06 13:25:12 -070067// ShimConfigurations is used with the “json” package and represents a shim
68// config file.
69type ShimConfiguration struct {
70 // DisabledTests maps from a glob-based pattern to a freeform string.
71 // The glob pattern is used to exclude tests from being run and the
72 // freeform string is unparsed but expected to explain why the test is
73 // disabled.
74 DisabledTests map[string]string
75
76 // ErrorMap maps from expected error strings to the correct error
77 // string for the shim in question. For example, it might map
78 // “:NO_SHARED_CIPHER:” (a BoringSSL error string) to something
79 // like “SSL_ERROR_NO_CYPHER_OVERLAP”.
80 ErrorMap map[string]string
81}
82
83var shimConfig ShimConfiguration
84
David Benjamin33863262016-07-08 17:20:12 -070085type testCert int
86
David Benjamin025b3d32014-07-01 19:53:04 -040087const (
David Benjamin33863262016-07-08 17:20:12 -070088 testCertRSA testCert = iota
David Benjamin7944a9f2016-07-12 22:27:01 -040089 testCertRSA1024
David Benjamin33863262016-07-08 17:20:12 -070090 testCertECDSAP256
91 testCertECDSAP384
92 testCertECDSAP521
93)
94
95const (
96 rsaCertificateFile = "cert.pem"
David Benjamin7944a9f2016-07-12 22:27:01 -040097 rsa1024CertificateFile = "rsa_1024_cert.pem"
David Benjamin33863262016-07-08 17:20:12 -070098 ecdsaP256CertificateFile = "ecdsa_p256_cert.pem"
99 ecdsaP384CertificateFile = "ecdsa_p384_cert.pem"
100 ecdsaP521CertificateFile = "ecdsa_p521_cert.pem"
David Benjamin025b3d32014-07-01 19:53:04 -0400101)
102
103const (
David Benjamina08e49d2014-08-24 01:46:07 -0400104 rsaKeyFile = "key.pem"
David Benjamin7944a9f2016-07-12 22:27:01 -0400105 rsa1024KeyFile = "rsa_1024_key.pem"
David Benjamin33863262016-07-08 17:20:12 -0700106 ecdsaP256KeyFile = "ecdsa_p256_key.pem"
107 ecdsaP384KeyFile = "ecdsa_p384_key.pem"
108 ecdsaP521KeyFile = "ecdsa_p521_key.pem"
David Benjamina08e49d2014-08-24 01:46:07 -0400109 channelIDKeyFile = "channel_id_key.pem"
David Benjamin025b3d32014-07-01 19:53:04 -0400110)
111
David Benjamin7944a9f2016-07-12 22:27:01 -0400112var (
113 rsaCertificate Certificate
114 rsa1024Certificate Certificate
115 ecdsaP256Certificate Certificate
116 ecdsaP384Certificate Certificate
117 ecdsaP521Certificate Certificate
118)
David Benjamin33863262016-07-08 17:20:12 -0700119
120var testCerts = []struct {
121 id testCert
122 certFile, keyFile string
123 cert *Certificate
124}{
125 {
126 id: testCertRSA,
127 certFile: rsaCertificateFile,
128 keyFile: rsaKeyFile,
129 cert: &rsaCertificate,
130 },
131 {
David Benjamin7944a9f2016-07-12 22:27:01 -0400132 id: testCertRSA1024,
133 certFile: rsa1024CertificateFile,
134 keyFile: rsa1024KeyFile,
135 cert: &rsa1024Certificate,
136 },
137 {
David Benjamin33863262016-07-08 17:20:12 -0700138 id: testCertECDSAP256,
139 certFile: ecdsaP256CertificateFile,
140 keyFile: ecdsaP256KeyFile,
141 cert: &ecdsaP256Certificate,
142 },
143 {
144 id: testCertECDSAP384,
145 certFile: ecdsaP384CertificateFile,
146 keyFile: ecdsaP384KeyFile,
147 cert: &ecdsaP384Certificate,
148 },
149 {
150 id: testCertECDSAP521,
151 certFile: ecdsaP521CertificateFile,
152 keyFile: ecdsaP521KeyFile,
153 cert: &ecdsaP521Certificate,
154 },
155}
156
David Benjamina08e49d2014-08-24 01:46:07 -0400157var channelIDKey *ecdsa.PrivateKey
158var channelIDBytes []byte
Adam Langley95c29f32014-06-20 12:00:00 -0700159
David Benjamin61f95272014-11-25 01:55:35 -0500160var testOCSPResponse = []byte{1, 2, 3, 4}
161var testSCTList = []byte{5, 6, 7, 8}
162
Adam Langley95c29f32014-06-20 12:00:00 -0700163func initCertificates() {
David Benjamin33863262016-07-08 17:20:12 -0700164 for i := range testCerts {
165 cert, err := LoadX509KeyPair(path.Join(*resourceDir, testCerts[i].certFile), path.Join(*resourceDir, testCerts[i].keyFile))
166 if err != nil {
167 panic(err)
168 }
169 cert.OCSPStaple = testOCSPResponse
170 cert.SignedCertificateTimestampList = testSCTList
171 *testCerts[i].cert = cert
Adam Langley95c29f32014-06-20 12:00:00 -0700172 }
David Benjamina08e49d2014-08-24 01:46:07 -0400173
Adam Langley7c803a62015-06-15 15:35:05 -0700174 channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
David Benjamina08e49d2014-08-24 01:46:07 -0400175 if err != nil {
176 panic(err)
177 }
178 channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock)
179 if channelIDDERBlock.Type != "EC PRIVATE KEY" {
180 panic("bad key type")
181 }
182 channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes)
183 if err != nil {
184 panic(err)
185 }
186 if channelIDKey.Curve != elliptic.P256() {
187 panic("bad curve")
188 }
189
190 channelIDBytes = make([]byte, 64)
191 writeIntPadded(channelIDBytes[:32], channelIDKey.X)
192 writeIntPadded(channelIDBytes[32:], channelIDKey.Y)
Adam Langley95c29f32014-06-20 12:00:00 -0700193}
194
David Benjamin33863262016-07-08 17:20:12 -0700195func getRunnerCertificate(t testCert) Certificate {
196 for _, cert := range testCerts {
197 if cert.id == t {
198 return *cert.cert
199 }
200 }
201 panic("Unknown test certificate")
Adam Langley95c29f32014-06-20 12:00:00 -0700202}
203
David Benjamin33863262016-07-08 17:20:12 -0700204func getShimCertificate(t testCert) string {
205 for _, cert := range testCerts {
206 if cert.id == t {
207 return cert.certFile
208 }
209 }
210 panic("Unknown test certificate")
211}
212
213func getShimKey(t testCert) string {
214 for _, cert := range testCerts {
215 if cert.id == t {
216 return cert.keyFile
217 }
218 }
219 panic("Unknown test certificate")
Adam Langley95c29f32014-06-20 12:00:00 -0700220}
221
David Benjamin025b3d32014-07-01 19:53:04 -0400222type testType int
223
224const (
225 clientTest testType = iota
226 serverTest
227)
228
David Benjamin6fd297b2014-08-11 18:43:38 -0400229type protocol int
230
231const (
232 tls protocol = iota
233 dtls
234)
235
David Benjaminfc7b0862014-09-06 13:21:53 -0400236const (
237 alpn = 1
238 npn = 2
239)
240
Adam Langley95c29f32014-06-20 12:00:00 -0700241type testCase struct {
David Benjamin025b3d32014-07-01 19:53:04 -0400242 testType testType
David Benjamin6fd297b2014-08-11 18:43:38 -0400243 protocol protocol
Adam Langley95c29f32014-06-20 12:00:00 -0700244 name string
245 config Config
246 shouldFail bool
247 expectedError string
Adam Langleyac61fa32014-06-23 12:03:11 -0700248 // expectedLocalError, if not empty, contains a substring that must be
249 // found in the local error.
250 expectedLocalError string
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400251 // expectedVersion, if non-zero, specifies the TLS version that must be
252 // negotiated.
253 expectedVersion uint16
David Benjamin01fe8202014-09-24 15:21:44 -0400254 // expectedResumeVersion, if non-zero, specifies the TLS version that
255 // must be negotiated on resumption. If zero, expectedVersion is used.
256 expectedResumeVersion uint16
David Benjamin90da8c82015-04-20 14:57:57 -0400257 // expectedCipher, if non-zero, specifies the TLS cipher suite that
258 // should be negotiated.
259 expectedCipher uint16
David Benjamina08e49d2014-08-24 01:46:07 -0400260 // expectChannelID controls whether the connection should have
261 // negotiated a Channel ID with channelIDKey.
262 expectChannelID bool
David Benjaminae2888f2014-09-06 12:58:58 -0400263 // expectedNextProto controls whether the connection should
264 // negotiate a next protocol via NPN or ALPN.
265 expectedNextProto string
David Benjaminc7ce9772015-10-09 19:32:41 -0400266 // expectNoNextProto, if true, means that no next protocol should be
267 // negotiated.
268 expectNoNextProto bool
David Benjaminfc7b0862014-09-06 13:21:53 -0400269 // expectedNextProtoType, if non-zero, is the expected next
270 // protocol negotiation mechanism.
271 expectedNextProtoType int
David Benjaminca6c8262014-11-15 19:06:08 -0500272 // expectedSRTPProtectionProfile is the DTLS-SRTP profile that
273 // should be negotiated. If zero, none should be negotiated.
274 expectedSRTPProtectionProfile uint16
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100275 // expectedOCSPResponse, if not nil, is the expected OCSP response to be received.
276 expectedOCSPResponse []uint8
Paul Lietar4fac72e2015-09-09 13:44:55 +0100277 // expectedSCTList, if not nil, is the expected SCT list to be received.
278 expectedSCTList []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700279 // expectedPeerSignatureAlgorithm, if not zero, is the signature
280 // algorithm that the peer should have used in the handshake.
281 expectedPeerSignatureAlgorithm signatureAlgorithm
Steven Valdez5440fe02016-07-18 12:40:30 -0400282 // expectedCurveID, if not zero, is the curve that the handshake should
283 // have used.
284 expectedCurveID CurveID
Adam Langley80842bd2014-06-20 12:00:00 -0700285 // messageLen is the length, in bytes, of the test message that will be
286 // sent.
287 messageLen int
David Benjamin8e6db492015-07-25 18:29:23 -0400288 // messageCount is the number of test messages that will be sent.
289 messageCount int
David Benjamin025b3d32014-07-01 19:53:04 -0400290 // certFile is the path to the certificate to use for the server.
291 certFile string
292 // keyFile is the path to the private key to use for the server.
293 keyFile string
David Benjamin1d5c83e2014-07-22 19:20:02 -0400294 // resumeSession controls whether a second connection should be tested
David Benjamin01fe8202014-09-24 15:21:44 -0400295 // which attempts to resume the first session.
David Benjamin1d5c83e2014-07-22 19:20:02 -0400296 resumeSession bool
David Benjamin46662482016-08-17 00:51:00 -0400297 // resumeRenewedSession controls whether a third connection should be
298 // tested which attempts to resume the second connection's session.
299 resumeRenewedSession bool
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700300 // expectResumeRejected, if true, specifies that the attempted
301 // resumption must be rejected by the client. This is only valid for a
302 // serverTest.
303 expectResumeRejected bool
David Benjamin01fe8202014-09-24 15:21:44 -0400304 // resumeConfig, if not nil, points to a Config to be used on
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500305 // resumption. Unless newSessionsOnResume is set,
306 // SessionTicketKey, ServerSessionCache, and
307 // ClientSessionCache are copied from the initial connection's
308 // config. If nil, the initial connection's config is used.
David Benjamin01fe8202014-09-24 15:21:44 -0400309 resumeConfig *Config
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500310 // newSessionsOnResume, if true, will cause resumeConfig to
311 // use a different session resumption context.
312 newSessionsOnResume bool
David Benjaminba4594a2015-06-18 18:36:15 -0400313 // noSessionCache, if true, will cause the server to run without a
314 // session cache.
315 noSessionCache bool
David Benjamin98e882e2014-08-08 13:24:34 -0400316 // sendPrefix sends a prefix on the socket before actually performing a
317 // handshake.
318 sendPrefix string
David Benjamine58c4f52014-08-24 03:47:07 -0400319 // shimWritesFirst controls whether the shim sends an initial "hello"
320 // message before doing a roundtrip with the runner.
321 shimWritesFirst bool
David Benjamin30789da2015-08-29 22:56:45 -0400322 // shimShutsDown, if true, runs a test where the shim shuts down the
323 // connection immediately after the handshake rather than echoing
324 // messages from the runner.
325 shimShutsDown bool
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400326 // renegotiate indicates the number of times the connection should be
327 // renegotiated during the exchange.
328 renegotiate int
David Benjamin47921102016-07-28 11:29:18 -0400329 // sendHalfHelloRequest, if true, causes the server to send half a
330 // HelloRequest when the handshake completes.
331 sendHalfHelloRequest bool
Adam Langleycf2d4f42014-10-28 19:06:14 -0700332 // renegotiateCiphers is a list of ciphersuite ids that will be
333 // switched in just before renegotiation.
334 renegotiateCiphers []uint16
David Benjamin5e961c12014-11-07 01:48:35 -0500335 // replayWrites, if true, configures the underlying transport
336 // to replay every write it makes in DTLS tests.
337 replayWrites bool
David Benjamin5fa3eba2015-01-22 16:35:40 -0500338 // damageFirstWrite, if true, configures the underlying transport to
339 // damage the final byte of the first application data write.
340 damageFirstWrite bool
David Benjaminc565ebb2015-04-03 04:06:36 -0400341 // exportKeyingMaterial, if non-zero, configures the test to exchange
342 // keying material and verify they match.
343 exportKeyingMaterial int
344 exportLabel string
345 exportContext string
346 useExportContext bool
David Benjamin325b5c32014-07-01 19:40:31 -0400347 // flags, if not empty, contains a list of command-line flags that will
348 // be passed to the shim program.
349 flags []string
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700350 // testTLSUnique, if true, causes the shim to send the tls-unique value
351 // which will be compared against the expected value.
352 testTLSUnique bool
David Benjamina8ebe222015-06-06 03:04:39 -0400353 // sendEmptyRecords is the number of consecutive empty records to send
354 // before and after the test message.
355 sendEmptyRecords int
David Benjamin24f346d2015-06-06 03:28:08 -0400356 // sendWarningAlerts is the number of consecutive warning alerts to send
357 // before and after the test message.
358 sendWarningAlerts int
Steven Valdez32635b82016-08-16 11:25:03 -0400359 // sendKeyUpdates is the number of consecutive key updates to send
360 // before and after the test message.
361 sendKeyUpdates int
David Benjamin4f75aaf2015-09-01 16:53:10 -0400362 // expectMessageDropped, if true, means the test message is expected to
363 // be dropped by the client rather than echoed back.
364 expectMessageDropped bool
Adam Langley95c29f32014-06-20 12:00:00 -0700365}
366
Adam Langley7c803a62015-06-15 15:35:05 -0700367var testCases []testCase
Adam Langley95c29f32014-06-20 12:00:00 -0700368
David Benjamin9867b7d2016-03-01 23:25:48 -0500369func writeTranscript(test *testCase, isResume bool, data []byte) {
370 if len(data) == 0 {
371 return
372 }
373
374 protocol := "tls"
375 if test.protocol == dtls {
376 protocol = "dtls"
377 }
378
379 side := "client"
380 if test.testType == serverTest {
381 side = "server"
382 }
383
384 dir := path.Join(*transcriptDir, protocol, side)
385 if err := os.MkdirAll(dir, 0755); err != nil {
386 fmt.Fprintf(os.Stderr, "Error making %s: %s\n", dir, err)
387 return
388 }
389
390 name := test.name
391 if isResume {
392 name += "-Resume"
393 } else {
394 name += "-Normal"
395 }
396
397 if err := ioutil.WriteFile(path.Join(dir, name), data, 0644); err != nil {
398 fmt.Fprintf(os.Stderr, "Error writing %s: %s\n", name, err)
399 }
400}
401
David Benjamin3ed59772016-03-08 12:50:21 -0500402// A timeoutConn implements an idle timeout on each Read and Write operation.
403type timeoutConn struct {
404 net.Conn
405 timeout time.Duration
406}
407
408func (t *timeoutConn) Read(b []byte) (int, error) {
409 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil {
410 return 0, err
411 }
412 return t.Conn.Read(b)
413}
414
415func (t *timeoutConn) Write(b []byte) (int, error) {
416 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil {
417 return 0, err
418 }
419 return t.Conn.Write(b)
420}
421
David Benjamin8e6db492015-07-25 18:29:23 -0400422func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
David Benjamine54af062016-08-08 19:21:18 -0400423 if !test.noSessionCache {
424 if config.ClientSessionCache == nil {
425 config.ClientSessionCache = NewLRUClientSessionCache(1)
426 }
427 if config.ServerSessionCache == nil {
428 config.ServerSessionCache = NewLRUServerSessionCache(1)
429 }
430 }
431 if test.testType == clientTest {
432 if len(config.Certificates) == 0 {
433 config.Certificates = []Certificate{rsaCertificate}
434 }
435 } else {
436 // Supply a ServerName to ensure a constant session cache key,
437 // rather than falling back to net.Conn.RemoteAddr.
438 if len(config.ServerName) == 0 {
439 config.ServerName = "test"
440 }
441 }
442 if *fuzzer {
443 config.Bugs.NullAllCiphers = true
444 }
David Benjamin01a90572016-09-22 00:11:43 -0400445 if *deterministic {
446 config.Time = func() time.Time { return time.Unix(1234, 1234) }
447 }
David Benjamine54af062016-08-08 19:21:18 -0400448
David Benjamin01784b42016-06-07 18:00:52 -0400449 conn = &timeoutConn{conn, *idleTimeout}
David Benjamin65ea8ff2014-11-23 03:01:00 -0500450
David Benjamin6fd297b2014-08-11 18:43:38 -0400451 if test.protocol == dtls {
David Benjamin83f90402015-01-27 01:09:43 -0500452 config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
453 conn = config.Bugs.PacketAdaptor
David Benjaminebda9b32015-11-02 15:33:18 -0500454 }
455
David Benjamin9867b7d2016-03-01 23:25:48 -0500456 if *flagDebug || len(*transcriptDir) != 0 {
David Benjaminebda9b32015-11-02 15:33:18 -0500457 local, peer := "client", "server"
458 if test.testType == clientTest {
459 local, peer = peer, local
David Benjamin5e961c12014-11-07 01:48:35 -0500460 }
David Benjaminebda9b32015-11-02 15:33:18 -0500461 connDebug := &recordingConn{
462 Conn: conn,
463 isDatagram: test.protocol == dtls,
464 local: local,
465 peer: peer,
466 }
467 conn = connDebug
David Benjamin9867b7d2016-03-01 23:25:48 -0500468 if *flagDebug {
469 defer connDebug.WriteTo(os.Stdout)
470 }
471 if len(*transcriptDir) != 0 {
472 defer func() {
473 writeTranscript(test, isResume, connDebug.Transcript())
474 }()
475 }
David Benjaminebda9b32015-11-02 15:33:18 -0500476
477 if config.Bugs.PacketAdaptor != nil {
478 config.Bugs.PacketAdaptor.debug = connDebug
479 }
480 }
481
482 if test.replayWrites {
483 conn = newReplayAdaptor(conn)
David Benjamin6fd297b2014-08-11 18:43:38 -0400484 }
485
David Benjamin3ed59772016-03-08 12:50:21 -0500486 var connDamage *damageAdaptor
David Benjamin5fa3eba2015-01-22 16:35:40 -0500487 if test.damageFirstWrite {
488 connDamage = newDamageAdaptor(conn)
489 conn = connDamage
490 }
491
David Benjamin6fd297b2014-08-11 18:43:38 -0400492 if test.sendPrefix != "" {
493 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil {
494 return err
495 }
David Benjamin98e882e2014-08-08 13:24:34 -0400496 }
497
David Benjamin1d5c83e2014-07-22 19:20:02 -0400498 var tlsConn *Conn
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400499 if test.testType == clientTest {
David Benjamin6fd297b2014-08-11 18:43:38 -0400500 if test.protocol == dtls {
501 tlsConn = DTLSServer(conn, config)
502 } else {
503 tlsConn = Server(conn, config)
504 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400505 } else {
506 config.InsecureSkipVerify = true
David Benjamin6fd297b2014-08-11 18:43:38 -0400507 if test.protocol == dtls {
508 tlsConn = DTLSClient(conn, config)
509 } else {
510 tlsConn = Client(conn, config)
511 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400512 }
David Benjamin30789da2015-08-29 22:56:45 -0400513 defer tlsConn.Close()
David Benjamin1d5c83e2014-07-22 19:20:02 -0400514
Adam Langley95c29f32014-06-20 12:00:00 -0700515 if err := tlsConn.Handshake(); err != nil {
516 return err
517 }
Kenny Root7fdeaf12014-08-05 15:23:37 -0700518
David Benjamin01fe8202014-09-24 15:21:44 -0400519 // TODO(davidben): move all per-connection expectations into a dedicated
520 // expectations struct that can be specified separately for the two
521 // legs.
522 expectedVersion := test.expectedVersion
523 if isResume && test.expectedResumeVersion != 0 {
524 expectedVersion = test.expectedResumeVersion
525 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700526 connState := tlsConn.ConnectionState()
527 if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion {
David Benjamin01fe8202014-09-24 15:21:44 -0400528 return fmt.Errorf("got version %x, expected %x", vers, expectedVersion)
David Benjamin7e2e6cf2014-08-07 17:44:24 -0400529 }
530
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700531 if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
David Benjamin90da8c82015-04-20 14:57:57 -0400532 return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher)
533 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700534 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
535 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
536 }
David Benjamin90da8c82015-04-20 14:57:57 -0400537
David Benjamina08e49d2014-08-24 01:46:07 -0400538 if test.expectChannelID {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700539 channelID := connState.ChannelID
David Benjamina08e49d2014-08-24 01:46:07 -0400540 if channelID == nil {
541 return fmt.Errorf("no channel ID negotiated")
542 }
543 if channelID.Curve != channelIDKey.Curve ||
544 channelIDKey.X.Cmp(channelIDKey.X) != 0 ||
545 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 {
546 return fmt.Errorf("incorrect channel ID")
547 }
548 }
549
David Benjaminae2888f2014-09-06 12:58:58 -0400550 if expected := test.expectedNextProto; expected != "" {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700551 if actual := connState.NegotiatedProtocol; actual != expected {
David Benjaminae2888f2014-09-06 12:58:58 -0400552 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
553 }
554 }
555
David Benjaminc7ce9772015-10-09 19:32:41 -0400556 if test.expectNoNextProto {
557 if actual := connState.NegotiatedProtocol; actual != "" {
558 return fmt.Errorf("got unexpected next proto %s", actual)
559 }
560 }
561
David Benjaminfc7b0862014-09-06 13:21:53 -0400562 if test.expectedNextProtoType != 0 {
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700563 if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
David Benjaminfc7b0862014-09-06 13:21:53 -0400564 return fmt.Errorf("next proto type mismatch")
565 }
566 }
567
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700568 if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
David Benjaminca6c8262014-11-15 19:06:08 -0500569 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
570 }
571
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100572 if test.expectedOCSPResponse != nil && !bytes.Equal(test.expectedOCSPResponse, tlsConn.OCSPResponse()) {
David Benjamin942f4ed2016-07-16 19:03:49 +0300573 return fmt.Errorf("OCSP Response mismatch: got %x, wanted %x", tlsConn.OCSPResponse(), test.expectedOCSPResponse)
Paul Lietaraeeff2c2015-08-12 11:47:11 +0100574 }
575
Paul Lietar4fac72e2015-09-09 13:44:55 +0100576 if test.expectedSCTList != nil && !bytes.Equal(test.expectedSCTList, connState.SCTList) {
577 return fmt.Errorf("SCT list mismatch")
578 }
579
Nick Harper60edffd2016-06-21 15:19:24 -0700580 if expected := test.expectedPeerSignatureAlgorithm; expected != 0 && expected != connState.PeerSignatureAlgorithm {
581 return fmt.Errorf("expected peer to use signature algorithm %04x, but got %04x", expected, connState.PeerSignatureAlgorithm)
Steven Valdez0d62f262015-09-04 12:41:04 -0400582 }
583
Steven Valdez5440fe02016-07-18 12:40:30 -0400584 if expected := test.expectedCurveID; expected != 0 && expected != connState.CurveID {
585 return fmt.Errorf("expected peer to use curve %04x, but got %04x", expected, connState.CurveID)
586 }
587
David Benjaminc565ebb2015-04-03 04:06:36 -0400588 if test.exportKeyingMaterial > 0 {
589 actual := make([]byte, test.exportKeyingMaterial)
590 if _, err := io.ReadFull(tlsConn, actual); err != nil {
591 return err
592 }
593 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext)
594 if err != nil {
595 return err
596 }
597 if !bytes.Equal(actual, expected) {
598 return fmt.Errorf("keying material mismatch")
599 }
600 }
601
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700602 if test.testTLSUnique {
603 var peersValue [12]byte
604 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
605 return err
606 }
607 expected := tlsConn.ConnectionState().TLSUnique
608 if !bytes.Equal(peersValue[:], expected) {
609 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
610 }
611 }
612
David Benjamine58c4f52014-08-24 03:47:07 -0400613 if test.shimWritesFirst {
614 var buf [5]byte
615 _, err := io.ReadFull(tlsConn, buf[:])
616 if err != nil {
617 return err
618 }
619 if string(buf[:]) != "hello" {
620 return fmt.Errorf("bad initial message")
621 }
622 }
623
Steven Valdez32635b82016-08-16 11:25:03 -0400624 for i := 0; i < test.sendKeyUpdates; i++ {
625 tlsConn.SendKeyUpdate()
626 }
627
David Benjamina8ebe222015-06-06 03:04:39 -0400628 for i := 0; i < test.sendEmptyRecords; i++ {
629 tlsConn.Write(nil)
630 }
631
David Benjamin24f346d2015-06-06 03:28:08 -0400632 for i := 0; i < test.sendWarningAlerts; i++ {
633 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
634 }
635
David Benjamin47921102016-07-28 11:29:18 -0400636 if test.sendHalfHelloRequest {
637 tlsConn.SendHalfHelloRequest()
638 }
639
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400640 if test.renegotiate > 0 {
Adam Langleycf2d4f42014-10-28 19:06:14 -0700641 if test.renegotiateCiphers != nil {
642 config.CipherSuites = test.renegotiateCiphers
643 }
David Benjamin1d5ef3b2015-10-12 19:54:18 -0400644 for i := 0; i < test.renegotiate; i++ {
645 if err := tlsConn.Renegotiate(); err != nil {
646 return err
647 }
Adam Langleycf2d4f42014-10-28 19:06:14 -0700648 }
649 } else if test.renegotiateCiphers != nil {
650 panic("renegotiateCiphers without renegotiate")
651 }
652
David Benjamin5fa3eba2015-01-22 16:35:40 -0500653 if test.damageFirstWrite {
654 connDamage.setDamage(true)
655 tlsConn.Write([]byte("DAMAGED WRITE"))
656 connDamage.setDamage(false)
657 }
658
David Benjamin8e6db492015-07-25 18:29:23 -0400659 messageLen := test.messageLen
Kenny Root7fdeaf12014-08-05 15:23:37 -0700660 if messageLen < 0 {
David Benjamin6fd297b2014-08-11 18:43:38 -0400661 if test.protocol == dtls {
662 return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
663 }
Kenny Root7fdeaf12014-08-05 15:23:37 -0700664 // Read until EOF.
665 _, err := io.Copy(ioutil.Discard, tlsConn)
666 return err
667 }
David Benjamin4417d052015-04-05 04:17:25 -0400668 if messageLen == 0 {
669 messageLen = 32
Adam Langley80842bd2014-06-20 12:00:00 -0700670 }
Adam Langley95c29f32014-06-20 12:00:00 -0700671
David Benjamin8e6db492015-07-25 18:29:23 -0400672 messageCount := test.messageCount
673 if messageCount == 0 {
674 messageCount = 1
David Benjamina8ebe222015-06-06 03:04:39 -0400675 }
676
David Benjamin8e6db492015-07-25 18:29:23 -0400677 for j := 0; j < messageCount; j++ {
678 testMessage := make([]byte, messageLen)
679 for i := range testMessage {
680 testMessage[i] = 0x42 ^ byte(j)
David Benjamin6fd297b2014-08-11 18:43:38 -0400681 }
David Benjamin8e6db492015-07-25 18:29:23 -0400682 tlsConn.Write(testMessage)
Adam Langley95c29f32014-06-20 12:00:00 -0700683
Steven Valdez32635b82016-08-16 11:25:03 -0400684 for i := 0; i < test.sendKeyUpdates; i++ {
685 tlsConn.SendKeyUpdate()
686 }
687
David Benjamin8e6db492015-07-25 18:29:23 -0400688 for i := 0; i < test.sendEmptyRecords; i++ {
689 tlsConn.Write(nil)
690 }
691
692 for i := 0; i < test.sendWarningAlerts; i++ {
693 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
694 }
695
David Benjamin4f75aaf2015-09-01 16:53:10 -0400696 if test.shimShutsDown || test.expectMessageDropped {
David Benjamin30789da2015-08-29 22:56:45 -0400697 // The shim will not respond.
698 continue
699 }
700
David Benjamin8e6db492015-07-25 18:29:23 -0400701 buf := make([]byte, len(testMessage))
702 if test.protocol == dtls {
703 bufTmp := make([]byte, len(buf)+1)
704 n, err := tlsConn.Read(bufTmp)
705 if err != nil {
706 return err
707 }
708 if n != len(buf) {
709 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
710 }
711 copy(buf, bufTmp)
712 } else {
713 _, err := io.ReadFull(tlsConn, buf)
714 if err != nil {
715 return err
716 }
717 }
718
719 for i, v := range buf {
720 if v != testMessage[i]^0xff {
721 return fmt.Errorf("bad reply contents at byte %d", i)
722 }
Adam Langley95c29f32014-06-20 12:00:00 -0700723 }
724 }
725
726 return nil
727}
728
David Benjamin325b5c32014-07-01 19:40:31 -0400729func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
David Benjamind2ba8892016-09-20 19:41:04 -0400730 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full", "--quiet"}
Adam Langley95c29f32014-06-20 12:00:00 -0700731 if dbAttach {
David Benjamin325b5c32014-07-01 19:40:31 -0400732 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p")
Adam Langley95c29f32014-06-20 12:00:00 -0700733 }
David Benjamin325b5c32014-07-01 19:40:31 -0400734 valgrindArgs = append(valgrindArgs, path)
735 valgrindArgs = append(valgrindArgs, args...)
Adam Langley95c29f32014-06-20 12:00:00 -0700736
David Benjamin325b5c32014-07-01 19:40:31 -0400737 return exec.Command("valgrind", valgrindArgs...)
Adam Langley95c29f32014-06-20 12:00:00 -0700738}
739
David Benjamin325b5c32014-07-01 19:40:31 -0400740func gdbOf(path string, args ...string) *exec.Cmd {
741 xtermArgs := []string{"-e", "gdb", "--args"}
742 xtermArgs = append(xtermArgs, path)
743 xtermArgs = append(xtermArgs, args...)
Adam Langley95c29f32014-06-20 12:00:00 -0700744
David Benjamin325b5c32014-07-01 19:40:31 -0400745 return exec.Command("xterm", xtermArgs...)
Adam Langley95c29f32014-06-20 12:00:00 -0700746}
747
David Benjamind16bf342015-12-18 00:53:12 -0500748func lldbOf(path string, args ...string) *exec.Cmd {
749 xtermArgs := []string{"-e", "lldb", "--"}
750 xtermArgs = append(xtermArgs, path)
751 xtermArgs = append(xtermArgs, args...)
752
753 return exec.Command("xterm", xtermArgs...)
754}
755
EKR842ae6c2016-07-27 09:22:05 +0200756var (
757 errMoreMallocs = errors.New("child process did not exhaust all allocation calls")
758 errUnimplemented = errors.New("child process does not implement needed flags")
759)
Adam Langley69a01602014-11-17 17:26:55 -0800760
David Benjamin87c8a642015-02-21 01:54:29 -0500761// accept accepts a connection from listener, unless waitChan signals a process
762// exit first.
763func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error) {
764 type connOrError struct {
765 conn net.Conn
766 err error
767 }
768 connChan := make(chan connOrError, 1)
769 go func() {
770 conn, err := listener.Accept()
771 connChan <- connOrError{conn, err}
772 close(connChan)
773 }()
774 select {
775 case result := <-connChan:
776 return result.conn, result.err
777 case childErr := <-waitChan:
778 waitChan <- childErr
779 return nil, fmt.Errorf("child exited early: %s", childErr)
780 }
781}
782
EKRf71d7ed2016-08-06 13:25:12 -0700783func translateExpectedError(errorStr string) string {
784 if translated, ok := shimConfig.ErrorMap[errorStr]; ok {
785 return translated
786 }
787
788 if *looseErrors {
789 return ""
790 }
791
792 return errorStr
793}
794
Adam Langley7c803a62015-06-15 15:35:05 -0700795func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
Adam Langley38311732014-10-16 19:04:35 -0700796 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
797 panic("Error expected without shouldFail in " + test.name)
798 }
799
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700800 if test.expectResumeRejected && !test.resumeSession {
801 panic("expectResumeRejected without resumeSession in " + test.name)
802 }
803
David Benjamin87c8a642015-02-21 01:54:29 -0500804 listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
805 if err != nil {
806 panic(err)
807 }
808 defer func() {
809 if listener != nil {
810 listener.Close()
811 }
812 }()
Adam Langley95c29f32014-06-20 12:00:00 -0700813
David Benjamin87c8a642015-02-21 01:54:29 -0500814 flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
David Benjamin1d5c83e2014-07-22 19:20:02 -0400815 if test.testType == serverTest {
David Benjamin5a593af2014-08-11 19:51:50 -0400816 flags = append(flags, "-server")
817
David Benjamin025b3d32014-07-01 19:53:04 -0400818 flags = append(flags, "-key-file")
819 if test.keyFile == "" {
Adam Langley7c803a62015-06-15 15:35:05 -0700820 flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400821 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700822 flags = append(flags, path.Join(*resourceDir, test.keyFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400823 }
824
825 flags = append(flags, "-cert-file")
826 if test.certFile == "" {
Adam Langley7c803a62015-06-15 15:35:05 -0700827 flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400828 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700829 flags = append(flags, path.Join(*resourceDir, test.certFile))
David Benjamin025b3d32014-07-01 19:53:04 -0400830 }
831 }
David Benjamin5a593af2014-08-11 19:51:50 -0400832
David Benjamin6fd297b2014-08-11 18:43:38 -0400833 if test.protocol == dtls {
834 flags = append(flags, "-dtls")
835 }
836
David Benjamin46662482016-08-17 00:51:00 -0400837 var resumeCount int
David Benjamin5a593af2014-08-11 19:51:50 -0400838 if test.resumeSession {
David Benjamin46662482016-08-17 00:51:00 -0400839 resumeCount++
840 if test.resumeRenewedSession {
841 resumeCount++
842 }
843 }
844
845 if resumeCount > 0 {
846 flags = append(flags, "-resume-count", strconv.Itoa(resumeCount))
David Benjamin5a593af2014-08-11 19:51:50 -0400847 }
848
David Benjamine58c4f52014-08-24 03:47:07 -0400849 if test.shimWritesFirst {
850 flags = append(flags, "-shim-writes-first")
851 }
852
David Benjamin30789da2015-08-29 22:56:45 -0400853 if test.shimShutsDown {
854 flags = append(flags, "-shim-shuts-down")
855 }
856
David Benjaminc565ebb2015-04-03 04:06:36 -0400857 if test.exportKeyingMaterial > 0 {
858 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
859 flags = append(flags, "-export-label", test.exportLabel)
860 flags = append(flags, "-export-context", test.exportContext)
861 if test.useExportContext {
862 flags = append(flags, "-use-export-context")
863 }
864 }
Adam Langleyb0eef0a2015-06-02 10:47:39 -0700865 if test.expectResumeRejected {
866 flags = append(flags, "-expect-session-miss")
867 }
David Benjaminc565ebb2015-04-03 04:06:36 -0400868
Adam Langleyaf0e32c2015-06-03 09:57:23 -0700869 if test.testTLSUnique {
870 flags = append(flags, "-tls-unique")
871 }
872
David Benjamin025b3d32014-07-01 19:53:04 -0400873 flags = append(flags, test.flags...)
874
875 var shim *exec.Cmd
876 if *useValgrind {
Adam Langley7c803a62015-06-15 15:35:05 -0700877 shim = valgrindOf(false, shimPath, flags...)
Adam Langley75712922014-10-10 16:23:43 -0700878 } else if *useGDB {
Adam Langley7c803a62015-06-15 15:35:05 -0700879 shim = gdbOf(shimPath, flags...)
David Benjamind16bf342015-12-18 00:53:12 -0500880 } else if *useLLDB {
881 shim = lldbOf(shimPath, flags...)
David Benjamin025b3d32014-07-01 19:53:04 -0400882 } else {
Adam Langley7c803a62015-06-15 15:35:05 -0700883 shim = exec.Command(shimPath, flags...)
David Benjamin025b3d32014-07-01 19:53:04 -0400884 }
David Benjamin025b3d32014-07-01 19:53:04 -0400885 shim.Stdin = os.Stdin
886 var stdoutBuf, stderrBuf bytes.Buffer
887 shim.Stdout = &stdoutBuf
888 shim.Stderr = &stderrBuf
Adam Langley69a01602014-11-17 17:26:55 -0800889 if mallocNumToFail >= 0 {
David Benjamin9e128b02015-02-09 13:13:09 -0500890 shim.Env = os.Environ()
891 shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
Adam Langley69a01602014-11-17 17:26:55 -0800892 if *mallocTestDebug {
David Benjamin184494d2015-06-12 18:23:47 -0400893 shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
Adam Langley69a01602014-11-17 17:26:55 -0800894 }
895 shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
896 }
David Benjamin025b3d32014-07-01 19:53:04 -0400897
898 if err := shim.Start(); err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700899 panic(err)
900 }
David Benjamin87c8a642015-02-21 01:54:29 -0500901 waitChan := make(chan error, 1)
902 go func() { waitChan <- shim.Wait() }()
Adam Langley95c29f32014-06-20 12:00:00 -0700903
904 config := test.config
Adam Langley95c29f32014-06-20 12:00:00 -0700905
David Benjamin7a4aaa42016-09-20 17:58:14 -0400906 if *deterministic {
907 config.Rand = &deterministicRand{}
908 }
909
David Benjamin87c8a642015-02-21 01:54:29 -0500910 conn, err := acceptOrWait(listener, waitChan)
911 if err == nil {
David Benjamin8e6db492015-07-25 18:29:23 -0400912 err = doExchange(test, &config, conn, false /* not a resumption */)
David Benjamin87c8a642015-02-21 01:54:29 -0500913 conn.Close()
914 }
David Benjamin65ea8ff2014-11-23 03:01:00 -0500915
David Benjamin46662482016-08-17 00:51:00 -0400916 for i := 0; err == nil && i < resumeCount; i++ {
David Benjamin01fe8202014-09-24 15:21:44 -0400917 var resumeConfig Config
918 if test.resumeConfig != nil {
919 resumeConfig = *test.resumeConfig
David Benjamine54af062016-08-08 19:21:18 -0400920 if !test.newSessionsOnResume {
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500921 resumeConfig.SessionTicketKey = config.SessionTicketKey
922 resumeConfig.ClientSessionCache = config.ClientSessionCache
923 resumeConfig.ServerSessionCache = config.ServerSessionCache
924 }
David Benjamin2e045a92016-06-08 13:09:56 -0400925 resumeConfig.Rand = config.Rand
David Benjamin01fe8202014-09-24 15:21:44 -0400926 } else {
927 resumeConfig = config
928 }
David Benjamin87c8a642015-02-21 01:54:29 -0500929 var connResume net.Conn
930 connResume, err = acceptOrWait(listener, waitChan)
931 if err == nil {
David Benjamin8e6db492015-07-25 18:29:23 -0400932 err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
David Benjamin87c8a642015-02-21 01:54:29 -0500933 connResume.Close()
934 }
David Benjamin1d5c83e2014-07-22 19:20:02 -0400935 }
936
David Benjamin87c8a642015-02-21 01:54:29 -0500937 // Close the listener now. This is to avoid hangs should the shim try to
938 // open more connections than expected.
939 listener.Close()
940 listener = nil
941
942 childErr := <-waitChan
David Benjamind2ba8892016-09-20 19:41:04 -0400943 var isValgrindError bool
Adam Langley69a01602014-11-17 17:26:55 -0800944 if exitError, ok := childErr.(*exec.ExitError); ok {
EKR842ae6c2016-07-27 09:22:05 +0200945 switch exitError.Sys().(syscall.WaitStatus).ExitStatus() {
946 case 88:
Adam Langley69a01602014-11-17 17:26:55 -0800947 return errMoreMallocs
EKR842ae6c2016-07-27 09:22:05 +0200948 case 89:
949 return errUnimplemented
David Benjamind2ba8892016-09-20 19:41:04 -0400950 case 99:
951 isValgrindError = true
Adam Langley69a01602014-11-17 17:26:55 -0800952 }
953 }
Adam Langley95c29f32014-06-20 12:00:00 -0700954
David Benjamin9bea3492016-03-02 10:59:16 -0500955 // Account for Windows line endings.
956 stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1)
957 stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1)
David Benjaminff3a1492016-03-02 10:12:06 -0500958
959 // Separate the errors from the shim and those from tools like
960 // AddressSanitizer.
961 var extraStderr string
962 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 {
963 stderr = stderrParts[0]
964 extraStderr = stderrParts[1]
965 }
966
Adam Langley95c29f32014-06-20 12:00:00 -0700967 failed := err != nil || childErr != nil
EKRf71d7ed2016-08-06 13:25:12 -0700968 expectedError := translateExpectedError(test.expectedError)
969 correctFailure := len(expectedError) == 0 || strings.Contains(stderr, expectedError)
EKR173bf932016-07-29 15:52:49 +0200970
Adam Langleyac61fa32014-06-23 12:03:11 -0700971 localError := "none"
972 if err != nil {
973 localError = err.Error()
974 }
975 if len(test.expectedLocalError) != 0 {
976 correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
977 }
Adam Langley95c29f32014-06-20 12:00:00 -0700978
979 if failed != test.shouldFail || failed && !correctFailure {
Adam Langley95c29f32014-06-20 12:00:00 -0700980 childError := "none"
Adam Langley95c29f32014-06-20 12:00:00 -0700981 if childErr != nil {
982 childError = childErr.Error()
983 }
984
985 var msg string
986 switch {
987 case failed && !test.shouldFail:
988 msg = "unexpected failure"
989 case !failed && test.shouldFail:
990 msg = "unexpected success"
991 case failed && !correctFailure:
EKRf71d7ed2016-08-06 13:25:12 -0700992 msg = "bad error (wanted '" + expectedError + "' / '" + test.expectedLocalError + "')"
Adam Langley95c29f32014-06-20 12:00:00 -0700993 default:
994 panic("internal error")
995 }
996
David Benjamin9aafb642016-09-20 19:36:53 -0400997 return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s\n%s", msg, localError, childError, stdout, stderr, extraStderr)
Adam Langley95c29f32014-06-20 12:00:00 -0700998 }
999
David Benjamind2ba8892016-09-20 19:41:04 -04001000 if len(extraStderr) > 0 || (!failed && len(stderr) > 0) {
David Benjaminff3a1492016-03-02 10:12:06 -05001001 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr)
Adam Langley95c29f32014-06-20 12:00:00 -07001002 }
1003
David Benjamind2ba8892016-09-20 19:41:04 -04001004 if *useValgrind && isValgrindError {
1005 return fmt.Errorf("valgrind error:\n%s\n%s", stderr, extraStderr)
1006 }
1007
Adam Langley95c29f32014-06-20 12:00:00 -07001008 return nil
1009}
1010
1011var tlsVersions = []struct {
1012 name string
1013 version uint16
David Benjamin7e2e6cf2014-08-07 17:44:24 -04001014 flag string
David Benjamin8b8c0062014-11-23 02:47:52 -05001015 hasDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -07001016}{
David Benjamin8b8c0062014-11-23 02:47:52 -05001017 {"SSL3", VersionSSL30, "-no-ssl3", false},
1018 {"TLS1", VersionTLS10, "-no-tls1", true},
1019 {"TLS11", VersionTLS11, "-no-tls11", false},
1020 {"TLS12", VersionTLS12, "-no-tls12", true},
Steven Valdez143e8b32016-07-11 13:19:03 -04001021 {"TLS13", VersionTLS13, "-no-tls13", false},
Adam Langley95c29f32014-06-20 12:00:00 -07001022}
1023
1024var testCipherSuites = []struct {
1025 name string
1026 id uint16
1027}{
1028 {"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjaminf4e5c4e2014-08-02 17:35:45 -04001029 {"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -07001030 {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001031 {"AES128-SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -04001032 {"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -07001033 {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001034 {"AES256-SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -04001035 {"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
1036 {"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001037 {"DHE-RSA-AES128-SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -04001038 {"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
1039 {"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001040 {"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -07001041 {"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
1042 {"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001043 {"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
1044 {"ECDHE-ECDSA-AES256-GCM", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -07001045 {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001046 {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
David Benjamin13414b32015-12-09 23:02:39 -05001047 {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
David Benjamine3203922015-12-09 21:21:31 -05001048 {"ECDHE-ECDSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
Adam Langley95c29f32014-06-20 12:00:00 -07001049 {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
Adam Langley95c29f32014-06-20 12:00:00 -07001050 {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001051 {"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
David Benjaminf4e5c4e2014-08-02 17:35:45 -04001052 {"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
Adam Langley95c29f32014-06-20 12:00:00 -07001053 {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
David Benjaminf7768e42014-08-31 02:06:47 -04001054 {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
David Benjamin13414b32015-12-09 23:02:39 -05001055 {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
David Benjamine3203922015-12-09 21:21:31 -05001056 {"ECDHE-RSA-CHACHA20-POLY1305-OLD", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD},
Matt Braithwaite053931e2016-05-25 12:06:05 -07001057 {"CECPQ1-RSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256},
1058 {"CECPQ1-ECDSA-CHACHA20-POLY1305-SHA256", TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
1059 {"CECPQ1-RSA-AES256-GCM-SHA384", TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
1060 {"CECPQ1-ECDSA-AES256-GCM-SHA384", TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384},
David Benjamin48cae082014-10-27 01:06:24 -04001061 {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
1062 {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
Adam Langley85bc5602015-06-09 09:54:04 -07001063 {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
1064 {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
David Benjamin13414b32015-12-09 23:02:39 -05001065 {"ECDHE-PSK-CHACHA20-POLY1305", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
Steven Valdez3084e7b2016-06-02 12:07:20 -04001066 {"ECDHE-PSK-AES128-GCM-SHA256", TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256},
1067 {"ECDHE-PSK-AES256-GCM-SHA384", TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384},
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001068 {"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
Adam Langley95c29f32014-06-20 12:00:00 -07001069}
1070
David Benjamin8b8c0062014-11-23 02:47:52 -05001071func hasComponent(suiteName, component string) bool {
1072 return strings.Contains("-"+suiteName+"-", "-"+component+"-")
1073}
1074
David Benjaminf7768e42014-08-31 02:06:47 -04001075func isTLS12Only(suiteName string) bool {
David Benjamin8b8c0062014-11-23 02:47:52 -05001076 return hasComponent(suiteName, "GCM") ||
1077 hasComponent(suiteName, "SHA256") ||
David Benjamine9a80ff2015-04-07 00:46:46 -04001078 hasComponent(suiteName, "SHA384") ||
1079 hasComponent(suiteName, "POLY1305")
David Benjamin8b8c0062014-11-23 02:47:52 -05001080}
1081
Nick Harper1fd39d82016-06-14 18:14:35 -07001082func isTLS13Suite(suiteName string) bool {
David Benjamin54c217c2016-07-13 12:35:25 -04001083 // Only AEADs.
1084 if !hasComponent(suiteName, "GCM") && !hasComponent(suiteName, "POLY1305") {
1085 return false
1086 }
1087 // No old CHACHA20_POLY1305.
1088 if hasComponent(suiteName, "CHACHA20-POLY1305-OLD") {
1089 return false
1090 }
1091 // Must have ECDHE.
1092 // TODO(davidben,svaldez): Add pure PSK support.
1093 if !hasComponent(suiteName, "ECDHE") {
1094 return false
1095 }
1096 // TODO(davidben,svaldez): Add PSK support.
1097 if hasComponent(suiteName, "PSK") {
1098 return false
1099 }
1100 return true
Nick Harper1fd39d82016-06-14 18:14:35 -07001101}
1102
David Benjamin8b8c0062014-11-23 02:47:52 -05001103func isDTLSCipher(suiteName string) bool {
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001104 return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL")
David Benjaminf7768e42014-08-31 02:06:47 -04001105}
1106
Adam Langleya7997f12015-05-14 17:38:50 -07001107func bigFromHex(hex string) *big.Int {
1108 ret, ok := new(big.Int).SetString(hex, 16)
1109 if !ok {
1110 panic("failed to parse hex number 0x" + hex)
1111 }
1112 return ret
1113}
1114
Adam Langley7c803a62015-06-15 15:35:05 -07001115func addBasicTests() {
1116 basicTests := []testCase{
1117 {
Adam Langley7c803a62015-06-15 15:35:05 -07001118 name: "NoFallbackSCSV",
1119 config: Config{
1120 Bugs: ProtocolBugs{
1121 FailIfNotFallbackSCSV: true,
1122 },
1123 },
1124 shouldFail: true,
1125 expectedLocalError: "no fallback SCSV found",
1126 },
1127 {
1128 name: "SendFallbackSCSV",
1129 config: Config{
1130 Bugs: ProtocolBugs{
1131 FailIfNotFallbackSCSV: true,
1132 },
1133 },
1134 flags: []string{"-fallback-scsv"},
1135 },
1136 {
1137 name: "ClientCertificateTypes",
1138 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001139 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001140 ClientAuth: RequestClientCert,
1141 ClientCertificateTypes: []byte{
1142 CertTypeDSSSign,
1143 CertTypeRSASign,
1144 CertTypeECDSASign,
1145 },
1146 },
1147 flags: []string{
1148 "-expect-certificate-types",
1149 base64.StdEncoding.EncodeToString([]byte{
1150 CertTypeDSSSign,
1151 CertTypeRSASign,
1152 CertTypeECDSASign,
1153 }),
1154 },
1155 },
1156 {
Adam Langley7c803a62015-06-15 15:35:05 -07001157 name: "UnauthenticatedECDH",
1158 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001159 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001160 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1161 Bugs: ProtocolBugs{
1162 UnauthenticatedECDH: true,
1163 },
1164 },
1165 shouldFail: true,
1166 expectedError: ":UNEXPECTED_MESSAGE:",
1167 },
1168 {
1169 name: "SkipCertificateStatus",
1170 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001171 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001172 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1173 Bugs: ProtocolBugs{
1174 SkipCertificateStatus: true,
1175 },
1176 },
1177 flags: []string{
1178 "-enable-ocsp-stapling",
1179 },
1180 },
1181 {
1182 name: "SkipServerKeyExchange",
1183 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001184 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001185 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1186 Bugs: ProtocolBugs{
1187 SkipServerKeyExchange: true,
1188 },
1189 },
1190 shouldFail: true,
1191 expectedError: ":UNEXPECTED_MESSAGE:",
1192 },
1193 {
Adam Langley7c803a62015-06-15 15:35:05 -07001194 testType: serverTest,
1195 name: "Alert",
1196 config: Config{
1197 Bugs: ProtocolBugs{
1198 SendSpuriousAlert: alertRecordOverflow,
1199 },
1200 },
1201 shouldFail: true,
1202 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1203 },
1204 {
1205 protocol: dtls,
1206 testType: serverTest,
1207 name: "Alert-DTLS",
1208 config: Config{
1209 Bugs: ProtocolBugs{
1210 SendSpuriousAlert: alertRecordOverflow,
1211 },
1212 },
1213 shouldFail: true,
1214 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1215 },
1216 {
1217 testType: serverTest,
1218 name: "FragmentAlert",
1219 config: Config{
1220 Bugs: ProtocolBugs{
1221 FragmentAlert: true,
1222 SendSpuriousAlert: alertRecordOverflow,
1223 },
1224 },
1225 shouldFail: true,
1226 expectedError: ":BAD_ALERT:",
1227 },
1228 {
1229 protocol: dtls,
1230 testType: serverTest,
1231 name: "FragmentAlert-DTLS",
1232 config: Config{
1233 Bugs: ProtocolBugs{
1234 FragmentAlert: true,
1235 SendSpuriousAlert: alertRecordOverflow,
1236 },
1237 },
1238 shouldFail: true,
1239 expectedError: ":BAD_ALERT:",
1240 },
1241 {
1242 testType: serverTest,
David Benjamin0d3a8c62016-03-11 22:25:18 -05001243 name: "DoubleAlert",
1244 config: Config{
1245 Bugs: ProtocolBugs{
1246 DoubleAlert: true,
1247 SendSpuriousAlert: alertRecordOverflow,
1248 },
1249 },
1250 shouldFail: true,
1251 expectedError: ":BAD_ALERT:",
1252 },
1253 {
1254 protocol: dtls,
1255 testType: serverTest,
1256 name: "DoubleAlert-DTLS",
1257 config: Config{
1258 Bugs: ProtocolBugs{
1259 DoubleAlert: true,
1260 SendSpuriousAlert: alertRecordOverflow,
1261 },
1262 },
1263 shouldFail: true,
1264 expectedError: ":BAD_ALERT:",
1265 },
1266 {
Adam Langley7c803a62015-06-15 15:35:05 -07001267 name: "SkipNewSessionTicket",
1268 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001269 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001270 Bugs: ProtocolBugs{
1271 SkipNewSessionTicket: true,
1272 },
1273 },
1274 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001275 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001276 },
1277 {
1278 testType: serverTest,
1279 name: "FallbackSCSV",
1280 config: Config{
1281 MaxVersion: VersionTLS11,
1282 Bugs: ProtocolBugs{
1283 SendFallbackSCSV: true,
1284 },
1285 },
1286 shouldFail: true,
1287 expectedError: ":INAPPROPRIATE_FALLBACK:",
1288 },
1289 {
1290 testType: serverTest,
1291 name: "FallbackSCSV-VersionMatch",
1292 config: Config{
1293 Bugs: ProtocolBugs{
1294 SendFallbackSCSV: true,
1295 },
1296 },
1297 },
1298 {
1299 testType: serverTest,
David Benjamin4c3ddf72016-06-29 18:13:53 -04001300 name: "FallbackSCSV-VersionMatch-TLS12",
1301 config: Config{
1302 MaxVersion: VersionTLS12,
1303 Bugs: ProtocolBugs{
1304 SendFallbackSCSV: true,
1305 },
1306 },
1307 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
1308 },
1309 {
1310 testType: serverTest,
Adam Langley7c803a62015-06-15 15:35:05 -07001311 name: "FragmentedClientVersion",
1312 config: Config{
1313 Bugs: ProtocolBugs{
1314 MaxHandshakeRecordLength: 1,
1315 FragmentClientVersion: true,
1316 },
1317 },
Nick Harper1fd39d82016-06-14 18:14:35 -07001318 expectedVersion: VersionTLS13,
Adam Langley7c803a62015-06-15 15:35:05 -07001319 },
1320 {
Adam Langley7c803a62015-06-15 15:35:05 -07001321 testType: serverTest,
1322 name: "HttpGET",
1323 sendPrefix: "GET / HTTP/1.0\n",
1324 shouldFail: true,
1325 expectedError: ":HTTP_REQUEST:",
1326 },
1327 {
1328 testType: serverTest,
1329 name: "HttpPOST",
1330 sendPrefix: "POST / HTTP/1.0\n",
1331 shouldFail: true,
1332 expectedError: ":HTTP_REQUEST:",
1333 },
1334 {
1335 testType: serverTest,
1336 name: "HttpHEAD",
1337 sendPrefix: "HEAD / HTTP/1.0\n",
1338 shouldFail: true,
1339 expectedError: ":HTTP_REQUEST:",
1340 },
1341 {
1342 testType: serverTest,
1343 name: "HttpPUT",
1344 sendPrefix: "PUT / HTTP/1.0\n",
1345 shouldFail: true,
1346 expectedError: ":HTTP_REQUEST:",
1347 },
1348 {
1349 testType: serverTest,
1350 name: "HttpCONNECT",
1351 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
1352 shouldFail: true,
1353 expectedError: ":HTTPS_PROXY_REQUEST:",
1354 },
1355 {
1356 testType: serverTest,
1357 name: "Garbage",
1358 sendPrefix: "blah",
1359 shouldFail: true,
David Benjamin97760d52015-07-24 23:02:49 -04001360 expectedError: ":WRONG_VERSION_NUMBER:",
Adam Langley7c803a62015-06-15 15:35:05 -07001361 },
1362 {
Adam Langley7c803a62015-06-15 15:35:05 -07001363 name: "RSAEphemeralKey",
1364 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001365 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001366 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
1367 Bugs: ProtocolBugs{
1368 RSAEphemeralKey: true,
1369 },
1370 },
1371 shouldFail: true,
1372 expectedError: ":UNEXPECTED_MESSAGE:",
1373 },
1374 {
1375 name: "DisableEverything",
Steven Valdez4f94b1c2016-05-24 12:31:07 -04001376 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
Adam Langley7c803a62015-06-15 15:35:05 -07001377 shouldFail: true,
1378 expectedError: ":WRONG_SSL_VERSION:",
1379 },
1380 {
1381 protocol: dtls,
1382 name: "DisableEverything-DTLS",
1383 flags: []string{"-no-tls12", "-no-tls1"},
1384 shouldFail: true,
1385 expectedError: ":WRONG_SSL_VERSION:",
1386 },
1387 {
Adam Langley7c803a62015-06-15 15:35:05 -07001388 protocol: dtls,
1389 testType: serverTest,
1390 name: "MTU",
1391 config: Config{
1392 Bugs: ProtocolBugs{
1393 MaxPacketLength: 256,
1394 },
1395 },
1396 flags: []string{"-mtu", "256"},
1397 },
1398 {
1399 protocol: dtls,
1400 testType: serverTest,
1401 name: "MTUExceeded",
1402 config: Config{
1403 Bugs: ProtocolBugs{
1404 MaxPacketLength: 255,
1405 },
1406 },
1407 flags: []string{"-mtu", "256"},
1408 shouldFail: true,
1409 expectedLocalError: "dtls: exceeded maximum packet length",
1410 },
1411 {
1412 name: "CertMismatchRSA",
1413 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001414 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001415 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07001416 Certificates: []Certificate{ecdsaP256Certificate},
Adam Langley7c803a62015-06-15 15:35:05 -07001417 Bugs: ProtocolBugs{
1418 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1419 },
1420 },
1421 shouldFail: true,
1422 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1423 },
1424 {
Steven Valdez143e8b32016-07-11 13:19:03 -04001425 name: "CertMismatchRSA-TLS13",
1426 config: Config{
1427 MaxVersion: VersionTLS13,
1428 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
1429 Certificates: []Certificate{ecdsaP256Certificate},
1430 Bugs: ProtocolBugs{
1431 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1432 },
1433 },
1434 shouldFail: true,
1435 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1436 },
1437 {
Adam Langley7c803a62015-06-15 15:35:05 -07001438 name: "CertMismatchECDSA",
1439 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001440 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001441 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07001442 Certificates: []Certificate{rsaCertificate},
Adam Langley7c803a62015-06-15 15:35:05 -07001443 Bugs: ProtocolBugs{
1444 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1445 },
1446 },
1447 shouldFail: true,
1448 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1449 },
1450 {
Steven Valdez143e8b32016-07-11 13:19:03 -04001451 name: "CertMismatchECDSA-TLS13",
1452 config: Config{
1453 MaxVersion: VersionTLS13,
1454 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1455 Certificates: []Certificate{rsaCertificate},
1456 Bugs: ProtocolBugs{
1457 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1458 },
1459 },
1460 shouldFail: true,
1461 expectedError: ":WRONG_CERTIFICATE_TYPE:",
1462 },
1463 {
Adam Langley7c803a62015-06-15 15:35:05 -07001464 name: "EmptyCertificateList",
1465 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001466 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001467 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1468 Bugs: ProtocolBugs{
1469 EmptyCertificateList: true,
1470 },
1471 },
1472 shouldFail: true,
1473 expectedError: ":DECODE_ERROR:",
1474 },
1475 {
David Benjamin9ec1c752016-07-14 12:45:01 -04001476 name: "EmptyCertificateList-TLS13",
1477 config: Config{
1478 MaxVersion: VersionTLS13,
1479 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1480 Bugs: ProtocolBugs{
1481 EmptyCertificateList: true,
1482 },
1483 },
1484 shouldFail: true,
David Benjamin4087df92016-08-01 20:16:31 -04001485 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
David Benjamin9ec1c752016-07-14 12:45:01 -04001486 },
1487 {
Adam Langley7c803a62015-06-15 15:35:05 -07001488 name: "TLSFatalBadPackets",
1489 damageFirstWrite: true,
1490 shouldFail: true,
1491 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
1492 },
1493 {
1494 protocol: dtls,
1495 name: "DTLSIgnoreBadPackets",
1496 damageFirstWrite: true,
1497 },
1498 {
1499 protocol: dtls,
1500 name: "DTLSIgnoreBadPackets-Async",
1501 damageFirstWrite: true,
1502 flags: []string{"-async"},
1503 },
1504 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001505 name: "AppDataBeforeHandshake",
1506 config: Config{
1507 Bugs: ProtocolBugs{
1508 AppDataBeforeHandshake: []byte("TEST MESSAGE"),
1509 },
1510 },
1511 shouldFail: true,
1512 expectedError: ":UNEXPECTED_RECORD:",
1513 },
1514 {
1515 name: "AppDataBeforeHandshake-Empty",
1516 config: Config{
1517 Bugs: ProtocolBugs{
1518 AppDataBeforeHandshake: []byte{},
1519 },
1520 },
1521 shouldFail: true,
1522 expectedError: ":UNEXPECTED_RECORD:",
1523 },
1524 {
1525 protocol: dtls,
1526 name: "AppDataBeforeHandshake-DTLS",
1527 config: Config{
1528 Bugs: ProtocolBugs{
1529 AppDataBeforeHandshake: []byte("TEST MESSAGE"),
1530 },
1531 },
1532 shouldFail: true,
1533 expectedError: ":UNEXPECTED_RECORD:",
1534 },
1535 {
1536 protocol: dtls,
1537 name: "AppDataBeforeHandshake-DTLS-Empty",
1538 config: Config{
1539 Bugs: ProtocolBugs{
1540 AppDataBeforeHandshake: []byte{},
1541 },
1542 },
1543 shouldFail: true,
1544 expectedError: ":UNEXPECTED_RECORD:",
1545 },
1546 {
Adam Langley7c803a62015-06-15 15:35:05 -07001547 name: "AppDataAfterChangeCipherSpec",
1548 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001549 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001550 Bugs: ProtocolBugs{
1551 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
1552 },
1553 },
1554 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001555 expectedError: ":UNEXPECTED_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001556 },
1557 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001558 name: "AppDataAfterChangeCipherSpec-Empty",
1559 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001560 MaxVersion: VersionTLS12,
David Benjamin4cf369b2015-08-22 01:35:43 -04001561 Bugs: ProtocolBugs{
1562 AppDataAfterChangeCipherSpec: []byte{},
1563 },
1564 },
1565 shouldFail: true,
David Benjamina41280d2015-11-26 02:16:49 -05001566 expectedError: ":UNEXPECTED_RECORD:",
David Benjamin4cf369b2015-08-22 01:35:43 -04001567 },
1568 {
Adam Langley7c803a62015-06-15 15:35:05 -07001569 protocol: dtls,
1570 name: "AppDataAfterChangeCipherSpec-DTLS",
1571 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001572 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001573 Bugs: ProtocolBugs{
1574 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
1575 },
1576 },
1577 // BoringSSL's DTLS implementation will drop the out-of-order
1578 // application data.
1579 },
1580 {
David Benjamin4cf369b2015-08-22 01:35:43 -04001581 protocol: dtls,
1582 name: "AppDataAfterChangeCipherSpec-DTLS-Empty",
1583 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001584 MaxVersion: VersionTLS12,
David Benjamin4cf369b2015-08-22 01:35:43 -04001585 Bugs: ProtocolBugs{
1586 AppDataAfterChangeCipherSpec: []byte{},
1587 },
1588 },
1589 // BoringSSL's DTLS implementation will drop the out-of-order
1590 // application data.
1591 },
1592 {
Adam Langley7c803a62015-06-15 15:35:05 -07001593 name: "AlertAfterChangeCipherSpec",
1594 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001595 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001596 Bugs: ProtocolBugs{
1597 AlertAfterChangeCipherSpec: alertRecordOverflow,
1598 },
1599 },
1600 shouldFail: true,
1601 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1602 },
1603 {
1604 protocol: dtls,
1605 name: "AlertAfterChangeCipherSpec-DTLS",
1606 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001607 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001608 Bugs: ProtocolBugs{
1609 AlertAfterChangeCipherSpec: alertRecordOverflow,
1610 },
1611 },
1612 shouldFail: true,
1613 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
1614 },
1615 {
1616 protocol: dtls,
1617 name: "ReorderHandshakeFragments-Small-DTLS",
1618 config: Config{
1619 Bugs: ProtocolBugs{
1620 ReorderHandshakeFragments: true,
1621 // Small enough that every handshake message is
1622 // fragmented.
1623 MaxHandshakeRecordLength: 2,
1624 },
1625 },
1626 },
1627 {
1628 protocol: dtls,
1629 name: "ReorderHandshakeFragments-Large-DTLS",
1630 config: Config{
1631 Bugs: ProtocolBugs{
1632 ReorderHandshakeFragments: true,
1633 // Large enough that no handshake message is
1634 // fragmented.
1635 MaxHandshakeRecordLength: 2048,
1636 },
1637 },
1638 },
1639 {
1640 protocol: dtls,
1641 name: "MixCompleteMessageWithFragments-DTLS",
1642 config: Config{
1643 Bugs: ProtocolBugs{
1644 ReorderHandshakeFragments: true,
1645 MixCompleteMessageWithFragments: true,
1646 MaxHandshakeRecordLength: 2,
1647 },
1648 },
1649 },
1650 {
1651 name: "SendInvalidRecordType",
1652 config: Config{
1653 Bugs: ProtocolBugs{
1654 SendInvalidRecordType: true,
1655 },
1656 },
1657 shouldFail: true,
1658 expectedError: ":UNEXPECTED_RECORD:",
1659 },
1660 {
1661 protocol: dtls,
1662 name: "SendInvalidRecordType-DTLS",
1663 config: Config{
1664 Bugs: ProtocolBugs{
1665 SendInvalidRecordType: true,
1666 },
1667 },
1668 shouldFail: true,
1669 expectedError: ":UNEXPECTED_RECORD:",
1670 },
1671 {
1672 name: "FalseStart-SkipServerSecondLeg",
1673 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001674 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001675 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1676 NextProtos: []string{"foo"},
1677 Bugs: ProtocolBugs{
1678 SkipNewSessionTicket: true,
1679 SkipChangeCipherSpec: true,
1680 SkipFinished: true,
1681 ExpectFalseStart: true,
1682 },
1683 },
1684 flags: []string{
1685 "-false-start",
1686 "-handshake-never-done",
1687 "-advertise-alpn", "\x03foo",
1688 },
1689 shimWritesFirst: true,
1690 shouldFail: true,
1691 expectedError: ":UNEXPECTED_RECORD:",
1692 },
1693 {
1694 name: "FalseStart-SkipServerSecondLeg-Implicit",
1695 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001696 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001697 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1698 NextProtos: []string{"foo"},
1699 Bugs: ProtocolBugs{
1700 SkipNewSessionTicket: true,
1701 SkipChangeCipherSpec: true,
1702 SkipFinished: true,
1703 },
1704 },
1705 flags: []string{
1706 "-implicit-handshake",
1707 "-false-start",
1708 "-handshake-never-done",
1709 "-advertise-alpn", "\x03foo",
1710 },
1711 shouldFail: true,
1712 expectedError: ":UNEXPECTED_RECORD:",
1713 },
1714 {
1715 testType: serverTest,
1716 name: "FailEarlyCallback",
1717 flags: []string{"-fail-early-callback"},
1718 shouldFail: true,
1719 expectedError: ":CONNECTION_REJECTED:",
David Benjamin2c66e072016-09-16 15:58:00 -04001720 expectedLocalError: "remote error: handshake failure",
Adam Langley7c803a62015-06-15 15:35:05 -07001721 },
1722 {
Adam Langley7c803a62015-06-15 15:35:05 -07001723 protocol: dtls,
1724 name: "FragmentMessageTypeMismatch-DTLS",
1725 config: Config{
1726 Bugs: ProtocolBugs{
1727 MaxHandshakeRecordLength: 2,
1728 FragmentMessageTypeMismatch: true,
1729 },
1730 },
1731 shouldFail: true,
1732 expectedError: ":FRAGMENT_MISMATCH:",
1733 },
1734 {
1735 protocol: dtls,
1736 name: "FragmentMessageLengthMismatch-DTLS",
1737 config: Config{
1738 Bugs: ProtocolBugs{
1739 MaxHandshakeRecordLength: 2,
1740 FragmentMessageLengthMismatch: true,
1741 },
1742 },
1743 shouldFail: true,
1744 expectedError: ":FRAGMENT_MISMATCH:",
1745 },
1746 {
1747 protocol: dtls,
1748 name: "SplitFragments-Header-DTLS",
1749 config: Config{
1750 Bugs: ProtocolBugs{
1751 SplitFragments: 2,
1752 },
1753 },
1754 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001755 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001756 },
1757 {
1758 protocol: dtls,
1759 name: "SplitFragments-Boundary-DTLS",
1760 config: Config{
1761 Bugs: ProtocolBugs{
1762 SplitFragments: dtlsRecordHeaderLen,
1763 },
1764 },
1765 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001766 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001767 },
1768 {
1769 protocol: dtls,
1770 name: "SplitFragments-Body-DTLS",
1771 config: Config{
1772 Bugs: ProtocolBugs{
1773 SplitFragments: dtlsRecordHeaderLen + 1,
1774 },
1775 },
1776 shouldFail: true,
David Benjaminc6604172016-06-02 16:38:35 -04001777 expectedError: ":BAD_HANDSHAKE_RECORD:",
Adam Langley7c803a62015-06-15 15:35:05 -07001778 },
1779 {
1780 protocol: dtls,
1781 name: "SendEmptyFragments-DTLS",
1782 config: Config{
1783 Bugs: ProtocolBugs{
1784 SendEmptyFragments: true,
1785 },
1786 },
1787 },
1788 {
David Benjaminbf82aed2016-03-01 22:57:40 -05001789 name: "BadFinished-Client",
1790 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001791 MaxVersion: VersionTLS12,
David Benjaminbf82aed2016-03-01 22:57:40 -05001792 Bugs: ProtocolBugs{
1793 BadFinished: true,
1794 },
1795 },
1796 shouldFail: true,
1797 expectedError: ":DIGEST_CHECK_FAILED:",
1798 },
1799 {
Steven Valdez143e8b32016-07-11 13:19:03 -04001800 name: "BadFinished-Client-TLS13",
1801 config: Config{
1802 MaxVersion: VersionTLS13,
1803 Bugs: ProtocolBugs{
1804 BadFinished: true,
1805 },
1806 },
1807 shouldFail: true,
1808 expectedError: ":DIGEST_CHECK_FAILED:",
1809 },
1810 {
David Benjaminbf82aed2016-03-01 22:57:40 -05001811 testType: serverTest,
1812 name: "BadFinished-Server",
Adam Langley7c803a62015-06-15 15:35:05 -07001813 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04001814 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001815 Bugs: ProtocolBugs{
1816 BadFinished: true,
1817 },
1818 },
1819 shouldFail: true,
1820 expectedError: ":DIGEST_CHECK_FAILED:",
1821 },
1822 {
Steven Valdez143e8b32016-07-11 13:19:03 -04001823 testType: serverTest,
1824 name: "BadFinished-Server-TLS13",
1825 config: Config{
1826 MaxVersion: VersionTLS13,
1827 Bugs: ProtocolBugs{
1828 BadFinished: true,
1829 },
1830 },
1831 shouldFail: true,
1832 expectedError: ":DIGEST_CHECK_FAILED:",
1833 },
1834 {
Adam Langley7c803a62015-06-15 15:35:05 -07001835 name: "FalseStart-BadFinished",
1836 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001837 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001838 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1839 NextProtos: []string{"foo"},
1840 Bugs: ProtocolBugs{
1841 BadFinished: true,
1842 ExpectFalseStart: true,
1843 },
1844 },
1845 flags: []string{
1846 "-false-start",
1847 "-handshake-never-done",
1848 "-advertise-alpn", "\x03foo",
1849 },
1850 shimWritesFirst: true,
1851 shouldFail: true,
1852 expectedError: ":DIGEST_CHECK_FAILED:",
1853 },
1854 {
1855 name: "NoFalseStart-NoALPN",
1856 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001857 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001858 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1859 Bugs: ProtocolBugs{
1860 ExpectFalseStart: true,
1861 AlertBeforeFalseStartTest: alertAccessDenied,
1862 },
1863 },
1864 flags: []string{
1865 "-false-start",
1866 },
1867 shimWritesFirst: true,
1868 shouldFail: true,
1869 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1870 expectedLocalError: "tls: peer did not false start: EOF",
1871 },
1872 {
1873 name: "NoFalseStart-NoAEAD",
1874 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001875 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001876 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
1877 NextProtos: []string{"foo"},
1878 Bugs: ProtocolBugs{
1879 ExpectFalseStart: true,
1880 AlertBeforeFalseStartTest: alertAccessDenied,
1881 },
1882 },
1883 flags: []string{
1884 "-false-start",
1885 "-advertise-alpn", "\x03foo",
1886 },
1887 shimWritesFirst: true,
1888 shouldFail: true,
1889 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1890 expectedLocalError: "tls: peer did not false start: EOF",
1891 },
1892 {
1893 name: "NoFalseStart-RSA",
1894 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001895 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001896 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
1897 NextProtos: []string{"foo"},
1898 Bugs: ProtocolBugs{
1899 ExpectFalseStart: true,
1900 AlertBeforeFalseStartTest: alertAccessDenied,
1901 },
1902 },
1903 flags: []string{
1904 "-false-start",
1905 "-advertise-alpn", "\x03foo",
1906 },
1907 shimWritesFirst: true,
1908 shouldFail: true,
1909 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1910 expectedLocalError: "tls: peer did not false start: EOF",
1911 },
1912 {
1913 name: "NoFalseStart-DHE_RSA",
1914 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07001915 MaxVersion: VersionTLS12,
Adam Langley7c803a62015-06-15 15:35:05 -07001916 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
1917 NextProtos: []string{"foo"},
1918 Bugs: ProtocolBugs{
1919 ExpectFalseStart: true,
1920 AlertBeforeFalseStartTest: alertAccessDenied,
1921 },
1922 },
1923 flags: []string{
1924 "-false-start",
1925 "-advertise-alpn", "\x03foo",
1926 },
1927 shimWritesFirst: true,
1928 shouldFail: true,
1929 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
1930 expectedLocalError: "tls: peer did not false start: EOF",
1931 },
1932 {
Adam Langley7c803a62015-06-15 15:35:05 -07001933 protocol: dtls,
1934 name: "SendSplitAlert-Sync",
1935 config: Config{
1936 Bugs: ProtocolBugs{
1937 SendSplitAlert: true,
1938 },
1939 },
1940 },
1941 {
1942 protocol: dtls,
1943 name: "SendSplitAlert-Async",
1944 config: Config{
1945 Bugs: ProtocolBugs{
1946 SendSplitAlert: true,
1947 },
1948 },
1949 flags: []string{"-async"},
1950 },
1951 {
1952 protocol: dtls,
1953 name: "PackDTLSHandshake",
1954 config: Config{
1955 Bugs: ProtocolBugs{
1956 MaxHandshakeRecordLength: 2,
1957 PackHandshakeFragments: 20,
1958 PackHandshakeRecords: 200,
1959 },
1960 },
1961 },
1962 {
Adam Langley7c803a62015-06-15 15:35:05 -07001963 name: "SendEmptyRecords-Pass",
1964 sendEmptyRecords: 32,
1965 },
1966 {
1967 name: "SendEmptyRecords",
1968 sendEmptyRecords: 33,
1969 shouldFail: true,
1970 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
1971 },
1972 {
1973 name: "SendEmptyRecords-Async",
1974 sendEmptyRecords: 33,
1975 flags: []string{"-async"},
1976 shouldFail: true,
1977 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
1978 },
1979 {
David Benjamine8e84b92016-08-03 15:39:47 -04001980 name: "SendWarningAlerts-Pass",
1981 config: Config{
1982 MaxVersion: VersionTLS12,
1983 },
Adam Langley7c803a62015-06-15 15:35:05 -07001984 sendWarningAlerts: 4,
1985 },
1986 {
David Benjamine8e84b92016-08-03 15:39:47 -04001987 protocol: dtls,
1988 name: "SendWarningAlerts-DTLS-Pass",
1989 config: Config{
1990 MaxVersion: VersionTLS12,
1991 },
Adam Langley7c803a62015-06-15 15:35:05 -07001992 sendWarningAlerts: 4,
1993 },
1994 {
David Benjamine8e84b92016-08-03 15:39:47 -04001995 name: "SendWarningAlerts-TLS13",
1996 config: Config{
1997 MaxVersion: VersionTLS13,
1998 },
1999 sendWarningAlerts: 4,
2000 shouldFail: true,
2001 expectedError: ":BAD_ALERT:",
2002 expectedLocalError: "remote error: error decoding message",
2003 },
2004 {
2005 name: "SendWarningAlerts",
2006 config: Config{
2007 MaxVersion: VersionTLS12,
2008 },
Adam Langley7c803a62015-06-15 15:35:05 -07002009 sendWarningAlerts: 5,
2010 shouldFail: true,
2011 expectedError: ":TOO_MANY_WARNING_ALERTS:",
2012 },
2013 {
David Benjamine8e84b92016-08-03 15:39:47 -04002014 name: "SendWarningAlerts-Async",
2015 config: Config{
2016 MaxVersion: VersionTLS12,
2017 },
Adam Langley7c803a62015-06-15 15:35:05 -07002018 sendWarningAlerts: 5,
2019 flags: []string{"-async"},
2020 shouldFail: true,
2021 expectedError: ":TOO_MANY_WARNING_ALERTS:",
2022 },
David Benjaminba4594a2015-06-18 18:36:15 -04002023 {
Steven Valdez32635b82016-08-16 11:25:03 -04002024 name: "SendKeyUpdates",
2025 config: Config{
2026 MaxVersion: VersionTLS13,
2027 },
2028 sendKeyUpdates: 33,
2029 shouldFail: true,
2030 expectedError: ":TOO_MANY_KEY_UPDATES:",
2031 },
2032 {
David Benjaminba4594a2015-06-18 18:36:15 -04002033 name: "EmptySessionID",
2034 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002035 MaxVersion: VersionTLS12,
David Benjaminba4594a2015-06-18 18:36:15 -04002036 SessionTicketsDisabled: true,
2037 },
2038 noSessionCache: true,
2039 flags: []string{"-expect-no-session"},
2040 },
David Benjamin30789da2015-08-29 22:56:45 -04002041 {
2042 name: "Unclean-Shutdown",
2043 config: Config{
2044 Bugs: ProtocolBugs{
2045 NoCloseNotify: true,
2046 ExpectCloseNotify: true,
2047 },
2048 },
2049 shimShutsDown: true,
2050 flags: []string{"-check-close-notify"},
2051 shouldFail: true,
2052 expectedError: "Unexpected SSL_shutdown result: -1 != 1",
2053 },
2054 {
2055 name: "Unclean-Shutdown-Ignored",
2056 config: Config{
2057 Bugs: ProtocolBugs{
2058 NoCloseNotify: true,
2059 },
2060 },
2061 shimShutsDown: true,
2062 },
David Benjamin4f75aaf2015-09-01 16:53:10 -04002063 {
David Benjaminfa214e42016-05-10 17:03:10 -04002064 name: "Unclean-Shutdown-Alert",
2065 config: Config{
2066 Bugs: ProtocolBugs{
2067 SendAlertOnShutdown: alertDecompressionFailure,
2068 ExpectCloseNotify: true,
2069 },
2070 },
2071 shimShutsDown: true,
2072 flags: []string{"-check-close-notify"},
2073 shouldFail: true,
2074 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:",
2075 },
2076 {
David Benjamin4f75aaf2015-09-01 16:53:10 -04002077 name: "LargePlaintext",
2078 config: Config{
2079 Bugs: ProtocolBugs{
2080 SendLargeRecords: true,
2081 },
2082 },
2083 messageLen: maxPlaintext + 1,
2084 shouldFail: true,
2085 expectedError: ":DATA_LENGTH_TOO_LONG:",
2086 },
2087 {
2088 protocol: dtls,
2089 name: "LargePlaintext-DTLS",
2090 config: Config{
2091 Bugs: ProtocolBugs{
2092 SendLargeRecords: true,
2093 },
2094 },
2095 messageLen: maxPlaintext + 1,
2096 shouldFail: true,
2097 expectedError: ":DATA_LENGTH_TOO_LONG:",
2098 },
2099 {
2100 name: "LargeCiphertext",
2101 config: Config{
2102 Bugs: ProtocolBugs{
2103 SendLargeRecords: true,
2104 },
2105 },
2106 messageLen: maxPlaintext * 2,
2107 shouldFail: true,
2108 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
2109 },
2110 {
2111 protocol: dtls,
2112 name: "LargeCiphertext-DTLS",
2113 config: Config{
2114 Bugs: ProtocolBugs{
2115 SendLargeRecords: true,
2116 },
2117 },
2118 messageLen: maxPlaintext * 2,
2119 // Unlike the other four cases, DTLS drops records which
2120 // are invalid before authentication, so the connection
2121 // does not fail.
2122 expectMessageDropped: true,
2123 },
David Benjamindd6fed92015-10-23 17:41:12 -04002124 {
David Benjamin4c3ddf72016-06-29 18:13:53 -04002125 // In TLS 1.2 and below, empty NewSessionTicket messages
2126 // mean the server changed its mind on sending a ticket.
David Benjamindd6fed92015-10-23 17:41:12 -04002127 name: "SendEmptySessionTicket",
2128 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002129 MaxVersion: VersionTLS12,
David Benjamindd6fed92015-10-23 17:41:12 -04002130 Bugs: ProtocolBugs{
2131 SendEmptySessionTicket: true,
2132 FailIfSessionOffered: true,
2133 },
2134 },
David Benjamin46662482016-08-17 00:51:00 -04002135 flags: []string{"-expect-no-session"},
David Benjamindd6fed92015-10-23 17:41:12 -04002136 },
David Benjamin99fdfb92015-11-02 12:11:35 -05002137 {
David Benjaminef5dfd22015-12-06 13:17:07 -05002138 name: "BadHelloRequest-1",
2139 renegotiate: 1,
2140 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002141 MaxVersion: VersionTLS12,
David Benjaminef5dfd22015-12-06 13:17:07 -05002142 Bugs: ProtocolBugs{
2143 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1},
2144 },
2145 },
2146 flags: []string{
2147 "-renegotiate-freely",
2148 "-expect-total-renegotiations", "1",
2149 },
2150 shouldFail: true,
David Benjamin163f29a2016-07-28 11:05:58 -04002151 expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
David Benjaminef5dfd22015-12-06 13:17:07 -05002152 },
2153 {
2154 name: "BadHelloRequest-2",
2155 renegotiate: 1,
2156 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002157 MaxVersion: VersionTLS12,
David Benjaminef5dfd22015-12-06 13:17:07 -05002158 Bugs: ProtocolBugs{
2159 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0},
2160 },
2161 },
2162 flags: []string{
2163 "-renegotiate-freely",
2164 "-expect-total-renegotiations", "1",
2165 },
2166 shouldFail: true,
2167 expectedError: ":BAD_HELLO_REQUEST:",
2168 },
David Benjaminef1b0092015-11-21 14:05:44 -05002169 {
2170 testType: serverTest,
2171 name: "SupportTicketsWithSessionID",
2172 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002173 MaxVersion: VersionTLS12,
David Benjaminef1b0092015-11-21 14:05:44 -05002174 SessionTicketsDisabled: true,
2175 },
David Benjamin4c3ddf72016-06-29 18:13:53 -04002176 resumeConfig: &Config{
2177 MaxVersion: VersionTLS12,
2178 },
David Benjaminef1b0092015-11-21 14:05:44 -05002179 resumeSession: true,
2180 },
David Benjamin02edcd02016-07-27 17:40:37 -04002181 {
2182 protocol: dtls,
2183 name: "DTLS-SendExtraFinished",
2184 config: Config{
2185 Bugs: ProtocolBugs{
2186 SendExtraFinished: true,
2187 },
2188 },
2189 shouldFail: true,
2190 expectedError: ":UNEXPECTED_RECORD:",
2191 },
2192 {
2193 protocol: dtls,
2194 name: "DTLS-SendExtraFinished-Reordered",
2195 config: Config{
2196 Bugs: ProtocolBugs{
2197 MaxHandshakeRecordLength: 2,
2198 ReorderHandshakeFragments: true,
2199 SendExtraFinished: true,
2200 },
2201 },
2202 shouldFail: true,
2203 expectedError: ":UNEXPECTED_RECORD:",
2204 },
David Benjamine97fb482016-07-29 09:23:07 -04002205 {
2206 testType: serverTest,
2207 name: "V2ClientHello-EmptyRecordPrefix",
2208 config: Config{
2209 // Choose a cipher suite that does not involve
2210 // elliptic curves, so no extensions are
2211 // involved.
2212 MaxVersion: VersionTLS12,
Matt Braithwaite07e78062016-08-21 14:50:43 -07002213 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjamine97fb482016-07-29 09:23:07 -04002214 Bugs: ProtocolBugs{
2215 SendV2ClientHello: true,
2216 },
2217 },
2218 sendPrefix: string([]byte{
2219 byte(recordTypeHandshake),
2220 3, 1, // version
2221 0, 0, // length
2222 }),
2223 // A no-op empty record may not be sent before V2ClientHello.
2224 shouldFail: true,
2225 expectedError: ":WRONG_VERSION_NUMBER:",
2226 },
2227 {
2228 testType: serverTest,
2229 name: "V2ClientHello-WarningAlertPrefix",
2230 config: Config{
2231 // Choose a cipher suite that does not involve
2232 // elliptic curves, so no extensions are
2233 // involved.
2234 MaxVersion: VersionTLS12,
Matt Braithwaite07e78062016-08-21 14:50:43 -07002235 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjamine97fb482016-07-29 09:23:07 -04002236 Bugs: ProtocolBugs{
2237 SendV2ClientHello: true,
2238 },
2239 },
2240 sendPrefix: string([]byte{
2241 byte(recordTypeAlert),
2242 3, 1, // version
2243 0, 2, // length
2244 alertLevelWarning, byte(alertDecompressionFailure),
2245 }),
2246 // A no-op warning alert may not be sent before V2ClientHello.
2247 shouldFail: true,
2248 expectedError: ":WRONG_VERSION_NUMBER:",
2249 },
Steven Valdez1dc53d22016-07-26 12:27:38 -04002250 {
2251 testType: clientTest,
2252 name: "KeyUpdate",
2253 config: Config{
2254 MaxVersion: VersionTLS13,
2255 Bugs: ProtocolBugs{
2256 SendKeyUpdateBeforeEveryAppDataRecord: true,
2257 },
2258 },
2259 },
David Benjaminabe94e32016-09-04 14:18:58 -04002260 {
2261 name: "SendSNIWarningAlert",
2262 config: Config{
2263 MaxVersion: VersionTLS12,
2264 Bugs: ProtocolBugs{
2265 SendSNIWarningAlert: true,
2266 },
2267 },
2268 },
David Benjaminc241d792016-09-09 10:34:20 -04002269 {
2270 testType: serverTest,
2271 name: "ExtraCompressionMethods-TLS12",
2272 config: Config{
2273 MaxVersion: VersionTLS12,
2274 Bugs: ProtocolBugs{
2275 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
2276 },
2277 },
2278 },
2279 {
2280 testType: serverTest,
2281 name: "ExtraCompressionMethods-TLS13",
2282 config: Config{
2283 MaxVersion: VersionTLS13,
2284 Bugs: ProtocolBugs{
2285 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
2286 },
2287 },
2288 shouldFail: true,
2289 expectedError: ":INVALID_COMPRESSION_LIST:",
2290 expectedLocalError: "remote error: illegal parameter",
2291 },
2292 {
2293 testType: serverTest,
2294 name: "NoNullCompression-TLS12",
2295 config: Config{
2296 MaxVersion: VersionTLS12,
2297 Bugs: ProtocolBugs{
2298 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
2299 },
2300 },
2301 shouldFail: true,
2302 expectedError: ":NO_COMPRESSION_SPECIFIED:",
2303 expectedLocalError: "remote error: illegal parameter",
2304 },
2305 {
2306 testType: serverTest,
2307 name: "NoNullCompression-TLS13",
2308 config: Config{
2309 MaxVersion: VersionTLS13,
2310 Bugs: ProtocolBugs{
2311 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
2312 },
2313 },
2314 shouldFail: true,
2315 expectedError: ":INVALID_COMPRESSION_LIST:",
2316 expectedLocalError: "remote error: illegal parameter",
2317 },
Adam Langley7c803a62015-06-15 15:35:05 -07002318 }
Adam Langley7c803a62015-06-15 15:35:05 -07002319 testCases = append(testCases, basicTests...)
2320}
2321
Adam Langley95c29f32014-06-20 12:00:00 -07002322func addCipherSuiteTests() {
David Benjamine470e662016-07-18 15:47:32 +02002323 const bogusCipher = 0xfe00
2324
Adam Langley95c29f32014-06-20 12:00:00 -07002325 for _, suite := range testCipherSuites {
David Benjamin48cae082014-10-27 01:06:24 -04002326 const psk = "12345"
2327 const pskIdentity = "luggage combo"
2328
Adam Langley95c29f32014-06-20 12:00:00 -07002329 var cert Certificate
David Benjamin025b3d32014-07-01 19:53:04 -04002330 var certFile string
2331 var keyFile string
David Benjamin8b8c0062014-11-23 02:47:52 -05002332 if hasComponent(suite.name, "ECDSA") {
David Benjamin33863262016-07-08 17:20:12 -07002333 cert = ecdsaP256Certificate
2334 certFile = ecdsaP256CertificateFile
2335 keyFile = ecdsaP256KeyFile
Adam Langley95c29f32014-06-20 12:00:00 -07002336 } else {
David Benjamin33863262016-07-08 17:20:12 -07002337 cert = rsaCertificate
David Benjamin025b3d32014-07-01 19:53:04 -04002338 certFile = rsaCertificateFile
2339 keyFile = rsaKeyFile
Adam Langley95c29f32014-06-20 12:00:00 -07002340 }
2341
David Benjamin48cae082014-10-27 01:06:24 -04002342 var flags []string
David Benjamin8b8c0062014-11-23 02:47:52 -05002343 if hasComponent(suite.name, "PSK") {
David Benjamin48cae082014-10-27 01:06:24 -04002344 flags = append(flags,
2345 "-psk", psk,
2346 "-psk-identity", pskIdentity)
2347 }
Matt Braithwaiteaf096752015-09-02 19:48:16 -07002348 if hasComponent(suite.name, "NULL") {
2349 // NULL ciphers must be explicitly enabled.
2350 flags = append(flags, "-cipher", "DEFAULT:NULL-SHA")
2351 }
Matt Braithwaite053931e2016-05-25 12:06:05 -07002352 if hasComponent(suite.name, "CECPQ1") {
2353 // CECPQ1 ciphers must be explicitly enabled.
2354 flags = append(flags, "-cipher", "DEFAULT:kCECPQ1")
2355 }
David Benjamin881f1962016-08-10 18:29:12 -04002356 if hasComponent(suite.name, "ECDHE-PSK") && hasComponent(suite.name, "GCM") {
2357 // ECDHE_PSK AES_GCM ciphers must be explicitly enabled
2358 // for now.
2359 flags = append(flags, "-cipher", suite.name)
2360 }
David Benjamin48cae082014-10-27 01:06:24 -04002361
Adam Langley95c29f32014-06-20 12:00:00 -07002362 for _, ver := range tlsVersions {
David Benjamin0407e762016-06-17 16:41:18 -04002363 for _, protocol := range []protocol{tls, dtls} {
2364 var prefix string
2365 if protocol == dtls {
2366 if !ver.hasDTLS {
2367 continue
2368 }
2369 prefix = "D"
2370 }
Adam Langley95c29f32014-06-20 12:00:00 -07002371
David Benjamin0407e762016-06-17 16:41:18 -04002372 var shouldServerFail, shouldClientFail bool
2373 if hasComponent(suite.name, "ECDHE") && ver.version == VersionSSL30 {
2374 // BoringSSL clients accept ECDHE on SSLv3, but
2375 // a BoringSSL server will never select it
2376 // because the extension is missing.
2377 shouldServerFail = true
2378 }
2379 if isTLS12Only(suite.name) && ver.version < VersionTLS12 {
2380 shouldClientFail = true
2381 shouldServerFail = true
2382 }
David Benjamin54c217c2016-07-13 12:35:25 -04002383 if !isTLS13Suite(suite.name) && ver.version >= VersionTLS13 {
Nick Harper1fd39d82016-06-14 18:14:35 -07002384 shouldClientFail = true
2385 shouldServerFail = true
2386 }
David Benjamin0407e762016-06-17 16:41:18 -04002387 if !isDTLSCipher(suite.name) && protocol == dtls {
2388 shouldClientFail = true
2389 shouldServerFail = true
2390 }
David Benjamin4298d772015-12-19 00:18:25 -05002391
David Benjamin0407e762016-06-17 16:41:18 -04002392 var expectedServerError, expectedClientError string
2393 if shouldServerFail {
2394 expectedServerError = ":NO_SHARED_CIPHER:"
2395 }
2396 if shouldClientFail {
2397 expectedClientError = ":WRONG_CIPHER_RETURNED:"
2398 }
David Benjamin025b3d32014-07-01 19:53:04 -04002399
David Benjamin6fd297b2014-08-11 18:43:38 -04002400 testCases = append(testCases, testCase{
2401 testType: serverTest,
David Benjamin0407e762016-06-17 16:41:18 -04002402 protocol: protocol,
2403
2404 name: prefix + ver.name + "-" + suite.name + "-server",
David Benjamin6fd297b2014-08-11 18:43:38 -04002405 config: Config{
David Benjamin48cae082014-10-27 01:06:24 -04002406 MinVersion: ver.version,
2407 MaxVersion: ver.version,
2408 CipherSuites: []uint16{suite.id},
2409 Certificates: []Certificate{cert},
2410 PreSharedKey: []byte(psk),
2411 PreSharedKeyIdentity: pskIdentity,
David Benjamin0407e762016-06-17 16:41:18 -04002412 Bugs: ProtocolBugs{
David Benjamin9acf0ca2016-06-25 00:01:28 -04002413 EnableAllCiphers: shouldServerFail,
2414 IgnorePeerCipherPreferences: shouldServerFail,
David Benjamin0407e762016-06-17 16:41:18 -04002415 },
David Benjamin6fd297b2014-08-11 18:43:38 -04002416 },
2417 certFile: certFile,
2418 keyFile: keyFile,
David Benjamin48cae082014-10-27 01:06:24 -04002419 flags: flags,
Steven Valdez4aa154e2016-07-29 14:32:55 -04002420 resumeSession: true,
David Benjamin0407e762016-06-17 16:41:18 -04002421 shouldFail: shouldServerFail,
2422 expectedError: expectedServerError,
2423 })
2424
2425 testCases = append(testCases, testCase{
2426 testType: clientTest,
2427 protocol: protocol,
2428 name: prefix + ver.name + "-" + suite.name + "-client",
2429 config: Config{
2430 MinVersion: ver.version,
2431 MaxVersion: ver.version,
2432 CipherSuites: []uint16{suite.id},
2433 Certificates: []Certificate{cert},
2434 PreSharedKey: []byte(psk),
2435 PreSharedKeyIdentity: pskIdentity,
2436 Bugs: ProtocolBugs{
David Benjamin9acf0ca2016-06-25 00:01:28 -04002437 EnableAllCiphers: shouldClientFail,
2438 IgnorePeerCipherPreferences: shouldClientFail,
David Benjamin0407e762016-06-17 16:41:18 -04002439 },
2440 },
2441 flags: flags,
Steven Valdez4aa154e2016-07-29 14:32:55 -04002442 resumeSession: true,
David Benjamin0407e762016-06-17 16:41:18 -04002443 shouldFail: shouldClientFail,
2444 expectedError: expectedClientError,
David Benjamin6fd297b2014-08-11 18:43:38 -04002445 })
David Benjamin2c99d282015-09-01 10:23:00 -04002446
Nick Harper1fd39d82016-06-14 18:14:35 -07002447 if !shouldClientFail {
2448 // Ensure the maximum record size is accepted.
2449 testCases = append(testCases, testCase{
2450 name: prefix + ver.name + "-" + suite.name + "-LargeRecord",
2451 config: Config{
2452 MinVersion: ver.version,
2453 MaxVersion: ver.version,
2454 CipherSuites: []uint16{suite.id},
2455 Certificates: []Certificate{cert},
2456 PreSharedKey: []byte(psk),
2457 PreSharedKeyIdentity: pskIdentity,
2458 },
2459 flags: flags,
2460 messageLen: maxPlaintext,
2461 })
2462 }
2463 }
David Benjamin2c99d282015-09-01 10:23:00 -04002464 }
Adam Langley95c29f32014-06-20 12:00:00 -07002465 }
Adam Langleya7997f12015-05-14 17:38:50 -07002466
2467 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002468 name: "NoSharedCipher",
2469 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002470 MaxVersion: VersionTLS12,
2471 CipherSuites: []uint16{},
2472 },
2473 shouldFail: true,
2474 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
2475 })
2476
2477 testCases = append(testCases, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04002478 name: "NoSharedCipher-TLS13",
2479 config: Config{
2480 MaxVersion: VersionTLS13,
2481 CipherSuites: []uint16{},
2482 },
2483 shouldFail: true,
2484 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
2485 })
2486
2487 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04002488 name: "UnsupportedCipherSuite",
2489 config: Config{
2490 MaxVersion: VersionTLS12,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002491 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
David Benjamin4c3ddf72016-06-29 18:13:53 -04002492 Bugs: ProtocolBugs{
2493 IgnorePeerCipherPreferences: true,
2494 },
2495 },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002496 flags: []string{"-cipher", "DEFAULT:!AES"},
David Benjamin4c3ddf72016-06-29 18:13:53 -04002497 shouldFail: true,
2498 expectedError: ":WRONG_CIPHER_RETURNED:",
2499 })
2500
2501 testCases = append(testCases, testCase{
David Benjamine470e662016-07-18 15:47:32 +02002502 name: "ServerHelloBogusCipher",
2503 config: Config{
2504 MaxVersion: VersionTLS12,
2505 Bugs: ProtocolBugs{
2506 SendCipherSuite: bogusCipher,
2507 },
2508 },
2509 shouldFail: true,
2510 expectedError: ":UNKNOWN_CIPHER_RETURNED:",
2511 })
2512 testCases = append(testCases, testCase{
2513 name: "ServerHelloBogusCipher-TLS13",
2514 config: Config{
2515 MaxVersion: VersionTLS13,
2516 Bugs: ProtocolBugs{
2517 SendCipherSuite: bogusCipher,
2518 },
2519 },
2520 shouldFail: true,
2521 expectedError: ":UNKNOWN_CIPHER_RETURNED:",
2522 })
2523
2524 testCases = append(testCases, testCase{
Adam Langleya7997f12015-05-14 17:38:50 -07002525 name: "WeakDH",
2526 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002527 MaxVersion: VersionTLS12,
Adam Langleya7997f12015-05-14 17:38:50 -07002528 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2529 Bugs: ProtocolBugs{
2530 // This is a 1023-bit prime number, generated
2531 // with:
2532 // openssl gendh 1023 | openssl asn1parse -i
2533 DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"),
2534 },
2535 },
2536 shouldFail: true,
David Benjamincd24a392015-11-11 13:23:05 -08002537 expectedError: ":BAD_DH_P_LENGTH:",
Adam Langleya7997f12015-05-14 17:38:50 -07002538 })
Adam Langleycef75832015-09-03 14:51:12 -07002539
David Benjamincd24a392015-11-11 13:23:05 -08002540 testCases = append(testCases, testCase{
2541 name: "SillyDH",
2542 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002543 MaxVersion: VersionTLS12,
David Benjamincd24a392015-11-11 13:23:05 -08002544 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2545 Bugs: ProtocolBugs{
2546 // This is a 4097-bit prime number, generated
2547 // with:
2548 // openssl gendh 4097 | openssl asn1parse -i
2549 DHGroupPrime: bigFromHex("01D366FA64A47419B0CD4A45918E8D8C8430F674621956A9F52B0CA592BC104C6E38D60C58F2CA66792A2B7EBDC6F8FFE75AB7D6862C261F34E96A2AEEF53AB7C21365C2E8FB0582F71EB57B1C227C0E55AE859E9904A25EFECD7B435C4D4357BD840B03649D4A1F8037D89EA4E1967DBEEF1CC17A6111C48F12E9615FFF336D3F07064CB17C0B765A012C850B9E3AA7A6984B96D8C867DDC6D0F4AB52042572244796B7ECFF681CD3B3E2E29AAECA391A775BEE94E502FB15881B0F4AC60314EA947C0C82541C3D16FD8C0E09BB7F8F786582032859D9C13187CE6C0CB6F2D3EE6C3C9727C15F14B21D3CD2E02BDB9D119959B0E03DC9E5A91E2578762300B1517D2352FC1D0BB934A4C3E1B20CE9327DB102E89A6C64A8C3148EDFC5A94913933853442FA84451B31FD21E492F92DD5488E0D871AEBFE335A4B92431DEC69591548010E76A5B365D346786E9A2D3E589867D796AA5E25211201D757560D318A87DFB27F3E625BC373DB48BF94A63161C674C3D4265CB737418441B7650EABC209CF675A439BEB3E9D1AA1B79F67198A40CEFD1C89144F7D8BAF61D6AD36F466DA546B4174A0E0CAF5BD788C8243C7C2DDDCC3DB6FC89F12F17D19FBD9B0BC76FE92891CD6BA07BEA3B66EF12D0D85E788FD58675C1B0FBD16029DCC4D34E7A1A41471BDEDF78BF591A8B4E96D88BEC8EDC093E616292BFC096E69A916E8D624B"),
2550 },
2551 },
2552 shouldFail: true,
2553 expectedError: ":DH_P_TOO_LONG:",
2554 })
2555
Adam Langleyc4f25ce2015-11-26 16:39:08 -08002556 // This test ensures that Diffie-Hellman public values are padded with
2557 // zeros so that they're the same length as the prime. This is to avoid
2558 // hitting a bug in yaSSL.
2559 testCases = append(testCases, testCase{
2560 testType: serverTest,
2561 name: "DHPublicValuePadded",
2562 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002563 MaxVersion: VersionTLS12,
Adam Langleyc4f25ce2015-11-26 16:39:08 -08002564 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
2565 Bugs: ProtocolBugs{
2566 RequireDHPublicValueLen: (1025 + 7) / 8,
2567 },
2568 },
2569 flags: []string{"-use-sparse-dh-prime"},
2570 })
David Benjamincd24a392015-11-11 13:23:05 -08002571
David Benjamin241ae832016-01-15 03:04:54 -05002572 // The server must be tolerant to bogus ciphers.
David Benjamin241ae832016-01-15 03:04:54 -05002573 testCases = append(testCases, testCase{
2574 testType: serverTest,
2575 name: "UnknownCipher",
2576 config: Config{
2577 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2578 },
2579 })
2580
David Benjamin78679342016-09-16 19:42:05 -04002581 // Test empty ECDHE_PSK identity hints work as expected.
2582 testCases = append(testCases, testCase{
2583 name: "EmptyECDHEPSKHint",
2584 config: Config{
2585 MaxVersion: VersionTLS12,
2586 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
2587 PreSharedKey: []byte("secret"),
2588 },
2589 flags: []string{"-psk", "secret"},
2590 })
2591
2592 // Test empty PSK identity hints work as expected, even if an explicit
2593 // ServerKeyExchange is sent.
2594 testCases = append(testCases, testCase{
2595 name: "ExplicitEmptyPSKHint",
2596 config: Config{
2597 MaxVersion: VersionTLS12,
2598 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
2599 PreSharedKey: []byte("secret"),
2600 Bugs: ProtocolBugs{
2601 AlwaysSendPreSharedKeyIdentityHint: true,
2602 },
2603 },
2604 flags: []string{"-psk", "secret"},
2605 })
2606
Adam Langleycef75832015-09-03 14:51:12 -07002607 // versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
2608 // 1.1 specific cipher suite settings. A server is setup with the given
2609 // cipher lists and then a connection is made for each member of
2610 // expectations. The cipher suite that the server selects must match
2611 // the specified one.
2612 var versionSpecificCiphersTest = []struct {
2613 ciphersDefault, ciphersTLS10, ciphersTLS11 string
2614 // expectations is a map from TLS version to cipher suite id.
2615 expectations map[uint16]uint16
2616 }{
2617 {
2618 // Test that the null case (where no version-specific ciphers are set)
2619 // works as expected.
Matt Braithwaite07e78062016-08-21 14:50:43 -07002620 "DES-CBC3-SHA:AES128-SHA", // default ciphers
2621 "", // no ciphers specifically for TLS ≥ 1.0
2622 "", // no ciphers specifically for TLS ≥ 1.1
Adam Langleycef75832015-09-03 14:51:12 -07002623 map[uint16]uint16{
Matt Braithwaite07e78062016-08-21 14:50:43 -07002624 VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
2625 VersionTLS10: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
2626 VersionTLS11: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
2627 VersionTLS12: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
Adam Langleycef75832015-09-03 14:51:12 -07002628 },
2629 },
2630 {
2631 // With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
2632 // cipher.
Matt Braithwaite07e78062016-08-21 14:50:43 -07002633 "DES-CBC3-SHA:AES128-SHA", // default
2634 "AES128-SHA", // these ciphers for TLS ≥ 1.0
2635 "", // no ciphers specifically for TLS ≥ 1.1
Adam Langleycef75832015-09-03 14:51:12 -07002636 map[uint16]uint16{
Matt Braithwaite07e78062016-08-21 14:50:43 -07002637 VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
Adam Langleycef75832015-09-03 14:51:12 -07002638 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
2639 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
2640 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
2641 },
2642 },
2643 {
2644 // With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
2645 // cipher.
Matt Braithwaite07e78062016-08-21 14:50:43 -07002646 "DES-CBC3-SHA:AES128-SHA", // default
2647 "", // no ciphers specifically for TLS ≥ 1.0
2648 "AES128-SHA", // these ciphers for TLS ≥ 1.1
Adam Langleycef75832015-09-03 14:51:12 -07002649 map[uint16]uint16{
Matt Braithwaite07e78062016-08-21 14:50:43 -07002650 VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
2651 VersionTLS10: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
Adam Langleycef75832015-09-03 14:51:12 -07002652 VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
2653 VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
2654 },
2655 },
2656 {
2657 // With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
2658 // mask ciphers_tls10 for TLS 1.1 and 1.2.
Matt Braithwaite07e78062016-08-21 14:50:43 -07002659 "DES-CBC3-SHA:AES128-SHA", // default
2660 "AES128-SHA", // these ciphers for TLS ≥ 1.0
2661 "AES256-SHA", // these ciphers for TLS ≥ 1.1
Adam Langleycef75832015-09-03 14:51:12 -07002662 map[uint16]uint16{
Matt Braithwaite07e78062016-08-21 14:50:43 -07002663 VersionSSL30: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
Adam Langleycef75832015-09-03 14:51:12 -07002664 VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
2665 VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
2666 VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
2667 },
2668 },
2669 }
2670
2671 for i, test := range versionSpecificCiphersTest {
2672 for version, expectedCipherSuite := range test.expectations {
2673 flags := []string{"-cipher", test.ciphersDefault}
2674 if len(test.ciphersTLS10) > 0 {
2675 flags = append(flags, "-cipher-tls10", test.ciphersTLS10)
2676 }
2677 if len(test.ciphersTLS11) > 0 {
2678 flags = append(flags, "-cipher-tls11", test.ciphersTLS11)
2679 }
2680
2681 testCases = append(testCases, testCase{
2682 testType: serverTest,
2683 name: fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version),
2684 config: Config{
2685 MaxVersion: version,
2686 MinVersion: version,
Matt Braithwaite07e78062016-08-21 14:50:43 -07002687 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
Adam Langleycef75832015-09-03 14:51:12 -07002688 },
2689 flags: flags,
2690 expectedCipher: expectedCipherSuite,
2691 })
2692 }
2693 }
Adam Langley95c29f32014-06-20 12:00:00 -07002694}
2695
2696func addBadECDSASignatureTests() {
2697 for badR := BadValue(1); badR < NumBadValues; badR++ {
2698 for badS := BadValue(1); badS < NumBadValues; badS++ {
David Benjamin025b3d32014-07-01 19:53:04 -04002699 testCases = append(testCases, testCase{
Adam Langley95c29f32014-06-20 12:00:00 -07002700 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
2701 config: Config{
2702 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07002703 Certificates: []Certificate{ecdsaP256Certificate},
Adam Langley95c29f32014-06-20 12:00:00 -07002704 Bugs: ProtocolBugs{
2705 BadECDSAR: badR,
2706 BadECDSAS: badS,
2707 },
2708 },
2709 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002710 expectedError: ":BAD_SIGNATURE:",
Adam Langley95c29f32014-06-20 12:00:00 -07002711 })
2712 }
2713 }
2714}
2715
Adam Langley80842bd2014-06-20 12:00:00 -07002716func addCBCPaddingTests() {
David Benjamin025b3d32014-07-01 19:53:04 -04002717 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002718 name: "MaxCBCPadding",
2719 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002720 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002721 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2722 Bugs: ProtocolBugs{
2723 MaxPadding: true,
2724 },
2725 },
2726 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
2727 })
David Benjamin025b3d32014-07-01 19:53:04 -04002728 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002729 name: "BadCBCPadding",
2730 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002731 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002732 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2733 Bugs: ProtocolBugs{
2734 PaddingFirstByteBad: true,
2735 },
2736 },
2737 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002738 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
Adam Langley80842bd2014-06-20 12:00:00 -07002739 })
2740 // OpenSSL previously had an issue where the first byte of padding in
2741 // 255 bytes of padding wasn't checked.
David Benjamin025b3d32014-07-01 19:53:04 -04002742 testCases = append(testCases, testCase{
Adam Langley80842bd2014-06-20 12:00:00 -07002743 name: "BadCBCPadding255",
2744 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002745 MaxVersion: VersionTLS12,
Adam Langley80842bd2014-06-20 12:00:00 -07002746 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2747 Bugs: ProtocolBugs{
2748 MaxPadding: true,
2749 PaddingFirstByteBadIf255: true,
2750 },
2751 },
2752 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
2753 shouldFail: true,
David Benjamin11d50f92016-03-10 15:55:45 -05002754 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
Adam Langley80842bd2014-06-20 12:00:00 -07002755 })
2756}
2757
Kenny Root7fdeaf12014-08-05 15:23:37 -07002758func addCBCSplittingTests() {
2759 testCases = append(testCases, testCase{
2760 name: "CBCRecordSplitting",
2761 config: Config{
2762 MaxVersion: VersionTLS10,
2763 MinVersion: VersionTLS10,
2764 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2765 },
David Benjaminac8302a2015-09-01 17:18:15 -04002766 messageLen: -1, // read until EOF
2767 resumeSession: true,
Kenny Root7fdeaf12014-08-05 15:23:37 -07002768 flags: []string{
2769 "-async",
2770 "-write-different-record-sizes",
2771 "-cbc-record-splitting",
2772 },
David Benjamina8e3e0e2014-08-06 22:11:10 -04002773 })
2774 testCases = append(testCases, testCase{
Kenny Root7fdeaf12014-08-05 15:23:37 -07002775 name: "CBCRecordSplittingPartialWrite",
2776 config: Config{
2777 MaxVersion: VersionTLS10,
2778 MinVersion: VersionTLS10,
2779 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2780 },
2781 messageLen: -1, // read until EOF
2782 flags: []string{
2783 "-async",
2784 "-write-different-record-sizes",
2785 "-cbc-record-splitting",
2786 "-partial-write",
2787 },
2788 })
2789}
2790
David Benjamin636293b2014-07-08 17:59:18 -04002791func addClientAuthTests() {
David Benjamin407a10c2014-07-16 12:58:59 -04002792 // Add a dummy cert pool to stress certificate authority parsing.
2793 // TODO(davidben): Add tests that those values parse out correctly.
2794 certPool := x509.NewCertPool()
2795 cert, err := x509.ParseCertificate(rsaCertificate.Certificate[0])
2796 if err != nil {
2797 panic(err)
2798 }
2799 certPool.AddCert(cert)
2800
David Benjamin636293b2014-07-08 17:59:18 -04002801 for _, ver := range tlsVersions {
David Benjamin636293b2014-07-08 17:59:18 -04002802 testCases = append(testCases, testCase{
2803 testType: clientTest,
David Benjamin67666e72014-07-12 15:47:52 -04002804 name: ver.name + "-Client-ClientAuth-RSA",
David Benjamin636293b2014-07-08 17:59:18 -04002805 config: Config{
David Benjamine098ec22014-08-27 23:13:20 -04002806 MinVersion: ver.version,
2807 MaxVersion: ver.version,
2808 ClientAuth: RequireAnyClientCert,
2809 ClientCAs: certPool,
David Benjamin636293b2014-07-08 17:59:18 -04002810 },
2811 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07002812 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2813 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin636293b2014-07-08 17:59:18 -04002814 },
2815 })
2816 testCases = append(testCases, testCase{
David Benjamin67666e72014-07-12 15:47:52 -04002817 testType: serverTest,
2818 name: ver.name + "-Server-ClientAuth-RSA",
2819 config: Config{
David Benjamine098ec22014-08-27 23:13:20 -04002820 MinVersion: ver.version,
2821 MaxVersion: ver.version,
David Benjamin67666e72014-07-12 15:47:52 -04002822 Certificates: []Certificate{rsaCertificate},
2823 },
2824 flags: []string{"-require-any-client-certificate"},
2825 })
David Benjamine098ec22014-08-27 23:13:20 -04002826 if ver.version != VersionSSL30 {
2827 testCases = append(testCases, testCase{
2828 testType: serverTest,
2829 name: ver.name + "-Server-ClientAuth-ECDSA",
2830 config: Config{
2831 MinVersion: ver.version,
2832 MaxVersion: ver.version,
David Benjamin33863262016-07-08 17:20:12 -07002833 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamine098ec22014-08-27 23:13:20 -04002834 },
2835 flags: []string{"-require-any-client-certificate"},
2836 })
2837 testCases = append(testCases, testCase{
2838 testType: clientTest,
2839 name: ver.name + "-Client-ClientAuth-ECDSA",
2840 config: Config{
2841 MinVersion: ver.version,
2842 MaxVersion: ver.version,
2843 ClientAuth: RequireAnyClientCert,
2844 ClientCAs: certPool,
2845 },
2846 flags: []string{
David Benjamin33863262016-07-08 17:20:12 -07002847 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
2848 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
David Benjamine098ec22014-08-27 23:13:20 -04002849 },
2850 })
2851 }
Adam Langley37646832016-08-01 16:16:46 -07002852
2853 testCases = append(testCases, testCase{
2854 name: "NoClientCertificate-" + ver.name,
2855 config: Config{
2856 MinVersion: ver.version,
2857 MaxVersion: ver.version,
2858 ClientAuth: RequireAnyClientCert,
2859 },
2860 shouldFail: true,
2861 expectedLocalError: "client didn't provide a certificate",
2862 })
2863
2864 testCases = append(testCases, testCase{
2865 // Even if not configured to expect a certificate, OpenSSL will
2866 // return X509_V_OK as the verify_result.
2867 testType: serverTest,
2868 name: "NoClientCertificateRequested-Server-" + ver.name,
2869 config: Config{
2870 MinVersion: ver.version,
2871 MaxVersion: ver.version,
2872 },
2873 flags: []string{
2874 "-expect-verify-result",
2875 },
2876 // TODO(davidben): Switch this to true when TLS 1.3
2877 // supports session resumption.
2878 resumeSession: ver.version < VersionTLS13,
2879 })
2880
2881 testCases = append(testCases, testCase{
2882 // If a client certificate is not provided, OpenSSL will still
2883 // return X509_V_OK as the verify_result.
2884 testType: serverTest,
2885 name: "NoClientCertificate-Server-" + ver.name,
2886 config: Config{
2887 MinVersion: ver.version,
2888 MaxVersion: ver.version,
2889 },
2890 flags: []string{
2891 "-expect-verify-result",
2892 "-verify-peer",
2893 },
2894 // TODO(davidben): Switch this to true when TLS 1.3
2895 // supports session resumption.
2896 resumeSession: ver.version < VersionTLS13,
2897 })
2898
2899 testCases = append(testCases, testCase{
2900 testType: serverTest,
2901 name: "RequireAnyClientCertificate-" + ver.name,
2902 config: Config{
2903 MinVersion: ver.version,
2904 MaxVersion: ver.version,
2905 },
2906 flags: []string{"-require-any-client-certificate"},
2907 shouldFail: true,
2908 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
2909 })
2910
2911 if ver.version != VersionSSL30 {
2912 testCases = append(testCases, testCase{
2913 testType: serverTest,
2914 name: "SkipClientCertificate-" + ver.name,
2915 config: Config{
2916 MinVersion: ver.version,
2917 MaxVersion: ver.version,
2918 Bugs: ProtocolBugs{
2919 SkipClientCertificate: true,
2920 },
2921 },
2922 // Setting SSL_VERIFY_PEER allows anonymous clients.
2923 flags: []string{"-verify-peer"},
2924 shouldFail: true,
2925 expectedError: ":UNEXPECTED_MESSAGE:",
2926 })
2927 }
David Benjamin636293b2014-07-08 17:59:18 -04002928 }
David Benjamin0b7ca7d2016-03-10 15:44:22 -05002929
David Benjaminc032dfa2016-05-12 14:54:57 -04002930 // Client auth is only legal in certificate-based ciphers.
2931 testCases = append(testCases, testCase{
2932 testType: clientTest,
2933 name: "ClientAuth-PSK",
2934 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002935 MaxVersion: VersionTLS12,
David Benjaminc032dfa2016-05-12 14:54:57 -04002936 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
2937 PreSharedKey: []byte("secret"),
2938 ClientAuth: RequireAnyClientCert,
2939 },
2940 flags: []string{
2941 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2942 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2943 "-psk", "secret",
2944 },
2945 shouldFail: true,
2946 expectedError: ":UNEXPECTED_MESSAGE:",
2947 })
2948 testCases = append(testCases, testCase{
2949 testType: clientTest,
2950 name: "ClientAuth-ECDHE_PSK",
2951 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07002952 MaxVersion: VersionTLS12,
David Benjaminc032dfa2016-05-12 14:54:57 -04002953 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
2954 PreSharedKey: []byte("secret"),
2955 ClientAuth: RequireAnyClientCert,
2956 },
2957 flags: []string{
2958 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
2959 "-key-file", path.Join(*resourceDir, rsaKeyFile),
2960 "-psk", "secret",
2961 },
2962 shouldFail: true,
2963 expectedError: ":UNEXPECTED_MESSAGE:",
2964 })
David Benjamin2f8935d2016-07-13 19:47:39 -04002965
2966 // Regression test for a bug where the client CA list, if explicitly
2967 // set to NULL, was mis-encoded.
2968 testCases = append(testCases, testCase{
2969 testType: serverTest,
2970 name: "Null-Client-CA-List",
2971 config: Config{
2972 MaxVersion: VersionTLS12,
2973 Certificates: []Certificate{rsaCertificate},
2974 },
2975 flags: []string{
2976 "-require-any-client-certificate",
2977 "-use-null-client-ca-list",
2978 },
2979 })
David Benjamin636293b2014-07-08 17:59:18 -04002980}
2981
Adam Langley75712922014-10-10 16:23:43 -07002982func addExtendedMasterSecretTests() {
2983 const expectEMSFlag = "-expect-extended-master-secret"
2984
2985 for _, with := range []bool{false, true} {
2986 prefix := "No"
Adam Langley75712922014-10-10 16:23:43 -07002987 if with {
2988 prefix = ""
Adam Langley75712922014-10-10 16:23:43 -07002989 }
2990
2991 for _, isClient := range []bool{false, true} {
2992 suffix := "-Server"
2993 testType := serverTest
2994 if isClient {
2995 suffix = "-Client"
2996 testType = clientTest
2997 }
2998
2999 for _, ver := range tlsVersions {
Steven Valdez143e8b32016-07-11 13:19:03 -04003000 // In TLS 1.3, the extension is irrelevant and
3001 // always reports as enabled.
3002 var flags []string
3003 if with || ver.version >= VersionTLS13 {
3004 flags = []string{expectEMSFlag}
3005 }
3006
Adam Langley75712922014-10-10 16:23:43 -07003007 test := testCase{
3008 testType: testType,
3009 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix,
3010 config: Config{
3011 MinVersion: ver.version,
3012 MaxVersion: ver.version,
3013 Bugs: ProtocolBugs{
3014 NoExtendedMasterSecret: !with,
3015 RequireExtendedMasterSecret: with,
3016 },
3017 },
David Benjamin48cae082014-10-27 01:06:24 -04003018 flags: flags,
3019 shouldFail: ver.version == VersionSSL30 && with,
Adam Langley75712922014-10-10 16:23:43 -07003020 }
3021 if test.shouldFail {
3022 test.expectedLocalError = "extended master secret required but not supported by peer"
3023 }
3024 testCases = append(testCases, test)
3025 }
3026 }
3027 }
3028
Adam Langleyba5934b2015-06-02 10:50:35 -07003029 for _, isClient := range []bool{false, true} {
3030 for _, supportedInFirstConnection := range []bool{false, true} {
3031 for _, supportedInResumeConnection := range []bool{false, true} {
3032 boolToWord := func(b bool) string {
3033 if b {
3034 return "Yes"
3035 }
3036 return "No"
3037 }
3038 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
3039 if isClient {
3040 suffix += "Client"
3041 } else {
3042 suffix += "Server"
3043 }
3044
3045 supportedConfig := Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003046 MaxVersion: VersionTLS12,
Adam Langleyba5934b2015-06-02 10:50:35 -07003047 Bugs: ProtocolBugs{
3048 RequireExtendedMasterSecret: true,
3049 },
3050 }
3051
3052 noSupportConfig := Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003053 MaxVersion: VersionTLS12,
Adam Langleyba5934b2015-06-02 10:50:35 -07003054 Bugs: ProtocolBugs{
3055 NoExtendedMasterSecret: true,
3056 },
3057 }
3058
3059 test := testCase{
3060 name: "ExtendedMasterSecret-" + suffix,
3061 resumeSession: true,
3062 }
3063
3064 if !isClient {
3065 test.testType = serverTest
3066 }
3067
3068 if supportedInFirstConnection {
3069 test.config = supportedConfig
3070 } else {
3071 test.config = noSupportConfig
3072 }
3073
3074 if supportedInResumeConnection {
3075 test.resumeConfig = &supportedConfig
3076 } else {
3077 test.resumeConfig = &noSupportConfig
3078 }
3079
3080 switch suffix {
3081 case "YesToYes-Client", "YesToYes-Server":
3082 // When a session is resumed, it should
3083 // still be aware that its master
3084 // secret was generated via EMS and
3085 // thus it's safe to use tls-unique.
3086 test.flags = []string{expectEMSFlag}
3087 case "NoToYes-Server":
3088 // If an original connection did not
3089 // contain EMS, but a resumption
3090 // handshake does, then a server should
3091 // not resume the session.
3092 test.expectResumeRejected = true
3093 case "YesToNo-Server":
3094 // Resuming an EMS session without the
3095 // EMS extension should cause the
3096 // server to abort the connection.
3097 test.shouldFail = true
3098 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
3099 case "NoToYes-Client":
3100 // A client should abort a connection
3101 // where the server resumed a non-EMS
3102 // session but echoed the EMS
3103 // extension.
3104 test.shouldFail = true
3105 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
3106 case "YesToNo-Client":
3107 // A client should abort a connection
3108 // where the server didn't echo EMS
3109 // when the session used it.
3110 test.shouldFail = true
3111 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
3112 }
3113
3114 testCases = append(testCases, test)
3115 }
3116 }
3117 }
David Benjamin163c9562016-08-29 23:14:17 -04003118
3119 // Switching EMS on renegotiation is forbidden.
3120 testCases = append(testCases, testCase{
3121 name: "ExtendedMasterSecret-Renego-NoEMS",
3122 config: Config{
3123 MaxVersion: VersionTLS12,
3124 Bugs: ProtocolBugs{
3125 NoExtendedMasterSecret: true,
3126 NoExtendedMasterSecretOnRenegotiation: true,
3127 },
3128 },
3129 renegotiate: 1,
3130 flags: []string{
3131 "-renegotiate-freely",
3132 "-expect-total-renegotiations", "1",
3133 },
3134 })
3135
3136 testCases = append(testCases, testCase{
3137 name: "ExtendedMasterSecret-Renego-Upgrade",
3138 config: Config{
3139 MaxVersion: VersionTLS12,
3140 Bugs: ProtocolBugs{
3141 NoExtendedMasterSecret: true,
3142 },
3143 },
3144 renegotiate: 1,
3145 flags: []string{
3146 "-renegotiate-freely",
3147 "-expect-total-renegotiations", "1",
3148 },
3149 shouldFail: true,
3150 expectedError: ":RENEGOTIATION_EMS_MISMATCH:",
3151 })
3152
3153 testCases = append(testCases, testCase{
3154 name: "ExtendedMasterSecret-Renego-Downgrade",
3155 config: Config{
3156 MaxVersion: VersionTLS12,
3157 Bugs: ProtocolBugs{
3158 NoExtendedMasterSecretOnRenegotiation: true,
3159 },
3160 },
3161 renegotiate: 1,
3162 flags: []string{
3163 "-renegotiate-freely",
3164 "-expect-total-renegotiations", "1",
3165 },
3166 shouldFail: true,
3167 expectedError: ":RENEGOTIATION_EMS_MISMATCH:",
3168 })
Adam Langley75712922014-10-10 16:23:43 -07003169}
3170
David Benjamin582ba042016-07-07 12:33:25 -07003171type stateMachineTestConfig struct {
3172 protocol protocol
3173 async bool
3174 splitHandshake, packHandshakeFlight bool
3175}
3176
David Benjamin43ec06f2014-08-05 02:28:57 -04003177// Adds tests that try to cover the range of the handshake state machine, under
3178// various conditions. Some of these are redundant with other tests, but they
3179// only cover the synchronous case.
David Benjamin582ba042016-07-07 12:33:25 -07003180func addAllStateMachineCoverageTests() {
3181 for _, async := range []bool{false, true} {
3182 for _, protocol := range []protocol{tls, dtls} {
3183 addStateMachineCoverageTests(stateMachineTestConfig{
3184 protocol: protocol,
3185 async: async,
3186 })
3187 addStateMachineCoverageTests(stateMachineTestConfig{
3188 protocol: protocol,
3189 async: async,
3190 splitHandshake: true,
3191 })
3192 if protocol == tls {
3193 addStateMachineCoverageTests(stateMachineTestConfig{
3194 protocol: protocol,
3195 async: async,
3196 packHandshakeFlight: true,
3197 })
3198 }
3199 }
3200 }
3201}
3202
3203func addStateMachineCoverageTests(config stateMachineTestConfig) {
David Benjamin760b1dd2015-05-15 23:33:48 -04003204 var tests []testCase
3205
3206 // Basic handshake, with resumption. Client and server,
3207 // session ID and session ticket.
3208 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003209 name: "Basic-Client",
3210 config: Config{
3211 MaxVersion: VersionTLS12,
3212 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003213 resumeSession: true,
David Benjaminef1b0092015-11-21 14:05:44 -05003214 // Ensure session tickets are used, not session IDs.
3215 noSessionCache: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003216 })
3217 tests = append(tests, testCase{
3218 name: "Basic-Client-RenewTicket",
3219 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003220 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003221 Bugs: ProtocolBugs{
3222 RenewTicketOnResume: true,
3223 },
3224 },
David Benjamin46662482016-08-17 00:51:00 -04003225 flags: []string{"-expect-ticket-renewal"},
3226 resumeSession: true,
3227 resumeRenewedSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003228 })
3229 tests = append(tests, testCase{
3230 name: "Basic-Client-NoTicket",
3231 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003232 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003233 SessionTicketsDisabled: true,
3234 },
3235 resumeSession: true,
3236 })
3237 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003238 name: "Basic-Client-Implicit",
3239 config: Config{
3240 MaxVersion: VersionTLS12,
3241 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003242 flags: []string{"-implicit-handshake"},
3243 resumeSession: true,
3244 })
3245 tests = append(tests, testCase{
David Benjaminef1b0092015-11-21 14:05:44 -05003246 testType: serverTest,
3247 name: "Basic-Server",
3248 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003249 MaxVersion: VersionTLS12,
David Benjaminef1b0092015-11-21 14:05:44 -05003250 Bugs: ProtocolBugs{
3251 RequireSessionTickets: true,
3252 },
3253 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003254 resumeSession: true,
3255 })
3256 tests = append(tests, testCase{
3257 testType: serverTest,
3258 name: "Basic-Server-NoTickets",
3259 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003260 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003261 SessionTicketsDisabled: true,
3262 },
3263 resumeSession: true,
3264 })
3265 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003266 testType: serverTest,
3267 name: "Basic-Server-Implicit",
3268 config: Config{
3269 MaxVersion: VersionTLS12,
3270 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003271 flags: []string{"-implicit-handshake"},
3272 resumeSession: true,
3273 })
3274 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003275 testType: serverTest,
3276 name: "Basic-Server-EarlyCallback",
3277 config: Config{
3278 MaxVersion: VersionTLS12,
3279 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003280 flags: []string{"-use-early-callback"},
3281 resumeSession: true,
3282 })
3283
Steven Valdez143e8b32016-07-11 13:19:03 -04003284 // TLS 1.3 basic handshake shapes.
David Benjamine73c7f42016-08-17 00:29:33 -04003285 if config.protocol == tls {
3286 tests = append(tests, testCase{
3287 name: "TLS13-1RTT-Client",
3288 config: Config{
3289 MaxVersion: VersionTLS13,
3290 MinVersion: VersionTLS13,
3291 },
David Benjamin46662482016-08-17 00:51:00 -04003292 resumeSession: true,
3293 resumeRenewedSession: true,
David Benjamine73c7f42016-08-17 00:29:33 -04003294 })
3295
3296 tests = append(tests, testCase{
3297 testType: serverTest,
3298 name: "TLS13-1RTT-Server",
3299 config: Config{
3300 MaxVersion: VersionTLS13,
3301 MinVersion: VersionTLS13,
3302 },
David Benjamin46662482016-08-17 00:51:00 -04003303 resumeSession: true,
3304 resumeRenewedSession: true,
David Benjamine73c7f42016-08-17 00:29:33 -04003305 })
3306
3307 tests = append(tests, testCase{
3308 name: "TLS13-HelloRetryRequest-Client",
3309 config: Config{
3310 MaxVersion: VersionTLS13,
3311 MinVersion: VersionTLS13,
3312 // P-384 requires a HelloRetryRequest against
3313 // BoringSSL's default configuration. Assert
3314 // that we do indeed test this with
3315 // ExpectMissingKeyShare.
3316 CurvePreferences: []CurveID{CurveP384},
3317 Bugs: ProtocolBugs{
3318 ExpectMissingKeyShare: true,
3319 },
3320 },
3321 // Cover HelloRetryRequest during an ECDHE-PSK resumption.
3322 resumeSession: true,
3323 })
3324
3325 tests = append(tests, testCase{
3326 testType: serverTest,
3327 name: "TLS13-HelloRetryRequest-Server",
3328 config: Config{
3329 MaxVersion: VersionTLS13,
3330 MinVersion: VersionTLS13,
3331 // Require a HelloRetryRequest for every curve.
3332 DefaultCurves: []CurveID{},
3333 },
3334 // Cover HelloRetryRequest during an ECDHE-PSK resumption.
3335 resumeSession: true,
3336 })
3337 }
Steven Valdez143e8b32016-07-11 13:19:03 -04003338
David Benjamin760b1dd2015-05-15 23:33:48 -04003339 // TLS client auth.
3340 tests = append(tests, testCase{
3341 testType: clientTest,
David Benjamin0b7ca7d2016-03-10 15:44:22 -05003342 name: "ClientAuth-NoCertificate-Client",
David Benjaminacb6dcc2016-03-10 09:15:01 -05003343 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003344 MaxVersion: VersionTLS12,
David Benjaminacb6dcc2016-03-10 09:15:01 -05003345 ClientAuth: RequestClientCert,
3346 },
3347 })
3348 tests = append(tests, testCase{
David Benjamin0b7ca7d2016-03-10 15:44:22 -05003349 testType: serverTest,
3350 name: "ClientAuth-NoCertificate-Server",
David Benjamin4c3ddf72016-06-29 18:13:53 -04003351 config: Config{
3352 MaxVersion: VersionTLS12,
3353 },
David Benjamin0b7ca7d2016-03-10 15:44:22 -05003354 // Setting SSL_VERIFY_PEER allows anonymous clients.
3355 flags: []string{"-verify-peer"},
3356 })
David Benjamin582ba042016-07-07 12:33:25 -07003357 if config.protocol == tls {
David Benjamin0b7ca7d2016-03-10 15:44:22 -05003358 tests = append(tests, testCase{
3359 testType: clientTest,
3360 name: "ClientAuth-NoCertificate-Client-SSL3",
3361 config: Config{
3362 MaxVersion: VersionSSL30,
3363 ClientAuth: RequestClientCert,
3364 },
3365 })
3366 tests = append(tests, testCase{
3367 testType: serverTest,
3368 name: "ClientAuth-NoCertificate-Server-SSL3",
3369 config: Config{
3370 MaxVersion: VersionSSL30,
3371 },
3372 // Setting SSL_VERIFY_PEER allows anonymous clients.
3373 flags: []string{"-verify-peer"},
3374 })
Steven Valdez143e8b32016-07-11 13:19:03 -04003375 tests = append(tests, testCase{
3376 testType: clientTest,
3377 name: "ClientAuth-NoCertificate-Client-TLS13",
3378 config: Config{
3379 MaxVersion: VersionTLS13,
3380 ClientAuth: RequestClientCert,
3381 },
3382 })
3383 tests = append(tests, testCase{
3384 testType: serverTest,
3385 name: "ClientAuth-NoCertificate-Server-TLS13",
3386 config: Config{
3387 MaxVersion: VersionTLS13,
3388 },
3389 // Setting SSL_VERIFY_PEER allows anonymous clients.
3390 flags: []string{"-verify-peer"},
3391 })
David Benjamin0b7ca7d2016-03-10 15:44:22 -05003392 }
3393 tests = append(tests, testCase{
David Benjaminacb6dcc2016-03-10 09:15:01 -05003394 testType: clientTest,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003395 name: "ClientAuth-RSA-Client",
David Benjamin760b1dd2015-05-15 23:33:48 -04003396 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003397 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003398 ClientAuth: RequireAnyClientCert,
3399 },
3400 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07003401 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3402 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin760b1dd2015-05-15 23:33:48 -04003403 },
3404 })
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003405 tests = append(tests, testCase{
3406 testType: clientTest,
Steven Valdez143e8b32016-07-11 13:19:03 -04003407 name: "ClientAuth-RSA-Client-TLS13",
3408 config: Config{
3409 MaxVersion: VersionTLS13,
3410 ClientAuth: RequireAnyClientCert,
3411 },
3412 flags: []string{
3413 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3414 "-key-file", path.Join(*resourceDir, rsaKeyFile),
3415 },
3416 })
3417 tests = append(tests, testCase{
3418 testType: clientTest,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003419 name: "ClientAuth-ECDSA-Client",
3420 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003421 MaxVersion: VersionTLS12,
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003422 ClientAuth: RequireAnyClientCert,
3423 },
3424 flags: []string{
David Benjamin33863262016-07-08 17:20:12 -07003425 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
3426 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
nagendra modadugu3398dbf2015-08-07 14:07:52 -07003427 },
3428 })
David Benjaminacb6dcc2016-03-10 09:15:01 -05003429 tests = append(tests, testCase{
3430 testType: clientTest,
Steven Valdez143e8b32016-07-11 13:19:03 -04003431 name: "ClientAuth-ECDSA-Client-TLS13",
3432 config: Config{
3433 MaxVersion: VersionTLS13,
3434 ClientAuth: RequireAnyClientCert,
3435 },
3436 flags: []string{
3437 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
3438 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
3439 },
3440 })
3441 tests = append(tests, testCase{
3442 testType: clientTest,
David Benjamin4c3ddf72016-06-29 18:13:53 -04003443 name: "ClientAuth-NoCertificate-OldCallback",
3444 config: Config{
3445 MaxVersion: VersionTLS12,
3446 ClientAuth: RequestClientCert,
3447 },
3448 flags: []string{"-use-old-client-cert-callback"},
3449 })
3450 tests = append(tests, testCase{
3451 testType: clientTest,
Steven Valdez143e8b32016-07-11 13:19:03 -04003452 name: "ClientAuth-NoCertificate-OldCallback-TLS13",
3453 config: Config{
3454 MaxVersion: VersionTLS13,
3455 ClientAuth: RequestClientCert,
3456 },
3457 flags: []string{"-use-old-client-cert-callback"},
3458 })
3459 tests = append(tests, testCase{
3460 testType: clientTest,
David Benjaminacb6dcc2016-03-10 09:15:01 -05003461 name: "ClientAuth-OldCallback",
3462 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003463 MaxVersion: VersionTLS12,
David Benjaminacb6dcc2016-03-10 09:15:01 -05003464 ClientAuth: RequireAnyClientCert,
3465 },
3466 flags: []string{
3467 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3468 "-key-file", path.Join(*resourceDir, rsaKeyFile),
3469 "-use-old-client-cert-callback",
3470 },
3471 })
David Benjamin760b1dd2015-05-15 23:33:48 -04003472 tests = append(tests, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04003473 testType: clientTest,
3474 name: "ClientAuth-OldCallback-TLS13",
3475 config: Config{
3476 MaxVersion: VersionTLS13,
3477 ClientAuth: RequireAnyClientCert,
3478 },
3479 flags: []string{
3480 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3481 "-key-file", path.Join(*resourceDir, rsaKeyFile),
3482 "-use-old-client-cert-callback",
3483 },
3484 })
3485 tests = append(tests, testCase{
David Benjamin760b1dd2015-05-15 23:33:48 -04003486 testType: serverTest,
3487 name: "ClientAuth-Server",
3488 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003489 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003490 Certificates: []Certificate{rsaCertificate},
3491 },
3492 flags: []string{"-require-any-client-certificate"},
3493 })
Steven Valdez143e8b32016-07-11 13:19:03 -04003494 tests = append(tests, testCase{
3495 testType: serverTest,
3496 name: "ClientAuth-Server-TLS13",
3497 config: Config{
3498 MaxVersion: VersionTLS13,
3499 Certificates: []Certificate{rsaCertificate},
3500 },
3501 flags: []string{"-require-any-client-certificate"},
3502 })
David Benjamin760b1dd2015-05-15 23:33:48 -04003503
David Benjamin4c3ddf72016-06-29 18:13:53 -04003504 // Test each key exchange on the server side for async keys.
David Benjamin4c3ddf72016-06-29 18:13:53 -04003505 tests = append(tests, testCase{
3506 testType: serverTest,
3507 name: "Basic-Server-RSA",
3508 config: Config{
3509 MaxVersion: VersionTLS12,
3510 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
3511 },
3512 flags: []string{
3513 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3514 "-key-file", path.Join(*resourceDir, rsaKeyFile),
3515 },
3516 })
3517 tests = append(tests, testCase{
3518 testType: serverTest,
3519 name: "Basic-Server-ECDHE-RSA",
3520 config: Config{
3521 MaxVersion: VersionTLS12,
3522 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3523 },
3524 flags: []string{
3525 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3526 "-key-file", path.Join(*resourceDir, rsaKeyFile),
3527 },
3528 })
3529 tests = append(tests, testCase{
3530 testType: serverTest,
3531 name: "Basic-Server-ECDHE-ECDSA",
3532 config: Config{
3533 MaxVersion: VersionTLS12,
3534 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
3535 },
3536 flags: []string{
David Benjamin33863262016-07-08 17:20:12 -07003537 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
3538 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
David Benjamin4c3ddf72016-06-29 18:13:53 -04003539 },
3540 })
3541
David Benjamin760b1dd2015-05-15 23:33:48 -04003542 // No session ticket support; server doesn't send NewSessionTicket.
3543 tests = append(tests, testCase{
3544 name: "SessionTicketsDisabled-Client",
3545 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003546 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003547 SessionTicketsDisabled: true,
3548 },
3549 })
3550 tests = append(tests, testCase{
3551 testType: serverTest,
3552 name: "SessionTicketsDisabled-Server",
3553 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003554 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003555 SessionTicketsDisabled: true,
3556 },
3557 })
3558
3559 // Skip ServerKeyExchange in PSK key exchange if there's no
3560 // identity hint.
3561 tests = append(tests, testCase{
3562 name: "EmptyPSKHint-Client",
3563 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003564 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003565 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3566 PreSharedKey: []byte("secret"),
3567 },
3568 flags: []string{"-psk", "secret"},
3569 })
3570 tests = append(tests, testCase{
3571 testType: serverTest,
3572 name: "EmptyPSKHint-Server",
3573 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003574 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003575 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3576 PreSharedKey: []byte("secret"),
3577 },
3578 flags: []string{"-psk", "secret"},
3579 })
3580
David Benjamin4c3ddf72016-06-29 18:13:53 -04003581 // OCSP stapling tests.
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003582 tests = append(tests, testCase{
3583 testType: clientTest,
3584 name: "OCSPStapling-Client",
David Benjamin4c3ddf72016-06-29 18:13:53 -04003585 config: Config{
3586 MaxVersion: VersionTLS12,
3587 },
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003588 flags: []string{
3589 "-enable-ocsp-stapling",
3590 "-expect-ocsp-response",
3591 base64.StdEncoding.EncodeToString(testOCSPResponse),
Paul Lietar8f1c2682015-08-18 12:21:54 +01003592 "-verify-peer",
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003593 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01003594 resumeSession: true,
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003595 })
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003596 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003597 testType: serverTest,
3598 name: "OCSPStapling-Server",
3599 config: Config{
3600 MaxVersion: VersionTLS12,
3601 },
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003602 expectedOCSPResponse: testOCSPResponse,
3603 flags: []string{
3604 "-ocsp-response",
3605 base64.StdEncoding.EncodeToString(testOCSPResponse),
3606 },
Paul Lietar62be8ac2015-09-16 10:03:30 +01003607 resumeSession: true,
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003608 })
David Benjamin942f4ed2016-07-16 19:03:49 +03003609 tests = append(tests, testCase{
3610 testType: clientTest,
3611 name: "OCSPStapling-Client-TLS13",
3612 config: Config{
3613 MaxVersion: VersionTLS13,
3614 },
3615 flags: []string{
3616 "-enable-ocsp-stapling",
3617 "-expect-ocsp-response",
3618 base64.StdEncoding.EncodeToString(testOCSPResponse),
3619 "-verify-peer",
3620 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04003621 resumeSession: true,
David Benjamin942f4ed2016-07-16 19:03:49 +03003622 })
3623 tests = append(tests, testCase{
3624 testType: serverTest,
3625 name: "OCSPStapling-Server-TLS13",
3626 config: Config{
3627 MaxVersion: VersionTLS13,
3628 },
3629 expectedOCSPResponse: testOCSPResponse,
3630 flags: []string{
3631 "-ocsp-response",
3632 base64.StdEncoding.EncodeToString(testOCSPResponse),
3633 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04003634 resumeSession: true,
David Benjamin942f4ed2016-07-16 19:03:49 +03003635 })
Paul Lietaraeeff2c2015-08-12 11:47:11 +01003636
David Benjamin4c3ddf72016-06-29 18:13:53 -04003637 // Certificate verification tests.
Steven Valdez143e8b32016-07-11 13:19:03 -04003638 for _, vers := range tlsVersions {
3639 if config.protocol == dtls && !vers.hasDTLS {
3640 continue
3641 }
David Benjaminbb9e36e2016-08-03 14:14:47 -04003642 for _, testType := range []testType{clientTest, serverTest} {
3643 suffix := "-Client"
3644 if testType == serverTest {
3645 suffix = "-Server"
3646 }
3647 suffix += "-" + vers.name
3648
3649 flag := "-verify-peer"
3650 if testType == serverTest {
3651 flag = "-require-any-client-certificate"
3652 }
3653
3654 tests = append(tests, testCase{
3655 testType: testType,
3656 name: "CertificateVerificationSucceed" + suffix,
3657 config: Config{
3658 MaxVersion: vers.version,
3659 Certificates: []Certificate{rsaCertificate},
3660 },
3661 flags: []string{
3662 flag,
3663 "-expect-verify-result",
3664 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04003665 resumeSession: true,
David Benjaminbb9e36e2016-08-03 14:14:47 -04003666 })
3667 tests = append(tests, testCase{
3668 testType: testType,
3669 name: "CertificateVerificationFail" + suffix,
3670 config: Config{
3671 MaxVersion: vers.version,
3672 Certificates: []Certificate{rsaCertificate},
3673 },
3674 flags: []string{
3675 flag,
3676 "-verify-fail",
3677 },
3678 shouldFail: true,
3679 expectedError: ":CERTIFICATE_VERIFY_FAILED:",
3680 })
3681 }
3682
3683 // By default, the client is in a soft fail mode where the peer
3684 // certificate is verified but failures are non-fatal.
Steven Valdez143e8b32016-07-11 13:19:03 -04003685 tests = append(tests, testCase{
3686 testType: clientTest,
3687 name: "CertificateVerificationSoftFail-" + vers.name,
3688 config: Config{
David Benjaminbb9e36e2016-08-03 14:14:47 -04003689 MaxVersion: vers.version,
3690 Certificates: []Certificate{rsaCertificate},
Steven Valdez143e8b32016-07-11 13:19:03 -04003691 },
3692 flags: []string{
3693 "-verify-fail",
3694 "-expect-verify-result",
3695 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04003696 resumeSession: true,
Steven Valdez143e8b32016-07-11 13:19:03 -04003697 })
3698 }
Paul Lietar8f1c2682015-08-18 12:21:54 +01003699
David Benjamin1d4f4c02016-07-26 18:03:08 -04003700 tests = append(tests, testCase{
3701 name: "ShimSendAlert",
3702 flags: []string{"-send-alert"},
3703 shimWritesFirst: true,
3704 shouldFail: true,
3705 expectedLocalError: "remote error: decompression failure",
3706 })
3707
David Benjamin582ba042016-07-07 12:33:25 -07003708 if config.protocol == tls {
David Benjamin760b1dd2015-05-15 23:33:48 -04003709 tests = append(tests, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003710 name: "Renegotiate-Client",
3711 config: Config{
3712 MaxVersion: VersionTLS12,
3713 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04003714 renegotiate: 1,
3715 flags: []string{
3716 "-renegotiate-freely",
3717 "-expect-total-renegotiations", "1",
3718 },
David Benjamin760b1dd2015-05-15 23:33:48 -04003719 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04003720
David Benjamin47921102016-07-28 11:29:18 -04003721 tests = append(tests, testCase{
3722 name: "SendHalfHelloRequest",
3723 config: Config{
3724 MaxVersion: VersionTLS12,
3725 Bugs: ProtocolBugs{
3726 PackHelloRequestWithFinished: config.packHandshakeFlight,
3727 },
3728 },
3729 sendHalfHelloRequest: true,
3730 flags: []string{"-renegotiate-ignore"},
3731 shouldFail: true,
3732 expectedError: ":UNEXPECTED_RECORD:",
3733 })
3734
David Benjamin760b1dd2015-05-15 23:33:48 -04003735 // NPN on client and server; results in post-handshake message.
3736 tests = append(tests, testCase{
3737 name: "NPN-Client",
3738 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003739 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003740 NextProtos: []string{"foo"},
3741 },
3742 flags: []string{"-select-next-proto", "foo"},
David Benjaminf8fcdf32016-06-08 15:56:13 -04003743 resumeSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003744 expectedNextProto: "foo",
3745 expectedNextProtoType: npn,
3746 })
3747 tests = append(tests, testCase{
3748 testType: serverTest,
3749 name: "NPN-Server",
3750 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003751 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003752 NextProtos: []string{"bar"},
3753 },
3754 flags: []string{
3755 "-advertise-npn", "\x03foo\x03bar\x03baz",
3756 "-expect-next-proto", "bar",
3757 },
David Benjaminf8fcdf32016-06-08 15:56:13 -04003758 resumeSession: true,
David Benjamin760b1dd2015-05-15 23:33:48 -04003759 expectedNextProto: "bar",
3760 expectedNextProtoType: npn,
3761 })
3762
3763 // TODO(davidben): Add tests for when False Start doesn't trigger.
3764
3765 // Client does False Start and negotiates NPN.
3766 tests = append(tests, testCase{
3767 name: "FalseStart",
3768 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003769 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003770 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3771 NextProtos: []string{"foo"},
3772 Bugs: ProtocolBugs{
3773 ExpectFalseStart: true,
3774 },
3775 },
3776 flags: []string{
3777 "-false-start",
3778 "-select-next-proto", "foo",
3779 },
3780 shimWritesFirst: true,
3781 resumeSession: true,
3782 })
3783
3784 // Client does False Start and negotiates ALPN.
3785 tests = append(tests, testCase{
3786 name: "FalseStart-ALPN",
3787 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003788 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003789 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3790 NextProtos: []string{"foo"},
3791 Bugs: ProtocolBugs{
3792 ExpectFalseStart: true,
3793 },
3794 },
3795 flags: []string{
3796 "-false-start",
3797 "-advertise-alpn", "\x03foo",
3798 },
3799 shimWritesFirst: true,
3800 resumeSession: true,
3801 })
3802
3803 // Client does False Start but doesn't explicitly call
3804 // SSL_connect.
3805 tests = append(tests, testCase{
3806 name: "FalseStart-Implicit",
3807 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003808 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003809 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3810 NextProtos: []string{"foo"},
3811 },
3812 flags: []string{
3813 "-implicit-handshake",
3814 "-false-start",
3815 "-advertise-alpn", "\x03foo",
3816 },
3817 })
3818
3819 // False Start without session tickets.
3820 tests = append(tests, testCase{
3821 name: "FalseStart-SessionTicketsDisabled",
3822 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07003823 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003824 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3825 NextProtos: []string{"foo"},
3826 SessionTicketsDisabled: true,
3827 Bugs: ProtocolBugs{
3828 ExpectFalseStart: true,
3829 },
3830 },
3831 flags: []string{
3832 "-false-start",
3833 "-select-next-proto", "foo",
3834 },
3835 shimWritesFirst: true,
3836 })
3837
Adam Langleydf759b52016-07-11 15:24:37 -07003838 tests = append(tests, testCase{
3839 name: "FalseStart-CECPQ1",
3840 config: Config{
3841 MaxVersion: VersionTLS12,
3842 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
3843 NextProtos: []string{"foo"},
3844 Bugs: ProtocolBugs{
3845 ExpectFalseStart: true,
3846 },
3847 },
3848 flags: []string{
3849 "-false-start",
3850 "-cipher", "DEFAULT:kCECPQ1",
3851 "-select-next-proto", "foo",
3852 },
3853 shimWritesFirst: true,
3854 resumeSession: true,
3855 })
3856
David Benjamin760b1dd2015-05-15 23:33:48 -04003857 // Server parses a V2ClientHello.
3858 tests = append(tests, testCase{
3859 testType: serverTest,
3860 name: "SendV2ClientHello",
3861 config: Config{
3862 // Choose a cipher suite that does not involve
3863 // elliptic curves, so no extensions are
3864 // involved.
Nick Harper1fd39d82016-06-14 18:14:35 -07003865 MaxVersion: VersionTLS12,
Matt Braithwaite07e78062016-08-21 14:50:43 -07003866 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjamin760b1dd2015-05-15 23:33:48 -04003867 Bugs: ProtocolBugs{
3868 SendV2ClientHello: true,
3869 },
3870 },
3871 })
3872
3873 // Client sends a Channel ID.
3874 tests = append(tests, testCase{
3875 name: "ChannelID-Client",
3876 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003877 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003878 RequestChannelID: true,
3879 },
Adam Langley7c803a62015-06-15 15:35:05 -07003880 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
David Benjamin760b1dd2015-05-15 23:33:48 -04003881 resumeSession: true,
3882 expectChannelID: true,
3883 })
3884
3885 // Server accepts a Channel ID.
3886 tests = append(tests, testCase{
3887 testType: serverTest,
3888 name: "ChannelID-Server",
3889 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003890 MaxVersion: VersionTLS12,
3891 ChannelID: channelIDKey,
David Benjamin760b1dd2015-05-15 23:33:48 -04003892 },
3893 flags: []string{
3894 "-expect-channel-id",
3895 base64.StdEncoding.EncodeToString(channelIDBytes),
3896 },
3897 resumeSession: true,
3898 expectChannelID: true,
3899 })
David Benjamin30789da2015-08-29 22:56:45 -04003900
David Benjaminf8fcdf32016-06-08 15:56:13 -04003901 // Channel ID and NPN at the same time, to ensure their relative
3902 // ordering is correct.
3903 tests = append(tests, testCase{
3904 name: "ChannelID-NPN-Client",
3905 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003906 MaxVersion: VersionTLS12,
David Benjaminf8fcdf32016-06-08 15:56:13 -04003907 RequestChannelID: true,
3908 NextProtos: []string{"foo"},
3909 },
3910 flags: []string{
3911 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
3912 "-select-next-proto", "foo",
3913 },
3914 resumeSession: true,
3915 expectChannelID: true,
3916 expectedNextProto: "foo",
3917 expectedNextProtoType: npn,
3918 })
3919 tests = append(tests, testCase{
3920 testType: serverTest,
3921 name: "ChannelID-NPN-Server",
3922 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003923 MaxVersion: VersionTLS12,
David Benjaminf8fcdf32016-06-08 15:56:13 -04003924 ChannelID: channelIDKey,
3925 NextProtos: []string{"bar"},
3926 },
3927 flags: []string{
3928 "-expect-channel-id",
3929 base64.StdEncoding.EncodeToString(channelIDBytes),
3930 "-advertise-npn", "\x03foo\x03bar\x03baz",
3931 "-expect-next-proto", "bar",
3932 },
3933 resumeSession: true,
3934 expectChannelID: true,
3935 expectedNextProto: "bar",
3936 expectedNextProtoType: npn,
3937 })
3938
David Benjamin30789da2015-08-29 22:56:45 -04003939 // Bidirectional shutdown with the runner initiating.
3940 tests = append(tests, testCase{
3941 name: "Shutdown-Runner",
3942 config: Config{
3943 Bugs: ProtocolBugs{
3944 ExpectCloseNotify: true,
3945 },
3946 },
3947 flags: []string{"-check-close-notify"},
3948 })
3949
3950 // Bidirectional shutdown with the shim initiating. The runner,
3951 // in the meantime, sends garbage before the close_notify which
3952 // the shim must ignore.
3953 tests = append(tests, testCase{
3954 name: "Shutdown-Shim",
3955 config: Config{
David Benjamine8e84b92016-08-03 15:39:47 -04003956 MaxVersion: VersionTLS12,
David Benjamin30789da2015-08-29 22:56:45 -04003957 Bugs: ProtocolBugs{
3958 ExpectCloseNotify: true,
3959 },
3960 },
3961 shimShutsDown: true,
3962 sendEmptyRecords: 1,
3963 sendWarningAlerts: 1,
3964 flags: []string{"-check-close-notify"},
3965 })
David Benjamin760b1dd2015-05-15 23:33:48 -04003966 } else {
David Benjamin4c3ddf72016-06-29 18:13:53 -04003967 // TODO(davidben): DTLS 1.3 will want a similar thing for
3968 // HelloRetryRequest.
David Benjamin760b1dd2015-05-15 23:33:48 -04003969 tests = append(tests, testCase{
3970 name: "SkipHelloVerifyRequest",
3971 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04003972 MaxVersion: VersionTLS12,
David Benjamin760b1dd2015-05-15 23:33:48 -04003973 Bugs: ProtocolBugs{
3974 SkipHelloVerifyRequest: true,
3975 },
3976 },
3977 })
3978 }
3979
David Benjamin760b1dd2015-05-15 23:33:48 -04003980 for _, test := range tests {
David Benjamin582ba042016-07-07 12:33:25 -07003981 test.protocol = config.protocol
3982 if config.protocol == dtls {
David Benjamin16285ea2015-11-03 15:39:45 -05003983 test.name += "-DTLS"
3984 }
David Benjamin582ba042016-07-07 12:33:25 -07003985 if config.async {
David Benjamin16285ea2015-11-03 15:39:45 -05003986 test.name += "-Async"
3987 test.flags = append(test.flags, "-async")
3988 } else {
3989 test.name += "-Sync"
3990 }
David Benjamin582ba042016-07-07 12:33:25 -07003991 if config.splitHandshake {
David Benjamin16285ea2015-11-03 15:39:45 -05003992 test.name += "-SplitHandshakeRecords"
3993 test.config.Bugs.MaxHandshakeRecordLength = 1
David Benjamin582ba042016-07-07 12:33:25 -07003994 if config.protocol == dtls {
David Benjamin16285ea2015-11-03 15:39:45 -05003995 test.config.Bugs.MaxPacketLength = 256
3996 test.flags = append(test.flags, "-mtu", "256")
3997 }
3998 }
David Benjamin582ba042016-07-07 12:33:25 -07003999 if config.packHandshakeFlight {
4000 test.name += "-PackHandshakeFlight"
4001 test.config.Bugs.PackHandshakeFlight = true
4002 }
David Benjamin760b1dd2015-05-15 23:33:48 -04004003 testCases = append(testCases, test)
David Benjamin6fd297b2014-08-11 18:43:38 -04004004 }
David Benjamin43ec06f2014-08-05 02:28:57 -04004005}
4006
Adam Langley524e7172015-02-20 16:04:00 -08004007func addDDoSCallbackTests() {
4008 // DDoS callback.
Adam Langley524e7172015-02-20 16:04:00 -08004009 for _, resume := range []bool{false, true} {
4010 suffix := "Resume"
4011 if resume {
4012 suffix = "No" + suffix
4013 }
4014
4015 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004016 testType: serverTest,
4017 name: "Server-DDoS-OK-" + suffix,
4018 config: Config{
4019 MaxVersion: VersionTLS12,
4020 },
Adam Langley524e7172015-02-20 16:04:00 -08004021 flags: []string{"-install-ddos-callback"},
4022 resumeSession: resume,
4023 })
Steven Valdez4aa154e2016-07-29 14:32:55 -04004024 testCases = append(testCases, testCase{
4025 testType: serverTest,
4026 name: "Server-DDoS-OK-" + suffix + "-TLS13",
4027 config: Config{
4028 MaxVersion: VersionTLS13,
4029 },
4030 flags: []string{"-install-ddos-callback"},
4031 resumeSession: resume,
4032 })
Adam Langley524e7172015-02-20 16:04:00 -08004033
4034 failFlag := "-fail-ddos-callback"
4035 if resume {
4036 failFlag = "-fail-second-ddos-callback"
4037 }
4038 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04004039 testType: serverTest,
4040 name: "Server-DDoS-Reject-" + suffix,
4041 config: Config{
4042 MaxVersion: VersionTLS12,
4043 },
David Benjamin2c66e072016-09-16 15:58:00 -04004044 flags: []string{"-install-ddos-callback", failFlag},
4045 resumeSession: resume,
4046 shouldFail: true,
4047 expectedError: ":CONNECTION_REJECTED:",
4048 expectedLocalError: "remote error: internal error",
Adam Langley524e7172015-02-20 16:04:00 -08004049 })
Steven Valdez4aa154e2016-07-29 14:32:55 -04004050 testCases = append(testCases, testCase{
4051 testType: serverTest,
4052 name: "Server-DDoS-Reject-" + suffix + "-TLS13",
4053 config: Config{
4054 MaxVersion: VersionTLS13,
4055 },
David Benjamin2c66e072016-09-16 15:58:00 -04004056 flags: []string{"-install-ddos-callback", failFlag},
4057 resumeSession: resume,
4058 shouldFail: true,
4059 expectedError: ":CONNECTION_REJECTED:",
4060 expectedLocalError: "remote error: internal error",
Steven Valdez4aa154e2016-07-29 14:32:55 -04004061 })
Adam Langley524e7172015-02-20 16:04:00 -08004062 }
4063}
4064
David Benjamin7e2e6cf2014-08-07 17:44:24 -04004065func addVersionNegotiationTests() {
4066 for i, shimVers := range tlsVersions {
4067 // Assemble flags to disable all newer versions on the shim.
4068 var flags []string
4069 for _, vers := range tlsVersions[i+1:] {
4070 flags = append(flags, vers.flag)
4071 }
4072
4073 for _, runnerVers := range tlsVersions {
David Benjamin8b8c0062014-11-23 02:47:52 -05004074 protocols := []protocol{tls}
4075 if runnerVers.hasDTLS && shimVers.hasDTLS {
4076 protocols = append(protocols, dtls)
David Benjamin7e2e6cf2014-08-07 17:44:24 -04004077 }
David Benjamin8b8c0062014-11-23 02:47:52 -05004078 for _, protocol := range protocols {
4079 expectedVersion := shimVers.version
4080 if runnerVers.version < shimVers.version {
4081 expectedVersion = runnerVers.version
4082 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04004083
David Benjamin8b8c0062014-11-23 02:47:52 -05004084 suffix := shimVers.name + "-" + runnerVers.name
4085 if protocol == dtls {
4086 suffix += "-DTLS"
4087 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04004088
David Benjamin1eb367c2014-12-12 18:17:51 -05004089 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
4090
David Benjamin1e29a6b2014-12-10 02:27:24 -05004091 clientVers := shimVers.version
4092 if clientVers > VersionTLS10 {
4093 clientVers = VersionTLS10
4094 }
Nick Harper1fd39d82016-06-14 18:14:35 -07004095 serverVers := expectedVersion
4096 if expectedVersion >= VersionTLS13 {
4097 serverVers = VersionTLS10
4098 }
David Benjamin8b8c0062014-11-23 02:47:52 -05004099 testCases = append(testCases, testCase{
4100 protocol: protocol,
4101 testType: clientTest,
4102 name: "VersionNegotiation-Client-" + suffix,
4103 config: Config{
4104 MaxVersion: runnerVers.version,
David Benjamin1e29a6b2014-12-10 02:27:24 -05004105 Bugs: ProtocolBugs{
4106 ExpectInitialRecordVersion: clientVers,
4107 },
David Benjamin8b8c0062014-11-23 02:47:52 -05004108 },
4109 flags: flags,
4110 expectedVersion: expectedVersion,
4111 })
David Benjamin1eb367c2014-12-12 18:17:51 -05004112 testCases = append(testCases, testCase{
4113 protocol: protocol,
4114 testType: clientTest,
4115 name: "VersionNegotiation-Client2-" + suffix,
4116 config: Config{
4117 MaxVersion: runnerVers.version,
4118 Bugs: ProtocolBugs{
4119 ExpectInitialRecordVersion: clientVers,
4120 },
4121 },
4122 flags: []string{"-max-version", shimVersFlag},
4123 expectedVersion: expectedVersion,
4124 })
David Benjamin8b8c0062014-11-23 02:47:52 -05004125
4126 testCases = append(testCases, testCase{
4127 protocol: protocol,
4128 testType: serverTest,
4129 name: "VersionNegotiation-Server-" + suffix,
4130 config: Config{
4131 MaxVersion: runnerVers.version,
David Benjamin1e29a6b2014-12-10 02:27:24 -05004132 Bugs: ProtocolBugs{
Nick Harper1fd39d82016-06-14 18:14:35 -07004133 ExpectInitialRecordVersion: serverVers,
David Benjamin1e29a6b2014-12-10 02:27:24 -05004134 },
David Benjamin8b8c0062014-11-23 02:47:52 -05004135 },
4136 flags: flags,
4137 expectedVersion: expectedVersion,
4138 })
David Benjamin1eb367c2014-12-12 18:17:51 -05004139 testCases = append(testCases, testCase{
4140 protocol: protocol,
4141 testType: serverTest,
4142 name: "VersionNegotiation-Server2-" + suffix,
4143 config: Config{
4144 MaxVersion: runnerVers.version,
4145 Bugs: ProtocolBugs{
Nick Harper1fd39d82016-06-14 18:14:35 -07004146 ExpectInitialRecordVersion: serverVers,
David Benjamin1eb367c2014-12-12 18:17:51 -05004147 },
4148 },
4149 flags: []string{"-max-version", shimVersFlag},
4150 expectedVersion: expectedVersion,
4151 })
David Benjamin8b8c0062014-11-23 02:47:52 -05004152 }
David Benjamin7e2e6cf2014-08-07 17:44:24 -04004153 }
4154 }
David Benjamin95c69562016-06-29 18:15:03 -04004155
4156 // Test for version tolerance.
4157 testCases = append(testCases, testCase{
4158 testType: serverTest,
4159 name: "MinorVersionTolerance",
4160 config: Config{
4161 Bugs: ProtocolBugs{
4162 SendClientVersion: 0x03ff,
4163 },
4164 },
4165 expectedVersion: VersionTLS13,
4166 })
4167 testCases = append(testCases, testCase{
4168 testType: serverTest,
4169 name: "MajorVersionTolerance",
4170 config: Config{
4171 Bugs: ProtocolBugs{
4172 SendClientVersion: 0x0400,
4173 },
4174 },
4175 expectedVersion: VersionTLS13,
4176 })
4177 testCases = append(testCases, testCase{
4178 protocol: dtls,
4179 testType: serverTest,
4180 name: "MinorVersionTolerance-DTLS",
4181 config: Config{
4182 Bugs: ProtocolBugs{
4183 SendClientVersion: 0x03ff,
4184 },
4185 },
4186 expectedVersion: VersionTLS12,
4187 })
4188 testCases = append(testCases, testCase{
4189 protocol: dtls,
4190 testType: serverTest,
4191 name: "MajorVersionTolerance-DTLS",
4192 config: Config{
4193 Bugs: ProtocolBugs{
4194 SendClientVersion: 0x0400,
4195 },
4196 },
4197 expectedVersion: VersionTLS12,
4198 })
4199
4200 // Test that versions below 3.0 are rejected.
4201 testCases = append(testCases, testCase{
4202 testType: serverTest,
4203 name: "VersionTooLow",
4204 config: Config{
4205 Bugs: ProtocolBugs{
4206 SendClientVersion: 0x0200,
4207 },
4208 },
4209 shouldFail: true,
4210 expectedError: ":UNSUPPORTED_PROTOCOL:",
4211 })
4212 testCases = append(testCases, testCase{
4213 protocol: dtls,
4214 testType: serverTest,
4215 name: "VersionTooLow-DTLS",
4216 config: Config{
4217 Bugs: ProtocolBugs{
4218 // 0x0201 is the lowest version expressable in
4219 // DTLS.
4220 SendClientVersion: 0x0201,
4221 },
4222 },
4223 shouldFail: true,
4224 expectedError: ":UNSUPPORTED_PROTOCOL:",
4225 })
David Benjamin1f61f0d2016-07-10 12:20:35 -04004226
David Benjamin2dc02042016-09-19 19:57:37 -04004227 testCases = append(testCases, testCase{
4228 name: "ServerBogusVersion",
4229 config: Config{
4230 Bugs: ProtocolBugs{
4231 SendServerHelloVersion: 0x1234,
4232 },
4233 },
4234 shouldFail: true,
4235 expectedError: ":UNSUPPORTED_PROTOCOL:",
4236 })
4237
David Benjamin1f61f0d2016-07-10 12:20:35 -04004238 // Test TLS 1.3's downgrade signal.
4239 testCases = append(testCases, testCase{
4240 name: "Downgrade-TLS12-Client",
4241 config: Config{
4242 Bugs: ProtocolBugs{
4243 NegotiateVersion: VersionTLS12,
4244 },
4245 },
David Benjamin55108632016-08-11 22:01:18 -04004246 // TODO(davidben): This test should fail once TLS 1.3 is final
4247 // and the fallback signal restored.
David Benjamin1f61f0d2016-07-10 12:20:35 -04004248 })
4249 testCases = append(testCases, testCase{
4250 testType: serverTest,
4251 name: "Downgrade-TLS12-Server",
4252 config: Config{
4253 Bugs: ProtocolBugs{
4254 SendClientVersion: VersionTLS12,
4255 },
4256 },
David Benjamin55108632016-08-11 22:01:18 -04004257 // TODO(davidben): This test should fail once TLS 1.3 is final
4258 // and the fallback signal restored.
David Benjamin1f61f0d2016-07-10 12:20:35 -04004259 })
David Benjamin7e2e6cf2014-08-07 17:44:24 -04004260}
4261
David Benjaminaccb4542014-12-12 23:44:33 -05004262func addMinimumVersionTests() {
4263 for i, shimVers := range tlsVersions {
4264 // Assemble flags to disable all older versions on the shim.
4265 var flags []string
4266 for _, vers := range tlsVersions[:i] {
4267 flags = append(flags, vers.flag)
4268 }
4269
4270 for _, runnerVers := range tlsVersions {
4271 protocols := []protocol{tls}
4272 if runnerVers.hasDTLS && shimVers.hasDTLS {
4273 protocols = append(protocols, dtls)
4274 }
4275 for _, protocol := range protocols {
4276 suffix := shimVers.name + "-" + runnerVers.name
4277 if protocol == dtls {
4278 suffix += "-DTLS"
4279 }
4280 shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
4281
David Benjaminaccb4542014-12-12 23:44:33 -05004282 var expectedVersion uint16
4283 var shouldFail bool
David Benjamin929d4ee2016-06-24 23:55:58 -04004284 var expectedClientError, expectedServerError string
4285 var expectedClientLocalError, expectedServerLocalError string
David Benjaminaccb4542014-12-12 23:44:33 -05004286 if runnerVers.version >= shimVers.version {
4287 expectedVersion = runnerVers.version
4288 } else {
4289 shouldFail = true
David Benjamin929d4ee2016-06-24 23:55:58 -04004290 expectedServerError = ":UNSUPPORTED_PROTOCOL:"
4291 expectedServerLocalError = "remote error: protocol version not supported"
4292 if shimVers.version >= VersionTLS13 && runnerVers.version <= VersionTLS11 {
4293 // If the client's minimum version is TLS 1.3 and the runner's
4294 // maximum is below TLS 1.2, the runner will fail to select a
4295 // cipher before the shim rejects the selected version.
4296 expectedClientError = ":SSLV3_ALERT_HANDSHAKE_FAILURE:"
4297 expectedClientLocalError = "tls: no cipher suite supported by both client and server"
4298 } else {
4299 expectedClientError = expectedServerError
4300 expectedClientLocalError = expectedServerLocalError
4301 }
David Benjaminaccb4542014-12-12 23:44:33 -05004302 }
4303
4304 testCases = append(testCases, testCase{
4305 protocol: protocol,
4306 testType: clientTest,
4307 name: "MinimumVersion-Client-" + suffix,
4308 config: Config{
4309 MaxVersion: runnerVers.version,
4310 },
David Benjamin87909c02014-12-13 01:55:01 -05004311 flags: flags,
4312 expectedVersion: expectedVersion,
4313 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04004314 expectedError: expectedClientError,
4315 expectedLocalError: expectedClientLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05004316 })
4317 testCases = append(testCases, testCase{
4318 protocol: protocol,
4319 testType: clientTest,
4320 name: "MinimumVersion-Client2-" + suffix,
4321 config: Config{
4322 MaxVersion: runnerVers.version,
4323 },
David Benjamin87909c02014-12-13 01:55:01 -05004324 flags: []string{"-min-version", shimVersFlag},
4325 expectedVersion: expectedVersion,
4326 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04004327 expectedError: expectedClientError,
4328 expectedLocalError: expectedClientLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05004329 })
4330
4331 testCases = append(testCases, testCase{
4332 protocol: protocol,
4333 testType: serverTest,
4334 name: "MinimumVersion-Server-" + suffix,
4335 config: Config{
4336 MaxVersion: runnerVers.version,
4337 },
David Benjamin87909c02014-12-13 01:55:01 -05004338 flags: flags,
4339 expectedVersion: expectedVersion,
4340 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04004341 expectedError: expectedServerError,
4342 expectedLocalError: expectedServerLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05004343 })
4344 testCases = append(testCases, testCase{
4345 protocol: protocol,
4346 testType: serverTest,
4347 name: "MinimumVersion-Server2-" + suffix,
4348 config: Config{
4349 MaxVersion: runnerVers.version,
4350 },
David Benjamin87909c02014-12-13 01:55:01 -05004351 flags: []string{"-min-version", shimVersFlag},
4352 expectedVersion: expectedVersion,
4353 shouldFail: shouldFail,
David Benjamin929d4ee2016-06-24 23:55:58 -04004354 expectedError: expectedServerError,
4355 expectedLocalError: expectedServerLocalError,
David Benjaminaccb4542014-12-12 23:44:33 -05004356 })
4357 }
4358 }
4359 }
4360}
4361
David Benjamine78bfde2014-09-06 12:45:15 -04004362func addExtensionTests() {
David Benjamin4c3ddf72016-06-29 18:13:53 -04004363 // TODO(davidben): Extensions, where applicable, all move their server
4364 // halves to EncryptedExtensions in TLS 1.3. Duplicate each of these
4365 // tests for both. Also test interaction with 0-RTT when implemented.
4366
David Benjamin97d17d92016-07-14 16:12:00 -04004367 // Repeat extensions tests all versions except SSL 3.0.
4368 for _, ver := range tlsVersions {
4369 if ver.version == VersionSSL30 {
4370 continue
4371 }
4372
David Benjamin97d17d92016-07-14 16:12:00 -04004373 // Test that duplicate extensions are rejected.
4374 testCases = append(testCases, testCase{
4375 testType: clientTest,
4376 name: "DuplicateExtensionClient-" + ver.name,
4377 config: Config{
4378 MaxVersion: ver.version,
4379 Bugs: ProtocolBugs{
4380 DuplicateExtension: true,
4381 },
David Benjamine78bfde2014-09-06 12:45:15 -04004382 },
David Benjamin97d17d92016-07-14 16:12:00 -04004383 shouldFail: true,
4384 expectedLocalError: "remote error: error decoding message",
4385 })
4386 testCases = append(testCases, testCase{
4387 testType: serverTest,
4388 name: "DuplicateExtensionServer-" + ver.name,
4389 config: Config{
4390 MaxVersion: ver.version,
4391 Bugs: ProtocolBugs{
4392 DuplicateExtension: true,
4393 },
David Benjamine78bfde2014-09-06 12:45:15 -04004394 },
David Benjamin97d17d92016-07-14 16:12:00 -04004395 shouldFail: true,
4396 expectedLocalError: "remote error: error decoding message",
4397 })
4398
4399 // Test SNI.
4400 testCases = append(testCases, testCase{
4401 testType: clientTest,
4402 name: "ServerNameExtensionClient-" + ver.name,
4403 config: Config{
4404 MaxVersion: ver.version,
4405 Bugs: ProtocolBugs{
4406 ExpectServerName: "example.com",
4407 },
David Benjamine78bfde2014-09-06 12:45:15 -04004408 },
David Benjamin97d17d92016-07-14 16:12:00 -04004409 flags: []string{"-host-name", "example.com"},
4410 })
4411 testCases = append(testCases, testCase{
4412 testType: clientTest,
4413 name: "ServerNameExtensionClientMismatch-" + ver.name,
4414 config: Config{
4415 MaxVersion: ver.version,
4416 Bugs: ProtocolBugs{
4417 ExpectServerName: "mismatch.com",
4418 },
David Benjamine78bfde2014-09-06 12:45:15 -04004419 },
David Benjamin97d17d92016-07-14 16:12:00 -04004420 flags: []string{"-host-name", "example.com"},
4421 shouldFail: true,
4422 expectedLocalError: "tls: unexpected server name",
4423 })
4424 testCases = append(testCases, testCase{
4425 testType: clientTest,
4426 name: "ServerNameExtensionClientMissing-" + ver.name,
4427 config: Config{
4428 MaxVersion: ver.version,
4429 Bugs: ProtocolBugs{
4430 ExpectServerName: "missing.com",
4431 },
David Benjamine78bfde2014-09-06 12:45:15 -04004432 },
David Benjamin97d17d92016-07-14 16:12:00 -04004433 shouldFail: true,
4434 expectedLocalError: "tls: unexpected server name",
4435 })
4436 testCases = append(testCases, testCase{
4437 testType: serverTest,
4438 name: "ServerNameExtensionServer-" + ver.name,
4439 config: Config{
4440 MaxVersion: ver.version,
4441 ServerName: "example.com",
David Benjaminfc7b0862014-09-06 13:21:53 -04004442 },
David Benjamin97d17d92016-07-14 16:12:00 -04004443 flags: []string{"-expect-server-name", "example.com"},
Steven Valdez4aa154e2016-07-29 14:32:55 -04004444 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004445 })
4446
4447 // Test ALPN.
4448 testCases = append(testCases, testCase{
4449 testType: clientTest,
4450 name: "ALPNClient-" + ver.name,
4451 config: Config{
4452 MaxVersion: ver.version,
4453 NextProtos: []string{"foo"},
4454 },
4455 flags: []string{
4456 "-advertise-alpn", "\x03foo\x03bar\x03baz",
4457 "-expect-alpn", "foo",
4458 },
4459 expectedNextProto: "foo",
4460 expectedNextProtoType: alpn,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004461 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004462 })
4463 testCases = append(testCases, testCase{
David Benjamin3e517572016-08-11 11:52:23 -04004464 testType: clientTest,
4465 name: "ALPNClient-Mismatch-" + ver.name,
4466 config: Config{
4467 MaxVersion: ver.version,
4468 Bugs: ProtocolBugs{
4469 SendALPN: "baz",
4470 },
4471 },
4472 flags: []string{
4473 "-advertise-alpn", "\x03foo\x03bar",
4474 },
4475 shouldFail: true,
4476 expectedError: ":INVALID_ALPN_PROTOCOL:",
4477 expectedLocalError: "remote error: illegal parameter",
4478 })
4479 testCases = append(testCases, testCase{
David Benjamin97d17d92016-07-14 16:12:00 -04004480 testType: serverTest,
4481 name: "ALPNServer-" + ver.name,
4482 config: Config{
4483 MaxVersion: ver.version,
4484 NextProtos: []string{"foo", "bar", "baz"},
4485 },
4486 flags: []string{
4487 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
4488 "-select-alpn", "foo",
4489 },
4490 expectedNextProto: "foo",
4491 expectedNextProtoType: alpn,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004492 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004493 })
4494 testCases = append(testCases, testCase{
4495 testType: serverTest,
4496 name: "ALPNServer-Decline-" + ver.name,
4497 config: Config{
4498 MaxVersion: ver.version,
4499 NextProtos: []string{"foo", "bar", "baz"},
4500 },
4501 flags: []string{"-decline-alpn"},
4502 expectNoNextProto: true,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004503 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004504 })
4505
David Benjamin25fe85b2016-08-09 20:00:32 -04004506 // Test ALPN in async mode as well to ensure that extensions callbacks are only
4507 // called once.
4508 testCases = append(testCases, testCase{
4509 testType: serverTest,
4510 name: "ALPNServer-Async-" + ver.name,
4511 config: Config{
4512 MaxVersion: ver.version,
4513 NextProtos: []string{"foo", "bar", "baz"},
4514 },
4515 flags: []string{
4516 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
4517 "-select-alpn", "foo",
4518 "-async",
4519 },
4520 expectedNextProto: "foo",
4521 expectedNextProtoType: alpn,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004522 resumeSession: true,
David Benjamin25fe85b2016-08-09 20:00:32 -04004523 })
4524
David Benjamin97d17d92016-07-14 16:12:00 -04004525 var emptyString string
4526 testCases = append(testCases, testCase{
4527 testType: clientTest,
4528 name: "ALPNClient-EmptyProtocolName-" + ver.name,
4529 config: Config{
4530 MaxVersion: ver.version,
4531 NextProtos: []string{""},
4532 Bugs: ProtocolBugs{
4533 // A server returning an empty ALPN protocol
4534 // should be rejected.
4535 ALPNProtocol: &emptyString,
4536 },
4537 },
4538 flags: []string{
4539 "-advertise-alpn", "\x03foo",
4540 },
4541 shouldFail: true,
4542 expectedError: ":PARSE_TLSEXT:",
4543 })
4544 testCases = append(testCases, testCase{
4545 testType: serverTest,
4546 name: "ALPNServer-EmptyProtocolName-" + ver.name,
4547 config: Config{
4548 MaxVersion: ver.version,
4549 // A ClientHello containing an empty ALPN protocol
Adam Langleyefb0e162015-07-09 11:35:04 -07004550 // should be rejected.
David Benjamin97d17d92016-07-14 16:12:00 -04004551 NextProtos: []string{"foo", "", "baz"},
Adam Langleyefb0e162015-07-09 11:35:04 -07004552 },
David Benjamin97d17d92016-07-14 16:12:00 -04004553 flags: []string{
4554 "-select-alpn", "foo",
David Benjamin76c2efc2015-08-31 14:24:29 -04004555 },
David Benjamin97d17d92016-07-14 16:12:00 -04004556 shouldFail: true,
4557 expectedError: ":PARSE_TLSEXT:",
4558 })
4559
4560 // Test NPN and the interaction with ALPN.
4561 if ver.version < VersionTLS13 {
4562 // Test that the server prefers ALPN over NPN.
4563 testCases = append(testCases, testCase{
4564 testType: serverTest,
4565 name: "ALPNServer-Preferred-" + ver.name,
4566 config: Config{
4567 MaxVersion: ver.version,
4568 NextProtos: []string{"foo", "bar", "baz"},
4569 },
4570 flags: []string{
4571 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
4572 "-select-alpn", "foo",
4573 "-advertise-npn", "\x03foo\x03bar\x03baz",
4574 },
4575 expectedNextProto: "foo",
4576 expectedNextProtoType: alpn,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004577 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004578 })
4579 testCases = append(testCases, testCase{
4580 testType: serverTest,
4581 name: "ALPNServer-Preferred-Swapped-" + ver.name,
4582 config: Config{
4583 MaxVersion: ver.version,
4584 NextProtos: []string{"foo", "bar", "baz"},
4585 Bugs: ProtocolBugs{
4586 SwapNPNAndALPN: true,
4587 },
4588 },
4589 flags: []string{
4590 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
4591 "-select-alpn", "foo",
4592 "-advertise-npn", "\x03foo\x03bar\x03baz",
4593 },
4594 expectedNextProto: "foo",
4595 expectedNextProtoType: alpn,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004596 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004597 })
4598
4599 // Test that negotiating both NPN and ALPN is forbidden.
4600 testCases = append(testCases, testCase{
4601 name: "NegotiateALPNAndNPN-" + ver.name,
4602 config: Config{
4603 MaxVersion: ver.version,
4604 NextProtos: []string{"foo", "bar", "baz"},
4605 Bugs: ProtocolBugs{
4606 NegotiateALPNAndNPN: true,
4607 },
4608 },
4609 flags: []string{
4610 "-advertise-alpn", "\x03foo",
4611 "-select-next-proto", "foo",
4612 },
4613 shouldFail: true,
4614 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
4615 })
4616 testCases = append(testCases, testCase{
4617 name: "NegotiateALPNAndNPN-Swapped-" + ver.name,
4618 config: Config{
4619 MaxVersion: ver.version,
4620 NextProtos: []string{"foo", "bar", "baz"},
4621 Bugs: ProtocolBugs{
4622 NegotiateALPNAndNPN: true,
4623 SwapNPNAndALPN: true,
4624 },
4625 },
4626 flags: []string{
4627 "-advertise-alpn", "\x03foo",
4628 "-select-next-proto", "foo",
4629 },
4630 shouldFail: true,
4631 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
4632 })
4633
4634 // Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
4635 testCases = append(testCases, testCase{
4636 name: "DisableNPN-" + ver.name,
4637 config: Config{
4638 MaxVersion: ver.version,
4639 NextProtos: []string{"foo"},
4640 },
4641 flags: []string{
4642 "-select-next-proto", "foo",
4643 "-disable-npn",
4644 },
4645 expectNoNextProto: true,
4646 })
4647 }
4648
4649 // Test ticket behavior.
Steven Valdez4aa154e2016-07-29 14:32:55 -04004650
4651 // Resume with a corrupt ticket.
4652 testCases = append(testCases, testCase{
4653 testType: serverTest,
4654 name: "CorruptTicket-" + ver.name,
4655 config: Config{
4656 MaxVersion: ver.version,
4657 Bugs: ProtocolBugs{
4658 CorruptTicket: true,
4659 },
4660 },
4661 resumeSession: true,
4662 expectResumeRejected: true,
4663 })
4664 // Test the ticket callback, with and without renewal.
4665 testCases = append(testCases, testCase{
4666 testType: serverTest,
4667 name: "TicketCallback-" + ver.name,
4668 config: Config{
4669 MaxVersion: ver.version,
4670 },
4671 resumeSession: true,
4672 flags: []string{"-use-ticket-callback"},
4673 })
4674 testCases = append(testCases, testCase{
4675 testType: serverTest,
4676 name: "TicketCallback-Renew-" + ver.name,
4677 config: Config{
4678 MaxVersion: ver.version,
4679 Bugs: ProtocolBugs{
4680 ExpectNewTicket: true,
4681 },
4682 },
4683 flags: []string{"-use-ticket-callback", "-renew-ticket"},
4684 resumeSession: true,
4685 })
4686
4687 // Test that the ticket callback is only called once when everything before
4688 // it in the ClientHello is asynchronous. This corrupts the ticket so
4689 // certificate selection callbacks run.
4690 testCases = append(testCases, testCase{
4691 testType: serverTest,
4692 name: "TicketCallback-SingleCall-" + ver.name,
4693 config: Config{
4694 MaxVersion: ver.version,
4695 Bugs: ProtocolBugs{
4696 CorruptTicket: true,
4697 },
4698 },
4699 resumeSession: true,
4700 expectResumeRejected: true,
4701 flags: []string{
4702 "-use-ticket-callback",
4703 "-async",
4704 },
4705 })
4706
4707 // Resume with an oversized session id.
David Benjamin97d17d92016-07-14 16:12:00 -04004708 if ver.version < VersionTLS13 {
David Benjamin97d17d92016-07-14 16:12:00 -04004709 testCases = append(testCases, testCase{
4710 testType: serverTest,
4711 name: "OversizedSessionId-" + ver.name,
4712 config: Config{
4713 MaxVersion: ver.version,
4714 Bugs: ProtocolBugs{
4715 OversizedSessionId: true,
4716 },
4717 },
4718 resumeSession: true,
4719 shouldFail: true,
4720 expectedError: ":DECODE_ERROR:",
4721 })
4722 }
4723
4724 // Basic DTLS-SRTP tests. Include fake profiles to ensure they
4725 // are ignored.
4726 if ver.hasDTLS {
4727 testCases = append(testCases, testCase{
4728 protocol: dtls,
4729 name: "SRTP-Client-" + ver.name,
4730 config: Config{
4731 MaxVersion: ver.version,
4732 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
4733 },
4734 flags: []string{
4735 "-srtp-profiles",
4736 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4737 },
4738 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
4739 })
4740 testCases = append(testCases, testCase{
4741 protocol: dtls,
4742 testType: serverTest,
4743 name: "SRTP-Server-" + ver.name,
4744 config: Config{
4745 MaxVersion: ver.version,
4746 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
4747 },
4748 flags: []string{
4749 "-srtp-profiles",
4750 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4751 },
4752 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
4753 })
4754 // Test that the MKI is ignored.
4755 testCases = append(testCases, testCase{
4756 protocol: dtls,
4757 testType: serverTest,
4758 name: "SRTP-Server-IgnoreMKI-" + ver.name,
4759 config: Config{
4760 MaxVersion: ver.version,
4761 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80},
4762 Bugs: ProtocolBugs{
4763 SRTPMasterKeyIdentifer: "bogus",
4764 },
4765 },
4766 flags: []string{
4767 "-srtp-profiles",
4768 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4769 },
4770 expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
4771 })
4772 // Test that SRTP isn't negotiated on the server if there were
4773 // no matching profiles.
4774 testCases = append(testCases, testCase{
4775 protocol: dtls,
4776 testType: serverTest,
4777 name: "SRTP-Server-NoMatch-" + ver.name,
4778 config: Config{
4779 MaxVersion: ver.version,
4780 SRTPProtectionProfiles: []uint16{100, 101, 102},
4781 },
4782 flags: []string{
4783 "-srtp-profiles",
4784 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
4785 },
4786 expectedSRTPProtectionProfile: 0,
4787 })
4788 // Test that the server returning an invalid SRTP profile is
4789 // flagged as an error by the client.
4790 testCases = append(testCases, testCase{
4791 protocol: dtls,
4792 name: "SRTP-Client-NoMatch-" + ver.name,
4793 config: Config{
4794 MaxVersion: ver.version,
4795 Bugs: ProtocolBugs{
4796 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32,
4797 },
4798 },
4799 flags: []string{
4800 "-srtp-profiles",
4801 "SRTP_AES128_CM_SHA1_80",
4802 },
4803 shouldFail: true,
4804 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
4805 })
4806 }
4807
4808 // Test SCT list.
4809 testCases = append(testCases, testCase{
4810 name: "SignedCertificateTimestampList-Client-" + ver.name,
4811 testType: clientTest,
4812 config: Config{
4813 MaxVersion: ver.version,
David Benjamin76c2efc2015-08-31 14:24:29 -04004814 },
David Benjamin97d17d92016-07-14 16:12:00 -04004815 flags: []string{
4816 "-enable-signed-cert-timestamps",
4817 "-expect-signed-cert-timestamps",
4818 base64.StdEncoding.EncodeToString(testSCTList),
Adam Langley38311732014-10-16 19:04:35 -07004819 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04004820 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004821 })
4822 testCases = append(testCases, testCase{
4823 name: "SendSCTListOnResume-" + ver.name,
4824 config: Config{
4825 MaxVersion: ver.version,
4826 Bugs: ProtocolBugs{
4827 SendSCTListOnResume: []byte("bogus"),
4828 },
David Benjamind98452d2015-06-16 14:16:23 -04004829 },
David Benjamin97d17d92016-07-14 16:12:00 -04004830 flags: []string{
4831 "-enable-signed-cert-timestamps",
4832 "-expect-signed-cert-timestamps",
4833 base64.StdEncoding.EncodeToString(testSCTList),
Adam Langley38311732014-10-16 19:04:35 -07004834 },
Steven Valdez4aa154e2016-07-29 14:32:55 -04004835 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004836 })
4837 testCases = append(testCases, testCase{
4838 name: "SignedCertificateTimestampList-Server-" + ver.name,
4839 testType: serverTest,
4840 config: Config{
4841 MaxVersion: ver.version,
David Benjaminca6c8262014-11-15 19:06:08 -05004842 },
David Benjamin97d17d92016-07-14 16:12:00 -04004843 flags: []string{
4844 "-signed-cert-timestamps",
4845 base64.StdEncoding.EncodeToString(testSCTList),
David Benjaminca6c8262014-11-15 19:06:08 -05004846 },
David Benjamin97d17d92016-07-14 16:12:00 -04004847 expectedSCTList: testSCTList,
Steven Valdez4aa154e2016-07-29 14:32:55 -04004848 resumeSession: true,
David Benjamin97d17d92016-07-14 16:12:00 -04004849 })
4850 }
David Benjamin4c3ddf72016-06-29 18:13:53 -04004851
Paul Lietar4fac72e2015-09-09 13:44:55 +01004852 testCases = append(testCases, testCase{
Adam Langley33ad2b52015-07-20 17:43:53 -07004853 testType: clientTest,
4854 name: "ClientHelloPadding",
4855 config: Config{
4856 Bugs: ProtocolBugs{
4857 RequireClientHelloSize: 512,
4858 },
4859 },
4860 // This hostname just needs to be long enough to push the
4861 // ClientHello into F5's danger zone between 256 and 511 bytes
4862 // long.
4863 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
4864 })
David Benjaminc7ce9772015-10-09 19:32:41 -04004865
4866 // Extensions should not function in SSL 3.0.
4867 testCases = append(testCases, testCase{
4868 testType: serverTest,
4869 name: "SSLv3Extensions-NoALPN",
4870 config: Config{
4871 MaxVersion: VersionSSL30,
4872 NextProtos: []string{"foo", "bar", "baz"},
4873 },
4874 flags: []string{
4875 "-select-alpn", "foo",
4876 },
4877 expectNoNextProto: true,
4878 })
4879
4880 // Test session tickets separately as they follow a different codepath.
4881 testCases = append(testCases, testCase{
4882 testType: serverTest,
4883 name: "SSLv3Extensions-NoTickets",
4884 config: Config{
4885 MaxVersion: VersionSSL30,
4886 Bugs: ProtocolBugs{
4887 // Historically, session tickets in SSL 3.0
4888 // failed in different ways depending on whether
4889 // the client supported renegotiation_info.
4890 NoRenegotiationInfo: true,
4891 },
4892 },
4893 resumeSession: true,
4894 })
4895 testCases = append(testCases, testCase{
4896 testType: serverTest,
4897 name: "SSLv3Extensions-NoTickets2",
4898 config: Config{
4899 MaxVersion: VersionSSL30,
4900 },
4901 resumeSession: true,
4902 })
4903
4904 // But SSL 3.0 does send and process renegotiation_info.
4905 testCases = append(testCases, testCase{
4906 testType: serverTest,
4907 name: "SSLv3Extensions-RenegotiationInfo",
4908 config: Config{
4909 MaxVersion: VersionSSL30,
4910 Bugs: ProtocolBugs{
4911 RequireRenegotiationInfo: true,
4912 },
4913 },
4914 })
4915 testCases = append(testCases, testCase{
4916 testType: serverTest,
4917 name: "SSLv3Extensions-RenegotiationInfo-SCSV",
4918 config: Config{
4919 MaxVersion: VersionSSL30,
4920 Bugs: ProtocolBugs{
4921 NoRenegotiationInfo: true,
4922 SendRenegotiationSCSV: true,
4923 RequireRenegotiationInfo: true,
4924 },
4925 },
4926 })
Steven Valdez143e8b32016-07-11 13:19:03 -04004927
4928 // Test that illegal extensions in TLS 1.3 are rejected by the client if
4929 // in ServerHello.
4930 testCases = append(testCases, testCase{
4931 name: "NPN-Forbidden-TLS13",
4932 config: Config{
4933 MaxVersion: VersionTLS13,
4934 NextProtos: []string{"foo"},
4935 Bugs: ProtocolBugs{
4936 NegotiateNPNAtAllVersions: true,
4937 },
4938 },
4939 flags: []string{"-select-next-proto", "foo"},
4940 shouldFail: true,
4941 expectedError: ":ERROR_PARSING_EXTENSION:",
4942 })
4943 testCases = append(testCases, testCase{
4944 name: "EMS-Forbidden-TLS13",
4945 config: Config{
4946 MaxVersion: VersionTLS13,
4947 Bugs: ProtocolBugs{
4948 NegotiateEMSAtAllVersions: true,
4949 },
4950 },
4951 shouldFail: true,
4952 expectedError: ":ERROR_PARSING_EXTENSION:",
4953 })
4954 testCases = append(testCases, testCase{
4955 name: "RenegotiationInfo-Forbidden-TLS13",
4956 config: Config{
4957 MaxVersion: VersionTLS13,
4958 Bugs: ProtocolBugs{
4959 NegotiateRenegotiationInfoAtAllVersions: true,
4960 },
4961 },
4962 shouldFail: true,
4963 expectedError: ":ERROR_PARSING_EXTENSION:",
4964 })
4965 testCases = append(testCases, testCase{
4966 name: "ChannelID-Forbidden-TLS13",
4967 config: Config{
4968 MaxVersion: VersionTLS13,
4969 RequestChannelID: true,
4970 Bugs: ProtocolBugs{
4971 NegotiateChannelIDAtAllVersions: true,
4972 },
4973 },
4974 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
4975 shouldFail: true,
4976 expectedError: ":ERROR_PARSING_EXTENSION:",
4977 })
4978 testCases = append(testCases, testCase{
4979 name: "Ticket-Forbidden-TLS13",
4980 config: Config{
4981 MaxVersion: VersionTLS12,
4982 },
4983 resumeConfig: &Config{
4984 MaxVersion: VersionTLS13,
4985 Bugs: ProtocolBugs{
4986 AdvertiseTicketExtension: true,
4987 },
4988 },
4989 resumeSession: true,
4990 shouldFail: true,
4991 expectedError: ":ERROR_PARSING_EXTENSION:",
4992 })
4993
4994 // Test that illegal extensions in TLS 1.3 are declined by the server if
4995 // offered in ClientHello. The runner's server will fail if this occurs,
4996 // so we exercise the offering path. (EMS and Renegotiation Info are
4997 // implicit in every test.)
4998 testCases = append(testCases, testCase{
4999 testType: serverTest,
5000 name: "ChannelID-Declined-TLS13",
5001 config: Config{
5002 MaxVersion: VersionTLS13,
5003 ChannelID: channelIDKey,
5004 },
5005 flags: []string{"-enable-channel-id"},
5006 })
5007 testCases = append(testCases, testCase{
5008 testType: serverTest,
5009 name: "NPN-Server",
5010 config: Config{
5011 MaxVersion: VersionTLS13,
5012 NextProtos: []string{"bar"},
5013 },
5014 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"},
5015 })
David Benjamin196df5b2016-09-21 16:23:27 -04005016
5017 testCases = append(testCases, testCase{
5018 testType: serverTest,
5019 name: "InvalidChannelIDSignature",
5020 config: Config{
5021 MaxVersion: VersionTLS12,
5022 ChannelID: channelIDKey,
5023 Bugs: ProtocolBugs{
5024 InvalidChannelIDSignature: true,
5025 },
5026 },
5027 flags: []string{"-enable-channel-id"},
5028 shouldFail: true,
5029 expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:",
5030 expectedLocalError: "remote error: error decrypting message",
5031 })
David Benjamine78bfde2014-09-06 12:45:15 -04005032}
5033
David Benjamin01fe8202014-09-24 15:21:44 -04005034func addResumptionVersionTests() {
David Benjamin01fe8202014-09-24 15:21:44 -04005035 for _, sessionVers := range tlsVersions {
David Benjamin01fe8202014-09-24 15:21:44 -04005036 for _, resumeVers := range tlsVersions {
Nick Harper1fd39d82016-06-14 18:14:35 -07005037 cipher := TLS_RSA_WITH_AES_128_CBC_SHA
5038 if sessionVers.version >= VersionTLS13 || resumeVers.version >= VersionTLS13 {
5039 // TLS 1.3 only shares ciphers with TLS 1.2, so
5040 // we skip certain combinations and use a
5041 // different cipher to test with.
5042 cipher = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
5043 if sessionVers.version < VersionTLS12 || resumeVers.version < VersionTLS12 {
5044 continue
5045 }
5046 }
5047
David Benjamin8b8c0062014-11-23 02:47:52 -05005048 protocols := []protocol{tls}
5049 if sessionVers.hasDTLS && resumeVers.hasDTLS {
5050 protocols = append(protocols, dtls)
David Benjaminbdf5e722014-11-11 00:52:15 -05005051 }
David Benjamin8b8c0062014-11-23 02:47:52 -05005052 for _, protocol := range protocols {
5053 suffix := "-" + sessionVers.name + "-" + resumeVers.name
5054 if protocol == dtls {
5055 suffix += "-DTLS"
5056 }
5057
David Benjaminece3de92015-03-16 18:02:20 -04005058 if sessionVers.version == resumeVers.version {
5059 testCases = append(testCases, testCase{
5060 protocol: protocol,
5061 name: "Resume-Client" + suffix,
5062 resumeSession: true,
5063 config: Config{
5064 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005065 CipherSuites: []uint16{cipher},
David Benjamin405da482016-08-08 17:25:07 -04005066 Bugs: ProtocolBugs{
5067 ExpectNoTLS12Session: sessionVers.version >= VersionTLS13,
5068 ExpectNoTLS13PSK: sessionVers.version < VersionTLS13,
5069 },
David Benjamin8b8c0062014-11-23 02:47:52 -05005070 },
David Benjaminece3de92015-03-16 18:02:20 -04005071 expectedVersion: sessionVers.version,
5072 expectedResumeVersion: resumeVers.version,
5073 })
5074 } else {
David Benjamin405da482016-08-08 17:25:07 -04005075 error := ":OLD_SESSION_VERSION_NOT_RETURNED:"
5076
5077 // Offering a TLS 1.3 session sends an empty session ID, so
5078 // there is no way to convince a non-lookahead client the
5079 // session was resumed. It will appear to the client that a
5080 // stray ChangeCipherSpec was sent.
5081 if resumeVers.version < VersionTLS13 && sessionVers.version >= VersionTLS13 {
5082 error = ":UNEXPECTED_RECORD:"
Steven Valdez4aa154e2016-07-29 14:32:55 -04005083 }
5084
David Benjaminece3de92015-03-16 18:02:20 -04005085 testCases = append(testCases, testCase{
5086 protocol: protocol,
5087 name: "Resume-Client-Mismatch" + suffix,
5088 resumeSession: true,
5089 config: Config{
5090 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005091 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05005092 },
David Benjaminece3de92015-03-16 18:02:20 -04005093 expectedVersion: sessionVers.version,
5094 resumeConfig: &Config{
5095 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005096 CipherSuites: []uint16{cipher},
David Benjaminece3de92015-03-16 18:02:20 -04005097 Bugs: ProtocolBugs{
David Benjamin405da482016-08-08 17:25:07 -04005098 AcceptAnySession: true,
David Benjaminece3de92015-03-16 18:02:20 -04005099 },
5100 },
5101 expectedResumeVersion: resumeVers.version,
5102 shouldFail: true,
Steven Valdez4aa154e2016-07-29 14:32:55 -04005103 expectedError: error,
David Benjaminece3de92015-03-16 18:02:20 -04005104 })
5105 }
David Benjamin8b8c0062014-11-23 02:47:52 -05005106
5107 testCases = append(testCases, testCase{
5108 protocol: protocol,
5109 name: "Resume-Client-NoResume" + suffix,
David Benjamin8b8c0062014-11-23 02:47:52 -05005110 resumeSession: true,
5111 config: Config{
5112 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005113 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05005114 },
5115 expectedVersion: sessionVers.version,
5116 resumeConfig: &Config{
5117 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005118 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05005119 },
5120 newSessionsOnResume: true,
Adam Langleyb0eef0a2015-06-02 10:47:39 -07005121 expectResumeRejected: true,
David Benjamin8b8c0062014-11-23 02:47:52 -05005122 expectedResumeVersion: resumeVers.version,
5123 })
5124
David Benjamin8b8c0062014-11-23 02:47:52 -05005125 testCases = append(testCases, testCase{
5126 protocol: protocol,
5127 testType: serverTest,
5128 name: "Resume-Server" + suffix,
David Benjamin8b8c0062014-11-23 02:47:52 -05005129 resumeSession: true,
5130 config: Config{
5131 MaxVersion: sessionVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005132 CipherSuites: []uint16{cipher},
David Benjamin8b8c0062014-11-23 02:47:52 -05005133 },
Adam Langleyb0eef0a2015-06-02 10:47:39 -07005134 expectedVersion: sessionVers.version,
5135 expectResumeRejected: sessionVers.version != resumeVers.version,
David Benjamin8b8c0062014-11-23 02:47:52 -05005136 resumeConfig: &Config{
5137 MaxVersion: resumeVers.version,
Nick Harper1fd39d82016-06-14 18:14:35 -07005138 CipherSuites: []uint16{cipher},
David Benjamin405da482016-08-08 17:25:07 -04005139 Bugs: ProtocolBugs{
5140 SendBothTickets: true,
5141 },
David Benjamin8b8c0062014-11-23 02:47:52 -05005142 },
5143 expectedResumeVersion: resumeVers.version,
5144 })
5145 }
David Benjamin01fe8202014-09-24 15:21:44 -04005146 }
5147 }
David Benjaminece3de92015-03-16 18:02:20 -04005148
5149 testCases = append(testCases, testCase{
5150 name: "Resume-Client-CipherMismatch",
5151 resumeSession: true,
5152 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005153 MaxVersion: VersionTLS12,
David Benjaminece3de92015-03-16 18:02:20 -04005154 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
5155 },
5156 resumeConfig: &Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005157 MaxVersion: VersionTLS12,
David Benjaminece3de92015-03-16 18:02:20 -04005158 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
5159 Bugs: ProtocolBugs{
5160 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA,
5161 },
5162 },
5163 shouldFail: true,
5164 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
5165 })
Steven Valdez4aa154e2016-07-29 14:32:55 -04005166
5167 testCases = append(testCases, testCase{
5168 name: "Resume-Client-CipherMismatch-TLS13",
5169 resumeSession: true,
5170 config: Config{
5171 MaxVersion: VersionTLS13,
5172 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5173 },
5174 resumeConfig: &Config{
5175 MaxVersion: VersionTLS13,
5176 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5177 Bugs: ProtocolBugs{
5178 SendCipherSuite: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
5179 },
5180 },
5181 shouldFail: true,
5182 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
5183 })
David Benjamin01fe8202014-09-24 15:21:44 -04005184}
5185
Adam Langley2ae77d22014-10-28 17:29:33 -07005186func addRenegotiationTests() {
David Benjamin44d3eed2015-05-21 01:29:55 -04005187 // Servers cannot renegotiate.
David Benjaminb16346b2015-04-08 19:16:58 -04005188 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005189 testType: serverTest,
5190 name: "Renegotiate-Server-Forbidden",
5191 config: Config{
5192 MaxVersion: VersionTLS12,
5193 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005194 renegotiate: 1,
David Benjaminb16346b2015-04-08 19:16:58 -04005195 shouldFail: true,
5196 expectedError: ":NO_RENEGOTIATION:",
5197 expectedLocalError: "remote error: no renegotiation",
5198 })
Adam Langley5021b222015-06-12 18:27:58 -07005199 // The server shouldn't echo the renegotiation extension unless
5200 // requested by the client.
5201 testCases = append(testCases, testCase{
5202 testType: serverTest,
5203 name: "Renegotiate-Server-NoExt",
5204 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005205 MaxVersion: VersionTLS12,
Adam Langley5021b222015-06-12 18:27:58 -07005206 Bugs: ProtocolBugs{
5207 NoRenegotiationInfo: true,
5208 RequireRenegotiationInfo: true,
5209 },
5210 },
5211 shouldFail: true,
5212 expectedLocalError: "renegotiation extension missing",
5213 })
5214 // The renegotiation SCSV should be sufficient for the server to echo
5215 // the extension.
5216 testCases = append(testCases, testCase{
5217 testType: serverTest,
5218 name: "Renegotiate-Server-NoExt-SCSV",
5219 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005220 MaxVersion: VersionTLS12,
Adam Langley5021b222015-06-12 18:27:58 -07005221 Bugs: ProtocolBugs{
5222 NoRenegotiationInfo: true,
5223 SendRenegotiationSCSV: true,
5224 RequireRenegotiationInfo: true,
5225 },
5226 },
5227 })
Adam Langleycf2d4f42014-10-28 19:06:14 -07005228 testCases = append(testCases, testCase{
David Benjamin4b27d9f2015-05-12 22:42:52 -04005229 name: "Renegotiate-Client",
David Benjamincdea40c2015-03-19 14:09:43 -04005230 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005231 MaxVersion: VersionTLS12,
David Benjamincdea40c2015-03-19 14:09:43 -04005232 Bugs: ProtocolBugs{
David Benjamin4b27d9f2015-05-12 22:42:52 -04005233 FailIfResumeOnRenego: true,
David Benjamincdea40c2015-03-19 14:09:43 -04005234 },
5235 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005236 renegotiate: 1,
5237 flags: []string{
5238 "-renegotiate-freely",
5239 "-expect-total-renegotiations", "1",
5240 },
David Benjamincdea40c2015-03-19 14:09:43 -04005241 })
5242 testCases = append(testCases, testCase{
Adam Langleycf2d4f42014-10-28 19:06:14 -07005243 name: "Renegotiate-Client-EmptyExt",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005244 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005245 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005246 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005247 Bugs: ProtocolBugs{
5248 EmptyRenegotiationInfo: true,
5249 },
5250 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005251 flags: []string{"-renegotiate-freely"},
Adam Langleycf2d4f42014-10-28 19:06:14 -07005252 shouldFail: true,
5253 expectedError: ":RENEGOTIATION_MISMATCH:",
5254 })
5255 testCases = append(testCases, testCase{
5256 name: "Renegotiate-Client-BadExt",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005257 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005258 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005259 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005260 Bugs: ProtocolBugs{
5261 BadRenegotiationInfo: true,
5262 },
5263 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005264 flags: []string{"-renegotiate-freely"},
Adam Langleycf2d4f42014-10-28 19:06:14 -07005265 shouldFail: true,
5266 expectedError: ":RENEGOTIATION_MISMATCH:",
5267 })
5268 testCases = append(testCases, testCase{
David Benjamin3e052de2015-11-25 20:10:31 -05005269 name: "Renegotiate-Client-Downgrade",
5270 renegotiate: 1,
5271 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005272 MaxVersion: VersionTLS12,
David Benjamin3e052de2015-11-25 20:10:31 -05005273 Bugs: ProtocolBugs{
5274 NoRenegotiationInfoAfterInitial: true,
5275 },
5276 },
5277 flags: []string{"-renegotiate-freely"},
5278 shouldFail: true,
5279 expectedError: ":RENEGOTIATION_MISMATCH:",
5280 })
5281 testCases = append(testCases, testCase{
5282 name: "Renegotiate-Client-Upgrade",
5283 renegotiate: 1,
5284 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005285 MaxVersion: VersionTLS12,
David Benjamin3e052de2015-11-25 20:10:31 -05005286 Bugs: ProtocolBugs{
5287 NoRenegotiationInfoInInitial: true,
5288 },
5289 },
5290 flags: []string{"-renegotiate-freely"},
5291 shouldFail: true,
5292 expectedError: ":RENEGOTIATION_MISMATCH:",
5293 })
5294 testCases = append(testCases, testCase{
David Benjamincff0b902015-05-15 23:09:47 -04005295 name: "Renegotiate-Client-NoExt-Allowed",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005296 renegotiate: 1,
David Benjamincff0b902015-05-15 23:09:47 -04005297 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005298 MaxVersion: VersionTLS12,
David Benjamincff0b902015-05-15 23:09:47 -04005299 Bugs: ProtocolBugs{
5300 NoRenegotiationInfo: true,
5301 },
5302 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005303 flags: []string{
5304 "-renegotiate-freely",
5305 "-expect-total-renegotiations", "1",
5306 },
David Benjamincff0b902015-05-15 23:09:47 -04005307 })
David Benjamine7e36aa2016-08-08 12:39:41 -04005308
5309 // Test that the server may switch ciphers on renegotiation without
5310 // problems.
David Benjamincff0b902015-05-15 23:09:47 -04005311 testCases = append(testCases, testCase{
Adam Langleycf2d4f42014-10-28 19:06:14 -07005312 name: "Renegotiate-Client-SwitchCiphers",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005313 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005314 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005315 MaxVersion: VersionTLS12,
Matt Braithwaite07e78062016-08-21 14:50:43 -07005316 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
Adam Langleycf2d4f42014-10-28 19:06:14 -07005317 },
5318 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005319 flags: []string{
5320 "-renegotiate-freely",
5321 "-expect-total-renegotiations", "1",
5322 },
Adam Langleycf2d4f42014-10-28 19:06:14 -07005323 })
5324 testCases = append(testCases, testCase{
5325 name: "Renegotiate-Client-SwitchCiphers2",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005326 renegotiate: 1,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005327 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005328 MaxVersion: VersionTLS12,
Adam Langleycf2d4f42014-10-28 19:06:14 -07005329 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5330 },
Matt Braithwaite07e78062016-08-21 14:50:43 -07005331 renegotiateCiphers: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005332 flags: []string{
5333 "-renegotiate-freely",
5334 "-expect-total-renegotiations", "1",
5335 },
David Benjaminb16346b2015-04-08 19:16:58 -04005336 })
David Benjamine7e36aa2016-08-08 12:39:41 -04005337
5338 // Test that the server may not switch versions on renegotiation.
5339 testCases = append(testCases, testCase{
5340 name: "Renegotiate-Client-SwitchVersion",
5341 config: Config{
5342 MaxVersion: VersionTLS12,
5343 // Pick a cipher which exists at both versions.
5344 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
5345 Bugs: ProtocolBugs{
5346 NegotiateVersionOnRenego: VersionTLS11,
5347 },
5348 },
5349 renegotiate: 1,
5350 flags: []string{
5351 "-renegotiate-freely",
5352 "-expect-total-renegotiations", "1",
5353 },
5354 shouldFail: true,
5355 expectedError: ":WRONG_SSL_VERSION:",
5356 })
5357
David Benjaminb16346b2015-04-08 19:16:58 -04005358 testCases = append(testCases, testCase{
David Benjaminc44b1df2014-11-23 12:11:01 -05005359 name: "Renegotiate-SameClientVersion",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005360 renegotiate: 1,
David Benjaminc44b1df2014-11-23 12:11:01 -05005361 config: Config{
5362 MaxVersion: VersionTLS10,
5363 Bugs: ProtocolBugs{
5364 RequireSameRenegoClientVersion: true,
5365 },
5366 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005367 flags: []string{
5368 "-renegotiate-freely",
5369 "-expect-total-renegotiations", "1",
5370 },
David Benjaminc44b1df2014-11-23 12:11:01 -05005371 })
Adam Langleyb558c4c2015-07-08 12:16:38 -07005372 testCases = append(testCases, testCase{
5373 name: "Renegotiate-FalseStart",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005374 renegotiate: 1,
Adam Langleyb558c4c2015-07-08 12:16:38 -07005375 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07005376 MaxVersion: VersionTLS12,
Adam Langleyb558c4c2015-07-08 12:16:38 -07005377 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5378 NextProtos: []string{"foo"},
5379 },
5380 flags: []string{
5381 "-false-start",
5382 "-select-next-proto", "foo",
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005383 "-renegotiate-freely",
David Benjamin324dce42015-10-12 19:49:00 -04005384 "-expect-total-renegotiations", "1",
Adam Langleyb558c4c2015-07-08 12:16:38 -07005385 },
5386 shimWritesFirst: true,
5387 })
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005388
5389 // Client-side renegotiation controls.
5390 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005391 name: "Renegotiate-Client-Forbidden-1",
5392 config: Config{
5393 MaxVersion: VersionTLS12,
5394 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005395 renegotiate: 1,
5396 shouldFail: true,
5397 expectedError: ":NO_RENEGOTIATION:",
5398 expectedLocalError: "remote error: no renegotiation",
5399 })
5400 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005401 name: "Renegotiate-Client-Once-1",
5402 config: Config{
5403 MaxVersion: VersionTLS12,
5404 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005405 renegotiate: 1,
5406 flags: []string{
5407 "-renegotiate-once",
5408 "-expect-total-renegotiations", "1",
5409 },
5410 })
5411 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005412 name: "Renegotiate-Client-Freely-1",
5413 config: Config{
5414 MaxVersion: VersionTLS12,
5415 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005416 renegotiate: 1,
5417 flags: []string{
5418 "-renegotiate-freely",
5419 "-expect-total-renegotiations", "1",
5420 },
5421 })
5422 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005423 name: "Renegotiate-Client-Once-2",
5424 config: Config{
5425 MaxVersion: VersionTLS12,
5426 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005427 renegotiate: 2,
5428 flags: []string{"-renegotiate-once"},
5429 shouldFail: true,
5430 expectedError: ":NO_RENEGOTIATION:",
5431 expectedLocalError: "remote error: no renegotiation",
5432 })
5433 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005434 name: "Renegotiate-Client-Freely-2",
5435 config: Config{
5436 MaxVersion: VersionTLS12,
5437 },
David Benjamin1d5ef3b2015-10-12 19:54:18 -04005438 renegotiate: 2,
5439 flags: []string{
5440 "-renegotiate-freely",
5441 "-expect-total-renegotiations", "2",
5442 },
5443 })
Adam Langley27a0d082015-11-03 13:34:10 -08005444 testCases = append(testCases, testCase{
5445 name: "Renegotiate-Client-NoIgnore",
5446 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005447 MaxVersion: VersionTLS12,
Adam Langley27a0d082015-11-03 13:34:10 -08005448 Bugs: ProtocolBugs{
5449 SendHelloRequestBeforeEveryAppDataRecord: true,
5450 },
5451 },
5452 shouldFail: true,
5453 expectedError: ":NO_RENEGOTIATION:",
5454 })
5455 testCases = append(testCases, testCase{
5456 name: "Renegotiate-Client-Ignore",
5457 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005458 MaxVersion: VersionTLS12,
Adam Langley27a0d082015-11-03 13:34:10 -08005459 Bugs: ProtocolBugs{
5460 SendHelloRequestBeforeEveryAppDataRecord: true,
5461 },
5462 },
5463 flags: []string{
5464 "-renegotiate-ignore",
5465 "-expect-total-renegotiations", "0",
5466 },
5467 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04005468
David Benjamin397c8e62016-07-08 14:14:36 -07005469 // Stray HelloRequests during the handshake are ignored in TLS 1.2.
David Benjamin71dd6662016-07-08 14:10:48 -07005470 testCases = append(testCases, testCase{
5471 name: "StrayHelloRequest",
5472 config: Config{
5473 MaxVersion: VersionTLS12,
5474 Bugs: ProtocolBugs{
5475 SendHelloRequestBeforeEveryHandshakeMessage: true,
5476 },
5477 },
5478 })
5479 testCases = append(testCases, testCase{
5480 name: "StrayHelloRequest-Packed",
5481 config: Config{
5482 MaxVersion: VersionTLS12,
5483 Bugs: ProtocolBugs{
5484 PackHandshakeFlight: true,
5485 SendHelloRequestBeforeEveryHandshakeMessage: true,
5486 },
5487 },
5488 })
5489
David Benjamin12d2c482016-07-24 10:56:51 -04005490 // Test renegotiation works if HelloRequest and server Finished come in
5491 // the same record.
5492 testCases = append(testCases, testCase{
5493 name: "Renegotiate-Client-Packed",
5494 config: Config{
5495 MaxVersion: VersionTLS12,
5496 Bugs: ProtocolBugs{
5497 PackHandshakeFlight: true,
5498 PackHelloRequestWithFinished: true,
5499 },
5500 },
5501 renegotiate: 1,
5502 flags: []string{
5503 "-renegotiate-freely",
5504 "-expect-total-renegotiations", "1",
5505 },
5506 })
5507
David Benjamin397c8e62016-07-08 14:14:36 -07005508 // Renegotiation is forbidden in TLS 1.3.
5509 testCases = append(testCases, testCase{
5510 name: "Renegotiate-Client-TLS13",
5511 config: Config{
5512 MaxVersion: VersionTLS13,
Steven Valdez143e8b32016-07-11 13:19:03 -04005513 Bugs: ProtocolBugs{
5514 SendHelloRequestBeforeEveryAppDataRecord: true,
5515 },
David Benjamin397c8e62016-07-08 14:14:36 -07005516 },
David Benjamin397c8e62016-07-08 14:14:36 -07005517 flags: []string{
5518 "-renegotiate-freely",
5519 },
Steven Valdez8e1c7be2016-07-26 12:39:22 -04005520 shouldFail: true,
5521 expectedError: ":UNEXPECTED_MESSAGE:",
David Benjamin397c8e62016-07-08 14:14:36 -07005522 })
5523
5524 // Stray HelloRequests during the handshake are forbidden in TLS 1.3.
5525 testCases = append(testCases, testCase{
5526 name: "StrayHelloRequest-TLS13",
5527 config: Config{
5528 MaxVersion: VersionTLS13,
5529 Bugs: ProtocolBugs{
5530 SendHelloRequestBeforeEveryHandshakeMessage: true,
5531 },
5532 },
5533 shouldFail: true,
5534 expectedError: ":UNEXPECTED_MESSAGE:",
5535 })
Adam Langley2ae77d22014-10-28 17:29:33 -07005536}
5537
David Benjamin5e961c12014-11-07 01:48:35 -05005538func addDTLSReplayTests() {
5539 // Test that sequence number replays are detected.
5540 testCases = append(testCases, testCase{
5541 protocol: dtls,
5542 name: "DTLS-Replay",
David Benjamin8e6db492015-07-25 18:29:23 -04005543 messageCount: 200,
David Benjamin5e961c12014-11-07 01:48:35 -05005544 replayWrites: true,
5545 })
5546
David Benjamin8e6db492015-07-25 18:29:23 -04005547 // Test the incoming sequence number skipping by values larger
David Benjamin5e961c12014-11-07 01:48:35 -05005548 // than the retransmit window.
5549 testCases = append(testCases, testCase{
5550 protocol: dtls,
5551 name: "DTLS-Replay-LargeGaps",
5552 config: Config{
5553 Bugs: ProtocolBugs{
David Benjamin8e6db492015-07-25 18:29:23 -04005554 SequenceNumberMapping: func(in uint64) uint64 {
5555 return in * 127
5556 },
David Benjamin5e961c12014-11-07 01:48:35 -05005557 },
5558 },
David Benjamin8e6db492015-07-25 18:29:23 -04005559 messageCount: 200,
5560 replayWrites: true,
5561 })
5562
5563 // Test the incoming sequence number changing non-monotonically.
5564 testCases = append(testCases, testCase{
5565 protocol: dtls,
5566 name: "DTLS-Replay-NonMonotonic",
5567 config: Config{
5568 Bugs: ProtocolBugs{
5569 SequenceNumberMapping: func(in uint64) uint64 {
5570 return in ^ 31
5571 },
5572 },
5573 },
5574 messageCount: 200,
David Benjamin5e961c12014-11-07 01:48:35 -05005575 replayWrites: true,
5576 })
5577}
5578
Nick Harper60edffd2016-06-21 15:19:24 -07005579var testSignatureAlgorithms = []struct {
David Benjamin000800a2014-11-14 01:43:59 -05005580 name string
Nick Harper60edffd2016-06-21 15:19:24 -07005581 id signatureAlgorithm
5582 cert testCert
David Benjamin000800a2014-11-14 01:43:59 -05005583}{
Nick Harper60edffd2016-06-21 15:19:24 -07005584 {"RSA-PKCS1-SHA1", signatureRSAPKCS1WithSHA1, testCertRSA},
5585 {"RSA-PKCS1-SHA256", signatureRSAPKCS1WithSHA256, testCertRSA},
5586 {"RSA-PKCS1-SHA384", signatureRSAPKCS1WithSHA384, testCertRSA},
5587 {"RSA-PKCS1-SHA512", signatureRSAPKCS1WithSHA512, testCertRSA},
David Benjamin33863262016-07-08 17:20:12 -07005588 {"ECDSA-SHA1", signatureECDSAWithSHA1, testCertECDSAP256},
David Benjamin33863262016-07-08 17:20:12 -07005589 {"ECDSA-P256-SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256},
5590 {"ECDSA-P384-SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384},
5591 {"ECDSA-P521-SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521},
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005592 {"RSA-PSS-SHA256", signatureRSAPSSWithSHA256, testCertRSA},
5593 {"RSA-PSS-SHA384", signatureRSAPSSWithSHA384, testCertRSA},
5594 {"RSA-PSS-SHA512", signatureRSAPSSWithSHA512, testCertRSA},
David Benjamin5208fd42016-07-13 21:43:25 -04005595 // Tests for key types prior to TLS 1.2.
5596 {"RSA", 0, testCertRSA},
5597 {"ECDSA", 0, testCertECDSAP256},
David Benjamin000800a2014-11-14 01:43:59 -05005598}
5599
Nick Harper60edffd2016-06-21 15:19:24 -07005600const fakeSigAlg1 signatureAlgorithm = 0x2a01
5601const fakeSigAlg2 signatureAlgorithm = 0xff01
5602
5603func addSignatureAlgorithmTests() {
David Benjamin5208fd42016-07-13 21:43:25 -04005604 // Not all ciphers involve a signature. Advertise a list which gives all
5605 // versions a signing cipher.
5606 signingCiphers := []uint16{
5607 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
5608 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
5609 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
5610 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
5611 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
5612 }
5613
David Benjaminca3d5452016-07-14 12:51:01 -04005614 var allAlgorithms []signatureAlgorithm
5615 for _, alg := range testSignatureAlgorithms {
5616 if alg.id != 0 {
5617 allAlgorithms = append(allAlgorithms, alg.id)
5618 }
5619 }
5620
Nick Harper60edffd2016-06-21 15:19:24 -07005621 // Make sure each signature algorithm works. Include some fake values in
5622 // the list and ensure they're ignored.
5623 for _, alg := range testSignatureAlgorithms {
David Benjamin1fb125c2016-07-08 18:52:12 -07005624 for _, ver := range tlsVersions {
David Benjamin5208fd42016-07-13 21:43:25 -04005625 if (ver.version < VersionTLS12) != (alg.id == 0) {
5626 continue
5627 }
5628
5629 // TODO(davidben): Support ECDSA in SSL 3.0 in Go for testing
5630 // or remove it in C.
5631 if ver.version == VersionSSL30 && alg.cert != testCertRSA {
David Benjamin1fb125c2016-07-08 18:52:12 -07005632 continue
5633 }
Nick Harper60edffd2016-06-21 15:19:24 -07005634
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005635 var shouldFail bool
David Benjamin1fb125c2016-07-08 18:52:12 -07005636 // ecdsa_sha1 does not exist in TLS 1.3.
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005637 if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 {
5638 shouldFail = true
5639 }
Steven Valdez54ed58e2016-08-18 14:03:49 -04005640 // RSA-PKCS1 does not exist in TLS 1.3.
5641 if ver.version == VersionTLS13 && hasComponent(alg.name, "PKCS1") {
5642 shouldFail = true
5643 }
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005644
5645 var signError, verifyError string
5646 if shouldFail {
5647 signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:"
5648 verifyError = ":WRONG_SIGNATURE_TYPE:"
David Benjamin1fb125c2016-07-08 18:52:12 -07005649 }
David Benjamin000800a2014-11-14 01:43:59 -05005650
David Benjamin1fb125c2016-07-08 18:52:12 -07005651 suffix := "-" + alg.name + "-" + ver.name
David Benjamin6e807652015-11-02 12:02:20 -05005652
David Benjamin7a41d372016-07-09 11:21:54 -07005653 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005654 name: "ClientAuth-Sign" + suffix,
David Benjamin7a41d372016-07-09 11:21:54 -07005655 config: Config{
5656 MaxVersion: ver.version,
5657 ClientAuth: RequireAnyClientCert,
5658 VerifySignatureAlgorithms: []signatureAlgorithm{
5659 fakeSigAlg1,
5660 alg.id,
5661 fakeSigAlg2,
David Benjamin1fb125c2016-07-08 18:52:12 -07005662 },
David Benjamin7a41d372016-07-09 11:21:54 -07005663 },
5664 flags: []string{
5665 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
5666 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
5667 "-enable-all-curves",
5668 },
5669 shouldFail: shouldFail,
5670 expectedError: signError,
5671 expectedPeerSignatureAlgorithm: alg.id,
5672 })
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005673
David Benjamin7a41d372016-07-09 11:21:54 -07005674 testCases = append(testCases, testCase{
5675 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04005676 name: "ClientAuth-Verify" + suffix,
David Benjamin7a41d372016-07-09 11:21:54 -07005677 config: Config{
5678 MaxVersion: ver.version,
5679 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
5680 SignSignatureAlgorithms: []signatureAlgorithm{
5681 alg.id,
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005682 },
David Benjamin7a41d372016-07-09 11:21:54 -07005683 Bugs: ProtocolBugs{
5684 SkipECDSACurveCheck: shouldFail,
5685 IgnoreSignatureVersionChecks: shouldFail,
5686 // The client won't advertise 1.3-only algorithms after
5687 // version negotiation.
5688 IgnorePeerSignatureAlgorithmPreferences: shouldFail,
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005689 },
David Benjamin7a41d372016-07-09 11:21:54 -07005690 },
5691 flags: []string{
5692 "-require-any-client-certificate",
5693 "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
5694 "-enable-all-curves",
5695 },
5696 shouldFail: shouldFail,
5697 expectedError: verifyError,
5698 })
David Benjamin1fb125c2016-07-08 18:52:12 -07005699
5700 testCases = append(testCases, testCase{
5701 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04005702 name: "ServerAuth-Sign" + suffix,
David Benjamin1fb125c2016-07-08 18:52:12 -07005703 config: Config{
David Benjamin5208fd42016-07-13 21:43:25 -04005704 MaxVersion: ver.version,
5705 CipherSuites: signingCiphers,
David Benjamin7a41d372016-07-09 11:21:54 -07005706 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07005707 fakeSigAlg1,
5708 alg.id,
5709 fakeSigAlg2,
5710 },
5711 },
5712 flags: []string{
5713 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
5714 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
5715 "-enable-all-curves",
5716 },
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005717 shouldFail: shouldFail,
5718 expectedError: signError,
David Benjamin1fb125c2016-07-08 18:52:12 -07005719 expectedPeerSignatureAlgorithm: alg.id,
5720 })
5721
5722 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005723 name: "ServerAuth-Verify" + suffix,
David Benjamin1fb125c2016-07-08 18:52:12 -07005724 config: Config{
5725 MaxVersion: ver.version,
5726 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
David Benjamin5208fd42016-07-13 21:43:25 -04005727 CipherSuites: signingCiphers,
David Benjamin7a41d372016-07-09 11:21:54 -07005728 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07005729 alg.id,
5730 },
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005731 Bugs: ProtocolBugs{
5732 SkipECDSACurveCheck: shouldFail,
5733 IgnoreSignatureVersionChecks: shouldFail,
5734 },
David Benjamin1fb125c2016-07-08 18:52:12 -07005735 },
5736 flags: []string{
5737 "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
5738 "-enable-all-curves",
5739 },
Steven Valdezeff1e8d2016-07-06 14:24:47 -04005740 shouldFail: shouldFail,
5741 expectedError: verifyError,
David Benjamin1fb125c2016-07-08 18:52:12 -07005742 })
David Benjamin5208fd42016-07-13 21:43:25 -04005743
5744 if !shouldFail {
5745 testCases = append(testCases, testCase{
5746 testType: serverTest,
5747 name: "ClientAuth-InvalidSignature" + suffix,
5748 config: Config{
5749 MaxVersion: ver.version,
5750 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
5751 SignSignatureAlgorithms: []signatureAlgorithm{
5752 alg.id,
5753 },
5754 Bugs: ProtocolBugs{
5755 InvalidSignature: true,
5756 },
5757 },
5758 flags: []string{
5759 "-require-any-client-certificate",
5760 "-enable-all-curves",
5761 },
5762 shouldFail: true,
5763 expectedError: ":BAD_SIGNATURE:",
5764 })
5765
5766 testCases = append(testCases, testCase{
5767 name: "ServerAuth-InvalidSignature" + suffix,
5768 config: Config{
5769 MaxVersion: ver.version,
5770 Certificates: []Certificate{getRunnerCertificate(alg.cert)},
5771 CipherSuites: signingCiphers,
5772 SignSignatureAlgorithms: []signatureAlgorithm{
5773 alg.id,
5774 },
5775 Bugs: ProtocolBugs{
5776 InvalidSignature: true,
5777 },
5778 },
5779 flags: []string{"-enable-all-curves"},
5780 shouldFail: true,
5781 expectedError: ":BAD_SIGNATURE:",
5782 })
5783 }
David Benjaminca3d5452016-07-14 12:51:01 -04005784
5785 if ver.version >= VersionTLS12 && !shouldFail {
5786 testCases = append(testCases, testCase{
5787 name: "ClientAuth-Sign-Negotiate" + suffix,
5788 config: Config{
5789 MaxVersion: ver.version,
5790 ClientAuth: RequireAnyClientCert,
5791 VerifySignatureAlgorithms: allAlgorithms,
5792 },
5793 flags: []string{
5794 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
5795 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
5796 "-enable-all-curves",
5797 "-signing-prefs", strconv.Itoa(int(alg.id)),
5798 },
5799 expectedPeerSignatureAlgorithm: alg.id,
5800 })
5801
5802 testCases = append(testCases, testCase{
5803 testType: serverTest,
5804 name: "ServerAuth-Sign-Negotiate" + suffix,
5805 config: Config{
5806 MaxVersion: ver.version,
5807 CipherSuites: signingCiphers,
5808 VerifySignatureAlgorithms: allAlgorithms,
5809 },
5810 flags: []string{
5811 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
5812 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
5813 "-enable-all-curves",
5814 "-signing-prefs", strconv.Itoa(int(alg.id)),
5815 },
5816 expectedPeerSignatureAlgorithm: alg.id,
5817 })
5818 }
David Benjamin1fb125c2016-07-08 18:52:12 -07005819 }
David Benjamin000800a2014-11-14 01:43:59 -05005820 }
5821
Nick Harper60edffd2016-06-21 15:19:24 -07005822 // Test that algorithm selection takes the key type into account.
David Benjamin000800a2014-11-14 01:43:59 -05005823 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005824 name: "ClientAuth-SignatureType",
David Benjamin000800a2014-11-14 01:43:59 -05005825 config: Config{
5826 ClientAuth: RequireAnyClientCert,
David Benjamin4c3ddf72016-06-29 18:13:53 -04005827 MaxVersion: VersionTLS12,
David Benjamin7a41d372016-07-09 11:21:54 -07005828 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005829 signatureECDSAWithP521AndSHA512,
5830 signatureRSAPKCS1WithSHA384,
5831 signatureECDSAWithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05005832 },
5833 },
5834 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07005835 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5836 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05005837 },
Nick Harper60edffd2016-06-21 15:19:24 -07005838 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA384,
David Benjamin000800a2014-11-14 01:43:59 -05005839 })
5840
5841 testCases = append(testCases, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04005842 name: "ClientAuth-SignatureType-TLS13",
5843 config: Config{
5844 ClientAuth: RequireAnyClientCert,
5845 MaxVersion: VersionTLS13,
5846 VerifySignatureAlgorithms: []signatureAlgorithm{
5847 signatureECDSAWithP521AndSHA512,
5848 signatureRSAPKCS1WithSHA384,
5849 signatureRSAPSSWithSHA384,
5850 signatureECDSAWithSHA1,
5851 },
5852 },
5853 flags: []string{
5854 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5855 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5856 },
5857 expectedPeerSignatureAlgorithm: signatureRSAPSSWithSHA384,
5858 })
5859
5860 testCases = append(testCases, testCase{
David Benjamin000800a2014-11-14 01:43:59 -05005861 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04005862 name: "ServerAuth-SignatureType",
David Benjamin000800a2014-11-14 01:43:59 -05005863 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005864 MaxVersion: VersionTLS12,
David Benjamin000800a2014-11-14 01:43:59 -05005865 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005866 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005867 signatureECDSAWithP521AndSHA512,
5868 signatureRSAPKCS1WithSHA384,
5869 signatureECDSAWithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05005870 },
5871 },
Nick Harper60edffd2016-06-21 15:19:24 -07005872 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA384,
David Benjamin000800a2014-11-14 01:43:59 -05005873 })
5874
Steven Valdez143e8b32016-07-11 13:19:03 -04005875 testCases = append(testCases, testCase{
5876 testType: serverTest,
5877 name: "ServerAuth-SignatureType-TLS13",
5878 config: Config{
5879 MaxVersion: VersionTLS13,
5880 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5881 VerifySignatureAlgorithms: []signatureAlgorithm{
5882 signatureECDSAWithP521AndSHA512,
5883 signatureRSAPKCS1WithSHA384,
5884 signatureRSAPSSWithSHA384,
5885 signatureECDSAWithSHA1,
5886 },
5887 },
5888 expectedPeerSignatureAlgorithm: signatureRSAPSSWithSHA384,
5889 })
5890
David Benjamina95e9f32016-07-08 16:28:04 -07005891 // Test that signature verification takes the key type into account.
David Benjamina95e9f32016-07-08 16:28:04 -07005892 testCases = append(testCases, testCase{
5893 testType: serverTest,
5894 name: "Verify-ClientAuth-SignatureType",
5895 config: Config{
5896 MaxVersion: VersionTLS12,
5897 Certificates: []Certificate{rsaCertificate},
David Benjamin7a41d372016-07-09 11:21:54 -07005898 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamina95e9f32016-07-08 16:28:04 -07005899 signatureRSAPKCS1WithSHA256,
5900 },
5901 Bugs: ProtocolBugs{
5902 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5903 },
5904 },
5905 flags: []string{
5906 "-require-any-client-certificate",
5907 },
5908 shouldFail: true,
5909 expectedError: ":WRONG_SIGNATURE_TYPE:",
5910 })
5911
5912 testCases = append(testCases, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04005913 testType: serverTest,
5914 name: "Verify-ClientAuth-SignatureType-TLS13",
5915 config: Config{
5916 MaxVersion: VersionTLS13,
5917 Certificates: []Certificate{rsaCertificate},
5918 SignSignatureAlgorithms: []signatureAlgorithm{
5919 signatureRSAPSSWithSHA256,
5920 },
5921 Bugs: ProtocolBugs{
5922 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5923 },
5924 },
5925 flags: []string{
5926 "-require-any-client-certificate",
5927 },
5928 shouldFail: true,
5929 expectedError: ":WRONG_SIGNATURE_TYPE:",
5930 })
5931
5932 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04005933 name: "Verify-ServerAuth-SignatureType",
David Benjamina95e9f32016-07-08 16:28:04 -07005934 config: Config{
5935 MaxVersion: VersionTLS12,
5936 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07005937 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamina95e9f32016-07-08 16:28:04 -07005938 signatureRSAPKCS1WithSHA256,
5939 },
5940 Bugs: ProtocolBugs{
5941 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5942 },
5943 },
5944 shouldFail: true,
5945 expectedError: ":WRONG_SIGNATURE_TYPE:",
5946 })
5947
Steven Valdez143e8b32016-07-11 13:19:03 -04005948 testCases = append(testCases, testCase{
5949 name: "Verify-ServerAuth-SignatureType-TLS13",
5950 config: Config{
5951 MaxVersion: VersionTLS13,
5952 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5953 SignSignatureAlgorithms: []signatureAlgorithm{
5954 signatureRSAPSSWithSHA256,
5955 },
5956 Bugs: ProtocolBugs{
5957 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
5958 },
5959 },
5960 shouldFail: true,
5961 expectedError: ":WRONG_SIGNATURE_TYPE:",
5962 })
5963
David Benjamin51dd7d62016-07-08 16:07:01 -07005964 // Test that, if the list is missing, the peer falls back to SHA-1 in
5965 // TLS 1.2, but not TLS 1.3.
David Benjamin000800a2014-11-14 01:43:59 -05005966 testCases = append(testCases, testCase{
David Benjaminee32bea2016-08-17 13:36:44 -04005967 name: "ClientAuth-SHA1-Fallback-RSA",
David Benjamin000800a2014-11-14 01:43:59 -05005968 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04005969 MaxVersion: VersionTLS12,
David Benjamin000800a2014-11-14 01:43:59 -05005970 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07005971 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005972 signatureRSAPKCS1WithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05005973 },
5974 Bugs: ProtocolBugs{
Nick Harper60edffd2016-06-21 15:19:24 -07005975 NoSignatureAlgorithms: true,
David Benjamin000800a2014-11-14 01:43:59 -05005976 },
5977 },
5978 flags: []string{
Adam Langley7c803a62015-06-15 15:35:05 -07005979 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5980 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjamin000800a2014-11-14 01:43:59 -05005981 },
5982 })
5983
5984 testCases = append(testCases, testCase{
5985 testType: serverTest,
David Benjaminee32bea2016-08-17 13:36:44 -04005986 name: "ServerAuth-SHA1-Fallback-RSA",
David Benjamin000800a2014-11-14 01:43:59 -05005987 config: Config{
David Benjaminee32bea2016-08-17 13:36:44 -04005988 MaxVersion: VersionTLS12,
David Benjamin7a41d372016-07-09 11:21:54 -07005989 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07005990 signatureRSAPKCS1WithSHA1,
David Benjamin000800a2014-11-14 01:43:59 -05005991 },
5992 Bugs: ProtocolBugs{
Nick Harper60edffd2016-06-21 15:19:24 -07005993 NoSignatureAlgorithms: true,
David Benjamin000800a2014-11-14 01:43:59 -05005994 },
5995 },
David Benjaminee32bea2016-08-17 13:36:44 -04005996 flags: []string{
5997 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5998 "-key-file", path.Join(*resourceDir, rsaKeyFile),
5999 },
6000 })
6001
6002 testCases = append(testCases, testCase{
6003 name: "ClientAuth-SHA1-Fallback-ECDSA",
6004 config: Config{
6005 MaxVersion: VersionTLS12,
6006 ClientAuth: RequireAnyClientCert,
6007 VerifySignatureAlgorithms: []signatureAlgorithm{
6008 signatureECDSAWithSHA1,
6009 },
6010 Bugs: ProtocolBugs{
6011 NoSignatureAlgorithms: true,
6012 },
6013 },
6014 flags: []string{
6015 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
6016 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
6017 },
6018 })
6019
6020 testCases = append(testCases, testCase{
6021 testType: serverTest,
6022 name: "ServerAuth-SHA1-Fallback-ECDSA",
6023 config: Config{
6024 MaxVersion: VersionTLS12,
6025 VerifySignatureAlgorithms: []signatureAlgorithm{
6026 signatureECDSAWithSHA1,
6027 },
6028 Bugs: ProtocolBugs{
6029 NoSignatureAlgorithms: true,
6030 },
6031 },
6032 flags: []string{
6033 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
6034 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
6035 },
David Benjamin000800a2014-11-14 01:43:59 -05006036 })
David Benjamin72dc7832015-03-16 17:49:43 -04006037
David Benjamin51dd7d62016-07-08 16:07:01 -07006038 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04006039 name: "ClientAuth-NoFallback-TLS13",
David Benjamin51dd7d62016-07-08 16:07:01 -07006040 config: Config{
6041 MaxVersion: VersionTLS13,
6042 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07006043 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin51dd7d62016-07-08 16:07:01 -07006044 signatureRSAPKCS1WithSHA1,
6045 },
6046 Bugs: ProtocolBugs{
6047 NoSignatureAlgorithms: true,
6048 },
6049 },
6050 flags: []string{
6051 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6052 "-key-file", path.Join(*resourceDir, rsaKeyFile),
6053 },
David Benjamin48901652016-08-01 12:12:47 -04006054 shouldFail: true,
6055 // An empty CertificateRequest signature algorithm list is a
6056 // syntax error in TLS 1.3.
6057 expectedError: ":DECODE_ERROR:",
6058 expectedLocalError: "remote error: error decoding message",
David Benjamin51dd7d62016-07-08 16:07:01 -07006059 })
6060
6061 testCases = append(testCases, testCase{
6062 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04006063 name: "ServerAuth-NoFallback-TLS13",
David Benjamin51dd7d62016-07-08 16:07:01 -07006064 config: Config{
6065 MaxVersion: VersionTLS13,
6066 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07006067 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin51dd7d62016-07-08 16:07:01 -07006068 signatureRSAPKCS1WithSHA1,
6069 },
6070 Bugs: ProtocolBugs{
6071 NoSignatureAlgorithms: true,
6072 },
6073 },
6074 shouldFail: true,
6075 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
6076 })
6077
David Benjaminb62d2872016-07-18 14:55:02 +02006078 // Test that hash preferences are enforced. BoringSSL does not implement
6079 // MD5 signatures.
David Benjamin72dc7832015-03-16 17:49:43 -04006080 testCases = append(testCases, testCase{
6081 testType: serverTest,
David Benjaminbbfff7c2016-07-13 21:08:33 -04006082 name: "ClientAuth-Enforced",
David Benjamin72dc7832015-03-16 17:49:43 -04006083 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006084 MaxVersion: VersionTLS12,
David Benjamin72dc7832015-03-16 17:49:43 -04006085 Certificates: []Certificate{rsaCertificate},
David Benjamin7a41d372016-07-09 11:21:54 -07006086 SignSignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07006087 signatureRSAPKCS1WithMD5,
David Benjamin72dc7832015-03-16 17:49:43 -04006088 },
6089 Bugs: ProtocolBugs{
6090 IgnorePeerSignatureAlgorithmPreferences: true,
6091 },
6092 },
6093 flags: []string{"-require-any-client-certificate"},
6094 shouldFail: true,
6095 expectedError: ":WRONG_SIGNATURE_TYPE:",
6096 })
6097
6098 testCases = append(testCases, testCase{
David Benjaminbbfff7c2016-07-13 21:08:33 -04006099 name: "ServerAuth-Enforced",
David Benjamin72dc7832015-03-16 17:49:43 -04006100 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006101 MaxVersion: VersionTLS12,
David Benjamin72dc7832015-03-16 17:49:43 -04006102 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07006103 SignSignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07006104 signatureRSAPKCS1WithMD5,
David Benjamin72dc7832015-03-16 17:49:43 -04006105 },
6106 Bugs: ProtocolBugs{
6107 IgnorePeerSignatureAlgorithmPreferences: true,
6108 },
6109 },
6110 shouldFail: true,
6111 expectedError: ":WRONG_SIGNATURE_TYPE:",
6112 })
David Benjaminb62d2872016-07-18 14:55:02 +02006113 testCases = append(testCases, testCase{
6114 testType: serverTest,
6115 name: "ClientAuth-Enforced-TLS13",
6116 config: Config{
6117 MaxVersion: VersionTLS13,
6118 Certificates: []Certificate{rsaCertificate},
6119 SignSignatureAlgorithms: []signatureAlgorithm{
6120 signatureRSAPKCS1WithMD5,
6121 },
6122 Bugs: ProtocolBugs{
6123 IgnorePeerSignatureAlgorithmPreferences: true,
6124 IgnoreSignatureVersionChecks: true,
6125 },
6126 },
6127 flags: []string{"-require-any-client-certificate"},
6128 shouldFail: true,
6129 expectedError: ":WRONG_SIGNATURE_TYPE:",
6130 })
6131
6132 testCases = append(testCases, testCase{
6133 name: "ServerAuth-Enforced-TLS13",
6134 config: Config{
6135 MaxVersion: VersionTLS13,
6136 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6137 SignSignatureAlgorithms: []signatureAlgorithm{
6138 signatureRSAPKCS1WithMD5,
6139 },
6140 Bugs: ProtocolBugs{
6141 IgnorePeerSignatureAlgorithmPreferences: true,
6142 IgnoreSignatureVersionChecks: true,
6143 },
6144 },
6145 shouldFail: true,
6146 expectedError: ":WRONG_SIGNATURE_TYPE:",
6147 })
Steven Valdez0d62f262015-09-04 12:41:04 -04006148
6149 // Test that the agreed upon digest respects the client preferences and
6150 // the server digests.
6151 testCases = append(testCases, testCase{
David Benjaminca3d5452016-07-14 12:51:01 -04006152 name: "NoCommonAlgorithms-Digests",
6153 config: Config{
6154 MaxVersion: VersionTLS12,
6155 ClientAuth: RequireAnyClientCert,
6156 VerifySignatureAlgorithms: []signatureAlgorithm{
6157 signatureRSAPKCS1WithSHA512,
6158 signatureRSAPKCS1WithSHA1,
6159 },
6160 },
6161 flags: []string{
6162 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6163 "-key-file", path.Join(*resourceDir, rsaKeyFile),
6164 "-digest-prefs", "SHA256",
6165 },
6166 shouldFail: true,
6167 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
6168 })
6169 testCases = append(testCases, testCase{
David Benjaminea9a0d52016-07-08 15:52:59 -07006170 name: "NoCommonAlgorithms",
Steven Valdez0d62f262015-09-04 12:41:04 -04006171 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006172 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04006173 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07006174 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07006175 signatureRSAPKCS1WithSHA512,
6176 signatureRSAPKCS1WithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04006177 },
6178 },
6179 flags: []string{
6180 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6181 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminca3d5452016-07-14 12:51:01 -04006182 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
Steven Valdez0d62f262015-09-04 12:41:04 -04006183 },
David Benjaminca3d5452016-07-14 12:51:01 -04006184 shouldFail: true,
6185 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
6186 })
6187 testCases = append(testCases, testCase{
6188 name: "NoCommonAlgorithms-TLS13",
6189 config: Config{
6190 MaxVersion: VersionTLS13,
6191 ClientAuth: RequireAnyClientCert,
6192 VerifySignatureAlgorithms: []signatureAlgorithm{
6193 signatureRSAPSSWithSHA512,
6194 signatureRSAPSSWithSHA384,
6195 },
6196 },
6197 flags: []string{
6198 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6199 "-key-file", path.Join(*resourceDir, rsaKeyFile),
6200 "-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)),
6201 },
David Benjaminea9a0d52016-07-08 15:52:59 -07006202 shouldFail: true,
6203 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
Steven Valdez0d62f262015-09-04 12:41:04 -04006204 })
6205 testCases = append(testCases, testCase{
6206 name: "Agree-Digest-SHA256",
6207 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006208 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04006209 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07006210 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07006211 signatureRSAPKCS1WithSHA1,
6212 signatureRSAPKCS1WithSHA256,
Steven Valdez0d62f262015-09-04 12:41:04 -04006213 },
6214 },
6215 flags: []string{
6216 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6217 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminca3d5452016-07-14 12:51:01 -04006218 "-digest-prefs", "SHA256,SHA1",
Steven Valdez0d62f262015-09-04 12:41:04 -04006219 },
Nick Harper60edffd2016-06-21 15:19:24 -07006220 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
Steven Valdez0d62f262015-09-04 12:41:04 -04006221 })
6222 testCases = append(testCases, testCase{
6223 name: "Agree-Digest-SHA1",
6224 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006225 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04006226 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07006227 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07006228 signatureRSAPKCS1WithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04006229 },
6230 },
6231 flags: []string{
6232 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6233 "-key-file", path.Join(*resourceDir, rsaKeyFile),
David Benjaminca3d5452016-07-14 12:51:01 -04006234 "-digest-prefs", "SHA512,SHA256,SHA1",
Steven Valdez0d62f262015-09-04 12:41:04 -04006235 },
Nick Harper60edffd2016-06-21 15:19:24 -07006236 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04006237 })
6238 testCases = append(testCases, testCase{
6239 name: "Agree-Digest-Default",
6240 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006241 MaxVersion: VersionTLS12,
Steven Valdez0d62f262015-09-04 12:41:04 -04006242 ClientAuth: RequireAnyClientCert,
David Benjamin7a41d372016-07-09 11:21:54 -07006243 VerifySignatureAlgorithms: []signatureAlgorithm{
Nick Harper60edffd2016-06-21 15:19:24 -07006244 signatureRSAPKCS1WithSHA256,
6245 signatureECDSAWithP256AndSHA256,
6246 signatureRSAPKCS1WithSHA1,
6247 signatureECDSAWithSHA1,
Steven Valdez0d62f262015-09-04 12:41:04 -04006248 },
6249 },
6250 flags: []string{
6251 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6252 "-key-file", path.Join(*resourceDir, rsaKeyFile),
6253 },
Nick Harper60edffd2016-06-21 15:19:24 -07006254 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
Steven Valdez0d62f262015-09-04 12:41:04 -04006255 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04006256
David Benjaminca3d5452016-07-14 12:51:01 -04006257 // Test that the signing preference list may include extra algorithms
6258 // without negotiation problems.
6259 testCases = append(testCases, testCase{
6260 testType: serverTest,
6261 name: "FilterExtraAlgorithms",
6262 config: Config{
6263 MaxVersion: VersionTLS12,
6264 VerifySignatureAlgorithms: []signatureAlgorithm{
6265 signatureRSAPKCS1WithSHA256,
6266 },
6267 },
6268 flags: []string{
6269 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
6270 "-key-file", path.Join(*resourceDir, rsaKeyFile),
6271 "-signing-prefs", strconv.Itoa(int(fakeSigAlg1)),
6272 "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)),
6273 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
6274 "-signing-prefs", strconv.Itoa(int(fakeSigAlg2)),
6275 },
6276 expectedPeerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
6277 })
6278
David Benjamin4c3ddf72016-06-29 18:13:53 -04006279 // In TLS 1.2 and below, ECDSA uses the curve list rather than the
6280 // signature algorithms.
David Benjamin4c3ddf72016-06-29 18:13:53 -04006281 testCases = append(testCases, testCase{
6282 name: "CheckLeafCurve",
6283 config: Config{
6284 MaxVersion: VersionTLS12,
6285 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin33863262016-07-08 17:20:12 -07006286 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamin4c3ddf72016-06-29 18:13:53 -04006287 },
6288 flags: []string{"-p384-only"},
6289 shouldFail: true,
6290 expectedError: ":BAD_ECC_CERT:",
6291 })
David Benjamin75ea5bb2016-07-08 17:43:29 -07006292
6293 // In TLS 1.3, ECDSA does not use the ECDHE curve list.
6294 testCases = append(testCases, testCase{
6295 name: "CheckLeafCurve-TLS13",
6296 config: Config{
6297 MaxVersion: VersionTLS13,
6298 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
6299 Certificates: []Certificate{ecdsaP256Certificate},
6300 },
6301 flags: []string{"-p384-only"},
6302 })
David Benjamin1fb125c2016-07-08 18:52:12 -07006303
6304 // In TLS 1.2, the ECDSA curve is not in the signature algorithm.
6305 testCases = append(testCases, testCase{
6306 name: "ECDSACurveMismatch-Verify-TLS12",
6307 config: Config{
6308 MaxVersion: VersionTLS12,
6309 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
6310 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamin7a41d372016-07-09 11:21:54 -07006311 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07006312 signatureECDSAWithP384AndSHA384,
6313 },
6314 },
6315 })
6316
6317 // In TLS 1.3, the ECDSA curve comes from the signature algorithm.
6318 testCases = append(testCases, testCase{
6319 name: "ECDSACurveMismatch-Verify-TLS13",
6320 config: Config{
6321 MaxVersion: VersionTLS13,
6322 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
6323 Certificates: []Certificate{ecdsaP256Certificate},
David Benjamin7a41d372016-07-09 11:21:54 -07006324 SignSignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07006325 signatureECDSAWithP384AndSHA384,
6326 },
6327 Bugs: ProtocolBugs{
6328 SkipECDSACurveCheck: true,
6329 },
6330 },
6331 shouldFail: true,
6332 expectedError: ":WRONG_SIGNATURE_TYPE:",
6333 })
6334
6335 // Signature algorithm selection in TLS 1.3 should take the curve into
6336 // account.
6337 testCases = append(testCases, testCase{
6338 testType: serverTest,
6339 name: "ECDSACurveMismatch-Sign-TLS13",
6340 config: Config{
6341 MaxVersion: VersionTLS13,
6342 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
David Benjamin7a41d372016-07-09 11:21:54 -07006343 VerifySignatureAlgorithms: []signatureAlgorithm{
David Benjamin1fb125c2016-07-08 18:52:12 -07006344 signatureECDSAWithP384AndSHA384,
6345 signatureECDSAWithP256AndSHA256,
6346 },
6347 },
6348 flags: []string{
6349 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
6350 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
6351 },
6352 expectedPeerSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
6353 })
David Benjamin7944a9f2016-07-12 22:27:01 -04006354
6355 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the
6356 // server does not attempt to sign in that case.
6357 testCases = append(testCases, testCase{
6358 testType: serverTest,
6359 name: "RSA-PSS-Large",
6360 config: Config{
6361 MaxVersion: VersionTLS13,
6362 VerifySignatureAlgorithms: []signatureAlgorithm{
6363 signatureRSAPSSWithSHA512,
6364 },
6365 },
6366 flags: []string{
6367 "-cert-file", path.Join(*resourceDir, rsa1024CertificateFile),
6368 "-key-file", path.Join(*resourceDir, rsa1024KeyFile),
6369 },
6370 shouldFail: true,
6371 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
6372 })
David Benjamin57e929f2016-08-30 00:30:38 -04006373
6374 // Test that RSA-PSS is enabled by default for TLS 1.2.
6375 testCases = append(testCases, testCase{
6376 testType: clientTest,
6377 name: "RSA-PSS-Default-Verify",
6378 config: Config{
6379 MaxVersion: VersionTLS12,
6380 SignSignatureAlgorithms: []signatureAlgorithm{
6381 signatureRSAPSSWithSHA256,
6382 },
6383 },
6384 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
6385 })
6386
6387 testCases = append(testCases, testCase{
6388 testType: serverTest,
6389 name: "RSA-PSS-Default-Sign",
6390 config: Config{
6391 MaxVersion: VersionTLS12,
6392 VerifySignatureAlgorithms: []signatureAlgorithm{
6393 signatureRSAPSSWithSHA256,
6394 },
6395 },
6396 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
6397 })
David Benjamin000800a2014-11-14 01:43:59 -05006398}
6399
David Benjamin83f90402015-01-27 01:09:43 -05006400// timeouts is the retransmit schedule for BoringSSL. It doubles and
6401// caps at 60 seconds. On the 13th timeout, it gives up.
6402var timeouts = []time.Duration{
6403 1 * time.Second,
6404 2 * time.Second,
6405 4 * time.Second,
6406 8 * time.Second,
6407 16 * time.Second,
6408 32 * time.Second,
6409 60 * time.Second,
6410 60 * time.Second,
6411 60 * time.Second,
6412 60 * time.Second,
6413 60 * time.Second,
6414 60 * time.Second,
6415 60 * time.Second,
6416}
6417
Taylor Brandstetter376a0fe2016-05-10 19:30:28 -07006418// shortTimeouts is an alternate set of timeouts which would occur if the
6419// initial timeout duration was set to 250ms.
6420var shortTimeouts = []time.Duration{
6421 250 * time.Millisecond,
6422 500 * time.Millisecond,
6423 1 * time.Second,
6424 2 * time.Second,
6425 4 * time.Second,
6426 8 * time.Second,
6427 16 * time.Second,
6428 32 * time.Second,
6429 60 * time.Second,
6430 60 * time.Second,
6431 60 * time.Second,
6432 60 * time.Second,
6433 60 * time.Second,
6434}
6435
David Benjamin83f90402015-01-27 01:09:43 -05006436func addDTLSRetransmitTests() {
David Benjamin585d7a42016-06-02 14:58:00 -04006437 // These tests work by coordinating some behavior on both the shim and
6438 // the runner.
6439 //
6440 // TimeoutSchedule configures the runner to send a series of timeout
6441 // opcodes to the shim (see packetAdaptor) immediately before reading
6442 // each peer handshake flight N. The timeout opcode both simulates a
6443 // timeout in the shim and acts as a synchronization point to help the
6444 // runner bracket each handshake flight.
6445 //
6446 // We assume the shim does not read from the channel eagerly. It must
6447 // first wait until it has sent flight N and is ready to receive
6448 // handshake flight N+1. At this point, it will process the timeout
6449 // opcode. It must then immediately respond with a timeout ACK and act
6450 // as if the shim was idle for the specified amount of time.
6451 //
6452 // The runner then drops all packets received before the ACK and
6453 // continues waiting for flight N. This ordering results in one attempt
6454 // at sending flight N to be dropped. For the test to complete, the
6455 // shim must send flight N again, testing that the shim implements DTLS
6456 // retransmit on a timeout.
6457
Steven Valdez143e8b32016-07-11 13:19:03 -04006458 // TODO(davidben): Add DTLS 1.3 versions of these tests. There will
David Benjamin4c3ddf72016-06-29 18:13:53 -04006459 // likely be more epochs to cross and the final message's retransmit may
6460 // be more complex.
6461
David Benjamin585d7a42016-06-02 14:58:00 -04006462 for _, async := range []bool{true, false} {
6463 var tests []testCase
6464
6465 // Test that this is indeed the timeout schedule. Stress all
6466 // four patterns of handshake.
6467 for i := 1; i < len(timeouts); i++ {
6468 number := strconv.Itoa(i)
6469 tests = append(tests, testCase{
6470 protocol: dtls,
6471 name: "DTLS-Retransmit-Client-" + number,
6472 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006473 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04006474 Bugs: ProtocolBugs{
6475 TimeoutSchedule: timeouts[:i],
6476 },
6477 },
6478 resumeSession: true,
6479 })
6480 tests = append(tests, testCase{
6481 protocol: dtls,
6482 testType: serverTest,
6483 name: "DTLS-Retransmit-Server-" + number,
6484 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006485 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04006486 Bugs: ProtocolBugs{
6487 TimeoutSchedule: timeouts[:i],
6488 },
6489 },
6490 resumeSession: true,
6491 })
6492 }
6493
6494 // Test that exceeding the timeout schedule hits a read
6495 // timeout.
6496 tests = append(tests, testCase{
David Benjamin83f90402015-01-27 01:09:43 -05006497 protocol: dtls,
David Benjamin585d7a42016-06-02 14:58:00 -04006498 name: "DTLS-Retransmit-Timeout",
David Benjamin83f90402015-01-27 01:09:43 -05006499 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006500 MaxVersion: VersionTLS12,
David Benjamin83f90402015-01-27 01:09:43 -05006501 Bugs: ProtocolBugs{
David Benjamin585d7a42016-06-02 14:58:00 -04006502 TimeoutSchedule: timeouts,
David Benjamin83f90402015-01-27 01:09:43 -05006503 },
6504 },
6505 resumeSession: true,
David Benjamin585d7a42016-06-02 14:58:00 -04006506 shouldFail: true,
6507 expectedError: ":READ_TIMEOUT_EXPIRED:",
David Benjamin83f90402015-01-27 01:09:43 -05006508 })
David Benjamin585d7a42016-06-02 14:58:00 -04006509
6510 if async {
6511 // Test that timeout handling has a fudge factor, due to API
6512 // problems.
6513 tests = append(tests, testCase{
6514 protocol: dtls,
6515 name: "DTLS-Retransmit-Fudge",
6516 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006517 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04006518 Bugs: ProtocolBugs{
6519 TimeoutSchedule: []time.Duration{
6520 timeouts[0] - 10*time.Millisecond,
6521 },
6522 },
6523 },
6524 resumeSession: true,
6525 })
6526 }
6527
6528 // Test that the final Finished retransmitting isn't
6529 // duplicated if the peer badly fragments everything.
6530 tests = append(tests, testCase{
6531 testType: serverTest,
6532 protocol: dtls,
6533 name: "DTLS-Retransmit-Fragmented",
6534 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006535 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04006536 Bugs: ProtocolBugs{
6537 TimeoutSchedule: []time.Duration{timeouts[0]},
6538 MaxHandshakeRecordLength: 2,
6539 },
6540 },
6541 })
6542
6543 // Test the timeout schedule when a shorter initial timeout duration is set.
6544 tests = append(tests, testCase{
6545 protocol: dtls,
6546 name: "DTLS-Retransmit-Short-Client",
6547 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006548 MaxVersion: VersionTLS12,
David Benjamin585d7a42016-06-02 14:58:00 -04006549 Bugs: ProtocolBugs{
6550 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
6551 },
6552 },
6553 resumeSession: true,
6554 flags: []string{"-initial-timeout-duration-ms", "250"},
6555 })
6556 tests = append(tests, testCase{
David Benjamin83f90402015-01-27 01:09:43 -05006557 protocol: dtls,
6558 testType: serverTest,
David Benjamin585d7a42016-06-02 14:58:00 -04006559 name: "DTLS-Retransmit-Short-Server",
David Benjamin83f90402015-01-27 01:09:43 -05006560 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006561 MaxVersion: VersionTLS12,
David Benjamin83f90402015-01-27 01:09:43 -05006562 Bugs: ProtocolBugs{
David Benjamin585d7a42016-06-02 14:58:00 -04006563 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
David Benjamin83f90402015-01-27 01:09:43 -05006564 },
6565 },
6566 resumeSession: true,
David Benjamin585d7a42016-06-02 14:58:00 -04006567 flags: []string{"-initial-timeout-duration-ms", "250"},
David Benjamin83f90402015-01-27 01:09:43 -05006568 })
David Benjamin585d7a42016-06-02 14:58:00 -04006569
6570 for _, test := range tests {
6571 if async {
6572 test.name += "-Async"
6573 test.flags = append(test.flags, "-async")
6574 }
6575
6576 testCases = append(testCases, test)
6577 }
David Benjamin83f90402015-01-27 01:09:43 -05006578 }
David Benjamin83f90402015-01-27 01:09:43 -05006579}
6580
David Benjaminc565ebb2015-04-03 04:06:36 -04006581func addExportKeyingMaterialTests() {
6582 for _, vers := range tlsVersions {
6583 if vers.version == VersionSSL30 {
6584 continue
6585 }
6586 testCases = append(testCases, testCase{
6587 name: "ExportKeyingMaterial-" + vers.name,
6588 config: Config{
6589 MaxVersion: vers.version,
6590 },
6591 exportKeyingMaterial: 1024,
6592 exportLabel: "label",
6593 exportContext: "context",
6594 useExportContext: true,
6595 })
6596 testCases = append(testCases, testCase{
6597 name: "ExportKeyingMaterial-NoContext-" + vers.name,
6598 config: Config{
6599 MaxVersion: vers.version,
6600 },
6601 exportKeyingMaterial: 1024,
6602 })
6603 testCases = append(testCases, testCase{
6604 name: "ExportKeyingMaterial-EmptyContext-" + vers.name,
6605 config: Config{
6606 MaxVersion: vers.version,
6607 },
6608 exportKeyingMaterial: 1024,
6609 useExportContext: true,
6610 })
6611 testCases = append(testCases, testCase{
6612 name: "ExportKeyingMaterial-Small-" + vers.name,
6613 config: Config{
6614 MaxVersion: vers.version,
6615 },
6616 exportKeyingMaterial: 1,
6617 exportLabel: "label",
6618 exportContext: "context",
6619 useExportContext: true,
6620 })
6621 }
6622 testCases = append(testCases, testCase{
6623 name: "ExportKeyingMaterial-SSL3",
6624 config: Config{
6625 MaxVersion: VersionSSL30,
6626 },
6627 exportKeyingMaterial: 1024,
6628 exportLabel: "label",
6629 exportContext: "context",
6630 useExportContext: true,
6631 shouldFail: true,
6632 expectedError: "failed to export keying material",
6633 })
6634}
6635
Adam Langleyaf0e32c2015-06-03 09:57:23 -07006636func addTLSUniqueTests() {
6637 for _, isClient := range []bool{false, true} {
6638 for _, isResumption := range []bool{false, true} {
6639 for _, hasEMS := range []bool{false, true} {
6640 var suffix string
6641 if isResumption {
6642 suffix = "Resume-"
6643 } else {
6644 suffix = "Full-"
6645 }
6646
6647 if hasEMS {
6648 suffix += "EMS-"
6649 } else {
6650 suffix += "NoEMS-"
6651 }
6652
6653 if isClient {
6654 suffix += "Client"
6655 } else {
6656 suffix += "Server"
6657 }
6658
6659 test := testCase{
6660 name: "TLSUnique-" + suffix,
6661 testTLSUnique: true,
6662 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006663 MaxVersion: VersionTLS12,
Adam Langleyaf0e32c2015-06-03 09:57:23 -07006664 Bugs: ProtocolBugs{
6665 NoExtendedMasterSecret: !hasEMS,
6666 },
6667 },
6668 }
6669
6670 if isResumption {
6671 test.resumeSession = true
6672 test.resumeConfig = &Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006673 MaxVersion: VersionTLS12,
Adam Langleyaf0e32c2015-06-03 09:57:23 -07006674 Bugs: ProtocolBugs{
6675 NoExtendedMasterSecret: !hasEMS,
6676 },
6677 }
6678 }
6679
6680 if isResumption && !hasEMS {
6681 test.shouldFail = true
6682 test.expectedError = "failed to get tls-unique"
6683 }
6684
6685 testCases = append(testCases, test)
6686 }
6687 }
6688 }
6689}
6690
Adam Langley09505632015-07-30 18:10:13 -07006691func addCustomExtensionTests() {
6692 expectedContents := "custom extension"
6693 emptyString := ""
6694
6695 for _, isClient := range []bool{false, true} {
6696 suffix := "Server"
6697 flag := "-enable-server-custom-extension"
6698 testType := serverTest
6699 if isClient {
6700 suffix = "Client"
6701 flag = "-enable-client-custom-extension"
6702 testType = clientTest
6703 }
6704
6705 testCases = append(testCases, testCase{
6706 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04006707 name: "CustomExtensions-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07006708 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006709 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04006710 Bugs: ProtocolBugs{
6711 CustomExtension: expectedContents,
Adam Langley09505632015-07-30 18:10:13 -07006712 ExpectedCustomExtension: &expectedContents,
6713 },
6714 },
6715 flags: []string{flag},
6716 })
Steven Valdez143e8b32016-07-11 13:19:03 -04006717 testCases = append(testCases, testCase{
6718 testType: testType,
6719 name: "CustomExtensions-" + suffix + "-TLS13",
6720 config: Config{
6721 MaxVersion: VersionTLS13,
6722 Bugs: ProtocolBugs{
6723 CustomExtension: expectedContents,
6724 ExpectedCustomExtension: &expectedContents,
6725 },
6726 },
6727 flags: []string{flag},
6728 })
Adam Langley09505632015-07-30 18:10:13 -07006729
6730 // If the parse callback fails, the handshake should also fail.
6731 testCases = append(testCases, testCase{
6732 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04006733 name: "CustomExtensions-ParseError-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07006734 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006735 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04006736 Bugs: ProtocolBugs{
6737 CustomExtension: expectedContents + "foo",
Adam Langley09505632015-07-30 18:10:13 -07006738 ExpectedCustomExtension: &expectedContents,
6739 },
6740 },
David Benjamin399e7c92015-07-30 23:01:27 -04006741 flags: []string{flag},
6742 shouldFail: true,
Adam Langley09505632015-07-30 18:10:13 -07006743 expectedError: ":CUSTOM_EXTENSION_ERROR:",
6744 })
Steven Valdez143e8b32016-07-11 13:19:03 -04006745 testCases = append(testCases, testCase{
6746 testType: testType,
6747 name: "CustomExtensions-ParseError-" + suffix + "-TLS13",
6748 config: Config{
6749 MaxVersion: VersionTLS13,
6750 Bugs: ProtocolBugs{
6751 CustomExtension: expectedContents + "foo",
6752 ExpectedCustomExtension: &expectedContents,
6753 },
6754 },
6755 flags: []string{flag},
6756 shouldFail: true,
6757 expectedError: ":CUSTOM_EXTENSION_ERROR:",
6758 })
Adam Langley09505632015-07-30 18:10:13 -07006759
6760 // If the add callback fails, the handshake should also fail.
6761 testCases = append(testCases, testCase{
6762 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04006763 name: "CustomExtensions-FailAdd-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07006764 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006765 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04006766 Bugs: ProtocolBugs{
6767 CustomExtension: expectedContents,
Adam Langley09505632015-07-30 18:10:13 -07006768 ExpectedCustomExtension: &expectedContents,
6769 },
6770 },
David Benjamin399e7c92015-07-30 23:01:27 -04006771 flags: []string{flag, "-custom-extension-fail-add"},
6772 shouldFail: true,
Adam Langley09505632015-07-30 18:10:13 -07006773 expectedError: ":CUSTOM_EXTENSION_ERROR:",
6774 })
Steven Valdez143e8b32016-07-11 13:19:03 -04006775 testCases = append(testCases, testCase{
6776 testType: testType,
6777 name: "CustomExtensions-FailAdd-" + suffix + "-TLS13",
6778 config: Config{
6779 MaxVersion: VersionTLS13,
6780 Bugs: ProtocolBugs{
6781 CustomExtension: expectedContents,
6782 ExpectedCustomExtension: &expectedContents,
6783 },
6784 },
6785 flags: []string{flag, "-custom-extension-fail-add"},
6786 shouldFail: true,
6787 expectedError: ":CUSTOM_EXTENSION_ERROR:",
6788 })
Adam Langley09505632015-07-30 18:10:13 -07006789
6790 // If the add callback returns zero, no extension should be
6791 // added.
6792 skipCustomExtension := expectedContents
6793 if isClient {
6794 // For the case where the client skips sending the
6795 // custom extension, the server must not “echo” it.
6796 skipCustomExtension = ""
6797 }
6798 testCases = append(testCases, testCase{
6799 testType: testType,
David Benjamin399e7c92015-07-30 23:01:27 -04006800 name: "CustomExtensions-Skip-" + suffix,
Adam Langley09505632015-07-30 18:10:13 -07006801 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006802 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04006803 Bugs: ProtocolBugs{
6804 CustomExtension: skipCustomExtension,
Adam Langley09505632015-07-30 18:10:13 -07006805 ExpectedCustomExtension: &emptyString,
6806 },
6807 },
6808 flags: []string{flag, "-custom-extension-skip"},
6809 })
Steven Valdez143e8b32016-07-11 13:19:03 -04006810 testCases = append(testCases, testCase{
6811 testType: testType,
6812 name: "CustomExtensions-Skip-" + suffix + "-TLS13",
6813 config: Config{
6814 MaxVersion: VersionTLS13,
6815 Bugs: ProtocolBugs{
6816 CustomExtension: skipCustomExtension,
6817 ExpectedCustomExtension: &emptyString,
6818 },
6819 },
6820 flags: []string{flag, "-custom-extension-skip"},
6821 })
Adam Langley09505632015-07-30 18:10:13 -07006822 }
6823
6824 // The custom extension add callback should not be called if the client
6825 // doesn't send the extension.
6826 testCases = append(testCases, testCase{
6827 testType: serverTest,
David Benjamin399e7c92015-07-30 23:01:27 -04006828 name: "CustomExtensions-NotCalled-Server",
Adam Langley09505632015-07-30 18:10:13 -07006829 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006830 MaxVersion: VersionTLS12,
David Benjamin399e7c92015-07-30 23:01:27 -04006831 Bugs: ProtocolBugs{
Adam Langley09505632015-07-30 18:10:13 -07006832 ExpectedCustomExtension: &emptyString,
6833 },
6834 },
6835 flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
6836 })
Adam Langley2deb9842015-08-07 11:15:37 -07006837
Steven Valdez143e8b32016-07-11 13:19:03 -04006838 testCases = append(testCases, testCase{
6839 testType: serverTest,
6840 name: "CustomExtensions-NotCalled-Server-TLS13",
6841 config: Config{
6842 MaxVersion: VersionTLS13,
6843 Bugs: ProtocolBugs{
6844 ExpectedCustomExtension: &emptyString,
6845 },
6846 },
6847 flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
6848 })
6849
Adam Langley2deb9842015-08-07 11:15:37 -07006850 // Test an unknown extension from the server.
6851 testCases = append(testCases, testCase{
6852 testType: clientTest,
6853 name: "UnknownExtension-Client",
6854 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006855 MaxVersion: VersionTLS12,
Adam Langley2deb9842015-08-07 11:15:37 -07006856 Bugs: ProtocolBugs{
6857 CustomExtension: expectedContents,
6858 },
6859 },
David Benjamin0c40a962016-08-01 12:05:50 -04006860 shouldFail: true,
6861 expectedError: ":UNEXPECTED_EXTENSION:",
6862 expectedLocalError: "remote error: unsupported extension",
Adam Langley2deb9842015-08-07 11:15:37 -07006863 })
Steven Valdez143e8b32016-07-11 13:19:03 -04006864 testCases = append(testCases, testCase{
6865 testType: clientTest,
6866 name: "UnknownExtension-Client-TLS13",
6867 config: Config{
6868 MaxVersion: VersionTLS13,
6869 Bugs: ProtocolBugs{
6870 CustomExtension: expectedContents,
6871 },
6872 },
David Benjamin0c40a962016-08-01 12:05:50 -04006873 shouldFail: true,
6874 expectedError: ":UNEXPECTED_EXTENSION:",
6875 expectedLocalError: "remote error: unsupported extension",
6876 })
6877
6878 // Test a known but unoffered extension from the server.
6879 testCases = append(testCases, testCase{
6880 testType: clientTest,
6881 name: "UnofferedExtension-Client",
6882 config: Config{
6883 MaxVersion: VersionTLS12,
6884 Bugs: ProtocolBugs{
6885 SendALPN: "alpn",
6886 },
6887 },
6888 shouldFail: true,
6889 expectedError: ":UNEXPECTED_EXTENSION:",
6890 expectedLocalError: "remote error: unsupported extension",
6891 })
6892 testCases = append(testCases, testCase{
6893 testType: clientTest,
6894 name: "UnofferedExtension-Client-TLS13",
6895 config: Config{
6896 MaxVersion: VersionTLS13,
6897 Bugs: ProtocolBugs{
6898 SendALPN: "alpn",
6899 },
6900 },
6901 shouldFail: true,
6902 expectedError: ":UNEXPECTED_EXTENSION:",
6903 expectedLocalError: "remote error: unsupported extension",
Steven Valdez143e8b32016-07-11 13:19:03 -04006904 })
Adam Langley09505632015-07-30 18:10:13 -07006905}
6906
David Benjaminb36a3952015-12-01 18:53:13 -05006907func addRSAClientKeyExchangeTests() {
6908 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ {
6909 testCases = append(testCases, testCase{
6910 testType: serverTest,
6911 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad),
6912 config: Config{
6913 // Ensure the ClientHello version and final
6914 // version are different, to detect if the
6915 // server uses the wrong one.
6916 MaxVersion: VersionTLS11,
Matt Braithwaite07e78062016-08-21 14:50:43 -07006917 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
David Benjaminb36a3952015-12-01 18:53:13 -05006918 Bugs: ProtocolBugs{
6919 BadRSAClientKeyExchange: bad,
6920 },
6921 },
6922 shouldFail: true,
6923 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
6924 })
6925 }
David Benjamine63d9d72016-09-19 18:27:34 -04006926
6927 // The server must compare whatever was in ClientHello.version for the
6928 // RSA premaster.
6929 testCases = append(testCases, testCase{
6930 testType: serverTest,
6931 name: "SendClientVersion-RSA",
6932 config: Config{
6933 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
6934 Bugs: ProtocolBugs{
6935 SendClientVersion: 0x1234,
6936 },
6937 },
6938 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
6939 })
David Benjaminb36a3952015-12-01 18:53:13 -05006940}
6941
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006942var testCurves = []struct {
6943 name string
6944 id CurveID
6945}{
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006946 {"P-256", CurveP256},
6947 {"P-384", CurveP384},
6948 {"P-521", CurveP521},
David Benjamin4298d772015-12-19 00:18:25 -05006949 {"X25519", CurveX25519},
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006950}
6951
Steven Valdez5440fe02016-07-18 12:40:30 -04006952const bogusCurve = 0x1234
6953
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006954func addCurveTests() {
6955 for _, curve := range testCurves {
6956 testCases = append(testCases, testCase{
6957 name: "CurveTest-Client-" + curve.name,
6958 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006959 MaxVersion: VersionTLS12,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006960 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6961 CurvePreferences: []CurveID{curve.id},
6962 },
David Benjamin5c4e8572016-08-19 17:44:53 -04006963 flags: []string{
6964 "-enable-all-curves",
6965 "-expect-curve-id", strconv.Itoa(int(curve.id)),
6966 },
Steven Valdez5440fe02016-07-18 12:40:30 -04006967 expectedCurveID: curve.id,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006968 })
6969 testCases = append(testCases, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04006970 name: "CurveTest-Client-" + curve.name + "-TLS13",
6971 config: Config{
6972 MaxVersion: VersionTLS13,
6973 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6974 CurvePreferences: []CurveID{curve.id},
6975 },
David Benjamin5c4e8572016-08-19 17:44:53 -04006976 flags: []string{
6977 "-enable-all-curves",
6978 "-expect-curve-id", strconv.Itoa(int(curve.id)),
6979 },
Steven Valdez5440fe02016-07-18 12:40:30 -04006980 expectedCurveID: curve.id,
Steven Valdez143e8b32016-07-11 13:19:03 -04006981 })
6982 testCases = append(testCases, testCase{
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006983 testType: serverTest,
6984 name: "CurveTest-Server-" + curve.name,
6985 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04006986 MaxVersion: VersionTLS12,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006987 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
6988 CurvePreferences: []CurveID{curve.id},
6989 },
David Benjamin5c4e8572016-08-19 17:44:53 -04006990 flags: []string{
6991 "-enable-all-curves",
6992 "-expect-curve-id", strconv.Itoa(int(curve.id)),
6993 },
Steven Valdez5440fe02016-07-18 12:40:30 -04006994 expectedCurveID: curve.id,
David Benjamin8c2b3bf2015-12-18 20:55:44 -05006995 })
Steven Valdez143e8b32016-07-11 13:19:03 -04006996 testCases = append(testCases, testCase{
6997 testType: serverTest,
6998 name: "CurveTest-Server-" + curve.name + "-TLS13",
6999 config: Config{
7000 MaxVersion: VersionTLS13,
7001 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7002 CurvePreferences: []CurveID{curve.id},
7003 },
David Benjamin5c4e8572016-08-19 17:44:53 -04007004 flags: []string{
7005 "-enable-all-curves",
7006 "-expect-curve-id", strconv.Itoa(int(curve.id)),
7007 },
Steven Valdez5440fe02016-07-18 12:40:30 -04007008 expectedCurveID: curve.id,
Steven Valdez143e8b32016-07-11 13:19:03 -04007009 })
David Benjamin8c2b3bf2015-12-18 20:55:44 -05007010 }
David Benjamin241ae832016-01-15 03:04:54 -05007011
7012 // The server must be tolerant to bogus curves.
David Benjamin241ae832016-01-15 03:04:54 -05007013 testCases = append(testCases, testCase{
7014 testType: serverTest,
7015 name: "UnknownCurve",
7016 config: Config{
7017 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7018 CurvePreferences: []CurveID{bogusCurve, CurveP256},
7019 },
7020 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04007021
7022 // The server must not consider ECDHE ciphers when there are no
7023 // supported curves.
7024 testCases = append(testCases, testCase{
7025 testType: serverTest,
7026 name: "NoSupportedCurves",
7027 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04007028 MaxVersion: VersionTLS12,
7029 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7030 Bugs: ProtocolBugs{
7031 NoSupportedCurves: true,
7032 },
7033 },
7034 shouldFail: true,
7035 expectedError: ":NO_SHARED_CIPHER:",
7036 })
Steven Valdez143e8b32016-07-11 13:19:03 -04007037 testCases = append(testCases, testCase{
7038 testType: serverTest,
7039 name: "NoSupportedCurves-TLS13",
7040 config: Config{
7041 MaxVersion: VersionTLS13,
7042 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7043 Bugs: ProtocolBugs{
7044 NoSupportedCurves: true,
7045 },
7046 },
7047 shouldFail: true,
7048 expectedError: ":NO_SHARED_CIPHER:",
7049 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04007050
7051 // The server must fall back to another cipher when there are no
7052 // supported curves.
7053 testCases = append(testCases, testCase{
7054 testType: serverTest,
7055 name: "NoCommonCurves",
7056 config: Config{
7057 MaxVersion: VersionTLS12,
7058 CipherSuites: []uint16{
7059 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
7060 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
7061 },
7062 CurvePreferences: []CurveID{CurveP224},
7063 },
7064 expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
7065 })
7066
7067 // The client must reject bogus curves and disabled curves.
7068 testCases = append(testCases, testCase{
7069 name: "BadECDHECurve",
7070 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04007071 MaxVersion: VersionTLS12,
7072 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7073 Bugs: ProtocolBugs{
7074 SendCurve: bogusCurve,
7075 },
7076 },
7077 shouldFail: true,
7078 expectedError: ":WRONG_CURVE:",
7079 })
Steven Valdez143e8b32016-07-11 13:19:03 -04007080 testCases = append(testCases, testCase{
7081 name: "BadECDHECurve-TLS13",
7082 config: Config{
7083 MaxVersion: VersionTLS13,
7084 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7085 Bugs: ProtocolBugs{
7086 SendCurve: bogusCurve,
7087 },
7088 },
7089 shouldFail: true,
7090 expectedError: ":WRONG_CURVE:",
7091 })
David Benjamin4c3ddf72016-06-29 18:13:53 -04007092
7093 testCases = append(testCases, testCase{
7094 name: "UnsupportedCurve",
7095 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04007096 MaxVersion: VersionTLS12,
7097 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7098 CurvePreferences: []CurveID{CurveP256},
7099 Bugs: ProtocolBugs{
7100 IgnorePeerCurvePreferences: true,
7101 },
7102 },
7103 flags: []string{"-p384-only"},
7104 shouldFail: true,
7105 expectedError: ":WRONG_CURVE:",
7106 })
7107
David Benjamin4f921572016-07-17 14:20:10 +02007108 testCases = append(testCases, testCase{
7109 // TODO(davidben): Add a TLS 1.3 version where
7110 // HelloRetryRequest requests an unsupported curve.
7111 name: "UnsupportedCurve-ServerHello-TLS13",
7112 config: Config{
7113 MaxVersion: VersionTLS12,
7114 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7115 CurvePreferences: []CurveID{CurveP384},
7116 Bugs: ProtocolBugs{
7117 SendCurve: CurveP256,
7118 },
7119 },
7120 flags: []string{"-p384-only"},
7121 shouldFail: true,
7122 expectedError: ":WRONG_CURVE:",
7123 })
7124
David Benjamin4c3ddf72016-06-29 18:13:53 -04007125 // Test invalid curve points.
7126 testCases = append(testCases, testCase{
7127 name: "InvalidECDHPoint-Client",
7128 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04007129 MaxVersion: VersionTLS12,
7130 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7131 CurvePreferences: []CurveID{CurveP256},
7132 Bugs: ProtocolBugs{
7133 InvalidECDHPoint: true,
7134 },
7135 },
7136 shouldFail: true,
7137 expectedError: ":INVALID_ENCODING:",
7138 })
7139 testCases = append(testCases, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04007140 name: "InvalidECDHPoint-Client-TLS13",
7141 config: Config{
7142 MaxVersion: VersionTLS13,
7143 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7144 CurvePreferences: []CurveID{CurveP256},
7145 Bugs: ProtocolBugs{
7146 InvalidECDHPoint: true,
7147 },
7148 },
7149 shouldFail: true,
7150 expectedError: ":INVALID_ENCODING:",
7151 })
7152 testCases = append(testCases, testCase{
David Benjamin4c3ddf72016-06-29 18:13:53 -04007153 testType: serverTest,
7154 name: "InvalidECDHPoint-Server",
7155 config: Config{
David Benjamin4c3ddf72016-06-29 18:13:53 -04007156 MaxVersion: VersionTLS12,
7157 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7158 CurvePreferences: []CurveID{CurveP256},
7159 Bugs: ProtocolBugs{
7160 InvalidECDHPoint: true,
7161 },
7162 },
7163 shouldFail: true,
7164 expectedError: ":INVALID_ENCODING:",
7165 })
Steven Valdez143e8b32016-07-11 13:19:03 -04007166 testCases = append(testCases, testCase{
7167 testType: serverTest,
7168 name: "InvalidECDHPoint-Server-TLS13",
7169 config: Config{
7170 MaxVersion: VersionTLS13,
7171 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
7172 CurvePreferences: []CurveID{CurveP256},
7173 Bugs: ProtocolBugs{
7174 InvalidECDHPoint: true,
7175 },
7176 },
7177 shouldFail: true,
7178 expectedError: ":INVALID_ENCODING:",
7179 })
David Benjamin8c2b3bf2015-12-18 20:55:44 -05007180}
7181
Matt Braithwaite54217e42016-06-13 13:03:47 -07007182func addCECPQ1Tests() {
7183 testCases = append(testCases, testCase{
7184 testType: clientTest,
7185 name: "CECPQ1-Client-BadX25519Part",
7186 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07007187 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07007188 MinVersion: VersionTLS12,
7189 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
7190 Bugs: ProtocolBugs{
7191 CECPQ1BadX25519Part: true,
7192 },
7193 },
7194 flags: []string{"-cipher", "kCECPQ1"},
7195 shouldFail: true,
7196 expectedLocalError: "local error: bad record MAC",
7197 })
7198 testCases = append(testCases, testCase{
7199 testType: clientTest,
7200 name: "CECPQ1-Client-BadNewhopePart",
7201 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07007202 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07007203 MinVersion: VersionTLS12,
7204 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
7205 Bugs: ProtocolBugs{
7206 CECPQ1BadNewhopePart: true,
7207 },
7208 },
7209 flags: []string{"-cipher", "kCECPQ1"},
7210 shouldFail: true,
7211 expectedLocalError: "local error: bad record MAC",
7212 })
7213 testCases = append(testCases, testCase{
7214 testType: serverTest,
7215 name: "CECPQ1-Server-BadX25519Part",
7216 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07007217 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07007218 MinVersion: VersionTLS12,
7219 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
7220 Bugs: ProtocolBugs{
7221 CECPQ1BadX25519Part: true,
7222 },
7223 },
7224 flags: []string{"-cipher", "kCECPQ1"},
7225 shouldFail: true,
7226 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
7227 })
7228 testCases = append(testCases, testCase{
7229 testType: serverTest,
7230 name: "CECPQ1-Server-BadNewhopePart",
7231 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07007232 MaxVersion: VersionTLS12,
Matt Braithwaite54217e42016-06-13 13:03:47 -07007233 MinVersion: VersionTLS12,
7234 CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384},
7235 Bugs: ProtocolBugs{
7236 CECPQ1BadNewhopePart: true,
7237 },
7238 },
7239 flags: []string{"-cipher", "kCECPQ1"},
7240 shouldFail: true,
7241 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
7242 })
7243}
7244
David Benjamin5c4e8572016-08-19 17:44:53 -04007245func addDHEGroupSizeTests() {
David Benjamin4cc36ad2015-12-19 14:23:26 -05007246 testCases = append(testCases, testCase{
David Benjamin5c4e8572016-08-19 17:44:53 -04007247 name: "DHEGroupSize-Client",
David Benjamin4cc36ad2015-12-19 14:23:26 -05007248 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07007249 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05007250 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
7251 Bugs: ProtocolBugs{
7252 // This is a 1234-bit prime number, generated
7253 // with:
7254 // openssl gendh 1234 | openssl asn1parse -i
7255 DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"),
7256 },
7257 },
David Benjamin9e68f192016-06-30 14:55:33 -04007258 flags: []string{"-expect-dhe-group-size", "1234"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05007259 })
7260 testCases = append(testCases, testCase{
7261 testType: serverTest,
David Benjamin5c4e8572016-08-19 17:44:53 -04007262 name: "DHEGroupSize-Server",
David Benjamin4cc36ad2015-12-19 14:23:26 -05007263 config: Config{
Nick Harper1fd39d82016-06-14 18:14:35 -07007264 MaxVersion: VersionTLS12,
David Benjamin4cc36ad2015-12-19 14:23:26 -05007265 CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
7266 },
7267 // bssl_shim as a server configures a 2048-bit DHE group.
David Benjamin9e68f192016-06-30 14:55:33 -04007268 flags: []string{"-expect-dhe-group-size", "2048"},
David Benjamin4cc36ad2015-12-19 14:23:26 -05007269 })
David Benjamin4cc36ad2015-12-19 14:23:26 -05007270}
7271
David Benjaminc9ae27c2016-06-24 22:56:37 -04007272func addTLS13RecordTests() {
7273 testCases = append(testCases, testCase{
7274 name: "TLS13-RecordPadding",
7275 config: Config{
7276 MaxVersion: VersionTLS13,
7277 MinVersion: VersionTLS13,
7278 Bugs: ProtocolBugs{
7279 RecordPadding: 10,
7280 },
7281 },
7282 })
7283
7284 testCases = append(testCases, testCase{
7285 name: "TLS13-EmptyRecords",
7286 config: Config{
7287 MaxVersion: VersionTLS13,
7288 MinVersion: VersionTLS13,
7289 Bugs: ProtocolBugs{
7290 OmitRecordContents: true,
7291 },
7292 },
7293 shouldFail: true,
7294 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
7295 })
7296
7297 testCases = append(testCases, testCase{
7298 name: "TLS13-OnlyPadding",
7299 config: Config{
7300 MaxVersion: VersionTLS13,
7301 MinVersion: VersionTLS13,
7302 Bugs: ProtocolBugs{
7303 OmitRecordContents: true,
7304 RecordPadding: 10,
7305 },
7306 },
7307 shouldFail: true,
7308 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
7309 })
7310
7311 testCases = append(testCases, testCase{
7312 name: "TLS13-WrongOuterRecord",
7313 config: Config{
7314 MaxVersion: VersionTLS13,
7315 MinVersion: VersionTLS13,
7316 Bugs: ProtocolBugs{
7317 OuterRecordType: recordTypeHandshake,
7318 },
7319 },
7320 shouldFail: true,
7321 expectedError: ":INVALID_OUTER_RECORD_TYPE:",
7322 })
7323}
7324
David Benjamin82261be2016-07-07 14:32:50 -07007325func addChangeCipherSpecTests() {
7326 // Test missing ChangeCipherSpecs.
7327 testCases = append(testCases, testCase{
7328 name: "SkipChangeCipherSpec-Client",
7329 config: Config{
7330 MaxVersion: VersionTLS12,
7331 Bugs: ProtocolBugs{
7332 SkipChangeCipherSpec: true,
7333 },
7334 },
7335 shouldFail: true,
7336 expectedError: ":UNEXPECTED_RECORD:",
7337 })
7338 testCases = append(testCases, testCase{
7339 testType: serverTest,
7340 name: "SkipChangeCipherSpec-Server",
7341 config: Config{
7342 MaxVersion: VersionTLS12,
7343 Bugs: ProtocolBugs{
7344 SkipChangeCipherSpec: true,
7345 },
7346 },
7347 shouldFail: true,
7348 expectedError: ":UNEXPECTED_RECORD:",
7349 })
7350 testCases = append(testCases, testCase{
7351 testType: serverTest,
7352 name: "SkipChangeCipherSpec-Server-NPN",
7353 config: Config{
7354 MaxVersion: VersionTLS12,
7355 NextProtos: []string{"bar"},
7356 Bugs: ProtocolBugs{
7357 SkipChangeCipherSpec: true,
7358 },
7359 },
7360 flags: []string{
7361 "-advertise-npn", "\x03foo\x03bar\x03baz",
7362 },
7363 shouldFail: true,
7364 expectedError: ":UNEXPECTED_RECORD:",
7365 })
7366
7367 // Test synchronization between the handshake and ChangeCipherSpec.
7368 // Partial post-CCS handshake messages before ChangeCipherSpec should be
7369 // rejected. Test both with and without handshake packing to handle both
7370 // when the partial post-CCS message is in its own record and when it is
7371 // attached to the pre-CCS message.
David Benjamin82261be2016-07-07 14:32:50 -07007372 for _, packed := range []bool{false, true} {
7373 var suffix string
7374 if packed {
7375 suffix = "-Packed"
7376 }
7377
7378 testCases = append(testCases, testCase{
7379 name: "FragmentAcrossChangeCipherSpec-Client" + suffix,
7380 config: Config{
7381 MaxVersion: VersionTLS12,
7382 Bugs: ProtocolBugs{
7383 FragmentAcrossChangeCipherSpec: true,
7384 PackHandshakeFlight: packed,
7385 },
7386 },
7387 shouldFail: true,
7388 expectedError: ":UNEXPECTED_RECORD:",
7389 })
7390 testCases = append(testCases, testCase{
7391 name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix,
7392 config: Config{
7393 MaxVersion: VersionTLS12,
7394 },
7395 resumeSession: true,
7396 resumeConfig: &Config{
7397 MaxVersion: VersionTLS12,
7398 Bugs: ProtocolBugs{
7399 FragmentAcrossChangeCipherSpec: true,
7400 PackHandshakeFlight: packed,
7401 },
7402 },
7403 shouldFail: true,
7404 expectedError: ":UNEXPECTED_RECORD:",
7405 })
7406 testCases = append(testCases, testCase{
7407 testType: serverTest,
7408 name: "FragmentAcrossChangeCipherSpec-Server" + suffix,
7409 config: Config{
7410 MaxVersion: VersionTLS12,
7411 Bugs: ProtocolBugs{
7412 FragmentAcrossChangeCipherSpec: true,
7413 PackHandshakeFlight: packed,
7414 },
7415 },
7416 shouldFail: true,
7417 expectedError: ":UNEXPECTED_RECORD:",
7418 })
7419 testCases = append(testCases, testCase{
7420 testType: serverTest,
7421 name: "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix,
7422 config: Config{
7423 MaxVersion: VersionTLS12,
7424 },
7425 resumeSession: true,
7426 resumeConfig: &Config{
7427 MaxVersion: VersionTLS12,
7428 Bugs: ProtocolBugs{
7429 FragmentAcrossChangeCipherSpec: true,
7430 PackHandshakeFlight: packed,
7431 },
7432 },
7433 shouldFail: true,
7434 expectedError: ":UNEXPECTED_RECORD:",
7435 })
7436 testCases = append(testCases, testCase{
7437 testType: serverTest,
7438 name: "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix,
7439 config: Config{
7440 MaxVersion: VersionTLS12,
7441 NextProtos: []string{"bar"},
7442 Bugs: ProtocolBugs{
7443 FragmentAcrossChangeCipherSpec: true,
7444 PackHandshakeFlight: packed,
7445 },
7446 },
7447 flags: []string{
7448 "-advertise-npn", "\x03foo\x03bar\x03baz",
7449 },
7450 shouldFail: true,
7451 expectedError: ":UNEXPECTED_RECORD:",
7452 })
7453 }
7454
David Benjamin61672812016-07-14 23:10:43 -04007455 // Test that, in DTLS, ChangeCipherSpec is not allowed when there are
7456 // messages in the handshake queue. Do this by testing the server
7457 // reading the client Finished, reversing the flight so Finished comes
7458 // first.
7459 testCases = append(testCases, testCase{
7460 protocol: dtls,
7461 testType: serverTest,
7462 name: "SendUnencryptedFinished-DTLS",
7463 config: Config{
7464 MaxVersion: VersionTLS12,
7465 Bugs: ProtocolBugs{
7466 SendUnencryptedFinished: true,
7467 ReverseHandshakeFragments: true,
7468 },
7469 },
7470 shouldFail: true,
7471 expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:",
7472 })
7473
Steven Valdez143e8b32016-07-11 13:19:03 -04007474 // Test synchronization between encryption changes and the handshake in
7475 // TLS 1.3, where ChangeCipherSpec is implicit.
7476 testCases = append(testCases, testCase{
7477 name: "PartialEncryptedExtensionsWithServerHello",
7478 config: Config{
7479 MaxVersion: VersionTLS13,
7480 Bugs: ProtocolBugs{
7481 PartialEncryptedExtensionsWithServerHello: true,
7482 },
7483 },
7484 shouldFail: true,
7485 expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:",
7486 })
7487 testCases = append(testCases, testCase{
7488 testType: serverTest,
7489 name: "PartialClientFinishedWithClientHello",
7490 config: Config{
7491 MaxVersion: VersionTLS13,
7492 Bugs: ProtocolBugs{
7493 PartialClientFinishedWithClientHello: true,
7494 },
7495 },
7496 shouldFail: true,
7497 expectedError: ":BUFFERED_MESSAGES_ON_CIPHER_CHANGE:",
7498 })
7499
David Benjamin82261be2016-07-07 14:32:50 -07007500 // Test that early ChangeCipherSpecs are handled correctly.
7501 testCases = append(testCases, testCase{
7502 testType: serverTest,
7503 name: "EarlyChangeCipherSpec-server-1",
7504 config: Config{
7505 MaxVersion: VersionTLS12,
7506 Bugs: ProtocolBugs{
7507 EarlyChangeCipherSpec: 1,
7508 },
7509 },
7510 shouldFail: true,
7511 expectedError: ":UNEXPECTED_RECORD:",
7512 })
7513 testCases = append(testCases, testCase{
7514 testType: serverTest,
7515 name: "EarlyChangeCipherSpec-server-2",
7516 config: Config{
7517 MaxVersion: VersionTLS12,
7518 Bugs: ProtocolBugs{
7519 EarlyChangeCipherSpec: 2,
7520 },
7521 },
7522 shouldFail: true,
7523 expectedError: ":UNEXPECTED_RECORD:",
7524 })
7525 testCases = append(testCases, testCase{
7526 protocol: dtls,
7527 name: "StrayChangeCipherSpec",
7528 config: Config{
7529 // TODO(davidben): Once DTLS 1.3 exists, test
7530 // that stray ChangeCipherSpec messages are
7531 // rejected.
7532 MaxVersion: VersionTLS12,
7533 Bugs: ProtocolBugs{
7534 StrayChangeCipherSpec: true,
7535 },
7536 },
7537 })
7538
7539 // Test that the contents of ChangeCipherSpec are checked.
7540 testCases = append(testCases, testCase{
7541 name: "BadChangeCipherSpec-1",
7542 config: Config{
7543 MaxVersion: VersionTLS12,
7544 Bugs: ProtocolBugs{
7545 BadChangeCipherSpec: []byte{2},
7546 },
7547 },
7548 shouldFail: true,
7549 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
7550 })
7551 testCases = append(testCases, testCase{
7552 name: "BadChangeCipherSpec-2",
7553 config: Config{
7554 MaxVersion: VersionTLS12,
7555 Bugs: ProtocolBugs{
7556 BadChangeCipherSpec: []byte{1, 1},
7557 },
7558 },
7559 shouldFail: true,
7560 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
7561 })
7562 testCases = append(testCases, testCase{
7563 protocol: dtls,
7564 name: "BadChangeCipherSpec-DTLS-1",
7565 config: Config{
7566 MaxVersion: VersionTLS12,
7567 Bugs: ProtocolBugs{
7568 BadChangeCipherSpec: []byte{2},
7569 },
7570 },
7571 shouldFail: true,
7572 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
7573 })
7574 testCases = append(testCases, testCase{
7575 protocol: dtls,
7576 name: "BadChangeCipherSpec-DTLS-2",
7577 config: Config{
7578 MaxVersion: VersionTLS12,
7579 Bugs: ProtocolBugs{
7580 BadChangeCipherSpec: []byte{1, 1},
7581 },
7582 },
7583 shouldFail: true,
7584 expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
7585 })
7586}
7587
David Benjamincd2c8062016-09-09 11:28:16 -04007588type perMessageTest struct {
7589 messageType uint8
7590 test testCase
7591}
7592
7593// makePerMessageTests returns a series of test templates which cover each
7594// message in the TLS handshake. These may be used with bugs like
7595// WrongMessageType to fully test a per-message bug.
7596func makePerMessageTests() []perMessageTest {
7597 var ret []perMessageTest
David Benjamin0b8d5da2016-07-15 00:39:56 -04007598 for _, protocol := range []protocol{tls, dtls} {
7599 var suffix string
7600 if protocol == dtls {
7601 suffix = "-DTLS"
7602 }
7603
David Benjamincd2c8062016-09-09 11:28:16 -04007604 ret = append(ret, perMessageTest{
7605 messageType: typeClientHello,
7606 test: testCase{
7607 protocol: protocol,
7608 testType: serverTest,
7609 name: "ClientHello" + suffix,
7610 config: Config{
7611 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007612 },
7613 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007614 })
7615
7616 if protocol == dtls {
David Benjamincd2c8062016-09-09 11:28:16 -04007617 ret = append(ret, perMessageTest{
7618 messageType: typeHelloVerifyRequest,
7619 test: testCase{
7620 protocol: protocol,
7621 name: "HelloVerifyRequest" + suffix,
7622 config: Config{
7623 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007624 },
7625 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007626 })
7627 }
7628
David Benjamincd2c8062016-09-09 11:28:16 -04007629 ret = append(ret, perMessageTest{
7630 messageType: typeServerHello,
7631 test: testCase{
7632 protocol: protocol,
7633 name: "ServerHello" + suffix,
7634 config: Config{
7635 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007636 },
7637 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007638 })
7639
David Benjamincd2c8062016-09-09 11:28:16 -04007640 ret = append(ret, perMessageTest{
7641 messageType: typeCertificate,
7642 test: testCase{
7643 protocol: protocol,
7644 name: "ServerCertificate" + suffix,
7645 config: Config{
7646 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007647 },
7648 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007649 })
7650
David Benjamincd2c8062016-09-09 11:28:16 -04007651 ret = append(ret, perMessageTest{
7652 messageType: typeCertificateStatus,
7653 test: testCase{
7654 protocol: protocol,
7655 name: "CertificateStatus" + suffix,
7656 config: Config{
7657 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007658 },
David Benjamincd2c8062016-09-09 11:28:16 -04007659 flags: []string{"-enable-ocsp-stapling"},
David Benjamin0b8d5da2016-07-15 00:39:56 -04007660 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007661 })
7662
David Benjamincd2c8062016-09-09 11:28:16 -04007663 ret = append(ret, perMessageTest{
7664 messageType: typeServerKeyExchange,
7665 test: testCase{
7666 protocol: protocol,
7667 name: "ServerKeyExchange" + suffix,
7668 config: Config{
7669 MaxVersion: VersionTLS12,
7670 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
David Benjamin0b8d5da2016-07-15 00:39:56 -04007671 },
7672 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007673 })
7674
David Benjamincd2c8062016-09-09 11:28:16 -04007675 ret = append(ret, perMessageTest{
7676 messageType: typeCertificateRequest,
7677 test: testCase{
7678 protocol: protocol,
7679 name: "CertificateRequest" + suffix,
7680 config: Config{
7681 MaxVersion: VersionTLS12,
7682 ClientAuth: RequireAnyClientCert,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007683 },
7684 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007685 })
7686
David Benjamincd2c8062016-09-09 11:28:16 -04007687 ret = append(ret, perMessageTest{
7688 messageType: typeServerHelloDone,
7689 test: testCase{
7690 protocol: protocol,
7691 name: "ServerHelloDone" + suffix,
7692 config: Config{
7693 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007694 },
7695 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007696 })
7697
David Benjamincd2c8062016-09-09 11:28:16 -04007698 ret = append(ret, perMessageTest{
7699 messageType: typeCertificate,
7700 test: testCase{
7701 testType: serverTest,
7702 protocol: protocol,
7703 name: "ClientCertificate" + suffix,
7704 config: Config{
7705 Certificates: []Certificate{rsaCertificate},
7706 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007707 },
David Benjamincd2c8062016-09-09 11:28:16 -04007708 flags: []string{"-require-any-client-certificate"},
David Benjamin0b8d5da2016-07-15 00:39:56 -04007709 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007710 })
7711
David Benjamincd2c8062016-09-09 11:28:16 -04007712 ret = append(ret, perMessageTest{
7713 messageType: typeCertificateVerify,
7714 test: testCase{
7715 testType: serverTest,
7716 protocol: protocol,
7717 name: "CertificateVerify" + suffix,
7718 config: Config{
7719 Certificates: []Certificate{rsaCertificate},
7720 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007721 },
David Benjamincd2c8062016-09-09 11:28:16 -04007722 flags: []string{"-require-any-client-certificate"},
David Benjamin0b8d5da2016-07-15 00:39:56 -04007723 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007724 })
7725
David Benjamincd2c8062016-09-09 11:28:16 -04007726 ret = append(ret, perMessageTest{
7727 messageType: typeClientKeyExchange,
7728 test: testCase{
7729 testType: serverTest,
7730 protocol: protocol,
7731 name: "ClientKeyExchange" + suffix,
7732 config: Config{
7733 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007734 },
7735 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007736 })
7737
7738 if protocol != dtls {
David Benjamincd2c8062016-09-09 11:28:16 -04007739 ret = append(ret, perMessageTest{
7740 messageType: typeNextProtocol,
7741 test: testCase{
7742 testType: serverTest,
7743 protocol: protocol,
7744 name: "NextProtocol" + suffix,
7745 config: Config{
7746 MaxVersion: VersionTLS12,
7747 NextProtos: []string{"bar"},
David Benjamin0b8d5da2016-07-15 00:39:56 -04007748 },
David Benjamincd2c8062016-09-09 11:28:16 -04007749 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"},
David Benjamin0b8d5da2016-07-15 00:39:56 -04007750 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007751 })
7752
David Benjamincd2c8062016-09-09 11:28:16 -04007753 ret = append(ret, perMessageTest{
7754 messageType: typeChannelID,
7755 test: testCase{
7756 testType: serverTest,
7757 protocol: protocol,
7758 name: "ChannelID" + suffix,
7759 config: Config{
7760 MaxVersion: VersionTLS12,
7761 ChannelID: channelIDKey,
7762 },
7763 flags: []string{
7764 "-expect-channel-id",
7765 base64.StdEncoding.EncodeToString(channelIDBytes),
David Benjamin0b8d5da2016-07-15 00:39:56 -04007766 },
7767 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007768 })
7769 }
7770
David Benjamincd2c8062016-09-09 11:28:16 -04007771 ret = append(ret, perMessageTest{
7772 messageType: typeFinished,
7773 test: testCase{
7774 testType: serverTest,
7775 protocol: protocol,
7776 name: "ClientFinished" + suffix,
7777 config: Config{
7778 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007779 },
7780 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007781 })
7782
David Benjamincd2c8062016-09-09 11:28:16 -04007783 ret = append(ret, perMessageTest{
7784 messageType: typeNewSessionTicket,
7785 test: testCase{
7786 protocol: protocol,
7787 name: "NewSessionTicket" + suffix,
7788 config: Config{
7789 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007790 },
7791 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007792 })
7793
David Benjamincd2c8062016-09-09 11:28:16 -04007794 ret = append(ret, perMessageTest{
7795 messageType: typeFinished,
7796 test: testCase{
7797 protocol: protocol,
7798 name: "ServerFinished" + suffix,
7799 config: Config{
7800 MaxVersion: VersionTLS12,
David Benjamin0b8d5da2016-07-15 00:39:56 -04007801 },
7802 },
David Benjamin0b8d5da2016-07-15 00:39:56 -04007803 })
7804
7805 }
David Benjamincd2c8062016-09-09 11:28:16 -04007806
7807 ret = append(ret, perMessageTest{
7808 messageType: typeClientHello,
7809 test: testCase{
7810 testType: serverTest,
7811 name: "TLS13-ClientHello",
7812 config: Config{
7813 MaxVersion: VersionTLS13,
7814 },
7815 },
7816 })
7817
7818 ret = append(ret, perMessageTest{
7819 messageType: typeServerHello,
7820 test: testCase{
7821 name: "TLS13-ServerHello",
7822 config: Config{
7823 MaxVersion: VersionTLS13,
7824 },
7825 },
7826 })
7827
7828 ret = append(ret, perMessageTest{
7829 messageType: typeEncryptedExtensions,
7830 test: testCase{
7831 name: "TLS13-EncryptedExtensions",
7832 config: Config{
7833 MaxVersion: VersionTLS13,
7834 },
7835 },
7836 })
7837
7838 ret = append(ret, perMessageTest{
7839 messageType: typeCertificateRequest,
7840 test: testCase{
7841 name: "TLS13-CertificateRequest",
7842 config: Config{
7843 MaxVersion: VersionTLS13,
7844 ClientAuth: RequireAnyClientCert,
7845 },
7846 },
7847 })
7848
7849 ret = append(ret, perMessageTest{
7850 messageType: typeCertificate,
7851 test: testCase{
7852 name: "TLS13-ServerCertificate",
7853 config: Config{
7854 MaxVersion: VersionTLS13,
7855 },
7856 },
7857 })
7858
7859 ret = append(ret, perMessageTest{
7860 messageType: typeCertificateVerify,
7861 test: testCase{
7862 name: "TLS13-ServerCertificateVerify",
7863 config: Config{
7864 MaxVersion: VersionTLS13,
7865 },
7866 },
7867 })
7868
7869 ret = append(ret, perMessageTest{
7870 messageType: typeFinished,
7871 test: testCase{
7872 name: "TLS13-ServerFinished",
7873 config: Config{
7874 MaxVersion: VersionTLS13,
7875 },
7876 },
7877 })
7878
7879 ret = append(ret, perMessageTest{
7880 messageType: typeCertificate,
7881 test: testCase{
7882 testType: serverTest,
7883 name: "TLS13-ClientCertificate",
7884 config: Config{
7885 Certificates: []Certificate{rsaCertificate},
7886 MaxVersion: VersionTLS13,
7887 },
7888 flags: []string{"-require-any-client-certificate"},
7889 },
7890 })
7891
7892 ret = append(ret, perMessageTest{
7893 messageType: typeCertificateVerify,
7894 test: testCase{
7895 testType: serverTest,
7896 name: "TLS13-ClientCertificateVerify",
7897 config: Config{
7898 Certificates: []Certificate{rsaCertificate},
7899 MaxVersion: VersionTLS13,
7900 },
7901 flags: []string{"-require-any-client-certificate"},
7902 },
7903 })
7904
7905 ret = append(ret, perMessageTest{
7906 messageType: typeFinished,
7907 test: testCase{
7908 testType: serverTest,
7909 name: "TLS13-ClientFinished",
7910 config: Config{
7911 MaxVersion: VersionTLS13,
7912 },
7913 },
7914 })
7915
7916 return ret
David Benjamin0b8d5da2016-07-15 00:39:56 -04007917}
7918
David Benjamincd2c8062016-09-09 11:28:16 -04007919func addWrongMessageTypeTests() {
7920 for _, t := range makePerMessageTests() {
7921 t.test.name = "WrongMessageType-" + t.test.name
7922 t.test.config.Bugs.SendWrongMessageType = t.messageType
7923 t.test.shouldFail = true
7924 t.test.expectedError = ":UNEXPECTED_MESSAGE:"
7925 t.test.expectedLocalError = "remote error: unexpected message"
Steven Valdez143e8b32016-07-11 13:19:03 -04007926
David Benjamincd2c8062016-09-09 11:28:16 -04007927 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello {
7928 // In TLS 1.3, a bad ServerHello means the client sends
7929 // an unencrypted alert while the server expects
7930 // encryption, so the alert is not readable by runner.
7931 t.test.expectedLocalError = "local error: bad record MAC"
7932 }
Steven Valdez143e8b32016-07-11 13:19:03 -04007933
David Benjamincd2c8062016-09-09 11:28:16 -04007934 testCases = append(testCases, t.test)
7935 }
Steven Valdez143e8b32016-07-11 13:19:03 -04007936}
7937
David Benjamin639846e2016-09-09 11:41:18 -04007938func addTrailingMessageDataTests() {
7939 for _, t := range makePerMessageTests() {
7940 t.test.name = "TrailingMessageData-" + t.test.name
7941 t.test.config.Bugs.SendTrailingMessageData = t.messageType
7942 t.test.shouldFail = true
7943 t.test.expectedError = ":DECODE_ERROR:"
7944 t.test.expectedLocalError = "remote error: error decoding message"
7945
7946 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello {
7947 // In TLS 1.3, a bad ServerHello means the client sends
7948 // an unencrypted alert while the server expects
7949 // encryption, so the alert is not readable by runner.
7950 t.test.expectedLocalError = "local error: bad record MAC"
7951 }
7952
7953 if t.messageType == typeFinished {
7954 // Bad Finished messages read as the verify data having
7955 // the wrong length.
7956 t.test.expectedError = ":DIGEST_CHECK_FAILED:"
7957 t.test.expectedLocalError = "remote error: error decrypting message"
7958 }
7959
7960 testCases = append(testCases, t.test)
7961 }
7962}
7963
Steven Valdez143e8b32016-07-11 13:19:03 -04007964func addTLS13HandshakeTests() {
7965 testCases = append(testCases, testCase{
7966 testType: clientTest,
7967 name: "MissingKeyShare-Client",
7968 config: Config{
7969 MaxVersion: VersionTLS13,
7970 Bugs: ProtocolBugs{
7971 MissingKeyShare: true,
7972 },
7973 },
7974 shouldFail: true,
7975 expectedError: ":MISSING_KEY_SHARE:",
7976 })
7977
7978 testCases = append(testCases, testCase{
Steven Valdez5440fe02016-07-18 12:40:30 -04007979 testType: serverTest,
7980 name: "MissingKeyShare-Server",
Steven Valdez143e8b32016-07-11 13:19:03 -04007981 config: Config{
7982 MaxVersion: VersionTLS13,
7983 Bugs: ProtocolBugs{
7984 MissingKeyShare: true,
7985 },
7986 },
7987 shouldFail: true,
7988 expectedError: ":MISSING_KEY_SHARE:",
7989 })
7990
7991 testCases = append(testCases, testCase{
Steven Valdez143e8b32016-07-11 13:19:03 -04007992 testType: serverTest,
7993 name: "DuplicateKeyShares",
7994 config: Config{
7995 MaxVersion: VersionTLS13,
7996 Bugs: ProtocolBugs{
7997 DuplicateKeyShares: true,
7998 },
7999 },
David Benjamin7e1f9842016-09-20 19:24:40 -04008000 shouldFail: true,
8001 expectedError: ":DUPLICATE_KEY_SHARE:",
Steven Valdez143e8b32016-07-11 13:19:03 -04008002 })
8003
8004 testCases = append(testCases, testCase{
8005 testType: clientTest,
8006 name: "EmptyEncryptedExtensions",
8007 config: Config{
8008 MaxVersion: VersionTLS13,
8009 Bugs: ProtocolBugs{
8010 EmptyEncryptedExtensions: true,
8011 },
8012 },
8013 shouldFail: true,
8014 expectedLocalError: "remote error: error decoding message",
8015 })
8016
8017 testCases = append(testCases, testCase{
8018 testType: clientTest,
8019 name: "EncryptedExtensionsWithKeyShare",
8020 config: Config{
8021 MaxVersion: VersionTLS13,
8022 Bugs: ProtocolBugs{
8023 EncryptedExtensionsWithKeyShare: true,
8024 },
8025 },
8026 shouldFail: true,
8027 expectedLocalError: "remote error: unsupported extension",
8028 })
Steven Valdez5440fe02016-07-18 12:40:30 -04008029
8030 testCases = append(testCases, testCase{
8031 testType: serverTest,
8032 name: "SendHelloRetryRequest",
8033 config: Config{
8034 MaxVersion: VersionTLS13,
8035 // Require a HelloRetryRequest for every curve.
8036 DefaultCurves: []CurveID{},
8037 },
8038 expectedCurveID: CurveX25519,
8039 })
8040
8041 testCases = append(testCases, testCase{
8042 testType: serverTest,
8043 name: "SendHelloRetryRequest-2",
8044 config: Config{
8045 MaxVersion: VersionTLS13,
8046 DefaultCurves: []CurveID{CurveP384},
8047 },
8048 // Although the ClientHello did not predict our preferred curve,
8049 // we always select it whether it is predicted or not.
8050 expectedCurveID: CurveX25519,
8051 })
8052
8053 testCases = append(testCases, testCase{
8054 name: "UnknownCurve-HelloRetryRequest",
8055 config: Config{
8056 MaxVersion: VersionTLS13,
8057 // P-384 requires HelloRetryRequest in BoringSSL.
8058 CurvePreferences: []CurveID{CurveP384},
8059 Bugs: ProtocolBugs{
8060 SendHelloRetryRequestCurve: bogusCurve,
8061 },
8062 },
8063 shouldFail: true,
8064 expectedError: ":WRONG_CURVE:",
8065 })
8066
8067 testCases = append(testCases, testCase{
8068 name: "DisabledCurve-HelloRetryRequest",
8069 config: Config{
8070 MaxVersion: VersionTLS13,
8071 CurvePreferences: []CurveID{CurveP256},
8072 Bugs: ProtocolBugs{
8073 IgnorePeerCurvePreferences: true,
8074 },
8075 },
8076 flags: []string{"-p384-only"},
8077 shouldFail: true,
8078 expectedError: ":WRONG_CURVE:",
8079 })
8080
8081 testCases = append(testCases, testCase{
8082 name: "UnnecessaryHelloRetryRequest",
8083 config: Config{
8084 MaxVersion: VersionTLS13,
8085 Bugs: ProtocolBugs{
8086 UnnecessaryHelloRetryRequest: true,
8087 },
8088 },
8089 shouldFail: true,
8090 expectedError: ":WRONG_CURVE:",
8091 })
8092
8093 testCases = append(testCases, testCase{
8094 name: "SecondHelloRetryRequest",
8095 config: Config{
8096 MaxVersion: VersionTLS13,
8097 // P-384 requires HelloRetryRequest in BoringSSL.
8098 CurvePreferences: []CurveID{CurveP384},
8099 Bugs: ProtocolBugs{
8100 SecondHelloRetryRequest: true,
8101 },
8102 },
8103 shouldFail: true,
8104 expectedError: ":UNEXPECTED_MESSAGE:",
8105 })
8106
8107 testCases = append(testCases, testCase{
8108 testType: serverTest,
8109 name: "SecondClientHelloMissingKeyShare",
8110 config: Config{
8111 MaxVersion: VersionTLS13,
8112 DefaultCurves: []CurveID{},
8113 Bugs: ProtocolBugs{
8114 SecondClientHelloMissingKeyShare: true,
8115 },
8116 },
8117 shouldFail: true,
8118 expectedError: ":MISSING_KEY_SHARE:",
8119 })
8120
8121 testCases = append(testCases, testCase{
8122 testType: serverTest,
8123 name: "SecondClientHelloWrongCurve",
8124 config: Config{
8125 MaxVersion: VersionTLS13,
8126 DefaultCurves: []CurveID{},
8127 Bugs: ProtocolBugs{
8128 MisinterpretHelloRetryRequestCurve: CurveP521,
8129 },
8130 },
8131 shouldFail: true,
8132 expectedError: ":WRONG_CURVE:",
8133 })
8134
8135 testCases = append(testCases, testCase{
8136 name: "HelloRetryRequestVersionMismatch",
8137 config: Config{
8138 MaxVersion: VersionTLS13,
8139 // P-384 requires HelloRetryRequest in BoringSSL.
8140 CurvePreferences: []CurveID{CurveP384},
8141 Bugs: ProtocolBugs{
8142 SendServerHelloVersion: 0x0305,
8143 },
8144 },
8145 shouldFail: true,
8146 expectedError: ":WRONG_VERSION_NUMBER:",
8147 })
8148
8149 testCases = append(testCases, testCase{
8150 name: "HelloRetryRequestCurveMismatch",
8151 config: Config{
8152 MaxVersion: VersionTLS13,
8153 // P-384 requires HelloRetryRequest in BoringSSL.
8154 CurvePreferences: []CurveID{CurveP384},
8155 Bugs: ProtocolBugs{
8156 // Send P-384 (correct) in the HelloRetryRequest.
8157 SendHelloRetryRequestCurve: CurveP384,
8158 // But send P-256 in the ServerHello.
8159 SendCurve: CurveP256,
8160 },
8161 },
8162 shouldFail: true,
8163 expectedError: ":WRONG_CURVE:",
8164 })
8165
8166 // Test the server selecting a curve that requires a HelloRetryRequest
8167 // without sending it.
8168 testCases = append(testCases, testCase{
8169 name: "SkipHelloRetryRequest",
8170 config: Config{
8171 MaxVersion: VersionTLS13,
8172 // P-384 requires HelloRetryRequest in BoringSSL.
8173 CurvePreferences: []CurveID{CurveP384},
8174 Bugs: ProtocolBugs{
8175 SkipHelloRetryRequest: true,
8176 },
8177 },
8178 shouldFail: true,
8179 expectedError: ":WRONG_CURVE:",
8180 })
David Benjamin8a8349b2016-08-18 02:32:23 -04008181
8182 testCases = append(testCases, testCase{
8183 name: "TLS13-RequestContextInHandshake",
8184 config: Config{
8185 MaxVersion: VersionTLS13,
8186 MinVersion: VersionTLS13,
8187 ClientAuth: RequireAnyClientCert,
8188 Bugs: ProtocolBugs{
8189 SendRequestContext: []byte("request context"),
8190 },
8191 },
8192 flags: []string{
8193 "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
8194 "-key-file", path.Join(*resourceDir, rsaKeyFile),
8195 },
8196 shouldFail: true,
8197 expectedError: ":DECODE_ERROR:",
8198 })
David Benjamin7e1f9842016-09-20 19:24:40 -04008199
8200 testCases = append(testCases, testCase{
8201 testType: serverTest,
8202 name: "TLS13-TrailingKeyShareData",
8203 config: Config{
8204 MaxVersion: VersionTLS13,
8205 Bugs: ProtocolBugs{
8206 TrailingKeyShareData: true,
8207 },
8208 },
8209 shouldFail: true,
8210 expectedError: ":DECODE_ERROR:",
8211 })
Steven Valdez143e8b32016-07-11 13:19:03 -04008212}
8213
David Benjaminf3fbade2016-09-19 13:08:16 -04008214func addPeekTests() {
8215 // Test SSL_peek works, including on empty records.
8216 testCases = append(testCases, testCase{
8217 name: "Peek-Basic",
8218 sendEmptyRecords: 1,
8219 flags: []string{"-peek-then-read"},
8220 })
8221
8222 // Test SSL_peek can drive the initial handshake.
8223 testCases = append(testCases, testCase{
8224 name: "Peek-ImplicitHandshake",
8225 flags: []string{
8226 "-peek-then-read",
8227 "-implicit-handshake",
8228 },
8229 })
8230
8231 // Test SSL_peek can discover and drive a renegotiation.
8232 testCases = append(testCases, testCase{
8233 name: "Peek-Renegotiate",
8234 config: Config{
8235 MaxVersion: VersionTLS12,
8236 },
8237 renegotiate: 1,
8238 flags: []string{
8239 "-peek-then-read",
8240 "-renegotiate-freely",
8241 "-expect-total-renegotiations", "1",
8242 },
8243 })
8244
8245 // Test SSL_peek can discover a close_notify.
8246 testCases = append(testCases, testCase{
8247 name: "Peek-Shutdown",
8248 config: Config{
8249 Bugs: ProtocolBugs{
8250 ExpectCloseNotify: true,
8251 },
8252 },
8253 flags: []string{
8254 "-peek-then-read",
8255 "-check-close-notify",
8256 },
8257 })
8258
8259 // Test SSL_peek can discover an alert.
8260 testCases = append(testCases, testCase{
8261 name: "Peek-Alert",
8262 config: Config{
8263 Bugs: ProtocolBugs{
8264 SendSpuriousAlert: alertRecordOverflow,
8265 },
8266 },
8267 flags: []string{"-peek-then-read"},
8268 shouldFail: true,
8269 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
8270 })
8271
8272 // Test SSL_peek can handle KeyUpdate.
8273 testCases = append(testCases, testCase{
8274 name: "Peek-KeyUpdate",
8275 config: Config{
8276 MaxVersion: VersionTLS13,
8277 Bugs: ProtocolBugs{
8278 SendKeyUpdateBeforeEveryAppDataRecord: true,
8279 },
8280 },
8281 flags: []string{"-peek-then-read"},
8282 })
8283}
8284
Adam Langley7c803a62015-06-15 15:35:05 -07008285func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
Adam Langley95c29f32014-06-20 12:00:00 -07008286 defer wg.Done()
8287
8288 for test := range c {
Adam Langley69a01602014-11-17 17:26:55 -08008289 var err error
8290
8291 if *mallocTest < 0 {
8292 statusChan <- statusMsg{test: test, started: true}
Adam Langley7c803a62015-06-15 15:35:05 -07008293 err = runTest(test, shimPath, -1)
Adam Langley69a01602014-11-17 17:26:55 -08008294 } else {
8295 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
8296 statusChan <- statusMsg{test: test, started: true}
Adam Langley7c803a62015-06-15 15:35:05 -07008297 if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
Adam Langley69a01602014-11-17 17:26:55 -08008298 if err != nil {
8299 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
8300 }
8301 break
8302 }
8303 }
8304 }
Adam Langley95c29f32014-06-20 12:00:00 -07008305 statusChan <- statusMsg{test: test, err: err}
8306 }
8307}
8308
8309type statusMsg struct {
8310 test *testCase
8311 started bool
8312 err error
8313}
8314
David Benjamin5f237bc2015-02-11 17:14:15 -05008315func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total int) {
EKR842ae6c2016-07-27 09:22:05 +02008316 var started, done, failed, unimplemented, lineLen int
Adam Langley95c29f32014-06-20 12:00:00 -07008317
David Benjamin5f237bc2015-02-11 17:14:15 -05008318 testOutput := newTestOutput()
Adam Langley95c29f32014-06-20 12:00:00 -07008319 for msg := range statusChan {
David Benjamin5f237bc2015-02-11 17:14:15 -05008320 if !*pipe {
8321 // Erase the previous status line.
David Benjamin87c8a642015-02-21 01:54:29 -05008322 var erase string
8323 for i := 0; i < lineLen; i++ {
8324 erase += "\b \b"
8325 }
8326 fmt.Print(erase)
David Benjamin5f237bc2015-02-11 17:14:15 -05008327 }
8328
Adam Langley95c29f32014-06-20 12:00:00 -07008329 if msg.started {
8330 started++
8331 } else {
8332 done++
David Benjamin5f237bc2015-02-11 17:14:15 -05008333
8334 if msg.err != nil {
EKR842ae6c2016-07-27 09:22:05 +02008335 if msg.err == errUnimplemented {
8336 if *pipe {
8337 // Print each test instead of a status line.
8338 fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name)
8339 }
8340 unimplemented++
8341 testOutput.addResult(msg.test.name, "UNIMPLEMENTED")
8342 } else {
8343 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
8344 failed++
8345 testOutput.addResult(msg.test.name, "FAIL")
8346 }
David Benjamin5f237bc2015-02-11 17:14:15 -05008347 } else {
8348 if *pipe {
8349 // Print each test instead of a status line.
8350 fmt.Printf("PASSED (%s)\n", msg.test.name)
8351 }
8352 testOutput.addResult(msg.test.name, "PASS")
8353 }
Adam Langley95c29f32014-06-20 12:00:00 -07008354 }
8355
David Benjamin5f237bc2015-02-11 17:14:15 -05008356 if !*pipe {
8357 // Print a new status line.
EKR842ae6c2016-07-27 09:22:05 +02008358 line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total)
David Benjamin5f237bc2015-02-11 17:14:15 -05008359 lineLen = len(line)
8360 os.Stdout.WriteString(line)
Adam Langley95c29f32014-06-20 12:00:00 -07008361 }
Adam Langley95c29f32014-06-20 12:00:00 -07008362 }
David Benjamin5f237bc2015-02-11 17:14:15 -05008363
8364 doneChan <- testOutput
Adam Langley95c29f32014-06-20 12:00:00 -07008365}
8366
8367func main() {
Adam Langley95c29f32014-06-20 12:00:00 -07008368 flag.Parse()
Adam Langley7c803a62015-06-15 15:35:05 -07008369 *resourceDir = path.Clean(*resourceDir)
David Benjamin33863262016-07-08 17:20:12 -07008370 initCertificates()
Adam Langley95c29f32014-06-20 12:00:00 -07008371
Adam Langley7c803a62015-06-15 15:35:05 -07008372 addBasicTests()
Adam Langley95c29f32014-06-20 12:00:00 -07008373 addCipherSuiteTests()
8374 addBadECDSASignatureTests()
Adam Langley80842bd2014-06-20 12:00:00 -07008375 addCBCPaddingTests()
Kenny Root7fdeaf12014-08-05 15:23:37 -07008376 addCBCSplittingTests()
David Benjamin636293b2014-07-08 17:59:18 -04008377 addClientAuthTests()
Adam Langley524e7172015-02-20 16:04:00 -08008378 addDDoSCallbackTests()
David Benjamin7e2e6cf2014-08-07 17:44:24 -04008379 addVersionNegotiationTests()
David Benjaminaccb4542014-12-12 23:44:33 -05008380 addMinimumVersionTests()
David Benjamine78bfde2014-09-06 12:45:15 -04008381 addExtensionTests()
David Benjamin01fe8202014-09-24 15:21:44 -04008382 addResumptionVersionTests()
Adam Langley75712922014-10-10 16:23:43 -07008383 addExtendedMasterSecretTests()
Adam Langley2ae77d22014-10-28 17:29:33 -07008384 addRenegotiationTests()
David Benjamin5e961c12014-11-07 01:48:35 -05008385 addDTLSReplayTests()
Nick Harper60edffd2016-06-21 15:19:24 -07008386 addSignatureAlgorithmTests()
David Benjamin83f90402015-01-27 01:09:43 -05008387 addDTLSRetransmitTests()
David Benjaminc565ebb2015-04-03 04:06:36 -04008388 addExportKeyingMaterialTests()
Adam Langleyaf0e32c2015-06-03 09:57:23 -07008389 addTLSUniqueTests()
Adam Langley09505632015-07-30 18:10:13 -07008390 addCustomExtensionTests()
David Benjaminb36a3952015-12-01 18:53:13 -05008391 addRSAClientKeyExchangeTests()
David Benjamin8c2b3bf2015-12-18 20:55:44 -05008392 addCurveTests()
Matt Braithwaite54217e42016-06-13 13:03:47 -07008393 addCECPQ1Tests()
David Benjamin5c4e8572016-08-19 17:44:53 -04008394 addDHEGroupSizeTests()
David Benjaminc9ae27c2016-06-24 22:56:37 -04008395 addTLS13RecordTests()
David Benjamin582ba042016-07-07 12:33:25 -07008396 addAllStateMachineCoverageTests()
David Benjamin82261be2016-07-07 14:32:50 -07008397 addChangeCipherSpecTests()
David Benjamin0b8d5da2016-07-15 00:39:56 -04008398 addWrongMessageTypeTests()
David Benjamin639846e2016-09-09 11:41:18 -04008399 addTrailingMessageDataTests()
Steven Valdez143e8b32016-07-11 13:19:03 -04008400 addTLS13HandshakeTests()
David Benjaminf3fbade2016-09-19 13:08:16 -04008401 addPeekTests()
Adam Langley95c29f32014-06-20 12:00:00 -07008402
8403 var wg sync.WaitGroup
8404
Adam Langley7c803a62015-06-15 15:35:05 -07008405 statusChan := make(chan statusMsg, *numWorkers)
8406 testChan := make(chan *testCase, *numWorkers)
David Benjamin5f237bc2015-02-11 17:14:15 -05008407 doneChan := make(chan *testOutput)
Adam Langley95c29f32014-06-20 12:00:00 -07008408
EKRf71d7ed2016-08-06 13:25:12 -07008409 if len(*shimConfigFile) != 0 {
8410 encoded, err := ioutil.ReadFile(*shimConfigFile)
8411 if err != nil {
8412 fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err)
8413 os.Exit(1)
8414 }
8415
8416 if err := json.Unmarshal(encoded, &shimConfig); err != nil {
8417 fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err)
8418 os.Exit(1)
8419 }
8420 }
8421
David Benjamin025b3d32014-07-01 19:53:04 -04008422 go statusPrinter(doneChan, statusChan, len(testCases))
Adam Langley95c29f32014-06-20 12:00:00 -07008423
Adam Langley7c803a62015-06-15 15:35:05 -07008424 for i := 0; i < *numWorkers; i++ {
Adam Langley95c29f32014-06-20 12:00:00 -07008425 wg.Add(1)
Adam Langley7c803a62015-06-15 15:35:05 -07008426 go worker(statusChan, testChan, *shimPath, &wg)
Adam Langley95c29f32014-06-20 12:00:00 -07008427 }
8428
David Benjamin270f0a72016-03-17 14:41:36 -04008429 var foundTest bool
David Benjamin025b3d32014-07-01 19:53:04 -04008430 for i := range testCases {
David Benjamin17e12922016-07-28 18:04:43 -04008431 matched := true
8432 if len(*testToRun) != 0 {
8433 var err error
8434 matched, err = filepath.Match(*testToRun, testCases[i].name)
8435 if err != nil {
8436 fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err)
8437 os.Exit(1)
8438 }
8439 }
8440
EKRf71d7ed2016-08-06 13:25:12 -07008441 if !*includeDisabled {
8442 for pattern := range shimConfig.DisabledTests {
8443 isDisabled, err := filepath.Match(pattern, testCases[i].name)
8444 if err != nil {
8445 fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err)
8446 os.Exit(1)
8447 }
8448
8449 if isDisabled {
8450 matched = false
8451 break
8452 }
8453 }
8454 }
8455
David Benjamin17e12922016-07-28 18:04:43 -04008456 if matched {
David Benjamin270f0a72016-03-17 14:41:36 -04008457 foundTest = true
David Benjamin025b3d32014-07-01 19:53:04 -04008458 testChan <- &testCases[i]
Adam Langley95c29f32014-06-20 12:00:00 -07008459 }
8460 }
David Benjamin17e12922016-07-28 18:04:43 -04008461
David Benjamin270f0a72016-03-17 14:41:36 -04008462 if !foundTest {
EKRf71d7ed2016-08-06 13:25:12 -07008463 fmt.Fprintf(os.Stderr, "No tests run\n")
David Benjamin270f0a72016-03-17 14:41:36 -04008464 os.Exit(1)
8465 }
Adam Langley95c29f32014-06-20 12:00:00 -07008466
8467 close(testChan)
8468 wg.Wait()
8469 close(statusChan)
David Benjamin5f237bc2015-02-11 17:14:15 -05008470 testOutput := <-doneChan
Adam Langley95c29f32014-06-20 12:00:00 -07008471
8472 fmt.Printf("\n")
David Benjamin5f237bc2015-02-11 17:14:15 -05008473
8474 if *jsonOutput != "" {
8475 if err := testOutput.writeTo(*jsonOutput); err != nil {
8476 fmt.Fprintf(os.Stderr, "Error: %s\n", err)
8477 }
8478 }
David Benjamin2ab7a862015-04-04 17:02:18 -04008479
EKR842ae6c2016-07-27 09:22:05 +02008480 if !*allowUnimplemented && testOutput.NumFailuresByType["UNIMPLEMENTED"] > 0 {
8481 os.Exit(1)
8482 }
8483
8484 if !testOutput.noneFailed {
David Benjamin2ab7a862015-04-04 17:02:18 -04008485 os.Exit(1)
8486 }
Adam Langley95c29f32014-06-20 12:00:00 -07008487}