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