bytestringtest.c revision 1.15
1/* $OpenBSD: bytestringtest.c,v 1.15 2021/12/15 17:37:42 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[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 319 uint8_t *buf = NULL; 320 size_t buf_len; 321 int ret = 0; 322 CBB cbb; 323 324 CHECK(CBB_init(&cbb, 100)); 325 326 CBB_cleanup(&cbb); 327 328 CHECK(CBB_init(&cbb, 0)); 329 CHECK_GOTO(CBB_add_u8(&cbb, 1)); 330 CHECK_GOTO(CBB_add_u16(&cbb, 0x203)); 331 CHECK_GOTO(CBB_add_u24(&cbb, 0x40506)); 332 CHECK_GOTO(CBB_add_u32(&cbb, 0x708090a)); 333 CHECK_GOTO(CBB_add_bytes(&cbb, (const uint8_t*) "\x0b\x0c", 2)); 334 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 335 336 ret = (buf_len == sizeof(kExpected) 337 && memcmp(buf, kExpected, buf_len) == 0); 338 339 if (0) { 340err: 341 CBB_cleanup(&cbb); 342 } 343 free(buf); 344 return ret; 345} 346 347static int 348test_cbb_add_space(void) 349{ 350 static const uint8_t kExpected[] = {1, 2, 0, 0, 0, 0, 7, 8}; 351 uint8_t *buf = NULL; 352 size_t buf_len; 353 uint8_t *data; 354 int ret = 0; 355 CBB cbb; 356 357 CHECK(CBB_init(&cbb, 100)); 358 359 CHECK_GOTO(CBB_add_u16(&cbb, 0x102)); 360 CHECK_GOTO(CBB_add_space(&cbb, &data, 4)); 361 CHECK_GOTO(CBB_add_u16(&cbb, 0x708)); 362 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 363 364 ret |= (buf_len == sizeof(kExpected) 365 && memcmp(buf, kExpected, buf_len) == 0); 366 367 memset(buf, 0xa5, buf_len); 368 CHECK(CBB_init_fixed(&cbb, buf, buf_len)); 369 370 CHECK_GOTO(CBB_add_u16(&cbb, 0x102)); 371 CHECK_GOTO(CBB_add_space(&cbb, &data, 4)); 372 CHECK_GOTO(CBB_add_u16(&cbb, 0x708)); 373 CHECK_GOTO(CBB_finish(&cbb, NULL, NULL)); 374 375 ret |= (buf_len == sizeof(kExpected) 376 && memcmp(buf, kExpected, buf_len) == 0); 377 378 if (0) { 379err: 380 CBB_cleanup(&cbb); 381 } 382 free(buf); 383 return ret; 384} 385 386static int 387test_cbb_fixed(void) 388{ 389 CBB cbb; 390 uint8_t buf[1]; 391 uint8_t *out_buf = NULL; 392 size_t out_size; 393 int ret = 0; 394 395 CHECK(CBB_init_fixed(&cbb, NULL, 0)); 396 CHECK_GOTO(!CBB_add_u8(&cbb, 1)); 397 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); 398 CHECK(out_buf == NULL && out_size == 0); 399 400 CHECK(CBB_init_fixed(&cbb, buf, 1)); 401 CHECK_GOTO(CBB_add_u8(&cbb, 1)); 402 CHECK_GOTO(!CBB_add_u8(&cbb, 2)); 403 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); 404 405 ret = (out_buf == buf && out_size == 1 && buf[0] == 1); 406 407 if (0) { 408err: 409 CBB_cleanup(&cbb); 410 } 411 412 return ret; 413} 414 415static int 416test_cbb_finish_child(void) 417{ 418 CBB cbb, child; 419 uint8_t *out_buf = NULL; 420 size_t out_size; 421 int ret = 0; 422 423 CHECK(CBB_init(&cbb, 16)); 424 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); 425 CHECK_GOTO(!CBB_finish(&child, &out_buf, &out_size)); 426 CHECK_GOTO(CBB_finish(&cbb, &out_buf, &out_size)); 427 428 ret = (out_size == 1 && out_buf[0] == 0); 429 430err: 431 free(out_buf); 432 return ret; 433} 434 435static int 436test_cbb_prefixed(void) 437{ 438 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3, 439 4, 5, 6, 5, 4, 1, 0, 1, 2}; 440 CBB cbb, contents, inner_contents, inner_inner_contents; 441 uint8_t *buf = NULL; 442 size_t buf_len; 443 int ret = 0; 444 445 CHECK(CBB_init(&cbb, 0)); 446 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 447 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 448 CHECK_GOTO(CBB_add_u8(&contents, 1)); 449 CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents)); 450 CHECK_GOTO(CBB_add_u16(&contents, 0x203)); 451 CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents)); 452 CHECK_GOTO(CBB_add_u24(&contents, 0x40506)); 453 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 454 CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents)); 455 CHECK_GOTO(CBB_add_u8(&inner_contents, 1)); 456 CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents, 457 &inner_inner_contents)); 458 CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 2)); 459 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 460 461 ret = (buf_len == sizeof(kExpected) 462 && memcmp(buf, kExpected, buf_len) == 0); 463 464 if (0) { 465err: 466 CBB_cleanup(&cbb); 467 } 468 free(buf); 469 return ret; 470} 471 472static int 473test_cbb_discard_child(void) 474{ 475 static const uint8_t kExpected[] = { 476 0xaa, 477 0, 478 1, 0xbb, 479 0, 2, 0xcc, 0xcc, 480 0, 0, 3, 0xdd, 0xdd, 0xdd, 481 1, 0xff, 482 }; 483 CBB cbb, contents, inner_contents, inner_inner_contents; 484 uint8_t *buf = NULL; 485 size_t buf_len; 486 int ret = 0; 487 488 CHECK(CBB_init(&cbb, 0)); 489 CHECK_GOTO(CBB_add_u8(&cbb, 0xaa)); 490 491 // Discarding |cbb|'s children preserves the byte written. 492 CBB_discard_child(&cbb); 493 494 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 495 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 496 CHECK_GOTO(CBB_add_u8(&contents, 0xbb)); 497 CHECK_GOTO(CBB_add_u16_length_prefixed(&cbb, &contents)); 498 CHECK_GOTO(CBB_add_u16(&contents, 0xcccc)); 499 CHECK_GOTO(CBB_add_u24_length_prefixed(&cbb, &contents)); 500 CHECK_GOTO(CBB_add_u24(&contents, 0xdddddd)); 501 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &contents)); 502 CHECK_GOTO(CBB_add_u8(&contents, 0xff)); 503 CHECK_GOTO(CBB_add_u8_length_prefixed(&contents, &inner_contents)); 504 CHECK_GOTO(CBB_add_u8(&inner_contents, 0x42)); 505 CHECK_GOTO(CBB_add_u16_length_prefixed(&inner_contents, 506 &inner_inner_contents)); 507 CHECK_GOTO(CBB_add_u8(&inner_inner_contents, 0x99)); 508 509 // Discard everything from |inner_contents| down. 510 CBB_discard_child(&contents); 511 512 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 513 514 ret = (buf_len == sizeof(kExpected) 515 && memcmp(buf, kExpected, buf_len) == 0); 516 517 if (0) { 518err: 519 CBB_cleanup(&cbb); 520 } 521 free(buf); 522 return ret; 523} 524 525static int 526test_cbb_misuse(void) 527{ 528 CBB cbb, child, contents; 529 uint8_t *buf = NULL; 530 size_t buf_len; 531 int ret = 0; 532 533 CHECK(CBB_init(&cbb, 0)); 534 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); 535 CHECK_GOTO(CBB_add_u8(&child, 1)); 536 CHECK_GOTO(CBB_add_u8(&cbb, 2)); 537 538 /* 539 * Since we wrote to |cbb|, |child| is now invalid and attempts to write 540 * to it should fail. 541 */ 542 CHECK_GOTO(!CBB_add_u8(&child, 1)); 543 CHECK_GOTO(!CBB_add_u16(&child, 1)); 544 CHECK_GOTO(!CBB_add_u24(&child, 1)); 545 CHECK_GOTO(!CBB_add_u8_length_prefixed(&child, &contents)); 546 CHECK_GOTO(!CBB_add_u16_length_prefixed(&child, &contents)); 547 CHECK_GOTO(!CBB_add_asn1(&child, &contents, 1)); 548 CHECK_GOTO(!CBB_add_bytes(&child, (const uint8_t*) "a", 1)); 549 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 550 551 ret = (buf_len == 3 && memcmp(buf, "\x01\x01\x02", 3) == 0); 552 553 if (0) { 554err: 555 CBB_cleanup(&cbb); 556 } 557 free(buf); 558 return ret; 559} 560 561static int 562test_cbb_asn1(void) 563{ 564 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3}; 565 uint8_t *buf = NULL, *test_data = NULL; 566 size_t buf_len; 567 CBB cbb, contents, inner_contents; 568 int ret = 0; 569 int alloc = 0; 570 571 CHECK_GOTO(CBB_init(&cbb, 0)); 572 alloc = 1; 573 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 574 CHECK_GOTO(CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 575 3)); 576 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 577 alloc = 0; 578 579 CHECK_GOTO(buf_len == sizeof(kExpected)); 580 CHECK_GOTO(memcmp(buf, kExpected, buf_len) == 0); 581 582 free(buf); 583 buf = NULL; 584 585 CHECK_GOTO(((test_data = malloc(100000)) != NULL)); 586 memset(test_data, 0x42, 100000); 587 588 CHECK_GOTO(CBB_init(&cbb, 0)); 589 alloc = 1; 590 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 591 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 130)); 592 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 593 alloc = 0; 594 595 CHECK_GOTO(buf_len == 3 + 130); 596 CHECK_GOTO(memcmp(buf, "\x30\x81\x82", 3) == 0); 597 CHECK_GOTO(memcmp(buf + 3, test_data, 130) == 0); 598 599 free(buf); 600 buf = NULL; 601 602 CHECK_GOTO(CBB_init(&cbb, 0)); 603 alloc = 1; 604 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 605 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 1000)); 606 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 607 alloc = 0; 608 609 CHECK_GOTO(buf_len == 4 + 1000); 610 CHECK_GOTO(memcmp(buf, "\x30\x82\x03\xe8", 4) == 0); 611 CHECK_GOTO(!memcmp(buf + 4, test_data, 1000)); 612 613 free(buf); 614 buf = NULL; 615 616 CHECK_GOTO(CBB_init(&cbb, 0)); 617 alloc = 1; 618 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 619 CHECK_GOTO(CBB_add_asn1(&contents, &inner_contents, 0x30)); 620 CHECK_GOTO(CBB_add_bytes(&inner_contents, test_data, 100000)); 621 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 622 alloc = 0; 623 624 CHECK_GOTO(buf_len == 5 + 5 + 100000); 625 CHECK_GOTO(memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) 626 == 0); 627 CHECK_GOTO(!memcmp(buf + 10, test_data, 100000)); 628 629 ret = 1; 630 631 if (0) { 632err: 633 if (alloc) 634 CBB_cleanup(&cbb); 635 } 636 free(buf); 637 free(test_data); 638 return ret; 639} 640 641static int 642do_indefinite_convert(const char *name, const uint8_t *definite_expected, 643 size_t definite_len, const uint8_t *indefinite, size_t indefinite_len) 644{ 645 CBS in; 646 uint8_t *out = NULL; 647 size_t out_len; 648 int ret = 0; 649 650 CBS_init(&in, indefinite, indefinite_len); 651 652 CHECK_GOTO(CBS_asn1_indefinite_to_definite(&in, &out, &out_len)); 653 654 if (out == NULL) { 655 656 if (indefinite_len != definite_len || 657 memcmp(definite_expected, indefinite, indefinite_len) != 0) { 658 PRINT_ERROR; 659 goto err; 660 } 661 662 return 1; 663 } 664 665 if (out_len != definite_len || 666 memcmp(out, definite_expected, definite_len) != 0) { 667 PRINT_ERROR; 668 goto err; 669 } 670 671 ret = 1; 672err: 673 free(out); 674 return ret; 675} 676 677static int 678test_indefinite_convert(void) 679{ 680 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; 681 682 /* kIndefBER contains a SEQUENCE with an indefinite length. */ 683 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 684 0x00}; 685 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; 686 687 /* 688 * kOctetStringBER contains an indefinite length OCTETSTRING with two 689 * parts. These parts need to be concatenated in DER form. 690 */ 691 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 692 1, 0x04, 0x02, 2, 3, 0x00, 0x00}; 693 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; 694 695 /* 696 * kNSSBER is part of a PKCS#12 message generated by NSS that uses 697 * indefinite length elements extensively. 698 */ 699 static const uint8_t kNSSBER[] = { 700 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 701 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 702 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 703 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 704 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 705 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 706 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44, 707 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b, 708 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, 709 }; 710 711 static const uint8_t kNSSDER[] = { 712 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, 713 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, 714 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 715 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 716 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 717 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 718 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 719 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 720 }; 721 722 CHECK(do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), 723 kSimpleBER, sizeof(kSimpleBER))); 724 CHECK(do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), 725 kIndefBER, sizeof(kIndefBER))); 726 CHECK(do_indefinite_convert("kOctetStringBER", kOctetStringDER, 727 sizeof(kOctetStringDER), kOctetStringBER, 728 sizeof(kOctetStringBER))); 729 CHECK(do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, 730 sizeof(kNSSBER))); 731 732 return 1; 733} 734 735typedef struct { 736 uint64_t value; 737 const char *encoding; 738 size_t encoding_len; 739} ASN1_UINT64_TEST; 740 741static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { 742 {0, "\x02\x01\x00", 3}, 743 {1, "\x02\x01\x01", 3}, 744 {127, "\x02\x01\x7f", 3}, 745 {128, "\x02\x02\x00\x80", 4}, 746 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, 747 {OPENSSL_U64(0x0102030405060708), 748 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, 749 {OPENSSL_U64(0xffffffffffffffff), 750 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, 751}; 752 753typedef struct { 754 const char *encoding; 755 size_t encoding_len; 756} ASN1_INVALID_UINT64_TEST; 757 758static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { 759 /* Bad tag. */ 760 {"\x03\x01\x00", 3}, 761 /* Empty contents. */ 762 {"\x02\x00", 2}, 763 /* Negative number. */ 764 {"\x02\x01\x80", 3}, 765 /* Overflow. */ 766 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, 767 /* Leading zeros. */ 768 {"\x02\x02\x00\x01", 4}, 769}; 770 771static int 772test_asn1_uint64(void) 773{ 774 CBB cbb; 775 uint8_t *out = NULL; 776 size_t i; 777 int ret = 0; 778 int alloc = 0; 779 780 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); 781 i++) { 782 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; 783 CBS cbs; 784 uint64_t value; 785 size_t len; 786 787 CBS_init(&cbs, (const uint8_t *)test->encoding, 788 test->encoding_len); 789 790 CHECK(CBS_get_asn1_uint64(&cbs, &value)); 791 CHECK(CBS_len(&cbs) == 0); 792 CHECK(value == test->value); 793 794 CHECK(CBB_init(&cbb, 0)); 795 alloc = 1; 796 CHECK_GOTO(CBB_add_asn1_uint64(&cbb, test->value)); 797 CHECK_GOTO(CBB_finish(&cbb, &out, &len)); 798 alloc = 0; 799 800 CHECK_GOTO(len == test->encoding_len); 801 CHECK_GOTO(memcmp(out, test->encoding, len) == 0); 802 free(out); 803 out = NULL; 804 } 805 806 for (i = 0; i < sizeof(kAsn1InvalidUint64Tests) 807 / sizeof(kAsn1InvalidUint64Tests[0]); i++) { 808 const ASN1_INVALID_UINT64_TEST *test = 809 &kAsn1InvalidUint64Tests[i]; 810 CBS cbs; 811 uint64_t value; 812 813 CBS_init(&cbs, (const uint8_t *)test->encoding, 814 test->encoding_len); 815 CHECK(!CBS_get_asn1_uint64(&cbs, &value)); 816 } 817 818 ret = 1; 819 820 if (0) { 821err: 822 if (alloc) 823 CBB_cleanup(&cbb); 824 } 825 free(out); 826 827 return ret; 828} 829 830static int 831test_offset(void) 832{ 833 uint8_t v; 834 static const uint8_t input[] = {1, 2, 3, 4, 5}; 835 CBS data; 836 837 CBS_init(&data, input, sizeof(input)); 838 CHECK(sizeof(input) == 5); 839 CHECK(CBS_len(&data) == 5); 840 CHECK(CBS_offset(&data) == 0); 841 CHECK(CBS_get_u8(&data, &v)); 842 CHECK(v == 1); 843 CHECK(CBS_len(&data) == 4); 844 CHECK(CBS_offset(&data) == 1); 845 CHECK(CBS_skip(&data, 2)); 846 CHECK(CBS_len(&data) == 2); 847 CHECK(CBS_offset(&data) == 3); 848 CHECK(CBS_get_u8(&data, &v)); 849 CHECK(v == 4); 850 CHECK(CBS_get_u8(&data, &v)); 851 CHECK(v == 5); 852 CHECK(CBS_len(&data) == 0); 853 CHECK(CBS_offset(&data) == 5); 854 CHECK(!CBS_skip(&data, 1)); 855 856 CBS_init(&data, input, sizeof(input)); 857 CHECK(CBS_skip(&data, 2)); 858 CHECK(CBS_len(&data) == 3); 859 CHECK(CBS_offset(&data) == 2); 860 CHECK(CBS_skip(&data, 3)); 861 CHECK(CBS_len(&data) == 0); 862 CHECK(CBS_offset(&data) == 5); 863 CHECK(!CBS_get_u8(&data, &v)); 864 865 return 1; 866} 867 868static int 869test_write_bytes(void) 870{ 871 int ret = 0; 872 uint8_t v; 873 size_t len; 874 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 875 CBS data; 876 uint8_t *tmp = NULL; 877 878 CHECK_GOTO((tmp = malloc(sizeof(input))) != NULL); 879 memset(tmp, 100, sizeof(input)); 880 881 CBS_init(&data, input, sizeof(input)); 882 CHECK_GOTO(CBS_len(&data) == 6); 883 CHECK_GOTO(CBS_offset(&data) == 0); 884 CHECK_GOTO(CBS_get_u8(&data, &v)); 885 CHECK_GOTO(v == 102 /* f */); 886 CHECK_GOTO(CBS_skip(&data, 1)); 887 CHECK_GOTO(!CBS_skip(&data, 15)); 888 CHECK_GOTO(CBS_write_bytes(&data, tmp, sizeof(input), &len)); 889 CHECK_GOTO(len == 4); 890 CHECK_GOTO(memcmp(input + 2, tmp, len) == 0); 891 CHECK_GOTO(tmp[4] == 100 && tmp[5] == 100); 892 893 ret = 1; 894 895err: 896 free(tmp); 897 return ret; 898} 899 900static int 901test_cbs_dup(void) 902{ 903 CBS data, check; 904 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 905 906 CBS_init(&data, input, sizeof(input)); 907 CHECK(CBS_len(&data) == 6); 908 CBS_dup(&data, &check); 909 CHECK(CBS_len(&check) == 6); 910 CHECK(CBS_data(&data) == CBS_data(&check)); 911 CHECK(CBS_skip(&data, 1)); 912 CHECK(CBS_len(&data) == 5); 913 CHECK(CBS_len(&check) == 6); 914 CHECK(CBS_data(&data) == CBS_data(&check) + 1); 915 CHECK(CBS_skip(&check, 1)); 916 CHECK(CBS_len(&data) == 5); 917 CHECK(CBS_len(&check) == 5); 918 CHECK(CBS_data(&data) == CBS_data(&check)); 919 CHECK(CBS_offset(&data) == 1); 920 CHECK(CBS_offset(&check) == 1); 921 922 CBS_init(&data, input, sizeof(input)); 923 CHECK(CBS_skip(&data, 5)); 924 CBS_dup(&data, &check); 925 CHECK(CBS_len(&data) == 1); 926 CHECK(CBS_len(&check) == 1); 927 CHECK(CBS_data(&data) == input + 5); 928 CHECK(CBS_data(&data) == CBS_data(&check)); 929 CHECK(CBS_offset(&data) == 5); 930 CHECK(CBS_offset(&check) == 5); 931 932 return 1; 933} 934 935int 936main(void) 937{ 938 int failed = 0; 939 940 failed |= !test_skip(); 941 failed |= !test_get_u(); 942 failed |= !test_get_prefixed(); 943 failed |= !test_get_prefixed_bad(); 944 failed |= !test_peek_u(); 945 failed |= !test_get_asn1(); 946 failed |= !test_cbb_basic(); 947 failed |= !test_cbb_add_space(); 948 failed |= !test_cbb_fixed(); 949 failed |= !test_cbb_finish_child(); 950 failed |= !test_cbb_discard_child(); 951 failed |= !test_cbb_misuse(); 952 failed |= !test_cbb_prefixed(); 953 failed |= !test_cbb_asn1(); 954 failed |= !test_indefinite_convert(); 955 failed |= !test_asn1_uint64(); 956 failed |= !test_get_optional_asn1_bool(); 957 failed |= !test_offset(); 958 failed |= !test_write_bytes(); 959 failed |= !test_cbs_dup(); 960 961 if (!failed) 962 printf("PASS\n"); 963 return failed; 964} 965