cell_introduce1.c (48181B)
1 /* cell_introduce1.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_introduce1.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 cellintroduce_deadcode_dummy__ = 0; 19 #define OR_DEADCODE_DUMMY || cellintroduce_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 typedef struct link_specifier_st link_specifier_t; 40 link_specifier_t *link_specifier_new(void); 41 void link_specifier_free(link_specifier_t *victim); 42 ssize_t link_specifier_parse(link_specifier_t **output, const uint8_t *input, const size_t len_in); 43 ssize_t link_specifier_encoded_len(const link_specifier_t *obj); 44 ssize_t link_specifier_encode(uint8_t *output, size_t avail, const link_specifier_t *input); 45 const char *link_specifier_check(const link_specifier_t *obj); 46 int link_specifier_clear_errors(link_specifier_t *obj); 47 trn_cell_extension_pow_t * 48 trn_cell_extension_pow_new(void) 49 { 50 trn_cell_extension_pow_t *val = trunnel_calloc(1, sizeof(trn_cell_extension_pow_t)); 51 if (NULL == val) 52 return NULL; 53 val->pow_version = 1; 54 return val; 55 } 56 57 /** Release all storage held inside 'obj', but do not free 'obj'. 58 */ 59 static void 60 trn_cell_extension_pow_clear(trn_cell_extension_pow_t *obj) 61 { 62 (void) obj; 63 } 64 65 void 66 trn_cell_extension_pow_free(trn_cell_extension_pow_t *obj) 67 { 68 if (obj == NULL) 69 return; 70 trn_cell_extension_pow_clear(obj); 71 trunnel_memwipe(obj, sizeof(trn_cell_extension_pow_t)); 72 trunnel_free_(obj); 73 } 74 75 uint8_t 76 trn_cell_extension_pow_get_pow_version(const trn_cell_extension_pow_t *inp) 77 { 78 return inp->pow_version; 79 } 80 int 81 trn_cell_extension_pow_set_pow_version(trn_cell_extension_pow_t *inp, uint8_t val) 82 { 83 if (! ((val == 1))) { 84 TRUNNEL_SET_ERROR_CODE(inp); 85 return -1; 86 } 87 inp->pow_version = val; 88 return 0; 89 } 90 size_t 91 trn_cell_extension_pow_getlen_pow_nonce(const trn_cell_extension_pow_t *inp) 92 { 93 (void)inp; return TRUNNEL_POW_NONCE_LEN; 94 } 95 96 uint8_t 97 trn_cell_extension_pow_get_pow_nonce(trn_cell_extension_pow_t *inp, size_t idx) 98 { 99 trunnel_assert(idx < TRUNNEL_POW_NONCE_LEN); 100 return inp->pow_nonce[idx]; 101 } 102 103 uint8_t 104 trn_cell_extension_pow_getconst_pow_nonce(const trn_cell_extension_pow_t *inp, size_t idx) 105 { 106 return trn_cell_extension_pow_get_pow_nonce((trn_cell_extension_pow_t*)inp, idx); 107 } 108 int 109 trn_cell_extension_pow_set_pow_nonce(trn_cell_extension_pow_t *inp, size_t idx, uint8_t elt) 110 { 111 trunnel_assert(idx < TRUNNEL_POW_NONCE_LEN); 112 inp->pow_nonce[idx] = elt; 113 return 0; 114 } 115 116 uint8_t * 117 trn_cell_extension_pow_getarray_pow_nonce(trn_cell_extension_pow_t *inp) 118 { 119 return inp->pow_nonce; 120 } 121 const uint8_t * 122 trn_cell_extension_pow_getconstarray_pow_nonce(const trn_cell_extension_pow_t *inp) 123 { 124 return (const uint8_t *)trn_cell_extension_pow_getarray_pow_nonce((trn_cell_extension_pow_t*)inp); 125 } 126 uint32_t 127 trn_cell_extension_pow_get_pow_effort(const trn_cell_extension_pow_t *inp) 128 { 129 return inp->pow_effort; 130 } 131 int 132 trn_cell_extension_pow_set_pow_effort(trn_cell_extension_pow_t *inp, uint32_t val) 133 { 134 inp->pow_effort = val; 135 return 0; 136 } 137 size_t 138 trn_cell_extension_pow_getlen_pow_seed(const trn_cell_extension_pow_t *inp) 139 { 140 (void)inp; return TRUNNEL_POW_SEED_HEAD_LEN; 141 } 142 143 uint8_t 144 trn_cell_extension_pow_get_pow_seed(trn_cell_extension_pow_t *inp, size_t idx) 145 { 146 trunnel_assert(idx < TRUNNEL_POW_SEED_HEAD_LEN); 147 return inp->pow_seed[idx]; 148 } 149 150 uint8_t 151 trn_cell_extension_pow_getconst_pow_seed(const trn_cell_extension_pow_t *inp, size_t idx) 152 { 153 return trn_cell_extension_pow_get_pow_seed((trn_cell_extension_pow_t*)inp, idx); 154 } 155 int 156 trn_cell_extension_pow_set_pow_seed(trn_cell_extension_pow_t *inp, size_t idx, uint8_t elt) 157 { 158 trunnel_assert(idx < TRUNNEL_POW_SEED_HEAD_LEN); 159 inp->pow_seed[idx] = elt; 160 return 0; 161 } 162 163 uint8_t * 164 trn_cell_extension_pow_getarray_pow_seed(trn_cell_extension_pow_t *inp) 165 { 166 return inp->pow_seed; 167 } 168 const uint8_t * 169 trn_cell_extension_pow_getconstarray_pow_seed(const trn_cell_extension_pow_t *inp) 170 { 171 return (const uint8_t *)trn_cell_extension_pow_getarray_pow_seed((trn_cell_extension_pow_t*)inp); 172 } 173 size_t 174 trn_cell_extension_pow_getlen_pow_solution(const trn_cell_extension_pow_t *inp) 175 { 176 (void)inp; return TRUNNEL_POW_SOLUTION_LEN; 177 } 178 179 uint8_t 180 trn_cell_extension_pow_get_pow_solution(trn_cell_extension_pow_t *inp, size_t idx) 181 { 182 trunnel_assert(idx < TRUNNEL_POW_SOLUTION_LEN); 183 return inp->pow_solution[idx]; 184 } 185 186 uint8_t 187 trn_cell_extension_pow_getconst_pow_solution(const trn_cell_extension_pow_t *inp, size_t idx) 188 { 189 return trn_cell_extension_pow_get_pow_solution((trn_cell_extension_pow_t*)inp, idx); 190 } 191 int 192 trn_cell_extension_pow_set_pow_solution(trn_cell_extension_pow_t *inp, size_t idx, uint8_t elt) 193 { 194 trunnel_assert(idx < TRUNNEL_POW_SOLUTION_LEN); 195 inp->pow_solution[idx] = elt; 196 return 0; 197 } 198 199 uint8_t * 200 trn_cell_extension_pow_getarray_pow_solution(trn_cell_extension_pow_t *inp) 201 { 202 return inp->pow_solution; 203 } 204 const uint8_t * 205 trn_cell_extension_pow_getconstarray_pow_solution(const trn_cell_extension_pow_t *inp) 206 { 207 return (const uint8_t *)trn_cell_extension_pow_getarray_pow_solution((trn_cell_extension_pow_t*)inp); 208 } 209 const char * 210 trn_cell_extension_pow_check(const trn_cell_extension_pow_t *obj) 211 { 212 if (obj == NULL) 213 return "Object was NULL"; 214 if (obj->trunnel_error_code_) 215 return "A set function failed on this object"; 216 if (! (obj->pow_version == 1)) 217 return "Integer out of bounds"; 218 return NULL; 219 } 220 221 ssize_t 222 trn_cell_extension_pow_encoded_len(const trn_cell_extension_pow_t *obj) 223 { 224 ssize_t result = 0; 225 226 if (NULL != trn_cell_extension_pow_check(obj)) 227 return -1; 228 229 230 /* Length of u8 pow_version IN [1] */ 231 result += 1; 232 233 /* Length of u8 pow_nonce[TRUNNEL_POW_NONCE_LEN] */ 234 result += TRUNNEL_POW_NONCE_LEN; 235 236 /* Length of u32 pow_effort */ 237 result += 4; 238 239 /* Length of u8 pow_seed[TRUNNEL_POW_SEED_HEAD_LEN] */ 240 result += TRUNNEL_POW_SEED_HEAD_LEN; 241 242 /* Length of u8 pow_solution[TRUNNEL_POW_SOLUTION_LEN] */ 243 result += TRUNNEL_POW_SOLUTION_LEN; 244 return result; 245 } 246 int 247 trn_cell_extension_pow_clear_errors(trn_cell_extension_pow_t *obj) 248 { 249 int r = obj->trunnel_error_code_; 250 obj->trunnel_error_code_ = 0; 251 return r; 252 } 253 ssize_t 254 trn_cell_extension_pow_encode(uint8_t *output, const size_t avail, const trn_cell_extension_pow_t *obj) 255 { 256 ssize_t result = 0; 257 size_t written = 0; 258 uint8_t *ptr = output; 259 const char *msg; 260 #ifdef TRUNNEL_CHECK_ENCODED_LEN 261 const ssize_t encoded_len = trn_cell_extension_pow_encoded_len(obj); 262 #endif 263 264 if (NULL != (msg = trn_cell_extension_pow_check(obj))) 265 goto check_failed; 266 267 #ifdef TRUNNEL_CHECK_ENCODED_LEN 268 trunnel_assert(encoded_len >= 0); 269 #endif 270 271 /* Encode u8 pow_version IN [1] */ 272 trunnel_assert(written <= avail); 273 if (avail - written < 1) 274 goto truncated; 275 trunnel_set_uint8(ptr, (obj->pow_version)); 276 written += 1; ptr += 1; 277 278 /* Encode u8 pow_nonce[TRUNNEL_POW_NONCE_LEN] */ 279 trunnel_assert(written <= avail); 280 if (avail - written < TRUNNEL_POW_NONCE_LEN) 281 goto truncated; 282 memcpy(ptr, obj->pow_nonce, TRUNNEL_POW_NONCE_LEN); 283 written += TRUNNEL_POW_NONCE_LEN; ptr += TRUNNEL_POW_NONCE_LEN; 284 285 /* Encode u32 pow_effort */ 286 trunnel_assert(written <= avail); 287 if (avail - written < 4) 288 goto truncated; 289 trunnel_set_uint32(ptr, trunnel_htonl(obj->pow_effort)); 290 written += 4; ptr += 4; 291 292 /* Encode u8 pow_seed[TRUNNEL_POW_SEED_HEAD_LEN] */ 293 trunnel_assert(written <= avail); 294 if (avail - written < TRUNNEL_POW_SEED_HEAD_LEN) 295 goto truncated; 296 memcpy(ptr, obj->pow_seed, TRUNNEL_POW_SEED_HEAD_LEN); 297 written += TRUNNEL_POW_SEED_HEAD_LEN; ptr += TRUNNEL_POW_SEED_HEAD_LEN; 298 299 /* Encode u8 pow_solution[TRUNNEL_POW_SOLUTION_LEN] */ 300 trunnel_assert(written <= avail); 301 if (avail - written < TRUNNEL_POW_SOLUTION_LEN) 302 goto truncated; 303 memcpy(ptr, obj->pow_solution, TRUNNEL_POW_SOLUTION_LEN); 304 written += TRUNNEL_POW_SOLUTION_LEN; ptr += TRUNNEL_POW_SOLUTION_LEN; 305 306 307 trunnel_assert(ptr == output + written); 308 #ifdef TRUNNEL_CHECK_ENCODED_LEN 309 { 310 trunnel_assert(encoded_len >= 0); 311 trunnel_assert((size_t)encoded_len == written); 312 } 313 314 #endif 315 316 return written; 317 318 truncated: 319 result = -2; 320 goto fail; 321 check_failed: 322 (void)msg; 323 result = -1; 324 goto fail; 325 fail: 326 trunnel_assert(result < 0); 327 return result; 328 } 329 330 /** As trn_cell_extension_pow_parse(), but do not allocate the output 331 * object. 332 */ 333 static ssize_t 334 trn_cell_extension_pow_parse_into(trn_cell_extension_pow_t *obj, const uint8_t *input, const size_t len_in) 335 { 336 const uint8_t *ptr = input; 337 size_t remaining = len_in; 338 ssize_t result = 0; 339 (void)result; 340 341 /* Parse u8 pow_version IN [1] */ 342 CHECK_REMAINING(1, truncated); 343 obj->pow_version = (trunnel_get_uint8(ptr)); 344 remaining -= 1; ptr += 1; 345 if (! (obj->pow_version == 1)) 346 goto fail; 347 348 /* Parse u8 pow_nonce[TRUNNEL_POW_NONCE_LEN] */ 349 CHECK_REMAINING(TRUNNEL_POW_NONCE_LEN, truncated); 350 memcpy(obj->pow_nonce, ptr, TRUNNEL_POW_NONCE_LEN); 351 remaining -= TRUNNEL_POW_NONCE_LEN; ptr += TRUNNEL_POW_NONCE_LEN; 352 353 /* Parse u32 pow_effort */ 354 CHECK_REMAINING(4, truncated); 355 obj->pow_effort = trunnel_ntohl(trunnel_get_uint32(ptr)); 356 remaining -= 4; ptr += 4; 357 358 /* Parse u8 pow_seed[TRUNNEL_POW_SEED_HEAD_LEN] */ 359 CHECK_REMAINING(TRUNNEL_POW_SEED_HEAD_LEN, truncated); 360 memcpy(obj->pow_seed, ptr, TRUNNEL_POW_SEED_HEAD_LEN); 361 remaining -= TRUNNEL_POW_SEED_HEAD_LEN; ptr += TRUNNEL_POW_SEED_HEAD_LEN; 362 363 /* Parse u8 pow_solution[TRUNNEL_POW_SOLUTION_LEN] */ 364 CHECK_REMAINING(TRUNNEL_POW_SOLUTION_LEN, truncated); 365 memcpy(obj->pow_solution, ptr, TRUNNEL_POW_SOLUTION_LEN); 366 remaining -= TRUNNEL_POW_SOLUTION_LEN; ptr += TRUNNEL_POW_SOLUTION_LEN; 367 trunnel_assert(ptr + remaining == input + len_in); 368 return len_in - remaining; 369 370 truncated: 371 return -2; 372 fail: 373 result = -1; 374 return result; 375 } 376 377 ssize_t 378 trn_cell_extension_pow_parse(trn_cell_extension_pow_t **output, const uint8_t *input, const size_t len_in) 379 { 380 ssize_t result; 381 *output = trn_cell_extension_pow_new(); 382 if (NULL == *output) 383 return -1; 384 result = trn_cell_extension_pow_parse_into(*output, input, len_in); 385 if (result < 0) { 386 trn_cell_extension_pow_free(*output); 387 *output = NULL; 388 } 389 return result; 390 } 391 trn_cell_introduce1_t * 392 trn_cell_introduce1_new(void) 393 { 394 trn_cell_introduce1_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce1_t)); 395 if (NULL == val) 396 return NULL; 397 val->auth_key_type = TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519; 398 return val; 399 } 400 401 /** Release all storage held inside 'obj', but do not free 'obj'. 402 */ 403 static void 404 trn_cell_introduce1_clear(trn_cell_introduce1_t *obj) 405 { 406 (void) obj; 407 TRUNNEL_DYNARRAY_WIPE(&obj->auth_key); 408 TRUNNEL_DYNARRAY_CLEAR(&obj->auth_key); 409 trn_extension_free(obj->extensions); 410 obj->extensions = NULL; 411 TRUNNEL_DYNARRAY_WIPE(&obj->encrypted); 412 TRUNNEL_DYNARRAY_CLEAR(&obj->encrypted); 413 } 414 415 void 416 trn_cell_introduce1_free(trn_cell_introduce1_t *obj) 417 { 418 if (obj == NULL) 419 return; 420 trn_cell_introduce1_clear(obj); 421 trunnel_memwipe(obj, sizeof(trn_cell_introduce1_t)); 422 trunnel_free_(obj); 423 } 424 425 size_t 426 trn_cell_introduce1_getlen_legacy_key_id(const trn_cell_introduce1_t *inp) 427 { 428 (void)inp; return TRUNNEL_SHA1_LEN; 429 } 430 431 uint8_t 432 trn_cell_introduce1_get_legacy_key_id(trn_cell_introduce1_t *inp, size_t idx) 433 { 434 trunnel_assert(idx < TRUNNEL_SHA1_LEN); 435 return inp->legacy_key_id[idx]; 436 } 437 438 uint8_t 439 trn_cell_introduce1_getconst_legacy_key_id(const trn_cell_introduce1_t *inp, size_t idx) 440 { 441 return trn_cell_introduce1_get_legacy_key_id((trn_cell_introduce1_t*)inp, idx); 442 } 443 int 444 trn_cell_introduce1_set_legacy_key_id(trn_cell_introduce1_t *inp, size_t idx, uint8_t elt) 445 { 446 trunnel_assert(idx < TRUNNEL_SHA1_LEN); 447 inp->legacy_key_id[idx] = elt; 448 return 0; 449 } 450 451 uint8_t * 452 trn_cell_introduce1_getarray_legacy_key_id(trn_cell_introduce1_t *inp) 453 { 454 return inp->legacy_key_id; 455 } 456 const uint8_t * 457 trn_cell_introduce1_getconstarray_legacy_key_id(const trn_cell_introduce1_t *inp) 458 { 459 return (const uint8_t *)trn_cell_introduce1_getarray_legacy_key_id((trn_cell_introduce1_t*)inp); 460 } 461 uint8_t 462 trn_cell_introduce1_get_auth_key_type(const trn_cell_introduce1_t *inp) 463 { 464 return inp->auth_key_type; 465 } 466 int 467 trn_cell_introduce1_set_auth_key_type(trn_cell_introduce1_t *inp, uint8_t val) 468 { 469 if (! ((val == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 || val == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 || val == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1))) { 470 TRUNNEL_SET_ERROR_CODE(inp); 471 return -1; 472 } 473 inp->auth_key_type = val; 474 return 0; 475 } 476 uint16_t 477 trn_cell_introduce1_get_auth_key_len(const trn_cell_introduce1_t *inp) 478 { 479 return inp->auth_key_len; 480 } 481 int 482 trn_cell_introduce1_set_auth_key_len(trn_cell_introduce1_t *inp, uint16_t val) 483 { 484 inp->auth_key_len = val; 485 return 0; 486 } 487 size_t 488 trn_cell_introduce1_getlen_auth_key(const trn_cell_introduce1_t *inp) 489 { 490 return TRUNNEL_DYNARRAY_LEN(&inp->auth_key); 491 } 492 493 uint8_t 494 trn_cell_introduce1_get_auth_key(trn_cell_introduce1_t *inp, size_t idx) 495 { 496 return TRUNNEL_DYNARRAY_GET(&inp->auth_key, idx); 497 } 498 499 uint8_t 500 trn_cell_introduce1_getconst_auth_key(const trn_cell_introduce1_t *inp, size_t idx) 501 { 502 return trn_cell_introduce1_get_auth_key((trn_cell_introduce1_t*)inp, idx); 503 } 504 int 505 trn_cell_introduce1_set_auth_key(trn_cell_introduce1_t *inp, size_t idx, uint8_t elt) 506 { 507 TRUNNEL_DYNARRAY_SET(&inp->auth_key, idx, elt); 508 return 0; 509 } 510 int 511 trn_cell_introduce1_add_auth_key(trn_cell_introduce1_t *inp, uint8_t elt) 512 { 513 #if SIZE_MAX >= UINT16_MAX 514 if (inp->auth_key.n_ == UINT16_MAX) 515 goto trunnel_alloc_failed; 516 #endif 517 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->auth_key, elt, {}); 518 return 0; 519 trunnel_alloc_failed: 520 TRUNNEL_SET_ERROR_CODE(inp); 521 return -1; 522 } 523 524 uint8_t * 525 trn_cell_introduce1_getarray_auth_key(trn_cell_introduce1_t *inp) 526 { 527 return inp->auth_key.elts_; 528 } 529 const uint8_t * 530 trn_cell_introduce1_getconstarray_auth_key(const trn_cell_introduce1_t *inp) 531 { 532 return (const uint8_t *)trn_cell_introduce1_getarray_auth_key((trn_cell_introduce1_t*)inp); 533 } 534 int 535 trn_cell_introduce1_setlen_auth_key(trn_cell_introduce1_t *inp, size_t newlen) 536 { 537 uint8_t *newptr; 538 #if UINT16_MAX < SIZE_MAX 539 if (newlen > UINT16_MAX) 540 goto trunnel_alloc_failed; 541 #endif 542 newptr = trunnel_dynarray_setlen(&inp->auth_key.allocated_, 543 &inp->auth_key.n_, inp->auth_key.elts_, newlen, 544 sizeof(inp->auth_key.elts_[0]), (trunnel_free_fn_t) NULL, 545 &inp->trunnel_error_code_); 546 if (newlen != 0 && newptr == NULL) 547 goto trunnel_alloc_failed; 548 inp->auth_key.elts_ = newptr; 549 return 0; 550 trunnel_alloc_failed: 551 TRUNNEL_SET_ERROR_CODE(inp); 552 return -1; 553 } 554 struct trn_extension_st * 555 trn_cell_introduce1_get_extensions(trn_cell_introduce1_t *inp) 556 { 557 return inp->extensions; 558 } 559 const struct trn_extension_st * 560 trn_cell_introduce1_getconst_extensions(const trn_cell_introduce1_t *inp) 561 { 562 return trn_cell_introduce1_get_extensions((trn_cell_introduce1_t*) inp); 563 } 564 int 565 trn_cell_introduce1_set_extensions(trn_cell_introduce1_t *inp, struct trn_extension_st *val) 566 { 567 if (inp->extensions && inp->extensions != val) 568 trn_extension_free(inp->extensions); 569 return trn_cell_introduce1_set0_extensions(inp, val); 570 } 571 int 572 trn_cell_introduce1_set0_extensions(trn_cell_introduce1_t *inp, struct trn_extension_st *val) 573 { 574 inp->extensions = val; 575 return 0; 576 } 577 size_t 578 trn_cell_introduce1_getlen_encrypted(const trn_cell_introduce1_t *inp) 579 { 580 return TRUNNEL_DYNARRAY_LEN(&inp->encrypted); 581 } 582 583 uint8_t 584 trn_cell_introduce1_get_encrypted(trn_cell_introduce1_t *inp, size_t idx) 585 { 586 return TRUNNEL_DYNARRAY_GET(&inp->encrypted, idx); 587 } 588 589 uint8_t 590 trn_cell_introduce1_getconst_encrypted(const trn_cell_introduce1_t *inp, size_t idx) 591 { 592 return trn_cell_introduce1_get_encrypted((trn_cell_introduce1_t*)inp, idx); 593 } 594 int 595 trn_cell_introduce1_set_encrypted(trn_cell_introduce1_t *inp, size_t idx, uint8_t elt) 596 { 597 TRUNNEL_DYNARRAY_SET(&inp->encrypted, idx, elt); 598 return 0; 599 } 600 int 601 trn_cell_introduce1_add_encrypted(trn_cell_introduce1_t *inp, uint8_t elt) 602 { 603 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->encrypted, elt, {}); 604 return 0; 605 trunnel_alloc_failed: 606 TRUNNEL_SET_ERROR_CODE(inp); 607 return -1; 608 } 609 610 uint8_t * 611 trn_cell_introduce1_getarray_encrypted(trn_cell_introduce1_t *inp) 612 { 613 return inp->encrypted.elts_; 614 } 615 const uint8_t * 616 trn_cell_introduce1_getconstarray_encrypted(const trn_cell_introduce1_t *inp) 617 { 618 return (const uint8_t *)trn_cell_introduce1_getarray_encrypted((trn_cell_introduce1_t*)inp); 619 } 620 int 621 trn_cell_introduce1_setlen_encrypted(trn_cell_introduce1_t *inp, size_t newlen) 622 { 623 uint8_t *newptr; 624 newptr = trunnel_dynarray_setlen(&inp->encrypted.allocated_, 625 &inp->encrypted.n_, inp->encrypted.elts_, newlen, 626 sizeof(inp->encrypted.elts_[0]), (trunnel_free_fn_t) NULL, 627 &inp->trunnel_error_code_); 628 if (newlen != 0 && newptr == NULL) 629 goto trunnel_alloc_failed; 630 inp->encrypted.elts_ = newptr; 631 return 0; 632 trunnel_alloc_failed: 633 TRUNNEL_SET_ERROR_CODE(inp); 634 return -1; 635 } 636 const char * 637 trn_cell_introduce1_check(const trn_cell_introduce1_t *obj) 638 { 639 if (obj == NULL) 640 return "Object was NULL"; 641 if (obj->trunnel_error_code_) 642 return "A set function failed on this object"; 643 if (! (obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1)) 644 return "Integer out of bounds"; 645 if (TRUNNEL_DYNARRAY_LEN(&obj->auth_key) != obj->auth_key_len) 646 return "Length mismatch for auth_key"; 647 { 648 const char *msg; 649 if (NULL != (msg = trn_extension_check(obj->extensions))) 650 return msg; 651 } 652 return NULL; 653 } 654 655 ssize_t 656 trn_cell_introduce1_encoded_len(const trn_cell_introduce1_t *obj) 657 { 658 ssize_t result = 0; 659 660 if (NULL != trn_cell_introduce1_check(obj)) 661 return -1; 662 663 664 /* Length of u8 legacy_key_id[TRUNNEL_SHA1_LEN] */ 665 result += TRUNNEL_SHA1_LEN; 666 667 /* Length of u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1] */ 668 result += 1; 669 670 /* Length of u16 auth_key_len */ 671 result += 2; 672 673 /* Length of u8 auth_key[auth_key_len] */ 674 result += TRUNNEL_DYNARRAY_LEN(&obj->auth_key); 675 676 /* Length of struct trn_extension extensions */ 677 result += trn_extension_encoded_len(obj->extensions); 678 679 /* Length of u8 encrypted[] */ 680 result += TRUNNEL_DYNARRAY_LEN(&obj->encrypted); 681 return result; 682 } 683 int 684 trn_cell_introduce1_clear_errors(trn_cell_introduce1_t *obj) 685 { 686 int r = obj->trunnel_error_code_; 687 obj->trunnel_error_code_ = 0; 688 return r; 689 } 690 ssize_t 691 trn_cell_introduce1_encode(uint8_t *output, const size_t avail, const trn_cell_introduce1_t *obj) 692 { 693 ssize_t result = 0; 694 size_t written = 0; 695 uint8_t *ptr = output; 696 const char *msg; 697 #ifdef TRUNNEL_CHECK_ENCODED_LEN 698 const ssize_t encoded_len = trn_cell_introduce1_encoded_len(obj); 699 #endif 700 701 if (NULL != (msg = trn_cell_introduce1_check(obj))) 702 goto check_failed; 703 704 #ifdef TRUNNEL_CHECK_ENCODED_LEN 705 trunnel_assert(encoded_len >= 0); 706 #endif 707 708 /* Encode u8 legacy_key_id[TRUNNEL_SHA1_LEN] */ 709 trunnel_assert(written <= avail); 710 if (avail - written < TRUNNEL_SHA1_LEN) 711 goto truncated; 712 memcpy(ptr, obj->legacy_key_id, TRUNNEL_SHA1_LEN); 713 written += TRUNNEL_SHA1_LEN; ptr += TRUNNEL_SHA1_LEN; 714 715 /* Encode u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1] */ 716 trunnel_assert(written <= avail); 717 if (avail - written < 1) 718 goto truncated; 719 trunnel_set_uint8(ptr, (obj->auth_key_type)); 720 written += 1; ptr += 1; 721 722 /* Encode u16 auth_key_len */ 723 trunnel_assert(written <= avail); 724 if (avail - written < 2) 725 goto truncated; 726 trunnel_set_uint16(ptr, trunnel_htons(obj->auth_key_len)); 727 written += 2; ptr += 2; 728 729 /* Encode u8 auth_key[auth_key_len] */ 730 { 731 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->auth_key); 732 trunnel_assert(obj->auth_key_len == elt_len); 733 trunnel_assert(written <= avail); 734 if (avail - written < elt_len) 735 goto truncated; 736 if (elt_len) 737 memcpy(ptr, obj->auth_key.elts_, elt_len); 738 written += elt_len; ptr += elt_len; 739 } 740 741 /* Encode struct trn_extension extensions */ 742 trunnel_assert(written <= avail); 743 result = trn_extension_encode(ptr, avail - written, obj->extensions); 744 if (result < 0) 745 goto fail; /* XXXXXXX !*/ 746 written += result; ptr += result; 747 748 /* Encode u8 encrypted[] */ 749 { 750 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->encrypted); 751 trunnel_assert(written <= avail); 752 if (avail - written < elt_len) 753 goto truncated; 754 if (elt_len) 755 memcpy(ptr, obj->encrypted.elts_, elt_len); 756 written += elt_len; ptr += elt_len; 757 } 758 759 760 trunnel_assert(ptr == output + written); 761 #ifdef TRUNNEL_CHECK_ENCODED_LEN 762 { 763 trunnel_assert(encoded_len >= 0); 764 trunnel_assert((size_t)encoded_len == written); 765 } 766 767 #endif 768 769 return written; 770 771 truncated: 772 result = -2; 773 goto fail; 774 check_failed: 775 (void)msg; 776 result = -1; 777 goto fail; 778 fail: 779 trunnel_assert(result < 0); 780 return result; 781 } 782 783 /** As trn_cell_introduce1_parse(), but do not allocate the output 784 * object. 785 */ 786 static ssize_t 787 trn_cell_introduce1_parse_into(trn_cell_introduce1_t *obj, const uint8_t *input, const size_t len_in) 788 { 789 const uint8_t *ptr = input; 790 size_t remaining = len_in; 791 ssize_t result = 0; 792 (void)result; 793 794 /* Parse u8 legacy_key_id[TRUNNEL_SHA1_LEN] */ 795 CHECK_REMAINING(TRUNNEL_SHA1_LEN, truncated); 796 memcpy(obj->legacy_key_id, ptr, TRUNNEL_SHA1_LEN); 797 remaining -= TRUNNEL_SHA1_LEN; ptr += TRUNNEL_SHA1_LEN; 798 799 /* Parse u8 auth_key_type IN [TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0, TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1] */ 800 CHECK_REMAINING(1, truncated); 801 obj->auth_key_type = (trunnel_get_uint8(ptr)); 802 remaining -= 1; ptr += 1; 803 if (! (obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0 || obj->auth_key_type == TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1)) 804 goto fail; 805 806 /* Parse u16 auth_key_len */ 807 CHECK_REMAINING(2, truncated); 808 obj->auth_key_len = trunnel_ntohs(trunnel_get_uint16(ptr)); 809 remaining -= 2; ptr += 2; 810 811 /* Parse u8 auth_key[auth_key_len] */ 812 CHECK_REMAINING(obj->auth_key_len, truncated); 813 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->auth_key, obj->auth_key_len, {}); 814 obj->auth_key.n_ = obj->auth_key_len; 815 if (obj->auth_key_len) 816 memcpy(obj->auth_key.elts_, ptr, obj->auth_key_len); 817 ptr += obj->auth_key_len; remaining -= obj->auth_key_len; 818 819 /* Parse struct trn_extension extensions */ 820 result = trn_extension_parse(&obj->extensions, ptr, remaining); 821 if (result < 0) 822 goto relay_fail; 823 trunnel_assert((size_t)result <= remaining); 824 remaining -= result; ptr += result; 825 826 /* Parse u8 encrypted[] */ 827 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->encrypted, remaining, {}); 828 obj->encrypted.n_ = remaining; 829 if (remaining) 830 memcpy(obj->encrypted.elts_, ptr, remaining); 831 ptr += remaining; remaining -= remaining; 832 trunnel_assert(ptr + remaining == input + len_in); 833 return len_in - remaining; 834 835 truncated: 836 return -2; 837 relay_fail: 838 trunnel_assert(result < 0); 839 return result; 840 trunnel_alloc_failed: 841 return -1; 842 fail: 843 result = -1; 844 return result; 845 } 846 847 ssize_t 848 trn_cell_introduce1_parse(trn_cell_introduce1_t **output, const uint8_t *input, const size_t len_in) 849 { 850 ssize_t result; 851 *output = trn_cell_introduce1_new(); 852 if (NULL == *output) 853 return -1; 854 result = trn_cell_introduce1_parse_into(*output, input, len_in); 855 if (result < 0) { 856 trn_cell_introduce1_free(*output); 857 *output = NULL; 858 } 859 return result; 860 } 861 trn_cell_introduce_ack_t * 862 trn_cell_introduce_ack_new(void) 863 { 864 trn_cell_introduce_ack_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce_ack_t)); 865 if (NULL == val) 866 return NULL; 867 return val; 868 } 869 870 /** Release all storage held inside 'obj', but do not free 'obj'. 871 */ 872 static void 873 trn_cell_introduce_ack_clear(trn_cell_introduce_ack_t *obj) 874 { 875 (void) obj; 876 trn_extension_free(obj->extensions); 877 obj->extensions = NULL; 878 } 879 880 void 881 trn_cell_introduce_ack_free(trn_cell_introduce_ack_t *obj) 882 { 883 if (obj == NULL) 884 return; 885 trn_cell_introduce_ack_clear(obj); 886 trunnel_memwipe(obj, sizeof(trn_cell_introduce_ack_t)); 887 trunnel_free_(obj); 888 } 889 890 uint16_t 891 trn_cell_introduce_ack_get_status(const trn_cell_introduce_ack_t *inp) 892 { 893 return inp->status; 894 } 895 int 896 trn_cell_introduce_ack_set_status(trn_cell_introduce_ack_t *inp, uint16_t val) 897 { 898 inp->status = val; 899 return 0; 900 } 901 struct trn_extension_st * 902 trn_cell_introduce_ack_get_extensions(trn_cell_introduce_ack_t *inp) 903 { 904 return inp->extensions; 905 } 906 const struct trn_extension_st * 907 trn_cell_introduce_ack_getconst_extensions(const trn_cell_introduce_ack_t *inp) 908 { 909 return trn_cell_introduce_ack_get_extensions((trn_cell_introduce_ack_t*) inp); 910 } 911 int 912 trn_cell_introduce_ack_set_extensions(trn_cell_introduce_ack_t *inp, struct trn_extension_st *val) 913 { 914 if (inp->extensions && inp->extensions != val) 915 trn_extension_free(inp->extensions); 916 return trn_cell_introduce_ack_set0_extensions(inp, val); 917 } 918 int 919 trn_cell_introduce_ack_set0_extensions(trn_cell_introduce_ack_t *inp, struct trn_extension_st *val) 920 { 921 inp->extensions = val; 922 return 0; 923 } 924 const char * 925 trn_cell_introduce_ack_check(const trn_cell_introduce_ack_t *obj) 926 { 927 if (obj == NULL) 928 return "Object was NULL"; 929 if (obj->trunnel_error_code_) 930 return "A set function failed on this object"; 931 { 932 const char *msg; 933 if (NULL != (msg = trn_extension_check(obj->extensions))) 934 return msg; 935 } 936 return NULL; 937 } 938 939 ssize_t 940 trn_cell_introduce_ack_encoded_len(const trn_cell_introduce_ack_t *obj) 941 { 942 ssize_t result = 0; 943 944 if (NULL != trn_cell_introduce_ack_check(obj)) 945 return -1; 946 947 948 /* Length of u16 status */ 949 result += 2; 950 951 /* Length of struct trn_extension extensions */ 952 result += trn_extension_encoded_len(obj->extensions); 953 return result; 954 } 955 int 956 trn_cell_introduce_ack_clear_errors(trn_cell_introduce_ack_t *obj) 957 { 958 int r = obj->trunnel_error_code_; 959 obj->trunnel_error_code_ = 0; 960 return r; 961 } 962 ssize_t 963 trn_cell_introduce_ack_encode(uint8_t *output, const size_t avail, const trn_cell_introduce_ack_t *obj) 964 { 965 ssize_t result = 0; 966 size_t written = 0; 967 uint8_t *ptr = output; 968 const char *msg; 969 #ifdef TRUNNEL_CHECK_ENCODED_LEN 970 const ssize_t encoded_len = trn_cell_introduce_ack_encoded_len(obj); 971 #endif 972 973 if (NULL != (msg = trn_cell_introduce_ack_check(obj))) 974 goto check_failed; 975 976 #ifdef TRUNNEL_CHECK_ENCODED_LEN 977 trunnel_assert(encoded_len >= 0); 978 #endif 979 980 /* Encode u16 status */ 981 trunnel_assert(written <= avail); 982 if (avail - written < 2) 983 goto truncated; 984 trunnel_set_uint16(ptr, trunnel_htons(obj->status)); 985 written += 2; ptr += 2; 986 987 /* Encode struct trn_extension extensions */ 988 trunnel_assert(written <= avail); 989 result = trn_extension_encode(ptr, avail - written, obj->extensions); 990 if (result < 0) 991 goto fail; /* XXXXXXX !*/ 992 written += result; ptr += result; 993 994 995 trunnel_assert(ptr == output + written); 996 #ifdef TRUNNEL_CHECK_ENCODED_LEN 997 { 998 trunnel_assert(encoded_len >= 0); 999 trunnel_assert((size_t)encoded_len == written); 1000 } 1001 1002 #endif 1003 1004 return written; 1005 1006 truncated: 1007 result = -2; 1008 goto fail; 1009 check_failed: 1010 (void)msg; 1011 result = -1; 1012 goto fail; 1013 fail: 1014 trunnel_assert(result < 0); 1015 return result; 1016 } 1017 1018 /** As trn_cell_introduce_ack_parse(), but do not allocate the output 1019 * object. 1020 */ 1021 static ssize_t 1022 trn_cell_introduce_ack_parse_into(trn_cell_introduce_ack_t *obj, const uint8_t *input, const size_t len_in) 1023 { 1024 const uint8_t *ptr = input; 1025 size_t remaining = len_in; 1026 ssize_t result = 0; 1027 (void)result; 1028 1029 /* Parse u16 status */ 1030 CHECK_REMAINING(2, truncated); 1031 obj->status = trunnel_ntohs(trunnel_get_uint16(ptr)); 1032 remaining -= 2; ptr += 2; 1033 1034 /* Parse struct trn_extension extensions */ 1035 result = trn_extension_parse(&obj->extensions, ptr, remaining); 1036 if (result < 0) 1037 goto relay_fail; 1038 trunnel_assert((size_t)result <= remaining); 1039 remaining -= result; ptr += result; 1040 trunnel_assert(ptr + remaining == input + len_in); 1041 return len_in - remaining; 1042 1043 truncated: 1044 return -2; 1045 relay_fail: 1046 trunnel_assert(result < 0); 1047 return result; 1048 } 1049 1050 ssize_t 1051 trn_cell_introduce_ack_parse(trn_cell_introduce_ack_t **output, const uint8_t *input, const size_t len_in) 1052 { 1053 ssize_t result; 1054 *output = trn_cell_introduce_ack_new(); 1055 if (NULL == *output) 1056 return -1; 1057 result = trn_cell_introduce_ack_parse_into(*output, input, len_in); 1058 if (result < 0) { 1059 trn_cell_introduce_ack_free(*output); 1060 *output = NULL; 1061 } 1062 return result; 1063 } 1064 trn_cell_introduce_encrypted_t * 1065 trn_cell_introduce_encrypted_new(void) 1066 { 1067 trn_cell_introduce_encrypted_t *val = trunnel_calloc(1, sizeof(trn_cell_introduce_encrypted_t)); 1068 if (NULL == val) 1069 return NULL; 1070 val->onion_key_type = TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR; 1071 return val; 1072 } 1073 1074 /** Release all storage held inside 'obj', but do not free 'obj'. 1075 */ 1076 static void 1077 trn_cell_introduce_encrypted_clear(trn_cell_introduce_encrypted_t *obj) 1078 { 1079 (void) obj; 1080 trn_extension_free(obj->extensions); 1081 obj->extensions = NULL; 1082 TRUNNEL_DYNARRAY_WIPE(&obj->onion_key); 1083 TRUNNEL_DYNARRAY_CLEAR(&obj->onion_key); 1084 { 1085 1086 unsigned idx; 1087 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->nspecs); ++idx) { 1088 link_specifier_free(TRUNNEL_DYNARRAY_GET(&obj->nspecs, idx)); 1089 } 1090 } 1091 TRUNNEL_DYNARRAY_WIPE(&obj->nspecs); 1092 TRUNNEL_DYNARRAY_CLEAR(&obj->nspecs); 1093 TRUNNEL_DYNARRAY_WIPE(&obj->pad); 1094 TRUNNEL_DYNARRAY_CLEAR(&obj->pad); 1095 } 1096 1097 void 1098 trn_cell_introduce_encrypted_free(trn_cell_introduce_encrypted_t *obj) 1099 { 1100 if (obj == NULL) 1101 return; 1102 trn_cell_introduce_encrypted_clear(obj); 1103 trunnel_memwipe(obj, sizeof(trn_cell_introduce_encrypted_t)); 1104 trunnel_free_(obj); 1105 } 1106 1107 size_t 1108 trn_cell_introduce_encrypted_getlen_rend_cookie(const trn_cell_introduce_encrypted_t *inp) 1109 { 1110 (void)inp; return TRUNNEL_REND_COOKIE_LEN; 1111 } 1112 1113 uint8_t 1114 trn_cell_introduce_encrypted_get_rend_cookie(trn_cell_introduce_encrypted_t *inp, size_t idx) 1115 { 1116 trunnel_assert(idx < TRUNNEL_REND_COOKIE_LEN); 1117 return inp->rend_cookie[idx]; 1118 } 1119 1120 uint8_t 1121 trn_cell_introduce_encrypted_getconst_rend_cookie(const trn_cell_introduce_encrypted_t *inp, size_t idx) 1122 { 1123 return trn_cell_introduce_encrypted_get_rend_cookie((trn_cell_introduce_encrypted_t*)inp, idx); 1124 } 1125 int 1126 trn_cell_introduce_encrypted_set_rend_cookie(trn_cell_introduce_encrypted_t *inp, size_t idx, uint8_t elt) 1127 { 1128 trunnel_assert(idx < TRUNNEL_REND_COOKIE_LEN); 1129 inp->rend_cookie[idx] = elt; 1130 return 0; 1131 } 1132 1133 uint8_t * 1134 trn_cell_introduce_encrypted_getarray_rend_cookie(trn_cell_introduce_encrypted_t *inp) 1135 { 1136 return inp->rend_cookie; 1137 } 1138 const uint8_t * 1139 trn_cell_introduce_encrypted_getconstarray_rend_cookie(const trn_cell_introduce_encrypted_t *inp) 1140 { 1141 return (const uint8_t *)trn_cell_introduce_encrypted_getarray_rend_cookie((trn_cell_introduce_encrypted_t*)inp); 1142 } 1143 struct trn_extension_st * 1144 trn_cell_introduce_encrypted_get_extensions(trn_cell_introduce_encrypted_t *inp) 1145 { 1146 return inp->extensions; 1147 } 1148 const struct trn_extension_st * 1149 trn_cell_introduce_encrypted_getconst_extensions(const trn_cell_introduce_encrypted_t *inp) 1150 { 1151 return trn_cell_introduce_encrypted_get_extensions((trn_cell_introduce_encrypted_t*) inp); 1152 } 1153 int 1154 trn_cell_introduce_encrypted_set_extensions(trn_cell_introduce_encrypted_t *inp, struct trn_extension_st *val) 1155 { 1156 if (inp->extensions && inp->extensions != val) 1157 trn_extension_free(inp->extensions); 1158 return trn_cell_introduce_encrypted_set0_extensions(inp, val); 1159 } 1160 int 1161 trn_cell_introduce_encrypted_set0_extensions(trn_cell_introduce_encrypted_t *inp, struct trn_extension_st *val) 1162 { 1163 inp->extensions = val; 1164 return 0; 1165 } 1166 uint8_t 1167 trn_cell_introduce_encrypted_get_onion_key_type(const trn_cell_introduce_encrypted_t *inp) 1168 { 1169 return inp->onion_key_type; 1170 } 1171 int 1172 trn_cell_introduce_encrypted_set_onion_key_type(trn_cell_introduce_encrypted_t *inp, uint8_t val) 1173 { 1174 if (! ((val == TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR))) { 1175 TRUNNEL_SET_ERROR_CODE(inp); 1176 return -1; 1177 } 1178 inp->onion_key_type = val; 1179 return 0; 1180 } 1181 uint16_t 1182 trn_cell_introduce_encrypted_get_onion_key_len(const trn_cell_introduce_encrypted_t *inp) 1183 { 1184 return inp->onion_key_len; 1185 } 1186 int 1187 trn_cell_introduce_encrypted_set_onion_key_len(trn_cell_introduce_encrypted_t *inp, uint16_t val) 1188 { 1189 inp->onion_key_len = val; 1190 return 0; 1191 } 1192 size_t 1193 trn_cell_introduce_encrypted_getlen_onion_key(const trn_cell_introduce_encrypted_t *inp) 1194 { 1195 return TRUNNEL_DYNARRAY_LEN(&inp->onion_key); 1196 } 1197 1198 uint8_t 1199 trn_cell_introduce_encrypted_get_onion_key(trn_cell_introduce_encrypted_t *inp, size_t idx) 1200 { 1201 return TRUNNEL_DYNARRAY_GET(&inp->onion_key, idx); 1202 } 1203 1204 uint8_t 1205 trn_cell_introduce_encrypted_getconst_onion_key(const trn_cell_introduce_encrypted_t *inp, size_t idx) 1206 { 1207 return trn_cell_introduce_encrypted_get_onion_key((trn_cell_introduce_encrypted_t*)inp, idx); 1208 } 1209 int 1210 trn_cell_introduce_encrypted_set_onion_key(trn_cell_introduce_encrypted_t *inp, size_t idx, uint8_t elt) 1211 { 1212 TRUNNEL_DYNARRAY_SET(&inp->onion_key, idx, elt); 1213 return 0; 1214 } 1215 int 1216 trn_cell_introduce_encrypted_add_onion_key(trn_cell_introduce_encrypted_t *inp, uint8_t elt) 1217 { 1218 #if SIZE_MAX >= UINT16_MAX 1219 if (inp->onion_key.n_ == UINT16_MAX) 1220 goto trunnel_alloc_failed; 1221 #endif 1222 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->onion_key, elt, {}); 1223 return 0; 1224 trunnel_alloc_failed: 1225 TRUNNEL_SET_ERROR_CODE(inp); 1226 return -1; 1227 } 1228 1229 uint8_t * 1230 trn_cell_introduce_encrypted_getarray_onion_key(trn_cell_introduce_encrypted_t *inp) 1231 { 1232 return inp->onion_key.elts_; 1233 } 1234 const uint8_t * 1235 trn_cell_introduce_encrypted_getconstarray_onion_key(const trn_cell_introduce_encrypted_t *inp) 1236 { 1237 return (const uint8_t *)trn_cell_introduce_encrypted_getarray_onion_key((trn_cell_introduce_encrypted_t*)inp); 1238 } 1239 int 1240 trn_cell_introduce_encrypted_setlen_onion_key(trn_cell_introduce_encrypted_t *inp, size_t newlen) 1241 { 1242 uint8_t *newptr; 1243 #if UINT16_MAX < SIZE_MAX 1244 if (newlen > UINT16_MAX) 1245 goto trunnel_alloc_failed; 1246 #endif 1247 newptr = trunnel_dynarray_setlen(&inp->onion_key.allocated_, 1248 &inp->onion_key.n_, inp->onion_key.elts_, newlen, 1249 sizeof(inp->onion_key.elts_[0]), (trunnel_free_fn_t) NULL, 1250 &inp->trunnel_error_code_); 1251 if (newlen != 0 && newptr == NULL) 1252 goto trunnel_alloc_failed; 1253 inp->onion_key.elts_ = newptr; 1254 return 0; 1255 trunnel_alloc_failed: 1256 TRUNNEL_SET_ERROR_CODE(inp); 1257 return -1; 1258 } 1259 uint8_t 1260 trn_cell_introduce_encrypted_get_nspec(const trn_cell_introduce_encrypted_t *inp) 1261 { 1262 return inp->nspec; 1263 } 1264 int 1265 trn_cell_introduce_encrypted_set_nspec(trn_cell_introduce_encrypted_t *inp, uint8_t val) 1266 { 1267 inp->nspec = val; 1268 return 0; 1269 } 1270 size_t 1271 trn_cell_introduce_encrypted_getlen_nspecs(const trn_cell_introduce_encrypted_t *inp) 1272 { 1273 return TRUNNEL_DYNARRAY_LEN(&inp->nspecs); 1274 } 1275 1276 struct link_specifier_st * 1277 trn_cell_introduce_encrypted_get_nspecs(trn_cell_introduce_encrypted_t *inp, size_t idx) 1278 { 1279 return TRUNNEL_DYNARRAY_GET(&inp->nspecs, idx); 1280 } 1281 1282 const struct link_specifier_st * 1283 trn_cell_introduce_encrypted_getconst_nspecs(const trn_cell_introduce_encrypted_t *inp, size_t idx) 1284 { 1285 return trn_cell_introduce_encrypted_get_nspecs((trn_cell_introduce_encrypted_t*)inp, idx); 1286 } 1287 int 1288 trn_cell_introduce_encrypted_set_nspecs(trn_cell_introduce_encrypted_t *inp, size_t idx, struct link_specifier_st * elt) 1289 { 1290 link_specifier_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->nspecs, idx); 1291 if (oldval && oldval != elt) 1292 link_specifier_free(oldval); 1293 return trn_cell_introduce_encrypted_set0_nspecs(inp, idx, elt); 1294 } 1295 int 1296 trn_cell_introduce_encrypted_set0_nspecs(trn_cell_introduce_encrypted_t *inp, size_t idx, struct link_specifier_st * elt) 1297 { 1298 TRUNNEL_DYNARRAY_SET(&inp->nspecs, idx, elt); 1299 return 0; 1300 } 1301 int 1302 trn_cell_introduce_encrypted_add_nspecs(trn_cell_introduce_encrypted_t *inp, struct link_specifier_st * elt) 1303 { 1304 #if SIZE_MAX >= UINT8_MAX 1305 if (inp->nspecs.n_ == UINT8_MAX) 1306 goto trunnel_alloc_failed; 1307 #endif 1308 TRUNNEL_DYNARRAY_ADD(struct link_specifier_st *, &inp->nspecs, elt, {}); 1309 return 0; 1310 trunnel_alloc_failed: 1311 TRUNNEL_SET_ERROR_CODE(inp); 1312 return -1; 1313 } 1314 1315 struct link_specifier_st * * 1316 trn_cell_introduce_encrypted_getarray_nspecs(trn_cell_introduce_encrypted_t *inp) 1317 { 1318 return inp->nspecs.elts_; 1319 } 1320 const struct link_specifier_st * const * 1321 trn_cell_introduce_encrypted_getconstarray_nspecs(const trn_cell_introduce_encrypted_t *inp) 1322 { 1323 return (const struct link_specifier_st * const *)trn_cell_introduce_encrypted_getarray_nspecs((trn_cell_introduce_encrypted_t*)inp); 1324 } 1325 int 1326 trn_cell_introduce_encrypted_setlen_nspecs(trn_cell_introduce_encrypted_t *inp, size_t newlen) 1327 { 1328 struct link_specifier_st * *newptr; 1329 #if UINT8_MAX < SIZE_MAX 1330 if (newlen > UINT8_MAX) 1331 goto trunnel_alloc_failed; 1332 #endif 1333 newptr = trunnel_dynarray_setlen(&inp->nspecs.allocated_, 1334 &inp->nspecs.n_, inp->nspecs.elts_, newlen, 1335 sizeof(inp->nspecs.elts_[0]), (trunnel_free_fn_t) link_specifier_free, 1336 &inp->trunnel_error_code_); 1337 if (newlen != 0 && newptr == NULL) 1338 goto trunnel_alloc_failed; 1339 inp->nspecs.elts_ = newptr; 1340 return 0; 1341 trunnel_alloc_failed: 1342 TRUNNEL_SET_ERROR_CODE(inp); 1343 return -1; 1344 } 1345 size_t 1346 trn_cell_introduce_encrypted_getlen_pad(const trn_cell_introduce_encrypted_t *inp) 1347 { 1348 return TRUNNEL_DYNARRAY_LEN(&inp->pad); 1349 } 1350 1351 uint8_t 1352 trn_cell_introduce_encrypted_get_pad(trn_cell_introduce_encrypted_t *inp, size_t idx) 1353 { 1354 return TRUNNEL_DYNARRAY_GET(&inp->pad, idx); 1355 } 1356 1357 uint8_t 1358 trn_cell_introduce_encrypted_getconst_pad(const trn_cell_introduce_encrypted_t *inp, size_t idx) 1359 { 1360 return trn_cell_introduce_encrypted_get_pad((trn_cell_introduce_encrypted_t*)inp, idx); 1361 } 1362 int 1363 trn_cell_introduce_encrypted_set_pad(trn_cell_introduce_encrypted_t *inp, size_t idx, uint8_t elt) 1364 { 1365 TRUNNEL_DYNARRAY_SET(&inp->pad, idx, elt); 1366 return 0; 1367 } 1368 int 1369 trn_cell_introduce_encrypted_add_pad(trn_cell_introduce_encrypted_t *inp, uint8_t elt) 1370 { 1371 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->pad, elt, {}); 1372 return 0; 1373 trunnel_alloc_failed: 1374 TRUNNEL_SET_ERROR_CODE(inp); 1375 return -1; 1376 } 1377 1378 uint8_t * 1379 trn_cell_introduce_encrypted_getarray_pad(trn_cell_introduce_encrypted_t *inp) 1380 { 1381 return inp->pad.elts_; 1382 } 1383 const uint8_t * 1384 trn_cell_introduce_encrypted_getconstarray_pad(const trn_cell_introduce_encrypted_t *inp) 1385 { 1386 return (const uint8_t *)trn_cell_introduce_encrypted_getarray_pad((trn_cell_introduce_encrypted_t*)inp); 1387 } 1388 int 1389 trn_cell_introduce_encrypted_setlen_pad(trn_cell_introduce_encrypted_t *inp, size_t newlen) 1390 { 1391 uint8_t *newptr; 1392 newptr = trunnel_dynarray_setlen(&inp->pad.allocated_, 1393 &inp->pad.n_, inp->pad.elts_, newlen, 1394 sizeof(inp->pad.elts_[0]), (trunnel_free_fn_t) NULL, 1395 &inp->trunnel_error_code_); 1396 if (newlen != 0 && newptr == NULL) 1397 goto trunnel_alloc_failed; 1398 inp->pad.elts_ = newptr; 1399 return 0; 1400 trunnel_alloc_failed: 1401 TRUNNEL_SET_ERROR_CODE(inp); 1402 return -1; 1403 } 1404 const char * 1405 trn_cell_introduce_encrypted_check(const trn_cell_introduce_encrypted_t *obj) 1406 { 1407 if (obj == NULL) 1408 return "Object was NULL"; 1409 if (obj->trunnel_error_code_) 1410 return "A set function failed on this object"; 1411 { 1412 const char *msg; 1413 if (NULL != (msg = trn_extension_check(obj->extensions))) 1414 return msg; 1415 } 1416 if (! (obj->onion_key_type == TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR)) 1417 return "Integer out of bounds"; 1418 if (TRUNNEL_DYNARRAY_LEN(&obj->onion_key) != obj->onion_key_len) 1419 return "Length mismatch for onion_key"; 1420 { 1421 const char *msg; 1422 1423 unsigned idx; 1424 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->nspecs); ++idx) { 1425 if (NULL != (msg = link_specifier_check(TRUNNEL_DYNARRAY_GET(&obj->nspecs, idx)))) 1426 return msg; 1427 } 1428 } 1429 if (TRUNNEL_DYNARRAY_LEN(&obj->nspecs) != obj->nspec) 1430 return "Length mismatch for nspecs"; 1431 return NULL; 1432 } 1433 1434 ssize_t 1435 trn_cell_introduce_encrypted_encoded_len(const trn_cell_introduce_encrypted_t *obj) 1436 { 1437 ssize_t result = 0; 1438 1439 if (NULL != trn_cell_introduce_encrypted_check(obj)) 1440 return -1; 1441 1442 1443 /* Length of u8 rend_cookie[TRUNNEL_REND_COOKIE_LEN] */ 1444 result += TRUNNEL_REND_COOKIE_LEN; 1445 1446 /* Length of struct trn_extension extensions */ 1447 result += trn_extension_encoded_len(obj->extensions); 1448 1449 /* Length of u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR] */ 1450 result += 1; 1451 1452 /* Length of u16 onion_key_len */ 1453 result += 2; 1454 1455 /* Length of u8 onion_key[onion_key_len] */ 1456 result += TRUNNEL_DYNARRAY_LEN(&obj->onion_key); 1457 1458 /* Length of u8 nspec */ 1459 result += 1; 1460 1461 /* Length of struct link_specifier nspecs[nspec] */ 1462 { 1463 1464 unsigned idx; 1465 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->nspecs); ++idx) { 1466 result += link_specifier_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->nspecs, idx)); 1467 } 1468 } 1469 1470 /* Length of u8 pad[] */ 1471 result += TRUNNEL_DYNARRAY_LEN(&obj->pad); 1472 return result; 1473 } 1474 int 1475 trn_cell_introduce_encrypted_clear_errors(trn_cell_introduce_encrypted_t *obj) 1476 { 1477 int r = obj->trunnel_error_code_; 1478 obj->trunnel_error_code_ = 0; 1479 return r; 1480 } 1481 ssize_t 1482 trn_cell_introduce_encrypted_encode(uint8_t *output, const size_t avail, const trn_cell_introduce_encrypted_t *obj) 1483 { 1484 ssize_t result = 0; 1485 size_t written = 0; 1486 uint8_t *ptr = output; 1487 const char *msg; 1488 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1489 const ssize_t encoded_len = trn_cell_introduce_encrypted_encoded_len(obj); 1490 #endif 1491 1492 if (NULL != (msg = trn_cell_introduce_encrypted_check(obj))) 1493 goto check_failed; 1494 1495 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1496 trunnel_assert(encoded_len >= 0); 1497 #endif 1498 1499 /* Encode u8 rend_cookie[TRUNNEL_REND_COOKIE_LEN] */ 1500 trunnel_assert(written <= avail); 1501 if (avail - written < TRUNNEL_REND_COOKIE_LEN) 1502 goto truncated; 1503 memcpy(ptr, obj->rend_cookie, TRUNNEL_REND_COOKIE_LEN); 1504 written += TRUNNEL_REND_COOKIE_LEN; ptr += TRUNNEL_REND_COOKIE_LEN; 1505 1506 /* Encode struct trn_extension extensions */ 1507 trunnel_assert(written <= avail); 1508 result = trn_extension_encode(ptr, avail - written, obj->extensions); 1509 if (result < 0) 1510 goto fail; /* XXXXXXX !*/ 1511 written += result; ptr += result; 1512 1513 /* Encode u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR] */ 1514 trunnel_assert(written <= avail); 1515 if (avail - written < 1) 1516 goto truncated; 1517 trunnel_set_uint8(ptr, (obj->onion_key_type)); 1518 written += 1; ptr += 1; 1519 1520 /* Encode u16 onion_key_len */ 1521 trunnel_assert(written <= avail); 1522 if (avail - written < 2) 1523 goto truncated; 1524 trunnel_set_uint16(ptr, trunnel_htons(obj->onion_key_len)); 1525 written += 2; ptr += 2; 1526 1527 /* Encode u8 onion_key[onion_key_len] */ 1528 { 1529 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->onion_key); 1530 trunnel_assert(obj->onion_key_len == elt_len); 1531 trunnel_assert(written <= avail); 1532 if (avail - written < elt_len) 1533 goto truncated; 1534 if (elt_len) 1535 memcpy(ptr, obj->onion_key.elts_, elt_len); 1536 written += elt_len; ptr += elt_len; 1537 } 1538 1539 /* Encode u8 nspec */ 1540 trunnel_assert(written <= avail); 1541 if (avail - written < 1) 1542 goto truncated; 1543 trunnel_set_uint8(ptr, (obj->nspec)); 1544 written += 1; ptr += 1; 1545 1546 /* Encode struct link_specifier nspecs[nspec] */ 1547 { 1548 1549 unsigned idx; 1550 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->nspecs); ++idx) { 1551 trunnel_assert(written <= avail); 1552 result = link_specifier_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->nspecs, idx)); 1553 if (result < 0) 1554 goto fail; /* XXXXXXX !*/ 1555 written += result; ptr += result; 1556 } 1557 } 1558 1559 /* Encode u8 pad[] */ 1560 { 1561 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->pad); 1562 trunnel_assert(written <= avail); 1563 if (avail - written < elt_len) 1564 goto truncated; 1565 if (elt_len) 1566 memcpy(ptr, obj->pad.elts_, elt_len); 1567 written += elt_len; ptr += elt_len; 1568 } 1569 1570 1571 trunnel_assert(ptr == output + written); 1572 #ifdef TRUNNEL_CHECK_ENCODED_LEN 1573 { 1574 trunnel_assert(encoded_len >= 0); 1575 trunnel_assert((size_t)encoded_len == written); 1576 } 1577 1578 #endif 1579 1580 return written; 1581 1582 truncated: 1583 result = -2; 1584 goto fail; 1585 check_failed: 1586 (void)msg; 1587 result = -1; 1588 goto fail; 1589 fail: 1590 trunnel_assert(result < 0); 1591 return result; 1592 } 1593 1594 /** As trn_cell_introduce_encrypted_parse(), but do not allocate the 1595 * output object. 1596 */ 1597 static ssize_t 1598 trn_cell_introduce_encrypted_parse_into(trn_cell_introduce_encrypted_t *obj, const uint8_t *input, const size_t len_in) 1599 { 1600 const uint8_t *ptr = input; 1601 size_t remaining = len_in; 1602 ssize_t result = 0; 1603 (void)result; 1604 1605 /* Parse u8 rend_cookie[TRUNNEL_REND_COOKIE_LEN] */ 1606 CHECK_REMAINING(TRUNNEL_REND_COOKIE_LEN, truncated); 1607 memcpy(obj->rend_cookie, ptr, TRUNNEL_REND_COOKIE_LEN); 1608 remaining -= TRUNNEL_REND_COOKIE_LEN; ptr += TRUNNEL_REND_COOKIE_LEN; 1609 1610 /* Parse struct trn_extension extensions */ 1611 result = trn_extension_parse(&obj->extensions, ptr, remaining); 1612 if (result < 0) 1613 goto relay_fail; 1614 trunnel_assert((size_t)result <= remaining); 1615 remaining -= result; ptr += result; 1616 1617 /* Parse u8 onion_key_type IN [TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR] */ 1618 CHECK_REMAINING(1, truncated); 1619 obj->onion_key_type = (trunnel_get_uint8(ptr)); 1620 remaining -= 1; ptr += 1; 1621 if (! (obj->onion_key_type == TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR)) 1622 goto fail; 1623 1624 /* Parse u16 onion_key_len */ 1625 CHECK_REMAINING(2, truncated); 1626 obj->onion_key_len = trunnel_ntohs(trunnel_get_uint16(ptr)); 1627 remaining -= 2; ptr += 2; 1628 1629 /* Parse u8 onion_key[onion_key_len] */ 1630 CHECK_REMAINING(obj->onion_key_len, truncated); 1631 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->onion_key, obj->onion_key_len, {}); 1632 obj->onion_key.n_ = obj->onion_key_len; 1633 if (obj->onion_key_len) 1634 memcpy(obj->onion_key.elts_, ptr, obj->onion_key_len); 1635 ptr += obj->onion_key_len; remaining -= obj->onion_key_len; 1636 1637 /* Parse u8 nspec */ 1638 CHECK_REMAINING(1, truncated); 1639 obj->nspec = (trunnel_get_uint8(ptr)); 1640 remaining -= 1; ptr += 1; 1641 1642 /* Parse struct link_specifier nspecs[nspec] */ 1643 TRUNNEL_DYNARRAY_EXPAND(link_specifier_t *, &obj->nspecs, obj->nspec, {}); 1644 { 1645 link_specifier_t * elt; 1646 unsigned idx; 1647 for (idx = 0; idx < obj->nspec; ++idx) { 1648 result = link_specifier_parse(&elt, ptr, remaining); 1649 if (result < 0) 1650 goto relay_fail; 1651 trunnel_assert((size_t)result <= remaining); 1652 remaining -= result; ptr += result; 1653 TRUNNEL_DYNARRAY_ADD(link_specifier_t *, &obj->nspecs, elt, {link_specifier_free(elt);}); 1654 } 1655 } 1656 1657 /* Parse u8 pad[] */ 1658 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->pad, remaining, {}); 1659 obj->pad.n_ = remaining; 1660 if (remaining) 1661 memcpy(obj->pad.elts_, ptr, remaining); 1662 ptr += remaining; remaining -= remaining; 1663 trunnel_assert(ptr + remaining == input + len_in); 1664 return len_in - remaining; 1665 1666 truncated: 1667 return -2; 1668 relay_fail: 1669 trunnel_assert(result < 0); 1670 return result; 1671 trunnel_alloc_failed: 1672 return -1; 1673 fail: 1674 result = -1; 1675 return result; 1676 } 1677 1678 ssize_t 1679 trn_cell_introduce_encrypted_parse(trn_cell_introduce_encrypted_t **output, const uint8_t *input, const size_t len_in) 1680 { 1681 ssize_t result; 1682 *output = trn_cell_introduce_encrypted_new(); 1683 if (NULL == *output) 1684 return -1; 1685 result = trn_cell_introduce_encrypted_parse_into(*output, input, len_in); 1686 if (result < 0) { 1687 trn_cell_introduce_encrypted_free(*output); 1688 *output = NULL; 1689 } 1690 return result; 1691 }