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
OSSL_SAFE_MATH_UNSIGNED(uint64_t,uint64_t)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
ossl_quic_wire_encode_padding(WPACKET * pkt,size_t num_bytes)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
encode_frame_hdr(WPACKET * pkt,uint64_t frame_type)45 static int encode_frame_hdr(WPACKET *pkt, uint64_t frame_type)
46 {
47 return WPACKET_quic_write_vlint(pkt, frame_type);
48 }
49
ossl_quic_wire_encode_frame_ping(WPACKET * pkt)50 int ossl_quic_wire_encode_frame_ping(WPACKET *pkt)
51 {
52 return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PING);
53 }
54
ossl_quic_wire_encode_frame_ack(WPACKET * pkt,uint32_t ack_delay_exponent,const OSSL_QUIC_FRAME_ACK * ack)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
ossl_quic_wire_encode_frame_reset_stream(WPACKET * pkt,const OSSL_QUIC_FRAME_RESET_STREAM * f)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
ossl_quic_wire_encode_frame_stop_sending(WPACKET * pkt,const OSSL_QUIC_FRAME_STOP_SENDING * f)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
ossl_quic_wire_encode_frame_crypto_hdr(WPACKET * pkt,const OSSL_QUIC_FRAME_CRYPTO * f)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
ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO * f)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
ossl_quic_wire_encode_frame_crypto(WPACKET * pkt,const OSSL_QUIC_FRAME_CRYPTO * f)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
ossl_quic_wire_encode_frame_new_token(WPACKET * pkt,const unsigned char * token,size_t token_len)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
ossl_quic_wire_encode_frame_stream_hdr(WPACKET * pkt,const OSSL_QUIC_FRAME_STREAM * f)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
ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM * f)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
ossl_quic_wire_encode_frame_stream(WPACKET * pkt,const OSSL_QUIC_FRAME_STREAM * f)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
ossl_quic_wire_encode_frame_max_data(WPACKET * pkt,uint64_t max_data)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
ossl_quic_wire_encode_frame_max_stream_data(WPACKET * pkt,uint64_t stream_id,uint64_t max_data)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
ossl_quic_wire_encode_frame_max_streams(WPACKET * pkt,char is_uni,uint64_t max_streams)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
ossl_quic_wire_encode_frame_data_blocked(WPACKET * pkt,uint64_t max_data)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
ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET * pkt,uint64_t stream_id,uint64_t max_stream_data)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
ossl_quic_wire_encode_frame_streams_blocked(WPACKET * pkt,char is_uni,uint64_t max_streams)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
ossl_quic_wire_encode_frame_new_conn_id(WPACKET * pkt,const OSSL_QUIC_FRAME_NEW_CONN_ID * f)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
ossl_quic_wire_encode_frame_retire_conn_id(WPACKET * pkt,uint64_t seq_num)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
ossl_quic_wire_encode_frame_path_challenge(WPACKET * pkt,uint64_t data)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
ossl_quic_wire_encode_frame_path_response(WPACKET * pkt,uint64_t data)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
ossl_quic_wire_encode_frame_conn_close(WPACKET * pkt,const OSSL_QUIC_FRAME_CONN_CLOSE * f)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
ossl_quic_wire_encode_frame_handshake_done(WPACKET * pkt)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
ossl_quic_wire_encode_transport_param_bytes(WPACKET * pkt,uint64_t id,const unsigned char * value,size_t value_len)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
ossl_quic_wire_encode_transport_param_int(WPACKET * pkt,uint64_t id,uint64_t value)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
ossl_quic_wire_encode_transport_param_cid(WPACKET * wpkt,uint64_t id,const QUIC_CONN_ID * cid)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 */
ossl_quic_wire_peek_frame_header(PACKET * pkt,uint64_t * type,int * was_minimal)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
ossl_quic_wire_skip_frame_header(PACKET * pkt,uint64_t * type)451 int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type)
452 {
453 return PACKET_get_quic_vlint(pkt, type);
454 }
455
expect_frame_header_mask(PACKET * pkt,uint64_t expected_frame_type,uint64_t mask_bits,uint64_t * actual_frame_type)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
expect_frame_header(PACKET * pkt,uint64_t expected_frame_type)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
ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET * orig_pkt,uint64_t * total_ranges)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
ossl_quic_wire_decode_frame_ack(PACKET * pkt,uint32_t ack_delay_exponent,OSSL_QUIC_FRAME_ACK * ack,uint64_t * total_ranges)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
ossl_quic_wire_decode_frame_reset_stream(PACKET * pkt,OSSL_QUIC_FRAME_RESET_STREAM * f)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
ossl_quic_wire_decode_frame_stop_sending(PACKET * pkt,OSSL_QUIC_FRAME_STOP_SENDING * f)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
ossl_quic_wire_decode_frame_crypto(PACKET * pkt,int nodata,OSSL_QUIC_FRAME_CRYPTO * f)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
ossl_quic_wire_decode_frame_new_token(PACKET * pkt,const unsigned char ** token,size_t * token_len)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
ossl_quic_wire_decode_frame_stream(PACKET * pkt,int nodata,OSSL_QUIC_FRAME_STREAM * f)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
ossl_quic_wire_decode_frame_max_data(PACKET * pkt,uint64_t * max_data)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
ossl_quic_wire_decode_frame_max_stream_data(PACKET * pkt,uint64_t * stream_id,uint64_t * max_stream_data)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
ossl_quic_wire_decode_frame_max_streams(PACKET * pkt,uint64_t * max_streams)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
ossl_quic_wire_decode_frame_data_blocked(PACKET * pkt,uint64_t * max_data)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
ossl_quic_wire_decode_frame_stream_data_blocked(PACKET * pkt,uint64_t * stream_id,uint64_t * max_stream_data)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
ossl_quic_wire_decode_frame_streams_blocked(PACKET * pkt,uint64_t * max_streams)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
ossl_quic_wire_decode_frame_new_conn_id(PACKET * pkt,OSSL_QUIC_FRAME_NEW_CONN_ID * f)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
ossl_quic_wire_decode_frame_retire_conn_id(PACKET * pkt,uint64_t * seq_num)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
ossl_quic_wire_decode_frame_path_challenge(PACKET * pkt,uint64_t * data)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
ossl_quic_wire_decode_frame_path_response(PACKET * pkt,uint64_t * data)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
ossl_quic_wire_decode_frame_conn_close(PACKET * pkt,OSSL_QUIC_FRAME_CONN_CLOSE * f)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
ossl_quic_wire_decode_padding(PACKET * pkt)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
ossl_quic_wire_decode_frame_ping(PACKET * pkt)900 int ossl_quic_wire_decode_frame_ping(PACKET *pkt)
901 {
902 return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING);
903 }
904
ossl_quic_wire_decode_frame_handshake_done(PACKET * pkt)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
ossl_quic_wire_peek_transport_param(PACKET * pkt,uint64_t * id)910 int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id)
911 {
912 return PACKET_peek_quic_vlint(pkt, id);
913 }
914
ossl_quic_wire_decode_transport_param_bytes(PACKET * pkt,uint64_t * id,size_t * len)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
ossl_quic_wire_decode_transport_param_int(PACKET * pkt,uint64_t * id,uint64_t * value)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
ossl_quic_wire_decode_transport_param_cid(PACKET * pkt,uint64_t * id,QUIC_CONN_ID * cid)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
ossl_quic_wire_decode_transport_param_preferred_addr(PACKET * pkt,QUIC_PREFERRED_ADDR * p)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 *
ossl_quic_frame_type_to_string(uint64_t frame_type)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
ossl_quic_err_to_string(uint64_t error_code)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