1 /* link_handshake.c -- generated by Trunnel v1.4.3.
2 * https://gitweb.torproject.org/trunnel.git
3 * You probably shouldn't edit this file.
6 #include "trunnel-impl.h"
8 #include "link_handshake.h"
10 #define TRUNNEL_SET_ERROR_CODE(obj) \
12 (obj)->trunnel_error_code_ = 1; \
15 #if defined(__COVERITY__) || defined(__clang_analyzer__)
16 /* If we're runnning 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__
21 #define OR_DEADCODE_DUMMY
24 #define CHECK_REMAINING(nbytes, label) \
26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
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
));
40 /** Release all storage held inside 'obj', but do not free 'obj'.
43 auth_challenge_cell_clear(auth_challenge_cell_t
*obj
)
46 TRUNNEL_DYNARRAY_WIPE(&obj
->methods
);
47 TRUNNEL_DYNARRAY_CLEAR(&obj
->methods
);
51 auth_challenge_cell_free(auth_challenge_cell_t
*obj
)
55 auth_challenge_cell_clear(obj
);
56 trunnel_memwipe(obj
, sizeof(auth_challenge_cell_t
));
61 auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t
*inp
)
67 auth_challenge_cell_get_challenge(const auth_challenge_cell_t
*inp
, size_t idx
)
69 trunnel_assert(idx
< 32);
70 return inp
->challenge
[idx
];
74 auth_challenge_cell_set_challenge(auth_challenge_cell_t
*inp
, size_t idx
, uint8_t elt
)
76 trunnel_assert(idx
< 32);
77 inp
->challenge
[idx
] = elt
;
82 auth_challenge_cell_getarray_challenge(auth_challenge_cell_t
*inp
)
84 return inp
->challenge
;
87 auth_challenge_cell_get_n_methods(auth_challenge_cell_t
*inp
)
89 return inp
->n_methods
;
92 auth_challenge_cell_set_n_methods(auth_challenge_cell_t
*inp
, uint16_t val
)
98 auth_challenge_cell_getlen_methods(const auth_challenge_cell_t
*inp
)
100 return TRUNNEL_DYNARRAY_LEN(&inp
->methods
);
104 auth_challenge_cell_get_methods(auth_challenge_cell_t
*inp
, size_t idx
)
106 return TRUNNEL_DYNARRAY_GET(&inp
->methods
, idx
);
110 auth_challenge_cell_set_methods(auth_challenge_cell_t
*inp
, size_t idx
, uint16_t elt
)
112 TRUNNEL_DYNARRAY_SET(&inp
->methods
, idx
, elt
);
116 auth_challenge_cell_add_methods(auth_challenge_cell_t
*inp
, uint16_t elt
)
118 #if SIZE_MAX >= UINT16_MAX
119 if (inp
->methods
.n_
== UINT16_MAX
)
120 goto trunnel_alloc_failed
;
122 TRUNNEL_DYNARRAY_ADD(uint16_t, &inp
->methods
, elt
, {});
124 trunnel_alloc_failed
:
125 TRUNNEL_SET_ERROR_CODE(inp
);
130 auth_challenge_cell_getarray_methods(auth_challenge_cell_t
*inp
)
132 return inp
->methods
.elts_
;
135 auth_challenge_cell_setlen_methods(auth_challenge_cell_t
*inp
, size_t newlen
)
138 #if UINT16_MAX < SIZE_MAX
139 if (newlen
> UINT16_MAX
)
140 goto trunnel_alloc_failed
;
142 newptr
= trunnel_dynarray_setlen(&inp
->methods
.allocated_
,
143 &inp
->methods
.n_
, inp
->methods
.elts_
, newlen
,
144 sizeof(inp
->methods
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
145 &inp
->trunnel_error_code_
);
147 goto trunnel_alloc_failed
;
148 inp
->methods
.elts_
= newptr
;
150 trunnel_alloc_failed
:
151 TRUNNEL_SET_ERROR_CODE(inp
);
155 auth_challenge_cell_check(const auth_challenge_cell_t
*obj
)
158 return "Object was NULL";
159 if (obj
->trunnel_error_code_
)
160 return "A set function failed on this object";
161 if (TRUNNEL_DYNARRAY_LEN(&obj
->methods
) != obj
->n_methods
)
162 return "Length mismatch for methods";
167 auth_challenge_cell_encoded_len(const auth_challenge_cell_t
*obj
)
171 if (NULL
!= auth_challenge_cell_check(obj
))
175 /* Length of u8 challenge[32] */
178 /* Length of u16 n_methods */
181 /* Length of u16 methods[n_methods] */
182 result
+= 2 * TRUNNEL_DYNARRAY_LEN(&obj
->methods
);
186 auth_challenge_cell_clear_errors(auth_challenge_cell_t
*obj
)
188 int r
= obj
->trunnel_error_code_
;
189 obj
->trunnel_error_code_
= 0;
193 auth_challenge_cell_encode(uint8_t *output
, const size_t avail
, const auth_challenge_cell_t
*obj
)
197 uint8_t *ptr
= output
;
199 #ifdef TRUNNEL_CHECK_ENCODED_LEN
200 const ssize_t encoded_len
= auth_challenge_cell_encoded_len(obj
);
203 if (NULL
!= (msg
= auth_challenge_cell_check(obj
)))
206 #ifdef TRUNNEL_CHECK_ENCODED_LEN
207 trunnel_assert(encoded_len
>= 0);
210 /* Encode u8 challenge[32] */
211 trunnel_assert(written
<= avail
);
212 if (avail
- written
< 32)
214 memcpy(ptr
, obj
->challenge
, 32);
215 written
+= 32; ptr
+= 32;
217 /* Encode u16 n_methods */
218 trunnel_assert(written
<= avail
);
219 if (avail
- written
< 2)
221 trunnel_set_uint16(ptr
, trunnel_htons(obj
->n_methods
));
222 written
+= 2; ptr
+= 2;
224 /* Encode u16 methods[n_methods] */
228 for (idx
= 0; idx
< TRUNNEL_DYNARRAY_LEN(&obj
->methods
); ++idx
) {
229 trunnel_assert(written
<= avail
);
230 if (avail
- written
< 2)
232 trunnel_set_uint16(ptr
, trunnel_htons(TRUNNEL_DYNARRAY_GET(&obj
->methods
, idx
)));
233 written
+= 2; ptr
+= 2;
238 trunnel_assert(ptr
== output
+ written
);
239 #ifdef TRUNNEL_CHECK_ENCODED_LEN
241 trunnel_assert(encoded_len
>= 0);
242 trunnel_assert((size_t)encoded_len
== written
);
257 trunnel_assert(result
< 0);
261 /** As auth_challenge_cell_parse(), but do not allocate the output
265 auth_challenge_cell_parse_into(auth_challenge_cell_t
*obj
, const uint8_t *input
, const size_t len_in
)
267 const uint8_t *ptr
= input
;
268 size_t remaining
= len_in
;
272 /* Parse u8 challenge[32] */
273 CHECK_REMAINING(32, truncated
);
274 memcpy(obj
->challenge
, ptr
, 32);
275 remaining
-= 32; ptr
+= 32;
277 /* Parse u16 n_methods */
278 CHECK_REMAINING(2, truncated
);
279 obj
->n_methods
= trunnel_ntohs(trunnel_get_uint16(ptr
));
280 remaining
-= 2; ptr
+= 2;
282 /* Parse u16 methods[n_methods] */
283 TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj
->methods
, obj
->n_methods
, {});
287 for (idx
= 0; idx
< obj
->n_methods
; ++idx
) {
288 CHECK_REMAINING(2, truncated
);
289 elt
= trunnel_ntohs(trunnel_get_uint16(ptr
));
290 remaining
-= 2; ptr
+= 2;
291 TRUNNEL_DYNARRAY_ADD(uint16_t, &obj
->methods
, elt
, {});
294 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
295 return len_in
- remaining
;
299 trunnel_alloc_failed
:
304 auth_challenge_cell_parse(auth_challenge_cell_t
**output
, const uint8_t *input
, const size_t len_in
)
307 *output
= auth_challenge_cell_new();
310 result
= auth_challenge_cell_parse_into(*output
, input
, len_in
);
312 auth_challenge_cell_free(*output
);
320 auth_ctx_t
*val
= trunnel_calloc(1, sizeof(auth_ctx_t
));
326 /** Release all storage held inside 'obj', but do not free 'obj'.
329 auth_ctx_clear(auth_ctx_t
*obj
)
335 auth_ctx_free(auth_ctx_t
*obj
)
340 trunnel_memwipe(obj
, sizeof(auth_ctx_t
));
345 auth_ctx_get_is_ed(auth_ctx_t
*inp
)
350 auth_ctx_set_is_ed(auth_ctx_t
*inp
, uint8_t val
)
356 certs_cell_cert_new(void)
358 certs_cell_cert_t
*val
= trunnel_calloc(1, sizeof(certs_cell_cert_t
));
364 /** Release all storage held inside 'obj', but do not free 'obj'.
367 certs_cell_cert_clear(certs_cell_cert_t
*obj
)
370 TRUNNEL_DYNARRAY_WIPE(&obj
->body
);
371 TRUNNEL_DYNARRAY_CLEAR(&obj
->body
);
375 certs_cell_cert_free(certs_cell_cert_t
*obj
)
379 certs_cell_cert_clear(obj
);
380 trunnel_memwipe(obj
, sizeof(certs_cell_cert_t
));
385 certs_cell_cert_get_cert_type(certs_cell_cert_t
*inp
)
387 return inp
->cert_type
;
390 certs_cell_cert_set_cert_type(certs_cell_cert_t
*inp
, uint8_t val
)
392 inp
->cert_type
= val
;
396 certs_cell_cert_get_cert_len(certs_cell_cert_t
*inp
)
398 return inp
->cert_len
;
401 certs_cell_cert_set_cert_len(certs_cell_cert_t
*inp
, uint16_t val
)
407 certs_cell_cert_getlen_body(const certs_cell_cert_t
*inp
)
409 return TRUNNEL_DYNARRAY_LEN(&inp
->body
);
413 certs_cell_cert_get_body(certs_cell_cert_t
*inp
, size_t idx
)
415 return TRUNNEL_DYNARRAY_GET(&inp
->body
, idx
);
419 certs_cell_cert_set_body(certs_cell_cert_t
*inp
, size_t idx
, uint8_t elt
)
421 TRUNNEL_DYNARRAY_SET(&inp
->body
, idx
, elt
);
425 certs_cell_cert_add_body(certs_cell_cert_t
*inp
, uint8_t elt
)
427 #if SIZE_MAX >= UINT16_MAX
428 if (inp
->body
.n_
== UINT16_MAX
)
429 goto trunnel_alloc_failed
;
431 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->body
, elt
, {});
433 trunnel_alloc_failed
:
434 TRUNNEL_SET_ERROR_CODE(inp
);
439 certs_cell_cert_getarray_body(certs_cell_cert_t
*inp
)
441 return inp
->body
.elts_
;
444 certs_cell_cert_setlen_body(certs_cell_cert_t
*inp
, size_t newlen
)
447 #if UINT16_MAX < SIZE_MAX
448 if (newlen
> UINT16_MAX
)
449 goto trunnel_alloc_failed
;
451 newptr
= trunnel_dynarray_setlen(&inp
->body
.allocated_
,
452 &inp
->body
.n_
, inp
->body
.elts_
, newlen
,
453 sizeof(inp
->body
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
454 &inp
->trunnel_error_code_
);
456 goto trunnel_alloc_failed
;
457 inp
->body
.elts_
= newptr
;
459 trunnel_alloc_failed
:
460 TRUNNEL_SET_ERROR_CODE(inp
);
464 certs_cell_cert_check(const certs_cell_cert_t
*obj
)
467 return "Object was NULL";
468 if (obj
->trunnel_error_code_
)
469 return "A set function failed on this object";
470 if (TRUNNEL_DYNARRAY_LEN(&obj
->body
) != obj
->cert_len
)
471 return "Length mismatch for body";
476 certs_cell_cert_encoded_len(const certs_cell_cert_t
*obj
)
480 if (NULL
!= certs_cell_cert_check(obj
))
484 /* Length of u8 cert_type */
487 /* Length of u16 cert_len */
490 /* Length of u8 body[cert_len] */
491 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->body
);
495 certs_cell_cert_clear_errors(certs_cell_cert_t
*obj
)
497 int r
= obj
->trunnel_error_code_
;
498 obj
->trunnel_error_code_
= 0;
502 certs_cell_cert_encode(uint8_t *output
, const size_t avail
, const certs_cell_cert_t
*obj
)
506 uint8_t *ptr
= output
;
508 #ifdef TRUNNEL_CHECK_ENCODED_LEN
509 const ssize_t encoded_len
= certs_cell_cert_encoded_len(obj
);
512 if (NULL
!= (msg
= certs_cell_cert_check(obj
)))
515 #ifdef TRUNNEL_CHECK_ENCODED_LEN
516 trunnel_assert(encoded_len
>= 0);
519 /* Encode u8 cert_type */
520 trunnel_assert(written
<= avail
);
521 if (avail
- written
< 1)
523 trunnel_set_uint8(ptr
, (obj
->cert_type
));
524 written
+= 1; ptr
+= 1;
526 /* Encode u16 cert_len */
527 trunnel_assert(written
<= avail
);
528 if (avail
- written
< 2)
530 trunnel_set_uint16(ptr
, trunnel_htons(obj
->cert_len
));
531 written
+= 2; ptr
+= 2;
533 /* Encode u8 body[cert_len] */
535 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->body
);
536 trunnel_assert(obj
->cert_len
== elt_len
);
537 trunnel_assert(written
<= avail
);
538 if (avail
- written
< elt_len
)
540 memcpy(ptr
, obj
->body
.elts_
, elt_len
);
541 written
+= elt_len
; ptr
+= elt_len
;
545 trunnel_assert(ptr
== output
+ written
);
546 #ifdef TRUNNEL_CHECK_ENCODED_LEN
548 trunnel_assert(encoded_len
>= 0);
549 trunnel_assert((size_t)encoded_len
== written
);
564 trunnel_assert(result
< 0);
568 /** As certs_cell_cert_parse(), but do not allocate the output object.
571 certs_cell_cert_parse_into(certs_cell_cert_t
*obj
, const uint8_t *input
, const size_t len_in
)
573 const uint8_t *ptr
= input
;
574 size_t remaining
= len_in
;
578 /* Parse u8 cert_type */
579 CHECK_REMAINING(1, truncated
);
580 obj
->cert_type
= (trunnel_get_uint8(ptr
));
581 remaining
-= 1; ptr
+= 1;
583 /* Parse u16 cert_len */
584 CHECK_REMAINING(2, truncated
);
585 obj
->cert_len
= trunnel_ntohs(trunnel_get_uint16(ptr
));
586 remaining
-= 2; ptr
+= 2;
588 /* Parse u8 body[cert_len] */
589 CHECK_REMAINING(obj
->cert_len
, truncated
);
590 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->body
, obj
->cert_len
, {});
591 obj
->body
.n_
= obj
->cert_len
;
592 memcpy(obj
->body
.elts_
, ptr
, obj
->cert_len
);
593 ptr
+= obj
->cert_len
; remaining
-= obj
->cert_len
;
594 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
595 return len_in
- remaining
;
599 trunnel_alloc_failed
:
604 certs_cell_cert_parse(certs_cell_cert_t
**output
, const uint8_t *input
, const size_t len_in
)
607 *output
= certs_cell_cert_new();
610 result
= certs_cell_cert_parse_into(*output
, input
, len_in
);
612 certs_cell_cert_free(*output
);
618 rsa_ed_crosscert_new(void)
620 rsa_ed_crosscert_t
*val
= trunnel_calloc(1, sizeof(rsa_ed_crosscert_t
));
626 /** Release all storage held inside 'obj', but do not free 'obj'.
629 rsa_ed_crosscert_clear(rsa_ed_crosscert_t
*obj
)
632 TRUNNEL_DYNARRAY_WIPE(&obj
->sig
);
633 TRUNNEL_DYNARRAY_CLEAR(&obj
->sig
);
637 rsa_ed_crosscert_free(rsa_ed_crosscert_t
*obj
)
641 rsa_ed_crosscert_clear(obj
);
642 trunnel_memwipe(obj
, sizeof(rsa_ed_crosscert_t
));
647 rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t
*inp
)
649 (void)inp
; return 32;
653 rsa_ed_crosscert_get_ed_key(const rsa_ed_crosscert_t
*inp
, size_t idx
)
655 trunnel_assert(idx
< 32);
656 return inp
->ed_key
[idx
];
660 rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t
*inp
, size_t idx
, uint8_t elt
)
662 trunnel_assert(idx
< 32);
663 inp
->ed_key
[idx
] = elt
;
668 rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t
*inp
)
673 rsa_ed_crosscert_get_expiration(rsa_ed_crosscert_t
*inp
)
675 return inp
->expiration
;
678 rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t
*inp
, uint32_t val
)
680 inp
->expiration
= val
;
684 rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t
*inp
)
686 return inp
->end_of_signed
;
689 rsa_ed_crosscert_get_sig_len(rsa_ed_crosscert_t
*inp
)
694 rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t
*inp
, uint8_t val
)
700 rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t
*inp
)
702 return TRUNNEL_DYNARRAY_LEN(&inp
->sig
);
706 rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t
*inp
, size_t idx
)
708 return TRUNNEL_DYNARRAY_GET(&inp
->sig
, idx
);
712 rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t
*inp
, size_t idx
, uint8_t elt
)
714 TRUNNEL_DYNARRAY_SET(&inp
->sig
, idx
, elt
);
718 rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t
*inp
, uint8_t elt
)
720 #if SIZE_MAX >= UINT8_MAX
721 if (inp
->sig
.n_
== UINT8_MAX
)
722 goto trunnel_alloc_failed
;
724 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->sig
, elt
, {});
726 trunnel_alloc_failed
:
727 TRUNNEL_SET_ERROR_CODE(inp
);
732 rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t
*inp
)
734 return inp
->sig
.elts_
;
737 rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t
*inp
, size_t newlen
)
740 #if UINT8_MAX < SIZE_MAX
741 if (newlen
> UINT8_MAX
)
742 goto trunnel_alloc_failed
;
744 newptr
= trunnel_dynarray_setlen(&inp
->sig
.allocated_
,
745 &inp
->sig
.n_
, inp
->sig
.elts_
, newlen
,
746 sizeof(inp
->sig
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
747 &inp
->trunnel_error_code_
);
749 goto trunnel_alloc_failed
;
750 inp
->sig
.elts_
= newptr
;
752 trunnel_alloc_failed
:
753 TRUNNEL_SET_ERROR_CODE(inp
);
757 rsa_ed_crosscert_check(const rsa_ed_crosscert_t
*obj
)
760 return "Object was NULL";
761 if (obj
->trunnel_error_code_
)
762 return "A set function failed on this object";
763 if (TRUNNEL_DYNARRAY_LEN(&obj
->sig
) != obj
->sig_len
)
764 return "Length mismatch for sig";
769 rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t
*obj
)
773 if (NULL
!= rsa_ed_crosscert_check(obj
))
777 /* Length of u8 ed_key[32] */
780 /* Length of u32 expiration */
783 /* Length of u8 sig_len */
786 /* Length of u8 sig[sig_len] */
787 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->sig
);
791 rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t
*obj
)
793 int r
= obj
->trunnel_error_code_
;
794 obj
->trunnel_error_code_
= 0;
798 rsa_ed_crosscert_encode(uint8_t *output
, const size_t avail
, const rsa_ed_crosscert_t
*obj
)
802 uint8_t *ptr
= output
;
804 #ifdef TRUNNEL_CHECK_ENCODED_LEN
805 const ssize_t encoded_len
= rsa_ed_crosscert_encoded_len(obj
);
808 if (NULL
!= (msg
= rsa_ed_crosscert_check(obj
)))
811 #ifdef TRUNNEL_CHECK_ENCODED_LEN
812 trunnel_assert(encoded_len
>= 0);
815 /* Encode u8 ed_key[32] */
816 trunnel_assert(written
<= avail
);
817 if (avail
- written
< 32)
819 memcpy(ptr
, obj
->ed_key
, 32);
820 written
+= 32; ptr
+= 32;
822 /* Encode u32 expiration */
823 trunnel_assert(written
<= avail
);
824 if (avail
- written
< 4)
826 trunnel_set_uint32(ptr
, trunnel_htonl(obj
->expiration
));
827 written
+= 4; ptr
+= 4;
829 /* Encode u8 sig_len */
830 trunnel_assert(written
<= avail
);
831 if (avail
- written
< 1)
833 trunnel_set_uint8(ptr
, (obj
->sig_len
));
834 written
+= 1; ptr
+= 1;
836 /* Encode u8 sig[sig_len] */
838 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->sig
);
839 trunnel_assert(obj
->sig_len
== elt_len
);
840 trunnel_assert(written
<= avail
);
841 if (avail
- written
< elt_len
)
843 memcpy(ptr
, obj
->sig
.elts_
, elt_len
);
844 written
+= elt_len
; ptr
+= elt_len
;
848 trunnel_assert(ptr
== output
+ written
);
849 #ifdef TRUNNEL_CHECK_ENCODED_LEN
851 trunnel_assert(encoded_len
>= 0);
852 trunnel_assert((size_t)encoded_len
== written
);
867 trunnel_assert(result
< 0);
871 /** As rsa_ed_crosscert_parse(), but do not allocate the output
875 rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t
*obj
, const uint8_t *input
, const size_t len_in
)
877 const uint8_t *ptr
= input
;
878 size_t remaining
= len_in
;
882 /* Parse u8 ed_key[32] */
883 CHECK_REMAINING(32, truncated
);
884 memcpy(obj
->ed_key
, ptr
, 32);
885 remaining
-= 32; ptr
+= 32;
887 /* Parse u32 expiration */
888 CHECK_REMAINING(4, truncated
);
889 obj
->expiration
= trunnel_ntohl(trunnel_get_uint32(ptr
));
890 remaining
-= 4; ptr
+= 4;
891 obj
->end_of_signed
= ptr
;
893 /* Parse u8 sig_len */
894 CHECK_REMAINING(1, truncated
);
895 obj
->sig_len
= (trunnel_get_uint8(ptr
));
896 remaining
-= 1; ptr
+= 1;
898 /* Parse u8 sig[sig_len] */
899 CHECK_REMAINING(obj
->sig_len
, truncated
);
900 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->sig
, obj
->sig_len
, {});
901 obj
->sig
.n_
= obj
->sig_len
;
902 memcpy(obj
->sig
.elts_
, ptr
, obj
->sig_len
);
903 ptr
+= obj
->sig_len
; remaining
-= obj
->sig_len
;
904 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
905 return len_in
- remaining
;
909 trunnel_alloc_failed
:
914 rsa_ed_crosscert_parse(rsa_ed_crosscert_t
**output
, const uint8_t *input
, const size_t len_in
)
917 *output
= rsa_ed_crosscert_new();
920 result
= rsa_ed_crosscert_parse_into(*output
, input
, len_in
);
922 rsa_ed_crosscert_free(*output
);
930 auth1_t
*val
= trunnel_calloc(1, sizeof(auth1_t
));
936 /** Release all storage held inside 'obj', but do not free 'obj'.
939 auth1_clear(auth1_t
*obj
)
942 TRUNNEL_DYNARRAY_WIPE(&obj
->sig
);
943 TRUNNEL_DYNARRAY_CLEAR(&obj
->sig
);
947 auth1_free(auth1_t
*obj
)
952 trunnel_memwipe(obj
, sizeof(auth1_t
));
957 auth1_getlen_type(const auth1_t
*inp
)
963 auth1_get_type(const auth1_t
*inp
, size_t idx
)
965 trunnel_assert(idx
< 8);
966 return inp
->type
[idx
];
970 auth1_set_type(auth1_t
*inp
, size_t idx
, uint8_t elt
)
972 trunnel_assert(idx
< 8);
973 inp
->type
[idx
] = elt
;
978 auth1_getarray_type(auth1_t
*inp
)
983 auth1_getlen_cid(const auth1_t
*inp
)
985 (void)inp
; return 32;
989 auth1_get_cid(const auth1_t
*inp
, size_t idx
)
991 trunnel_assert(idx
< 32);
992 return inp
->cid
[idx
];
996 auth1_set_cid(auth1_t
*inp
, size_t idx
, uint8_t elt
)
998 trunnel_assert(idx
< 32);
1004 auth1_getarray_cid(auth1_t
*inp
)
1009 auth1_getlen_sid(const auth1_t
*inp
)
1011 (void)inp
; return 32;
1015 auth1_get_sid(const auth1_t
*inp
, size_t idx
)
1017 trunnel_assert(idx
< 32);
1018 return inp
->sid
[idx
];
1022 auth1_set_sid(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1024 trunnel_assert(idx
< 32);
1025 inp
->sid
[idx
] = elt
;
1030 auth1_getarray_sid(auth1_t
*inp
)
1035 auth1_getlen_u1_cid_ed(const auth1_t
*inp
)
1037 (void)inp
; return 32;
1041 auth1_get_u1_cid_ed(const auth1_t
*inp
, size_t idx
)
1043 trunnel_assert(idx
< 32);
1044 return inp
->u1_cid_ed
[idx
];
1048 auth1_set_u1_cid_ed(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1050 trunnel_assert(idx
< 32);
1051 inp
->u1_cid_ed
[idx
] = elt
;
1056 auth1_getarray_u1_cid_ed(auth1_t
*inp
)
1058 return inp
->u1_cid_ed
;
1061 auth1_getlen_u1_sid_ed(const auth1_t
*inp
)
1063 (void)inp
; return 32;
1067 auth1_get_u1_sid_ed(const auth1_t
*inp
, size_t idx
)
1069 trunnel_assert(idx
< 32);
1070 return inp
->u1_sid_ed
[idx
];
1074 auth1_set_u1_sid_ed(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1076 trunnel_assert(idx
< 32);
1077 inp
->u1_sid_ed
[idx
] = elt
;
1082 auth1_getarray_u1_sid_ed(auth1_t
*inp
)
1084 return inp
->u1_sid_ed
;
1087 auth1_getlen_slog(const auth1_t
*inp
)
1089 (void)inp
; return 32;
1093 auth1_get_slog(const auth1_t
*inp
, size_t idx
)
1095 trunnel_assert(idx
< 32);
1096 return inp
->slog
[idx
];
1100 auth1_set_slog(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1102 trunnel_assert(idx
< 32);
1103 inp
->slog
[idx
] = elt
;
1108 auth1_getarray_slog(auth1_t
*inp
)
1113 auth1_getlen_clog(const auth1_t
*inp
)
1115 (void)inp
; return 32;
1119 auth1_get_clog(const auth1_t
*inp
, size_t idx
)
1121 trunnel_assert(idx
< 32);
1122 return inp
->clog
[idx
];
1126 auth1_set_clog(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1128 trunnel_assert(idx
< 32);
1129 inp
->clog
[idx
] = elt
;
1134 auth1_getarray_clog(auth1_t
*inp
)
1139 auth1_getlen_scert(const auth1_t
*inp
)
1141 (void)inp
; return 32;
1145 auth1_get_scert(const auth1_t
*inp
, size_t idx
)
1147 trunnel_assert(idx
< 32);
1148 return inp
->scert
[idx
];
1152 auth1_set_scert(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1154 trunnel_assert(idx
< 32);
1155 inp
->scert
[idx
] = elt
;
1160 auth1_getarray_scert(auth1_t
*inp
)
1165 auth1_getlen_tlssecrets(const auth1_t
*inp
)
1167 (void)inp
; return 32;
1171 auth1_get_tlssecrets(const auth1_t
*inp
, size_t idx
)
1173 trunnel_assert(idx
< 32);
1174 return inp
->tlssecrets
[idx
];
1178 auth1_set_tlssecrets(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1180 trunnel_assert(idx
< 32);
1181 inp
->tlssecrets
[idx
] = elt
;
1186 auth1_getarray_tlssecrets(auth1_t
*inp
)
1188 return inp
->tlssecrets
;
1191 auth1_get_end_of_fixed_part(const auth1_t
*inp
)
1193 return inp
->end_of_fixed_part
;
1196 auth1_getlen_rand(const auth1_t
*inp
)
1198 (void)inp
; return 24;
1202 auth1_get_rand(const auth1_t
*inp
, size_t idx
)
1204 trunnel_assert(idx
< 24);
1205 return inp
->rand
[idx
];
1209 auth1_set_rand(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1211 trunnel_assert(idx
< 24);
1212 inp
->rand
[idx
] = elt
;
1217 auth1_getarray_rand(auth1_t
*inp
)
1222 auth1_get_end_of_signed(const auth1_t
*inp
)
1224 return inp
->end_of_signed
;
1227 auth1_getlen_sig(const auth1_t
*inp
)
1229 return TRUNNEL_DYNARRAY_LEN(&inp
->sig
);
1233 auth1_get_sig(auth1_t
*inp
, size_t idx
)
1235 return TRUNNEL_DYNARRAY_GET(&inp
->sig
, idx
);
1239 auth1_set_sig(auth1_t
*inp
, size_t idx
, uint8_t elt
)
1241 TRUNNEL_DYNARRAY_SET(&inp
->sig
, idx
, elt
);
1245 auth1_add_sig(auth1_t
*inp
, uint8_t elt
)
1247 TRUNNEL_DYNARRAY_ADD(uint8_t, &inp
->sig
, elt
, {});
1249 trunnel_alloc_failed
:
1250 TRUNNEL_SET_ERROR_CODE(inp
);
1255 auth1_getarray_sig(auth1_t
*inp
)
1257 return inp
->sig
.elts_
;
1260 auth1_setlen_sig(auth1_t
*inp
, size_t newlen
)
1263 newptr
= trunnel_dynarray_setlen(&inp
->sig
.allocated_
,
1264 &inp
->sig
.n_
, inp
->sig
.elts_
, newlen
,
1265 sizeof(inp
->sig
.elts_
[0]), (trunnel_free_fn_t
) NULL
,
1266 &inp
->trunnel_error_code_
);
1268 goto trunnel_alloc_failed
;
1269 inp
->sig
.elts_
= newptr
;
1271 trunnel_alloc_failed
:
1272 TRUNNEL_SET_ERROR_CODE(inp
);
1276 auth1_check(const auth1_t
*obj
, const auth_ctx_t
*auth_ctx_ctx
)
1279 return "Object was NULL";
1280 if (obj
->trunnel_error_code_
)
1281 return "A set function failed on this object";
1282 if (auth_ctx_ctx
== NULL
)
1283 return "Context was NULL";
1284 switch (auth_ctx_ctx
->is_ed
) {
1293 return "Bad tag for union";
1300 auth1_encoded_len(const auth1_t
*obj
, const auth_ctx_t
*auth_ctx_ctx
)
1304 if (NULL
!= auth1_check(obj
, auth_ctx_ctx
))
1308 /* Length of u8 type[8] */
1311 /* Length of u8 cid[32] */
1314 /* Length of u8 sid[32] */
1316 switch (auth_ctx_ctx
->is_ed
) {
1323 /* Length of u8 u1_cid_ed[32] */
1326 /* Length of u8 u1_sid_ed[32] */
1335 /* Length of u8 slog[32] */
1338 /* Length of u8 clog[32] */
1341 /* Length of u8 scert[32] */
1344 /* Length of u8 tlssecrets[32] */
1347 /* Length of u8 rand[24] */
1350 /* Length of u8 sig[] */
1351 result
+= TRUNNEL_DYNARRAY_LEN(&obj
->sig
);
1355 auth1_clear_errors(auth1_t
*obj
)
1357 int r
= obj
->trunnel_error_code_
;
1358 obj
->trunnel_error_code_
= 0;
1362 auth1_encode(uint8_t *output
, const size_t avail
, const auth1_t
*obj
, const auth_ctx_t
*auth_ctx_ctx
)
1366 uint8_t *ptr
= output
;
1368 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1369 const ssize_t encoded_len
= auth1_encoded_len(obj
, auth_ctx_ctx
);
1372 if (NULL
!= (msg
= auth1_check(obj
, auth_ctx_ctx
)))
1375 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1376 trunnel_assert(encoded_len
>= 0);
1379 /* Encode u8 type[8] */
1380 trunnel_assert(written
<= avail
);
1381 if (avail
- written
< 8)
1383 memcpy(ptr
, obj
->type
, 8);
1384 written
+= 8; ptr
+= 8;
1386 /* Encode u8 cid[32] */
1387 trunnel_assert(written
<= avail
);
1388 if (avail
- written
< 32)
1390 memcpy(ptr
, obj
->cid
, 32);
1391 written
+= 32; ptr
+= 32;
1393 /* Encode u8 sid[32] */
1394 trunnel_assert(written
<= avail
);
1395 if (avail
- written
< 32)
1397 memcpy(ptr
, obj
->sid
, 32);
1398 written
+= 32; ptr
+= 32;
1400 /* Encode union u1[auth_ctx.is_ed] */
1401 trunnel_assert(written
<= avail
);
1402 switch (auth_ctx_ctx
->is_ed
) {
1409 /* Encode u8 u1_cid_ed[32] */
1410 trunnel_assert(written
<= avail
);
1411 if (avail
- written
< 32)
1413 memcpy(ptr
, obj
->u1_cid_ed
, 32);
1414 written
+= 32; ptr
+= 32;
1416 /* Encode u8 u1_sid_ed[32] */
1417 trunnel_assert(written
<= avail
);
1418 if (avail
- written
< 32)
1420 memcpy(ptr
, obj
->u1_sid_ed
, 32);
1421 written
+= 32; ptr
+= 32;
1429 /* Encode u8 slog[32] */
1430 trunnel_assert(written
<= avail
);
1431 if (avail
- written
< 32)
1433 memcpy(ptr
, obj
->slog
, 32);
1434 written
+= 32; ptr
+= 32;
1436 /* Encode u8 clog[32] */
1437 trunnel_assert(written
<= avail
);
1438 if (avail
- written
< 32)
1440 memcpy(ptr
, obj
->clog
, 32);
1441 written
+= 32; ptr
+= 32;
1443 /* Encode u8 scert[32] */
1444 trunnel_assert(written
<= avail
);
1445 if (avail
- written
< 32)
1447 memcpy(ptr
, obj
->scert
, 32);
1448 written
+= 32; ptr
+= 32;
1450 /* Encode u8 tlssecrets[32] */
1451 trunnel_assert(written
<= avail
);
1452 if (avail
- written
< 32)
1454 memcpy(ptr
, obj
->tlssecrets
, 32);
1455 written
+= 32; ptr
+= 32;
1457 /* Encode u8 rand[24] */
1458 trunnel_assert(written
<= avail
);
1459 if (avail
- written
< 24)
1461 memcpy(ptr
, obj
->rand
, 24);
1462 written
+= 24; ptr
+= 24;
1464 /* Encode u8 sig[] */
1466 size_t elt_len
= TRUNNEL_DYNARRAY_LEN(&obj
->sig
);
1467 trunnel_assert(written
<= avail
);
1468 if (avail
- written
< elt_len
)
1470 memcpy(ptr
, obj
->sig
.elts_
, elt_len
);
1471 written
+= elt_len
; ptr
+= elt_len
;
1475 trunnel_assert(ptr
== output
+ written
);
1476 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1478 trunnel_assert(encoded_len
>= 0);
1479 trunnel_assert((size_t)encoded_len
== written
);
1494 trunnel_assert(result
< 0);
1498 /** As auth1_parse(), but do not allocate the output object.
1501 auth1_parse_into(auth1_t
*obj
, const uint8_t *input
, const size_t len_in
, const auth_ctx_t
*auth_ctx_ctx
)
1503 const uint8_t *ptr
= input
;
1504 size_t remaining
= len_in
;
1507 if (auth_ctx_ctx
== NULL
)
1510 /* Parse u8 type[8] */
1511 CHECK_REMAINING(8, truncated
);
1512 memcpy(obj
->type
, ptr
, 8);
1513 remaining
-= 8; ptr
+= 8;
1515 /* Parse u8 cid[32] */
1516 CHECK_REMAINING(32, truncated
);
1517 memcpy(obj
->cid
, ptr
, 32);
1518 remaining
-= 32; ptr
+= 32;
1520 /* Parse u8 sid[32] */
1521 CHECK_REMAINING(32, truncated
);
1522 memcpy(obj
->sid
, ptr
, 32);
1523 remaining
-= 32; ptr
+= 32;
1525 /* Parse union u1[auth_ctx.is_ed] */
1526 switch (auth_ctx_ctx
->is_ed
) {
1533 /* Parse u8 u1_cid_ed[32] */
1534 CHECK_REMAINING(32, truncated
);
1535 memcpy(obj
->u1_cid_ed
, ptr
, 32);
1536 remaining
-= 32; ptr
+= 32;
1538 /* Parse u8 u1_sid_ed[32] */
1539 CHECK_REMAINING(32, truncated
);
1540 memcpy(obj
->u1_sid_ed
, ptr
, 32);
1541 remaining
-= 32; ptr
+= 32;
1549 /* Parse u8 slog[32] */
1550 CHECK_REMAINING(32, truncated
);
1551 memcpy(obj
->slog
, ptr
, 32);
1552 remaining
-= 32; ptr
+= 32;
1554 /* Parse u8 clog[32] */
1555 CHECK_REMAINING(32, truncated
);
1556 memcpy(obj
->clog
, ptr
, 32);
1557 remaining
-= 32; ptr
+= 32;
1559 /* Parse u8 scert[32] */
1560 CHECK_REMAINING(32, truncated
);
1561 memcpy(obj
->scert
, ptr
, 32);
1562 remaining
-= 32; ptr
+= 32;
1564 /* Parse u8 tlssecrets[32] */
1565 CHECK_REMAINING(32, truncated
);
1566 memcpy(obj
->tlssecrets
, ptr
, 32);
1567 remaining
-= 32; ptr
+= 32;
1568 obj
->end_of_fixed_part
= ptr
;
1570 /* Parse u8 rand[24] */
1571 CHECK_REMAINING(24, truncated
);
1572 memcpy(obj
->rand
, ptr
, 24);
1573 remaining
-= 24; ptr
+= 24;
1574 obj
->end_of_signed
= ptr
;
1576 /* Parse u8 sig[] */
1577 TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj
->sig
, remaining
, {});
1578 obj
->sig
.n_
= remaining
;
1579 memcpy(obj
->sig
.elts_
, ptr
, remaining
);
1580 ptr
+= remaining
; remaining
-= remaining
;
1581 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
1582 return len_in
- remaining
;
1586 trunnel_alloc_failed
:
1594 auth1_parse(auth1_t
**output
, const uint8_t *input
, const size_t len_in
, const auth_ctx_t
*auth_ctx_ctx
)
1597 *output
= auth1_new();
1598 if (NULL
== *output
)
1600 result
= auth1_parse_into(*output
, input
, len_in
, auth_ctx_ctx
);
1602 auth1_free(*output
);
1608 certs_cell_new(void)
1610 certs_cell_t
*val
= trunnel_calloc(1, sizeof(certs_cell_t
));
1616 /** Release all storage held inside 'obj', but do not free 'obj'.
1619 certs_cell_clear(certs_cell_t
*obj
)
1625 for (idx
= 0; idx
< TRUNNEL_DYNARRAY_LEN(&obj
->certs
); ++idx
) {
1626 certs_cell_cert_free(TRUNNEL_DYNARRAY_GET(&obj
->certs
, idx
));
1629 TRUNNEL_DYNARRAY_WIPE(&obj
->certs
);
1630 TRUNNEL_DYNARRAY_CLEAR(&obj
->certs
);
1634 certs_cell_free(certs_cell_t
*obj
)
1638 certs_cell_clear(obj
);
1639 trunnel_memwipe(obj
, sizeof(certs_cell_t
));
1644 certs_cell_get_n_certs(certs_cell_t
*inp
)
1646 return inp
->n_certs
;
1649 certs_cell_set_n_certs(certs_cell_t
*inp
, uint8_t val
)
1655 certs_cell_getlen_certs(const certs_cell_t
*inp
)
1657 return TRUNNEL_DYNARRAY_LEN(&inp
->certs
);
1660 struct certs_cell_cert_st
*
1661 certs_cell_get_certs(certs_cell_t
*inp
, size_t idx
)
1663 return TRUNNEL_DYNARRAY_GET(&inp
->certs
, idx
);
1667 certs_cell_set_certs(certs_cell_t
*inp
, size_t idx
, struct certs_cell_cert_st
* elt
)
1669 certs_cell_cert_t
*oldval
= TRUNNEL_DYNARRAY_GET(&inp
->certs
, idx
);
1670 if (oldval
&& oldval
!= elt
)
1671 certs_cell_cert_free(oldval
);
1672 return certs_cell_set0_certs(inp
, idx
, elt
);
1675 certs_cell_set0_certs(certs_cell_t
*inp
, size_t idx
, struct certs_cell_cert_st
* elt
)
1677 TRUNNEL_DYNARRAY_SET(&inp
->certs
, idx
, elt
);
1681 certs_cell_add_certs(certs_cell_t
*inp
, struct certs_cell_cert_st
* elt
)
1683 #if SIZE_MAX >= UINT8_MAX
1684 if (inp
->certs
.n_
== UINT8_MAX
)
1685 goto trunnel_alloc_failed
;
1687 TRUNNEL_DYNARRAY_ADD(struct certs_cell_cert_st
*, &inp
->certs
, elt
, {});
1689 trunnel_alloc_failed
:
1690 TRUNNEL_SET_ERROR_CODE(inp
);
1694 struct certs_cell_cert_st
* *
1695 certs_cell_getarray_certs(certs_cell_t
*inp
)
1697 return inp
->certs
.elts_
;
1700 certs_cell_setlen_certs(certs_cell_t
*inp
, size_t newlen
)
1702 struct certs_cell_cert_st
* *newptr
;
1703 #if UINT8_MAX < SIZE_MAX
1704 if (newlen
> UINT8_MAX
)
1705 goto trunnel_alloc_failed
;
1707 newptr
= trunnel_dynarray_setlen(&inp
->certs
.allocated_
,
1708 &inp
->certs
.n_
, inp
->certs
.elts_
, newlen
,
1709 sizeof(inp
->certs
.elts_
[0]), (trunnel_free_fn_t
) certs_cell_cert_free
,
1710 &inp
->trunnel_error_code_
);
1712 goto trunnel_alloc_failed
;
1713 inp
->certs
.elts_
= newptr
;
1715 trunnel_alloc_failed
:
1716 TRUNNEL_SET_ERROR_CODE(inp
);
1720 certs_cell_check(const certs_cell_t
*obj
)
1723 return "Object was NULL";
1724 if (obj
->trunnel_error_code_
)
1725 return "A set function failed on this object";
1730 for (idx
= 0; idx
< TRUNNEL_DYNARRAY_LEN(&obj
->certs
); ++idx
) {
1731 if (NULL
!= (msg
= certs_cell_cert_check(TRUNNEL_DYNARRAY_GET(&obj
->certs
, idx
))))
1735 if (TRUNNEL_DYNARRAY_LEN(&obj
->certs
) != obj
->n_certs
)
1736 return "Length mismatch for certs";
1741 certs_cell_encoded_len(const certs_cell_t
*obj
)
1745 if (NULL
!= certs_cell_check(obj
))
1749 /* Length of u8 n_certs */
1752 /* Length of struct certs_cell_cert certs[n_certs] */
1756 for (idx
= 0; idx
< TRUNNEL_DYNARRAY_LEN(&obj
->certs
); ++idx
) {
1757 result
+= certs_cell_cert_encoded_len(TRUNNEL_DYNARRAY_GET(&obj
->certs
, idx
));
1763 certs_cell_clear_errors(certs_cell_t
*obj
)
1765 int r
= obj
->trunnel_error_code_
;
1766 obj
->trunnel_error_code_
= 0;
1770 certs_cell_encode(uint8_t *output
, const size_t avail
, const certs_cell_t
*obj
)
1774 uint8_t *ptr
= output
;
1776 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1777 const ssize_t encoded_len
= certs_cell_encoded_len(obj
);
1780 if (NULL
!= (msg
= certs_cell_check(obj
)))
1783 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1784 trunnel_assert(encoded_len
>= 0);
1787 /* Encode u8 n_certs */
1788 trunnel_assert(written
<= avail
);
1789 if (avail
- written
< 1)
1791 trunnel_set_uint8(ptr
, (obj
->n_certs
));
1792 written
+= 1; ptr
+= 1;
1794 /* Encode struct certs_cell_cert certs[n_certs] */
1798 for (idx
= 0; idx
< TRUNNEL_DYNARRAY_LEN(&obj
->certs
); ++idx
) {
1799 trunnel_assert(written
<= avail
);
1800 result
= certs_cell_cert_encode(ptr
, avail
- written
, TRUNNEL_DYNARRAY_GET(&obj
->certs
, idx
));
1802 goto fail
; /* XXXXXXX !*/
1803 written
+= result
; ptr
+= result
;
1808 trunnel_assert(ptr
== output
+ written
);
1809 #ifdef TRUNNEL_CHECK_ENCODED_LEN
1811 trunnel_assert(encoded_len
>= 0);
1812 trunnel_assert((size_t)encoded_len
== written
);
1827 trunnel_assert(result
< 0);
1831 /** As certs_cell_parse(), but do not allocate the output object.
1834 certs_cell_parse_into(certs_cell_t
*obj
, const uint8_t *input
, const size_t len_in
)
1836 const uint8_t *ptr
= input
;
1837 size_t remaining
= len_in
;
1841 /* Parse u8 n_certs */
1842 CHECK_REMAINING(1, truncated
);
1843 obj
->n_certs
= (trunnel_get_uint8(ptr
));
1844 remaining
-= 1; ptr
+= 1;
1846 /* Parse struct certs_cell_cert certs[n_certs] */
1847 TRUNNEL_DYNARRAY_EXPAND(certs_cell_cert_t
*, &obj
->certs
, obj
->n_certs
, {});
1849 certs_cell_cert_t
* elt
;
1851 for (idx
= 0; idx
< obj
->n_certs
; ++idx
) {
1852 result
= certs_cell_cert_parse(&elt
, ptr
, remaining
);
1855 trunnel_assert((size_t)result
<= remaining
);
1856 remaining
-= result
; ptr
+= result
;
1857 TRUNNEL_DYNARRAY_ADD(certs_cell_cert_t
*, &obj
->certs
, elt
, {certs_cell_cert_free(elt
);});
1860 trunnel_assert(ptr
+ remaining
== input
+ len_in
);
1861 return len_in
- remaining
;
1866 trunnel_assert(result
< 0);
1868 trunnel_alloc_failed
:
1873 certs_cell_parse(certs_cell_t
**output
, const uint8_t *input
, const size_t len_in
)
1876 *output
= certs_cell_new();
1877 if (NULL
== *output
)
1879 result
= certs_cell_parse_into(*output
, input
, len_in
);
1881 certs_cell_free(*output
);