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