Home | History | Annotate | Line # | Download | only in test
wpackettest.c revision 1.1
      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