1
2
3
4
5
6
7 package quic
8
9 import (
10 "crypto/tls"
11 "crypto/x509"
12 "errors"
13 "testing"
14 "time"
15 )
16
17
18 func (tc *testConn) handshake() {
19 tc.t.Helper()
20 if *testVV {
21 *testVV = false
22 defer func() {
23 tc.t.Helper()
24 *testVV = true
25 tc.t.Logf("performed connection handshake")
26 }()
27 }
28 defer func(saved map[byte]bool) {
29 tc.ignoreFrames = saved
30 }(tc.ignoreFrames)
31 tc.ignoreFrames = nil
32 t := tc.t
33 dgrams := handshakeDatagrams(tc)
34 i := 0
35 for {
36 if i == len(dgrams)-1 {
37 if tc.conn.side == clientSide {
38 want := tc.endpoint.now.Add(maxAckDelay - timerGranularity)
39 if !tc.timer.Equal(want) {
40 t.Fatalf("want timer = %v (max_ack_delay), got %v", want, tc.timer)
41 }
42 if got := tc.readDatagram(); got != nil {
43 t.Fatalf("client unexpectedly sent: %v", got)
44 }
45 }
46 tc.advance(maxAckDelay)
47 }
48
49
50
51 got := tc.readDatagram()
52 var want *testDatagram
53 if !(tc.conn.side == serverSide && i == 0) && i < len(dgrams) {
54 want = dgrams[i]
55 fillCryptoFrames(want, tc.cryptoDataOut)
56 i++
57 }
58 if !datagramEqual(got, want) {
59 t.Fatalf("dgram %v:\ngot %v\n\nwant %v", i, got, want)
60 }
61 if i >= len(dgrams) {
62 break
63 }
64
65 fillCryptoFrames(dgrams[i], tc.cryptoDataIn)
66 tc.write(dgrams[i])
67 i++
68 }
69 }
70
71 func handshakeDatagrams(tc *testConn) (dgrams []*testDatagram) {
72 var (
73 clientConnIDs [][]byte
74 serverConnIDs [][]byte
75 clientResetToken statelessResetToken
76 serverResetToken statelessResetToken
77 transientConnID []byte
78 )
79 localConnIDs := [][]byte{
80 testLocalConnID(0),
81 testLocalConnID(1),
82 }
83 peerConnIDs := [][]byte{
84 testPeerConnID(0),
85 testPeerConnID(1),
86 }
87 localResetToken := tc.endpoint.e.resetGen.tokenForConnID(localConnIDs[1])
88 peerResetToken := testPeerStatelessResetToken(1)
89 if tc.conn.side == clientSide {
90 clientConnIDs = localConnIDs
91 serverConnIDs = peerConnIDs
92 clientResetToken = localResetToken
93 serverResetToken = peerResetToken
94 transientConnID = testLocalConnID(-1)
95 } else {
96 clientConnIDs = peerConnIDs
97 serverConnIDs = localConnIDs
98 clientResetToken = peerResetToken
99 serverResetToken = localResetToken
100 transientConnID = testPeerConnID(-1)
101 }
102 return []*testDatagram{{
103
104 packets: []*testPacket{{
105 ptype: packetTypeInitial,
106 num: 0,
107 version: quicVersion1,
108 srcConnID: clientConnIDs[0],
109 dstConnID: transientConnID,
110 frames: []debugFrame{
111 debugFrameCrypto{},
112 },
113 }},
114 paddedSize: 1200,
115 }, {
116
117 packets: []*testPacket{{
118 ptype: packetTypeInitial,
119 num: 0,
120 version: quicVersion1,
121 srcConnID: serverConnIDs[0],
122 dstConnID: clientConnIDs[0],
123 frames: []debugFrame{
124 debugFrameAck{
125 ranges: []i64range[packetNumber]{{0, 1}},
126 },
127 debugFrameCrypto{},
128 },
129 }, {
130 ptype: packetTypeHandshake,
131 num: 0,
132 version: quicVersion1,
133 srcConnID: serverConnIDs[0],
134 dstConnID: clientConnIDs[0],
135 frames: []debugFrame{
136 debugFrameCrypto{},
137 },
138 }, {
139 ptype: packetType1RTT,
140 num: 0,
141 dstConnID: clientConnIDs[0],
142 frames: []debugFrame{
143 debugFrameNewConnectionID{
144 seq: 1,
145 connID: serverConnIDs[1],
146 token: serverResetToken,
147 },
148 },
149 }},
150 paddedSize: 1200,
151 }, {
152
153 packets: []*testPacket{{
154 ptype: packetTypeInitial,
155 num: 1,
156 version: quicVersion1,
157 srcConnID: clientConnIDs[0],
158 dstConnID: serverConnIDs[0],
159 frames: []debugFrame{
160 debugFrameAck{
161 ranges: []i64range[packetNumber]{{0, 1}},
162 },
163 },
164 }, {
165 ptype: packetTypeHandshake,
166 num: 0,
167 version: quicVersion1,
168 srcConnID: clientConnIDs[0],
169 dstConnID: serverConnIDs[0],
170 frames: []debugFrame{
171 debugFrameAck{
172 ranges: []i64range[packetNumber]{{0, 1}},
173 },
174 debugFrameCrypto{},
175 },
176 }, {
177 ptype: packetType1RTT,
178 num: 0,
179 dstConnID: serverConnIDs[0],
180 frames: []debugFrame{
181 debugFrameAck{
182 ranges: []i64range[packetNumber]{{0, 1}},
183 },
184 debugFrameNewConnectionID{
185 seq: 1,
186 connID: clientConnIDs[1],
187 token: clientResetToken,
188 },
189 },
190 }},
191 paddedSize: 1200,
192 }, {
193
194 packets: []*testPacket{{
195 ptype: packetType1RTT,
196 num: 1,
197 dstConnID: clientConnIDs[0],
198 frames: []debugFrame{
199 debugFrameAck{
200 ranges: []i64range[packetNumber]{{0, 1}},
201 },
202 debugFrameHandshakeDone{},
203 },
204 }},
205 }, {
206
207 packets: []*testPacket{{
208 ptype: packetType1RTT,
209 num: 1,
210 dstConnID: serverConnIDs[0],
211 frames: []debugFrame{
212 debugFrameAck{
213 ackDelay: unscaledAckDelayFromDuration(
214 maxAckDelay, ackDelayExponent),
215 ranges: []i64range[packetNumber]{{0, 2}},
216 },
217 },
218 }},
219 }}
220 }
221
222 func fillCryptoFrames(d *testDatagram, data map[tls.QUICEncryptionLevel][]byte) {
223 for _, p := range d.packets {
224 var level tls.QUICEncryptionLevel
225 switch p.ptype {
226 case packetTypeInitial:
227 level = tls.QUICEncryptionLevelInitial
228 case packetTypeHandshake:
229 level = tls.QUICEncryptionLevelHandshake
230 case packetType1RTT:
231 level = tls.QUICEncryptionLevelApplication
232 default:
233 continue
234 }
235 for i := range p.frames {
236 c, ok := p.frames[i].(debugFrameCrypto)
237 if !ok {
238 continue
239 }
240 c.data = data[level]
241 data[level] = nil
242 p.frames[i] = c
243 }
244 }
245 }
246
247
248
249
250
251
252
253
254
255 func (tc *testConn) uncheckedHandshake() {
256 tc.t.Helper()
257 defer func(saved map[byte]bool) {
258 tc.ignoreFrames = saved
259 }(tc.ignoreFrames)
260 tc.ignoreFrames = map[byte]bool{
261 frameTypeAck: true,
262 frameTypeCrypto: true,
263 frameTypeNewConnectionID: true,
264 }
265 if tc.conn.side == serverSide {
266 tc.writeFrames(packetTypeInitial,
267 debugFrameCrypto{
268 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
269 })
270 tc.writeFrames(packetTypeHandshake,
271 debugFrameCrypto{
272 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
273 })
274 tc.wantFrame("send HANDSHAKE_DONE after handshake completes",
275 packetType1RTT, debugFrameHandshakeDone{})
276 tc.writeFrames(packetType1RTT,
277 debugFrameAck{
278 ackDelay: unscaledAckDelayFromDuration(
279 maxAckDelay, ackDelayExponent),
280 ranges: []i64range[packetNumber]{{0, tc.lastPacket.num + 1}},
281 })
282 } else {
283 tc.wantIdle("initial frames are ignored")
284 tc.writeFrames(packetTypeInitial,
285 debugFrameCrypto{
286 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
287 })
288 tc.writeFrames(packetTypeHandshake,
289 debugFrameCrypto{
290 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
291 })
292 tc.wantIdle("don't expect any frames we aren't ignoring")
293
294
295
296 tc.ignoreFrames = nil
297 tc.writeFrames(packetType1RTT,
298 debugFrameHandshakeDone{})
299 tc.writeFrames(packetType1RTT,
300 debugFrameCrypto{
301 data: tc.cryptoDataIn[tls.QUICEncryptionLevelApplication],
302 })
303 tc.wantFrame("client ACKs server's first 1-RTT packet",
304 packetType1RTT, debugFrameAck{
305 ranges: []i64range[packetNumber]{{0, 2}},
306 })
307
308 }
309 tc.wantIdle("handshake is done")
310 }
311
312 func TestConnClientHandshake(t *testing.T) {
313 tc := newTestConn(t, clientSide)
314 tc.handshake()
315 tc.advance(1 * time.Second)
316 tc.wantIdle("no packets should be sent by an idle conn after the handshake")
317 }
318
319 func TestConnServerHandshake(t *testing.T) {
320 tc := newTestConn(t, serverSide)
321 tc.handshake()
322 tc.advance(1 * time.Second)
323 tc.wantIdle("no packets should be sent by an idle conn after the handshake")
324 }
325
326 func TestConnKeysDiscardedClient(t *testing.T) {
327 tc := newTestConn(t, clientSide)
328 tc.ignoreFrame(frameTypeAck)
329
330 tc.wantFrame("client sends Initial CRYPTO frame",
331 packetTypeInitial, debugFrameCrypto{
332 data: tc.cryptoDataOut[tls.QUICEncryptionLevelInitial],
333 })
334 tc.writeFrames(packetTypeInitial,
335 debugFrameCrypto{
336 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
337 })
338 tc.writeFrames(packetTypeHandshake,
339 debugFrameCrypto{
340 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
341 })
342 tc.wantFrame("client sends Handshake CRYPTO frame",
343 packetTypeHandshake, debugFrameCrypto{
344 data: tc.cryptoDataOut[tls.QUICEncryptionLevelHandshake],
345 })
346 tc.wantFrame("client provides an additional connection ID",
347 packetType1RTT, debugFrameNewConnectionID{
348 seq: 1,
349 connID: testLocalConnID(1),
350 token: testLocalStatelessResetToken(1),
351 })
352
353
354 tc.writeFrames(packetTypeInitial,
355 debugFrameConnectionCloseTransport{code: errInternal})
356 tc.wantIdle("client has discarded Initial keys, cannot read CONNECTION_CLOSE")
357
358
359 tc.writeFrames(packetType1RTT,
360 debugFrameHandshakeDone{})
361 tc.writeFrames(packetTypeHandshake,
362 debugFrameConnectionCloseTransport{code: errInternal})
363 tc.wantIdle("client has discarded Handshake keys, cannot read CONNECTION_CLOSE")
364
365 tc.writeFrames(packetType1RTT,
366 debugFrameConnectionCloseTransport{code: errInternal})
367 tc.conn.Abort(nil)
368 tc.wantFrame("client closes connection after 1-RTT CONNECTION_CLOSE",
369 packetType1RTT, debugFrameConnectionCloseTransport{
370 code: errNo,
371 })
372 }
373
374 func TestConnKeysDiscardedServer(t *testing.T) {
375 tc := newTestConn(t, serverSide)
376 tc.ignoreFrame(frameTypeAck)
377
378 tc.writeFrames(packetTypeInitial,
379 debugFrameCrypto{
380 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
381 })
382 tc.wantFrame("server sends Initial CRYPTO frame",
383 packetTypeInitial, debugFrameCrypto{
384 data: tc.cryptoDataOut[tls.QUICEncryptionLevelInitial],
385 })
386 tc.wantFrame("server sends Handshake CRYPTO frame",
387 packetTypeHandshake, debugFrameCrypto{
388 data: tc.cryptoDataOut[tls.QUICEncryptionLevelHandshake],
389 })
390
391
392
393
394 tc.writeFrames(packetTypeHandshake,
395 debugFrameCrypto{
396 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][:1],
397 })
398 tc.writeFrames(packetTypeInitial,
399 debugFrameConnectionCloseTransport{code: errInternal})
400 tc.wantFrame("server provides an additional connection ID",
401 packetType1RTT, debugFrameNewConnectionID{
402 seq: 1,
403 connID: testLocalConnID(1),
404 token: testLocalStatelessResetToken(1),
405 })
406 tc.wantIdle("server has discarded Initial keys, cannot read CONNECTION_CLOSE")
407
408
409 tc.writeFrames(packetTypeHandshake,
410 debugFrameCrypto{
411 off: 1,
412 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][1:],
413 })
414 tc.wantFrame("server sends HANDSHAKE_DONE after handshake completes",
415 packetType1RTT, debugFrameHandshakeDone{})
416 tc.writeFrames(packetTypeHandshake,
417 debugFrameConnectionCloseTransport{code: errInternal})
418 tc.wantIdle("server has discarded Handshake keys, cannot read CONNECTION_CLOSE")
419
420 tc.writeFrames(packetType1RTT,
421 debugFrameConnectionCloseTransport{code: errInternal})
422 tc.conn.Abort(nil)
423 tc.wantFrame("server closes connection after 1-RTT CONNECTION_CLOSE",
424 packetType1RTT, debugFrameConnectionCloseTransport{
425 code: errNo,
426 })
427 }
428
429 func TestConnInvalidCryptoData(t *testing.T) {
430 tc := newTestConn(t, clientSide)
431 tc.ignoreFrame(frameTypeAck)
432
433 tc.wantFrame("client sends Initial CRYPTO frame",
434 packetTypeInitial, debugFrameCrypto{
435 data: tc.cryptoDataOut[tls.QUICEncryptionLevelInitial],
436 })
437 tc.writeFrames(packetTypeInitial,
438 debugFrameCrypto{
439 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
440 })
441
442
443
444
445
446
447
448 tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][0] ^= 0x1
449 tc.writeFrames(packetTypeHandshake,
450 debugFrameCrypto{
451 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
452 })
453 tc.wantFrame("client closes connection due to TLS handshake error",
454 packetTypeInitial, debugFrameConnectionCloseTransport{
455 code: errTLSBase + 10,
456 })
457 }
458
459 func TestConnInvalidPeerCertificate(t *testing.T) {
460 tc := newTestConn(t, clientSide, func(c *tls.Config) {
461 c.VerifyPeerCertificate = func([][]byte, [][]*x509.Certificate) error {
462 return errors.New("I will not buy this certificate. It is scratched.")
463 }
464 })
465 tc.ignoreFrame(frameTypeAck)
466
467 tc.wantFrame("client sends Initial CRYPTO frame",
468 packetTypeInitial, debugFrameCrypto{
469 data: tc.cryptoDataOut[tls.QUICEncryptionLevelInitial],
470 })
471 tc.writeFrames(packetTypeInitial,
472 debugFrameCrypto{
473 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
474 })
475 tc.writeFrames(packetTypeHandshake,
476 debugFrameCrypto{
477 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
478 })
479 tc.wantFrame("client closes connection due to rejecting server certificate",
480 packetTypeInitial, debugFrameConnectionCloseTransport{
481 code: errTLSBase + 42,
482 })
483 }
484
485 func TestConnHandshakeDoneSentToServer(t *testing.T) {
486 tc := newTestConn(t, serverSide)
487 tc.handshake()
488
489 tc.writeFrames(packetType1RTT,
490 debugFrameHandshakeDone{})
491 tc.wantFrame("server closes connection when client sends a HANDSHAKE_DONE frame",
492 packetType1RTT, debugFrameConnectionCloseTransport{
493 code: errProtocolViolation,
494 })
495 }
496
497 func TestConnCryptoDataOutOfOrder(t *testing.T) {
498 tc := newTestConn(t, clientSide)
499 tc.ignoreFrame(frameTypeAck)
500
501 tc.wantFrame("client sends Initial CRYPTO frame",
502 packetTypeInitial, debugFrameCrypto{
503 data: tc.cryptoDataOut[tls.QUICEncryptionLevelInitial],
504 })
505 tc.writeFrames(packetTypeInitial,
506 debugFrameCrypto{
507 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
508 })
509 tc.wantIdle("client is idle, server Handshake flight has not arrived")
510
511 tc.writeFrames(packetTypeHandshake,
512 debugFrameCrypto{
513 off: 15,
514 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][15:],
515 })
516 tc.wantIdle("client is idle, server Handshake flight is not complete")
517
518 tc.writeFrames(packetTypeHandshake,
519 debugFrameCrypto{
520 off: 1,
521 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][1:20],
522 })
523 tc.wantIdle("client is idle, server Handshake flight is still not complete")
524
525 tc.writeFrames(packetTypeHandshake,
526 debugFrameCrypto{
527 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake][0:1],
528 })
529 tc.wantFrame("client sends Handshake CRYPTO frame",
530 packetTypeHandshake, debugFrameCrypto{
531 data: tc.cryptoDataOut[tls.QUICEncryptionLevelHandshake],
532 })
533 }
534
535 func TestConnCryptoBufferSizeExceeded(t *testing.T) {
536 tc := newTestConn(t, clientSide)
537 tc.ignoreFrame(frameTypeAck)
538
539 tc.wantFrame("client sends Initial CRYPTO frame",
540 packetTypeInitial, debugFrameCrypto{
541 data: tc.cryptoDataOut[tls.QUICEncryptionLevelInitial],
542 })
543 tc.writeFrames(packetTypeInitial,
544 debugFrameCrypto{
545 off: cryptoBufferSize,
546 data: []byte{0},
547 })
548 tc.wantFrame("client closes connection after server exceeds CRYPTO buffer",
549 packetTypeInitial, debugFrameConnectionCloseTransport{
550 code: errCryptoBufferExceeded,
551 })
552 }
553
554 func TestConnAEADLimitReached(t *testing.T) {
555
556
557
558
559
560
561 tc := newTestConn(t, clientSide, func(c *Config) {
562 clear(c.StatelessResetKey[:])
563 })
564 tc.handshake()
565
566 var limit int64
567 switch suite := tc.conn.keysAppData.r.suite; suite {
568 case tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384:
569 limit = 1 << 52
570 case tls.TLS_CHACHA20_POLY1305_SHA256:
571 limit = 1 << 36
572 default:
573 t.Fatalf("conn.keysAppData.r.suite = %v, unknown suite", suite)
574 }
575
576 dstConnID := tc.conn.connIDState.local[0].cid
577 if tc.conn.connIDState.local[0].seq == -1 {
578
579 dstConnID = tc.conn.connIDState.local[1].cid
580 }
581 invalid := encodeTestPacket(t, tc, &testPacket{
582 ptype: packetType1RTT,
583 num: 1000,
584 frames: []debugFrame{debugFramePing{}},
585 version: quicVersion1,
586 dstConnID: dstConnID,
587 srcConnID: tc.peerConnID,
588 }, 0)
589 invalid[len(invalid)-1] ^= 1
590 sendInvalid := func() {
591 t.Logf("<- conn under test receives invalid datagram")
592 tc.conn.sendMsg(&datagram{
593 b: invalid,
594 })
595 tc.wait()
596 }
597
598
599 tc.conn.keysAppData.authFailures = limit - 1
600
601 tc.writeFrames(packetType1RTT, debugFramePing{})
602 tc.advanceToTimer()
603 tc.wantFrameType("auth failures less than limit: conn ACKs packet",
604 packetType1RTT, debugFrameAck{})
605
606 sendInvalid()
607 tc.writeFrames(packetType1RTT, debugFramePing{})
608 tc.advanceToTimer()
609 tc.wantFrameType("auth failures at limit: conn closes",
610 packetType1RTT, debugFrameConnectionCloseTransport{
611 code: errAEADLimitReached,
612 })
613
614 tc.writeFrames(packetType1RTT, debugFramePing{})
615 tc.advance(1 * time.Second)
616 tc.wantIdle("auth failures at limit: conn does not process additional packets")
617 }
618
619 func TestConnKeysDiscardedWithExcessCryptoData(t *testing.T) {
620 tc := newTestConn(t, serverSide, permissiveTransportParameters)
621 tc.ignoreFrame(frameTypeAck)
622 tc.ignoreFrame(frameTypeNewConnectionID)
623 tc.ignoreFrame(frameTypeCrypto)
624
625
626 tc.writeFrames(packetTypeInitial,
627 debugFrameCrypto{
628 off: int64(len(tc.cryptoDataIn[tls.QUICEncryptionLevelInitial]) + 1),
629 data: []byte{0},
630 })
631 tc.writeFrames(packetTypeInitial,
632 debugFrameCrypto{
633 data: tc.cryptoDataIn[tls.QUICEncryptionLevelInitial],
634 })
635
636
637
638 tc.writeFrames(packetTypeHandshake,
639 debugFrameCrypto{
640 data: tc.cryptoDataIn[tls.QUICEncryptionLevelHandshake],
641 })
642 tc.wantFrame("connection closed due to excess Initial CRYPTO data",
643 packetType1RTT, debugFrameConnectionCloseTransport{
644 code: errTLSBase + 10,
645 })
646 }
647
View as plain text