1 /* 2 * Copyright 2016-2025 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 <string.h> 11 #include <openssl/buffer.h> 12 #include <openssl/rand.h> 13 #include "internal/packet_quic.h" 14 #include "testutil.h" 15 16 static const unsigned char simple1[] = { 0xff }; 17 static const unsigned char simple2[] = { 0x01, 0xff }; 18 static const unsigned char simple3[] = { 0x00, 0x00, 0x00, 0x01, 0xff }; 19 static const unsigned char nestedsub[] = { 0x03, 0xff, 0x01, 0xff }; 20 static const unsigned char seqsub[] = { 0x01, 0xff, 0x01, 0xff }; 21 static const unsigned char empty[] = { 0x00 }; 22 static const unsigned char alloc[] = { 0x02, 0xfe, 0xff }; 23 static const unsigned char submem[] = { 0x03, 0x02, 0xfe, 0xff }; 24 static const unsigned char fixed[] = { 0xff, 0xff, 0xff }; 25 static const unsigned char simpleder[] = { 26 0xfc, 0x04, 0x00, 0x01, 0x02, 0x03, 0xff, 0xfe, 0xfd 27 }; 28 29 #ifndef OPENSSL_NO_QUIC 30 31 /* QUIC sub-packet with 4-byte length prefix, containing a 1-byte vlint */ 32 static const unsigned char quic1[] = { 0x80, 0x00, 0x00, 0x01, 0x09 }; 33 /* QUIC sub-packet with 1-byte length prefix, containing a 1-byte vlint */ 34 static const unsigned char quic2[] = { 0x01, 0x09 }; 35 /* QUIC sub-packet with 2-byte length prefix, containing a 2-byte vlint */ 36 static const unsigned char quic3[] = { 0x40, 0x02, 0x40, 0x41 }; 37 /* QUIC sub-packet with 8-byte length prefix, containing a 4-byte vlint */ 38 static const unsigned char quic4[] = { 39 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 40 0x80, 0x01, 0x3c, 0x6a 41 }; 42 /* QUIC sub-packet with 8-byte length prefix, containing a 8-byte vlint */ 43 static const unsigned char quic5[] = { 44 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 45 0xef, 0x77, 0x21, 0x3f, 0x3f, 0x50, 0x5b, 0xa5 46 }; 47 /* QUIC sub-packet, length known up-front */ 48 static const unsigned char quic6[] = { 0x03, 0x55, 0x66, 0x77 }; 49 /* Nested and sequential sub-packets with length prefixes */ 50 static const unsigned char quic7[] = { 51 0x07, 0x80, 0x00, 0x00, 0x08, 0x65, 0x14, 0x40, 0x01, 0x05, 52 0x40, 0x01, 0x11, 0x40, 0x01, 0x12, 0x40, 0x01, 0x13 53 }; 54 55 #endif 56 57 static BUF_MEM *buf; 58 59 static int cleanup(WPACKET *pkt) 60 { 61 WPACKET_cleanup(pkt); 62 return 0; 63 } 64 65 static int test_WPACKET_init(void) 66 { 67 WPACKET pkt; 68 int i; 69 size_t written; 70 unsigned char sbuf[3]; 71 72 if (!TEST_true(WPACKET_init(&pkt, buf)) 73 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 74 /* Closing a top level WPACKET should fail */ 75 || !TEST_false(WPACKET_close(&pkt)) 76 /* Finishing a top level WPACKET should succeed */ 77 || !TEST_true(WPACKET_finish(&pkt)) 78 /* 79 * Can't call close or finish on a WPACKET that's already 80 * finished. 81 */ 82 || !TEST_false(WPACKET_close(&pkt)) 83 || !TEST_false(WPACKET_finish(&pkt)) 84 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 85 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 86 return cleanup(&pkt); 87 88 /* Now try with a one byte length prefix */ 89 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 90 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 91 || !TEST_true(WPACKET_finish(&pkt)) 92 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 93 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 94 return cleanup(&pkt); 95 96 /* And a longer length prefix */ 97 if (!TEST_true(WPACKET_init_len(&pkt, buf, 4)) 98 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 99 || !TEST_true(WPACKET_finish(&pkt)) 100 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 101 || !TEST_mem_eq(buf->data, written, simple3, sizeof(simple3))) 102 return cleanup(&pkt); 103 104 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))) 105 return cleanup(&pkt); 106 for (i = 1; i < 257; i++) { 107 /* 108 * Putting more bytes in than fit for the size of the length prefix 109 * should fail 110 */ 111 if (!TEST_int_eq(WPACKET_put_bytes_u8(&pkt, 0xff), i < 256)) 112 return cleanup(&pkt); 113 } 114 if (!TEST_true(WPACKET_finish(&pkt))) 115 return cleanup(&pkt); 116 117 /* Test initialising from a fixed size buffer */ 118 if (!TEST_true(WPACKET_init_static_len(&pkt, sbuf, sizeof(sbuf), 0)) 119 /* Adding 3 bytes should succeed */ 120 || !TEST_true(WPACKET_put_bytes_u24(&pkt, 0xffffff)) 121 /* Adding 1 more byte should fail */ 122 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 123 /* Finishing the top level WPACKET should succeed */ 124 || !TEST_true(WPACKET_finish(&pkt)) 125 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 126 || !TEST_mem_eq(sbuf, written, fixed, sizeof(sbuf)) 127 /* Initialise with 1 len byte */ 128 || !TEST_true(WPACKET_init_static_len(&pkt, sbuf, sizeof(sbuf), 1)) 129 /* Adding 2 bytes should succeed */ 130 || !TEST_true(WPACKET_put_bytes_u16(&pkt, 0xfeff)) 131 /* Adding 1 more byte should fail */ 132 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 133 || !TEST_true(WPACKET_finish(&pkt)) 134 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 135 || !TEST_mem_eq(sbuf, written, alloc, sizeof(alloc))) 136 return cleanup(&pkt); 137 138 return 1; 139 } 140 141 static int test_WPACKET_set_max_size(void) 142 { 143 WPACKET pkt; 144 size_t written; 145 146 if (!TEST_true(WPACKET_init(&pkt, buf)) 147 /* 148 * No previous lenbytes set so we should be ok to set the max 149 * possible max size 150 */ 151 || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX)) 152 /* We should be able to set it smaller too */ 153 || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX -1)) 154 /* And setting it bigger again should be ok */ 155 || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX)) 156 || !TEST_true(WPACKET_finish(&pkt))) 157 return cleanup(&pkt); 158 159 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 160 /* 161 * Should fail because we already consumed 1 byte with the 162 * length 163 */ 164 || !TEST_false(WPACKET_set_max_size(&pkt, 0)) 165 /* 166 * Max size can't be bigger than biggest that will fit in 167 * lenbytes 168 */ 169 || !TEST_false(WPACKET_set_max_size(&pkt, 0x0101)) 170 /* It can be the same as the maximum possible size */ 171 || !TEST_true(WPACKET_set_max_size(&pkt, 0x0100)) 172 /* Or it can be less */ 173 || !TEST_true(WPACKET_set_max_size(&pkt, 0x01)) 174 /* Should fail because packet is already filled */ 175 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 176 /* You can't put in more bytes than max size */ 177 || !TEST_true(WPACKET_set_max_size(&pkt, 0x02)) 178 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 179 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 180 || !TEST_true(WPACKET_finish(&pkt)) 181 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 182 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 183 return cleanup(&pkt); 184 185 return 1; 186 } 187 188 static int test_WPACKET_start_sub_packet(void) 189 { 190 WPACKET pkt; 191 size_t written; 192 size_t len; 193 194 if (!TEST_true(WPACKET_init(&pkt, buf)) 195 || !TEST_true(WPACKET_start_sub_packet(&pkt)) 196 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 197 /* Can't finish because we have a sub packet */ 198 || !TEST_false(WPACKET_finish(&pkt)) 199 || !TEST_true(WPACKET_close(&pkt)) 200 /* Sub packet is closed so can't close again */ 201 || !TEST_false(WPACKET_close(&pkt)) 202 /* Now a top level so finish should succeed */ 203 || !TEST_true(WPACKET_finish(&pkt)) 204 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 205 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 206 return cleanup(&pkt); 207 208 /* Single sub-packet with length prefix */ 209 if (!TEST_true(WPACKET_init(&pkt, buf)) 210 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 211 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 212 || !TEST_true(WPACKET_close(&pkt)) 213 || !TEST_true(WPACKET_finish(&pkt)) 214 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 215 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 216 return cleanup(&pkt); 217 218 /* Nested sub-packets with length prefixes */ 219 if (!TEST_true(WPACKET_init(&pkt, buf)) 220 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 221 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 222 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 223 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 224 || !TEST_true(WPACKET_get_length(&pkt, &len)) 225 || !TEST_size_t_eq(len, 1) 226 || !TEST_true(WPACKET_close(&pkt)) 227 || !TEST_true(WPACKET_get_length(&pkt, &len)) 228 || !TEST_size_t_eq(len, 3) 229 || !TEST_true(WPACKET_close(&pkt)) 230 || !TEST_true(WPACKET_finish(&pkt)) 231 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 232 || !TEST_mem_eq(buf->data, written, nestedsub, sizeof(nestedsub))) 233 return cleanup(&pkt); 234 235 /* Sequential sub-packets with length prefixes */ 236 if (!TEST_true(WPACKET_init(&pkt, buf)) 237 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 238 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 239 || !TEST_true(WPACKET_close(&pkt)) 240 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 241 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 242 || !TEST_true(WPACKET_close(&pkt)) 243 || !TEST_true(WPACKET_finish(&pkt)) 244 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 245 || !TEST_mem_eq(buf->data, written, seqsub, sizeof(seqsub))) 246 return cleanup(&pkt); 247 248 /* Nested sub-packets with lengths filled before finish */ 249 if (!TEST_true(WPACKET_init(&pkt, buf)) 250 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 251 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 252 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 253 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 254 || !TEST_true(WPACKET_get_length(&pkt, &len)) 255 || !TEST_size_t_eq(len, 1) 256 || !TEST_true(WPACKET_close(&pkt)) 257 || !TEST_true(WPACKET_get_length(&pkt, &len)) 258 || !TEST_size_t_eq(len, 3) 259 || !TEST_true(WPACKET_close(&pkt)) 260 || !TEST_true(WPACKET_fill_lengths(&pkt)) 261 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 262 || !TEST_mem_eq(buf->data, written, nestedsub, sizeof(nestedsub)) 263 || !TEST_true(WPACKET_finish(&pkt))) 264 return cleanup(&pkt); 265 266 return 1; 267 } 268 269 270 static int test_WPACKET_set_flags(void) 271 { 272 WPACKET pkt; 273 size_t written; 274 275 /* Set packet to be non-zero length */ 276 if (!TEST_true(WPACKET_init(&pkt, buf)) 277 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)) 278 /* Should fail because of zero length */ 279 || !TEST_false(WPACKET_finish(&pkt)) 280 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 281 || !TEST_true(WPACKET_finish(&pkt)) 282 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 283 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 284 return cleanup(&pkt); 285 286 /* Repeat above test in a sub-packet */ 287 if (!TEST_true(WPACKET_init(&pkt, buf)) 288 || !TEST_true(WPACKET_start_sub_packet(&pkt)) 289 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)) 290 /* Should fail because of zero length */ 291 || !TEST_false(WPACKET_close(&pkt)) 292 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 293 || !TEST_true(WPACKET_close(&pkt)) 294 || !TEST_true(WPACKET_finish(&pkt)) 295 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 296 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 297 return cleanup(&pkt); 298 299 /* Set packet to abandon non-zero length */ 300 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 301 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) 302 || !TEST_true(WPACKET_finish(&pkt)) 303 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 304 || !TEST_size_t_eq(written, 0)) 305 return cleanup(&pkt); 306 307 /* Repeat above test but only abandon a sub-packet */ 308 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 309 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 310 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) 311 || !TEST_true(WPACKET_close(&pkt)) 312 || !TEST_true(WPACKET_finish(&pkt)) 313 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 314 || !TEST_mem_eq(buf->data, written, empty, sizeof(empty))) 315 return cleanup(&pkt); 316 317 /* And repeat with a non empty sub-packet */ 318 if (!TEST_true(WPACKET_init(&pkt, buf)) 319 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 320 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) 321 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 322 || !TEST_true(WPACKET_close(&pkt)) 323 || !TEST_true(WPACKET_finish(&pkt)) 324 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 325 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 326 return cleanup(&pkt); 327 return 1; 328 } 329 330 static int test_WPACKET_allocate_bytes(void) 331 { 332 WPACKET pkt; 333 size_t written; 334 unsigned char *bytes; 335 336 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 337 || !TEST_true(WPACKET_allocate_bytes(&pkt, 2, &bytes))) 338 return cleanup(&pkt); 339 bytes[0] = 0xfe; 340 bytes[1] = 0xff; 341 if (!TEST_true(WPACKET_finish(&pkt)) 342 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 343 || !TEST_mem_eq(buf->data, written, alloc, sizeof(alloc))) 344 return cleanup(&pkt); 345 346 /* Repeat with WPACKET_sub_allocate_bytes */ 347 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 348 || !TEST_true(WPACKET_sub_allocate_bytes_u8(&pkt, 2, &bytes))) 349 return cleanup(&pkt); 350 bytes[0] = 0xfe; 351 bytes[1] = 0xff; 352 if (!TEST_true(WPACKET_finish(&pkt)) 353 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 354 || !TEST_mem_eq(buf->data, written, submem, sizeof(submem))) 355 return cleanup(&pkt); 356 357 return 1; 358 } 359 360 static int test_WPACKET_memcpy(void) 361 { 362 WPACKET pkt; 363 size_t written; 364 const unsigned char bytes[] = { 0xfe, 0xff }; 365 366 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 367 || !TEST_true(WPACKET_memcpy(&pkt, bytes, sizeof(bytes))) 368 || !TEST_true(WPACKET_finish(&pkt)) 369 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 370 || !TEST_mem_eq(buf->data, written, alloc, sizeof(alloc))) 371 return cleanup(&pkt); 372 373 /* Repeat with WPACKET_sub_memcpy() */ 374 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 375 || !TEST_true(WPACKET_sub_memcpy_u8(&pkt, bytes, sizeof(bytes))) 376 || !TEST_true(WPACKET_finish(&pkt)) 377 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 378 || !TEST_mem_eq(buf->data, written, submem, sizeof(submem))) 379 return cleanup(&pkt); 380 381 return 1; 382 } 383 384 static int test_WPACKET_init_der(void) 385 { 386 WPACKET pkt; 387 unsigned char sbuf[1024]; 388 unsigned char testdata[] = { 0x00, 0x01, 0x02, 0x03 }; 389 unsigned char testdata2[259] = { 0x82, 0x01, 0x00 }; 390 size_t written[2]; 391 size_t size1, size2; 392 int flags = WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH; 393 int i; 394 395 /* Test initialising for writing DER */ 396 if (!TEST_true(WPACKET_init_der(&pkt, sbuf, sizeof(sbuf))) 397 || !TEST_true(WPACKET_put_bytes_u24(&pkt, 0xfffefd)) 398 /* Test writing data in a length prefixed sub-packet */ 399 || !TEST_true(WPACKET_start_sub_packet(&pkt)) 400 || !TEST_true(WPACKET_memcpy(&pkt, testdata, sizeof(testdata))) 401 || !TEST_true(WPACKET_close(&pkt)) 402 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xfc)) 403 /* this sub-packet is empty, and should render zero bytes */ 404 || (!TEST_true(WPACKET_start_sub_packet(&pkt)) 405 || !TEST_true(WPACKET_set_flags(&pkt, flags)) 406 || !TEST_true(WPACKET_get_total_written(&pkt, &size1)) 407 || !TEST_true(WPACKET_close(&pkt)) 408 || !TEST_true(WPACKET_get_total_written(&pkt, &size2)) 409 || !TEST_size_t_eq(size1, size2)) 410 || !TEST_true(WPACKET_finish(&pkt)) 411 || !TEST_true(WPACKET_get_total_written(&pkt, &written[0])) 412 || !TEST_mem_eq(WPACKET_get_curr(&pkt), written[0], simpleder, 413 sizeof(simpleder))) 414 return cleanup(&pkt); 415 416 /* Generate random packet data for test */ 417 if (!TEST_int_gt(RAND_bytes(&testdata2[3], sizeof(testdata2) - 3), 0)) 418 return 0; 419 420 /* 421 * Test with a sub-packet that has 2 length bytes. We do 2 passes - first 422 * with a NULL buffer, just to calculate lengths, and a second pass with a 423 * real buffer to actually generate a packet 424 */ 425 for (i = 0; i < 2; i++) { 426 if (i == 0) { 427 if (!TEST_true(WPACKET_init_null_der(&pkt))) 428 return 0; 429 } else { 430 if (!TEST_true(WPACKET_init_der(&pkt, sbuf, sizeof(sbuf)))) 431 return 0; 432 } 433 if (!TEST_true(WPACKET_start_sub_packet(&pkt)) 434 || !TEST_true(WPACKET_memcpy(&pkt, &testdata2[3], 435 sizeof(testdata2) - 3)) 436 || !TEST_true(WPACKET_close(&pkt)) 437 || !TEST_true(WPACKET_finish(&pkt)) 438 || !TEST_true(WPACKET_get_total_written(&pkt, &written[i]))) 439 return cleanup(&pkt); 440 } 441 442 /* 443 * Check that the size calculated in the first pass equals the size of the 444 * packet actually generated in the second pass. Also check the generated 445 * packet looks as we expect it to. 446 */ 447 if (!TEST_size_t_eq(written[0], written[1]) 448 || !TEST_mem_eq(WPACKET_get_curr(&pkt), written[1], testdata2, 449 sizeof(testdata2))) 450 return 0; 451 452 return 1; 453 } 454 455 #ifndef OPENSSL_NO_QUIC 456 457 static int test_WPACKET_quic(void) 458 { 459 WPACKET pkt; 460 size_t written, len; 461 unsigned char *bytes; 462 463 /* QUIC sub-packet with 4-byte length prefix, containing a 1-byte vlint */ 464 if (!TEST_true(WPACKET_init(&pkt, buf)) 465 || !TEST_true(WPACKET_start_quic_sub_packet(&pkt)) 466 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x09)) 467 /* Can't finish because we have a sub packet */ 468 || !TEST_false(WPACKET_finish(&pkt)) 469 || !TEST_true(WPACKET_close(&pkt)) 470 /* Sub packet is closed so can't close again */ 471 || !TEST_false(WPACKET_close(&pkt)) 472 /* Now a top level so finish should succeed */ 473 || !TEST_true(WPACKET_finish(&pkt)) 474 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 475 || !TEST_mem_eq(buf->data, written, quic1, sizeof(quic1))) 476 return cleanup(&pkt); 477 478 /* QUIC sub-packet with 1-byte length prefix, containing a 1-byte vlint */ 479 if (!TEST_true(WPACKET_init(&pkt, buf)) 480 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_1B_MAX)) 481 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x09)) 482 || !TEST_false(WPACKET_finish(&pkt)) 483 || !TEST_true(WPACKET_close(&pkt)) 484 || !TEST_false(WPACKET_close(&pkt)) 485 || !TEST_true(WPACKET_finish(&pkt)) 486 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 487 || !TEST_mem_eq(buf->data, written, quic2, sizeof(quic2))) 488 return cleanup(&pkt); 489 490 /* QUIC sub-packet with 2-byte length prefix, containing a 2-byte vlint */ 491 if (!TEST_true(WPACKET_init(&pkt, buf)) 492 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN)) 493 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x41)) 494 || !TEST_false(WPACKET_finish(&pkt)) 495 || !TEST_true(WPACKET_close(&pkt)) 496 || !TEST_false(WPACKET_close(&pkt)) 497 || !TEST_true(WPACKET_finish(&pkt)) 498 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 499 || !TEST_mem_eq(buf->data, written, quic3, sizeof(quic3))) 500 return cleanup(&pkt); 501 502 /* QUIC sub-packet with 8-byte length prefix, containing a 4-byte vlint */ 503 if (!TEST_true(WPACKET_init(&pkt, buf)) 504 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_8B_MIN)) 505 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x13c6a)) 506 || !TEST_false(WPACKET_finish(&pkt)) 507 || !TEST_true(WPACKET_close(&pkt)) 508 || !TEST_false(WPACKET_close(&pkt)) 509 || !TEST_true(WPACKET_finish(&pkt)) 510 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 511 || !TEST_mem_eq(buf->data, written, quic4, sizeof(quic4))) 512 return cleanup(&pkt); 513 514 /* QUIC sub-packet with 8-byte length prefix, containing a 8-byte vlint */ 515 if (!TEST_true(WPACKET_init(&pkt, buf)) 516 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_8B_MIN)) 517 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x2f77213f3f505ba5ULL)) 518 || !TEST_false(WPACKET_finish(&pkt)) 519 || !TEST_true(WPACKET_close(&pkt)) 520 || !TEST_false(WPACKET_close(&pkt)) 521 || !TEST_true(WPACKET_finish(&pkt)) 522 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 523 || !TEST_mem_eq(buf->data, written, quic5, sizeof(quic5))) 524 return cleanup(&pkt); 525 526 /* QUIC sub-packet, length known up-front */ 527 if (!TEST_true(WPACKET_init(&pkt, buf)) 528 || !TEST_true(WPACKET_quic_sub_allocate_bytes(&pkt, 3, &bytes))) 529 return cleanup(&pkt); 530 531 bytes[0] = 0x55; 532 bytes[1] = 0x66; 533 bytes[2] = 0x77; 534 535 if (!TEST_true(WPACKET_finish(&pkt)) 536 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 537 || !TEST_mem_eq(buf->data, written, quic6, sizeof(quic6))) 538 return cleanup(&pkt); 539 540 /* Nested and sequential sub-packets with length prefixes */ 541 if (!TEST_true(WPACKET_init(&pkt, buf)) 542 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x07)) 543 || !TEST_true(WPACKET_get_length(&pkt, &len)) 544 || !TEST_size_t_eq(len, 1) 545 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_4B_MIN)) 546 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x2514)) 547 || !TEST_true(WPACKET_get_length(&pkt, &len)) 548 || !TEST_size_t_eq(len, 2) 549 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN)) 550 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x05)) 551 || !TEST_true(WPACKET_get_length(&pkt, &len)) 552 || !TEST_size_t_eq(len, 1) 553 || !TEST_true(WPACKET_close(&pkt)) 554 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN)) 555 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x11)) 556 || !TEST_true(WPACKET_close(&pkt)) 557 || !TEST_true(WPACKET_get_length(&pkt, &len)) 558 || !TEST_size_t_eq(len, 8) 559 || !TEST_true(WPACKET_close(&pkt)) 560 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN)) 561 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x12)) 562 || !TEST_true(WPACKET_close(&pkt)) 563 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt, OSSL_QUIC_VLINT_2B_MIN)) 564 || !TEST_true(WPACKET_quic_write_vlint(&pkt, 0x13)) 565 || !TEST_true(WPACKET_close(&pkt)) 566 || !TEST_true(WPACKET_finish(&pkt)) 567 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 568 || !TEST_mem_eq(buf->data, written, quic7, sizeof(quic7))) 569 return cleanup(&pkt); 570 571 /* Trying to encode a value above OSSL_QUIC_VLINT_MAX should fail */ 572 if (!TEST_true(WPACKET_init(&pkt, buf)) 573 || !TEST_false(WPACKET_quic_write_vlint(&pkt, OSSL_QUIC_VLINT_MAX+1)) 574 || !TEST_true(WPACKET_quic_write_vlint(&pkt, OSSL_QUIC_VLINT_MAX))) 575 return cleanup(&pkt); 576 577 WPACKET_cleanup(&pkt); 578 return 1; 579 } 580 581 static int test_WPACKET_quic_vlint_random(void) 582 { 583 size_t i, written; 584 uint64_t expected, actual = 0; 585 unsigned char rand_data[9]; 586 WPACKET pkt; 587 PACKET read_pkt = {0}; 588 589 for (i = 0; i < 10000; ++i) { 590 if (!TEST_int_gt(RAND_bytes(rand_data, sizeof(rand_data)), 0)) 591 return cleanup(&pkt); 592 593 memcpy(&expected, rand_data, sizeof(expected)); 594 595 /* 596 * Ensure that all size classes get tested with equal probability. 597 */ 598 switch (rand_data[8] & 3) { 599 case 0: 600 expected &= OSSL_QUIC_VLINT_1B_MAX; 601 break; 602 case 1: 603 expected &= OSSL_QUIC_VLINT_2B_MAX; 604 break; 605 case 2: 606 expected &= OSSL_QUIC_VLINT_4B_MAX; 607 break; 608 case 3: 609 expected &= OSSL_QUIC_VLINT_8B_MAX; 610 break; 611 } 612 613 if (!TEST_true(WPACKET_init(&pkt, buf)) 614 || !TEST_true(WPACKET_quic_write_vlint(&pkt, expected)) 615 || !TEST_true(WPACKET_get_total_written(&pkt, &written))) 616 return cleanup(&pkt); 617 618 if (!TEST_true(PACKET_buf_init(&read_pkt, (unsigned char *)buf->data, written)) 619 || !TEST_true(PACKET_get_quic_vlint(&read_pkt, &actual)) 620 || !TEST_uint64_t_eq(expected, actual)) 621 return cleanup(&pkt); 622 623 WPACKET_cleanup(&pkt); 624 } 625 626 WPACKET_cleanup(&pkt); 627 return 1; 628 } 629 630 #endif 631 632 int setup_tests(void) 633 { 634 if (!TEST_ptr(buf = BUF_MEM_new())) 635 return 0; 636 637 ADD_TEST(test_WPACKET_init); 638 ADD_TEST(test_WPACKET_set_max_size); 639 ADD_TEST(test_WPACKET_start_sub_packet); 640 ADD_TEST(test_WPACKET_set_flags); 641 ADD_TEST(test_WPACKET_allocate_bytes); 642 ADD_TEST(test_WPACKET_memcpy); 643 ADD_TEST(test_WPACKET_init_der); 644 #ifndef OPENSSL_NO_QUIC 645 ADD_TEST(test_WPACKET_quic); 646 ADD_TEST(test_WPACKET_quic_vlint_random); 647 #endif 648 return 1; 649 } 650 651 void cleanup_tests(void) 652 { 653 BUF_MEM_free(buf); 654 } 655