link_handshake.c (43614B)
1 /* link_handshake.c -- generated by Trunnel v1.5.3. 2 * https://gitweb.torproject.org/trunnel.git 3 * You probably shouldn't edit this file. 4 */ 5 #include <stdlib.h> 6 #include "trunnel-impl.h" 7 8 #include "link_handshake.h" 9 10 #define TRUNNEL_SET_ERROR_CODE(obj) \ 11 do { \ 12 (obj)->trunnel_error_code_ = 1; \ 13 } while (0) 14 15 #if defined(__COVERITY__) || defined(__clang_analyzer__) 16 /* If we're running a static analysis tool, we don't want it to complain 17 * that some of our remaining-bytes checks are dead-code. */ 18 int linkhandshake_deadcode_dummy__ = 0; 19 #define OR_DEADCODE_DUMMY || linkhandshake_deadcode_dummy__ 20 #else 21 #define OR_DEADCODE_DUMMY 22 #endif 23 24 #define CHECK_REMAINING(nbytes, label) \ 25 do { \ 26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \ 27 goto label; \ 28 } \ 29 } while (0) 30 31 auth1_t * 32 auth1_new(void) 33 { 34 auth1_t *val = trunnel_calloc(1, sizeof(auth1_t)); 35 if (NULL == val) 36 return NULL; 37 return val; 38 } 39 40 /** Release all storage held inside 'obj', but do not free 'obj'. 41 */ 42 static void 43 auth1_clear(auth1_t *obj) 44 { 45 (void) obj; 46 TRUNNEL_DYNARRAY_WIPE(&obj->sig); 47 TRUNNEL_DYNARRAY_CLEAR(&obj->sig); 48 } 49 50 void 51 auth1_free(auth1_t *obj) 52 { 53 if (obj == NULL) 54 return; 55 auth1_clear(obj); 56 trunnel_memwipe(obj, sizeof(auth1_t)); 57 trunnel_free_(obj); 58 } 59 60 size_t 61 auth1_getlen_type(const auth1_t *inp) 62 { 63 (void)inp; return 8; 64 } 65 66 uint8_t 67 auth1_get_type(auth1_t *inp, size_t idx) 68 { 69 trunnel_assert(idx < 8); 70 return inp->type[idx]; 71 } 72 73 uint8_t 74 auth1_getconst_type(const auth1_t *inp, size_t idx) 75 { 76 return auth1_get_type((auth1_t*)inp, idx); 77 } 78 int 79 auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt) 80 { 81 trunnel_assert(idx < 8); 82 inp->type[idx] = elt; 83 return 0; 84 } 85 86 uint8_t * 87 auth1_getarray_type(auth1_t *inp) 88 { 89 return inp->type; 90 } 91 const uint8_t * 92 auth1_getconstarray_type(const auth1_t *inp) 93 { 94 return (const uint8_t *)auth1_getarray_type((auth1_t*)inp); 95 } 96 size_t 97 auth1_getlen_cid(const auth1_t *inp) 98 { 99 (void)inp; return 32; 100 } 101 102 uint8_t 103 auth1_get_cid(auth1_t *inp, size_t idx) 104 { 105 trunnel_assert(idx < 32); 106 return inp->cid[idx]; 107 } 108 109 uint8_t 110 auth1_getconst_cid(const auth1_t *inp, size_t idx) 111 { 112 return auth1_get_cid((auth1_t*)inp, idx); 113 } 114 int 115 auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt) 116 { 117 trunnel_assert(idx < 32); 118 inp->cid[idx] = elt; 119 return 0; 120 } 121 122 uint8_t * 123 auth1_getarray_cid(auth1_t *inp) 124 { 125 return inp->cid; 126 } 127 const uint8_t * 128 auth1_getconstarray_cid(const auth1_t *inp) 129 { 130 return (const uint8_t *)auth1_getarray_cid((auth1_t*)inp); 131 } 132 size_t 133 auth1_getlen_sid(const auth1_t *inp) 134 { 135 (void)inp; return 32; 136 } 137 138 uint8_t 139 auth1_get_sid(auth1_t *inp, size_t idx) 140 { 141 trunnel_assert(idx < 32); 142 return inp->sid[idx]; 143 } 144 145 uint8_t 146 auth1_getconst_sid(const auth1_t *inp, size_t idx) 147 { 148 return auth1_get_sid((auth1_t*)inp, idx); 149 } 150 int 151 auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt) 152 { 153 trunnel_assert(idx < 32); 154 inp->sid[idx] = elt; 155 return 0; 156 } 157 158 uint8_t * 159 auth1_getarray_sid(auth1_t *inp) 160 { 161 return inp->sid; 162 } 163 const uint8_t * 164 auth1_getconstarray_sid(const auth1_t *inp) 165 { 166 return (const uint8_t *)auth1_getarray_sid((auth1_t*)inp); 167 } 168 size_t 169 auth1_getlen_cid_ed(const auth1_t *inp) 170 { 171 (void)inp; return 32; 172 } 173 174 uint8_t 175 auth1_get_cid_ed(auth1_t *inp, size_t idx) 176 { 177 trunnel_assert(idx < 32); 178 return inp->cid_ed[idx]; 179 } 180 181 uint8_t 182 auth1_getconst_cid_ed(const auth1_t *inp, size_t idx) 183 { 184 return auth1_get_cid_ed((auth1_t*)inp, idx); 185 } 186 int 187 auth1_set_cid_ed(auth1_t *inp, size_t idx, uint8_t elt) 188 { 189 trunnel_assert(idx < 32); 190 inp->cid_ed[idx] = elt; 191 return 0; 192 } 193 194 uint8_t * 195 auth1_getarray_cid_ed(auth1_t *inp) 196 { 197 return inp->cid_ed; 198 } 199 const uint8_t * 200 auth1_getconstarray_cid_ed(const auth1_t *inp) 201 { 202 return (const uint8_t *)auth1_getarray_cid_ed((auth1_t*)inp); 203 } 204 size_t 205 auth1_getlen_sid_ed(const auth1_t *inp) 206 { 207 (void)inp; return 32; 208 } 209 210 uint8_t 211 auth1_get_sid_ed(auth1_t *inp, size_t idx) 212 { 213 trunnel_assert(idx < 32); 214 return inp->sid_ed[idx]; 215 } 216 217 uint8_t 218 auth1_getconst_sid_ed(const auth1_t *inp, size_t idx) 219 { 220 return auth1_get_sid_ed((auth1_t*)inp, idx); 221 } 222 int 223 auth1_set_sid_ed(auth1_t *inp, size_t idx, uint8_t elt) 224 { 225 trunnel_assert(idx < 32); 226 inp->sid_ed[idx] = elt; 227 return 0; 228 } 229 230 uint8_t * 231 auth1_getarray_sid_ed(auth1_t *inp) 232 { 233 return inp->sid_ed; 234 } 235 const uint8_t * 236 auth1_getconstarray_sid_ed(const auth1_t *inp) 237 { 238 return (const uint8_t *)auth1_getarray_sid_ed((auth1_t*)inp); 239 } 240 size_t 241 auth1_getlen_slog(const auth1_t *inp) 242 { 243 (void)inp; return 32; 244 } 245 246 uint8_t 247 auth1_get_slog(auth1_t *inp, size_t idx) 248 { 249 trunnel_assert(idx < 32); 250 return inp->slog[idx]; 251 } 252 253 uint8_t 254 auth1_getconst_slog(const auth1_t *inp, size_t idx) 255 { 256 return auth1_get_slog((auth1_t*)inp, idx); 257 } 258 int 259 auth1_set_slog(auth1_t *inp, size_t idx, uint8_t elt) 260 { 261 trunnel_assert(idx < 32); 262 inp->slog[idx] = elt; 263 return 0; 264 } 265 266 uint8_t * 267 auth1_getarray_slog(auth1_t *inp) 268 { 269 return inp->slog; 270 } 271 const uint8_t * 272 auth1_getconstarray_slog(const auth1_t *inp) 273 { 274 return (const uint8_t *)auth1_getarray_slog((auth1_t*)inp); 275 } 276 size_t 277 auth1_getlen_clog(const auth1_t *inp) 278 { 279 (void)inp; return 32; 280 } 281 282 uint8_t 283 auth1_get_clog(auth1_t *inp, size_t idx) 284 { 285 trunnel_assert(idx < 32); 286 return inp->clog[idx]; 287 } 288 289 uint8_t 290 auth1_getconst_clog(const auth1_t *inp, size_t idx) 291 { 292 return auth1_get_clog((auth1_t*)inp, idx); 293 } 294 int 295 auth1_set_clog(auth1_t *inp, size_t idx, uint8_t elt) 296 { 297 trunnel_assert(idx < 32); 298 inp->clog[idx] = elt; 299 return 0; 300 } 301 302 uint8_t * 303 auth1_getarray_clog(auth1_t *inp) 304 { 305 return inp->clog; 306 } 307 const uint8_t * 308 auth1_getconstarray_clog(const auth1_t *inp) 309 { 310 return (const uint8_t *)auth1_getarray_clog((auth1_t*)inp); 311 } 312 size_t 313 auth1_getlen_scert(const auth1_t *inp) 314 { 315 (void)inp; return 32; 316 } 317 318 uint8_t 319 auth1_get_scert(auth1_t *inp, size_t idx) 320 { 321 trunnel_assert(idx < 32); 322 return inp->scert[idx]; 323 } 324 325 uint8_t 326 auth1_getconst_scert(const auth1_t *inp, size_t idx) 327 { 328 return auth1_get_scert((auth1_t*)inp, idx); 329 } 330 int 331 auth1_set_scert(auth1_t *inp, size_t idx, uint8_t elt) 332 { 333 trunnel_assert(idx < 32); 334 inp->scert[idx] = elt; 335 return 0; 336 } 337 338 uint8_t * 339 auth1_getarray_scert(auth1_t *inp) 340 { 341 return inp->scert; 342 } 343 const uint8_t * 344 auth1_getconstarray_scert(const auth1_t *inp) 345 { 346 return (const uint8_t *)auth1_getarray_scert((auth1_t*)inp); 347 } 348 size_t 349 auth1_getlen_tlssecrets(const auth1_t *inp) 350 { 351 (void)inp; return 32; 352 } 353 354 uint8_t 355 auth1_get_tlssecrets(auth1_t *inp, size_t idx) 356 { 357 trunnel_assert(idx < 32); 358 return inp->tlssecrets[idx]; 359 } 360 361 uint8_t 362 auth1_getconst_tlssecrets(const auth1_t *inp, size_t idx) 363 { 364 return auth1_get_tlssecrets((auth1_t*)inp, idx); 365 } 366 int 367 auth1_set_tlssecrets(auth1_t *inp, size_t idx, uint8_t elt) 368 { 369 trunnel_assert(idx < 32); 370 inp->tlssecrets[idx] = elt; 371 return 0; 372 } 373 374 uint8_t * 375 auth1_getarray_tlssecrets(auth1_t *inp) 376 { 377 return inp->tlssecrets; 378 } 379 const uint8_t * 380 auth1_getconstarray_tlssecrets(const auth1_t *inp) 381 { 382 return (const uint8_t *)auth1_getarray_tlssecrets((auth1_t*)inp); 383 } 384 const uint8_t * 385 auth1_get_end_of_fixed_part(const auth1_t *inp) 386 { 387 return inp->end_of_fixed_part; 388 } 389 size_t 390 auth1_getlen_rand(const auth1_t *inp) 391 { 392 (void)inp; return 24; 393 } 394 395 uint8_t 396 auth1_get_rand(auth1_t *inp, size_t idx) 397 { 398 trunnel_assert(idx < 24); 399 return inp->rand[idx]; 400 } 401 402 uint8_t 403 auth1_getconst_rand(const auth1_t *inp, size_t idx) 404 { 405 return auth1_get_rand((auth1_t*)inp, idx); 406 } 407 int 408 auth1_set_rand(auth1_t *inp, size_t idx, uint8_t elt) 409 { 410 trunnel_assert(idx < 24); 411 inp->rand[idx] = elt; 412 return 0; 413 } 414 415 uint8_t * 416 auth1_getarray_rand(auth1_t *inp) 417 { 418 return inp->rand; 419 } 420 const uint8_t * 421 auth1_getconstarray_rand(const auth1_t *inp) 422 { 423 return (const uint8_t *)auth1_getarray_rand((auth1_t*)inp); 424 } 425 const uint8_t * 426 auth1_get_end_of_signed(const auth1_t *inp) 427 { 428 return inp->end_of_signed; 429 } 430 size_t 431 auth1_getlen_sig(const auth1_t *inp) 432 { 433 return TRUNNEL_DYNARRAY_LEN(&inp->sig); 434 } 435 436 uint8_t 437 auth1_get_sig(auth1_t *inp, size_t idx) 438 { 439 return TRUNNEL_DYNARRAY_GET(&inp->sig, idx); 440 } 441 442 uint8_t 443 auth1_getconst_sig(const auth1_t *inp, size_t idx) 444 { 445 return auth1_get_sig((auth1_t*)inp, idx); 446 } 447 int 448 auth1_set_sig(auth1_t *inp, size_t idx, uint8_t elt) 449 { 450 TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt); 451 return 0; 452 } 453 int 454 auth1_add_sig(auth1_t *inp, uint8_t elt) 455 { 456 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {}); 457 return 0; 458 trunnel_alloc_failed: 459 TRUNNEL_SET_ERROR_CODE(inp); 460 return -1; 461 } 462 463 uint8_t * 464 auth1_getarray_sig(auth1_t *inp) 465 { 466 return inp->sig.elts_; 467 } 468 const uint8_t * 469 auth1_getconstarray_sig(const auth1_t *inp) 470 { 471 return (const uint8_t *)auth1_getarray_sig((auth1_t*)inp); 472 } 473 int 474 auth1_setlen_sig(auth1_t *inp, size_t newlen) 475 { 476 uint8_t *newptr; 477 newptr = trunnel_dynarray_setlen(&inp->sig.allocated_, 478 &inp->sig.n_, inp->sig.elts_, newlen, 479 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL, 480 &inp->trunnel_error_code_); 481 if (newlen != 0 && newptr == NULL) 482 goto trunnel_alloc_failed; 483 inp->sig.elts_ = newptr; 484 return 0; 485 trunnel_alloc_failed: 486 TRUNNEL_SET_ERROR_CODE(inp); 487 return -1; 488 } 489 const char * 490 auth1_check(const auth1_t *obj) 491 { 492 if (obj == NULL) 493 return "Object was NULL"; 494 if (obj->trunnel_error_code_) 495 return "A set function failed on this object"; 496 return NULL; 497 } 498 499 ssize_t 500 auth1_encoded_len(const auth1_t *obj) 501 { 502 ssize_t result = 0; 503 504 if (NULL != auth1_check(obj)) 505 return -1; 506 507 508 /* Length of u8 type[8] */ 509 result += 8; 510 511 /* Length of u8 cid[32] */ 512 result += 32; 513 514 /* Length of u8 sid[32] */ 515 result += 32; 516 517 /* Length of u8 cid_ed[32] */ 518 result += 32; 519 520 /* Length of u8 sid_ed[32] */ 521 result += 32; 522 523 /* Length of u8 slog[32] */ 524 result += 32; 525 526 /* Length of u8 clog[32] */ 527 result += 32; 528 529 /* Length of u8 scert[32] */ 530 result += 32; 531 532 /* Length of u8 tlssecrets[32] */ 533 result += 32; 534 535 /* Length of u8 rand[24] */ 536 result += 24; 537 538 /* Length of u8 sig[] */ 539 result += TRUNNEL_DYNARRAY_LEN(&obj->sig); 540 return result; 541 } 542 int 543 auth1_clear_errors(auth1_t *obj) 544 { 545 int r = obj->trunnel_error_code_; 546 obj->trunnel_error_code_ = 0; 547 return r; 548 } 549 ssize_t 550 auth1_encode(uint8_t *output, const size_t avail, const auth1_t *obj) 551 { 552 ssize_t result = 0; 553 size_t written = 0; 554 uint8_t *ptr = output; 555 const char *msg; 556 #ifdef TRUNNEL_CHECK_ENCODED_LEN 557 const ssize_t encoded_len = auth1_encoded_len(obj); 558 #endif 559 560 if (NULL != (msg = auth1_check(obj))) 561 goto check_failed; 562 563 #ifdef TRUNNEL_CHECK_ENCODED_LEN 564 trunnel_assert(encoded_len >= 0); 565 #endif 566 567 /* Encode u8 type[8] */ 568 trunnel_assert(written <= avail); 569 if (avail - written < 8) 570 goto truncated; 571 memcpy(ptr, obj->type, 8); 572 written += 8; ptr += 8; 573 574 /* Encode u8 cid[32] */ 575 trunnel_assert(written <= avail); 576 if (avail - written < 32) 577 goto truncated; 578 memcpy(ptr, obj->cid, 32); 579 written += 32; ptr += 32; 580 581 /* Encode u8 sid[32] */ 582 trunnel_assert(written <= avail); 583 if (avail - written < 32) 584 goto truncated; 585 memcpy(ptr, obj->sid, 32); 586 written += 32; ptr += 32; 587 588 /* Encode u8 cid_ed[32] */ 589 trunnel_assert(written <= avail); 590 if (avail - written < 32) 591 goto truncated; 592 memcpy(ptr, obj->cid_ed, 32); 593 written += 32; ptr += 32; 594 595 /* Encode u8 sid_ed[32] */ 596 trunnel_assert(written <= avail); 597 if (avail - written < 32) 598 goto truncated; 599 memcpy(ptr, obj->sid_ed, 32); 600 written += 32; ptr += 32; 601 602 /* Encode u8 slog[32] */ 603 trunnel_assert(written <= avail); 604 if (avail - written < 32) 605 goto truncated; 606 memcpy(ptr, obj->slog, 32); 607 written += 32; ptr += 32; 608 609 /* Encode u8 clog[32] */ 610 trunnel_assert(written <= avail); 611 if (avail - written < 32) 612 goto truncated; 613 memcpy(ptr, obj->clog, 32); 614 written += 32; ptr += 32; 615 616 /* Encode u8 scert[32] */ 617 trunnel_assert(written <= avail); 618 if (avail - written < 32) 619 goto truncated; 620 memcpy(ptr, obj->scert, 32); 621 written += 32; ptr += 32; 622 623 /* Encode u8 tlssecrets[32] */ 624 trunnel_assert(written <= avail); 625 if (avail - written < 32) 626 goto truncated; 627 memcpy(ptr, obj->tlssecrets, 32); 628 written += 32; ptr += 32; 629 630 /* Encode u8 rand[24] */ 631 trunnel_assert(written <= avail); 632 if (avail - written < 24) 633 goto truncated; 634 memcpy(ptr, obj->rand, 24); 635 written += 24; ptr += 24; 636 637 /* Encode u8 sig[] */ 638 { 639 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig); 640 trunnel_assert(written <= avail); 641 if (avail - written < elt_len) 642 goto truncated; 643 if (elt_len) 644 memcpy(ptr, obj->sig.elts_, elt_len); 645 written += elt_len; ptr += elt_len; 646 } 647 648 649 trunnel_assert(ptr == output + written); 650 #ifdef TRUNNEL_CHECK_ENCODED_LEN 651 { 652 trunnel_assert(encoded_len >= 0); 653 trunnel_assert((size_t)encoded_len == written); 654 } 655 656 #endif 657 658 return written; 659 660 truncated: 661 result = -2; 662 goto fail; 663 check_failed: 664 (void)msg; 665 result = -1; 666 goto fail; 667 fail: 668 trunnel_assert(result < 0); 669 return result; 670 } 671 672 /** As auth1_parse(), but do not allocate the output object. 673 */ 674 static ssize_t 675 auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in) 676 { 677 const uint8_t *ptr = input; 678 size_t remaining = len_in; 679 ssize_t result = 0; 680 (void)result; 681 682 /* Parse u8 type[8] */ 683 CHECK_REMAINING(8, truncated); 684 memcpy(obj->type, ptr, 8); 685 remaining -= 8; ptr += 8; 686 687 /* Parse u8 cid[32] */ 688 CHECK_REMAINING(32, truncated); 689 memcpy(obj->cid, ptr, 32); 690 remaining -= 32; ptr += 32; 691 692 /* Parse u8 sid[32] */ 693 CHECK_REMAINING(32, truncated); 694 memcpy(obj->sid, ptr, 32); 695 remaining -= 32; ptr += 32; 696 697 /* Parse u8 cid_ed[32] */ 698 CHECK_REMAINING(32, truncated); 699 memcpy(obj->cid_ed, ptr, 32); 700 remaining -= 32; ptr += 32; 701 702 /* Parse u8 sid_ed[32] */ 703 CHECK_REMAINING(32, truncated); 704 memcpy(obj->sid_ed, ptr, 32); 705 remaining -= 32; ptr += 32; 706 707 /* Parse u8 slog[32] */ 708 CHECK_REMAINING(32, truncated); 709 memcpy(obj->slog, ptr, 32); 710 remaining -= 32; ptr += 32; 711 712 /* Parse u8 clog[32] */ 713 CHECK_REMAINING(32, truncated); 714 memcpy(obj->clog, ptr, 32); 715 remaining -= 32; ptr += 32; 716 717 /* Parse u8 scert[32] */ 718 CHECK_REMAINING(32, truncated); 719 memcpy(obj->scert, ptr, 32); 720 remaining -= 32; ptr += 32; 721 722 /* Parse u8 tlssecrets[32] */ 723 CHECK_REMAINING(32, truncated); 724 memcpy(obj->tlssecrets, ptr, 32); 725 remaining -= 32; ptr += 32; 726 obj->end_of_fixed_part = ptr; 727 728 /* Parse u8 rand[24] */ 729 CHECK_REMAINING(24, truncated); 730 memcpy(obj->rand, ptr, 24); 731 remaining -= 24; ptr += 24; 732 obj->end_of_signed = ptr; 733 734 /* Parse u8 sig[] */ 735 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, remaining, {}); 736 obj->sig.n_ = remaining; 737 if (remaining) 738 memcpy(obj->sig.elts_, ptr, remaining); 739 ptr += remaining; remaining -= remaining; 740 trunnel_assert(ptr + remaining == input + len_in); 741 return len_in - remaining; 742 743 truncated: 744 return -2; 745 trunnel_alloc_failed: 746 return -1; 747 } 748 749 ssize_t 750 auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in) 751 { 752 ssize_t result; 753 *output = auth1_new(); 754 if (NULL == *output) 755 return -1; 756 result = auth1_parse_into(*output, input, len_in); 757 if (result < 0) { 758 auth1_free(*output); 759 *output = NULL; 760 } 761 return result; 762 } 763 auth_challenge_cell_t * 764 auth_challenge_cell_new(void) 765 { 766 auth_challenge_cell_t *val = trunnel_calloc(1, sizeof(auth_challenge_cell_t)); 767 if (NULL == val) 768 return NULL; 769 return val; 770 } 771 772 /** Release all storage held inside 'obj', but do not free 'obj'. 773 */ 774 static void 775 auth_challenge_cell_clear(auth_challenge_cell_t *obj) 776 { 777 (void) obj; 778 TRUNNEL_DYNARRAY_WIPE(&obj->methods); 779 TRUNNEL_DYNARRAY_CLEAR(&obj->methods); 780 } 781 782 void 783 auth_challenge_cell_free(auth_challenge_cell_t *obj) 784 { 785 if (obj == NULL) 786 return; 787 auth_challenge_cell_clear(obj); 788 trunnel_memwipe(obj, sizeof(auth_challenge_cell_t)); 789 trunnel_free_(obj); 790 } 791 792 size_t 793 auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp) 794 { 795 (void)inp; return 32; 796 } 797 798 uint8_t 799 auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx) 800 { 801 trunnel_assert(idx < 32); 802 return inp->challenge[idx]; 803 } 804 805 uint8_t 806 auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx) 807 { 808 return auth_challenge_cell_get_challenge((auth_challenge_cell_t*)inp, idx); 809 } 810 int 811 auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt) 812 { 813 trunnel_assert(idx < 32); 814 inp->challenge[idx] = elt; 815 return 0; 816 } 817 818 uint8_t * 819 auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp) 820 { 821 return inp->challenge; 822 } 823 const uint8_t * 824 auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp) 825 { 826 return (const uint8_t *)auth_challenge_cell_getarray_challenge((auth_challenge_cell_t*)inp); 827 } 828 uint16_t 829 auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp) 830 { 831 return inp->n_methods; 832 } 833 int 834 auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val) 835 { 836 inp->n_methods = val; 837 return 0; 838 } 839 size_t 840 auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp) 841 { 842 return TRUNNEL_DYNARRAY_LEN(&inp->methods); 843 } 844 845 uint16_t 846 auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx) 847 { 848 return TRUNNEL_DYNARRAY_GET(&inp->methods, idx); 849 } 850 851 uint16_t 852 auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx) 853 { 854 return auth_challenge_cell_get_methods((auth_challenge_cell_t*)inp, idx); 855 } 856 int 857 auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt) 858 { 859 TRUNNEL_DYNARRAY_SET(&inp->methods, idx, elt); 860 return 0; 861 } 862 int 863 auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt) 864 { 865 #if SIZE_MAX >= UINT16_MAX 866 if (inp->methods.n_ == UINT16_MAX) 867 goto trunnel_alloc_failed; 868 #endif 869 TRUNNEL_DYNARRAY_ADD(uint16_t, &inp->methods, elt, {}); 870 return 0; 871 trunnel_alloc_failed: 872 TRUNNEL_SET_ERROR_CODE(inp); 873 return -1; 874 } 875 876 uint16_t * 877 auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp) 878 { 879 return inp->methods.elts_; 880 } 881 const uint16_t * 882 auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp) 883 { 884 return (const uint16_t *)auth_challenge_cell_getarray_methods((auth_challenge_cell_t*)inp); 885 } 886 int 887 auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen) 888 { 889 uint16_t *newptr; 890 #if UINT16_MAX < SIZE_MAX 891 if (newlen > UINT16_MAX) 892 goto trunnel_alloc_failed; 893 #endif 894 newptr = trunnel_dynarray_setlen(&inp->methods.allocated_, 895 &inp->methods.n_, inp->methods.elts_, newlen, 896 sizeof(inp->methods.elts_[0]), (trunnel_free_fn_t) NULL, 897 &inp->trunnel_error_code_); 898 if (newlen != 0 && newptr == NULL) 899 goto trunnel_alloc_failed; 900 inp->methods.elts_ = newptr; 901 return 0; 902 trunnel_alloc_failed: 903 TRUNNEL_SET_ERROR_CODE(inp); 904 return -1; 905 } 906 const char * 907 auth_challenge_cell_check(const auth_challenge_cell_t *obj) 908 { 909 if (obj == NULL) 910 return "Object was NULL"; 911 if (obj->trunnel_error_code_) 912 return "A set function failed on this object"; 913 if (TRUNNEL_DYNARRAY_LEN(&obj->methods) != obj->n_methods) 914 return "Length mismatch for methods"; 915 return NULL; 916 } 917 918 ssize_t 919 auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj) 920 { 921 ssize_t result = 0; 922 923 if (NULL != auth_challenge_cell_check(obj)) 924 return -1; 925 926 927 /* Length of u8 challenge[32] */ 928 result += 32; 929 930 /* Length of u16 n_methods */ 931 result += 2; 932 933 /* Length of u16 methods[n_methods] */ 934 result += 2 * TRUNNEL_DYNARRAY_LEN(&obj->methods); 935 return result; 936 } 937 int 938 auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj) 939 { 940 int r = obj->trunnel_error_code_; 941 obj->trunnel_error_code_ = 0; 942 return r; 943 } 944 ssize_t 945 auth_challenge_cell_encode(uint8_t *output, const size_t avail, const auth_challenge_cell_t *obj) 946 { 947 ssize_t result = 0; 948 size_t written = 0; 949 uint8_t *ptr = output; 950 const char *msg; 951 #ifdef TRUNNEL_CHECK_ENCODED_LEN 952 const ssize_t encoded_len = auth_challenge_cell_encoded_len(obj); 953 #endif 954 955 if (NULL != (msg = auth_challenge_cell_check(obj))) 956 goto check_failed; 957 958 #ifdef TRUNNEL_CHECK_ENCODED_LEN 959 trunnel_assert(encoded_len >= 0); 960 #endif 961 962 /* Encode u8 challenge[32] */ 963 trunnel_assert(written <= avail); 964 if (avail - written < 32) 965 goto truncated; 966 memcpy(ptr, obj->challenge, 32); 967 written += 32; ptr += 32; 968 969 /* Encode u16 n_methods */ 970 trunnel_assert(written <= avail); 971 if (avail - written < 2) 972 goto truncated; 973 trunnel_set_uint16(ptr, trunnel_htons(obj->n_methods)); 974 written += 2; ptr += 2; 975 976 /* Encode u16 methods[n_methods] */ 977 { 978 979 unsigned idx; 980 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->methods); ++idx) { 981 trunnel_assert(written <= avail); 982 if (avail - written < 2) 983 goto truncated; 984 trunnel_set_uint16(ptr, trunnel_htons(TRUNNEL_DYNARRAY_GET(&obj->methods, idx))); 985 written += 2; ptr += 2; 986 } 987 } 988 989 990 trunnel_assert(ptr == output + written); 991 #ifdef TRUNNEL_CHECK_ENCODED_LEN 992 { 993 trunnel_assert(encoded_len >= 0); 994 trunnel_assert((size_t)encoded_len == written); 995 } 996 997 #endif 998 999 return written; 1000 1001 truncated: 1002 result = -2; 1003 goto fail; 1004 check_failed: 1005 (void)msg; 1006 result = -1; 1007 goto fail; 1008 fail: 1009 trunnel_assert(result < 0); 1010 return result; 1011 } 1012 1013 /** As auth_challenge_cell_parse(), but do not allocate the output 1014 * object. 1015 */ 1016 static ssize_t 1017 auth_challenge_cell_parse_into(auth_challenge_cell_t *obj, const uint8_t *input, const size_t len_in) 1018 { 1019 const uint8_t *ptr = input; 1020 size_t remaining = len_in; 1021 ssize_t result = 0; 1022 (void)result; 1023 1024 /* Parse u8 challenge[32] */ 1025 CHECK_REMAINING(32, truncated); 1026 memcpy(obj->challenge, ptr, 32); 1027 remaining -= 32; ptr += 32; 1028 1029 /* Parse u16 n_methods */ 1030 CHECK_REMAINING(2, truncated); 1031 obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr)); 1032 remaining -= 2; ptr += 2; 1033 1034 /* Parse u16 methods[n_methods] */ 1035 TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {}); 1036 { 1037 uint16_t elt; 1038 unsigned idx; 1039 for (idx = 0; idx < obj->n_methods; ++idx) { 1040 CHECK_REMAINING(2, truncated); 1041 elt = trunnel_ntohs(trunnel_get_uint16(ptr)); 1042 remaining -= 2; ptr += 2; 1043 TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {}); 1044 } 1045 } 1046 trunnel_assert(ptr + remaining == input + len_in); 1047 return len_in - remaining; 1048 1049 truncated: 1050 return -2; 1051 trunnel_alloc_failed: 1052 return -1; 1053 } 1054 1055 ssize_t 1056 auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in) 1057 { 1058 ssize_t result; 1059 *output = auth_challenge_cell_new(); 1060 if (NULL == *output) 1061 return -1; 1062 result = auth_challenge_cell_parse_into(*output, input, len_in); 1063 if (result < 0) { 1064 auth_challenge_cell_free(*output); 1065 *output = NULL; 1066 } 1067 return result; 1068 } 1069 certs_cell_cert_t * 1070 certs_cell_cert_new(void) 1071 { 1072 certs_cell_cert_t *val = trunnel_calloc(1, sizeof(certs_cell_cert_t)); 1073 if (NULL == val) 1074 return NULL; 1075 return val; 1076 } 1077 1078 /** Release all storage held inside 'obj', but do not free 'obj'. 1079 */ 1080 static void 1081 certs_cell_cert_clear(certs_cell_cert_t *obj) 1082 { 1083 (void) obj; 1084 TRUNNEL_DYNARRAY_WIPE(&obj->body); 1085 TRUNNEL_DYNARRAY_CLEAR(&obj->body); 1086 } 1087 1088 void 1089 certs_cell_cert_free(certs_cell_cert_t *obj) 1090 { 1091 if (obj == NULL) 1092 return; 1093 certs_cell_cert_clear(obj); 1094 trunnel_memwipe(obj, sizeof(certs_cell_cert_t)); 1095 trunnel_free_(obj); 1096 } 1097 1098 uint8_t 1099 certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp) 1100 { 1101 return inp->cert_type; 1102 } 1103 int 1104 certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val) 1105 { 1106 inp->cert_type = val; 1107 return 0; 1108 } 1109 uint16_t 1110 certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp) 1111 { 1112 return inp->cert_len; 1113 } 1114 int 1115 certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val) 1116 { 1117 inp->cert_len = val; 1118 return 0; 1119 } 1120 size_t 1121 certs_cell_cert_getlen_body(const certs_cell_cert_t *inp) 1122 { 1123 return TRUNNEL_DYNARRAY_LEN(&inp->body); 1124 } 1125 1126 uint8_t 1127 certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx) 1128 { 1129 return TRUNNEL_DYNARRAY_GET(&inp->body, idx); 1130 } 1131 1132 uint8_t 1133 certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx) 1134 { 1135 return certs_cell_cert_get_body((certs_cell_cert_t*)inp, idx); 1136 } 1137 int 1138 certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt) 1139 { 1140 TRUNNEL_DYNARRAY_SET(&inp->body, idx, elt); 1141 return 0; 1142 } 1143 int 1144 certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt) 1145 { 1146 #if SIZE_MAX >= UINT16_MAX 1147 if (inp->body.n_ == UINT16_MAX) 1148 goto trunnel_alloc_failed; 1149 #endif 1150 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->body, elt, {}); 1151 return 0; 1152 trunnel_alloc_failed: 1153 TRUNNEL_SET_ERROR_CODE(inp); 1154 return -1; 1155 } 1156 1157 uint8_t * 1158 certs_cell_cert_getarray_body(certs_cell_cert_t *inp) 1159 { 1160 return inp->body.elts_; 1161 } 1162 const uint8_t * 1163 certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp) 1164 { 1165 return (const uint8_t *)certs_cell_cert_getarray_body((certs_cell_cert_t*)inp); 1166 } 1167 int 1168 certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen) 1169 { 1170 uint8_t *newptr; 1171 #if UINT16_MAX < SIZE_MAX 1172 if (newlen > UINT16_MAX) 1173 goto trunnel_alloc_failed; 1174 #endif 1175 newptr = trunnel_dynarray_setlen(&inp->body.allocated_, 1176 &inp->body.n_, inp->body.elts_, newlen, 1177 sizeof(inp->body.elts_[0]), (trunnel_free_fn_t) NULL, 1178 &inp->trunnel_error_code_); 1179 if (newlen != 0 && newptr == NULL) 1180 goto trunnel_alloc_failed; 1181 inp->body.elts_ = newptr; 1182 return 0; 1183 trunnel_alloc_failed: 1184 TRUNNEL_SET_ERROR_CODE(inp); 1185 return -1; 1186 } 1187 const char * 1188 certs_cell_cert_check(const certs_cell_cert_t *obj) 1189 { 1190 if (obj == NULL) 1191 return "Object was NULL"; 1192 if (obj->trunnel_error_code_) 1193 return "A set function failed on this object"; 1194 if (TRUNNEL_DYNARRAY_LEN(&obj->body) != obj->cert_len) 1195 return "Length mismatch for body"; 1196 return NULL; 1197 } 1198 1199 ssize_t 1200 certs_cell_cert_encoded_len(const certs_cell_cert_t *obj) 1201 { 1202 ssize_t result = 0; 1203 1204 if (NULL != certs_cell_cert_check(obj)) 1205 return -1; 1206 1207 1208 /* Length of u8 cert_type */ 1209 result += 1; 1210 1211 /* Length of u16 cert_len */ 1212 result += 2; 1213 1214 /* Length of u8 body[cert_len] */ 1215 result += TRUNNEL_DYNARRAY_LEN(&obj->body); 1216 return result; 1217 } 1218 int 1219 certs_cell_cert_clear_errors(certs_cell_cert_t *obj) 1220 { 1221 int r = obj->trunnel_error_code_; 1222 obj->trunnel_error_code_ = 0; 1223 return r; 1224 } 1225 ssize_t 1226 certs_cell_cert_encode(uint8_t *output, const size_t avail, const certs_cell_cert_t *obj) 1227 { 1228 ssize_t result = 0; 1229 size_t written = 0; 1230 uint8_t *ptr = output; 1231 const char *msg; 1232 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1233 const ssize_t encoded_len = certs_cell_cert_encoded_len(obj); 1234 #endif 1235 1236 if (NULL != (msg = certs_cell_cert_check(obj))) 1237 goto check_failed; 1238 1239 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1240 trunnel_assert(encoded_len >= 0); 1241 #endif 1242 1243 /* Encode u8 cert_type */ 1244 trunnel_assert(written <= avail); 1245 if (avail - written < 1) 1246 goto truncated; 1247 trunnel_set_uint8(ptr, (obj->cert_type)); 1248 written += 1; ptr += 1; 1249 1250 /* Encode u16 cert_len */ 1251 trunnel_assert(written <= avail); 1252 if (avail - written < 2) 1253 goto truncated; 1254 trunnel_set_uint16(ptr, trunnel_htons(obj->cert_len)); 1255 written += 2; ptr += 2; 1256 1257 /* Encode u8 body[cert_len] */ 1258 { 1259 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->body); 1260 trunnel_assert(obj->cert_len == elt_len); 1261 trunnel_assert(written <= avail); 1262 if (avail - written < elt_len) 1263 goto truncated; 1264 if (elt_len) 1265 memcpy(ptr, obj->body.elts_, elt_len); 1266 written += elt_len; ptr += elt_len; 1267 } 1268 1269 1270 trunnel_assert(ptr == output + written); 1271 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1272 { 1273 trunnel_assert(encoded_len >= 0); 1274 trunnel_assert((size_t)encoded_len == written); 1275 } 1276 1277 #endif 1278 1279 return written; 1280 1281 truncated: 1282 result = -2; 1283 goto fail; 1284 check_failed: 1285 (void)msg; 1286 result = -1; 1287 goto fail; 1288 fail: 1289 trunnel_assert(result < 0); 1290 return result; 1291 } 1292 1293 /** As certs_cell_cert_parse(), but do not allocate the output object. 1294 */ 1295 static ssize_t 1296 certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const size_t len_in) 1297 { 1298 const uint8_t *ptr = input; 1299 size_t remaining = len_in; 1300 ssize_t result = 0; 1301 (void)result; 1302 1303 /* Parse u8 cert_type */ 1304 CHECK_REMAINING(1, truncated); 1305 obj->cert_type = (trunnel_get_uint8(ptr)); 1306 remaining -= 1; ptr += 1; 1307 1308 /* Parse u16 cert_len */ 1309 CHECK_REMAINING(2, truncated); 1310 obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr)); 1311 remaining -= 2; ptr += 2; 1312 1313 /* Parse u8 body[cert_len] */ 1314 CHECK_REMAINING(obj->cert_len, truncated); 1315 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {}); 1316 obj->body.n_ = obj->cert_len; 1317 if (obj->cert_len) 1318 memcpy(obj->body.elts_, ptr, obj->cert_len); 1319 ptr += obj->cert_len; remaining -= obj->cert_len; 1320 trunnel_assert(ptr + remaining == input + len_in); 1321 return len_in - remaining; 1322 1323 truncated: 1324 return -2; 1325 trunnel_alloc_failed: 1326 return -1; 1327 } 1328 1329 ssize_t 1330 certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in) 1331 { 1332 ssize_t result; 1333 *output = certs_cell_cert_new(); 1334 if (NULL == *output) 1335 return -1; 1336 result = certs_cell_cert_parse_into(*output, input, len_in); 1337 if (result < 0) { 1338 certs_cell_cert_free(*output); 1339 *output = NULL; 1340 } 1341 return result; 1342 } 1343 rsa_ed_crosscert_t * 1344 rsa_ed_crosscert_new(void) 1345 { 1346 rsa_ed_crosscert_t *val = trunnel_calloc(1, sizeof(rsa_ed_crosscert_t)); 1347 if (NULL == val) 1348 return NULL; 1349 return val; 1350 } 1351 1352 /** Release all storage held inside 'obj', but do not free 'obj'. 1353 */ 1354 static void 1355 rsa_ed_crosscert_clear(rsa_ed_crosscert_t *obj) 1356 { 1357 (void) obj; 1358 TRUNNEL_DYNARRAY_WIPE(&obj->sig); 1359 TRUNNEL_DYNARRAY_CLEAR(&obj->sig); 1360 } 1361 1362 void 1363 rsa_ed_crosscert_free(rsa_ed_crosscert_t *obj) 1364 { 1365 if (obj == NULL) 1366 return; 1367 rsa_ed_crosscert_clear(obj); 1368 trunnel_memwipe(obj, sizeof(rsa_ed_crosscert_t)); 1369 trunnel_free_(obj); 1370 } 1371 1372 size_t 1373 rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp) 1374 { 1375 (void)inp; return 32; 1376 } 1377 1378 uint8_t 1379 rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx) 1380 { 1381 trunnel_assert(idx < 32); 1382 return inp->ed_key[idx]; 1383 } 1384 1385 uint8_t 1386 rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx) 1387 { 1388 return rsa_ed_crosscert_get_ed_key((rsa_ed_crosscert_t*)inp, idx); 1389 } 1390 int 1391 rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt) 1392 { 1393 trunnel_assert(idx < 32); 1394 inp->ed_key[idx] = elt; 1395 return 0; 1396 } 1397 1398 uint8_t * 1399 rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp) 1400 { 1401 return inp->ed_key; 1402 } 1403 const uint8_t * 1404 rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp) 1405 { 1406 return (const uint8_t *)rsa_ed_crosscert_getarray_ed_key((rsa_ed_crosscert_t*)inp); 1407 } 1408 uint32_t 1409 rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp) 1410 { 1411 return inp->expiration; 1412 } 1413 int 1414 rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val) 1415 { 1416 inp->expiration = val; 1417 return 0; 1418 } 1419 const uint8_t * 1420 rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp) 1421 { 1422 return inp->end_of_signed; 1423 } 1424 uint8_t 1425 rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp) 1426 { 1427 return inp->sig_len; 1428 } 1429 int 1430 rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val) 1431 { 1432 inp->sig_len = val; 1433 return 0; 1434 } 1435 size_t 1436 rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp) 1437 { 1438 return TRUNNEL_DYNARRAY_LEN(&inp->sig); 1439 } 1440 1441 uint8_t 1442 rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx) 1443 { 1444 return TRUNNEL_DYNARRAY_GET(&inp->sig, idx); 1445 } 1446 1447 uint8_t 1448 rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx) 1449 { 1450 return rsa_ed_crosscert_get_sig((rsa_ed_crosscert_t*)inp, idx); 1451 } 1452 int 1453 rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt) 1454 { 1455 TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt); 1456 return 0; 1457 } 1458 int 1459 rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt) 1460 { 1461 #if SIZE_MAX >= UINT8_MAX 1462 if (inp->sig.n_ == UINT8_MAX) 1463 goto trunnel_alloc_failed; 1464 #endif 1465 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {}); 1466 return 0; 1467 trunnel_alloc_failed: 1468 TRUNNEL_SET_ERROR_CODE(inp); 1469 return -1; 1470 } 1471 1472 uint8_t * 1473 rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp) 1474 { 1475 return inp->sig.elts_; 1476 } 1477 const uint8_t * 1478 rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp) 1479 { 1480 return (const uint8_t *)rsa_ed_crosscert_getarray_sig((rsa_ed_crosscert_t*)inp); 1481 } 1482 int 1483 rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen) 1484 { 1485 uint8_t *newptr; 1486 #if UINT8_MAX < SIZE_MAX 1487 if (newlen > UINT8_MAX) 1488 goto trunnel_alloc_failed; 1489 #endif 1490 newptr = trunnel_dynarray_setlen(&inp->sig.allocated_, 1491 &inp->sig.n_, inp->sig.elts_, newlen, 1492 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL, 1493 &inp->trunnel_error_code_); 1494 if (newlen != 0 && newptr == NULL) 1495 goto trunnel_alloc_failed; 1496 inp->sig.elts_ = newptr; 1497 return 0; 1498 trunnel_alloc_failed: 1499 TRUNNEL_SET_ERROR_CODE(inp); 1500 return -1; 1501 } 1502 const char * 1503 rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj) 1504 { 1505 if (obj == NULL) 1506 return "Object was NULL"; 1507 if (obj->trunnel_error_code_) 1508 return "A set function failed on this object"; 1509 if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len) 1510 return "Length mismatch for sig"; 1511 return NULL; 1512 } 1513 1514 ssize_t 1515 rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj) 1516 { 1517 ssize_t result = 0; 1518 1519 if (NULL != rsa_ed_crosscert_check(obj)) 1520 return -1; 1521 1522 1523 /* Length of u8 ed_key[32] */ 1524 result += 32; 1525 1526 /* Length of u32 expiration */ 1527 result += 4; 1528 1529 /* Length of u8 sig_len */ 1530 result += 1; 1531 1532 /* Length of u8 sig[sig_len] */ 1533 result += TRUNNEL_DYNARRAY_LEN(&obj->sig); 1534 return result; 1535 } 1536 int 1537 rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj) 1538 { 1539 int r = obj->trunnel_error_code_; 1540 obj->trunnel_error_code_ = 0; 1541 return r; 1542 } 1543 ssize_t 1544 rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crosscert_t *obj) 1545 { 1546 ssize_t result = 0; 1547 size_t written = 0; 1548 uint8_t *ptr = output; 1549 const char *msg; 1550 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1551 const ssize_t encoded_len = rsa_ed_crosscert_encoded_len(obj); 1552 #endif 1553 1554 if (NULL != (msg = rsa_ed_crosscert_check(obj))) 1555 goto check_failed; 1556 1557 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1558 trunnel_assert(encoded_len >= 0); 1559 #endif 1560 1561 /* Encode u8 ed_key[32] */ 1562 trunnel_assert(written <= avail); 1563 if (avail - written < 32) 1564 goto truncated; 1565 memcpy(ptr, obj->ed_key, 32); 1566 written += 32; ptr += 32; 1567 1568 /* Encode u32 expiration */ 1569 trunnel_assert(written <= avail); 1570 if (avail - written < 4) 1571 goto truncated; 1572 trunnel_set_uint32(ptr, trunnel_htonl(obj->expiration)); 1573 written += 4; ptr += 4; 1574 1575 /* Encode u8 sig_len */ 1576 trunnel_assert(written <= avail); 1577 if (avail - written < 1) 1578 goto truncated; 1579 trunnel_set_uint8(ptr, (obj->sig_len)); 1580 written += 1; ptr += 1; 1581 1582 /* Encode u8 sig[sig_len] */ 1583 { 1584 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig); 1585 trunnel_assert(obj->sig_len == elt_len); 1586 trunnel_assert(written <= avail); 1587 if (avail - written < elt_len) 1588 goto truncated; 1589 if (elt_len) 1590 memcpy(ptr, obj->sig.elts_, elt_len); 1591 written += elt_len; ptr += elt_len; 1592 } 1593 1594 1595 trunnel_assert(ptr == output + written); 1596 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1597 { 1598 trunnel_assert(encoded_len >= 0); 1599 trunnel_assert((size_t)encoded_len == written); 1600 } 1601 1602 #endif 1603 1604 return written; 1605 1606 truncated: 1607 result = -2; 1608 goto fail; 1609 check_failed: 1610 (void)msg; 1611 result = -1; 1612 goto fail; 1613 fail: 1614 trunnel_assert(result < 0); 1615 return result; 1616 } 1617 1618 /** As rsa_ed_crosscert_parse(), but do not allocate the output 1619 * object. 1620 */ 1621 static ssize_t 1622 rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const size_t len_in) 1623 { 1624 const uint8_t *ptr = input; 1625 size_t remaining = len_in; 1626 ssize_t result = 0; 1627 (void)result; 1628 1629 /* Parse u8 ed_key[32] */ 1630 CHECK_REMAINING(32, truncated); 1631 memcpy(obj->ed_key, ptr, 32); 1632 remaining -= 32; ptr += 32; 1633 1634 /* Parse u32 expiration */ 1635 CHECK_REMAINING(4, truncated); 1636 obj->expiration = trunnel_ntohl(trunnel_get_uint32(ptr)); 1637 remaining -= 4; ptr += 4; 1638 obj->end_of_signed = ptr; 1639 1640 /* Parse u8 sig_len */ 1641 CHECK_REMAINING(1, truncated); 1642 obj->sig_len = (trunnel_get_uint8(ptr)); 1643 remaining -= 1; ptr += 1; 1644 1645 /* Parse u8 sig[sig_len] */ 1646 CHECK_REMAINING(obj->sig_len, truncated); 1647 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {}); 1648 obj->sig.n_ = obj->sig_len; 1649 if (obj->sig_len) 1650 memcpy(obj->sig.elts_, ptr, obj->sig_len); 1651 ptr += obj->sig_len; remaining -= obj->sig_len; 1652 trunnel_assert(ptr + remaining == input + len_in); 1653 return len_in - remaining; 1654 1655 truncated: 1656 return -2; 1657 trunnel_alloc_failed: 1658 return -1; 1659 } 1660 1661 ssize_t 1662 rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in) 1663 { 1664 ssize_t result; 1665 *output = rsa_ed_crosscert_new(); 1666 if (NULL == *output) 1667 return -1; 1668 result = rsa_ed_crosscert_parse_into(*output, input, len_in); 1669 if (result < 0) { 1670 rsa_ed_crosscert_free(*output); 1671 *output = NULL; 1672 } 1673 return result; 1674 } 1675 certs_cell_t * 1676 certs_cell_new(void) 1677 { 1678 certs_cell_t *val = trunnel_calloc(1, sizeof(certs_cell_t)); 1679 if (NULL == val) 1680 return NULL; 1681 return val; 1682 } 1683 1684 /** Release all storage held inside 'obj', but do not free 'obj'. 1685 */ 1686 static void 1687 certs_cell_clear(certs_cell_t *obj) 1688 { 1689 (void) obj; 1690 { 1691 1692 unsigned idx; 1693 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) { 1694 certs_cell_cert_free(TRUNNEL_DYNARRAY_GET(&obj->certs, idx)); 1695 } 1696 } 1697 TRUNNEL_DYNARRAY_WIPE(&obj->certs); 1698 TRUNNEL_DYNARRAY_CLEAR(&obj->certs); 1699 } 1700 1701 void 1702 certs_cell_free(certs_cell_t *obj) 1703 { 1704 if (obj == NULL) 1705 return; 1706 certs_cell_clear(obj); 1707 trunnel_memwipe(obj, sizeof(certs_cell_t)); 1708 trunnel_free_(obj); 1709 } 1710 1711 uint8_t 1712 certs_cell_get_n_certs(const certs_cell_t *inp) 1713 { 1714 return inp->n_certs; 1715 } 1716 int 1717 certs_cell_set_n_certs(certs_cell_t *inp, uint8_t val) 1718 { 1719 inp->n_certs = val; 1720 return 0; 1721 } 1722 size_t 1723 certs_cell_getlen_certs(const certs_cell_t *inp) 1724 { 1725 return TRUNNEL_DYNARRAY_LEN(&inp->certs); 1726 } 1727 1728 struct certs_cell_cert_st * 1729 certs_cell_get_certs(certs_cell_t *inp, size_t idx) 1730 { 1731 return TRUNNEL_DYNARRAY_GET(&inp->certs, idx); 1732 } 1733 1734 const struct certs_cell_cert_st * 1735 certs_cell_getconst_certs(const certs_cell_t *inp, size_t idx) 1736 { 1737 return certs_cell_get_certs((certs_cell_t*)inp, idx); 1738 } 1739 int 1740 certs_cell_set_certs(certs_cell_t *inp, size_t idx, struct certs_cell_cert_st * elt) 1741 { 1742 certs_cell_cert_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->certs, idx); 1743 if (oldval && oldval != elt) 1744 certs_cell_cert_free(oldval); 1745 return certs_cell_set0_certs(inp, idx, elt); 1746 } 1747 int 1748 certs_cell_set0_certs(certs_cell_t *inp, size_t idx, struct certs_cell_cert_st * elt) 1749 { 1750 TRUNNEL_DYNARRAY_SET(&inp->certs, idx, elt); 1751 return 0; 1752 } 1753 int 1754 certs_cell_add_certs(certs_cell_t *inp, struct certs_cell_cert_st * elt) 1755 { 1756 #if SIZE_MAX >= UINT8_MAX 1757 if (inp->certs.n_ == UINT8_MAX) 1758 goto trunnel_alloc_failed; 1759 #endif 1760 TRUNNEL_DYNARRAY_ADD(struct certs_cell_cert_st *, &inp->certs, elt, {}); 1761 return 0; 1762 trunnel_alloc_failed: 1763 TRUNNEL_SET_ERROR_CODE(inp); 1764 return -1; 1765 } 1766 1767 struct certs_cell_cert_st * * 1768 certs_cell_getarray_certs(certs_cell_t *inp) 1769 { 1770 return inp->certs.elts_; 1771 } 1772 const struct certs_cell_cert_st * const * 1773 certs_cell_getconstarray_certs(const certs_cell_t *inp) 1774 { 1775 return (const struct certs_cell_cert_st * const *)certs_cell_getarray_certs((certs_cell_t*)inp); 1776 } 1777 int 1778 certs_cell_setlen_certs(certs_cell_t *inp, size_t newlen) 1779 { 1780 struct certs_cell_cert_st * *newptr; 1781 #if UINT8_MAX < SIZE_MAX 1782 if (newlen > UINT8_MAX) 1783 goto trunnel_alloc_failed; 1784 #endif 1785 newptr = trunnel_dynarray_setlen(&inp->certs.allocated_, 1786 &inp->certs.n_, inp->certs.elts_, newlen, 1787 sizeof(inp->certs.elts_[0]), (trunnel_free_fn_t) certs_cell_cert_free, 1788 &inp->trunnel_error_code_); 1789 if (newlen != 0 && newptr == NULL) 1790 goto trunnel_alloc_failed; 1791 inp->certs.elts_ = newptr; 1792 return 0; 1793 trunnel_alloc_failed: 1794 TRUNNEL_SET_ERROR_CODE(inp); 1795 return -1; 1796 } 1797 const char * 1798 certs_cell_check(const certs_cell_t *obj) 1799 { 1800 if (obj == NULL) 1801 return "Object was NULL"; 1802 if (obj->trunnel_error_code_) 1803 return "A set function failed on this object"; 1804 { 1805 const char *msg; 1806 1807 unsigned idx; 1808 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) { 1809 if (NULL != (msg = certs_cell_cert_check(TRUNNEL_DYNARRAY_GET(&obj->certs, idx)))) 1810 return msg; 1811 } 1812 } 1813 if (TRUNNEL_DYNARRAY_LEN(&obj->certs) != obj->n_certs) 1814 return "Length mismatch for certs"; 1815 return NULL; 1816 } 1817 1818 ssize_t 1819 certs_cell_encoded_len(const certs_cell_t *obj) 1820 { 1821 ssize_t result = 0; 1822 1823 if (NULL != certs_cell_check(obj)) 1824 return -1; 1825 1826 1827 /* Length of u8 n_certs */ 1828 result += 1; 1829 1830 /* Length of struct certs_cell_cert certs[n_certs] */ 1831 { 1832 1833 unsigned idx; 1834 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) { 1835 result += certs_cell_cert_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->certs, idx)); 1836 } 1837 } 1838 return result; 1839 } 1840 int 1841 certs_cell_clear_errors(certs_cell_t *obj) 1842 { 1843 int r = obj->trunnel_error_code_; 1844 obj->trunnel_error_code_ = 0; 1845 return r; 1846 } 1847 ssize_t 1848 certs_cell_encode(uint8_t *output, const size_t avail, const certs_cell_t *obj) 1849 { 1850 ssize_t result = 0; 1851 size_t written = 0; 1852 uint8_t *ptr = output; 1853 const char *msg; 1854 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1855 const ssize_t encoded_len = certs_cell_encoded_len(obj); 1856 #endif 1857 1858 if (NULL != (msg = certs_cell_check(obj))) 1859 goto check_failed; 1860 1861 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1862 trunnel_assert(encoded_len >= 0); 1863 #endif 1864 1865 /* Encode u8 n_certs */ 1866 trunnel_assert(written <= avail); 1867 if (avail - written < 1) 1868 goto truncated; 1869 trunnel_set_uint8(ptr, (obj->n_certs)); 1870 written += 1; ptr += 1; 1871 1872 /* Encode struct certs_cell_cert certs[n_certs] */ 1873 { 1874 1875 unsigned idx; 1876 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) { 1877 trunnel_assert(written <= avail); 1878 result = certs_cell_cert_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->certs, idx)); 1879 if (result < 0) 1880 goto fail; /* XXXXXXX !*/ 1881 written += result; ptr += result; 1882 } 1883 } 1884 1885 1886 trunnel_assert(ptr == output + written); 1887 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1888 { 1889 trunnel_assert(encoded_len >= 0); 1890 trunnel_assert((size_t)encoded_len == written); 1891 } 1892 1893 #endif 1894 1895 return written; 1896 1897 truncated: 1898 result = -2; 1899 goto fail; 1900 check_failed: 1901 (void)msg; 1902 result = -1; 1903 goto fail; 1904 fail: 1905 trunnel_assert(result < 0); 1906 return result; 1907 } 1908 1909 /** As certs_cell_parse(), but do not allocate the output object. 1910 */ 1911 static ssize_t 1912 certs_cell_parse_into(certs_cell_t *obj, const uint8_t *input, const size_t len_in) 1913 { 1914 const uint8_t *ptr = input; 1915 size_t remaining = len_in; 1916 ssize_t result = 0; 1917 (void)result; 1918 1919 /* Parse u8 n_certs */ 1920 CHECK_REMAINING(1, truncated); 1921 obj->n_certs = (trunnel_get_uint8(ptr)); 1922 remaining -= 1; ptr += 1; 1923 1924 /* Parse struct certs_cell_cert certs[n_certs] */ 1925 TRUNNEL_DYNARRAY_EXPAND(certs_cell_cert_t *, &obj->certs, obj->n_certs, {}); 1926 { 1927 certs_cell_cert_t * elt; 1928 unsigned idx; 1929 for (idx = 0; idx < obj->n_certs; ++idx) { 1930 result = certs_cell_cert_parse(&elt, ptr, remaining); 1931 if (result < 0) 1932 goto relay_fail; 1933 trunnel_assert((size_t)result <= remaining); 1934 remaining -= result; ptr += result; 1935 TRUNNEL_DYNARRAY_ADD(certs_cell_cert_t *, &obj->certs, elt, {certs_cell_cert_free(elt);}); 1936 } 1937 } 1938 trunnel_assert(ptr + remaining == input + len_in); 1939 return len_in - remaining; 1940 1941 truncated: 1942 return -2; 1943 relay_fail: 1944 trunnel_assert(result < 0); 1945 return result; 1946 trunnel_alloc_failed: 1947 return -1; 1948 } 1949 1950 ssize_t 1951 certs_cell_parse(certs_cell_t **output, const uint8_t *input, const size_t len_in) 1952 { 1953 ssize_t result; 1954 *output = certs_cell_new(); 1955 if (NULL == *output) 1956 return -1; 1957 result = certs_cell_parse_into(*output, input, len_in); 1958 if (result < 0) { 1959 certs_cell_free(*output); 1960 *output = NULL; 1961 } 1962 return result; 1963 }