bytestringtest.c revision 1.16
1/* $OpenBSD: bytestringtest.c,v 1.16 2022/01/06 14:31:03 jsing Exp $ */ 2/* 3 * Copyright (c) 2014, Google Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20 21#include <openssl/crypto.h> 22 23#include "bytestring.h" 24 25/* This is from <openssl/base.h> in boringssl */ 26#define OPENSSL_U64(x) x##ULL 27 28#define PRINT_ERROR printf("Error in %s [%s:%d]\n", __func__, __FILE__, \ 29 __LINE__) 30 31#define CHECK(a) do { \ 32 if (!(a)) { \ 33 PRINT_ERROR; \ 34 return 0; \ 35 } \ 36} while (0) 37 38#define CHECK_GOTO(a) do { \ 39 if (!(a)) { \ 40 PRINT_ERROR; \ 41 goto err; \ 42 } \ 43} while (0) 44 45static int 46test_skip(void) 47{ 48 static const uint8_t kData[] = {1, 2, 3}; 49 CBS data; 50 51 CBS_init(&data, kData, sizeof(kData)); 52 53 CHECK(CBS_len(&data) == 3); 54 CHECK(CBS_skip(&data, 1)); 55 CHECK(CBS_len(&data) == 2); 56 CHECK(CBS_skip(&data, 2)); 57 CHECK(CBS_len(&data) == 0); 58 CHECK(!CBS_skip(&data, 1)); 59 60 return 1; 61} 62 63static int 64test_get_u(void) 65{ 66 static const uint8_t kData[] = { 67 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 68 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 69 }; 70 uint8_t u8; 71 uint16_t u16; 72 uint32_t u32; 73 uint64_t u64; 74 CBS data; 75 76 CBS_init(&data, kData, sizeof(kData)); 77 78 CHECK(CBS_get_u8(&data, &u8)); 79 CHECK(u8 == 1); 80 CHECK(CBS_get_u16(&data, &u16)); 81 CHECK(u16 == 0x203); 82 CHECK(CBS_get_u24(&data, &u32)); 83 CHECK(u32 == 0x40506); 84 CHECK(CBS_get_u32(&data, &u32)); 85 CHECK(u32 == 0x708090a); 86 CHECK(CBS_get_u64(&data, &u64)); 87 CHECK(u64 == 0x0b0c0d0e0f101112U); 88 CHECK(CBS_get_last_u8(&data, &u8)); 89 CHECK(u8 == 20); 90 CHECK(CBS_get_last_u8(&data, &u8)); 91 CHECK(u8 == 19); 92 CHECK(!CBS_get_u8(&data, &u8)); 93 CHECK(!CBS_get_last_u8(&data, &u8)); 94 95 return 1; 96} 97 98static int 99test_get_prefixed(void) 100{ 101 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1}; 102 uint8_t u8; 103 uint16_t u16; 104 uint32_t u32; 105 CBS data, prefixed; 106 107 CBS_init(&data, kData, sizeof(kData)); 108 109 CHECK(CBS_get_u8_length_prefixed(&data, &prefixed)); 110 CHECK(CBS_len(&prefixed) == 1); 111 CHECK(CBS_get_u8(&prefixed, &u8)); 112 CHECK(u8 == 2); 113 CHECK(CBS_get_u16_length_prefixed(&data, &prefixed)); 114 CHECK(CBS_len(&prefixed) == 2); 115 CHECK(CBS_get_u16(&prefixed, &u16)); 116 CHECK(u16 == 0x304); 117 CHECK(CBS_get_u24_length_prefixed(&data, &prefixed)); 118 CHECK(CBS_len(&prefixed) == 3); 119 CHECK(CBS_get_u24(&prefixed, &u32)); 120 CHECK(u32 == 0x30201); 121 122 return 1; 123} 124 125static int 126test_get_prefixed_bad(void) 127{ 128 static const uint8_t kData1[] = {2, 1}; 129 static const uint8_t kData2[] = {0, 2, 1}; 130 static const uint8_t kData3[] = {0, 0, 2, 1}; 131 CBS data, prefixed; 132 133 CBS_init(&data, kData1, sizeof(kData1)); 134 CHECK(!CBS_get_u8_length_prefixed(&data, &prefixed)); 135 136 CBS_init(&data, kData2, sizeof(kData2)); 137 CHECK(!CBS_get_u16_length_prefixed(&data, &prefixed)); 138 139 CBS_init(&data, kData3, sizeof(kData3)); 140 CHECK(!CBS_get_u24_length_prefixed(&data, &prefixed)); 141 142 return 1; 143} 144 145static int 146test_peek_u(void) 147{ 148 static const uint8_t kData[] = { 149 1, 2, 3, 4, 5, 6, 7, 8, 9, 150 }; 151 uint8_t u8; 152 uint16_t u16; 153 uint32_t u32; 154 CBS data; 155 156 CBS_init(&data, kData, sizeof(kData)); 157 158 CHECK(CBS_peek_u8(&data, &u8)); 159 CHECK(u8 == 1); 160 CHECK(CBS_peek_u16(&data, &u16)); 161 CHECK(u16 == 0x102); 162 CHECK(CBS_peek_u24(&data, &u32)); 163 CHECK(u32 == 0x10203); 164 CHECK(CBS_peek_u32(&data, &u32)); 165 CHECK(u32 == 0x1020304); 166 CHECK(CBS_get_u32(&data, &u32)); 167 CHECK(u32 == 0x1020304); 168 CHECK(CBS_peek_last_u8(&data, &u8)); 169 CHECK(u8 == 9); 170 CHECK(CBS_peek_u32(&data, &u32)); 171 CHECK(u32 == 0x5060708); 172 CHECK(CBS_get_u32(&data, &u32)); 173 CHECK(u32 == 0x5060708); 174 CHECK(CBS_get_u8(&data, &u8)); 175 CHECK(u8 == 9); 176 CHECK(!CBS_get_u8(&data, &u8)); 177 178 return 1; 179} 180 181static int 182test_get_asn1(void) 183{ 184 static const uint8_t kData1[] = {0x30, 2, 1, 2}; 185 static const uint8_t kData2[] = {0x30, 3, 1, 2}; 186 static const uint8_t kData3[] = {0x30, 0x80}; 187 static const uint8_t kData4[] = {0x30, 0x81, 1, 1}; 188 static const uint8_t kData5[4 + 0x80] = {0x30, 0x82, 0, 0x80}; 189 static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1}; 190 static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1}; 191 static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1}; 192 static const uint8_t kData9[] = {0xa1, 3, 0x2, 1, 0xff}; 193 194 CBS data, contents; 195 int present; 196 uint64_t value; 197 198 CBS_init(&data, kData1, sizeof(kData1)); 199 200 CHECK(!CBS_peek_asn1_tag(&data, 0x1)); 201 CHECK(CBS_peek_asn1_tag(&data, 0x30)); 202 203 CHECK(CBS_get_asn1(&data, &contents, 0x30)); 204 CHECK(CBS_len(&contents) == 2); 205 CHECK(memcmp(CBS_data(&contents), "\x01\x02", 2) == 0); 206 207 CBS_init(&data, kData2, sizeof(kData2)); 208 /* data is truncated */ 209 CHECK(!CBS_get_asn1(&data, &contents, 0x30)); 210 211 CBS_init(&data, kData3, sizeof(kData3)); 212 /* zero byte length of length */ 213 CHECK(!CBS_get_asn1(&data, &contents, 0x30)); 214 215 CBS_init(&data, kData4, sizeof(kData4)); 216 /* long form mistakenly used. */ 217 CHECK(!CBS_get_asn1(&data, &contents, 0x30)); 218 219 CBS_init(&data, kData5, sizeof(kData5)); 220 /* length takes too many bytes. */ 221 CHECK(!CBS_get_asn1(&data, &contents, 0x30)); 222 223 CBS_init(&data, kData1, sizeof(kData1)); 224 /* wrong tag. */ 225 CHECK(!CBS_get_asn1(&data, &contents, 0x31)); 226 227 CBS_init(&data, NULL, 0); 228 /* peek at empty data. */ 229 CHECK(!CBS_peek_asn1_tag(&data, 0x30)); 230 231 CBS_init(&data, NULL, 0); 232 /* optional elements at empty data. */ 233 CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa0)); 234 CHECK(!present); 235 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present, 236 0xa0)); 237 CHECK(!present); 238 CHECK(CBS_len(&contents) == 0); 239 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0)); 240 CHECK(CBS_len(&contents) == 0); 241 CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42)); 242 CHECK(value == 42); 243 244 CBS_init(&data, kData6, sizeof(kData6)); 245 /* optional element. */ 246 CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa0)); 247 CHECK(!present); 248 CHECK(CBS_get_optional_asn1(&data, &contents, &present, 0xa1)); 249 CHECK(present); 250 CHECK(CBS_len(&contents) == 3); 251 CHECK(memcmp(CBS_data(&contents), "\x04\x01\x01", 3) == 0); 252 253 CBS_init(&data, kData6, sizeof(kData6)); 254 /* optional octet string. */ 255 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present, 256 0xa0)); 257 CHECK(!present); 258 CHECK(CBS_len(&contents) == 0); 259 CHECK(CBS_get_optional_asn1_octet_string(&data, &contents, &present, 260 0xa1)); 261 CHECK(present); 262 CHECK(CBS_len(&contents) == 1); 263 CHECK(CBS_data(&contents)[0] == 1); 264 265 CBS_init(&data, kData7, sizeof(kData7)); 266 /* invalid optional octet string. */ 267 CHECK(!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 268 0xa1)); 269 270 CBS_init(&data, kData8, sizeof(kData8)); 271 /* optional octet string. */ 272 CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42)); 273 CHECK(value == 42); 274 CHECK(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)); 275 CHECK(value == 1); 276 277 CBS_init(&data, kData9, sizeof(kData9)); 278 /* invalid optional integer. */ 279 CHECK(!CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)); 280 281 return 1; 282} 283 284static int 285test_get_optional_asn1_bool(void) 286{ 287 CBS data; 288 int val; 289 290 static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff}; 291 static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00}; 292 static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01}; 293 294 CBS_init(&data, NULL, 0); 295 val = 2; 296 CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0)); 297 CHECK(val == 0); 298 299 CBS_init(&data, kTrue, sizeof(kTrue)); 300 val = 2; 301 CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0)); 302 CHECK(val == 1); 303 304 CBS_init(&data, kFalse, sizeof(kFalse)); 305 val = 2; 306 CHECK(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)); 307 CHECK(val == 0); 308 309 CBS_init(&data, kInvalid, sizeof(kInvalid)); 310 CHECK(!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)); 311 312 return 1; 313} 314 315static int 316test_cbb_basic(void) 317{ 318 static const uint8_t kExpected[] = { 319 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 320 13, 14, 15, 16, 17, 18, 19, 20, 321 }; 322 uint8_t *buf = NULL; 323 size_t buf_len; 324 int ret = 0; 325 CBB cbb; 326 327 CHECK(CBB_init(&cbb, 100)); 328 329 CBB_cleanup(&cbb); 330 331 CHECK(CBB_init(&cbb, 0)); 332 CHECK_GOTO(CBB_add_u8(&cbb, 1)); 333 CHECK_GOTO(CBB_add_u16(&cbb, 0x203)); 334 CHECK_GOTO(CBB_add_u24(&cbb, 0x40506)); 335 CHECK_GOTO(CBB_add_u32(&cbb, 0x708090a)); 336 CHECK_GOTO(CBB_add_bytes(&cbb, (const uint8_t*) "\x0b\x0c", 2)); 337 CHECK_GOTO(CBB_add_u64(&cbb, 0xd0e0f1011121314)); 338 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 339 340 ret = (buf_len == sizeof(kExpected) 341 && memcmp(buf, kExpected, buf_len) == 0); 342 343 if (0) { 344err: 345 CBB_cleanup(&cbb); 346 } 347 free(buf); 348 return ret; 349} 350 351static int 352test_cbb_add_space(void) 353{ 354 static const uint8_t kExpected[] = {1, 2, 0, 0, 0, 0, 7, 8}; 355 uint8_t *buf = NULL; 356 size_t buf_len; 357 uint8_t *data; 358 int ret = 0; 359 CBB cbb; 360 361 CHECK(CBB_init(&cbb, 100)); 362 363 CHECK_GOTO(CBB_add_u16(&cbb, 0x102)); 364 CHECK_GOTO(CBB_add_space(&cbb, &data, 4)); 365 CHECK_GOTO(CBB_add_u16(&cbb, 0x708)); 366 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 367 368 ret |= (buf_len == sizeof(kExpected) 369 && memcmp(buf, kExpected, buf_len) == 0); 370 371 memset(buf, 0xa5, buf_len); 372 CHECK(CBB_init_fixed(&cbb, buf, buf_len)); 373 374 CHECK_GOTO(CBB_add_u16(&cbb, 0x102)); 375 CHECK_GOTO(CBB_add_space(&cbb, &data, 4)); 376 CHECK_GOTO(CBB_add_u16(&cbb, 0x708)); 377 CHECK_GOTO(CBB_finish(&cbb, NULL, NULL)); 378 379 ret |= (buf_len == sizeof(kExpected) 380 && memcmp(buf, kExpected, buf_len) == 0); 381 382 if (0) { 383err: 384 CBB_cleanup(&cbb); 385 } 386 free(buf); 387 return ret; 388} 389 390static int 391test_cbb_fixed(void) 392{ 393 CBB cbb; 394 uint8_t buf[1]; 395 uint8_t *out_buf = NULL; 396 size_t out_size; 397 int ret = 0; 398 399 CHECK(CBB_init_fixed(&cbb, NULL, 0)); 400 CHECK_GOTO(!CBB_add_u8(&cbb, 1)); 401 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); 402 CHECK(out_buf == NULL && out_size == 0); 403 404 CHECK(CBB_init_fixed(&cbb, buf, 1)); 405 CHECK_GOTO(CBB_add_u8(&cbb, 1)); 406 CHECK_GOTO(!CBB_add_u8(&cbb, 2)); 407 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); 408 409 ret = (out_buf == buf && out_size == 1 && buf[0] == 1); 410 411 if (0) { 412err: 413 CBB_cleanup(&cbb); 414 } 415 416 return ret; 417} 418 419static int 420test_cbb_finish_child(void) 421{ 422 CBB cbb, child; 423 uint8_t *out_buf = NULL; 424 size_t out_size; 425 int ret = 0; 426 427 CHECK(CBB_init(&cbb, 16)); 428 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); 429 CHECK_GOTO(!CBB_finish(&child, &out_buf, &out_size)); 430 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); 431 432 ret = (out_size == 1 && out_buf[0] == 0); 433 434err: 435 free(out_buf); 436 return ret; 437} 438 439static int 440test_cbb_prefixed(void) 441{ 442 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3, 443 4, 5, 6, 5, 4, 1, 0, 1, 2}; 444 CBB cbb, contents, inner_contents, inner_inner_contents; 445 uint8_t *buf = NULL; 446 size_t buf_len; 447 int ret = 0; 448 449 CHECK(CBB_init(&cbb, 0)); 450 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 451 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 452 CHECK_GOTO(CBB_add_u8(&contents, 1)); 453 CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents)); 454 CHECK_GOTO(CBB_add_u16(&contents, 0x203)); 455 CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents)); 456 CHECK_GOTO(CBB_add_u24(&contents, 0x40506)); 457 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 458 CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents)); 459 CHECK_GOTO(CBB_add_u8(&inner_contents, 1)); 460 CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents, 461 &inner_inner_contents)); 462 CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 2)); 463 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 464 465 ret = (buf_len == sizeof(kExpected) 466 && memcmp(buf, kExpected, buf_len) == 0); 467 468 if (0) { 469err: 470 CBB_cleanup(&cbb); 471 } 472 free(buf); 473 return ret; 474} 475 476static int 477test_cbb_discard_child(void) 478{ 479 static const uint8_t kExpected[] = { 480 0xaa, 481 0, 482 1, 0xbb, 483 0, 2, 0xcc, 0xcc, 484 0, 0, 3, 0xdd, 0xdd, 0xdd, 485 1, 0xff, 486 }; 487 CBB cbb, contents, inner_contents, inner_inner_contents; 488 uint8_t *buf = NULL; 489 size_t buf_len; 490 int ret = 0; 491 492 CHECK(CBB_init(&cbb, 0)); 493 CHECK_GOTO(CBB_add_u8(&cbb, 0xaa)); 494 495 // Discarding |cbb|'s children preserves the byte written. 496 CBB_discard_child(&cbb); 497 498 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 499 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 500 CHECK_GOTO(CBB_add_u8(&contents, 0xbb)); 501 CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents)); 502 CHECK_GOTO(CBB_add_u16(&contents, 0xcccc)); 503 CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents)); 504 CHECK_GOTO(CBB_add_u24(&contents, 0xdddddd)); 505 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 506 CHECK_GOTO(CBB_add_u8(&contents, 0xff)); 507 CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents)); 508 CHECK_GOTO(CBB_add_u8(&inner_contents, 0x42)); 509 CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents, 510 &inner_inner_contents)); 511 CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 0x99)); 512 513 // Discard everything from |inner_contents| down. 514 CBB_discard_child(&contents); 515 516 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 517 518 ret = (buf_len == sizeof(kExpected) 519 && memcmp(buf, kExpected, buf_len) == 0); 520 521 if (0) { 522err: 523 CBB_cleanup(&cbb); 524 } 525 free(buf); 526 return ret; 527} 528 529static int 530test_cbb_misuse(void) 531{ 532 CBB cbb, child, contents; 533 uint8_t *buf = NULL; 534 size_t buf_len; 535 int ret = 0; 536 537 CHECK(CBB_init(&cbb, 0)); 538 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); 539 CHECK_GOTO(CBB_add_u8(&child, 1)); 540 CHECK_GOTO(CBB_add_u8(&cbb, 2)); 541 542 /* 543 * Since we wrote to |cbb|, |child| is now invalid and attempts to write 544 * to it should fail. 545 */ 546 CHECK_GOTO(!CBB_add_u8(&child, 1)); 547 CHECK_GOTO(!CBB_add_u16(&child, 1)); 548 CHECK_GOTO(!CBB_add_u24(&child, 1)); 549 CHECK_GOTO(!CBB_add_u8_length_prefixed(&child, &contents)); 550 CHECK_GOTO(!CBB_add_u16_length_prefixed(&child, &contents)); 551 CHECK_GOTO(!CBB_add_asn1(&child, &contents, 1)); 552 CHECK_GOTO(!CBB_add_bytes(&child, (const uint8_t*) "a", 1)); 553 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 554 555 ret = (buf_len == 3 && memcmp(buf, "\x01\x01\x02", 3) == 0); 556 557 if (0) { 558err: 559 CBB_cleanup(&cbb); 560 } 561 free(buf); 562 return ret; 563} 564 565static int 566test_cbb_asn1(void) 567{ 568 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3}; 569 uint8_t *buf = NULL, *test_data = NULL; 570 size_t buf_len; 571 CBB cbb, contents, inner_contents; 572 int ret = 0; 573 int alloc = 0; 574 575 CHECK_GOTO(CBB_init(&cbb, 0)); 576 alloc = 1; 577 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 578 CHECK_GOTO(CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 579 3)); 580 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 581 alloc = 0; 582 583 CHECK_GOTO(buf_len == sizeof(kExpected)); 584 CHECK_GOTO(memcmp(buf, kExpected, buf_len) == 0); 585 586 free(buf); 587 buf = NULL; 588 589 CHECK_GOTO(((test_data = malloc(100000)) != NULL)); 590 memset(test_data, 0x42, 100000); 591 592 CHECK_GOTO(CBB_init(&cbb, 0)); 593 alloc = 1; 594 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 595 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 130)); 596 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 597 alloc = 0; 598 599 CHECK_GOTO(buf_len == 3 + 130); 600 CHECK_GOTO(memcmp(buf, "\x30\x81\x82", 3) == 0); 601 CHECK_GOTO(memcmp(buf + 3, test_data, 130) == 0); 602 603 free(buf); 604 buf = NULL; 605 606 CHECK_GOTO(CBB_init(&cbb, 0)); 607 alloc = 1; 608 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 609 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 1000)); 610 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 611 alloc = 0; 612 613 CHECK_GOTO(buf_len == 4 + 1000); 614 CHECK_GOTO(memcmp(buf, "\x30\x82\x03\xe8", 4) == 0); 615 CHECK_GOTO(!memcmp(buf + 4, test_data, 1000)); 616 617 free(buf); 618 buf = NULL; 619 620 CHECK_GOTO(CBB_init(&cbb, 0)); 621 alloc = 1; 622 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 623 CHECK_GOTO(CBB_add_asn1(&contents, &inner_contents, 0x30)); 624 CHECK_GOTO(CBB_add_bytes(&inner_contents, test_data, 100000)); 625 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 626 alloc = 0; 627 628 CHECK_GOTO(buf_len == 5 + 5 + 100000); 629 CHECK_GOTO(memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) 630 == 0); 631 CHECK_GOTO(!memcmp(buf + 10, test_data, 100000)); 632 633 ret = 1; 634 635 if (0) { 636err: 637 if (alloc) 638 CBB_cleanup(&cbb); 639 } 640 free(buf); 641 free(test_data); 642 return ret; 643} 644 645static int 646do_indefinite_convert(const char *name, const uint8_t *definite_expected, 647 size_t definite_len, const uint8_t *indefinite, size_t indefinite_len) 648{ 649 CBS in; 650 uint8_t *out = NULL; 651 size_t out_len; 652 int ret = 0; 653 654 CBS_init(&in, indefinite, indefinite_len); 655 656 CHECK_GOTO(CBS_asn1_indefinite_to_definite(&in, &out, &out_len)); 657 658 if (out == NULL) { 659 660 if (indefinite_len != definite_len || 661 memcmp(definite_expected, indefinite, indefinite_len) != 0) { 662 PRINT_ERROR; 663 goto err; 664 } 665 666 return 1; 667 } 668 669 if (out_len != definite_len || 670 memcmp(out, definite_expected, definite_len) != 0) { 671 PRINT_ERROR; 672 goto err; 673 } 674 675 ret = 1; 676err: 677 free(out); 678 return ret; 679} 680 681static int 682test_indefinite_convert(void) 683{ 684 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; 685 686 /* kIndefBER contains a SEQUENCE with an indefinite length. */ 687 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 688 0x00}; 689 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; 690 691 /* 692 * kOctetStringBER contains an indefinite length OCTETSTRING with two 693 * parts. These parts need to be concatenated in DER form. 694 */ 695 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 696 1, 0x04, 0x02, 2, 3, 0x00, 0x00}; 697 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; 698 699 /* 700 * kNSSBER is part of a PKCS#12 message generated by NSS that uses 701 * indefinite length elements extensively. 702 */ 703 static const uint8_t kNSSBER[] = { 704 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 705 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 706 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 707 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 708 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 709 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 710 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44, 711 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b, 712 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, 713 }; 714 715 static const uint8_t kNSSDER[] = { 716 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, 717 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, 718 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 719 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 720 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 721 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 722 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 723 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 724 }; 725 726 CHECK(do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), 727 kSimpleBER, sizeof(kSimpleBER))); 728 CHECK(do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), 729 kIndefBER, sizeof(kIndefBER))); 730 CHECK(do_indefinite_convert("kOctetStringBER", kOctetStringDER, 731 sizeof(kOctetStringDER), kOctetStringBER, 732 sizeof(kOctetStringBER))); 733 CHECK(do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, 734 sizeof(kNSSBER))); 735 736 return 1; 737} 738 739typedef struct { 740 uint64_t value; 741 const char *encoding; 742 size_t encoding_len; 743} ASN1_UINT64_TEST; 744 745static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { 746 {0, "\x02\x01\x00", 3}, 747 {1, "\x02\x01\x01", 3}, 748 {127, "\x02\x01\x7f", 3}, 749 {128, "\x02\x02\x00\x80", 4}, 750 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, 751 {OPENSSL_U64(0x0102030405060708), 752 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, 753 {OPENSSL_U64(0xffffffffffffffff), 754 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, 755}; 756 757typedef struct { 758 const char *encoding; 759 size_t encoding_len; 760} ASN1_INVALID_UINT64_TEST; 761 762static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { 763 /* Bad tag. */ 764 {"\x03\x01\x00", 3}, 765 /* Empty contents. */ 766 {"\x02\x00", 2}, 767 /* Negative number. */ 768 {"\x02\x01\x80", 3}, 769 /* Overflow. */ 770 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, 771 /* Leading zeros. */ 772 {"\x02\x02\x00\x01", 4}, 773}; 774 775static int 776test_asn1_uint64(void) 777{ 778 CBB cbb; 779 uint8_t *out = NULL; 780 size_t i; 781 int ret = 0; 782 int alloc = 0; 783 784 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); 785 i++) { 786 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; 787 CBS cbs; 788 uint64_t value; 789 size_t len; 790 791 CBS_init(&cbs, (const uint8_t *)test->encoding, 792 test->encoding_len); 793 794 CHECK(CBS_get_asn1_uint64(&cbs, &value)); 795 CHECK(CBS_len(&cbs) == 0); 796 CHECK(value == test->value); 797 798 CHECK(CBB_init(&cbb, 0)); 799 alloc = 1; 800 CHECK_GOTO(CBB_add_asn1_uint64(&cbb, test->value)); 801 CHECK_GOTO(CBB_finish(&cbb, &out, &len)); 802 alloc = 0; 803 804 CHECK_GOTO(len == test->encoding_len); 805 CHECK_GOTO(memcmp(out, test->encoding, len) == 0); 806 free(out); 807 out = NULL; 808 } 809 810 for (i = 0; i < sizeof(kAsn1InvalidUint64Tests) 811 / sizeof(kAsn1InvalidUint64Tests[0]); i++) { 812 const ASN1_INVALID_UINT64_TEST *test = 813 &kAsn1InvalidUint64Tests[i]; 814 CBS cbs; 815 uint64_t value; 816 817 CBS_init(&cbs, (const uint8_t *)test->encoding, 818 test->encoding_len); 819 CHECK(!CBS_get_asn1_uint64(&cbs, &value)); 820 } 821 822 ret = 1; 823 824 if (0) { 825err: 826 if (alloc) 827 CBB_cleanup(&cbb); 828 } 829 free(out); 830 831 return ret; 832} 833 834static int 835test_offset(void) 836{ 837 uint8_t v; 838 static const uint8_t input[] = {1, 2, 3, 4, 5}; 839 CBS data; 840 841 CBS_init(&data, input, sizeof(input)); 842 CHECK(sizeof(input) == 5); 843 CHECK(CBS_len(&data) == 5); 844 CHECK(CBS_offset(&data) == 0); 845 CHECK(CBS_get_u8(&data, &v)); 846 CHECK(v == 1); 847 CHECK(CBS_len(&data) == 4); 848 CHECK(CBS_offset(&data) == 1); 849 CHECK(CBS_skip(&data, 2)); 850 CHECK(CBS_len(&data) == 2); 851 CHECK(CBS_offset(&data) == 3); 852 CHECK(CBS_get_u8(&data, &v)); 853 CHECK(v == 4); 854 CHECK(CBS_get_u8(&data, &v)); 855 CHECK(v == 5); 856 CHECK(CBS_len(&data) == 0); 857 CHECK(CBS_offset(&data) == 5); 858 CHECK(!CBS_skip(&data, 1)); 859 860 CBS_init(&data, input, sizeof(input)); 861 CHECK(CBS_skip(&data, 2)); 862 CHECK(CBS_len(&data) == 3); 863 CHECK(CBS_offset(&data) == 2); 864 CHECK(CBS_skip(&data, 3)); 865 CHECK(CBS_len(&data) == 0); 866 CHECK(CBS_offset(&data) == 5); 867 CHECK(!CBS_get_u8(&data, &v)); 868 869 return 1; 870} 871 872static int 873test_write_bytes(void) 874{ 875 int ret = 0; 876 uint8_t v; 877 size_t len; 878 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 879 CBS data; 880 uint8_t *tmp = NULL; 881 882 CHECK_GOTO((tmp = malloc(sizeof(input))) != NULL); 883 memset(tmp, 100, sizeof(input)); 884 885 CBS_init(&data, input, sizeof(input)); 886 CHECK_GOTO(CBS_len(&data) == 6); 887 CHECK_GOTO(CBS_offset(&data) == 0); 888 CHECK_GOTO(CBS_get_u8(&data, &v)); 889 CHECK_GOTO(v == 102 /* f */); 890 CHECK_GOTO(CBS_skip(&data, 1)); 891 CHECK_GOTO(!CBS_skip(&data, 15)); 892 CHECK_GOTO(CBS_write_bytes(&data, tmp, sizeof(input), &len)); 893 CHECK_GOTO(len == 4); 894 CHECK_GOTO(memcmp(input + 2, tmp, len) == 0); 895 CHECK_GOTO(tmp[4] == 100 && tmp[5] == 100); 896 897 ret = 1; 898 899err: 900 free(tmp); 901 return ret; 902} 903 904static int 905test_cbs_dup(void) 906{ 907 CBS data, check; 908 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 909 910 CBS_init(&data, input, sizeof(input)); 911 CHECK(CBS_len(&data) == 6); 912 CBS_dup(&data, &check); 913 CHECK(CBS_len(&check) == 6); 914 CHECK(CBS_data(&data) == CBS_data(&check)); 915 CHECK(CBS_skip(&data, 1)); 916 CHECK(CBS_len(&data) == 5); 917 CHECK(CBS_len(&check) == 6); 918 CHECK(CBS_data(&data) == CBS_data(&check) + 1); 919 CHECK(CBS_skip(&check, 1)); 920 CHECK(CBS_len(&data) == 5); 921 CHECK(CBS_len(&check) == 5); 922 CHECK(CBS_data(&data) == CBS_data(&check)); 923 CHECK(CBS_offset(&data) == 1); 924 CHECK(CBS_offset(&check) == 1); 925 926 CBS_init(&data, input, sizeof(input)); 927 CHECK(CBS_skip(&data, 5)); 928 CBS_dup(&data, &check); 929 CHECK(CBS_len(&data) == 1); 930 CHECK(CBS_len(&check) == 1); 931 CHECK(CBS_data(&data) == input + 5); 932 CHECK(CBS_data(&data) == CBS_data(&check)); 933 CHECK(CBS_offset(&data) == 5); 934 CHECK(CBS_offset(&check) == 5); 935 936 return 1; 937} 938 939int 940main(void) 941{ 942 int failed = 0; 943 944 failed |= !test_skip(); 945 failed |= !test_get_u(); 946 failed |= !test_get_prefixed(); 947 failed |= !test_get_prefixed_bad(); 948 failed |= !test_peek_u(); 949 failed |= !test_get_asn1(); 950 failed |= !test_cbb_basic(); 951 failed |= !test_cbb_add_space(); 952 failed |= !test_cbb_fixed(); 953 failed |= !test_cbb_finish_child(); 954 failed |= !test_cbb_discard_child(); 955 failed |= !test_cbb_misuse(); 956 failed |= !test_cbb_prefixed(); 957 failed |= !test_cbb_asn1(); 958 failed |= !test_indefinite_convert(); 959 failed |= !test_asn1_uint64(); 960 failed |= !test_get_optional_asn1_bool(); 961 failed |= !test_offset(); 962 failed |= !test_write_bytes(); 963 failed |= !test_cbs_dup(); 964 965 if (!failed) 966 printf("PASS\n"); 967 return failed; 968} 969