bytestringtest.c revision 1.4
1/* $OpenBSD: bytestringtest.c,v 1.4 2015/04/25 15:28:47 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_ber_convert(const char *name, const uint8_t *der_expected, size_t der_len, 488 const uint8_t *ber, size_t ber_len) 489{ 490 CBS in; 491 uint8_t *out = NULL; 492 size_t out_len; 493 int ret = 0; 494 495 CBS_init(&in, ber, ber_len); 496 if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) { 497 fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name); 498 goto end; 499 } 500 501 if (out == NULL) { 502 if (ber_len != der_len || 503 memcmp(der_expected, ber, ber_len) != 0) { 504 fprintf(stderr, "%s: incorrect unconverted result.\n", 505 name); 506 return 0; 507 } 508 509 return 1; 510 } 511 512 if (out_len != der_len || memcmp(out, der_expected, der_len) != 0) { 513 fprintf(stderr, "%s: incorrect converted result.\n", name); 514 goto end; 515 } 516 517 ret = 1; 518 519end: 520 free(out); 521 return ret; 522} 523 524static int 525test_ber_convert(void) 526{ 527 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; 528 529 /* kIndefBER contains a SEQUENCE with an indefinite length. */ 530 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 531 0x00}; 532 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; 533 534 /* 535 * kOctetStringBER contains an indefinite length OCTETSTRING with two 536 * parts. These parts need to be concatenated in DER form. 537 */ 538 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 539 1, 0x04, 0x02, 2, 3, 0x00, 0x00}; 540 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; 541 542 /* 543 * kNSSBER is part of a PKCS#12 message generated by NSS that uses 544 * indefinite length elements extensively. 545 */ 546 static const uint8_t kNSSBER[] = { 547 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 548 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 549 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 550 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 551 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 552 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 553 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44, 554 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b, 555 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, 556 }; 557 558 static const uint8_t kNSSDER[] = { 559 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, 560 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, 561 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 562 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 563 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 564 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 565 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 566 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 567 }; 568 569 return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), 570 kSimpleBER, sizeof(kSimpleBER)) && 571 do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER, 572 sizeof(kIndefBER)) && 573 do_ber_convert("kOctetStringBER", kOctetStringDER, 574 sizeof(kOctetStringDER), kOctetStringBER, 575 sizeof(kOctetStringBER)) && 576 do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, 577 sizeof(kNSSBER)); 578} 579 580typedef struct { 581 uint64_t value; 582 const char *encoding; 583 size_t encoding_len; 584} ASN1_UINT64_TEST; 585 586static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { 587 {0, "\x02\x01\x00", 3}, 588 {1, "\x02\x01\x01", 3}, 589 {127, "\x02\x01\x7f", 3}, 590 {128, "\x02\x02\x00\x80", 4}, 591 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, 592 {OPENSSL_U64(0x0102030405060708), 593 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, 594 {OPENSSL_U64(0xffffffffffffffff), 595 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, 596}; 597 598typedef struct { 599 const char *encoding; 600 size_t encoding_len; 601} ASN1_INVALID_UINT64_TEST; 602 603static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { 604 /* Bad tag. */ 605 {"\x03\x01\x00", 3}, 606 /* Empty contents. */ 607 {"\x02\x00", 2}, 608 /* Negative number. */ 609 {"\x02\x01\x80", 3}, 610 /* Overflow. */ 611 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, 612 /* Leading zeros. */ 613 {"\x02\x02\x00\x01", 4}, 614}; 615 616static int 617test_asn1_uint64(void) 618{ 619 size_t i; 620 621 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); 622 i++) { 623 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; 624 CBS cbs; 625 uint64_t value; 626 CBB cbb; 627 uint8_t *out; 628 size_t len; 629 630 CBS_init(&cbs, (const uint8_t *)test->encoding, 631 test->encoding_len); 632 633 if (!CBS_get_asn1_uint64(&cbs, &value) || 634 CBS_len(&cbs) != 0 || 635 value != test->value) 636 return 0; 637 638 if (!CBB_init(&cbb, 0)) 639 return 0; 640 641 if (!CBB_add_asn1_uint64(&cbb, test->value) || 642 !CBB_finish(&cbb, &out, &len)) { 643 CBB_cleanup(&cbb); 644 return 0; 645 } 646 647 if (len != test->encoding_len || memcmp(out, test->encoding, 648 len) != 0) { 649 free(out); 650 return 0; 651 } 652 free(out); 653 } 654 655 for (i = 0; i < sizeof(kAsn1InvalidUint64Tests) 656 / sizeof(kAsn1InvalidUint64Tests[0]); i++) { 657 const ASN1_INVALID_UINT64_TEST *test = 658 &kAsn1InvalidUint64Tests[i]; 659 CBS cbs; 660 uint64_t value; 661 662 CBS_init(&cbs, (const uint8_t *)test->encoding, 663 test->encoding_len); 664 if (CBS_get_asn1_uint64(&cbs, &value)) 665 return 0; 666 } 667 668 return 1; 669} 670 671int 672main(void) 673{ 674 if (!test_skip() || 675 !test_get_u() || 676 !test_get_prefixed() || 677 !test_get_prefixed_bad() || 678 !test_get_asn1() || 679 !test_cbb_basic() || 680 !test_cbb_fixed() || 681 !test_cbb_finish_child() || 682 !test_cbb_misuse() || 683 !test_cbb_prefixed() || 684 !test_cbb_asn1() || 685 !test_ber_convert() || 686 !test_asn1_uint64() || 687 !test_get_optional_asn1_bool()) 688 return 1; 689 690 printf("PASS\n"); 691 return 0; 692} 693