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