bytestringtest.c revision 1.9
1/* $OpenBSD: bytestringtest.c,v 1.9 2015/07/18 21:57:00 bcook 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[] = {0x30, 0x82, 0, 1, 1}; 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 uint8_t *buf = NULL; 354 size_t buf_len; 355 CBB cbb, contents, inner_contents, inner_inner_contents; 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_misuse(void) 387{ 388 CBB cbb, child, contents; 389 uint8_t *buf = NULL; 390 size_t buf_len; 391 int ret = 0; 392 393 CHECK(CBB_init(&cbb, 0)); 394 CHECK_GOTO(CBB_add_u8_length_prefixed(&cbb, &child)); 395 CHECK_GOTO(CBB_add_u8(&child, 1)); 396 CHECK_GOTO(CBB_add_u8(&cbb, 2)); 397 398 /* 399 * Since we wrote to |cbb|, |child| is now invalid and attempts to write 400 * to it should fail. 401 */ 402 CHECK_GOTO(!CBB_add_u8(&child, 1)); 403 CHECK_GOTO(!CBB_add_u16(&child, 1)); 404 CHECK_GOTO(!CBB_add_u24(&child, 1)); 405 CHECK_GOTO(!CBB_add_u8_length_prefixed(&child, &contents)); 406 CHECK_GOTO(!CBB_add_u16_length_prefixed(&child, &contents)); 407 CHECK_GOTO(!CBB_add_asn1(&child, &contents, 1)); 408 CHECK_GOTO(!CBB_add_bytes(&child, (const uint8_t*) "a", 1)); 409 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 410 411 ret = (buf_len == 3 && memcmp(buf, "\x01\x01\x02", 3) == 0); 412 413 if (0) { 414err: 415 CBB_cleanup(&cbb); 416 } 417 free(buf); 418 return ret; 419} 420 421static int 422test_cbb_asn1(void) 423{ 424 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3}; 425 uint8_t *buf = NULL, *test_data = NULL; 426 size_t buf_len; 427 CBB cbb, contents, inner_contents; 428 int ret = 0; 429 int alloc = 0; 430 431 CHECK_GOTO(CBB_init(&cbb, 0)); 432 alloc = 1; 433 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 434 CHECK_GOTO(CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 435 3)); 436 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 437 alloc = 0; 438 439 CHECK_GOTO(buf_len == sizeof(kExpected)); 440 CHECK_GOTO(memcmp(buf, kExpected, buf_len) == 0); 441 442 free(buf); 443 buf = NULL; 444 445 CHECK_GOTO(((test_data = malloc(100000)) != NULL)); 446 memset(test_data, 0x42, 100000); 447 448 CHECK_GOTO(CBB_init(&cbb, 0)); 449 alloc = 1; 450 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 451 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 130)); 452 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 453 alloc = 0; 454 455 CHECK_GOTO(buf_len == 3 + 130); 456 CHECK_GOTO(memcmp(buf, "\x30\x81\x82", 3) == 0); 457 CHECK_GOTO(memcmp(buf + 3, test_data, 130) == 0); 458 459 free(buf); 460 buf = NULL; 461 462 CHECK_GOTO(CBB_init(&cbb, 0)); 463 alloc = 1; 464 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 465 CHECK_GOTO(CBB_add_bytes(&contents, test_data, 1000)); 466 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 467 alloc = 0; 468 469 CHECK_GOTO(buf_len == 4 + 1000); 470 CHECK_GOTO(memcmp(buf, "\x30\x82\x03\xe8", 4) == 0); 471 CHECK_GOTO(!memcmp(buf + 4, test_data, 1000)); 472 473 free(buf); 474 buf = NULL; 475 476 CHECK_GOTO(CBB_init(&cbb, 0)); 477 alloc = 1; 478 CHECK_GOTO(CBB_add_asn1(&cbb, &contents, 0x30)); 479 CHECK_GOTO(CBB_add_asn1(&contents, &inner_contents, 0x30)); 480 CHECK_GOTO(CBB_add_bytes(&inner_contents, test_data, 100000)); 481 CHECK_GOTO(CBB_finish(&cbb, &buf, &buf_len)); 482 alloc = 0; 483 484 CHECK_GOTO(buf_len == 5 + 5 + 100000); 485 CHECK_GOTO(memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) 486 == 0); 487 CHECK_GOTO(!memcmp(buf + 10, test_data, 100000)); 488 489 ret = 1; 490 491 if (0) { 492err: 493 if (alloc) 494 CBB_cleanup(&cbb); 495 } 496 free(buf); 497 free(test_data); 498 return ret; 499} 500 501static int 502do_indefinite_convert(const char *name, const uint8_t *definite_expected, 503 size_t definite_len, const uint8_t *indefinite, size_t indefinite_len) 504{ 505 CBS in; 506 uint8_t *out = NULL; 507 size_t out_len; 508 int ret = 0; 509 510 CBS_init(&in, indefinite, indefinite_len); 511 512 CHECK_GOTO(CBS_asn1_indefinite_to_definite(&in, &out, &out_len)); 513 514 if (out == NULL) { 515 516 if (indefinite_len != definite_len || 517 memcmp(definite_expected, indefinite, indefinite_len) != 0) { 518 PRINT_ERROR; 519 goto err; 520 } 521 522 return 1; 523 } 524 525 if (out_len != definite_len || 526 memcmp(out, definite_expected, definite_len) != 0) { 527 PRINT_ERROR; 528 goto err; 529 } 530 531 ret = 1; 532err: 533 free(out); 534 return ret; 535} 536 537static int 538test_indefinite_convert(void) 539{ 540 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; 541 542 /* kIndefBER contains a SEQUENCE with an indefinite length. */ 543 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 544 0x00}; 545 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; 546 547 /* 548 * kOctetStringBER contains an indefinite length OCTETSTRING with two 549 * parts. These parts need to be concatenated in DER form. 550 */ 551 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 552 1, 0x04, 0x02, 2, 3, 0x00, 0x00}; 553 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; 554 555 /* 556 * kNSSBER is part of a PKCS#12 message generated by NSS that uses 557 * indefinite length elements extensively. 558 */ 559 static const uint8_t kNSSBER[] = { 560 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 561 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 562 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 563 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 564 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 565 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 566 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44, 567 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b, 568 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, 569 }; 570 571 static const uint8_t kNSSDER[] = { 572 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, 573 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, 574 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 575 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 576 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 577 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 578 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 579 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 580 }; 581 582 CHECK(do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), 583 kSimpleBER, sizeof(kSimpleBER))); 584 CHECK(do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), 585 kIndefBER, sizeof(kIndefBER))); 586 CHECK(do_indefinite_convert("kOctetStringBER", kOctetStringDER, 587 sizeof(kOctetStringDER), kOctetStringBER, 588 sizeof(kOctetStringBER))); 589 CHECK(do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, 590 sizeof(kNSSBER))); 591 592 return 1; 593} 594 595typedef struct { 596 uint64_t value; 597 const char *encoding; 598 size_t encoding_len; 599} ASN1_UINT64_TEST; 600 601static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { 602 {0, "\x02\x01\x00", 3}, 603 {1, "\x02\x01\x01", 3}, 604 {127, "\x02\x01\x7f", 3}, 605 {128, "\x02\x02\x00\x80", 4}, 606 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, 607 {OPENSSL_U64(0x0102030405060708), 608 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, 609 {OPENSSL_U64(0xffffffffffffffff), 610 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, 611}; 612 613typedef struct { 614 const char *encoding; 615 size_t encoding_len; 616} ASN1_INVALID_UINT64_TEST; 617 618static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { 619 /* Bad tag. */ 620 {"\x03\x01\x00", 3}, 621 /* Empty contents. */ 622 {"\x02\x00", 2}, 623 /* Negative number. */ 624 {"\x02\x01\x80", 3}, 625 /* Overflow. */ 626 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, 627 /* Leading zeros. */ 628 {"\x02\x02\x00\x01", 4}, 629}; 630 631static int 632test_asn1_uint64(void) 633{ 634 CBB cbb; 635 uint8_t *out = NULL; 636 size_t i; 637 int ret = 0; 638 int alloc = 0; 639 640 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); 641 i++) { 642 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; 643 CBS cbs; 644 uint64_t value; 645 size_t len; 646 647 CBS_init(&cbs, (const uint8_t *)test->encoding, 648 test->encoding_len); 649 650 CHECK(CBS_get_asn1_uint64(&cbs, &value)); 651 CHECK(CBS_len(&cbs) == 0); 652 CHECK(value == test->value); 653 654 CHECK(CBB_init(&cbb, 0)); 655 alloc = 1; 656 CHECK_GOTO(CBB_add_asn1_uint64(&cbb, test->value)); 657 CHECK_GOTO(CBB_finish(&cbb, &out, &len)); 658 alloc = 0; 659 660 CHECK_GOTO(len == test->encoding_len); 661 CHECK_GOTO(memcmp(out, test->encoding, len) == 0); 662 free(out); 663 out = NULL; 664 } 665 666 for (i = 0; i < sizeof(kAsn1InvalidUint64Tests) 667 / sizeof(kAsn1InvalidUint64Tests[0]); i++) { 668 const ASN1_INVALID_UINT64_TEST *test = 669 &kAsn1InvalidUint64Tests[i]; 670 CBS cbs; 671 uint64_t value; 672 673 CBS_init(&cbs, (const uint8_t *)test->encoding, 674 test->encoding_len); 675 CHECK(!CBS_get_asn1_uint64(&cbs, &value)); 676 } 677 678 ret = 1; 679 680 if (0) { 681err: 682 if (alloc) 683 CBB_cleanup(&cbb); 684 } 685 free(out); 686 687 return ret; 688} 689 690static int 691test_offset(void) 692{ 693 uint8_t v; 694 static const uint8_t input[] = {1, 2, 3, 4, 5}; 695 CBS data; 696 697 CBS_init(&data, input, sizeof(input)); 698 CHECK(sizeof(input) == 5); 699 CHECK(CBS_len(&data) == 5); 700 CHECK(CBS_offset(&data) == 0); 701 CHECK(CBS_get_u8(&data, &v)); 702 CHECK(v == 1); 703 CHECK(CBS_len(&data) == 4); 704 CHECK(CBS_offset(&data) == 1); 705 CHECK(CBS_skip(&data, 2)); 706 CHECK(CBS_len(&data) == 2); 707 CHECK(CBS_offset(&data) == 3); 708 CHECK(CBS_get_u8(&data, &v)); 709 CHECK(v == 4); 710 CHECK(CBS_get_u8(&data, &v)); 711 CHECK(v == 5); 712 CHECK(CBS_len(&data) == 0); 713 CHECK(CBS_offset(&data) == 5); 714 CHECK(!CBS_skip(&data, 1)); 715 716 CBS_init(&data, input, sizeof(input)); 717 CHECK(CBS_skip(&data, 2)); 718 CHECK(CBS_len(&data) == 3); 719 CHECK(CBS_offset(&data) == 2); 720 CHECK(CBS_skip(&data, 3)); 721 CHECK(CBS_len(&data) == 0); 722 CHECK(CBS_offset(&data) == 5); 723 CHECK(!CBS_get_u8(&data, &v)); 724 725 return 1; 726} 727 728static int 729test_write_bytes(void) 730{ 731 int ret = 0; 732 uint8_t v; 733 size_t len; 734 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 735 CBS data; 736 char *tmp = NULL; 737 738 CHECK_GOTO((tmp = malloc(sizeof(input))) != NULL); 739 memset(tmp, 100, sizeof(input)); 740 741 CBS_init(&data, input, sizeof(input)); 742 CHECK_GOTO(CBS_len(&data) == 6); 743 CHECK_GOTO(CBS_offset(&data) == 0); 744 CHECK_GOTO(CBS_get_u8(&data, &v)); 745 CHECK_GOTO(v == 102 /* f */); 746 CHECK_GOTO(CBS_skip(&data, 1)); 747 CHECK_GOTO(!CBS_skip(&data, 15)); 748 CHECK_GOTO(CBS_write_bytes(&data, tmp, sizeof(input), &len)); 749 CHECK_GOTO(len == 4); 750 CHECK_GOTO(memcmp(input + 2, tmp, len) == 0); 751 CHECK_GOTO(tmp[4] == 100 && tmp[5] == 100); 752 753 ret = 1; 754 755err: 756 free(tmp); 757 return ret; 758} 759 760static int 761test_cbs_dup(void) 762{ 763 CBS data, check; 764 static const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'}; 765 766 CBS_init(&data, input, sizeof(input)); 767 CHECK(CBS_len(&data) == 6); 768 CBS_dup(&data, &check); 769 CHECK(CBS_len(&check) == 6); 770 CHECK(CBS_data(&data) == CBS_data(&check)); 771 CHECK(CBS_skip(&data, 1)); 772 CHECK(CBS_len(&data) == 5); 773 CHECK(CBS_len(&check) == 6); 774 CHECK(CBS_data(&data) == CBS_data(&check) + 1); 775 CHECK(CBS_skip(&check, 1)); 776 CHECK(CBS_len(&data) == 5); 777 CHECK(CBS_len(&check) == 5); 778 CHECK(CBS_data(&data) == CBS_data(&check)); 779 CHECK(CBS_offset(&data) == 1); 780 CHECK(CBS_offset(&check) == 1); 781 782 CBS_init(&data, input, sizeof(input)); 783 CHECK(CBS_skip(&data, 5)); 784 CBS_dup(&data, &check); 785 CHECK(CBS_len(&data) == 1); 786 CHECK(CBS_len(&check) == 1); 787 CHECK(CBS_data(&data) == input + 5); 788 CHECK(CBS_data(&data) == CBS_data(&check)); 789 CHECK(CBS_offset(&data) == 5); 790 CHECK(CBS_offset(&check) == 5); 791 792 return 1; 793} 794 795int 796main(void) 797{ 798 int failed = 0; 799 800 failed |= !test_skip(); 801 failed |= !test_get_u(); 802 failed |= !test_get_prefixed(); 803 failed |= !test_get_prefixed_bad(); 804 failed |= !test_get_asn1(); 805 failed |= !test_cbb_basic(); 806 failed |= !test_cbb_fixed(); 807 failed |= !test_cbb_finish_child(); 808 failed |= !test_cbb_misuse(); 809 failed |= !test_cbb_prefixed(); 810 failed |= !test_cbb_asn1(); 811 failed |= !test_indefinite_convert(); 812 failed |= !test_asn1_uint64(); 813 failed |= !test_get_optional_asn1_bool(); 814 failed |= !test_offset(); 815 failed |= !test_write_bytes(); 816 failed |= !test_cbs_dup(); 817 818 if (!failed) 819 printf("PASS\n"); 820 return failed; 821} 822