]> git.ipfire.org Git - thirdparty/openssl.git/blame - ssl/quic/quic_wire.c
Make OSSL_TIME a structure
[thirdparty/openssl.git] / ssl / quic / quic_wire.c
CommitLineData
dffafaf4
HL
1/*
2 * Copyright 2022 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 "quic_local.h"
13#include "internal/quic_vlint.h"
14#include "internal/quic_wire.h"
15
16OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t)
17
18/*
19 * QUIC Wire Format Encoding
20 * =========================
21 */
22
23int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes)
24{
25 /*
26 * PADDING is frame type zero, which as a variable-length integer is
27 * represented as a single zero byte. As an optimisation, just use memset.
28 */
29 return WPACKET_memset(pkt, 0, num_bytes);
30}
31
32static int encode_frame_hdr(WPACKET *pkt, uint64_t frame_type)
33{
34 return WPACKET_quic_write_vlint(pkt, frame_type);
35}
36
37int ossl_quic_wire_encode_frame_ping(WPACKET *pkt)
38{
39 return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PING);
40}
41
42int ossl_quic_wire_encode_frame_ack(WPACKET *pkt,
43 uint32_t ack_delay_exponent,
44 const OSSL_QUIC_FRAME_ACK *ack)
45{
46 uint64_t frame_type = ack->ecn_present ? OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN
47 : OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN;
48
49 uint64_t largest_ackd, first_ack_range, ack_delay_enc;
50 size_t i, num_ack_ranges = ack->num_ack_ranges;
d13c8b77 51 OSSL_TIME delay;
dffafaf4
HL
52
53 if (num_ack_ranges == 0)
54 return 0;
55
d13c8b77
P
56 delay = ossl_time_divide(ossl_time_divide(ack->delay_time, OSSL_TIME_US),
57 1UL << ack_delay_exponent);
58 ack_delay_enc = ossl_time2ticks(delay);
59
dffafaf4
HL
60 largest_ackd = ack->ack_ranges[0].end;
61 first_ack_range = ack->ack_ranges[0].end - ack->ack_ranges[0].start;
62
63 if (!encode_frame_hdr(pkt, frame_type)
64 || !WPACKET_quic_write_vlint(pkt, largest_ackd)
65 || !WPACKET_quic_write_vlint(pkt, ack_delay_enc)
66 || !WPACKET_quic_write_vlint(pkt, num_ack_ranges - 1)
67 || !WPACKET_quic_write_vlint(pkt, first_ack_range))
68 return 0;
69
70 for (i = 1; i < num_ack_ranges; ++i) {
71 uint64_t gap, range_len;
72
73 gap = ack->ack_ranges[i - 1].start - ack->ack_ranges[i].end - 2;
74 range_len = ack->ack_ranges[i].end - ack->ack_ranges[i].start;
75
76 if (!WPACKET_quic_write_vlint(pkt, gap)
77 || !WPACKET_quic_write_vlint(pkt, range_len))
78 return 0;
79 }
80
81 if (ack->ecn_present)
82 if (!WPACKET_quic_write_vlint(pkt, ack->ect0)
83 || !WPACKET_quic_write_vlint(pkt, ack->ect1)
84 || !WPACKET_quic_write_vlint(pkt, ack->ecnce))
85 return 0;
86
87 return 1;
88}
89
90int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt,
91 const OSSL_QUIC_FRAME_RESET_STREAM *f)
92{
93 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
94 || !WPACKET_quic_write_vlint(pkt, f->stream_id)
95 || !WPACKET_quic_write_vlint(pkt, f->app_error_code)
96 || !WPACKET_quic_write_vlint(pkt, f->final_size))
97 return 0;
98
99 return 1;
100}
101
102int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt,
103 const OSSL_QUIC_FRAME_STOP_SENDING *f)
104{
105 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
106 || !WPACKET_quic_write_vlint(pkt, f->stream_id)
107 || !WPACKET_quic_write_vlint(pkt, f->app_error_code))
108 return 0;
109
110 return 1;
111}
112
113int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *pkt,
114 const OSSL_QUIC_FRAME_CRYPTO *f)
115{
116 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
117 || !WPACKET_quic_write_vlint(pkt, f->offset)
118 || !WPACKET_quic_write_vlint(pkt, f->len))
119 return 0;
120
121 return 1;
122}
123
124void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt,
125 const OSSL_QUIC_FRAME_CRYPTO *f)
126{
127 unsigned char *p = NULL;
128
129 if (!ossl_quic_wire_encode_frame_crypto_hdr(pkt, f)
130 || !WPACKET_allocate_bytes(pkt, f->len, &p))
131 return NULL;
132
133 if (f->data != NULL)
134 memcpy(p, f->data, f->len);
135
136 return p;
137}
138
139int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt,
140 const unsigned char *token,
141 size_t token_len)
142{
143 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
144 || !WPACKET_quic_write_vlint(pkt, token_len)
145 || !WPACKET_memcpy(pkt, token, token_len))
146 return 0;
147
148 return 1;
149}
150
151int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt,
152 const OSSL_QUIC_FRAME_STREAM *f)
153{
154 uint64_t frame_type = OSSL_QUIC_FRAME_TYPE_STREAM;
155
156 if (f->offset != 0)
157 frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_OFF;
158 if (f->has_explicit_len)
159 frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_LEN;
160 if (f->is_fin)
161 frame_type |= OSSL_QUIC_FRAME_FLAG_STREAM_FIN;
162
163 if (!encode_frame_hdr(pkt, frame_type)
164 || !WPACKET_quic_write_vlint(pkt, f->stream_id))
165 return 0;
166
167 if (f->offset != 0 && !WPACKET_quic_write_vlint(pkt, f->offset))
168 return 0;
169
170 if (f->has_explicit_len && !WPACKET_quic_write_vlint(pkt, f->len))
171 return 0;
172
173 return 1;
174}
175
176void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt,
177 const OSSL_QUIC_FRAME_STREAM *f)
178{
179
180 unsigned char *p = NULL;
181
182 if (!ossl_quic_wire_encode_frame_stream_hdr(pkt, f))
183 return NULL;
184
185 if (!WPACKET_allocate_bytes(pkt, f->len, &p))
186 return NULL;
187
188 if (f->data != NULL)
189 memcpy(p, f->data, f->len);
190
191 return p;
192}
193
194int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt,
195 uint64_t max_data)
196{
197 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
198 || !WPACKET_quic_write_vlint(pkt, max_data))
199 return 0;
200
201 return 1;
202}
203
204int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt,
205 uint64_t stream_id,
206 uint64_t max_data)
207{
208 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
209 || !WPACKET_quic_write_vlint(pkt, stream_id)
210 || !WPACKET_quic_write_vlint(pkt, max_data))
211 return 0;
212
213 return 1;
214}
215
216int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt,
217 char is_uni,
218 uint64_t max_streams)
219{
220 if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI
221 : OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI)
222 || !WPACKET_quic_write_vlint(pkt, max_streams))
223 return 0;
224
225 return 1;
226}
227
228int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt,
229 uint64_t max_data)
230{
231 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
232 || !WPACKET_quic_write_vlint(pkt, max_data))
233 return 0;
234
235 return 1;
236}
237
238
239int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt,
240 uint64_t stream_id,
241 uint64_t max_stream_data)
242{
243 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
244 || !WPACKET_quic_write_vlint(pkt, stream_id)
245 || !WPACKET_quic_write_vlint(pkt, max_stream_data))
246 return 0;
247
248 return 1;
249}
250
251int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt,
252 char is_uni,
253 uint64_t max_streams)
254{
255 if (!encode_frame_hdr(pkt, is_uni ? OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI
256 : OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI)
257 || !WPACKET_quic_write_vlint(pkt, max_streams))
258 return 0;
259
260 return 1;
261}
262
263int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt,
264 const OSSL_QUIC_FRAME_NEW_CONN_ID *f)
265{
266 if (f->conn_id.id_len > OSSL_QUIC_MAX_CONN_ID_LEN)
267 return 0;
268
269 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
270 || !WPACKET_quic_write_vlint(pkt, f->seq_num)
271 || !WPACKET_quic_write_vlint(pkt, f->retire_prior_to)
272 || !WPACKET_put_bytes_u8(pkt, f->conn_id.id_len)
273 || !WPACKET_memcpy(pkt, f->conn_id.id, f->conn_id.id_len)
274 || !WPACKET_memcpy(pkt, f->stateless_reset_token,
275 sizeof(f->stateless_reset_token)))
276 return 0;
277
278 return 1;
279}
280
281int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt,
282 uint64_t seq_num)
283{
284 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
285 || !WPACKET_quic_write_vlint(pkt, seq_num))
286 return 0;
287
288 return 1;
289}
290
291int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt,
292 uint64_t data)
293{
294 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
295 || !WPACKET_put_bytes_u64(pkt, data))
296 return 0;
297
298 return 1;
299}
300
301int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt,
302 uint64_t data)
303{
304 if (!encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
305 || !WPACKET_put_bytes_u64(pkt, data))
306 return 0;
307
308 return 1;
309}
310
311int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt,
312 const OSSL_QUIC_FRAME_CONN_CLOSE *f)
313{
314 if (!encode_frame_hdr(pkt, f->is_app ? OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP
315 : OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT)
316 || !WPACKET_quic_write_vlint(pkt, f->error_code))
317 return 0;
318
319 if (!f->is_app && !WPACKET_quic_write_vlint(pkt, f->frame_type))
320 return 0;
321
322 if (!WPACKET_quic_write_vlint(pkt, f->reason_len)
323 || !WPACKET_memcpy(pkt, f->reason, f->reason_len))
324 return 0;
325
326 return 1;
327}
328
329int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt)
330{
331 return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
332}
333
334unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt,
335 uint64_t id,
336 const unsigned char *value,
337 size_t value_len)
338{
339 unsigned char *b = NULL;
340
341 if (!WPACKET_quic_write_vlint(pkt, id)
342 || !WPACKET_quic_write_vlint(pkt, value_len)
343 || !WPACKET_allocate_bytes(pkt, value_len, (unsigned char **)&b))
344 return NULL;
345
346 if (value != NULL)
347 memcpy(b, value, value_len);
348
349 return b;
350}
351
352int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt,
353 uint64_t id,
354 uint64_t value)
355{
356 if (!WPACKET_quic_write_vlint(pkt, id)
357 || !WPACKET_quic_write_vlint(pkt, ossl_quic_vlint_encode_len(value))
358 || !WPACKET_quic_write_vlint(pkt, value))
359 return 0;
360
361 return 1;
362}
363
364/*
365 * QUIC Wire Format Decoding
366 * =========================
367 */
368int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type)
369{
370 return PACKET_peek_quic_vlint(pkt, type);
371}
372
373int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type)
374{
375 return PACKET_get_quic_vlint(pkt, type);
376}
377
378static int expect_frame_header_mask(PACKET *pkt,
379 uint64_t expected_frame_type,
380 uint64_t mask_bits,
381 uint64_t *actual_frame_type)
382{
383 uint64_t actual_frame_type_;
384
385 if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type_)
386 || (actual_frame_type_ & ~mask_bits) != expected_frame_type)
387 return 0;
388
389 if (actual_frame_type != NULL)
390 *actual_frame_type = actual_frame_type_;
391
392 return 1;
393}
394
395static int expect_frame_header(PACKET *pkt, uint64_t expected_frame_type)
396{
397 uint64_t actual_frame_type;
398
399 if (!ossl_quic_wire_skip_frame_header(pkt, &actual_frame_type)
400 || actual_frame_type != expected_frame_type)
401 return 0;
402
403 return 1;
404}
405
406int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *orig_pkt,
407 uint64_t *total_ranges)
408{
409 PACKET pkt = *orig_pkt;
410 uint64_t ack_range_count;
411
412 if (!expect_frame_header_mask(&pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
413 1, NULL)
414 || !PACKET_skip_quic_vlint(&pkt)
415 || !PACKET_skip_quic_vlint(&pkt)
416 || !PACKET_get_quic_vlint(&pkt, &ack_range_count))
417 return 0;
418
419 /* (cannot overflow because QUIC vlints can only encode up to 2**62-1) */
420 *total_ranges = ack_range_count + 1;
421 return 1;
422}
423
424int ossl_quic_wire_decode_frame_ack(PACKET *pkt,
425 uint32_t ack_delay_exponent,
426 OSSL_QUIC_FRAME_ACK *ack,
427 uint64_t *total_ranges) {
428 uint64_t frame_type, largest_ackd, ack_delay_raw;
429 uint64_t ack_range_count, first_ack_range, start, end, i;
430
431 /* This call matches both ACK_WITHOUT_ECN and ACK_WITH_ECN. */
432 if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN,
433 1, &frame_type)
434 || !PACKET_get_quic_vlint(pkt, &largest_ackd)
435 || !PACKET_get_quic_vlint(pkt, &ack_delay_raw)
436 || !PACKET_get_quic_vlint(pkt, &ack_range_count)
437 || !PACKET_get_quic_vlint(pkt, &first_ack_range))
438 return 0;
439
440 if (first_ack_range > largest_ackd)
441 return 0;
442
443 start = largest_ackd - first_ack_range;
444
445 if (ack != NULL) {
446 int err = 0;
447 ack->delay_time
d13c8b77 448 = ossl_time_multiply(ossl_ticks2time(OSSL_TIME_US),
dffafaf4
HL
449 safe_mul_uint64_t(ack_delay_raw,
450 1UL << ack_delay_exponent,
451 &err));
452 if (err)
d13c8b77 453 ack->delay_time = ossl_time_infinite();
dffafaf4
HL
454
455 if (ack->num_ack_ranges > 0) {
456 ack->ack_ranges[0].end = largest_ackd;
457 ack->ack_ranges[0].start = start;
458 }
459 }
460
461 for (i = 0; i < ack_range_count; ++i) {
462 uint64_t gap, len;
463
464 if (!PACKET_get_quic_vlint(pkt, &gap)
465 || !PACKET_get_quic_vlint(pkt, &len))
466 return 0;
467
468 end = start - gap - 2;
469 if (start < gap + 2 || len > end)
470 return 0;
471
472 if (ack != NULL && i + 1 < ack->num_ack_ranges) {
473 ack->ack_ranges[i + 1].start = start = end - len;
474 ack->ack_ranges[i + 1].end = end;
475 }
476 }
477
478 if (ack != NULL && ack_range_count + 1 < ack->num_ack_ranges)
479 ack->num_ack_ranges = ack_range_count + 1;
480
481 if (total_ranges != NULL)
482 *total_ranges = ack_range_count + 1;
483
484 if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) {
485 uint64_t ect0, ect1, ecnce;
486
487 if (!PACKET_get_quic_vlint(pkt, &ect0)
488 || !PACKET_get_quic_vlint(pkt, &ect1)
489 || !PACKET_get_quic_vlint(pkt, &ecnce))
490 return 0;
491
492 if (ack != NULL) {
493 ack->ect0 = ect0;
494 ack->ect1 = ect1;
495 ack->ecnce = ecnce;
496 ack->ecn_present = 1;
497 }
498 } else if (ack != NULL) {
499 ack->ecn_present = 0;
500 }
501
502 return 1;
503}
504
505int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt,
506 OSSL_QUIC_FRAME_RESET_STREAM *f)
507{
508 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RESET_STREAM)
509 || !PACKET_get_quic_vlint(pkt, &f->stream_id)
510 || !PACKET_get_quic_vlint(pkt, &f->app_error_code)
511 || !PACKET_get_quic_vlint(pkt, &f->final_size))
512 return 0;
513
514 return 1;
515}
516
517int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt,
518 OSSL_QUIC_FRAME_STOP_SENDING *f)
519{
520 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STOP_SENDING)
521 || !PACKET_get_quic_vlint(pkt, &f->stream_id)
522 || !PACKET_get_quic_vlint(pkt, &f->app_error_code))
523 return 0;
524
525 return 1;
526}
527
528int ossl_quic_wire_decode_frame_crypto(PACKET *pkt,
529 OSSL_QUIC_FRAME_CRYPTO *f)
530{
531 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)
532 || !PACKET_get_quic_vlint(pkt, &f->offset)
533 || !PACKET_get_quic_vlint(pkt, &f->len))
534 return 0;
535
536 if (PACKET_remaining(pkt) < f->len)
537 return 0;
538
539 f->data = PACKET_data(pkt);
540
541 if (!PACKET_forward(pkt, f->len))
542 return 0;
543
544 return 1;
545}
546
547int ossl_quic_wire_decode_frame_new_token(PACKET *pkt,
548 const unsigned char **token,
549 size_t *token_len)
550{
551 uint64_t token_len_;
552
553 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)
554 || !PACKET_get_quic_vlint(pkt, &token_len_))
555 return 0;
556
557 if (token_len_ > SIZE_MAX)
558 return 0;
559
560 *token = PACKET_data(pkt);
561 *token_len = token_len_;
562
563 if (!PACKET_forward(pkt, token_len_))
564 return 0;
565
566 return 1;
567}
568
569int ossl_quic_wire_decode_frame_stream(PACKET *pkt,
570 OSSL_QUIC_FRAME_STREAM *f)
571{
572 uint64_t frame_type;
573
574 /* This call matches all STREAM values (low 3 bits are masked). */
575 if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAM,
576 OSSL_QUIC_FRAME_FLAG_STREAM_MASK,
577 &frame_type)
578 || !PACKET_get_quic_vlint(pkt, &f->stream_id))
579 return 0;
580
581 if ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_OFF) != 0) {
582 if (!PACKET_get_quic_vlint(pkt, &f->offset))
583 return 0;
584 } else {
585 f->offset = 0;
586 }
587
588 f->has_explicit_len = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_LEN) != 0);
589 f->is_fin = ((frame_type & OSSL_QUIC_FRAME_FLAG_STREAM_FIN) != 0);
590
591 if (f->has_explicit_len) {
592 if (!PACKET_get_quic_vlint(pkt, &f->len))
593 return 0;
594 } else {
595 f->len = PACKET_remaining(pkt);
596 }
597
598 f->data = PACKET_data(pkt);
599
600 if (!PACKET_forward(pkt, f->len))
601 return 0;
602
603 return 1;
604}
605
606int ossl_quic_wire_decode_frame_max_data(PACKET *pkt,
607 uint64_t *max_data)
608{
609 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_DATA)
610 || !PACKET_get_quic_vlint(pkt, max_data))
611 return 0;
612
613 return 1;
614}
615
616int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt,
617 uint64_t *stream_id,
618 uint64_t *max_stream_data)
619{
620 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA)
621 || !PACKET_get_quic_vlint(pkt, stream_id)
622 || !PACKET_get_quic_vlint(pkt, max_stream_data))
623 return 0;
624
625 return 1;
626}
627
628int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt,
629 uint64_t *max_streams)
630{
631 /* This call matches both MAX_STREAMS_BIDI and MAX_STREAMS_UNI. */
632 if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI,
633 1, NULL)
634 || !PACKET_get_quic_vlint(pkt, max_streams))
635 return 0;
636
637 return 1;
638}
639
640int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt,
641 uint64_t *max_data)
642{
643 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED)
644 || !PACKET_get_quic_vlint(pkt, max_data))
645 return 0;
646
647 return 1;
648}
649
650int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt,
651 uint64_t *stream_id,
652 uint64_t *max_stream_data)
653{
654 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED)
655 || !PACKET_get_quic_vlint(pkt, stream_id)
656 || !PACKET_get_quic_vlint(pkt, max_stream_data))
657 return 0;
658
659 return 1;
660}
661
662int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt,
663 uint64_t *max_streams)
664{
665 /* This call matches both STREAMS_BLOCKED_BIDI and STREAMS_BLOCKED_UNI. */
666 if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI,
667 1, NULL)
668 || !PACKET_get_quic_vlint(pkt, max_streams))
669 return 0;
670
671 return 1;
672}
673
674int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt,
675 OSSL_QUIC_FRAME_NEW_CONN_ID *f)
676{
677 unsigned int len;
678
679 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)
680 || !PACKET_get_quic_vlint(pkt, &f->seq_num)
681 || !PACKET_get_quic_vlint(pkt, &f->retire_prior_to)
682 || !PACKET_get_1(pkt, &len)
683 || len > OSSL_QUIC_MAX_CONN_ID_LEN)
684 return 0;
685
686 f->conn_id.id_len = (unsigned char)len;
687 if (!PACKET_copy_bytes(pkt, f->conn_id.id, len))
688 return 0;
689
690 /* Clear unused bytes to allow consistent memcmp. */
691 if (len < OSSL_QUIC_MAX_CONN_ID_LEN)
692 memset(f->conn_id.id + len, 0, OSSL_QUIC_MAX_CONN_ID_LEN - len);
693
694 if (!PACKET_copy_bytes(pkt, f->stateless_reset_token,
695 sizeof(f->stateless_reset_token)))
696 return 0;
697
698 return 1;
699}
700
701int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt,
702 uint64_t *seq_num)
703{
704 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID)
705 || !PACKET_get_quic_vlint(pkt, seq_num))
706 return 0;
707
708 return 1;
709}
710
711int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt,
712 uint64_t *data)
713{
714 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE)
715 || !PACKET_get_net_8(pkt, data))
716 return 0;
717
718 return 1;
719}
720
721int ossl_quic_wire_decode_frame_path_response(PACKET *pkt,
722 uint64_t *data)
723{
724 if (!expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE)
725 || !PACKET_get_net_8(pkt, data))
726 return 0;
727
728 return 1;
729}
730
731int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt,
732 OSSL_QUIC_FRAME_CONN_CLOSE *f)
733{
734 uint64_t frame_type, reason_len;
735
736 /* This call matches both CONN_CLOSE_TRANSPORT and CONN_CLOSE_APP. */
737 if (!expect_frame_header_mask(pkt, OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT,
738 1, &frame_type)
739 || !PACKET_get_quic_vlint(pkt, &f->error_code))
740 return 0;
741
742 f->is_app = ((frame_type & 1) != 0);
743
744 if (!f->is_app) {
745 if (!PACKET_get_quic_vlint(pkt, &f->frame_type))
746 return 0;
747 } else {
748 f->frame_type = 0;
749 }
750
751 if (!PACKET_get_quic_vlint(pkt, &reason_len)
752 || reason_len > SIZE_MAX)
753 return 0;
754
755 if (!PACKET_get_bytes(pkt, (const unsigned char **)&f->reason, reason_len))
756 return 0;
757
758 f->reason_len = reason_len;
759 return 1;
760}
761
762size_t ossl_quic_wire_decode_padding(PACKET *pkt)
763{
764 const unsigned char *start = PACKET_data(pkt), *end = PACKET_end(pkt),
765 *p = start;
766
767 while (p < end && *p == 0)
768 ++p;
769
770 if (!PACKET_forward(pkt, p - start))
771 return 0;
772
773 return p - start;
774}
775
776int ossl_quic_wire_decode_frame_ping(PACKET *pkt)
777{
778 return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING);
779}
780
781int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt)
782{
783 return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE);
784}
785
786int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id)
787{
788 return PACKET_peek_quic_vlint(pkt, id);
789}
790
791const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt,
792 uint64_t *id,
793 size_t *len)
794{
795 uint64_t len_;
796 const unsigned char *b = NULL;
797
798 if (!PACKET_get_quic_vlint(pkt, id)
799 || !PACKET_get_quic_vlint(pkt, &len_))
800 return NULL;
801
802 if (len_ > SIZE_MAX
803 || !PACKET_get_bytes(pkt, (const unsigned char **)&b, (size_t)len_))
804 return NULL;
805
806 *len = (size_t)len_;
807 return b;
808}
809
810int ossl_quic_wire_decode_transport_param_int(PACKET *pkt,
811 uint64_t *id,
812 uint64_t *value)
813{
814 PACKET sub;
815
816 sub.curr = ossl_quic_wire_decode_transport_param_bytes(pkt,
817 id, &sub.remaining);
818 if (sub.curr == NULL)
819 return 0;
820
821 if (!PACKET_get_quic_vlint(&sub, value))
822 return 0;
823
824 return 1;
825}