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