Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/ssl/quic/quic_wire.c
107437 views
1
/*
2
* Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
#include <openssl/macros.h>
11
#include <openssl/objects.h>
12
#include "internal/quic_ssl.h"
13
#include "internal/quic_vlint.h"
14
#include "internal/quic_wire.h"
15
#include "internal/quic_error.h"
16
17
OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t)
18
19
int ossl_quic_frame_ack_contains_pn(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pn)
20
{
21
size_t i;
22
23
for (i = 0; i < ack->num_ack_ranges; ++i)
24
if (pn >= ack->ack_ranges[i].start
25
&& pn <= ack->ack_ranges[i].end)
26
return 1;
27
28
return 0;
29
}
30
31
/*
32
* QUIC Wire Format Encoding
33
* =========================
34
*/
35
36
int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes)
37
{
38
/*
39
* PADDING is frame type zero, which as a variable-length integer is
40
* represented as a single zero byte. As an optimisation, just use memset.
41
*/
42
return WPACKET_memset(pkt, 0, num_bytes);
43
}
44
45
static int encode_frame_hdr(WPACKET *pkt, uint64_t frame_type)
46
{
47
return WPACKET_quic_write_vlint(pkt, frame_type);
48
}
49
50
int ossl_quic_wire_encode_frame_ping(WPACKET *pkt)
51
{
52
return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PING);
53
}
54
55
int ossl_quic_wire_encode_frame_ack(WPACKET *pkt,
56
uint32_t ack_delay_exponent,
57
const OSSL_QUIC_FRAME_ACK *ack)
58
{
59
uint64_t frame_type = ack->ecn_present ? OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN
60
: OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN;
61
62
uint64_t largest_ackd, first_ack_range, ack_delay_enc;
63
uint64_t i, num_ack_ranges = ack->num_ack_ranges;
64
OSSL_TIME delay;
65
66
if (num_ack_ranges == 0)
67
return 0;
68
69
delay = ossl_time_divide(ossl_time_divide(ack->delay_time, OSSL_TIME_US),
70
(uint64_t)1 << ack_delay_exponent);
71
ack_delay_enc = ossl_time2ticks(delay);
72
73
largest_ackd = ack->ack_ranges[0].end;
74
first_ack_range = ack->ack_ranges[0].end - ack->ack_ranges[0].start;
75
76
if (!encode_frame_hdr(pkt, frame_type)
77
|| !WPACKET_quic_write_vlint(pkt, largest_ackd)
78
|| !WPACKET_quic_write_vlint(pkt, ack_delay_enc)
79
|| !WPACKET_quic_write_vlint(pkt, num_ack_ranges - 1)
80
|| !WPACKET_quic_write_vlint(pkt, first_ack_range))
81
return 0;
82
83
for (i = 1; i < num_ack_ranges; ++i) {
84
uint64_t gap, range_len;
85
86
gap = ack->ack_ranges[i - 1].start - ack->ack_ranges[i].end - 2;
87
range_len = ack->ack_ranges[i].end - ack->ack_ranges[i].start;
88
89
if (!WPACKET_quic_write_vlint(pkt, gap)
90
|| !WPACKET_quic_write_vlint(pkt, range_len))
91
return 0;
92
}
93
94
if (ack->ecn_present)
95
if (!WPACKET_quic_write_vlint(pkt, ack->ect0)
96
|| !WPACKET_quic_write_vlint(pkt, ack->ect1)
97
|| !WPACKET_quic_write_vlint(pkt, ack->ecnce))
98
return 0;
99
100
return 1;
101
}
102
103
int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt,
104
const OSSL_QUIC_FRAME_RESET_STREAM *f)
105
{
106
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
107
|| !WPACKET_quic_write_vlint(pkt, f->stream_id)
108
|| !WPACKET_quic_write_vlint(pkt, f->app_error_code)
109
|| !WPACKET_quic_write_vlint(pkt, f->final_size))
110
return 0;
111
112
return 1;
113
}
114
115
int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt,
116
const OSSL_QUIC_FRAME_STOP_SENDING *f)
117
{
118
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
119
|| !WPACKET_quic_write_vlint(pkt, f->stream_id)
120
|| !WPACKET_quic_write_vlint(pkt, f->app_error_code))
121
return 0;
122
123
return 1;
124
}
125
126
int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *pkt,
127
const OSSL_QUIC_FRAME_CRYPTO *f)
128
{
129
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
130
|| !WPACKET_quic_write_vlint(pkt, f->offset)
131
|| !WPACKET_quic_write_vlint(pkt, f->len))
132
return 0;
133
134
return 1;
135
}
136
137
size_t ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO *f)
138
{
139
size_t a, b, c;
140
141
a = ossl_quic_vlint_encode_len(OSSL_QUIC_FRAME_TYPE_CRYPTO);
142
b = ossl_quic_vlint_encode_len(f->offset);
143
c = ossl_quic_vlint_encode_len(f->len);
144
if (a == 0 || b == 0 || c == 0)
145
return 0;
146
147
return a + b + c;
148
}
149
150
void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt,
151
const OSSL_QUIC_FRAME_CRYPTO *f)
152
{
153
unsigned char *p = NULL;
154
155
if (!ossl_quic_wire_encode_frame_crypto_hdr(pkt, f)
156
|| f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
157
|| !WPACKET_allocate_bytes(pkt, (size_t)f->len, &p))
158
return NULL;
159
160
if (f->data != NULL)
161
memcpy(p, f->data, (size_t)f->len);
162
163
return p;
164
}
165
166
int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt,
167
const unsigned char *token,
168
size_t token_len)
169
{
170
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
171
|| !WPACKET_quic_write_vlint(pkt, token_len)
172
|| !WPACKET_memcpy(pkt, token, token_len))
173
return 0;
174
175
return 1;
176
}
177
178
int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt,
179
const OSSL_QUIC_FRAME_STREAM *f)
180
{
181
uint64_t frame_type = OSSL_QUIC_FRAME_TYPE_STREAM;
182
183
if (f->offset != 0)
184
frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_OFF;
185
if (f->has_explicit_len)
186
frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_LEN;
187
if (f->is_fin)
188
frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_FIN;
189
190
if (!encode_frame_hdr(pkt, frame_type)
191
|| !WPACKET_quic_write_vlint(pkt, f->stream_id))
192
return 0;
193
194
if (f->offset != 0 && !WPACKET_quic_write_vlint(pkt, f->offset))
195
return 0;
196
197
if (f->has_explicit_len && !WPACKET_quic_write_vlint(pkt, f->len))
198
return 0;
199
200
return 1;
201
}
202
203
size_t ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM *f)
204
{
205
size_t a, b, c, d;
206
207
a = ossl_quic_vlint_encode_len(OSSL_QUIC_FRAME_TYPE_STREAM);
208
b = ossl_quic_vlint_encode_len(f->stream_id);
209
if (a == 0 || b == 0)
210
return 0;
211
212
if (f->offset > 0) {
213
c = ossl_quic_vlint_encode_len(f->offset);
214
if (c == 0)
215
return 0;
216
} else {
217
c = 0;
218
}
219
220
if (f->has_explicit_len) {
221
d = ossl_quic_vlint_encode_len(f->len);
222
if (d == 0)
223
return 0;
224
} else {
225
d = 0;
226
}
227
228
return a + b + c + d;
229
}
230
231
void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt,
232
const OSSL_QUIC_FRAME_STREAM *f)
233
{
234
235
unsigned char *p = NULL;
236
237
if (!ossl_quic_wire_encode_frame_stream_hdr(pkt, f)
238
|| f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
239
return NULL;
240
241
if (!WPACKET_allocate_bytes(pkt, (size_t)f->len, &p))
242
return NULL;
243
244
if (f->data != NULL)
245
memcpy(p, f->data, (size_t)f->len);
246
247
return p;
248
}
249
250
int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt,
251
uint64_t max_data)
252
{
253
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
254
|| !WPACKET_quic_write_vlint(pkt, max_data))
255
return 0;
256
257
return 1;
258
}
259
260
int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt,
261
uint64_t stream_id,
262
uint64_t max_data)
263
{
264
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
265
|| !WPACKET_quic_write_vlint(pkt, stream_id)
266
|| !WPACKET_quic_write_vlint(pkt, max_data))
267
return 0;
268
269
return 1;
270
}
271
272
int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt,
273
char is_uni,
274
uint64_t max_streams)
275
{
276
if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI : OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI)
277
|| !WPACKET_quic_write_vlint(pkt, max_streams))
278
return 0;
279
280
return 1;
281
}
282
283
int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt,
284
uint64_t max_data)
285
{
286
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
287
|| !WPACKET_quic_write_vlint(pkt, max_data))
288
return 0;
289
290
return 1;
291
}
292
293
int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt,
294
uint64_t stream_id,
295
uint64_t max_stream_data)
296
{
297
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
298
|| !WPACKET_quic_write_vlint(pkt, stream_id)
299
|| !WPACKET_quic_write_vlint(pkt, max_stream_data))
300
return 0;
301
302
return 1;
303
}
304
305
int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt,
306
char is_uni,
307
uint64_t max_streams)
308
{
309
if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI : OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI)
310
|| !WPACKET_quic_write_vlint(pkt, max_streams))
311
return 0;
312
313
return 1;
314
}
315
316
int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt,
317
const OSSL_QUIC_FRAME_NEW_CONN_ID *f)
318
{
319
if (f->conn_id.id_len < 1
320
|| f->conn_id.id_len > QUIC_MAX_CONN_ID_LEN)
321
return 0;
322
323
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
324
|| !WPACKET_quic_write_vlint(pkt, f->seq_num)
325
|| !WPACKET_quic_write_vlint(pkt, f->retire_prior_to)
326
|| !WPACKET_put_bytes_u8(pkt, f->conn_id.id_len)
327
|| !WPACKET_memcpy(pkt, f->conn_id.id, f->conn_id.id_len)
328
|| !WPACKET_memcpy(pkt, f->stateless_reset.token,
329
sizeof(f->stateless_reset.token)))
330
return 0;
331
332
return 1;
333
}
334
335
int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt,
336
uint64_t seq_num)
337
{
338
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
339
|| !WPACKET_quic_write_vlint(pkt, seq_num))
340
return 0;
341
342
return 1;
343
}
344
345
int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt,
346
uint64_t data)
347
{
348
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
349
|| !WPACKET_put_bytes_u64(pkt, data))
350
return 0;
351
352
return 1;
353
}
354
355
int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt,
356
uint64_t data)
357
{
358
if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
359
|| !WPACKET_put_bytes_u64(pkt, data))
360
return 0;
361
362
return 1;
363
}
364
365
int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt,
366
const OSSL_QUIC_FRAME_CONN_CLOSE *f)
367
{
368
if (!encode_frame_hdr(pkt, f->is_app ? OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP : OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT)
369
|| !WPACKET_quic_write_vlint(pkt, f->error_code))
370
return 0;
371
372
/*
373
* RFC 9000 s. 19.19: The application-specific variant of CONNECTION_CLOSE
374
* (type 0x1d) does not include this field.
375
*/
376
if (!f->is_app && !WPACKET_quic_write_vlint(pkt, f->frame_type))
377
return 0;
378
379
if (!WPACKET_quic_write_vlint(pkt, f->reason_len)
380
|| !WPACKET_memcpy(pkt, f->reason, f->reason_len))
381
return 0;
382
383
return 1;
384
}
385
386
int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt)
387
{
388
return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
389
}
390
391
unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt,
392
uint64_t id,
393
const unsigned char *value,
394
size_t value_len)
395
{
396
unsigned char *b = NULL;
397
398
if (!WPACKET_quic_write_vlint(pkt, id)
399
|| !WPACKET_quic_write_vlint(pkt, value_len))
400
return NULL;
401
402
if (value_len == 0)
403
b = WPACKET_get_curr(pkt);
404
else if (!WPACKET_allocate_bytes(pkt, value_len, (unsigned char **)&b))
405
return NULL;
406
407
if (value != NULL)
408
memcpy(b, value, value_len);
409
410
return b;
411
}
412
413
int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt,
414
uint64_t id,
415
uint64_t value)
416
{
417
if (!WPACKET_quic_write_vlint(pkt, id)
418
|| !WPACKET_quic_write_vlint(pkt, ossl_quic_vlint_encode_len(value))
419
|| !WPACKET_quic_write_vlint(pkt, value))
420
return 0;
421
422
return 1;
423
}
424
425
int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt,
426
uint64_t id,
427
const QUIC_CONN_ID *cid)
428
{
429
if (cid->id_len > QUIC_MAX_CONN_ID_LEN)
430
return 0;
431
432
if (ossl_quic_wire_encode_transport_param_bytes(wpkt, id,
433
cid->id,
434
cid->id_len)
435
== NULL)
436
return 0;
437
438
return 1;
439
}
440
441
/*
442
* QUIC Wire Format Decoding
443
* =========================
444
*/
445
int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type,
446
int *was_minimal)
447
{
448
return PACKET_peek_quic_vlint_ex(pkt, type, was_minimal);
449
}
450
451
int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type)
452
{
453
return PACKET_get_quic_vlint(pkt, type);
454
}
455
456
static int expect_frame_header_mask(PACKET *pkt,
457
uint64_t expected_frame_type,
458
uint64_t mask_bits,
459
uint64_t *actual_frame_type)
460
{
461
uint64_t actual_frame_type_;
462
463
if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type_)
464
|| (actual_frame_type_ & ~mask_bits) != expected_frame_type)
465
return 0;
466
467
if (actual_frame_type != NULL)
468
*actual_frame_type = actual_frame_type_;
469
470
return 1;
471
}
472
473
static int expect_frame_header(PACKET *pkt, uint64_t expected_frame_type)
474
{
475
uint64_t actual_frame_type;
476
477
if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type)
478
|| actual_frame_type != expected_frame_type)
479
return 0;
480
481
return 1;
482
}
483
484
int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *orig_pkt,
485
uint64_t *total_ranges)
486
{
487
PACKET pkt = *orig_pkt;
488
uint64_t ack_range_count, i;
489
490
if (!expect_frame_header_mask(&pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
491
1, NULL)
492
|| !PACKET_skip_quic_vlint(&pkt)
493
|| !PACKET_skip_quic_vlint(&pkt)
494
|| !PACKET_get_quic_vlint(&pkt, &ack_range_count))
495
return 0;
496
497
/*
498
* Ensure the specified number of ack ranges listed in the ACK frame header
499
* actually are available in the frame data. This naturally bounds the
500
* number of ACK ranges which can be requested by the MDPL, and therefore by
501
* the MTU. This ensures we do not allocate memory for an excessive number
502
* of ACK ranges.
503
*/
504
for (i = 0; i < ack_range_count; ++i)
505
if (!PACKET_skip_quic_vlint(&pkt)
506
|| !PACKET_skip_quic_vlint(&pkt))
507
return 0;
508
509
/* (cannot overflow because QUIC vlints can only encode up to 2**62-1) */
510
*total_ranges = ack_range_count + 1;
511
return 1;
512
}
513
514
int ossl_quic_wire_decode_frame_ack(PACKET *pkt,
515
uint32_t ack_delay_exponent,
516
OSSL_QUIC_FRAME_ACK *ack,
517
uint64_t *total_ranges)
518
{
519
uint64_t frame_type, largest_ackd, ack_delay_raw;
520
uint64_t ack_range_count, first_ack_range, start, end, i;
521
522
/* This call matches both ACK_WITHOUT_ECN and ACK_WITH_ECN. */
523
if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
524
1, &frame_type)
525
|| !PACKET_get_quic_vlint(pkt, &largest_ackd)
526
|| !PACKET_get_quic_vlint(pkt, &ack_delay_raw)
527
|| !PACKET_get_quic_vlint(pkt, &ack_range_count)
528
|| !PACKET_get_quic_vlint(pkt, &first_ack_range))
529
return 0;
530
531
if (first_ack_range > largest_ackd)
532
return 0;
533
534
if (ack_range_count > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
535
return 0;
536
537
start = largest_ackd - first_ack_range;
538
539
if (ack != NULL) {
540
int err = 0;
541
ack->delay_time
542
= ossl_time_multiply(ossl_ticks2time(OSSL_TIME_US),
543
safe_mul_uint64_t(ack_delay_raw,
544
(uint64_t)1 << ack_delay_exponent,
545
&err));
546
if (err)
547
ack->delay_time = ossl_time_infinite();
548
549
if (ack->num_ack_ranges > 0) {
550
ack->ack_ranges[0].end = largest_ackd;
551
ack->ack_ranges[0].start = start;
552
}
553
}
554
555
for (i = 0; i < ack_range_count; ++i) {
556
uint64_t gap, len;
557
558
if (!PACKET_get_quic_vlint(pkt, &gap)
559
|| !PACKET_get_quic_vlint(pkt, &len))
560
return 0;
561
562
end = start - gap - 2;
563
if (start < gap + 2 || len > end)
564
return 0;
565
566
if (ack != NULL && i + 1 < ack->num_ack_ranges) {
567
ack->ack_ranges[i + 1].start = start = end - len;
568
ack->ack_ranges[i + 1].end = end;
569
}
570
}
571
572
if (ack != NULL && ack_range_count + 1 < ack->num_ack_ranges)
573
ack->num_ack_ranges = (size_t)ack_range_count + 1;
574
575
if (total_ranges != NULL)
576
*total_ranges = ack_range_count + 1;
577
578
if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) {
579
uint64_t ect0, ect1, ecnce;
580
581
if (!PACKET_get_quic_vlint(pkt, &ect0)
582
|| !PACKET_get_quic_vlint(pkt, &ect1)
583
|| !PACKET_get_quic_vlint(pkt, &ecnce))
584
return 0;
585
586
if (ack != NULL) {
587
ack->ect0 = ect0;
588
ack->ect1 = ect1;
589
ack->ecnce = ecnce;
590
ack->ecn_present = 1;
591
}
592
} else if (ack != NULL) {
593
ack->ecn_present = 0;
594
}
595
596
return 1;
597
}
598
599
int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt,
600
OSSL_QUIC_FRAME_RESET_STREAM *f)
601
{
602
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
603
|| !PACKET_get_quic_vlint(pkt, &f->stream_id)
604
|| !PACKET_get_quic_vlint(pkt, &f->app_error_code)
605
|| !PACKET_get_quic_vlint(pkt, &f->final_size))
606
return 0;
607
608
return 1;
609
}
610
611
int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt,
612
OSSL_QUIC_FRAME_STOP_SENDING *f)
613
{
614
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
615
|| !PACKET_get_quic_vlint(pkt, &f->stream_id)
616
|| !PACKET_get_quic_vlint(pkt, &f->app_error_code))
617
return 0;
618
619
return 1;
620
}
621
622
int ossl_quic_wire_decode_frame_crypto(PACKET *pkt,
623
int nodata,
624
OSSL_QUIC_FRAME_CRYPTO *f)
625
{
626
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
627
|| !PACKET_get_quic_vlint(pkt, &f->offset)
628
|| !PACKET_get_quic_vlint(pkt, &f->len)
629
|| f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */)
630
return 0;
631
632
if (f->offset + f->len > (((uint64_t)1) << 62) - 1)
633
/* RFC 9000 s. 19.6 */
634
return 0;
635
636
if (nodata) {
637
f->data = NULL;
638
} else {
639
if (PACKET_remaining(pkt) < f->len)
640
return 0;
641
642
f->data = PACKET_data(pkt);
643
644
if (!PACKET_forward(pkt, (size_t)f->len))
645
return 0;
646
}
647
648
return 1;
649
}
650
651
int ossl_quic_wire_decode_frame_new_token(PACKET *pkt,
652
const unsigned char **token,
653
size_t *token_len)
654
{
655
uint64_t token_len_;
656
657
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
658
|| !PACKET_get_quic_vlint(pkt, &token_len_))
659
return 0;
660
661
if (token_len_ > SIZE_MAX)
662
return 0;
663
664
*token = PACKET_data(pkt);
665
*token_len = (size_t)token_len_;
666
667
if (!PACKET_forward(pkt, (size_t)token_len_))
668
return 0;
669
670
return 1;
671
}
672
673
int ossl_quic_wire_decode_frame_stream(PACKET *pkt,
674
int nodata,
675
OSSL_QUIC_FRAME_STREAM *f)
676
{
677
uint64_t frame_type;
678
679
/* This call matches all STREAM values (low 3 bits are masked). */
680
if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAM,
681
OSSL_QUIC_FRAME_FLAG_STREAM_MASK,
682
&frame_type)
683
|| !PACKET_get_quic_vlint(pkt, &f->stream_id))
684
return 0;
685
686
if ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_OFF) != 0) {
687
if (!PACKET_get_quic_vlint(pkt, &f->offset))
688
return 0;
689
} else {
690
f->offset = 0;
691
}
692
693
f->has_explicit_len = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_LEN) != 0);
694
f->is_fin = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_FIN) != 0);
695
696
if (f->has_explicit_len) {
697
if (!PACKET_get_quic_vlint(pkt, &f->len))
698
return 0;
699
} else {
700
if (nodata)
701
f->len = 0;
702
else
703
f->len = PACKET_remaining(pkt);
704
}
705
706
/*
707
* RFC 9000 s. 19.8: "The largest offset delivered on a stream -- the sum of
708
* the offset and data length -- cannot exceed 2**62 - 1, as it is not
709
* possible to provide flow control credit for that data."
710
*/
711
if (f->offset + f->len > (((uint64_t)1) << 62) - 1)
712
return 0;
713
714
if (nodata) {
715
f->data = NULL;
716
} else {
717
f->data = PACKET_data(pkt);
718
719
if (f->len > SIZE_MAX /* sizeof(uint64_t) > sizeof(size_t)? */
720
|| !PACKET_forward(pkt, (size_t)f->len))
721
return 0;
722
}
723
724
return 1;
725
}
726
727
int ossl_quic_wire_decode_frame_max_data(PACKET *pkt,
728
uint64_t *max_data)
729
{
730
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
731
|| !PACKET_get_quic_vlint(pkt, max_data))
732
return 0;
733
734
return 1;
735
}
736
737
int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt,
738
uint64_t *stream_id,
739
uint64_t *max_stream_data)
740
{
741
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
742
|| !PACKET_get_quic_vlint(pkt, stream_id)
743
|| !PACKET_get_quic_vlint(pkt, max_stream_data))
744
return 0;
745
746
return 1;
747
}
748
749
int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt,
750
uint64_t *max_streams)
751
{
752
/* This call matches both MAX_STREAMS_BIDI and MAX_STREAMS_UNI. */
753
if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI,
754
1, NULL)
755
|| !PACKET_get_quic_vlint(pkt, max_streams))
756
return 0;
757
758
return 1;
759
}
760
761
int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt,
762
uint64_t *max_data)
763
{
764
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
765
|| !PACKET_get_quic_vlint(pkt, max_data))
766
return 0;
767
768
return 1;
769
}
770
771
int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt,
772
uint64_t *stream_id,
773
uint64_t *max_stream_data)
774
{
775
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
776
|| !PACKET_get_quic_vlint(pkt, stream_id)
777
|| !PACKET_get_quic_vlint(pkt, max_stream_data))
778
return 0;
779
780
return 1;
781
}
782
783
int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt,
784
uint64_t *max_streams)
785
{
786
/* This call matches both STREAMS_BLOCKED_BIDI and STREAMS_BLOCKED_UNI. */
787
if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI,
788
1, NULL)
789
|| !PACKET_get_quic_vlint(pkt, max_streams))
790
return 0;
791
792
return 1;
793
}
794
795
int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt,
796
OSSL_QUIC_FRAME_NEW_CONN_ID *f)
797
{
798
unsigned int len;
799
800
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
801
|| !PACKET_get_quic_vlint(pkt, &f->seq_num)
802
|| !PACKET_get_quic_vlint(pkt, &f->retire_prior_to)
803
|| f->seq_num < f->retire_prior_to
804
|| !PACKET_get_1(pkt, &len)
805
|| len < 1
806
|| len > QUIC_MAX_CONN_ID_LEN)
807
return 0;
808
809
f->conn_id.id_len = (unsigned char)len;
810
if (!PACKET_copy_bytes(pkt, f->conn_id.id, len))
811
return 0;
812
813
/* Clear unused bytes to allow consistent memcmp. */
814
if (len < QUIC_MAX_CONN_ID_LEN)
815
memset(f->conn_id.id + len, 0, QUIC_MAX_CONN_ID_LEN - len);
816
817
if (!PACKET_copy_bytes(pkt, f->stateless_reset.token,
818
sizeof(f->stateless_reset.token)))
819
return 0;
820
821
return 1;
822
}
823
824
int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt,
825
uint64_t *seq_num)
826
{
827
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
828
|| !PACKET_get_quic_vlint(pkt, seq_num))
829
return 0;
830
831
return 1;
832
}
833
834
int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt,
835
uint64_t *data)
836
{
837
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
838
|| !PACKET_get_net_8(pkt, data))
839
return 0;
840
841
return 1;
842
}
843
844
int ossl_quic_wire_decode_frame_path_response(PACKET *pkt,
845
uint64_t *data)
846
{
847
if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
848
|| !PACKET_get_net_8(pkt, data))
849
return 0;
850
851
return 1;
852
}
853
854
int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt,
855
OSSL_QUIC_FRAME_CONN_CLOSE *f)
856
{
857
uint64_t frame_type, reason_len;
858
859
/* This call matches both CONN_CLOSE_TRANSPORT and CONN_CLOSE_APP. */
860
if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT,
861
1, &frame_type)
862
|| !PACKET_get_quic_vlint(pkt, &f->error_code))
863
return 0;
864
865
f->is_app = ((frame_type & 1) != 0);
866
867
if (!f->is_app) {
868
if (!PACKET_get_quic_vlint(pkt, &f->frame_type))
869
return 0;
870
} else {
871
f->frame_type = 0;
872
}
873
874
if (!PACKET_get_quic_vlint(pkt, &reason_len)
875
|| reason_len > SIZE_MAX)
876
return 0;
877
878
if (!PACKET_get_bytes(pkt, (const unsigned char **)&f->reason,
879
(size_t)reason_len))
880
return 0;
881
882
f->reason_len = (size_t)reason_len;
883
return 1;
884
}
885
886
size_t ossl_quic_wire_decode_padding(PACKET *pkt)
887
{
888
const unsigned char *start = PACKET_data(pkt), *end = PACKET_end(pkt),
889
*p = start;
890
891
while (p < end && *p == 0)
892
++p;
893
894
if (!PACKET_forward(pkt, p - start))
895
return 0;
896
897
return p - start;
898
}
899
900
int ossl_quic_wire_decode_frame_ping(PACKET *pkt)
901
{
902
return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING);
903
}
904
905
int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt)
906
{
907
return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
908
}
909
910
int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id)
911
{
912
return PACKET_peek_quic_vlint(pkt, id);
913
}
914
915
const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt,
916
uint64_t *id,
917
size_t *len)
918
{
919
uint64_t len_;
920
const unsigned char *b = NULL;
921
uint64_t id_;
922
923
if (!PACKET_get_quic_vlint(pkt, &id_)
924
|| !PACKET_get_quic_vlint(pkt, &len_))
925
return NULL;
926
927
if (len_ > SIZE_MAX
928
|| !PACKET_get_bytes(pkt, (const unsigned char **)&b, (size_t)len_))
929
return NULL;
930
931
*len = (size_t)len_;
932
if (id != NULL)
933
*id = id_;
934
return b;
935
}
936
937
int ossl_quic_wire_decode_transport_param_int(PACKET *pkt,
938
uint64_t *id,
939
uint64_t *value)
940
{
941
PACKET sub;
942
943
sub.curr = ossl_quic_wire_decode_transport_param_bytes(pkt,
944
id, &sub.remaining);
945
if (sub.curr == NULL)
946
return 0;
947
948
if (!PACKET_get_quic_vlint(&sub, value))
949
return 0;
950
951
if (PACKET_remaining(&sub) > 0)
952
return 0;
953
954
return 1;
955
}
956
957
int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt,
958
uint64_t *id,
959
QUIC_CONN_ID *cid)
960
{
961
const unsigned char *body;
962
size_t len = 0;
963
964
body = ossl_quic_wire_decode_transport_param_bytes(pkt, id, &len);
965
if (body == NULL || len > QUIC_MAX_CONN_ID_LEN)
966
return 0;
967
968
cid->id_len = (unsigned char)len;
969
memcpy(cid->id, body, cid->id_len);
970
return 1;
971
}
972
973
int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt,
974
QUIC_PREFERRED_ADDR *p)
975
{
976
const unsigned char *body;
977
uint64_t id;
978
size_t len = 0;
979
PACKET pkt2;
980
unsigned int ipv4_port, ipv6_port, cidl;
981
982
body = ossl_quic_wire_decode_transport_param_bytes(pkt, &id, &len);
983
if (body == NULL
984
|| len < QUIC_MIN_ENCODED_PREFERRED_ADDR_LEN
985
|| len > QUIC_MAX_ENCODED_PREFERRED_ADDR_LEN
986
|| id != QUIC_TPARAM_PREFERRED_ADDR)
987
return 0;
988
989
if (!PACKET_buf_init(&pkt2, body, len))
990
return 0;
991
992
if (!PACKET_copy_bytes(&pkt2, p->ipv4, sizeof(p->ipv4))
993
|| !PACKET_get_net_2(&pkt2, &ipv4_port)
994
|| !PACKET_copy_bytes(&pkt2, p->ipv6, sizeof(p->ipv6))
995
|| !PACKET_get_net_2(&pkt2, &ipv6_port)
996
|| !PACKET_get_1(&pkt2, &cidl)
997
|| cidl > QUIC_MAX_CONN_ID_LEN
998
|| !PACKET_copy_bytes(&pkt2, p->cid.id, cidl)
999
|| !PACKET_copy_bytes(&pkt2, p->stateless_reset.token,
1000
sizeof(p->stateless_reset.token)))
1001
return 0;
1002
1003
p->ipv4_port = (uint16_t)ipv4_port;
1004
p->ipv6_port = (uint16_t)ipv6_port;
1005
p->cid.id_len = (unsigned char)cidl;
1006
return 1;
1007
}
1008
1009
const char *
1010
ossl_quic_frame_type_to_string(uint64_t frame_type)
1011
{
1012
switch (frame_type) {
1013
#define X(name) \
1014
case OSSL_QUIC_FRAME_TYPE_##name: \
1015
return #name;
1016
X(PADDING)
1017
X(PING)
1018
X(ACK_WITHOUT_ECN)
1019
X(ACK_WITH_ECN)
1020
X(RESET_STREAM)
1021
X(STOP_SENDING)
1022
X(CRYPTO)
1023
X(NEW_TOKEN)
1024
X(MAX_DATA)
1025
X(MAX_STREAM_DATA)
1026
X(MAX_STREAMS_BIDI)
1027
X(MAX_STREAMS_UNI)
1028
X(DATA_BLOCKED)
1029
X(STREAM_DATA_BLOCKED)
1030
X(STREAMS_BLOCKED_BIDI)
1031
X(STREAMS_BLOCKED_UNI)
1032
X(NEW_CONN_ID)
1033
X(RETIRE_CONN_ID)
1034
X(PATH_CHALLENGE)
1035
X(PATH_RESPONSE)
1036
X(CONN_CLOSE_TRANSPORT)
1037
X(CONN_CLOSE_APP)
1038
X(HANDSHAKE_DONE)
1039
X(STREAM)
1040
X(STREAM_FIN)
1041
X(STREAM_LEN)
1042
X(STREAM_LEN_FIN)
1043
X(STREAM_OFF)
1044
X(STREAM_OFF_FIN)
1045
X(STREAM_OFF_LEN)
1046
X(STREAM_OFF_LEN_FIN)
1047
#undef X
1048
default:
1049
return NULL;
1050
}
1051
}
1052
1053
const char *ossl_quic_err_to_string(uint64_t error_code)
1054
{
1055
switch (error_code) {
1056
#define X(name) \
1057
case OSSL_QUIC_ERR_##name: \
1058
return #name;
1059
X(NO_ERROR)
1060
X(INTERNAL_ERROR)
1061
X(CONNECTION_REFUSED)
1062
X(FLOW_CONTROL_ERROR)
1063
X(STREAM_LIMIT_ERROR)
1064
X(STREAM_STATE_ERROR)
1065
X(FINAL_SIZE_ERROR)
1066
X(FRAME_ENCODING_ERROR)
1067
X(TRANSPORT_PARAMETER_ERROR)
1068
X(CONNECTION_ID_LIMIT_ERROR)
1069
X(PROTOCOL_VIOLATION)
1070
X(INVALID_TOKEN)
1071
X(APPLICATION_ERROR)
1072
X(CRYPTO_BUFFER_EXCEEDED)
1073
X(KEY_UPDATE_ERROR)
1074
X(AEAD_LIMIT_REACHED)
1075
X(NO_VIABLE_PATH)
1076
#undef X
1077
default:
1078
return NULL;
1079
}
1080
}
1081
1082