cell_establish_intro.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. /* cell_establish_intro.c -- generated by Trunnel v1.5.1.
  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. #include "cell_establish_intro.h"
  8. #define TRUNNEL_SET_ERROR_CODE(obj) \
  9. do { \
  10. (obj)->trunnel_error_code_ = 1; \
  11. } while (0)
  12. #if defined(__COVERITY__) || defined(__clang_analyzer__)
  13. /* If we're runnning a static analysis tool, we don't want it to complain
  14. * that some of our remaining-bytes checks are dead-code. */
  15. int cellestablishintro_deadcode_dummy__ = 0;
  16. #define OR_DEADCODE_DUMMY || cellestablishintro_deadcode_dummy__
  17. #else
  18. #define OR_DEADCODE_DUMMY
  19. #endif
  20. #define CHECK_REMAINING(nbytes, label) \
  21. do { \
  22. if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
  23. goto label; \
  24. } \
  25. } while (0)
  26. typedef struct trn_cell_extension_st trn_cell_extension_t;
  27. trn_cell_extension_t *trn_cell_extension_new(void);
  28. void trn_cell_extension_free(trn_cell_extension_t *victim);
  29. ssize_t trn_cell_extension_parse(trn_cell_extension_t **output, const uint8_t *input, const size_t len_in);
  30. ssize_t trn_cell_extension_encoded_len(const trn_cell_extension_t *obj);
  31. ssize_t trn_cell_extension_encode(uint8_t *output, size_t avail, const trn_cell_extension_t *input);
  32. const char *trn_cell_extension_check(const trn_cell_extension_t *obj);
  33. int trn_cell_extension_clear_errors(trn_cell_extension_t *obj);
  34. trn_cell_establish_intro_t *
  35. trn_cell_establish_intro_new(void)
  36. {
  37. trn_cell_establish_intro_t *val = trunnel_calloc(1, sizeof(trn_cell_establish_intro_t));
  38. if (NULL == val)
  39. return NULL;
  40. return val;
  41. }
  42. /** Release all storage held inside 'obj', but do not free 'obj'.
  43. */
  44. static void
  45. trn_cell_establish_intro_clear(trn_cell_establish_intro_t *obj)
  46. {
  47. (void) obj;
  48. TRUNNEL_DYNARRAY_WIPE(&obj->auth_key);
  49. TRUNNEL_DYNARRAY_CLEAR(&obj->auth_key);
  50. trn_cell_extension_free(obj->extensions);
  51. obj->extensions = NULL;
  52. TRUNNEL_DYNARRAY_WIPE(&obj->sig);
  53. TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
  54. }
  55. void
  56. trn_cell_establish_intro_free(trn_cell_establish_intro_t *obj)
  57. {
  58. if (obj == NULL)
  59. return;
  60. trn_cell_establish_intro_clear(obj);
  61. trunnel_memwipe(obj, sizeof(trn_cell_establish_intro_t));
  62. trunnel_free_(obj);
  63. }
  64. const uint8_t *
  65. trn_cell_establish_intro_get_start_cell(const trn_cell_establish_intro_t *inp)
  66. {
  67. return inp->start_cell;
  68. }
  69. uint8_t
  70. trn_cell_establish_intro_get_auth_key_type(const trn_cell_establish_intro_t *inp)
  71. {
  72. return inp->auth_key_type;
  73. }
  74. int
  75. trn_cell_establish_intro_set_auth_key_type(trn_cell_establish_intro_t *inp, uint8_t val)
  76. {
  77. if (! ((val == 0 || val == 1 || val == 2))) {
  78. TRUNNEL_SET_ERROR_CODE(inp);
  79. return -1;
  80. }
  81. inp->auth_key_type = val;
  82. return 0;
  83. }
  84. uint16_t
  85. trn_cell_establish_intro_get_auth_key_len(const trn_cell_establish_intro_t *inp)
  86. {
  87. return inp->auth_key_len;
  88. }
  89. int
  90. trn_cell_establish_intro_set_auth_key_len(trn_cell_establish_intro_t *inp, uint16_t val)
  91. {
  92. inp->auth_key_len = val;
  93. return 0;
  94. }
  95. size_t
  96. trn_cell_establish_intro_getlen_auth_key(const trn_cell_establish_intro_t *inp)
  97. {
  98. return TRUNNEL_DYNARRAY_LEN(&inp->auth_key);
  99. }
  100. uint8_t
  101. trn_cell_establish_intro_get_auth_key(trn_cell_establish_intro_t *inp, size_t idx)
  102. {
  103. return TRUNNEL_DYNARRAY_GET(&inp->auth_key, idx);
  104. }
  105. uint8_t
  106. trn_cell_establish_intro_getconst_auth_key(const trn_cell_establish_intro_t *inp, size_t idx)
  107. {
  108. return trn_cell_establish_intro_get_auth_key((trn_cell_establish_intro_t*)inp, idx);
  109. }
  110. int
  111. trn_cell_establish_intro_set_auth_key(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt)
  112. {
  113. TRUNNEL_DYNARRAY_SET(&inp->auth_key, idx, elt);
  114. return 0;
  115. }
  116. int
  117. trn_cell_establish_intro_add_auth_key(trn_cell_establish_intro_t *inp, uint8_t elt)
  118. {
  119. #if SIZE_MAX >= UINT16_MAX
  120. if (inp->auth_key.n_ == UINT16_MAX)
  121. goto trunnel_alloc_failed;
  122. #endif
  123. TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->auth_key, elt, {});
  124. return 0;
  125. trunnel_alloc_failed:
  126. TRUNNEL_SET_ERROR_CODE(inp);
  127. return -1;
  128. }
  129. uint8_t *
  130. trn_cell_establish_intro_getarray_auth_key(trn_cell_establish_intro_t *inp)
  131. {
  132. return inp->auth_key.elts_;
  133. }
  134. const uint8_t *
  135. trn_cell_establish_intro_getconstarray_auth_key(const trn_cell_establish_intro_t *inp)
  136. {
  137. return (const uint8_t *)trn_cell_establish_intro_getarray_auth_key((trn_cell_establish_intro_t*)inp);
  138. }
  139. int
  140. trn_cell_establish_intro_setlen_auth_key(trn_cell_establish_intro_t *inp, size_t newlen)
  141. {
  142. uint8_t *newptr;
  143. #if UINT16_MAX < SIZE_MAX
  144. if (newlen > UINT16_MAX)
  145. goto trunnel_alloc_failed;
  146. #endif
  147. newptr = trunnel_dynarray_setlen(&inp->auth_key.allocated_,
  148. &inp->auth_key.n_, inp->auth_key.elts_, newlen,
  149. sizeof(inp->auth_key.elts_[0]), (trunnel_free_fn_t) NULL,
  150. &inp->trunnel_error_code_);
  151. if (newlen != 0 && newptr == NULL)
  152. goto trunnel_alloc_failed;
  153. inp->auth_key.elts_ = newptr;
  154. return 0;
  155. trunnel_alloc_failed:
  156. TRUNNEL_SET_ERROR_CODE(inp);
  157. return -1;
  158. }
  159. struct trn_cell_extension_st *
  160. trn_cell_establish_intro_get_extensions(trn_cell_establish_intro_t *inp)
  161. {
  162. return inp->extensions;
  163. }
  164. const struct trn_cell_extension_st *
  165. trn_cell_establish_intro_getconst_extensions(const trn_cell_establish_intro_t *inp)
  166. {
  167. return trn_cell_establish_intro_get_extensions((trn_cell_establish_intro_t*) inp);
  168. }
  169. int
  170. trn_cell_establish_intro_set_extensions(trn_cell_establish_intro_t *inp, struct trn_cell_extension_st *val)
  171. {
  172. if (inp->extensions && inp->extensions != val)
  173. trn_cell_extension_free(inp->extensions);
  174. return trn_cell_establish_intro_set0_extensions(inp, val);
  175. }
  176. int
  177. trn_cell_establish_intro_set0_extensions(trn_cell_establish_intro_t *inp, struct trn_cell_extension_st *val)
  178. {
  179. inp->extensions = val;
  180. return 0;
  181. }
  182. const uint8_t *
  183. trn_cell_establish_intro_get_end_mac_fields(const trn_cell_establish_intro_t *inp)
  184. {
  185. return inp->end_mac_fields;
  186. }
  187. size_t
  188. trn_cell_establish_intro_getlen_handshake_mac(const trn_cell_establish_intro_t *inp)
  189. {
  190. (void)inp; return TRUNNEL_SHA3_256_LEN;
  191. }
  192. uint8_t
  193. trn_cell_establish_intro_get_handshake_mac(trn_cell_establish_intro_t *inp, size_t idx)
  194. {
  195. trunnel_assert(idx < TRUNNEL_SHA3_256_LEN);
  196. return inp->handshake_mac[idx];
  197. }
  198. uint8_t
  199. trn_cell_establish_intro_getconst_handshake_mac(const trn_cell_establish_intro_t *inp, size_t idx)
  200. {
  201. return trn_cell_establish_intro_get_handshake_mac((trn_cell_establish_intro_t*)inp, idx);
  202. }
  203. int
  204. trn_cell_establish_intro_set_handshake_mac(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt)
  205. {
  206. trunnel_assert(idx < TRUNNEL_SHA3_256_LEN);
  207. inp->handshake_mac[idx] = elt;
  208. return 0;
  209. }
  210. uint8_t *
  211. trn_cell_establish_intro_getarray_handshake_mac(trn_cell_establish_intro_t *inp)
  212. {
  213. return inp->handshake_mac;
  214. }
  215. const uint8_t *
  216. trn_cell_establish_intro_getconstarray_handshake_mac(const trn_cell_establish_intro_t *inp)
  217. {
  218. return (const uint8_t *)trn_cell_establish_intro_getarray_handshake_mac((trn_cell_establish_intro_t*)inp);
  219. }
  220. const uint8_t *
  221. trn_cell_establish_intro_get_end_sig_fields(const trn_cell_establish_intro_t *inp)
  222. {
  223. return inp->end_sig_fields;
  224. }
  225. uint16_t
  226. trn_cell_establish_intro_get_sig_len(const trn_cell_establish_intro_t *inp)
  227. {
  228. return inp->sig_len;
  229. }
  230. int
  231. trn_cell_establish_intro_set_sig_len(trn_cell_establish_intro_t *inp, uint16_t val)
  232. {
  233. inp->sig_len = val;
  234. return 0;
  235. }
  236. size_t
  237. trn_cell_establish_intro_getlen_sig(const trn_cell_establish_intro_t *inp)
  238. {
  239. return TRUNNEL_DYNARRAY_LEN(&inp->sig);
  240. }
  241. uint8_t
  242. trn_cell_establish_intro_get_sig(trn_cell_establish_intro_t *inp, size_t idx)
  243. {
  244. return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
  245. }
  246. uint8_t
  247. trn_cell_establish_intro_getconst_sig(const trn_cell_establish_intro_t *inp, size_t idx)
  248. {
  249. return trn_cell_establish_intro_get_sig((trn_cell_establish_intro_t*)inp, idx);
  250. }
  251. int
  252. trn_cell_establish_intro_set_sig(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt)
  253. {
  254. TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
  255. return 0;
  256. }
  257. int
  258. trn_cell_establish_intro_add_sig(trn_cell_establish_intro_t *inp, uint8_t elt)
  259. {
  260. #if SIZE_MAX >= UINT16_MAX
  261. if (inp->sig.n_ == UINT16_MAX)
  262. goto trunnel_alloc_failed;
  263. #endif
  264. TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
  265. return 0;
  266. trunnel_alloc_failed:
  267. TRUNNEL_SET_ERROR_CODE(inp);
  268. return -1;
  269. }
  270. uint8_t *
  271. trn_cell_establish_intro_getarray_sig(trn_cell_establish_intro_t *inp)
  272. {
  273. return inp->sig.elts_;
  274. }
  275. const uint8_t *
  276. trn_cell_establish_intro_getconstarray_sig(const trn_cell_establish_intro_t *inp)
  277. {
  278. return (const uint8_t *)trn_cell_establish_intro_getarray_sig((trn_cell_establish_intro_t*)inp);
  279. }
  280. int
  281. trn_cell_establish_intro_setlen_sig(trn_cell_establish_intro_t *inp, size_t newlen)
  282. {
  283. uint8_t *newptr;
  284. #if UINT16_MAX < SIZE_MAX
  285. if (newlen > UINT16_MAX)
  286. goto trunnel_alloc_failed;
  287. #endif
  288. newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
  289. &inp->sig.n_, inp->sig.elts_, newlen,
  290. sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
  291. &inp->trunnel_error_code_);
  292. if (newlen != 0 && newptr == NULL)
  293. goto trunnel_alloc_failed;
  294. inp->sig.elts_ = newptr;
  295. return 0;
  296. trunnel_alloc_failed:
  297. TRUNNEL_SET_ERROR_CODE(inp);
  298. return -1;
  299. }
  300. const char *
  301. trn_cell_establish_intro_check(const trn_cell_establish_intro_t *obj)
  302. {
  303. if (obj == NULL)
  304. return "Object was NULL";
  305. if (obj->trunnel_error_code_)
  306. return "A set function failed on this object";
  307. if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2))
  308. return "Integer out of bounds";
  309. if (TRUNNEL_DYNARRAY_LEN(&obj->auth_key) != obj->auth_key_len)
  310. return "Length mismatch for auth_key";
  311. {
  312. const char *msg;
  313. if (NULL != (msg = trn_cell_extension_check(obj->extensions)))
  314. return msg;
  315. }
  316. if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len)
  317. return "Length mismatch for sig";
  318. return NULL;
  319. }
  320. ssize_t
  321. trn_cell_establish_intro_encoded_len(const trn_cell_establish_intro_t *obj)
  322. {
  323. ssize_t result = 0;
  324. if (NULL != trn_cell_establish_intro_check(obj))
  325. return -1;
  326. /* Length of u8 auth_key_type IN [0, 1, 2] */
  327. result += 1;
  328. /* Length of u16 auth_key_len */
  329. result += 2;
  330. /* Length of u8 auth_key[auth_key_len] */
  331. result += TRUNNEL_DYNARRAY_LEN(&obj->auth_key);
  332. /* Length of struct trn_cell_extension extensions */
  333. result += trn_cell_extension_encoded_len(obj->extensions);
  334. /* Length of u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */
  335. result += TRUNNEL_SHA3_256_LEN;
  336. /* Length of u16 sig_len */
  337. result += 2;
  338. /* Length of u8 sig[sig_len] */
  339. result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
  340. return result;
  341. }
  342. int
  343. trn_cell_establish_intro_clear_errors(trn_cell_establish_intro_t *obj)
  344. {
  345. int r = obj->trunnel_error_code_;
  346. obj->trunnel_error_code_ = 0;
  347. return r;
  348. }
  349. ssize_t
  350. trn_cell_establish_intro_encode(uint8_t *output, const size_t avail, const trn_cell_establish_intro_t *obj)
  351. {
  352. ssize_t result = 0;
  353. size_t written = 0;
  354. uint8_t *ptr = output;
  355. const char *msg;
  356. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  357. const ssize_t encoded_len = trn_cell_establish_intro_encoded_len(obj);
  358. #endif
  359. if (NULL != (msg = trn_cell_establish_intro_check(obj)))
  360. goto check_failed;
  361. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  362. trunnel_assert(encoded_len >= 0);
  363. #endif
  364. /* Encode u8 auth_key_type IN [0, 1, 2] */
  365. trunnel_assert(written <= avail);
  366. if (avail - written < 1)
  367. goto truncated;
  368. trunnel_set_uint8(ptr, (obj->auth_key_type));
  369. written += 1; ptr += 1;
  370. /* Encode u16 auth_key_len */
  371. trunnel_assert(written <= avail);
  372. if (avail - written < 2)
  373. goto truncated;
  374. trunnel_set_uint16(ptr, trunnel_htons(obj->auth_key_len));
  375. written += 2; ptr += 2;
  376. /* Encode u8 auth_key[auth_key_len] */
  377. {
  378. size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->auth_key);
  379. trunnel_assert(obj->auth_key_len == elt_len);
  380. trunnel_assert(written <= avail);
  381. if (avail - written < elt_len)
  382. goto truncated;
  383. if (elt_len)
  384. memcpy(ptr, obj->auth_key.elts_, elt_len);
  385. written += elt_len; ptr += elt_len;
  386. }
  387. /* Encode struct trn_cell_extension extensions */
  388. trunnel_assert(written <= avail);
  389. result = trn_cell_extension_encode(ptr, avail - written, obj->extensions);
  390. if (result < 0)
  391. goto fail; /* XXXXXXX !*/
  392. written += result; ptr += result;
  393. /* Encode u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */
  394. trunnel_assert(written <= avail);
  395. if (avail - written < TRUNNEL_SHA3_256_LEN)
  396. goto truncated;
  397. memcpy(ptr, obj->handshake_mac, TRUNNEL_SHA3_256_LEN);
  398. written += TRUNNEL_SHA3_256_LEN; ptr += TRUNNEL_SHA3_256_LEN;
  399. /* Encode u16 sig_len */
  400. trunnel_assert(written <= avail);
  401. if (avail - written < 2)
  402. goto truncated;
  403. trunnel_set_uint16(ptr, trunnel_htons(obj->sig_len));
  404. written += 2; ptr += 2;
  405. /* Encode u8 sig[sig_len] */
  406. {
  407. size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
  408. trunnel_assert(obj->sig_len == elt_len);
  409. trunnel_assert(written <= avail);
  410. if (avail - written < elt_len)
  411. goto truncated;
  412. if (elt_len)
  413. memcpy(ptr, obj->sig.elts_, elt_len);
  414. written += elt_len; ptr += elt_len;
  415. }
  416. trunnel_assert(ptr == output + written);
  417. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  418. {
  419. trunnel_assert(encoded_len >= 0);
  420. trunnel_assert((size_t)encoded_len == written);
  421. }
  422. #endif
  423. return written;
  424. truncated:
  425. result = -2;
  426. goto fail;
  427. check_failed:
  428. (void)msg;
  429. result = -1;
  430. goto fail;
  431. fail:
  432. trunnel_assert(result < 0);
  433. return result;
  434. }
  435. /** As trn_cell_establish_intro_parse(), but do not allocate the
  436. * output object.
  437. */
  438. static ssize_t
  439. trn_cell_establish_intro_parse_into(trn_cell_establish_intro_t *obj, const uint8_t *input, const size_t len_in)
  440. {
  441. const uint8_t *ptr = input;
  442. size_t remaining = len_in;
  443. ssize_t result = 0;
  444. (void)result;
  445. obj->start_cell = ptr;
  446. /* Parse u8 auth_key_type IN [0, 1, 2] */
  447. CHECK_REMAINING(1, truncated);
  448. obj->auth_key_type = (trunnel_get_uint8(ptr));
  449. remaining -= 1; ptr += 1;
  450. if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2))
  451. goto fail;
  452. /* Parse u16 auth_key_len */
  453. CHECK_REMAINING(2, truncated);
  454. obj->auth_key_len = trunnel_ntohs(trunnel_get_uint16(ptr));
  455. remaining -= 2; ptr += 2;
  456. /* Parse u8 auth_key[auth_key_len] */
  457. CHECK_REMAINING(obj->auth_key_len, truncated);
  458. TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->auth_key, obj->auth_key_len, {});
  459. obj->auth_key.n_ = obj->auth_key_len;
  460. if (obj->auth_key_len)
  461. memcpy(obj->auth_key.elts_, ptr, obj->auth_key_len);
  462. ptr += obj->auth_key_len; remaining -= obj->auth_key_len;
  463. /* Parse struct trn_cell_extension extensions */
  464. result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
  465. if (result < 0)
  466. goto relay_fail;
  467. trunnel_assert((size_t)result <= remaining);
  468. remaining -= result; ptr += result;
  469. obj->end_mac_fields = ptr;
  470. /* Parse u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */
  471. CHECK_REMAINING(TRUNNEL_SHA3_256_LEN, truncated);
  472. memcpy(obj->handshake_mac, ptr, TRUNNEL_SHA3_256_LEN);
  473. remaining -= TRUNNEL_SHA3_256_LEN; ptr += TRUNNEL_SHA3_256_LEN;
  474. obj->end_sig_fields = ptr;
  475. /* Parse u16 sig_len */
  476. CHECK_REMAINING(2, truncated);
  477. obj->sig_len = trunnel_ntohs(trunnel_get_uint16(ptr));
  478. remaining -= 2; ptr += 2;
  479. /* Parse u8 sig[sig_len] */
  480. CHECK_REMAINING(obj->sig_len, truncated);
  481. TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
  482. obj->sig.n_ = obj->sig_len;
  483. if (obj->sig_len)
  484. memcpy(obj->sig.elts_, ptr, obj->sig_len);
  485. ptr += obj->sig_len; remaining -= obj->sig_len;
  486. trunnel_assert(ptr + remaining == input + len_in);
  487. return len_in - remaining;
  488. truncated:
  489. return -2;
  490. relay_fail:
  491. trunnel_assert(result < 0);
  492. return result;
  493. trunnel_alloc_failed:
  494. return -1;
  495. fail:
  496. result = -1;
  497. return result;
  498. }
  499. ssize_t
  500. trn_cell_establish_intro_parse(trn_cell_establish_intro_t **output, const uint8_t *input, const size_t len_in)
  501. {
  502. ssize_t result;
  503. *output = trn_cell_establish_intro_new();
  504. if (NULL == *output)
  505. return -1;
  506. result = trn_cell_establish_intro_parse_into(*output, input, len_in);
  507. if (result < 0) {
  508. trn_cell_establish_intro_free(*output);
  509. *output = NULL;
  510. }
  511. return result;
  512. }
  513. trn_cell_intro_established_t *
  514. trn_cell_intro_established_new(void)
  515. {
  516. trn_cell_intro_established_t *val = trunnel_calloc(1, sizeof(trn_cell_intro_established_t));
  517. if (NULL == val)
  518. return NULL;
  519. return val;
  520. }
  521. /** Release all storage held inside 'obj', but do not free 'obj'.
  522. */
  523. static void
  524. trn_cell_intro_established_clear(trn_cell_intro_established_t *obj)
  525. {
  526. (void) obj;
  527. trn_cell_extension_free(obj->extensions);
  528. obj->extensions = NULL;
  529. }
  530. void
  531. trn_cell_intro_established_free(trn_cell_intro_established_t *obj)
  532. {
  533. if (obj == NULL)
  534. return;
  535. trn_cell_intro_established_clear(obj);
  536. trunnel_memwipe(obj, sizeof(trn_cell_intro_established_t));
  537. trunnel_free_(obj);
  538. }
  539. struct trn_cell_extension_st *
  540. trn_cell_intro_established_get_extensions(trn_cell_intro_established_t *inp)
  541. {
  542. return inp->extensions;
  543. }
  544. const struct trn_cell_extension_st *
  545. trn_cell_intro_established_getconst_extensions(const trn_cell_intro_established_t *inp)
  546. {
  547. return trn_cell_intro_established_get_extensions((trn_cell_intro_established_t*) inp);
  548. }
  549. int
  550. trn_cell_intro_established_set_extensions(trn_cell_intro_established_t *inp, struct trn_cell_extension_st *val)
  551. {
  552. if (inp->extensions && inp->extensions != val)
  553. trn_cell_extension_free(inp->extensions);
  554. return trn_cell_intro_established_set0_extensions(inp, val);
  555. }
  556. int
  557. trn_cell_intro_established_set0_extensions(trn_cell_intro_established_t *inp, struct trn_cell_extension_st *val)
  558. {
  559. inp->extensions = val;
  560. return 0;
  561. }
  562. const char *
  563. trn_cell_intro_established_check(const trn_cell_intro_established_t *obj)
  564. {
  565. if (obj == NULL)
  566. return "Object was NULL";
  567. if (obj->trunnel_error_code_)
  568. return "A set function failed on this object";
  569. {
  570. const char *msg;
  571. if (NULL != (msg = trn_cell_extension_check(obj->extensions)))
  572. return msg;
  573. }
  574. return NULL;
  575. }
  576. ssize_t
  577. trn_cell_intro_established_encoded_len(const trn_cell_intro_established_t *obj)
  578. {
  579. ssize_t result = 0;
  580. if (NULL != trn_cell_intro_established_check(obj))
  581. return -1;
  582. /* Length of struct trn_cell_extension extensions */
  583. result += trn_cell_extension_encoded_len(obj->extensions);
  584. return result;
  585. }
  586. int
  587. trn_cell_intro_established_clear_errors(trn_cell_intro_established_t *obj)
  588. {
  589. int r = obj->trunnel_error_code_;
  590. obj->trunnel_error_code_ = 0;
  591. return r;
  592. }
  593. ssize_t
  594. trn_cell_intro_established_encode(uint8_t *output, const size_t avail, const trn_cell_intro_established_t *obj)
  595. {
  596. ssize_t result = 0;
  597. size_t written = 0;
  598. uint8_t *ptr = output;
  599. const char *msg;
  600. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  601. const ssize_t encoded_len = trn_cell_intro_established_encoded_len(obj);
  602. #endif
  603. if (NULL != (msg = trn_cell_intro_established_check(obj)))
  604. goto check_failed;
  605. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  606. trunnel_assert(encoded_len >= 0);
  607. #endif
  608. /* Encode struct trn_cell_extension extensions */
  609. trunnel_assert(written <= avail);
  610. result = trn_cell_extension_encode(ptr, avail - written, obj->extensions);
  611. if (result < 0)
  612. goto fail; /* XXXXXXX !*/
  613. written += result; ptr += result;
  614. trunnel_assert(ptr == output + written);
  615. #ifdef TRUNNEL_CHECK_ENCODED_LEN
  616. {
  617. trunnel_assert(encoded_len >= 0);
  618. trunnel_assert((size_t)encoded_len == written);
  619. }
  620. #endif
  621. return written;
  622. check_failed:
  623. (void)msg;
  624. result = -1;
  625. goto fail;
  626. fail:
  627. trunnel_assert(result < 0);
  628. return result;
  629. }
  630. /** As trn_cell_intro_established_parse(), but do not allocate the
  631. * output object.
  632. */
  633. static ssize_t
  634. trn_cell_intro_established_parse_into(trn_cell_intro_established_t *obj, const uint8_t *input, const size_t len_in)
  635. {
  636. const uint8_t *ptr = input;
  637. size_t remaining = len_in;
  638. ssize_t result = 0;
  639. (void)result;
  640. /* Parse struct trn_cell_extension extensions */
  641. result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
  642. if (result < 0)
  643. goto relay_fail;
  644. trunnel_assert((size_t)result <= remaining);
  645. remaining -= result; ptr += result;
  646. trunnel_assert(ptr + remaining == input + len_in);
  647. return len_in - remaining;
  648. relay_fail:
  649. trunnel_assert(result < 0);
  650. return result;
  651. }
  652. ssize_t
  653. trn_cell_intro_established_parse(trn_cell_intro_established_t **output, const uint8_t *input, const size_t len_in)
  654. {
  655. ssize_t result;
  656. *output = trn_cell_intro_established_new();
  657. if (NULL == *output)
  658. return -1;
  659. result = trn_cell_intro_established_parse_into(*output, input, len_in);
  660. if (result < 0) {
  661. trn_cell_intro_established_free(*output);
  662. *output = NULL;
  663. }
  664. return result;
  665. }