1 /* 2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 13 #ifdef __VMS 14 # pragma names save 15 # pragma names as_is,shortened 16 #endif 17 18 #include "../ssl/packet_local.h" 19 20 #ifdef __VMS 21 # pragma names restore 22 #endif 23 24 #include "testutil.h" 25 26 static const unsigned char simple1[] = { 0xff }; 27 static const unsigned char simple2[] = { 0x01, 0xff }; 28 static const unsigned char simple3[] = { 0x00, 0x00, 0x00, 0x01, 0xff }; 29 static const unsigned char nestedsub[] = { 0x03, 0xff, 0x01, 0xff }; 30 static const unsigned char seqsub[] = { 0x01, 0xff, 0x01, 0xff }; 31 static const unsigned char empty[] = { 0x00 }; 32 static const unsigned char alloc[] = { 0x02, 0xfe, 0xff }; 33 static const unsigned char submem[] = { 0x03, 0x02, 0xfe, 0xff }; 34 static const unsigned char fixed[] = { 0xff, 0xff, 0xff }; 35 36 static BUF_MEM *buf; 37 38 static int cleanup(WPACKET *pkt) 39 { 40 WPACKET_cleanup(pkt); 41 return 0; 42 } 43 44 static int test_WPACKET_init(void) 45 { 46 WPACKET pkt; 47 int i; 48 size_t written; 49 unsigned char sbuf[3]; 50 51 if (!TEST_true(WPACKET_init(&pkt, buf)) 52 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 53 /* Closing a top level WPACKET should fail */ 54 || !TEST_false(WPACKET_close(&pkt)) 55 /* Finishing a top level WPACKET should succeed */ 56 || !TEST_true(WPACKET_finish(&pkt)) 57 /* 58 * Can't call close or finish on a WPACKET that's already 59 * finished. 60 */ 61 || !TEST_false(WPACKET_close(&pkt)) 62 || !TEST_false(WPACKET_finish(&pkt)) 63 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 64 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 65 return cleanup(&pkt); 66 67 /* Now try with a one byte length prefix */ 68 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 69 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 70 || !TEST_true(WPACKET_finish(&pkt)) 71 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 72 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 73 return cleanup(&pkt); 74 75 /* And a longer length prefix */ 76 if (!TEST_true(WPACKET_init_len(&pkt, buf, 4)) 77 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 78 || !TEST_true(WPACKET_finish(&pkt)) 79 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 80 || !TEST_mem_eq(buf->data, written, simple3, sizeof(simple3))) 81 return cleanup(&pkt); 82 83 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))) 84 return cleanup(&pkt); 85 for (i = 1; i < 257; i++) { 86 /* 87 * Putting more bytes in than fit for the size of the length prefix 88 * should fail 89 */ 90 if (!TEST_int_eq(WPACKET_put_bytes_u8(&pkt, 0xff), i < 256)) 91 return cleanup(&pkt); 92 } 93 if (!TEST_true(WPACKET_finish(&pkt))) 94 return cleanup(&pkt); 95 96 /* Test initialising from a fixed size buffer */ 97 if (!TEST_true(WPACKET_init_static_len(&pkt, sbuf, sizeof(sbuf), 0)) 98 /* Adding 3 bytes should succeed */ 99 || !TEST_true(WPACKET_put_bytes_u24(&pkt, 0xffffff)) 100 /* Adding 1 more byte should fail */ 101 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 102 /* Finishing the top level WPACKET should succeed */ 103 || !TEST_true(WPACKET_finish(&pkt)) 104 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 105 || !TEST_mem_eq(sbuf, written, fixed, sizeof(sbuf)) 106 /* Initialise with 1 len byte */ 107 || !TEST_true(WPACKET_init_static_len(&pkt, sbuf, sizeof(sbuf), 1)) 108 /* Adding 2 bytes should succeed */ 109 || !TEST_true(WPACKET_put_bytes_u16(&pkt, 0xfeff)) 110 /* Adding 1 more byte should fail */ 111 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 112 || !TEST_true(WPACKET_finish(&pkt)) 113 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 114 || !TEST_mem_eq(sbuf, written, alloc, sizeof(alloc))) 115 return cleanup(&pkt); 116 117 return 1; 118 } 119 120 static int test_WPACKET_set_max_size(void) 121 { 122 WPACKET pkt; 123 size_t written; 124 125 if (!TEST_true(WPACKET_init(&pkt, buf)) 126 /* 127 * No previous lenbytes set so we should be ok to set the max 128 * possible max size 129 */ 130 || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX)) 131 /* We should be able to set it smaller too */ 132 || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX -1)) 133 /* And setting it bigger again should be ok */ 134 || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX)) 135 || !TEST_true(WPACKET_finish(&pkt))) 136 return cleanup(&pkt); 137 138 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 139 /* 140 * Should fail because we already consumed 1 byte with the 141 * length 142 */ 143 || !TEST_false(WPACKET_set_max_size(&pkt, 0)) 144 /* 145 * Max size can't be bigger than biggest that will fit in 146 * lenbytes 147 */ 148 || !TEST_false(WPACKET_set_max_size(&pkt, 0x0101)) 149 /* It can be the same as the maximum possible size */ 150 || !TEST_true(WPACKET_set_max_size(&pkt, 0x0100)) 151 /* Or it can be less */ 152 || !TEST_true(WPACKET_set_max_size(&pkt, 0x01)) 153 /* Should fail because packet is already filled */ 154 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 155 /* You can't put in more bytes than max size */ 156 || !TEST_true(WPACKET_set_max_size(&pkt, 0x02)) 157 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 158 || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff)) 159 || !TEST_true(WPACKET_finish(&pkt)) 160 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 161 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 162 return cleanup(&pkt); 163 164 return 1; 165 } 166 167 static int test_WPACKET_start_sub_packet(void) 168 { 169 WPACKET pkt; 170 size_t written; 171 size_t len; 172 173 if (!TEST_true(WPACKET_init(&pkt, buf)) 174 || !TEST_true(WPACKET_start_sub_packet(&pkt)) 175 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 176 /* Can't finish because we have a sub packet */ 177 || !TEST_false(WPACKET_finish(&pkt)) 178 || !TEST_true(WPACKET_close(&pkt)) 179 /* Sub packet is closed so can't close again */ 180 || !TEST_false(WPACKET_close(&pkt)) 181 /* Now a top level so finish should succeed */ 182 || !TEST_true(WPACKET_finish(&pkt)) 183 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 184 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 185 return cleanup(&pkt); 186 187 /* Single sub-packet with length prefix */ 188 if (!TEST_true(WPACKET_init(&pkt, buf)) 189 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 190 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 191 || !TEST_true(WPACKET_close(&pkt)) 192 || !TEST_true(WPACKET_finish(&pkt)) 193 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 194 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 195 return cleanup(&pkt); 196 197 /* Nested sub-packets with length prefixes */ 198 if (!TEST_true(WPACKET_init(&pkt, buf)) 199 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 200 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 201 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 202 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 203 || !TEST_true(WPACKET_get_length(&pkt, &len)) 204 || !TEST_size_t_eq(len, 1) 205 || !TEST_true(WPACKET_close(&pkt)) 206 || !TEST_true(WPACKET_get_length(&pkt, &len)) 207 || !TEST_size_t_eq(len, 3) 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, nestedsub, sizeof(nestedsub))) 212 return cleanup(&pkt); 213 214 /* Sequential 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_close(&pkt)) 219 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 220 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 221 || !TEST_true(WPACKET_close(&pkt)) 222 || !TEST_true(WPACKET_finish(&pkt)) 223 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 224 || !TEST_mem_eq(buf->data, written, seqsub, sizeof(seqsub))) 225 return cleanup(&pkt); 226 227 /* Nested sub-packets with lengths filled before finish */ 228 if (!TEST_true(WPACKET_init(&pkt, buf)) 229 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 230 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 231 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 232 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 233 || !TEST_true(WPACKET_get_length(&pkt, &len)) 234 || !TEST_size_t_eq(len, 1) 235 || !TEST_true(WPACKET_close(&pkt)) 236 || !TEST_true(WPACKET_get_length(&pkt, &len)) 237 || !TEST_size_t_eq(len, 3) 238 || !TEST_true(WPACKET_close(&pkt)) 239 || !TEST_true(WPACKET_fill_lengths(&pkt)) 240 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 241 || !TEST_mem_eq(buf->data, written, nestedsub, sizeof(nestedsub)) 242 || !TEST_true(WPACKET_finish(&pkt))) 243 return cleanup(&pkt); 244 245 return 1; 246 } 247 248 249 static int test_WPACKET_set_flags(void) 250 { 251 WPACKET pkt; 252 size_t written; 253 254 /* Set packet to be non-zero length */ 255 if (!TEST_true(WPACKET_init(&pkt, buf)) 256 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)) 257 /* Should fail because of zero length */ 258 || !TEST_false(WPACKET_finish(&pkt)) 259 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 260 || !TEST_true(WPACKET_finish(&pkt)) 261 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 262 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 263 return cleanup(&pkt); 264 265 /* Repeat above test in a sub-packet */ 266 if (!TEST_true(WPACKET_init(&pkt, buf)) 267 || !TEST_true(WPACKET_start_sub_packet(&pkt)) 268 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)) 269 /* Should fail because of zero length */ 270 || !TEST_false(WPACKET_close(&pkt)) 271 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 272 || !TEST_true(WPACKET_close(&pkt)) 273 || !TEST_true(WPACKET_finish(&pkt)) 274 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 275 || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1))) 276 return cleanup(&pkt); 277 278 /* Set packet to abandon non-zero length */ 279 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 280 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) 281 || !TEST_true(WPACKET_finish(&pkt)) 282 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 283 || !TEST_size_t_eq(written, 0)) 284 return cleanup(&pkt); 285 286 /* Repeat above test but only abandon a sub-packet */ 287 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 288 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 289 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) 290 || !TEST_true(WPACKET_close(&pkt)) 291 || !TEST_true(WPACKET_finish(&pkt)) 292 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 293 || !TEST_mem_eq(buf->data, written, empty, sizeof(empty))) 294 return cleanup(&pkt); 295 296 /* And repeat with a non empty sub-packet */ 297 if (!TEST_true(WPACKET_init(&pkt, buf)) 298 || !TEST_true(WPACKET_start_sub_packet_u8(&pkt)) 299 || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) 300 || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff)) 301 || !TEST_true(WPACKET_close(&pkt)) 302 || !TEST_true(WPACKET_finish(&pkt)) 303 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 304 || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2))) 305 return cleanup(&pkt); 306 return 1; 307 } 308 309 static int test_WPACKET_allocate_bytes(void) 310 { 311 WPACKET pkt; 312 size_t written; 313 unsigned char *bytes; 314 315 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 316 || !TEST_true(WPACKET_allocate_bytes(&pkt, 2, &bytes))) 317 return cleanup(&pkt); 318 bytes[0] = 0xfe; 319 bytes[1] = 0xff; 320 if (!TEST_true(WPACKET_finish(&pkt)) 321 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 322 || !TEST_mem_eq(buf->data, written, alloc, sizeof(alloc))) 323 return cleanup(&pkt); 324 325 /* Repeat with WPACKET_sub_allocate_bytes */ 326 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 327 || !TEST_true(WPACKET_sub_allocate_bytes_u8(&pkt, 2, &bytes))) 328 return cleanup(&pkt); 329 bytes[0] = 0xfe; 330 bytes[1] = 0xff; 331 if (!TEST_true(WPACKET_finish(&pkt)) 332 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 333 || !TEST_mem_eq(buf->data, written, submem, sizeof(submem))) 334 return cleanup(&pkt); 335 336 return 1; 337 } 338 339 static int test_WPACKET_memcpy(void) 340 { 341 WPACKET pkt; 342 size_t written; 343 const unsigned char bytes[] = { 0xfe, 0xff }; 344 345 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 346 || !TEST_true(WPACKET_memcpy(&pkt, bytes, sizeof(bytes))) 347 || !TEST_true(WPACKET_finish(&pkt)) 348 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 349 || !TEST_mem_eq(buf->data, written, alloc, sizeof(alloc))) 350 return cleanup(&pkt); 351 352 /* Repeat with WPACKET_sub_memcpy() */ 353 if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)) 354 || !TEST_true(WPACKET_sub_memcpy_u8(&pkt, bytes, sizeof(bytes))) 355 || !TEST_true(WPACKET_finish(&pkt)) 356 || !TEST_true(WPACKET_get_total_written(&pkt, &written)) 357 || !TEST_mem_eq(buf->data, written, submem, sizeof(submem))) 358 return cleanup(&pkt); 359 360 return 1; 361 } 362 363 int setup_tests(void) 364 { 365 if (!TEST_ptr(buf = BUF_MEM_new())) 366 return 0; 367 368 ADD_TEST(test_WPACKET_init); 369 ADD_TEST(test_WPACKET_set_max_size); 370 ADD_TEST(test_WPACKET_start_sub_packet); 371 ADD_TEST(test_WPACKET_set_flags); 372 ADD_TEST(test_WPACKET_allocate_bytes); 373 ADD_TEST(test_WPACKET_memcpy); 374 return 1; 375 } 376 377 void cleanup_tests(void) 378 { 379 BUF_MEM_free(buf); 380 } 381