2 * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/buffer.h>
12 #include <openssl/rand.h>
13 #include "internal/packet.h"
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
29 /* QUIC sub-packet with 4-byte length prefix, containing a 1-byte vlint */
30 static const unsigned char quic1
[] = { 0x80, 0x00, 0x00, 0x01, 0x09 };
31 /* QUIC sub-packet with 1-byte length prefix, containing a 1-byte vlint */
32 static const unsigned char quic2
[] = { 0x01, 0x09 };
33 /* QUIC sub-packet with 2-byte length prefix, containing a 2-byte vlint */
34 static const unsigned char quic3
[] = { 0x40, 0x02, 0x40, 0x41 };
35 /* QUIC sub-packet with 8-byte length prefix, containing a 4-byte vlint */
36 static const unsigned char quic4
[] = {
37 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
38 0x80, 0x01, 0x3c, 0x6a
40 /* QUIC sub-packet with 8-byte length prefix, containing a 8-byte vlint */
41 static const unsigned char quic5
[] = {
42 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
43 0xef, 0x77, 0x21, 0x3f, 0x3f, 0x50, 0x5b, 0xa5
45 /* QUIC sub-packet, length known up-front */
46 static const unsigned char quic6
[] = { 0x03, 0x55, 0x66, 0x77 };
47 /* Nested and sequential sub-packets with length prefixes */
48 static const unsigned char quic7
[] = {
49 0x07, 0x80, 0x00, 0x00, 0x08, 0x65, 0x14, 0x40, 0x01, 0x05,
50 0x40, 0x01, 0x11, 0x40, 0x01, 0x12, 0x40, 0x01, 0x13
55 static int cleanup(WPACKET
*pkt
)
61 static int test_WPACKET_init(void)
66 unsigned char sbuf
[3];
68 if (!TEST_true(WPACKET_init(&pkt
, buf
))
69 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
70 /* Closing a top level WPACKET should fail */
71 || !TEST_false(WPACKET_close(&pkt
))
72 /* Finishing a top level WPACKET should succeed */
73 || !TEST_true(WPACKET_finish(&pkt
))
75 * Can't call close or finish on a WPACKET that's already
78 || !TEST_false(WPACKET_close(&pkt
))
79 || !TEST_false(WPACKET_finish(&pkt
))
80 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
81 || !TEST_mem_eq(buf
->data
, written
, simple1
, sizeof(simple1
)))
84 /* Now try with a one byte length prefix */
85 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
86 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
87 || !TEST_true(WPACKET_finish(&pkt
))
88 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
89 || !TEST_mem_eq(buf
->data
, written
, simple2
, sizeof(simple2
)))
92 /* And a longer length prefix */
93 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 4))
94 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
95 || !TEST_true(WPACKET_finish(&pkt
))
96 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
97 || !TEST_mem_eq(buf
->data
, written
, simple3
, sizeof(simple3
)))
100 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1)))
101 return cleanup(&pkt
);
102 for (i
= 1; i
< 257; i
++) {
104 * Putting more bytes in than fit for the size of the length prefix
107 if (!TEST_int_eq(WPACKET_put_bytes_u8(&pkt
, 0xff), i
< 256))
108 return cleanup(&pkt
);
110 if (!TEST_true(WPACKET_finish(&pkt
)))
111 return cleanup(&pkt
);
113 /* Test initialising from a fixed size buffer */
114 if (!TEST_true(WPACKET_init_static_len(&pkt
, sbuf
, sizeof(sbuf
), 0))
115 /* Adding 3 bytes should succeed */
116 || !TEST_true(WPACKET_put_bytes_u24(&pkt
, 0xffffff))
117 /* Adding 1 more byte should fail */
118 || !TEST_false(WPACKET_put_bytes_u8(&pkt
, 0xff))
119 /* Finishing the top level WPACKET should succeed */
120 || !TEST_true(WPACKET_finish(&pkt
))
121 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
122 || !TEST_mem_eq(sbuf
, written
, fixed
, sizeof(sbuf
))
123 /* Initialise with 1 len byte */
124 || !TEST_true(WPACKET_init_static_len(&pkt
, sbuf
, sizeof(sbuf
), 1))
125 /* Adding 2 bytes should succeed */
126 || !TEST_true(WPACKET_put_bytes_u16(&pkt
, 0xfeff))
127 /* Adding 1 more byte should fail */
128 || !TEST_false(WPACKET_put_bytes_u8(&pkt
, 0xff))
129 || !TEST_true(WPACKET_finish(&pkt
))
130 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
131 || !TEST_mem_eq(sbuf
, written
, alloc
, sizeof(alloc
)))
132 return cleanup(&pkt
);
137 static int test_WPACKET_set_max_size(void)
142 if (!TEST_true(WPACKET_init(&pkt
, buf
))
144 * No previous lenbytes set so we should be ok to set the max
147 || !TEST_true(WPACKET_set_max_size(&pkt
, SIZE_MAX
))
148 /* We should be able to set it smaller too */
149 || !TEST_true(WPACKET_set_max_size(&pkt
, SIZE_MAX
-1))
150 /* And setting it bigger again should be ok */
151 || !TEST_true(WPACKET_set_max_size(&pkt
, SIZE_MAX
))
152 || !TEST_true(WPACKET_finish(&pkt
)))
153 return cleanup(&pkt
);
155 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
157 * Should fail because we already consumed 1 byte with the
160 || !TEST_false(WPACKET_set_max_size(&pkt
, 0))
162 * Max size can't be bigger than biggest that will fit in
165 || !TEST_false(WPACKET_set_max_size(&pkt
, 0x0101))
166 /* It can be the same as the maximum possible size */
167 || !TEST_true(WPACKET_set_max_size(&pkt
, 0x0100))
168 /* Or it can be less */
169 || !TEST_true(WPACKET_set_max_size(&pkt
, 0x01))
170 /* Should fail because packet is already filled */
171 || !TEST_false(WPACKET_put_bytes_u8(&pkt
, 0xff))
172 /* You can't put in more bytes than max size */
173 || !TEST_true(WPACKET_set_max_size(&pkt
, 0x02))
174 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
175 || !TEST_false(WPACKET_put_bytes_u8(&pkt
, 0xff))
176 || !TEST_true(WPACKET_finish(&pkt
))
177 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
178 || !TEST_mem_eq(buf
->data
, written
, simple2
, sizeof(simple2
)))
179 return cleanup(&pkt
);
184 static int test_WPACKET_start_sub_packet(void)
190 if (!TEST_true(WPACKET_init(&pkt
, buf
))
191 || !TEST_true(WPACKET_start_sub_packet(&pkt
))
192 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
193 /* Can't finish because we have a sub packet */
194 || !TEST_false(WPACKET_finish(&pkt
))
195 || !TEST_true(WPACKET_close(&pkt
))
196 /* Sub packet is closed so can't close again */
197 || !TEST_false(WPACKET_close(&pkt
))
198 /* Now a top level so finish should succeed */
199 || !TEST_true(WPACKET_finish(&pkt
))
200 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
201 || !TEST_mem_eq(buf
->data
, written
, simple1
, sizeof(simple1
)))
202 return cleanup(&pkt
);
204 /* Single sub-packet with length prefix */
205 if (!TEST_true(WPACKET_init(&pkt
, buf
))
206 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
207 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
208 || !TEST_true(WPACKET_close(&pkt
))
209 || !TEST_true(WPACKET_finish(&pkt
))
210 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
211 || !TEST_mem_eq(buf
->data
, written
, simple2
, sizeof(simple2
)))
212 return cleanup(&pkt
);
214 /* Nested sub-packets with length prefixes */
215 if (!TEST_true(WPACKET_init(&pkt
, buf
))
216 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
217 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
218 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
219 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
220 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
221 || !TEST_size_t_eq(len
, 1)
222 || !TEST_true(WPACKET_close(&pkt
))
223 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
224 || !TEST_size_t_eq(len
, 3)
225 || !TEST_true(WPACKET_close(&pkt
))
226 || !TEST_true(WPACKET_finish(&pkt
))
227 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
228 || !TEST_mem_eq(buf
->data
, written
, nestedsub
, sizeof(nestedsub
)))
229 return cleanup(&pkt
);
231 /* Sequential sub-packets with length prefixes */
232 if (!TEST_true(WPACKET_init(&pkt
, buf
))
233 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
234 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
235 || !TEST_true(WPACKET_close(&pkt
))
236 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
237 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
238 || !TEST_true(WPACKET_close(&pkt
))
239 || !TEST_true(WPACKET_finish(&pkt
))
240 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
241 || !TEST_mem_eq(buf
->data
, written
, seqsub
, sizeof(seqsub
)))
242 return cleanup(&pkt
);
244 /* Nested sub-packets with lengths filled before finish */
245 if (!TEST_true(WPACKET_init(&pkt
, buf
))
246 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
247 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
248 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
249 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
250 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
251 || !TEST_size_t_eq(len
, 1)
252 || !TEST_true(WPACKET_close(&pkt
))
253 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
254 || !TEST_size_t_eq(len
, 3)
255 || !TEST_true(WPACKET_close(&pkt
))
256 || !TEST_true(WPACKET_fill_lengths(&pkt
))
257 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
258 || !TEST_mem_eq(buf
->data
, written
, nestedsub
, sizeof(nestedsub
))
259 || !TEST_true(WPACKET_finish(&pkt
)))
260 return cleanup(&pkt
);
266 static int test_WPACKET_set_flags(void)
271 /* Set packet to be non-zero length */
272 if (!TEST_true(WPACKET_init(&pkt
, buf
))
273 || !TEST_true(WPACKET_set_flags(&pkt
, WPACKET_FLAGS_NON_ZERO_LENGTH
))
274 /* Should fail because of zero length */
275 || !TEST_false(WPACKET_finish(&pkt
))
276 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
277 || !TEST_true(WPACKET_finish(&pkt
))
278 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
279 || !TEST_mem_eq(buf
->data
, written
, simple1
, sizeof(simple1
)))
280 return cleanup(&pkt
);
282 /* Repeat above test in a sub-packet */
283 if (!TEST_true(WPACKET_init(&pkt
, buf
))
284 || !TEST_true(WPACKET_start_sub_packet(&pkt
))
285 || !TEST_true(WPACKET_set_flags(&pkt
, WPACKET_FLAGS_NON_ZERO_LENGTH
))
286 /* Should fail because of zero length */
287 || !TEST_false(WPACKET_close(&pkt
))
288 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
289 || !TEST_true(WPACKET_close(&pkt
))
290 || !TEST_true(WPACKET_finish(&pkt
))
291 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
292 || !TEST_mem_eq(buf
->data
, written
, simple1
, sizeof(simple1
)))
293 return cleanup(&pkt
);
295 /* Set packet to abandon non-zero length */
296 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
297 || !TEST_true(WPACKET_set_flags(&pkt
, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH
))
298 || !TEST_true(WPACKET_finish(&pkt
))
299 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
300 || !TEST_size_t_eq(written
, 0))
301 return cleanup(&pkt
);
303 /* Repeat above test but only abandon a sub-packet */
304 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
305 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
306 || !TEST_true(WPACKET_set_flags(&pkt
, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH
))
307 || !TEST_true(WPACKET_close(&pkt
))
308 || !TEST_true(WPACKET_finish(&pkt
))
309 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
310 || !TEST_mem_eq(buf
->data
, written
, empty
, sizeof(empty
)))
311 return cleanup(&pkt
);
313 /* And repeat with a non empty sub-packet */
314 if (!TEST_true(WPACKET_init(&pkt
, buf
))
315 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt
))
316 || !TEST_true(WPACKET_set_flags(&pkt
, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH
))
317 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xff))
318 || !TEST_true(WPACKET_close(&pkt
))
319 || !TEST_true(WPACKET_finish(&pkt
))
320 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
321 || !TEST_mem_eq(buf
->data
, written
, simple2
, sizeof(simple2
)))
322 return cleanup(&pkt
);
326 static int test_WPACKET_allocate_bytes(void)
330 unsigned char *bytes
;
332 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
333 || !TEST_true(WPACKET_allocate_bytes(&pkt
, 2, &bytes
)))
334 return cleanup(&pkt
);
337 if (!TEST_true(WPACKET_finish(&pkt
))
338 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
339 || !TEST_mem_eq(buf
->data
, written
, alloc
, sizeof(alloc
)))
340 return cleanup(&pkt
);
342 /* Repeat with WPACKET_sub_allocate_bytes */
343 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
344 || !TEST_true(WPACKET_sub_allocate_bytes_u8(&pkt
, 2, &bytes
)))
345 return cleanup(&pkt
);
348 if (!TEST_true(WPACKET_finish(&pkt
))
349 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
350 || !TEST_mem_eq(buf
->data
, written
, submem
, sizeof(submem
)))
351 return cleanup(&pkt
);
356 static int test_WPACKET_memcpy(void)
360 const unsigned char bytes
[] = { 0xfe, 0xff };
362 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
363 || !TEST_true(WPACKET_memcpy(&pkt
, bytes
, sizeof(bytes
)))
364 || !TEST_true(WPACKET_finish(&pkt
))
365 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
366 || !TEST_mem_eq(buf
->data
, written
, alloc
, sizeof(alloc
)))
367 return cleanup(&pkt
);
369 /* Repeat with WPACKET_sub_memcpy() */
370 if (!TEST_true(WPACKET_init_len(&pkt
, buf
, 1))
371 || !TEST_true(WPACKET_sub_memcpy_u8(&pkt
, bytes
, sizeof(bytes
)))
372 || !TEST_true(WPACKET_finish(&pkt
))
373 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
374 || !TEST_mem_eq(buf
->data
, written
, submem
, sizeof(submem
)))
375 return cleanup(&pkt
);
380 static int test_WPACKET_init_der(void)
383 unsigned char sbuf
[1024];
384 unsigned char testdata
[] = { 0x00, 0x01, 0x02, 0x03 };
385 unsigned char testdata2
[259] = { 0x82, 0x01, 0x00 };
388 int flags
= WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH
;
391 /* Test initialising for writing DER */
392 if (!TEST_true(WPACKET_init_der(&pkt
, sbuf
, sizeof(sbuf
)))
393 || !TEST_true(WPACKET_put_bytes_u24(&pkt
, 0xfffefd))
394 /* Test writing data in a length prefixed sub-packet */
395 || !TEST_true(WPACKET_start_sub_packet(&pkt
))
396 || !TEST_true(WPACKET_memcpy(&pkt
, testdata
, sizeof(testdata
)))
397 || !TEST_true(WPACKET_close(&pkt
))
398 || !TEST_true(WPACKET_put_bytes_u8(&pkt
, 0xfc))
399 /* this sub-packet is empty, and should render zero bytes */
400 || (!TEST_true(WPACKET_start_sub_packet(&pkt
))
401 || !TEST_true(WPACKET_set_flags(&pkt
, flags
))
402 || !TEST_true(WPACKET_get_total_written(&pkt
, &size1
))
403 || !TEST_true(WPACKET_close(&pkt
))
404 || !TEST_true(WPACKET_get_total_written(&pkt
, &size2
))
405 || !TEST_size_t_eq(size1
, size2
))
406 || !TEST_true(WPACKET_finish(&pkt
))
407 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
[0]))
408 || !TEST_mem_eq(WPACKET_get_curr(&pkt
), written
[0], simpleder
,
410 return cleanup(&pkt
);
412 /* Generate random packet data for test */
413 if (!TEST_true(RAND_bytes(&testdata2
[3], sizeof(testdata2
) - 3)))
417 * Test with a sub-packet that has 2 length bytes. We do 2 passes - first
418 * with a NULL buffer, just to calculate lengths, and a second pass with a
419 * real buffer to actually generate a packet
421 for (i
= 0; i
< 2; i
++) {
423 if (!TEST_true(WPACKET_init_null_der(&pkt
)))
426 if (!TEST_true(WPACKET_init_der(&pkt
, sbuf
, sizeof(sbuf
))))
429 if (!TEST_true(WPACKET_start_sub_packet(&pkt
))
430 || !TEST_true(WPACKET_memcpy(&pkt
, &testdata2
[3],
431 sizeof(testdata2
) - 3))
432 || !TEST_true(WPACKET_close(&pkt
))
433 || !TEST_true(WPACKET_finish(&pkt
))
434 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
[i
])))
435 return cleanup(&pkt
);
439 * Check that the size calculated in the first pass equals the size of the
440 * packet actually generated in the second pass. Also check the generated
441 * packet looks as we expect it to.
443 if (!TEST_size_t_eq(written
[0], written
[1])
444 || !TEST_mem_eq(WPACKET_get_curr(&pkt
), written
[1], testdata2
,
451 static int test_WPACKET_quic(void)
455 unsigned char *bytes
;
457 /* QUIC sub-packet with 4-byte length prefix, containing a 1-byte vlint */
458 if (!TEST_true(WPACKET_init(&pkt
, buf
))
459 || !TEST_true(WPACKET_start_quic_sub_packet(&pkt
))
460 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x09))
461 /* Can't finish because we have a sub packet */
462 || !TEST_false(WPACKET_finish(&pkt
))
463 || !TEST_true(WPACKET_close(&pkt
))
464 /* Sub packet is closed so can't close again */
465 || !TEST_false(WPACKET_close(&pkt
))
466 /* Now a top level so finish should succeed */
467 || !TEST_true(WPACKET_finish(&pkt
))
468 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
469 || !TEST_mem_eq(buf
->data
, written
, quic1
, sizeof(quic1
)))
470 return cleanup(&pkt
);
472 /* QUIC sub-packet with 1-byte length prefix, containing a 1-byte vlint */
473 if (!TEST_true(WPACKET_init(&pkt
, buf
))
474 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_1B_MAX
))
475 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x09))
476 || !TEST_false(WPACKET_finish(&pkt
))
477 || !TEST_true(WPACKET_close(&pkt
))
478 || !TEST_false(WPACKET_close(&pkt
))
479 || !TEST_true(WPACKET_finish(&pkt
))
480 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
481 || !TEST_mem_eq(buf
->data
, written
, quic2
, sizeof(quic2
)))
482 return cleanup(&pkt
);
484 /* QUIC sub-packet with 2-byte length prefix, containing a 2-byte vlint */
485 if (!TEST_true(WPACKET_init(&pkt
, buf
))
486 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_2B_MIN
))
487 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x41))
488 || !TEST_false(WPACKET_finish(&pkt
))
489 || !TEST_true(WPACKET_close(&pkt
))
490 || !TEST_false(WPACKET_close(&pkt
))
491 || !TEST_true(WPACKET_finish(&pkt
))
492 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
493 || !TEST_mem_eq(buf
->data
, written
, quic3
, sizeof(quic3
)))
494 return cleanup(&pkt
);
496 /* QUIC sub-packet with 8-byte length prefix, containing a 4-byte vlint */
497 if (!TEST_true(WPACKET_init(&pkt
, buf
))
498 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_8B_MIN
))
499 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x13c6a))
500 || !TEST_false(WPACKET_finish(&pkt
))
501 || !TEST_true(WPACKET_close(&pkt
))
502 || !TEST_false(WPACKET_close(&pkt
))
503 || !TEST_true(WPACKET_finish(&pkt
))
504 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
505 || !TEST_mem_eq(buf
->data
, written
, quic4
, sizeof(quic4
)))
506 return cleanup(&pkt
);
508 /* QUIC sub-packet with 8-byte length prefix, containing a 8-byte vlint */
509 if (!TEST_true(WPACKET_init(&pkt
, buf
))
510 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_8B_MIN
))
511 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x2f77213f3f505ba5ULL
))
512 || !TEST_false(WPACKET_finish(&pkt
))
513 || !TEST_true(WPACKET_close(&pkt
))
514 || !TEST_false(WPACKET_close(&pkt
))
515 || !TEST_true(WPACKET_finish(&pkt
))
516 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
517 || !TEST_mem_eq(buf
->data
, written
, quic5
, sizeof(quic5
)))
518 return cleanup(&pkt
);
520 /* QUIC sub-packet, length known up-front */
521 if (!TEST_true(WPACKET_init(&pkt
, buf
))
522 || !TEST_true(WPACKET_quic_sub_allocate_bytes(&pkt
, 3, &bytes
)))
523 return cleanup(&pkt
);
529 if (!TEST_true(WPACKET_finish(&pkt
))
530 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
531 || !TEST_mem_eq(buf
->data
, written
, quic6
, sizeof(quic6
)))
532 return cleanup(&pkt
);
534 /* Nested and sequential sub-packets with length prefixes */
535 if (!TEST_true(WPACKET_init(&pkt
, buf
))
536 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x07))
537 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
538 || !TEST_size_t_eq(len
, 1)
539 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_4B_MIN
))
540 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x2514))
541 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
542 || !TEST_size_t_eq(len
, 2)
543 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_2B_MIN
))
544 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x05))
545 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
546 || !TEST_size_t_eq(len
, 1)
547 || !TEST_true(WPACKET_close(&pkt
))
548 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_2B_MIN
))
549 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x11))
550 || !TEST_true(WPACKET_close(&pkt
))
551 || !TEST_true(WPACKET_get_length(&pkt
, &len
))
552 || !TEST_size_t_eq(len
, 8)
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
, 0x12))
556 || !TEST_true(WPACKET_close(&pkt
))
557 || !TEST_true(WPACKET_start_quic_sub_packet_bound(&pkt
, OSSL_QUIC_VLINT_2B_MIN
))
558 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, 0x13))
559 || !TEST_true(WPACKET_close(&pkt
))
560 || !TEST_true(WPACKET_finish(&pkt
))
561 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
))
562 || !TEST_mem_eq(buf
->data
, written
, quic7
, sizeof(quic7
)))
563 return cleanup(&pkt
);
565 /* Trying to encode a value above OSSL_QUIC_VLINT_MAX should fail */
566 if (!TEST_true(WPACKET_init(&pkt
, buf
))
567 || !TEST_false(WPACKET_quic_write_vlint(&pkt
, OSSL_QUIC_VLINT_MAX
+1))
568 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, OSSL_QUIC_VLINT_MAX
)))
569 return cleanup(&pkt
);
571 WPACKET_cleanup(&pkt
);
575 static int test_WPACKET_quic_vlint_random(void)
578 uint64_t expected
, actual
= 0;
579 unsigned char rand_data
[9];
581 PACKET read_pkt
= {0};
583 for (i
= 0; i
< 10000; ++i
) {
584 if (!TEST_true(RAND_bytes(rand_data
, sizeof(rand_data
))))
585 return cleanup(&pkt
);
587 expected
= *(uint64_t*)rand_data
;
590 * Ensure that all size classes get tested with equal probability.
592 switch (rand_data
[8] & 3) {
594 expected
&= OSSL_QUIC_VLINT_1B_MAX
;
597 expected
&= OSSL_QUIC_VLINT_2B_MAX
;
600 expected
&= OSSL_QUIC_VLINT_4B_MAX
;
603 expected
&= OSSL_QUIC_VLINT_8B_MAX
;
607 if (!TEST_true(WPACKET_init(&pkt
, buf
))
608 || !TEST_true(WPACKET_quic_write_vlint(&pkt
, expected
))
609 || !TEST_true(WPACKET_get_total_written(&pkt
, &written
)))
610 return cleanup(&pkt
);
612 if (!TEST_true(PACKET_buf_init(&read_pkt
, (unsigned char *)buf
->data
, written
))
613 || !TEST_true(PACKET_get_quic_vlint(&read_pkt
, &actual
))
614 || !TEST_uint64_t_eq(expected
, actual
))
615 return cleanup(&pkt
);
617 WPACKET_cleanup(&pkt
);
620 WPACKET_cleanup(&pkt
);
624 int setup_tests(void)
626 if (!TEST_ptr(buf
= BUF_MEM_new()))
629 ADD_TEST(test_WPACKET_init
);
630 ADD_TEST(test_WPACKET_set_max_size
);
631 ADD_TEST(test_WPACKET_start_sub_packet
);
632 ADD_TEST(test_WPACKET_set_flags
);
633 ADD_TEST(test_WPACKET_allocate_bytes
);
634 ADD_TEST(test_WPACKET_memcpy
);
635 ADD_TEST(test_WPACKET_init_der
);
636 ADD_TEST(test_WPACKET_quic
);
637 ADD_TEST(test_WPACKET_quic_vlint_random
);
641 void cleanup_tests(void)