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