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