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