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