cell_establish_intro.c (32697B)
1 /* cell_establish_intro.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 "cell_establish_intro.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 cellestablishintro_deadcode_dummy__ = 0; 19 #define OR_DEADCODE_DUMMY || cellestablishintro_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 typedef struct trn_extension_st trn_extension_t; 32 trn_extension_t *trn_extension_new(void); 33 void trn_extension_free(trn_extension_t *victim); 34 ssize_t trn_extension_parse(trn_extension_t **output, const uint8_t *input, const size_t len_in); 35 ssize_t trn_extension_encoded_len(const trn_extension_t *obj); 36 ssize_t trn_extension_encode(uint8_t *output, size_t avail, const trn_extension_t *input); 37 const char *trn_extension_check(const trn_extension_t *obj); 38 int trn_extension_clear_errors(trn_extension_t *obj); 39 trn_cell_extension_dos_param_t * 40 trn_cell_extension_dos_param_new(void) 41 { 42 trn_cell_extension_dos_param_t *val = trunnel_calloc(1, sizeof(trn_cell_extension_dos_param_t)); 43 if (NULL == val) 44 return NULL; 45 return val; 46 } 47 48 /** Release all storage held inside 'obj', but do not free 'obj'. 49 */ 50 static void 51 trn_cell_extension_dos_param_clear(trn_cell_extension_dos_param_t *obj) 52 { 53 (void) obj; 54 } 55 56 void 57 trn_cell_extension_dos_param_free(trn_cell_extension_dos_param_t *obj) 58 { 59 if (obj == NULL) 60 return; 61 trn_cell_extension_dos_param_clear(obj); 62 trunnel_memwipe(obj, sizeof(trn_cell_extension_dos_param_t)); 63 trunnel_free_(obj); 64 } 65 66 uint8_t 67 trn_cell_extension_dos_param_get_type(const trn_cell_extension_dos_param_t *inp) 68 { 69 return inp->type; 70 } 71 int 72 trn_cell_extension_dos_param_set_type(trn_cell_extension_dos_param_t *inp, uint8_t val) 73 { 74 inp->type = val; 75 return 0; 76 } 77 uint64_t 78 trn_cell_extension_dos_param_get_value(const trn_cell_extension_dos_param_t *inp) 79 { 80 return inp->value; 81 } 82 int 83 trn_cell_extension_dos_param_set_value(trn_cell_extension_dos_param_t *inp, uint64_t val) 84 { 85 inp->value = val; 86 return 0; 87 } 88 const char * 89 trn_cell_extension_dos_param_check(const trn_cell_extension_dos_param_t *obj) 90 { 91 if (obj == NULL) 92 return "Object was NULL"; 93 if (obj->trunnel_error_code_) 94 return "A set function failed on this object"; 95 return NULL; 96 } 97 98 ssize_t 99 trn_cell_extension_dos_param_encoded_len(const trn_cell_extension_dos_param_t *obj) 100 { 101 ssize_t result = 0; 102 103 if (NULL != trn_cell_extension_dos_param_check(obj)) 104 return -1; 105 106 107 /* Length of u8 type */ 108 result += 1; 109 110 /* Length of u64 value */ 111 result += 8; 112 return result; 113 } 114 int 115 trn_cell_extension_dos_param_clear_errors(trn_cell_extension_dos_param_t *obj) 116 { 117 int r = obj->trunnel_error_code_; 118 obj->trunnel_error_code_ = 0; 119 return r; 120 } 121 ssize_t 122 trn_cell_extension_dos_param_encode(uint8_t *output, const size_t avail, const trn_cell_extension_dos_param_t *obj) 123 { 124 ssize_t result = 0; 125 size_t written = 0; 126 uint8_t *ptr = output; 127 const char *msg; 128 #ifdef TRUNNEL_CHECK_ENCODED_LEN 129 const ssize_t encoded_len = trn_cell_extension_dos_param_encoded_len(obj); 130 #endif 131 132 if (NULL != (msg = trn_cell_extension_dos_param_check(obj))) 133 goto check_failed; 134 135 #ifdef TRUNNEL_CHECK_ENCODED_LEN 136 trunnel_assert(encoded_len >= 0); 137 #endif 138 139 /* Encode u8 type */ 140 trunnel_assert(written <= avail); 141 if (avail - written < 1) 142 goto truncated; 143 trunnel_set_uint8(ptr, (obj->type)); 144 written += 1; ptr += 1; 145 146 /* Encode u64 value */ 147 trunnel_assert(written <= avail); 148 if (avail - written < 8) 149 goto truncated; 150 trunnel_set_uint64(ptr, trunnel_htonll(obj->value)); 151 written += 8; ptr += 8; 152 153 154 trunnel_assert(ptr == output + written); 155 #ifdef TRUNNEL_CHECK_ENCODED_LEN 156 { 157 trunnel_assert(encoded_len >= 0); 158 trunnel_assert((size_t)encoded_len == written); 159 } 160 161 #endif 162 163 return written; 164 165 truncated: 166 result = -2; 167 goto fail; 168 check_failed: 169 (void)msg; 170 result = -1; 171 goto fail; 172 fail: 173 trunnel_assert(result < 0); 174 return result; 175 } 176 177 /** As trn_cell_extension_dos_param_parse(), but do not allocate the 178 * output object. 179 */ 180 static ssize_t 181 trn_cell_extension_dos_param_parse_into(trn_cell_extension_dos_param_t *obj, const uint8_t *input, const size_t len_in) 182 { 183 const uint8_t *ptr = input; 184 size_t remaining = len_in; 185 ssize_t result = 0; 186 (void)result; 187 188 /* Parse u8 type */ 189 CHECK_REMAINING(1, truncated); 190 obj->type = (trunnel_get_uint8(ptr)); 191 remaining -= 1; ptr += 1; 192 193 /* Parse u64 value */ 194 CHECK_REMAINING(8, truncated); 195 obj->value = trunnel_ntohll(trunnel_get_uint64(ptr)); 196 remaining -= 8; ptr += 8; 197 trunnel_assert(ptr + remaining == input + len_in); 198 return len_in - remaining; 199 200 truncated: 201 return -2; 202 } 203 204 ssize_t 205 trn_cell_extension_dos_param_parse(trn_cell_extension_dos_param_t **output, const uint8_t *input, const size_t len_in) 206 { 207 ssize_t result; 208 *output = trn_cell_extension_dos_param_new(); 209 if (NULL == *output) 210 return -1; 211 result = trn_cell_extension_dos_param_parse_into(*output, input, len_in); 212 if (result < 0) { 213 trn_cell_extension_dos_param_free(*output); 214 *output = NULL; 215 } 216 return result; 217 } 218 trn_cell_establish_intro_t * 219 trn_cell_establish_intro_new(void) 220 { 221 trn_cell_establish_intro_t *val = trunnel_calloc(1, sizeof(trn_cell_establish_intro_t)); 222 if (NULL == val) 223 return NULL; 224 return val; 225 } 226 227 /** Release all storage held inside 'obj', but do not free 'obj'. 228 */ 229 static void 230 trn_cell_establish_intro_clear(trn_cell_establish_intro_t *obj) 231 { 232 (void) obj; 233 TRUNNEL_DYNARRAY_WIPE(&obj->auth_key); 234 TRUNNEL_DYNARRAY_CLEAR(&obj->auth_key); 235 trn_extension_free(obj->extensions); 236 obj->extensions = NULL; 237 TRUNNEL_DYNARRAY_WIPE(&obj->sig); 238 TRUNNEL_DYNARRAY_CLEAR(&obj->sig); 239 } 240 241 void 242 trn_cell_establish_intro_free(trn_cell_establish_intro_t *obj) 243 { 244 if (obj == NULL) 245 return; 246 trn_cell_establish_intro_clear(obj); 247 trunnel_memwipe(obj, sizeof(trn_cell_establish_intro_t)); 248 trunnel_free_(obj); 249 } 250 251 const uint8_t * 252 trn_cell_establish_intro_get_start_cell(const trn_cell_establish_intro_t *inp) 253 { 254 return inp->start_cell; 255 } 256 uint8_t 257 trn_cell_establish_intro_get_auth_key_type(const trn_cell_establish_intro_t *inp) 258 { 259 return inp->auth_key_type; 260 } 261 int 262 trn_cell_establish_intro_set_auth_key_type(trn_cell_establish_intro_t *inp, uint8_t val) 263 { 264 if (! ((val == 0 || val == 1 || val == 2))) { 265 TRUNNEL_SET_ERROR_CODE(inp); 266 return -1; 267 } 268 inp->auth_key_type = val; 269 return 0; 270 } 271 uint16_t 272 trn_cell_establish_intro_get_auth_key_len(const trn_cell_establish_intro_t *inp) 273 { 274 return inp->auth_key_len; 275 } 276 int 277 trn_cell_establish_intro_set_auth_key_len(trn_cell_establish_intro_t *inp, uint16_t val) 278 { 279 inp->auth_key_len = val; 280 return 0; 281 } 282 size_t 283 trn_cell_establish_intro_getlen_auth_key(const trn_cell_establish_intro_t *inp) 284 { 285 return TRUNNEL_DYNARRAY_LEN(&inp->auth_key); 286 } 287 288 uint8_t 289 trn_cell_establish_intro_get_auth_key(trn_cell_establish_intro_t *inp, size_t idx) 290 { 291 return TRUNNEL_DYNARRAY_GET(&inp->auth_key, idx); 292 } 293 294 uint8_t 295 trn_cell_establish_intro_getconst_auth_key(const trn_cell_establish_intro_t *inp, size_t idx) 296 { 297 return trn_cell_establish_intro_get_auth_key((trn_cell_establish_intro_t*)inp, idx); 298 } 299 int 300 trn_cell_establish_intro_set_auth_key(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt) 301 { 302 TRUNNEL_DYNARRAY_SET(&inp->auth_key, idx, elt); 303 return 0; 304 } 305 int 306 trn_cell_establish_intro_add_auth_key(trn_cell_establish_intro_t *inp, uint8_t elt) 307 { 308 #if SIZE_MAX >= UINT16_MAX 309 if (inp->auth_key.n_ == UINT16_MAX) 310 goto trunnel_alloc_failed; 311 #endif 312 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->auth_key, elt, {}); 313 return 0; 314 trunnel_alloc_failed: 315 TRUNNEL_SET_ERROR_CODE(inp); 316 return -1; 317 } 318 319 uint8_t * 320 trn_cell_establish_intro_getarray_auth_key(trn_cell_establish_intro_t *inp) 321 { 322 return inp->auth_key.elts_; 323 } 324 const uint8_t * 325 trn_cell_establish_intro_getconstarray_auth_key(const trn_cell_establish_intro_t *inp) 326 { 327 return (const uint8_t *)trn_cell_establish_intro_getarray_auth_key((trn_cell_establish_intro_t*)inp); 328 } 329 int 330 trn_cell_establish_intro_setlen_auth_key(trn_cell_establish_intro_t *inp, size_t newlen) 331 { 332 uint8_t *newptr; 333 #if UINT16_MAX < SIZE_MAX 334 if (newlen > UINT16_MAX) 335 goto trunnel_alloc_failed; 336 #endif 337 newptr = trunnel_dynarray_setlen(&inp->auth_key.allocated_, 338 &inp->auth_key.n_, inp->auth_key.elts_, newlen, 339 sizeof(inp->auth_key.elts_[0]), (trunnel_free_fn_t) NULL, 340 &inp->trunnel_error_code_); 341 if (newlen != 0 && newptr == NULL) 342 goto trunnel_alloc_failed; 343 inp->auth_key.elts_ = newptr; 344 return 0; 345 trunnel_alloc_failed: 346 TRUNNEL_SET_ERROR_CODE(inp); 347 return -1; 348 } 349 struct trn_extension_st * 350 trn_cell_establish_intro_get_extensions(trn_cell_establish_intro_t *inp) 351 { 352 return inp->extensions; 353 } 354 const struct trn_extension_st * 355 trn_cell_establish_intro_getconst_extensions(const trn_cell_establish_intro_t *inp) 356 { 357 return trn_cell_establish_intro_get_extensions((trn_cell_establish_intro_t*) inp); 358 } 359 int 360 trn_cell_establish_intro_set_extensions(trn_cell_establish_intro_t *inp, struct trn_extension_st *val) 361 { 362 if (inp->extensions && inp->extensions != val) 363 trn_extension_free(inp->extensions); 364 return trn_cell_establish_intro_set0_extensions(inp, val); 365 } 366 int 367 trn_cell_establish_intro_set0_extensions(trn_cell_establish_intro_t *inp, struct trn_extension_st *val) 368 { 369 inp->extensions = val; 370 return 0; 371 } 372 const uint8_t * 373 trn_cell_establish_intro_get_end_mac_fields(const trn_cell_establish_intro_t *inp) 374 { 375 return inp->end_mac_fields; 376 } 377 size_t 378 trn_cell_establish_intro_getlen_handshake_mac(const trn_cell_establish_intro_t *inp) 379 { 380 (void)inp; return TRUNNEL_SHA3_256_LEN; 381 } 382 383 uint8_t 384 trn_cell_establish_intro_get_handshake_mac(trn_cell_establish_intro_t *inp, size_t idx) 385 { 386 trunnel_assert(idx < TRUNNEL_SHA3_256_LEN); 387 return inp->handshake_mac[idx]; 388 } 389 390 uint8_t 391 trn_cell_establish_intro_getconst_handshake_mac(const trn_cell_establish_intro_t *inp, size_t idx) 392 { 393 return trn_cell_establish_intro_get_handshake_mac((trn_cell_establish_intro_t*)inp, idx); 394 } 395 int 396 trn_cell_establish_intro_set_handshake_mac(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt) 397 { 398 trunnel_assert(idx < TRUNNEL_SHA3_256_LEN); 399 inp->handshake_mac[idx] = elt; 400 return 0; 401 } 402 403 uint8_t * 404 trn_cell_establish_intro_getarray_handshake_mac(trn_cell_establish_intro_t *inp) 405 { 406 return inp->handshake_mac; 407 } 408 const uint8_t * 409 trn_cell_establish_intro_getconstarray_handshake_mac(const trn_cell_establish_intro_t *inp) 410 { 411 return (const uint8_t *)trn_cell_establish_intro_getarray_handshake_mac((trn_cell_establish_intro_t*)inp); 412 } 413 const uint8_t * 414 trn_cell_establish_intro_get_end_sig_fields(const trn_cell_establish_intro_t *inp) 415 { 416 return inp->end_sig_fields; 417 } 418 uint16_t 419 trn_cell_establish_intro_get_sig_len(const trn_cell_establish_intro_t *inp) 420 { 421 return inp->sig_len; 422 } 423 int 424 trn_cell_establish_intro_set_sig_len(trn_cell_establish_intro_t *inp, uint16_t val) 425 { 426 inp->sig_len = val; 427 return 0; 428 } 429 size_t 430 trn_cell_establish_intro_getlen_sig(const trn_cell_establish_intro_t *inp) 431 { 432 return TRUNNEL_DYNARRAY_LEN(&inp->sig); 433 } 434 435 uint8_t 436 trn_cell_establish_intro_get_sig(trn_cell_establish_intro_t *inp, size_t idx) 437 { 438 return TRUNNEL_DYNARRAY_GET(&inp->sig, idx); 439 } 440 441 uint8_t 442 trn_cell_establish_intro_getconst_sig(const trn_cell_establish_intro_t *inp, size_t idx) 443 { 444 return trn_cell_establish_intro_get_sig((trn_cell_establish_intro_t*)inp, idx); 445 } 446 int 447 trn_cell_establish_intro_set_sig(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt) 448 { 449 TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt); 450 return 0; 451 } 452 int 453 trn_cell_establish_intro_add_sig(trn_cell_establish_intro_t *inp, uint8_t elt) 454 { 455 #if SIZE_MAX >= UINT16_MAX 456 if (inp->sig.n_ == UINT16_MAX) 457 goto trunnel_alloc_failed; 458 #endif 459 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {}); 460 return 0; 461 trunnel_alloc_failed: 462 TRUNNEL_SET_ERROR_CODE(inp); 463 return -1; 464 } 465 466 uint8_t * 467 trn_cell_establish_intro_getarray_sig(trn_cell_establish_intro_t *inp) 468 { 469 return inp->sig.elts_; 470 } 471 const uint8_t * 472 trn_cell_establish_intro_getconstarray_sig(const trn_cell_establish_intro_t *inp) 473 { 474 return (const uint8_t *)trn_cell_establish_intro_getarray_sig((trn_cell_establish_intro_t*)inp); 475 } 476 int 477 trn_cell_establish_intro_setlen_sig(trn_cell_establish_intro_t *inp, size_t newlen) 478 { 479 uint8_t *newptr; 480 #if UINT16_MAX < SIZE_MAX 481 if (newlen > UINT16_MAX) 482 goto trunnel_alloc_failed; 483 #endif 484 newptr = trunnel_dynarray_setlen(&inp->sig.allocated_, 485 &inp->sig.n_, inp->sig.elts_, newlen, 486 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL, 487 &inp->trunnel_error_code_); 488 if (newlen != 0 && newptr == NULL) 489 goto trunnel_alloc_failed; 490 inp->sig.elts_ = newptr; 491 return 0; 492 trunnel_alloc_failed: 493 TRUNNEL_SET_ERROR_CODE(inp); 494 return -1; 495 } 496 const char * 497 trn_cell_establish_intro_check(const trn_cell_establish_intro_t *obj) 498 { 499 if (obj == NULL) 500 return "Object was NULL"; 501 if (obj->trunnel_error_code_) 502 return "A set function failed on this object"; 503 if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2)) 504 return "Integer out of bounds"; 505 if (TRUNNEL_DYNARRAY_LEN(&obj->auth_key) != obj->auth_key_len) 506 return "Length mismatch for auth_key"; 507 { 508 const char *msg; 509 if (NULL != (msg = trn_extension_check(obj->extensions))) 510 return msg; 511 } 512 if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len) 513 return "Length mismatch for sig"; 514 return NULL; 515 } 516 517 ssize_t 518 trn_cell_establish_intro_encoded_len(const trn_cell_establish_intro_t *obj) 519 { 520 ssize_t result = 0; 521 522 if (NULL != trn_cell_establish_intro_check(obj)) 523 return -1; 524 525 526 /* Length of u8 auth_key_type IN [0, 1, 2] */ 527 result += 1; 528 529 /* Length of u16 auth_key_len */ 530 result += 2; 531 532 /* Length of u8 auth_key[auth_key_len] */ 533 result += TRUNNEL_DYNARRAY_LEN(&obj->auth_key); 534 535 /* Length of struct trn_extension extensions */ 536 result += trn_extension_encoded_len(obj->extensions); 537 538 /* Length of u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */ 539 result += TRUNNEL_SHA3_256_LEN; 540 541 /* Length of u16 sig_len */ 542 result += 2; 543 544 /* Length of u8 sig[sig_len] */ 545 result += TRUNNEL_DYNARRAY_LEN(&obj->sig); 546 return result; 547 } 548 int 549 trn_cell_establish_intro_clear_errors(trn_cell_establish_intro_t *obj) 550 { 551 int r = obj->trunnel_error_code_; 552 obj->trunnel_error_code_ = 0; 553 return r; 554 } 555 ssize_t 556 trn_cell_establish_intro_encode(uint8_t *output, const size_t avail, const trn_cell_establish_intro_t *obj) 557 { 558 ssize_t result = 0; 559 size_t written = 0; 560 uint8_t *ptr = output; 561 const char *msg; 562 #ifdef TRUNNEL_CHECK_ENCODED_LEN 563 const ssize_t encoded_len = trn_cell_establish_intro_encoded_len(obj); 564 #endif 565 566 if (NULL != (msg = trn_cell_establish_intro_check(obj))) 567 goto check_failed; 568 569 #ifdef TRUNNEL_CHECK_ENCODED_LEN 570 trunnel_assert(encoded_len >= 0); 571 #endif 572 573 /* Encode u8 auth_key_type IN [0, 1, 2] */ 574 trunnel_assert(written <= avail); 575 if (avail - written < 1) 576 goto truncated; 577 trunnel_set_uint8(ptr, (obj->auth_key_type)); 578 written += 1; ptr += 1; 579 580 /* Encode u16 auth_key_len */ 581 trunnel_assert(written <= avail); 582 if (avail - written < 2) 583 goto truncated; 584 trunnel_set_uint16(ptr, trunnel_htons(obj->auth_key_len)); 585 written += 2; ptr += 2; 586 587 /* Encode u8 auth_key[auth_key_len] */ 588 { 589 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->auth_key); 590 trunnel_assert(obj->auth_key_len == elt_len); 591 trunnel_assert(written <= avail); 592 if (avail - written < elt_len) 593 goto truncated; 594 if (elt_len) 595 memcpy(ptr, obj->auth_key.elts_, elt_len); 596 written += elt_len; ptr += elt_len; 597 } 598 599 /* Encode struct trn_extension extensions */ 600 trunnel_assert(written <= avail); 601 result = trn_extension_encode(ptr, avail - written, obj->extensions); 602 if (result < 0) 603 goto fail; /* XXXXXXX !*/ 604 written += result; ptr += result; 605 606 /* Encode u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */ 607 trunnel_assert(written <= avail); 608 if (avail - written < TRUNNEL_SHA3_256_LEN) 609 goto truncated; 610 memcpy(ptr, obj->handshake_mac, TRUNNEL_SHA3_256_LEN); 611 written += TRUNNEL_SHA3_256_LEN; ptr += TRUNNEL_SHA3_256_LEN; 612 613 /* Encode u16 sig_len */ 614 trunnel_assert(written <= avail); 615 if (avail - written < 2) 616 goto truncated; 617 trunnel_set_uint16(ptr, trunnel_htons(obj->sig_len)); 618 written += 2; ptr += 2; 619 620 /* Encode u8 sig[sig_len] */ 621 { 622 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig); 623 trunnel_assert(obj->sig_len == elt_len); 624 trunnel_assert(written <= avail); 625 if (avail - written < elt_len) 626 goto truncated; 627 if (elt_len) 628 memcpy(ptr, obj->sig.elts_, elt_len); 629 written += elt_len; ptr += elt_len; 630 } 631 632 633 trunnel_assert(ptr == output + written); 634 #ifdef TRUNNEL_CHECK_ENCODED_LEN 635 { 636 trunnel_assert(encoded_len >= 0); 637 trunnel_assert((size_t)encoded_len == written); 638 } 639 640 #endif 641 642 return written; 643 644 truncated: 645 result = -2; 646 goto fail; 647 check_failed: 648 (void)msg; 649 result = -1; 650 goto fail; 651 fail: 652 trunnel_assert(result < 0); 653 return result; 654 } 655 656 /** As trn_cell_establish_intro_parse(), but do not allocate the 657 * output object. 658 */ 659 static ssize_t 660 trn_cell_establish_intro_parse_into(trn_cell_establish_intro_t *obj, const uint8_t *input, const size_t len_in) 661 { 662 const uint8_t *ptr = input; 663 size_t remaining = len_in; 664 ssize_t result = 0; 665 (void)result; 666 obj->start_cell = ptr; 667 668 /* Parse u8 auth_key_type IN [0, 1, 2] */ 669 CHECK_REMAINING(1, truncated); 670 obj->auth_key_type = (trunnel_get_uint8(ptr)); 671 remaining -= 1; ptr += 1; 672 if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2)) 673 goto fail; 674 675 /* Parse u16 auth_key_len */ 676 CHECK_REMAINING(2, truncated); 677 obj->auth_key_len = trunnel_ntohs(trunnel_get_uint16(ptr)); 678 remaining -= 2; ptr += 2; 679 680 /* Parse u8 auth_key[auth_key_len] */ 681 CHECK_REMAINING(obj->auth_key_len, truncated); 682 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->auth_key, obj->auth_key_len, {}); 683 obj->auth_key.n_ = obj->auth_key_len; 684 if (obj->auth_key_len) 685 memcpy(obj->auth_key.elts_, ptr, obj->auth_key_len); 686 ptr += obj->auth_key_len; remaining -= obj->auth_key_len; 687 688 /* Parse struct trn_extension extensions */ 689 result = trn_extension_parse(&obj->extensions, ptr, remaining); 690 if (result < 0) 691 goto relay_fail; 692 trunnel_assert((size_t)result <= remaining); 693 remaining -= result; ptr += result; 694 obj->end_mac_fields = ptr; 695 696 /* Parse u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */ 697 CHECK_REMAINING(TRUNNEL_SHA3_256_LEN, truncated); 698 memcpy(obj->handshake_mac, ptr, TRUNNEL_SHA3_256_LEN); 699 remaining -= TRUNNEL_SHA3_256_LEN; ptr += TRUNNEL_SHA3_256_LEN; 700 obj->end_sig_fields = ptr; 701 702 /* Parse u16 sig_len */ 703 CHECK_REMAINING(2, truncated); 704 obj->sig_len = trunnel_ntohs(trunnel_get_uint16(ptr)); 705 remaining -= 2; ptr += 2; 706 707 /* Parse u8 sig[sig_len] */ 708 CHECK_REMAINING(obj->sig_len, truncated); 709 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {}); 710 obj->sig.n_ = obj->sig_len; 711 if (obj->sig_len) 712 memcpy(obj->sig.elts_, ptr, obj->sig_len); 713 ptr += obj->sig_len; remaining -= obj->sig_len; 714 trunnel_assert(ptr + remaining == input + len_in); 715 return len_in - remaining; 716 717 truncated: 718 return -2; 719 relay_fail: 720 trunnel_assert(result < 0); 721 return result; 722 trunnel_alloc_failed: 723 return -1; 724 fail: 725 result = -1; 726 return result; 727 } 728 729 ssize_t 730 trn_cell_establish_intro_parse(trn_cell_establish_intro_t **output, const uint8_t *input, const size_t len_in) 731 { 732 ssize_t result; 733 *output = trn_cell_establish_intro_new(); 734 if (NULL == *output) 735 return -1; 736 result = trn_cell_establish_intro_parse_into(*output, input, len_in); 737 if (result < 0) { 738 trn_cell_establish_intro_free(*output); 739 *output = NULL; 740 } 741 return result; 742 } 743 trn_cell_extension_dos_t * 744 trn_cell_extension_dos_new(void) 745 { 746 trn_cell_extension_dos_t *val = trunnel_calloc(1, sizeof(trn_cell_extension_dos_t)); 747 if (NULL == val) 748 return NULL; 749 return val; 750 } 751 752 /** Release all storage held inside 'obj', but do not free 'obj'. 753 */ 754 static void 755 trn_cell_extension_dos_clear(trn_cell_extension_dos_t *obj) 756 { 757 (void) obj; 758 { 759 760 unsigned idx; 761 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) { 762 trn_cell_extension_dos_param_free(TRUNNEL_DYNARRAY_GET(&obj->params, idx)); 763 } 764 } 765 TRUNNEL_DYNARRAY_WIPE(&obj->params); 766 TRUNNEL_DYNARRAY_CLEAR(&obj->params); 767 } 768 769 void 770 trn_cell_extension_dos_free(trn_cell_extension_dos_t *obj) 771 { 772 if (obj == NULL) 773 return; 774 trn_cell_extension_dos_clear(obj); 775 trunnel_memwipe(obj, sizeof(trn_cell_extension_dos_t)); 776 trunnel_free_(obj); 777 } 778 779 uint8_t 780 trn_cell_extension_dos_get_n_params(const trn_cell_extension_dos_t *inp) 781 { 782 return inp->n_params; 783 } 784 int 785 trn_cell_extension_dos_set_n_params(trn_cell_extension_dos_t *inp, uint8_t val) 786 { 787 inp->n_params = val; 788 return 0; 789 } 790 size_t 791 trn_cell_extension_dos_getlen_params(const trn_cell_extension_dos_t *inp) 792 { 793 return TRUNNEL_DYNARRAY_LEN(&inp->params); 794 } 795 796 struct trn_cell_extension_dos_param_st * 797 trn_cell_extension_dos_get_params(trn_cell_extension_dos_t *inp, size_t idx) 798 { 799 return TRUNNEL_DYNARRAY_GET(&inp->params, idx); 800 } 801 802 const struct trn_cell_extension_dos_param_st * 803 trn_cell_extension_dos_getconst_params(const trn_cell_extension_dos_t *inp, size_t idx) 804 { 805 return trn_cell_extension_dos_get_params((trn_cell_extension_dos_t*)inp, idx); 806 } 807 int 808 trn_cell_extension_dos_set_params(trn_cell_extension_dos_t *inp, size_t idx, struct trn_cell_extension_dos_param_st * elt) 809 { 810 trn_cell_extension_dos_param_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->params, idx); 811 if (oldval && oldval != elt) 812 trn_cell_extension_dos_param_free(oldval); 813 return trn_cell_extension_dos_set0_params(inp, idx, elt); 814 } 815 int 816 trn_cell_extension_dos_set0_params(trn_cell_extension_dos_t *inp, size_t idx, struct trn_cell_extension_dos_param_st * elt) 817 { 818 TRUNNEL_DYNARRAY_SET(&inp->params, idx, elt); 819 return 0; 820 } 821 int 822 trn_cell_extension_dos_add_params(trn_cell_extension_dos_t *inp, struct trn_cell_extension_dos_param_st * elt) 823 { 824 #if SIZE_MAX >= UINT8_MAX 825 if (inp->params.n_ == UINT8_MAX) 826 goto trunnel_alloc_failed; 827 #endif 828 TRUNNEL_DYNARRAY_ADD(struct trn_cell_extension_dos_param_st *, &inp->params, elt, {}); 829 return 0; 830 trunnel_alloc_failed: 831 TRUNNEL_SET_ERROR_CODE(inp); 832 return -1; 833 } 834 835 struct trn_cell_extension_dos_param_st * * 836 trn_cell_extension_dos_getarray_params(trn_cell_extension_dos_t *inp) 837 { 838 return inp->params.elts_; 839 } 840 const struct trn_cell_extension_dos_param_st * const * 841 trn_cell_extension_dos_getconstarray_params(const trn_cell_extension_dos_t *inp) 842 { 843 return (const struct trn_cell_extension_dos_param_st * const *)trn_cell_extension_dos_getarray_params((trn_cell_extension_dos_t*)inp); 844 } 845 int 846 trn_cell_extension_dos_setlen_params(trn_cell_extension_dos_t *inp, size_t newlen) 847 { 848 struct trn_cell_extension_dos_param_st * *newptr; 849 #if UINT8_MAX < SIZE_MAX 850 if (newlen > UINT8_MAX) 851 goto trunnel_alloc_failed; 852 #endif 853 newptr = trunnel_dynarray_setlen(&inp->params.allocated_, 854 &inp->params.n_, inp->params.elts_, newlen, 855 sizeof(inp->params.elts_[0]), (trunnel_free_fn_t) trn_cell_extension_dos_param_free, 856 &inp->trunnel_error_code_); 857 if (newlen != 0 && newptr == NULL) 858 goto trunnel_alloc_failed; 859 inp->params.elts_ = newptr; 860 return 0; 861 trunnel_alloc_failed: 862 TRUNNEL_SET_ERROR_CODE(inp); 863 return -1; 864 } 865 const char * 866 trn_cell_extension_dos_check(const trn_cell_extension_dos_t *obj) 867 { 868 if (obj == NULL) 869 return "Object was NULL"; 870 if (obj->trunnel_error_code_) 871 return "A set function failed on this object"; 872 { 873 const char *msg; 874 875 unsigned idx; 876 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) { 877 if (NULL != (msg = trn_cell_extension_dos_param_check(TRUNNEL_DYNARRAY_GET(&obj->params, idx)))) 878 return msg; 879 } 880 } 881 if (TRUNNEL_DYNARRAY_LEN(&obj->params) != obj->n_params) 882 return "Length mismatch for params"; 883 return NULL; 884 } 885 886 ssize_t 887 trn_cell_extension_dos_encoded_len(const trn_cell_extension_dos_t *obj) 888 { 889 ssize_t result = 0; 890 891 if (NULL != trn_cell_extension_dos_check(obj)) 892 return -1; 893 894 895 /* Length of u8 n_params */ 896 result += 1; 897 898 /* Length of struct trn_cell_extension_dos_param params[n_params] */ 899 { 900 901 unsigned idx; 902 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) { 903 result += trn_cell_extension_dos_param_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->params, idx)); 904 } 905 } 906 return result; 907 } 908 int 909 trn_cell_extension_dos_clear_errors(trn_cell_extension_dos_t *obj) 910 { 911 int r = obj->trunnel_error_code_; 912 obj->trunnel_error_code_ = 0; 913 return r; 914 } 915 ssize_t 916 trn_cell_extension_dos_encode(uint8_t *output, const size_t avail, const trn_cell_extension_dos_t *obj) 917 { 918 ssize_t result = 0; 919 size_t written = 0; 920 uint8_t *ptr = output; 921 const char *msg; 922 #ifdef TRUNNEL_CHECK_ENCODED_LEN 923 const ssize_t encoded_len = trn_cell_extension_dos_encoded_len(obj); 924 #endif 925 926 if (NULL != (msg = trn_cell_extension_dos_check(obj))) 927 goto check_failed; 928 929 #ifdef TRUNNEL_CHECK_ENCODED_LEN 930 trunnel_assert(encoded_len >= 0); 931 #endif 932 933 /* Encode u8 n_params */ 934 trunnel_assert(written <= avail); 935 if (avail - written < 1) 936 goto truncated; 937 trunnel_set_uint8(ptr, (obj->n_params)); 938 written += 1; ptr += 1; 939 940 /* Encode struct trn_cell_extension_dos_param params[n_params] */ 941 { 942 943 unsigned idx; 944 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) { 945 trunnel_assert(written <= avail); 946 result = trn_cell_extension_dos_param_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->params, idx)); 947 if (result < 0) 948 goto fail; /* XXXXXXX !*/ 949 written += result; ptr += result; 950 } 951 } 952 953 954 trunnel_assert(ptr == output + written); 955 #ifdef TRUNNEL_CHECK_ENCODED_LEN 956 { 957 trunnel_assert(encoded_len >= 0); 958 trunnel_assert((size_t)encoded_len == written); 959 } 960 961 #endif 962 963 return written; 964 965 truncated: 966 result = -2; 967 goto fail; 968 check_failed: 969 (void)msg; 970 result = -1; 971 goto fail; 972 fail: 973 trunnel_assert(result < 0); 974 return result; 975 } 976 977 /** As trn_cell_extension_dos_parse(), but do not allocate the output 978 * object. 979 */ 980 static ssize_t 981 trn_cell_extension_dos_parse_into(trn_cell_extension_dos_t *obj, const uint8_t *input, const size_t len_in) 982 { 983 const uint8_t *ptr = input; 984 size_t remaining = len_in; 985 ssize_t result = 0; 986 (void)result; 987 988 /* Parse u8 n_params */ 989 CHECK_REMAINING(1, truncated); 990 obj->n_params = (trunnel_get_uint8(ptr)); 991 remaining -= 1; ptr += 1; 992 993 /* Parse struct trn_cell_extension_dos_param params[n_params] */ 994 TRUNNEL_DYNARRAY_EXPAND(trn_cell_extension_dos_param_t *, &obj->params, obj->n_params, {}); 995 { 996 trn_cell_extension_dos_param_t * elt; 997 unsigned idx; 998 for (idx = 0; idx < obj->n_params; ++idx) { 999 result = trn_cell_extension_dos_param_parse(&elt, ptr, remaining); 1000 if (result < 0) 1001 goto relay_fail; 1002 trunnel_assert((size_t)result <= remaining); 1003 remaining -= result; ptr += result; 1004 TRUNNEL_DYNARRAY_ADD(trn_cell_extension_dos_param_t *, &obj->params, elt, {trn_cell_extension_dos_param_free(elt);}); 1005 } 1006 } 1007 trunnel_assert(ptr + remaining == input + len_in); 1008 return len_in - remaining; 1009 1010 truncated: 1011 return -2; 1012 relay_fail: 1013 trunnel_assert(result < 0); 1014 return result; 1015 trunnel_alloc_failed: 1016 return -1; 1017 } 1018 1019 ssize_t 1020 trn_cell_extension_dos_parse(trn_cell_extension_dos_t **output, const uint8_t *input, const size_t len_in) 1021 { 1022 ssize_t result; 1023 *output = trn_cell_extension_dos_new(); 1024 if (NULL == *output) 1025 return -1; 1026 result = trn_cell_extension_dos_parse_into(*output, input, len_in); 1027 if (result < 0) { 1028 trn_cell_extension_dos_free(*output); 1029 *output = NULL; 1030 } 1031 return result; 1032 } 1033 trn_cell_intro_established_t * 1034 trn_cell_intro_established_new(void) 1035 { 1036 trn_cell_intro_established_t *val = trunnel_calloc(1, sizeof(trn_cell_intro_established_t)); 1037 if (NULL == val) 1038 return NULL; 1039 return val; 1040 } 1041 1042 /** Release all storage held inside 'obj', but do not free 'obj'. 1043 */ 1044 static void 1045 trn_cell_intro_established_clear(trn_cell_intro_established_t *obj) 1046 { 1047 (void) obj; 1048 trn_extension_free(obj->extensions); 1049 obj->extensions = NULL; 1050 } 1051 1052 void 1053 trn_cell_intro_established_free(trn_cell_intro_established_t *obj) 1054 { 1055 if (obj == NULL) 1056 return; 1057 trn_cell_intro_established_clear(obj); 1058 trunnel_memwipe(obj, sizeof(trn_cell_intro_established_t)); 1059 trunnel_free_(obj); 1060 } 1061 1062 struct trn_extension_st * 1063 trn_cell_intro_established_get_extensions(trn_cell_intro_established_t *inp) 1064 { 1065 return inp->extensions; 1066 } 1067 const struct trn_extension_st * 1068 trn_cell_intro_established_getconst_extensions(const trn_cell_intro_established_t *inp) 1069 { 1070 return trn_cell_intro_established_get_extensions((trn_cell_intro_established_t*) inp); 1071 } 1072 int 1073 trn_cell_intro_established_set_extensions(trn_cell_intro_established_t *inp, struct trn_extension_st *val) 1074 { 1075 if (inp->extensions && inp->extensions != val) 1076 trn_extension_free(inp->extensions); 1077 return trn_cell_intro_established_set0_extensions(inp, val); 1078 } 1079 int 1080 trn_cell_intro_established_set0_extensions(trn_cell_intro_established_t *inp, struct trn_extension_st *val) 1081 { 1082 inp->extensions = val; 1083 return 0; 1084 } 1085 const char * 1086 trn_cell_intro_established_check(const trn_cell_intro_established_t *obj) 1087 { 1088 if (obj == NULL) 1089 return "Object was NULL"; 1090 if (obj->trunnel_error_code_) 1091 return "A set function failed on this object"; 1092 { 1093 const char *msg; 1094 if (NULL != (msg = trn_extension_check(obj->extensions))) 1095 return msg; 1096 } 1097 return NULL; 1098 } 1099 1100 ssize_t 1101 trn_cell_intro_established_encoded_len(const trn_cell_intro_established_t *obj) 1102 { 1103 ssize_t result = 0; 1104 1105 if (NULL != trn_cell_intro_established_check(obj)) 1106 return -1; 1107 1108 1109 /* Length of struct trn_extension extensions */ 1110 result += trn_extension_encoded_len(obj->extensions); 1111 return result; 1112 } 1113 int 1114 trn_cell_intro_established_clear_errors(trn_cell_intro_established_t *obj) 1115 { 1116 int r = obj->trunnel_error_code_; 1117 obj->trunnel_error_code_ = 0; 1118 return r; 1119 } 1120 ssize_t 1121 trn_cell_intro_established_encode(uint8_t *output, const size_t avail, const trn_cell_intro_established_t *obj) 1122 { 1123 ssize_t result = 0; 1124 size_t written = 0; 1125 uint8_t *ptr = output; 1126 const char *msg; 1127 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1128 const ssize_t encoded_len = trn_cell_intro_established_encoded_len(obj); 1129 #endif 1130 1131 if (NULL != (msg = trn_cell_intro_established_check(obj))) 1132 goto check_failed; 1133 1134 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1135 trunnel_assert(encoded_len >= 0); 1136 #endif 1137 1138 /* Encode struct trn_extension extensions */ 1139 trunnel_assert(written <= avail); 1140 result = trn_extension_encode(ptr, avail - written, obj->extensions); 1141 if (result < 0) 1142 goto fail; /* XXXXXXX !*/ 1143 written += result; ptr += result; 1144 1145 1146 trunnel_assert(ptr == output + written); 1147 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1148 { 1149 trunnel_assert(encoded_len >= 0); 1150 trunnel_assert((size_t)encoded_len == written); 1151 } 1152 1153 #endif 1154 1155 return written; 1156 1157 check_failed: 1158 (void)msg; 1159 result = -1; 1160 goto fail; 1161 fail: 1162 trunnel_assert(result < 0); 1163 return result; 1164 } 1165 1166 /** As trn_cell_intro_established_parse(), but do not allocate the 1167 * output object. 1168 */ 1169 static ssize_t 1170 trn_cell_intro_established_parse_into(trn_cell_intro_established_t *obj, const uint8_t *input, const size_t len_in) 1171 { 1172 const uint8_t *ptr = input; 1173 size_t remaining = len_in; 1174 ssize_t result = 0; 1175 (void)result; 1176 1177 /* Parse struct trn_extension extensions */ 1178 result = trn_extension_parse(&obj->extensions, ptr, remaining); 1179 if (result < 0) 1180 goto relay_fail; 1181 trunnel_assert((size_t)result <= remaining); 1182 remaining -= result; ptr += result; 1183 trunnel_assert(ptr + remaining == input + len_in); 1184 return len_in - remaining; 1185 1186 relay_fail: 1187 trunnel_assert(result < 0); 1188 return result; 1189 } 1190 1191 ssize_t 1192 trn_cell_intro_established_parse(trn_cell_intro_established_t **output, const uint8_t *input, const size_t len_in) 1193 { 1194 ssize_t result; 1195 *output = trn_cell_intro_established_new(); 1196 if (NULL == *output) 1197 return -1; 1198 result = trn_cell_intro_established_parse_into(*output, input, len_in); 1199 if (result < 0) { 1200 trn_cell_intro_established_free(*output); 1201 *output = NULL; 1202 } 1203 return result; 1204 }