Merge branch 'maint-0.4.5' into maint-0.4.6
[tor.git] / src / trunnel / link_handshake.c
blob76db4b0e292881736bb33080a6c12e6d1a06afc1
1 /* link_handshake.c -- generated by Trunnel v1.5.3.
2 * https://gitweb.torproject.org/trunnel.git
3 * You probably shouldn't edit this file.
4 */
5 #include <stdlib.h>
6 #include "trunnel-impl.h"
8 #include "link_handshake.h"
10 #define TRUNNEL_SET_ERROR_CODE(obj) \
11 do { \
12 (obj)->trunnel_error_code_ = 1; \
13 } while (0)
15 #if defined(__COVERITY__) || defined(__clang_analyzer__)
16 /* If we're running a static analysis tool, we don't want it to complain
17 * that some of our remaining-bytes checks are dead-code. */
18 int linkhandshake_deadcode_dummy__ = 0;
19 #define OR_DEADCODE_DUMMY || linkhandshake_deadcode_dummy__
20 #else
21 #define OR_DEADCODE_DUMMY
22 #endif
24 #define CHECK_REMAINING(nbytes, label) \
25 do { \
26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
27 goto label; \
28 } \
29 } while (0)
31 auth_challenge_cell_t *
32 auth_challenge_cell_new(void)
34 auth_challenge_cell_t *val = trunnel_calloc(1, sizeof(auth_challenge_cell_t));
35 if (NULL == val)
36 return NULL;
37 return val;
40 /** Release all storage held inside 'obj', but do not free 'obj'.
42 static void
43 auth_challenge_cell_clear(auth_challenge_cell_t *obj)
45 (void) obj;
46 TRUNNEL_DYNARRAY_WIPE(&obj->methods);
47 TRUNNEL_DYNARRAY_CLEAR(&obj->methods);
50 void
51 auth_challenge_cell_free(auth_challenge_cell_t *obj)
53 if (obj == NULL)
54 return;
55 auth_challenge_cell_clear(obj);
56 trunnel_memwipe(obj, sizeof(auth_challenge_cell_t));
57 trunnel_free_(obj);
60 size_t
61 auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp)
63 (void)inp; return 32;
66 uint8_t
67 auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx)
69 trunnel_assert(idx < 32);
70 return inp->challenge[idx];
73 uint8_t
74 auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx)
76 return auth_challenge_cell_get_challenge((auth_challenge_cell_t*)inp, idx);
78 int
79 auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt)
81 trunnel_assert(idx < 32);
82 inp->challenge[idx] = elt;
83 return 0;
86 uint8_t *
87 auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp)
89 return inp->challenge;
91 const uint8_t *
92 auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp)
94 return (const uint8_t *)auth_challenge_cell_getarray_challenge((auth_challenge_cell_t*)inp);
96 uint16_t
97 auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp)
99 return inp->n_methods;
102 auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val)
104 inp->n_methods = val;
105 return 0;
107 size_t
108 auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp)
110 return TRUNNEL_DYNARRAY_LEN(&inp->methods);
113 uint16_t
114 auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx)
116 return TRUNNEL_DYNARRAY_GET(&inp->methods, idx);
119 uint16_t
120 auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx)
122 return auth_challenge_cell_get_methods((auth_challenge_cell_t*)inp, idx);
125 auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt)
127 TRUNNEL_DYNARRAY_SET(&inp->methods, idx, elt);
128 return 0;
131 auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt)
133 #if SIZE_MAX >= UINT16_MAX
134 if (inp->methods.n_ == UINT16_MAX)
135 goto trunnel_alloc_failed;
136 #endif
137 TRUNNEL_DYNARRAY_ADD(uint16_t, &inp->methods, elt, {});
138 return 0;
139 trunnel_alloc_failed:
140 TRUNNEL_SET_ERROR_CODE(inp);
141 return -1;
144 uint16_t *
145 auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp)
147 return inp->methods.elts_;
149 const uint16_t *
150 auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp)
152 return (const uint16_t *)auth_challenge_cell_getarray_methods((auth_challenge_cell_t*)inp);
155 auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen)
157 uint16_t *newptr;
158 #if UINT16_MAX < SIZE_MAX
159 if (newlen > UINT16_MAX)
160 goto trunnel_alloc_failed;
161 #endif
162 newptr = trunnel_dynarray_setlen(&inp->methods.allocated_,
163 &inp->methods.n_, inp->methods.elts_, newlen,
164 sizeof(inp->methods.elts_[0]), (trunnel_free_fn_t) NULL,
165 &inp->trunnel_error_code_);
166 if (newlen != 0 && newptr == NULL)
167 goto trunnel_alloc_failed;
168 inp->methods.elts_ = newptr;
169 return 0;
170 trunnel_alloc_failed:
171 TRUNNEL_SET_ERROR_CODE(inp);
172 return -1;
174 const char *
175 auth_challenge_cell_check(const auth_challenge_cell_t *obj)
177 if (obj == NULL)
178 return "Object was NULL";
179 if (obj->trunnel_error_code_)
180 return "A set function failed on this object";
181 if (TRUNNEL_DYNARRAY_LEN(&obj->methods) != obj->n_methods)
182 return "Length mismatch for methods";
183 return NULL;
186 ssize_t
187 auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj)
189 ssize_t result = 0;
191 if (NULL != auth_challenge_cell_check(obj))
192 return -1;
195 /* Length of u8 challenge[32] */
196 result += 32;
198 /* Length of u16 n_methods */
199 result += 2;
201 /* Length of u16 methods[n_methods] */
202 result += 2 * TRUNNEL_DYNARRAY_LEN(&obj->methods);
203 return result;
206 auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj)
208 int r = obj->trunnel_error_code_;
209 obj->trunnel_error_code_ = 0;
210 return r;
212 ssize_t
213 auth_challenge_cell_encode(uint8_t *output, const size_t avail, const auth_challenge_cell_t *obj)
215 ssize_t result = 0;
216 size_t written = 0;
217 uint8_t *ptr = output;
218 const char *msg;
219 #ifdef TRUNNEL_CHECK_ENCODED_LEN
220 const ssize_t encoded_len = auth_challenge_cell_encoded_len(obj);
221 #endif
223 if (NULL != (msg = auth_challenge_cell_check(obj)))
224 goto check_failed;
226 #ifdef TRUNNEL_CHECK_ENCODED_LEN
227 trunnel_assert(encoded_len >= 0);
228 #endif
230 /* Encode u8 challenge[32] */
231 trunnel_assert(written <= avail);
232 if (avail - written < 32)
233 goto truncated;
234 memcpy(ptr, obj->challenge, 32);
235 written += 32; ptr += 32;
237 /* Encode u16 n_methods */
238 trunnel_assert(written <= avail);
239 if (avail - written < 2)
240 goto truncated;
241 trunnel_set_uint16(ptr, trunnel_htons(obj->n_methods));
242 written += 2; ptr += 2;
244 /* Encode u16 methods[n_methods] */
247 unsigned idx;
248 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->methods); ++idx) {
249 trunnel_assert(written <= avail);
250 if (avail - written < 2)
251 goto truncated;
252 trunnel_set_uint16(ptr, trunnel_htons(TRUNNEL_DYNARRAY_GET(&obj->methods, idx)));
253 written += 2; ptr += 2;
258 trunnel_assert(ptr == output + written);
259 #ifdef TRUNNEL_CHECK_ENCODED_LEN
261 trunnel_assert(encoded_len >= 0);
262 trunnel_assert((size_t)encoded_len == written);
265 #endif
267 return written;
269 truncated:
270 result = -2;
271 goto fail;
272 check_failed:
273 (void)msg;
274 result = -1;
275 goto fail;
276 fail:
277 trunnel_assert(result < 0);
278 return result;
281 /** As auth_challenge_cell_parse(), but do not allocate the output
282 * object.
284 static ssize_t
285 auth_challenge_cell_parse_into(auth_challenge_cell_t *obj, const uint8_t *input, const size_t len_in)
287 const uint8_t *ptr = input;
288 size_t remaining = len_in;
289 ssize_t result = 0;
290 (void)result;
292 /* Parse u8 challenge[32] */
293 CHECK_REMAINING(32, truncated);
294 memcpy(obj->challenge, ptr, 32);
295 remaining -= 32; ptr += 32;
297 /* Parse u16 n_methods */
298 CHECK_REMAINING(2, truncated);
299 obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr));
300 remaining -= 2; ptr += 2;
302 /* Parse u16 methods[n_methods] */
303 TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {});
305 uint16_t elt;
306 unsigned idx;
307 for (idx = 0; idx < obj->n_methods; ++idx) {
308 CHECK_REMAINING(2, truncated);
309 elt = trunnel_ntohs(trunnel_get_uint16(ptr));
310 remaining -= 2; ptr += 2;
311 TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {});
314 trunnel_assert(ptr + remaining == input + len_in);
315 return len_in - remaining;
317 truncated:
318 return -2;
319 trunnel_alloc_failed:
320 return -1;
323 ssize_t
324 auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in)
326 ssize_t result;
327 *output = auth_challenge_cell_new();
328 if (NULL == *output)
329 return -1;
330 result = auth_challenge_cell_parse_into(*output, input, len_in);
331 if (result < 0) {
332 auth_challenge_cell_free(*output);
333 *output = NULL;
335 return result;
337 auth_ctx_t *
338 auth_ctx_new(void)
340 auth_ctx_t *val = trunnel_calloc(1, sizeof(auth_ctx_t));
341 if (NULL == val)
342 return NULL;
343 return val;
346 /** Release all storage held inside 'obj', but do not free 'obj'.
348 static void
349 auth_ctx_clear(auth_ctx_t *obj)
351 (void) obj;
354 void
355 auth_ctx_free(auth_ctx_t *obj)
357 if (obj == NULL)
358 return;
359 auth_ctx_clear(obj);
360 trunnel_memwipe(obj, sizeof(auth_ctx_t));
361 trunnel_free_(obj);
364 uint8_t
365 auth_ctx_get_is_ed(const auth_ctx_t *inp)
367 return inp->is_ed;
370 auth_ctx_set_is_ed(auth_ctx_t *inp, uint8_t val)
372 inp->is_ed = val;
373 return 0;
375 certs_cell_cert_t *
376 certs_cell_cert_new(void)
378 certs_cell_cert_t *val = trunnel_calloc(1, sizeof(certs_cell_cert_t));
379 if (NULL == val)
380 return NULL;
381 return val;
384 /** Release all storage held inside 'obj', but do not free 'obj'.
386 static void
387 certs_cell_cert_clear(certs_cell_cert_t *obj)
389 (void) obj;
390 TRUNNEL_DYNARRAY_WIPE(&obj->body);
391 TRUNNEL_DYNARRAY_CLEAR(&obj->body);
394 void
395 certs_cell_cert_free(certs_cell_cert_t *obj)
397 if (obj == NULL)
398 return;
399 certs_cell_cert_clear(obj);
400 trunnel_memwipe(obj, sizeof(certs_cell_cert_t));
401 trunnel_free_(obj);
404 uint8_t
405 certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp)
407 return inp->cert_type;
410 certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val)
412 inp->cert_type = val;
413 return 0;
415 uint16_t
416 certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp)
418 return inp->cert_len;
421 certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val)
423 inp->cert_len = val;
424 return 0;
426 size_t
427 certs_cell_cert_getlen_body(const certs_cell_cert_t *inp)
429 return TRUNNEL_DYNARRAY_LEN(&inp->body);
432 uint8_t
433 certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx)
435 return TRUNNEL_DYNARRAY_GET(&inp->body, idx);
438 uint8_t
439 certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx)
441 return certs_cell_cert_get_body((certs_cell_cert_t*)inp, idx);
444 certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt)
446 TRUNNEL_DYNARRAY_SET(&inp->body, idx, elt);
447 return 0;
450 certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt)
452 #if SIZE_MAX >= UINT16_MAX
453 if (inp->body.n_ == UINT16_MAX)
454 goto trunnel_alloc_failed;
455 #endif
456 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->body, elt, {});
457 return 0;
458 trunnel_alloc_failed:
459 TRUNNEL_SET_ERROR_CODE(inp);
460 return -1;
463 uint8_t *
464 certs_cell_cert_getarray_body(certs_cell_cert_t *inp)
466 return inp->body.elts_;
468 const uint8_t *
469 certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp)
471 return (const uint8_t *)certs_cell_cert_getarray_body((certs_cell_cert_t*)inp);
474 certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen)
476 uint8_t *newptr;
477 #if UINT16_MAX < SIZE_MAX
478 if (newlen > UINT16_MAX)
479 goto trunnel_alloc_failed;
480 #endif
481 newptr = trunnel_dynarray_setlen(&inp->body.allocated_,
482 &inp->body.n_, inp->body.elts_, newlen,
483 sizeof(inp->body.elts_[0]), (trunnel_free_fn_t) NULL,
484 &inp->trunnel_error_code_);
485 if (newlen != 0 && newptr == NULL)
486 goto trunnel_alloc_failed;
487 inp->body.elts_ = newptr;
488 return 0;
489 trunnel_alloc_failed:
490 TRUNNEL_SET_ERROR_CODE(inp);
491 return -1;
493 const char *
494 certs_cell_cert_check(const certs_cell_cert_t *obj)
496 if (obj == NULL)
497 return "Object was NULL";
498 if (obj->trunnel_error_code_)
499 return "A set function failed on this object";
500 if (TRUNNEL_DYNARRAY_LEN(&obj->body) != obj->cert_len)
501 return "Length mismatch for body";
502 return NULL;
505 ssize_t
506 certs_cell_cert_encoded_len(const certs_cell_cert_t *obj)
508 ssize_t result = 0;
510 if (NULL != certs_cell_cert_check(obj))
511 return -1;
514 /* Length of u8 cert_type */
515 result += 1;
517 /* Length of u16 cert_len */
518 result += 2;
520 /* Length of u8 body[cert_len] */
521 result += TRUNNEL_DYNARRAY_LEN(&obj->body);
522 return result;
525 certs_cell_cert_clear_errors(certs_cell_cert_t *obj)
527 int r = obj->trunnel_error_code_;
528 obj->trunnel_error_code_ = 0;
529 return r;
531 ssize_t
532 certs_cell_cert_encode(uint8_t *output, const size_t avail, const certs_cell_cert_t *obj)
534 ssize_t result = 0;
535 size_t written = 0;
536 uint8_t *ptr = output;
537 const char *msg;
538 #ifdef TRUNNEL_CHECK_ENCODED_LEN
539 const ssize_t encoded_len = certs_cell_cert_encoded_len(obj);
540 #endif
542 if (NULL != (msg = certs_cell_cert_check(obj)))
543 goto check_failed;
545 #ifdef TRUNNEL_CHECK_ENCODED_LEN
546 trunnel_assert(encoded_len >= 0);
547 #endif
549 /* Encode u8 cert_type */
550 trunnel_assert(written <= avail);
551 if (avail - written < 1)
552 goto truncated;
553 trunnel_set_uint8(ptr, (obj->cert_type));
554 written += 1; ptr += 1;
556 /* Encode u16 cert_len */
557 trunnel_assert(written <= avail);
558 if (avail - written < 2)
559 goto truncated;
560 trunnel_set_uint16(ptr, trunnel_htons(obj->cert_len));
561 written += 2; ptr += 2;
563 /* Encode u8 body[cert_len] */
565 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->body);
566 trunnel_assert(obj->cert_len == elt_len);
567 trunnel_assert(written <= avail);
568 if (avail - written < elt_len)
569 goto truncated;
570 if (elt_len)
571 memcpy(ptr, obj->body.elts_, elt_len);
572 written += elt_len; ptr += elt_len;
576 trunnel_assert(ptr == output + written);
577 #ifdef TRUNNEL_CHECK_ENCODED_LEN
579 trunnel_assert(encoded_len >= 0);
580 trunnel_assert((size_t)encoded_len == written);
583 #endif
585 return written;
587 truncated:
588 result = -2;
589 goto fail;
590 check_failed:
591 (void)msg;
592 result = -1;
593 goto fail;
594 fail:
595 trunnel_assert(result < 0);
596 return result;
599 /** As certs_cell_cert_parse(), but do not allocate the output object.
601 static ssize_t
602 certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const size_t len_in)
604 const uint8_t *ptr = input;
605 size_t remaining = len_in;
606 ssize_t result = 0;
607 (void)result;
609 /* Parse u8 cert_type */
610 CHECK_REMAINING(1, truncated);
611 obj->cert_type = (trunnel_get_uint8(ptr));
612 remaining -= 1; ptr += 1;
614 /* Parse u16 cert_len */
615 CHECK_REMAINING(2, truncated);
616 obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr));
617 remaining -= 2; ptr += 2;
619 /* Parse u8 body[cert_len] */
620 CHECK_REMAINING(obj->cert_len, truncated);
621 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {});
622 obj->body.n_ = obj->cert_len;
623 if (obj->cert_len)
624 memcpy(obj->body.elts_, ptr, obj->cert_len);
625 ptr += obj->cert_len; remaining -= obj->cert_len;
626 trunnel_assert(ptr + remaining == input + len_in);
627 return len_in - remaining;
629 truncated:
630 return -2;
631 trunnel_alloc_failed:
632 return -1;
635 ssize_t
636 certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in)
638 ssize_t result;
639 *output = certs_cell_cert_new();
640 if (NULL == *output)
641 return -1;
642 result = certs_cell_cert_parse_into(*output, input, len_in);
643 if (result < 0) {
644 certs_cell_cert_free(*output);
645 *output = NULL;
647 return result;
649 rsa_ed_crosscert_t *
650 rsa_ed_crosscert_new(void)
652 rsa_ed_crosscert_t *val = trunnel_calloc(1, sizeof(rsa_ed_crosscert_t));
653 if (NULL == val)
654 return NULL;
655 return val;
658 /** Release all storage held inside 'obj', but do not free 'obj'.
660 static void
661 rsa_ed_crosscert_clear(rsa_ed_crosscert_t *obj)
663 (void) obj;
664 TRUNNEL_DYNARRAY_WIPE(&obj->sig);
665 TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
668 void
669 rsa_ed_crosscert_free(rsa_ed_crosscert_t *obj)
671 if (obj == NULL)
672 return;
673 rsa_ed_crosscert_clear(obj);
674 trunnel_memwipe(obj, sizeof(rsa_ed_crosscert_t));
675 trunnel_free_(obj);
678 size_t
679 rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp)
681 (void)inp; return 32;
684 uint8_t
685 rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx)
687 trunnel_assert(idx < 32);
688 return inp->ed_key[idx];
691 uint8_t
692 rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx)
694 return rsa_ed_crosscert_get_ed_key((rsa_ed_crosscert_t*)inp, idx);
697 rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
699 trunnel_assert(idx < 32);
700 inp->ed_key[idx] = elt;
701 return 0;
704 uint8_t *
705 rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp)
707 return inp->ed_key;
709 const uint8_t *
710 rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp)
712 return (const uint8_t *)rsa_ed_crosscert_getarray_ed_key((rsa_ed_crosscert_t*)inp);
714 uint32_t
715 rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp)
717 return inp->expiration;
720 rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val)
722 inp->expiration = val;
723 return 0;
725 const uint8_t *
726 rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp)
728 return inp->end_of_signed;
730 uint8_t
731 rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp)
733 return inp->sig_len;
736 rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val)
738 inp->sig_len = val;
739 return 0;
741 size_t
742 rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp)
744 return TRUNNEL_DYNARRAY_LEN(&inp->sig);
747 uint8_t
748 rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx)
750 return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
753 uint8_t
754 rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx)
756 return rsa_ed_crosscert_get_sig((rsa_ed_crosscert_t*)inp, idx);
759 rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
761 TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
762 return 0;
765 rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt)
767 #if SIZE_MAX >= UINT8_MAX
768 if (inp->sig.n_ == UINT8_MAX)
769 goto trunnel_alloc_failed;
770 #endif
771 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
772 return 0;
773 trunnel_alloc_failed:
774 TRUNNEL_SET_ERROR_CODE(inp);
775 return -1;
778 uint8_t *
779 rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp)
781 return inp->sig.elts_;
783 const uint8_t *
784 rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp)
786 return (const uint8_t *)rsa_ed_crosscert_getarray_sig((rsa_ed_crosscert_t*)inp);
789 rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen)
791 uint8_t *newptr;
792 #if UINT8_MAX < SIZE_MAX
793 if (newlen > UINT8_MAX)
794 goto trunnel_alloc_failed;
795 #endif
796 newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
797 &inp->sig.n_, inp->sig.elts_, newlen,
798 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
799 &inp->trunnel_error_code_);
800 if (newlen != 0 && newptr == NULL)
801 goto trunnel_alloc_failed;
802 inp->sig.elts_ = newptr;
803 return 0;
804 trunnel_alloc_failed:
805 TRUNNEL_SET_ERROR_CODE(inp);
806 return -1;
808 const char *
809 rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj)
811 if (obj == NULL)
812 return "Object was NULL";
813 if (obj->trunnel_error_code_)
814 return "A set function failed on this object";
815 if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len)
816 return "Length mismatch for sig";
817 return NULL;
820 ssize_t
821 rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj)
823 ssize_t result = 0;
825 if (NULL != rsa_ed_crosscert_check(obj))
826 return -1;
829 /* Length of u8 ed_key[32] */
830 result += 32;
832 /* Length of u32 expiration */
833 result += 4;
835 /* Length of u8 sig_len */
836 result += 1;
838 /* Length of u8 sig[sig_len] */
839 result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
840 return result;
843 rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj)
845 int r = obj->trunnel_error_code_;
846 obj->trunnel_error_code_ = 0;
847 return r;
849 ssize_t
850 rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crosscert_t *obj)
852 ssize_t result = 0;
853 size_t written = 0;
854 uint8_t *ptr = output;
855 const char *msg;
856 #ifdef TRUNNEL_CHECK_ENCODED_LEN
857 const ssize_t encoded_len = rsa_ed_crosscert_encoded_len(obj);
858 #endif
860 if (NULL != (msg = rsa_ed_crosscert_check(obj)))
861 goto check_failed;
863 #ifdef TRUNNEL_CHECK_ENCODED_LEN
864 trunnel_assert(encoded_len >= 0);
865 #endif
867 /* Encode u8 ed_key[32] */
868 trunnel_assert(written <= avail);
869 if (avail - written < 32)
870 goto truncated;
871 memcpy(ptr, obj->ed_key, 32);
872 written += 32; ptr += 32;
874 /* Encode u32 expiration */
875 trunnel_assert(written <= avail);
876 if (avail - written < 4)
877 goto truncated;
878 trunnel_set_uint32(ptr, trunnel_htonl(obj->expiration));
879 written += 4; ptr += 4;
881 /* Encode u8 sig_len */
882 trunnel_assert(written <= avail);
883 if (avail - written < 1)
884 goto truncated;
885 trunnel_set_uint8(ptr, (obj->sig_len));
886 written += 1; ptr += 1;
888 /* Encode u8 sig[sig_len] */
890 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
891 trunnel_assert(obj->sig_len == elt_len);
892 trunnel_assert(written <= avail);
893 if (avail - written < elt_len)
894 goto truncated;
895 if (elt_len)
896 memcpy(ptr, obj->sig.elts_, elt_len);
897 written += elt_len; ptr += elt_len;
901 trunnel_assert(ptr == output + written);
902 #ifdef TRUNNEL_CHECK_ENCODED_LEN
904 trunnel_assert(encoded_len >= 0);
905 trunnel_assert((size_t)encoded_len == written);
908 #endif
910 return written;
912 truncated:
913 result = -2;
914 goto fail;
915 check_failed:
916 (void)msg;
917 result = -1;
918 goto fail;
919 fail:
920 trunnel_assert(result < 0);
921 return result;
924 /** As rsa_ed_crosscert_parse(), but do not allocate the output
925 * object.
927 static ssize_t
928 rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const size_t len_in)
930 const uint8_t *ptr = input;
931 size_t remaining = len_in;
932 ssize_t result = 0;
933 (void)result;
935 /* Parse u8 ed_key[32] */
936 CHECK_REMAINING(32, truncated);
937 memcpy(obj->ed_key, ptr, 32);
938 remaining -= 32; ptr += 32;
940 /* Parse u32 expiration */
941 CHECK_REMAINING(4, truncated);
942 obj->expiration = trunnel_ntohl(trunnel_get_uint32(ptr));
943 remaining -= 4; ptr += 4;
944 obj->end_of_signed = ptr;
946 /* Parse u8 sig_len */
947 CHECK_REMAINING(1, truncated);
948 obj->sig_len = (trunnel_get_uint8(ptr));
949 remaining -= 1; ptr += 1;
951 /* Parse u8 sig[sig_len] */
952 CHECK_REMAINING(obj->sig_len, truncated);
953 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
954 obj->sig.n_ = obj->sig_len;
955 if (obj->sig_len)
956 memcpy(obj->sig.elts_, ptr, obj->sig_len);
957 ptr += obj->sig_len; remaining -= obj->sig_len;
958 trunnel_assert(ptr + remaining == input + len_in);
959 return len_in - remaining;
961 truncated:
962 return -2;
963 trunnel_alloc_failed:
964 return -1;
967 ssize_t
968 rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in)
970 ssize_t result;
971 *output = rsa_ed_crosscert_new();
972 if (NULL == *output)
973 return -1;
974 result = rsa_ed_crosscert_parse_into(*output, input, len_in);
975 if (result < 0) {
976 rsa_ed_crosscert_free(*output);
977 *output = NULL;
979 return result;
981 auth1_t *
982 auth1_new(void)
984 auth1_t *val = trunnel_calloc(1, sizeof(auth1_t));
985 if (NULL == val)
986 return NULL;
987 return val;
990 /** Release all storage held inside 'obj', but do not free 'obj'.
992 static void
993 auth1_clear(auth1_t *obj)
995 (void) obj;
996 TRUNNEL_DYNARRAY_WIPE(&obj->sig);
997 TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
1000 void
1001 auth1_free(auth1_t *obj)
1003 if (obj == NULL)
1004 return;
1005 auth1_clear(obj);
1006 trunnel_memwipe(obj, sizeof(auth1_t));
1007 trunnel_free_(obj);
1010 size_t
1011 auth1_getlen_type(const auth1_t *inp)
1013 (void)inp; return 8;
1016 uint8_t
1017 auth1_get_type(auth1_t *inp, size_t idx)
1019 trunnel_assert(idx < 8);
1020 return inp->type[idx];
1023 uint8_t
1024 auth1_getconst_type(const auth1_t *inp, size_t idx)
1026 return auth1_get_type((auth1_t*)inp, idx);
1029 auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt)
1031 trunnel_assert(idx < 8);
1032 inp->type[idx] = elt;
1033 return 0;
1036 uint8_t *
1037 auth1_getarray_type(auth1_t *inp)
1039 return inp->type;
1041 const uint8_t *
1042 auth1_getconstarray_type(const auth1_t *inp)
1044 return (const uint8_t *)auth1_getarray_type((auth1_t*)inp);
1046 size_t
1047 auth1_getlen_cid(const auth1_t *inp)
1049 (void)inp; return 32;
1052 uint8_t
1053 auth1_get_cid(auth1_t *inp, size_t idx)
1055 trunnel_assert(idx < 32);
1056 return inp->cid[idx];
1059 uint8_t
1060 auth1_getconst_cid(const auth1_t *inp, size_t idx)
1062 return auth1_get_cid((auth1_t*)inp, idx);
1065 auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt)
1067 trunnel_assert(idx < 32);
1068 inp->cid[idx] = elt;
1069 return 0;
1072 uint8_t *
1073 auth1_getarray_cid(auth1_t *inp)
1075 return inp->cid;
1077 const uint8_t *
1078 auth1_getconstarray_cid(const auth1_t *inp)
1080 return (const uint8_t *)auth1_getarray_cid((auth1_t*)inp);
1082 size_t
1083 auth1_getlen_sid(const auth1_t *inp)
1085 (void)inp; return 32;
1088 uint8_t
1089 auth1_get_sid(auth1_t *inp, size_t idx)
1091 trunnel_assert(idx < 32);
1092 return inp->sid[idx];
1095 uint8_t
1096 auth1_getconst_sid(const auth1_t *inp, size_t idx)
1098 return auth1_get_sid((auth1_t*)inp, idx);
1101 auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt)
1103 trunnel_assert(idx < 32);
1104 inp->sid[idx] = elt;
1105 return 0;
1108 uint8_t *
1109 auth1_getarray_sid(auth1_t *inp)
1111 return inp->sid;
1113 const uint8_t *
1114 auth1_getconstarray_sid(const auth1_t *inp)
1116 return (const uint8_t *)auth1_getarray_sid((auth1_t*)inp);
1118 size_t
1119 auth1_getlen_u1_cid_ed(const auth1_t *inp)
1121 (void)inp; return 32;
1124 uint8_t
1125 auth1_get_u1_cid_ed(auth1_t *inp, size_t idx)
1127 trunnel_assert(idx < 32);
1128 return inp->u1_cid_ed[idx];
1131 uint8_t
1132 auth1_getconst_u1_cid_ed(const auth1_t *inp, size_t idx)
1134 return auth1_get_u1_cid_ed((auth1_t*)inp, idx);
1137 auth1_set_u1_cid_ed(auth1_t *inp, size_t idx, uint8_t elt)
1139 trunnel_assert(idx < 32);
1140 inp->u1_cid_ed[idx] = elt;
1141 return 0;
1144 uint8_t *
1145 auth1_getarray_u1_cid_ed(auth1_t *inp)
1147 return inp->u1_cid_ed;
1149 const uint8_t *
1150 auth1_getconstarray_u1_cid_ed(const auth1_t *inp)
1152 return (const uint8_t *)auth1_getarray_u1_cid_ed((auth1_t*)inp);
1154 size_t
1155 auth1_getlen_u1_sid_ed(const auth1_t *inp)
1157 (void)inp; return 32;
1160 uint8_t
1161 auth1_get_u1_sid_ed(auth1_t *inp, size_t idx)
1163 trunnel_assert(idx < 32);
1164 return inp->u1_sid_ed[idx];
1167 uint8_t
1168 auth1_getconst_u1_sid_ed(const auth1_t *inp, size_t idx)
1170 return auth1_get_u1_sid_ed((auth1_t*)inp, idx);
1173 auth1_set_u1_sid_ed(auth1_t *inp, size_t idx, uint8_t elt)
1175 trunnel_assert(idx < 32);
1176 inp->u1_sid_ed[idx] = elt;
1177 return 0;
1180 uint8_t *
1181 auth1_getarray_u1_sid_ed(auth1_t *inp)
1183 return inp->u1_sid_ed;
1185 const uint8_t *
1186 auth1_getconstarray_u1_sid_ed(const auth1_t *inp)
1188 return (const uint8_t *)auth1_getarray_u1_sid_ed((auth1_t*)inp);
1190 size_t
1191 auth1_getlen_slog(const auth1_t *inp)
1193 (void)inp; return 32;
1196 uint8_t
1197 auth1_get_slog(auth1_t *inp, size_t idx)
1199 trunnel_assert(idx < 32);
1200 return inp->slog[idx];
1203 uint8_t
1204 auth1_getconst_slog(const auth1_t *inp, size_t idx)
1206 return auth1_get_slog((auth1_t*)inp, idx);
1209 auth1_set_slog(auth1_t *inp, size_t idx, uint8_t elt)
1211 trunnel_assert(idx < 32);
1212 inp->slog[idx] = elt;
1213 return 0;
1216 uint8_t *
1217 auth1_getarray_slog(auth1_t *inp)
1219 return inp->slog;
1221 const uint8_t *
1222 auth1_getconstarray_slog(const auth1_t *inp)
1224 return (const uint8_t *)auth1_getarray_slog((auth1_t*)inp);
1226 size_t
1227 auth1_getlen_clog(const auth1_t *inp)
1229 (void)inp; return 32;
1232 uint8_t
1233 auth1_get_clog(auth1_t *inp, size_t idx)
1235 trunnel_assert(idx < 32);
1236 return inp->clog[idx];
1239 uint8_t
1240 auth1_getconst_clog(const auth1_t *inp, size_t idx)
1242 return auth1_get_clog((auth1_t*)inp, idx);
1245 auth1_set_clog(auth1_t *inp, size_t idx, uint8_t elt)
1247 trunnel_assert(idx < 32);
1248 inp->clog[idx] = elt;
1249 return 0;
1252 uint8_t *
1253 auth1_getarray_clog(auth1_t *inp)
1255 return inp->clog;
1257 const uint8_t *
1258 auth1_getconstarray_clog(const auth1_t *inp)
1260 return (const uint8_t *)auth1_getarray_clog((auth1_t*)inp);
1262 size_t
1263 auth1_getlen_scert(const auth1_t *inp)
1265 (void)inp; return 32;
1268 uint8_t
1269 auth1_get_scert(auth1_t *inp, size_t idx)
1271 trunnel_assert(idx < 32);
1272 return inp->scert[idx];
1275 uint8_t
1276 auth1_getconst_scert(const auth1_t *inp, size_t idx)
1278 return auth1_get_scert((auth1_t*)inp, idx);
1281 auth1_set_scert(auth1_t *inp, size_t idx, uint8_t elt)
1283 trunnel_assert(idx < 32);
1284 inp->scert[idx] = elt;
1285 return 0;
1288 uint8_t *
1289 auth1_getarray_scert(auth1_t *inp)
1291 return inp->scert;
1293 const uint8_t *
1294 auth1_getconstarray_scert(const auth1_t *inp)
1296 return (const uint8_t *)auth1_getarray_scert((auth1_t*)inp);
1298 size_t
1299 auth1_getlen_tlssecrets(const auth1_t *inp)
1301 (void)inp; return 32;
1304 uint8_t
1305 auth1_get_tlssecrets(auth1_t *inp, size_t idx)
1307 trunnel_assert(idx < 32);
1308 return inp->tlssecrets[idx];
1311 uint8_t
1312 auth1_getconst_tlssecrets(const auth1_t *inp, size_t idx)
1314 return auth1_get_tlssecrets((auth1_t*)inp, idx);
1317 auth1_set_tlssecrets(auth1_t *inp, size_t idx, uint8_t elt)
1319 trunnel_assert(idx < 32);
1320 inp->tlssecrets[idx] = elt;
1321 return 0;
1324 uint8_t *
1325 auth1_getarray_tlssecrets(auth1_t *inp)
1327 return inp->tlssecrets;
1329 const uint8_t *
1330 auth1_getconstarray_tlssecrets(const auth1_t *inp)
1332 return (const uint8_t *)auth1_getarray_tlssecrets((auth1_t*)inp);
1334 const uint8_t *
1335 auth1_get_end_of_fixed_part(const auth1_t *inp)
1337 return inp->end_of_fixed_part;
1339 size_t
1340 auth1_getlen_rand(const auth1_t *inp)
1342 (void)inp; return 24;
1345 uint8_t
1346 auth1_get_rand(auth1_t *inp, size_t idx)
1348 trunnel_assert(idx < 24);
1349 return inp->rand[idx];
1352 uint8_t
1353 auth1_getconst_rand(const auth1_t *inp, size_t idx)
1355 return auth1_get_rand((auth1_t*)inp, idx);
1358 auth1_set_rand(auth1_t *inp, size_t idx, uint8_t elt)
1360 trunnel_assert(idx < 24);
1361 inp->rand[idx] = elt;
1362 return 0;
1365 uint8_t *
1366 auth1_getarray_rand(auth1_t *inp)
1368 return inp->rand;
1370 const uint8_t *
1371 auth1_getconstarray_rand(const auth1_t *inp)
1373 return (const uint8_t *)auth1_getarray_rand((auth1_t*)inp);
1375 const uint8_t *
1376 auth1_get_end_of_signed(const auth1_t *inp)
1378 return inp->end_of_signed;
1380 size_t
1381 auth1_getlen_sig(const auth1_t *inp)
1383 return TRUNNEL_DYNARRAY_LEN(&inp->sig);
1386 uint8_t
1387 auth1_get_sig(auth1_t *inp, size_t idx)
1389 return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
1392 uint8_t
1393 auth1_getconst_sig(const auth1_t *inp, size_t idx)
1395 return auth1_get_sig((auth1_t*)inp, idx);
1398 auth1_set_sig(auth1_t *inp, size_t idx, uint8_t elt)
1400 TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
1401 return 0;
1404 auth1_add_sig(auth1_t *inp, uint8_t elt)
1406 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
1407 return 0;
1408 trunnel_alloc_failed:
1409 TRUNNEL_SET_ERROR_CODE(inp);
1410 return -1;
1413 uint8_t *
1414 auth1_getarray_sig(auth1_t *inp)
1416 return inp->sig.elts_;
1418 const uint8_t *
1419 auth1_getconstarray_sig(const auth1_t *inp)
1421 return (const uint8_t *)auth1_getarray_sig((auth1_t*)inp);
1424 auth1_setlen_sig(auth1_t *inp, size_t newlen)
1426 uint8_t *newptr;
1427 newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
1428 &inp->sig.n_, inp->sig.elts_, newlen,
1429 sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
1430 &inp->trunnel_error_code_);
1431 if (newlen != 0 && newptr == NULL)
1432 goto trunnel_alloc_failed;
1433 inp->sig.elts_ = newptr;
1434 return 0;
1435 trunnel_alloc_failed:
1436 TRUNNEL_SET_ERROR_CODE(inp);
1437 return -1;
1439 const char *
1440 auth1_check(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
1442 if (obj == NULL)
1443 return "Object was NULL";
1444 if (obj->trunnel_error_code_)
1445 return "A set function failed on this object";
1446 if (auth_ctx_ctx == NULL)
1447 return "Context was NULL";
1448 switch (auth_ctx_ctx->is_ed) {
1450 case 0:
1451 break;
1453 case 1:
1454 break;
1456 default:
1457 return "Bad tag for union";
1458 break;
1460 return NULL;
1463 ssize_t
1464 auth1_encoded_len(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
1466 ssize_t result = 0;
1468 if (NULL != auth1_check(obj, auth_ctx_ctx))
1469 return -1;
1472 /* Length of u8 type[8] */
1473 result += 8;
1475 /* Length of u8 cid[32] */
1476 result += 32;
1478 /* Length of u8 sid[32] */
1479 result += 32;
1480 switch (auth_ctx_ctx->is_ed) {
1482 case 0:
1483 break;
1485 case 1:
1487 /* Length of u8 u1_cid_ed[32] */
1488 result += 32;
1490 /* Length of u8 u1_sid_ed[32] */
1491 result += 32;
1492 break;
1494 default:
1495 trunnel_assert(0);
1496 break;
1499 /* Length of u8 slog[32] */
1500 result += 32;
1502 /* Length of u8 clog[32] */
1503 result += 32;
1505 /* Length of u8 scert[32] */
1506 result += 32;
1508 /* Length of u8 tlssecrets[32] */
1509 result += 32;
1511 /* Length of u8 rand[24] */
1512 result += 24;
1514 /* Length of u8 sig[] */
1515 result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
1516 return result;
1519 auth1_clear_errors(auth1_t *obj)
1521 int r = obj->trunnel_error_code_;
1522 obj->trunnel_error_code_ = 0;
1523 return r;
1525 ssize_t
1526 auth1_encode(uint8_t *output, const size_t avail, const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
1528 ssize_t result = 0;
1529 size_t written = 0;
1530 uint8_t *ptr = output;
1531 const char *msg;
1532 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1533 const ssize_t encoded_len = auth1_encoded_len(obj, auth_ctx_ctx);
1534 #endif
1536 if (NULL != (msg = auth1_check(obj, auth_ctx_ctx)))
1537 goto check_failed;
1539 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1540 trunnel_assert(encoded_len >= 0);
1541 #endif
1543 /* Encode u8 type[8] */
1544 trunnel_assert(written <= avail);
1545 if (avail - written < 8)
1546 goto truncated;
1547 memcpy(ptr, obj->type, 8);
1548 written += 8; ptr += 8;
1550 /* Encode u8 cid[32] */
1551 trunnel_assert(written <= avail);
1552 if (avail - written < 32)
1553 goto truncated;
1554 memcpy(ptr, obj->cid, 32);
1555 written += 32; ptr += 32;
1557 /* Encode u8 sid[32] */
1558 trunnel_assert(written <= avail);
1559 if (avail - written < 32)
1560 goto truncated;
1561 memcpy(ptr, obj->sid, 32);
1562 written += 32; ptr += 32;
1564 /* Encode union u1[auth_ctx.is_ed] */
1565 trunnel_assert(written <= avail);
1566 switch (auth_ctx_ctx->is_ed) {
1568 case 0:
1569 break;
1571 case 1:
1573 /* Encode u8 u1_cid_ed[32] */
1574 trunnel_assert(written <= avail);
1575 if (avail - written < 32)
1576 goto truncated;
1577 memcpy(ptr, obj->u1_cid_ed, 32);
1578 written += 32; ptr += 32;
1580 /* Encode u8 u1_sid_ed[32] */
1581 trunnel_assert(written <= avail);
1582 if (avail - written < 32)
1583 goto truncated;
1584 memcpy(ptr, obj->u1_sid_ed, 32);
1585 written += 32; ptr += 32;
1586 break;
1588 default:
1589 trunnel_assert(0);
1590 break;
1593 /* Encode u8 slog[32] */
1594 trunnel_assert(written <= avail);
1595 if (avail - written < 32)
1596 goto truncated;
1597 memcpy(ptr, obj->slog, 32);
1598 written += 32; ptr += 32;
1600 /* Encode u8 clog[32] */
1601 trunnel_assert(written <= avail);
1602 if (avail - written < 32)
1603 goto truncated;
1604 memcpy(ptr, obj->clog, 32);
1605 written += 32; ptr += 32;
1607 /* Encode u8 scert[32] */
1608 trunnel_assert(written <= avail);
1609 if (avail - written < 32)
1610 goto truncated;
1611 memcpy(ptr, obj->scert, 32);
1612 written += 32; ptr += 32;
1614 /* Encode u8 tlssecrets[32] */
1615 trunnel_assert(written <= avail);
1616 if (avail - written < 32)
1617 goto truncated;
1618 memcpy(ptr, obj->tlssecrets, 32);
1619 written += 32; ptr += 32;
1621 /* Encode u8 rand[24] */
1622 trunnel_assert(written <= avail);
1623 if (avail - written < 24)
1624 goto truncated;
1625 memcpy(ptr, obj->rand, 24);
1626 written += 24; ptr += 24;
1628 /* Encode u8 sig[] */
1630 size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
1631 trunnel_assert(written <= avail);
1632 if (avail - written < elt_len)
1633 goto truncated;
1634 if (elt_len)
1635 memcpy(ptr, obj->sig.elts_, elt_len);
1636 written += elt_len; ptr += elt_len;
1640 trunnel_assert(ptr == output + written);
1641 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1643 trunnel_assert(encoded_len >= 0);
1644 trunnel_assert((size_t)encoded_len == written);
1647 #endif
1649 return written;
1651 truncated:
1652 result = -2;
1653 goto fail;
1654 check_failed:
1655 (void)msg;
1656 result = -1;
1657 goto fail;
1658 fail:
1659 trunnel_assert(result < 0);
1660 return result;
1663 /** As auth1_parse(), but do not allocate the output object.
1665 static ssize_t
1666 auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
1668 const uint8_t *ptr = input;
1669 size_t remaining = len_in;
1670 ssize_t result = 0;
1671 (void)result;
1672 if (auth_ctx_ctx == NULL)
1673 return -1;
1675 /* Parse u8 type[8] */
1676 CHECK_REMAINING(8, truncated);
1677 memcpy(obj->type, ptr, 8);
1678 remaining -= 8; ptr += 8;
1680 /* Parse u8 cid[32] */
1681 CHECK_REMAINING(32, truncated);
1682 memcpy(obj->cid, ptr, 32);
1683 remaining -= 32; ptr += 32;
1685 /* Parse u8 sid[32] */
1686 CHECK_REMAINING(32, truncated);
1687 memcpy(obj->sid, ptr, 32);
1688 remaining -= 32; ptr += 32;
1690 /* Parse union u1[auth_ctx.is_ed] */
1691 switch (auth_ctx_ctx->is_ed) {
1693 case 0:
1694 break;
1696 case 1:
1698 /* Parse u8 u1_cid_ed[32] */
1699 CHECK_REMAINING(32, truncated);
1700 memcpy(obj->u1_cid_ed, ptr, 32);
1701 remaining -= 32; ptr += 32;
1703 /* Parse u8 u1_sid_ed[32] */
1704 CHECK_REMAINING(32, truncated);
1705 memcpy(obj->u1_sid_ed, ptr, 32);
1706 remaining -= 32; ptr += 32;
1707 break;
1709 default:
1710 goto fail;
1711 break;
1714 /* Parse u8 slog[32] */
1715 CHECK_REMAINING(32, truncated);
1716 memcpy(obj->slog, ptr, 32);
1717 remaining -= 32; ptr += 32;
1719 /* Parse u8 clog[32] */
1720 CHECK_REMAINING(32, truncated);
1721 memcpy(obj->clog, ptr, 32);
1722 remaining -= 32; ptr += 32;
1724 /* Parse u8 scert[32] */
1725 CHECK_REMAINING(32, truncated);
1726 memcpy(obj->scert, ptr, 32);
1727 remaining -= 32; ptr += 32;
1729 /* Parse u8 tlssecrets[32] */
1730 CHECK_REMAINING(32, truncated);
1731 memcpy(obj->tlssecrets, ptr, 32);
1732 remaining -= 32; ptr += 32;
1733 obj->end_of_fixed_part = ptr;
1735 /* Parse u8 rand[24] */
1736 CHECK_REMAINING(24, truncated);
1737 memcpy(obj->rand, ptr, 24);
1738 remaining -= 24; ptr += 24;
1739 obj->end_of_signed = ptr;
1741 /* Parse u8 sig[] */
1742 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, remaining, {});
1743 obj->sig.n_ = remaining;
1744 if (remaining)
1745 memcpy(obj->sig.elts_, ptr, remaining);
1746 ptr += remaining; remaining -= remaining;
1747 trunnel_assert(ptr + remaining == input + len_in);
1748 return len_in - remaining;
1750 truncated:
1751 return -2;
1752 trunnel_alloc_failed:
1753 return -1;
1754 fail:
1755 result = -1;
1756 return result;
1759 ssize_t
1760 auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
1762 ssize_t result;
1763 *output = auth1_new();
1764 if (NULL == *output)
1765 return -1;
1766 result = auth1_parse_into(*output, input, len_in, auth_ctx_ctx);
1767 if (result < 0) {
1768 auth1_free(*output);
1769 *output = NULL;
1771 return result;
1773 certs_cell_t *
1774 certs_cell_new(void)
1776 certs_cell_t *val = trunnel_calloc(1, sizeof(certs_cell_t));
1777 if (NULL == val)
1778 return NULL;
1779 return val;
1782 /** Release all storage held inside 'obj', but do not free 'obj'.
1784 static void
1785 certs_cell_clear(certs_cell_t *obj)
1787 (void) obj;
1790 unsigned idx;
1791 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
1792 certs_cell_cert_free(TRUNNEL_DYNARRAY_GET(&obj->certs, idx));
1795 TRUNNEL_DYNARRAY_WIPE(&obj->certs);
1796 TRUNNEL_DYNARRAY_CLEAR(&obj->certs);
1799 void
1800 certs_cell_free(certs_cell_t *obj)
1802 if (obj == NULL)
1803 return;
1804 certs_cell_clear(obj);
1805 trunnel_memwipe(obj, sizeof(certs_cell_t));
1806 trunnel_free_(obj);
1809 uint8_t
1810 certs_cell_get_n_certs(const certs_cell_t *inp)
1812 return inp->n_certs;
1815 certs_cell_set_n_certs(certs_cell_t *inp, uint8_t val)
1817 inp->n_certs = val;
1818 return 0;
1820 size_t
1821 certs_cell_getlen_certs(const certs_cell_t *inp)
1823 return TRUNNEL_DYNARRAY_LEN(&inp->certs);
1826 struct certs_cell_cert_st *
1827 certs_cell_get_certs(certs_cell_t *inp, size_t idx)
1829 return TRUNNEL_DYNARRAY_GET(&inp->certs, idx);
1832 const struct certs_cell_cert_st *
1833 certs_cell_getconst_certs(const certs_cell_t *inp, size_t idx)
1835 return certs_cell_get_certs((certs_cell_t*)inp, idx);
1838 certs_cell_set_certs(certs_cell_t *inp, size_t idx, struct certs_cell_cert_st * elt)
1840 certs_cell_cert_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->certs, idx);
1841 if (oldval && oldval != elt)
1842 certs_cell_cert_free(oldval);
1843 return certs_cell_set0_certs(inp, idx, elt);
1846 certs_cell_set0_certs(certs_cell_t *inp, size_t idx, struct certs_cell_cert_st * elt)
1848 TRUNNEL_DYNARRAY_SET(&inp->certs, idx, elt);
1849 return 0;
1852 certs_cell_add_certs(certs_cell_t *inp, struct certs_cell_cert_st * elt)
1854 #if SIZE_MAX >= UINT8_MAX
1855 if (inp->certs.n_ == UINT8_MAX)
1856 goto trunnel_alloc_failed;
1857 #endif
1858 TRUNNEL_DYNARRAY_ADD(struct certs_cell_cert_st *, &inp->certs, elt, {});
1859 return 0;
1860 trunnel_alloc_failed:
1861 TRUNNEL_SET_ERROR_CODE(inp);
1862 return -1;
1865 struct certs_cell_cert_st * *
1866 certs_cell_getarray_certs(certs_cell_t *inp)
1868 return inp->certs.elts_;
1870 const struct certs_cell_cert_st * const *
1871 certs_cell_getconstarray_certs(const certs_cell_t *inp)
1873 return (const struct certs_cell_cert_st * const *)certs_cell_getarray_certs((certs_cell_t*)inp);
1876 certs_cell_setlen_certs(certs_cell_t *inp, size_t newlen)
1878 struct certs_cell_cert_st * *newptr;
1879 #if UINT8_MAX < SIZE_MAX
1880 if (newlen > UINT8_MAX)
1881 goto trunnel_alloc_failed;
1882 #endif
1883 newptr = trunnel_dynarray_setlen(&inp->certs.allocated_,
1884 &inp->certs.n_, inp->certs.elts_, newlen,
1885 sizeof(inp->certs.elts_[0]), (trunnel_free_fn_t) certs_cell_cert_free,
1886 &inp->trunnel_error_code_);
1887 if (newlen != 0 && newptr == NULL)
1888 goto trunnel_alloc_failed;
1889 inp->certs.elts_ = newptr;
1890 return 0;
1891 trunnel_alloc_failed:
1892 TRUNNEL_SET_ERROR_CODE(inp);
1893 return -1;
1895 const char *
1896 certs_cell_check(const certs_cell_t *obj)
1898 if (obj == NULL)
1899 return "Object was NULL";
1900 if (obj->trunnel_error_code_)
1901 return "A set function failed on this object";
1903 const char *msg;
1905 unsigned idx;
1906 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
1907 if (NULL != (msg = certs_cell_cert_check(TRUNNEL_DYNARRAY_GET(&obj->certs, idx))))
1908 return msg;
1911 if (TRUNNEL_DYNARRAY_LEN(&obj->certs) != obj->n_certs)
1912 return "Length mismatch for certs";
1913 return NULL;
1916 ssize_t
1917 certs_cell_encoded_len(const certs_cell_t *obj)
1919 ssize_t result = 0;
1921 if (NULL != certs_cell_check(obj))
1922 return -1;
1925 /* Length of u8 n_certs */
1926 result += 1;
1928 /* Length of struct certs_cell_cert certs[n_certs] */
1931 unsigned idx;
1932 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
1933 result += certs_cell_cert_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->certs, idx));
1936 return result;
1939 certs_cell_clear_errors(certs_cell_t *obj)
1941 int r = obj->trunnel_error_code_;
1942 obj->trunnel_error_code_ = 0;
1943 return r;
1945 ssize_t
1946 certs_cell_encode(uint8_t *output, const size_t avail, const certs_cell_t *obj)
1948 ssize_t result = 0;
1949 size_t written = 0;
1950 uint8_t *ptr = output;
1951 const char *msg;
1952 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1953 const ssize_t encoded_len = certs_cell_encoded_len(obj);
1954 #endif
1956 if (NULL != (msg = certs_cell_check(obj)))
1957 goto check_failed;
1959 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1960 trunnel_assert(encoded_len >= 0);
1961 #endif
1963 /* Encode u8 n_certs */
1964 trunnel_assert(written <= avail);
1965 if (avail - written < 1)
1966 goto truncated;
1967 trunnel_set_uint8(ptr, (obj->n_certs));
1968 written += 1; ptr += 1;
1970 /* Encode struct certs_cell_cert certs[n_certs] */
1973 unsigned idx;
1974 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
1975 trunnel_assert(written <= avail);
1976 result = certs_cell_cert_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->certs, idx));
1977 if (result < 0)
1978 goto fail; /* XXXXXXX !*/
1979 written += result; ptr += result;
1984 trunnel_assert(ptr == output + written);
1985 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1987 trunnel_assert(encoded_len >= 0);
1988 trunnel_assert((size_t)encoded_len == written);
1991 #endif
1993 return written;
1995 truncated:
1996 result = -2;
1997 goto fail;
1998 check_failed:
1999 (void)msg;
2000 result = -1;
2001 goto fail;
2002 fail:
2003 trunnel_assert(result < 0);
2004 return result;
2007 /** As certs_cell_parse(), but do not allocate the output object.
2009 static ssize_t
2010 certs_cell_parse_into(certs_cell_t *obj, const uint8_t *input, const size_t len_in)
2012 const uint8_t *ptr = input;
2013 size_t remaining = len_in;
2014 ssize_t result = 0;
2015 (void)result;
2017 /* Parse u8 n_certs */
2018 CHECK_REMAINING(1, truncated);
2019 obj->n_certs = (trunnel_get_uint8(ptr));
2020 remaining -= 1; ptr += 1;
2022 /* Parse struct certs_cell_cert certs[n_certs] */
2023 TRUNNEL_DYNARRAY_EXPAND(certs_cell_cert_t *, &obj->certs, obj->n_certs, {});
2025 certs_cell_cert_t * elt;
2026 unsigned idx;
2027 for (idx = 0; idx < obj->n_certs; ++idx) {
2028 result = certs_cell_cert_parse(&elt, ptr, remaining);
2029 if (result < 0)
2030 goto relay_fail;
2031 trunnel_assert((size_t)result <= remaining);
2032 remaining -= result; ptr += result;
2033 TRUNNEL_DYNARRAY_ADD(certs_cell_cert_t *, &obj->certs, elt, {certs_cell_cert_free(elt);});
2036 trunnel_assert(ptr + remaining == input + len_in);
2037 return len_in - remaining;
2039 truncated:
2040 return -2;
2041 relay_fail:
2042 trunnel_assert(result < 0);
2043 return result;
2044 trunnel_alloc_failed:
2045 return -1;
2048 ssize_t
2049 certs_cell_parse(certs_cell_t **output, const uint8_t *input, const size_t len_in)
2051 ssize_t result;
2052 *output = certs_cell_new();
2053 if (NULL == *output)
2054 return -1;
2055 result = certs_cell_parse_into(*output, input, len_in);
2056 if (result < 0) {
2057 certs_cell_free(*output);
2058 *output = NULL;
2060 return result;