]>
Commit | Line | Data |
---|---|---|
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 | ||
16 | OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t) | |
17 | ||
18 | /* | |
19 | * QUIC Wire Format Encoding | |
20 | * ========================= | |
21 | */ | |
22 | ||
23 | int 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 | ||
32 | static int encode_frame_hdr(WPACKET *pkt, uint64_t frame_type) | |
33 | { | |
34 | return WPACKET_quic_write_vlint(pkt, frame_type); | |
35 | } | |
36 | ||
37 | int ossl_quic_wire_encode_frame_ping(WPACKET *pkt) | |
38 | { | |
39 | return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_PING); | |
40 | } | |
41 | ||
42 | int 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 | ||
90 | int 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 | ||
102 | int 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 | ||
113 | int 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 | ||
124 | void *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 | ||
139 | int 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 | ||
151 | int 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 | ||
176 | void *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 | ||
194 | int 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 | ||
204 | int 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 | ||
216 | int 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 | ||
228 | int 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 | ||
239 | int 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 | ||
251 | int 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 | ||
263 | int 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 | ||
281 | int 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 | ||
291 | int 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 | ||
301 | int 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 | ||
311 | int 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 | ||
329 | int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt) | |
330 | { | |
331 | return encode_frame_hdr(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE); | |
332 | } | |
333 | ||
334 | unsigned 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 | ||
352 | int 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 | */ | |
368 | int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type) | |
369 | { | |
370 | return PACKET_peek_quic_vlint(pkt, type); | |
371 | } | |
372 | ||
373 | int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type) | |
374 | { | |
375 | return PACKET_get_quic_vlint(pkt, type); | |
376 | } | |
377 | ||
378 | static 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 | ||
395 | static 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 | ||
406 | int 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 | ||
424 | int 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 | ||
505 | int 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 | ||
517 | int 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 | ||
528 | int 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 | ||
547 | int 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 | ||
569 | int 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 | ||
606 | int 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 | ||
616 | int 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 | ||
628 | int 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 | ||
640 | int 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 | ||
650 | int 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 | ||
662 | int 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 | ||
674 | int 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 | ||
701 | int 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 | ||
711 | int 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 | ||
721 | int 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 | ||
731 | int 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 | ||
762 | size_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 | ||
776 | int ossl_quic_wire_decode_frame_ping(PACKET *pkt) | |
777 | { | |
778 | return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_PING); | |
779 | } | |
780 | ||
781 | int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt) | |
782 | { | |
783 | return expect_frame_header(pkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE); | |
784 | } | |
785 | ||
786 | int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id) | |
787 | { | |
788 | return PACKET_peek_quic_vlint(pkt, id); | |
789 | } | |
790 | ||
791 | const 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 | ||
810 | int 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 | } |