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