LCOV - code coverage report
Current view: top level - trunnel - link_handshake.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 548 970 56.5 %
Date: 2021-11-24 03:28:48 Functions: 67 177 37.9 %

          Line data    Source code
       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"
       7             : 
       8             : #include "link_handshake.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 linkhandshake_deadcode_dummy__ = 0;
      19             : #define OR_DEADCODE_DUMMY || linkhandshake_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             : auth_challenge_cell_t *
      32           8 : auth_challenge_cell_new(void)
      33             : {
      34           8 :   auth_challenge_cell_t *val = trunnel_calloc(1, sizeof(auth_challenge_cell_t));
      35           8 :   if (NULL == val)
      36           0 :     return NULL;
      37             :   return val;
      38             : }
      39             : 
      40             : /** Release all storage held inside 'obj', but do not free 'obj'.
      41             :  */
      42             : static void
      43           8 : auth_challenge_cell_clear(auth_challenge_cell_t *obj)
      44             : {
      45           8 :   (void) obj;
      46           8 :   TRUNNEL_DYNARRAY_WIPE(&obj->methods);
      47           8 :   TRUNNEL_DYNARRAY_CLEAR(&obj->methods);
      48           8 : }
      49             : 
      50             : void
      51          16 : auth_challenge_cell_free(auth_challenge_cell_t *obj)
      52             : {
      53          16 :   if (obj == NULL)
      54             :     return;
      55           8 :   auth_challenge_cell_clear(obj);
      56           8 :   trunnel_memwipe(obj, sizeof(auth_challenge_cell_t));
      57           8 :   trunnel_free_(obj);
      58             : }
      59             : 
      60             : size_t
      61           0 : auth_challenge_cell_getlen_challenge(const auth_challenge_cell_t *inp)
      62             : {
      63           0 :   (void)inp;  return 32;
      64             : }
      65             : 
      66             : uint8_t
      67           0 : auth_challenge_cell_get_challenge(auth_challenge_cell_t *inp, size_t idx)
      68             : {
      69           0 :   trunnel_assert(idx < 32);
      70           0 :   return inp->challenge[idx];
      71             : }
      72             : 
      73             : uint8_t
      74           0 : auth_challenge_cell_getconst_challenge(const auth_challenge_cell_t *inp, size_t idx)
      75             : {
      76           0 :   return auth_challenge_cell_get_challenge((auth_challenge_cell_t*)inp, idx);
      77             : }
      78             : int
      79           0 : auth_challenge_cell_set_challenge(auth_challenge_cell_t *inp, size_t idx, uint8_t elt)
      80             : {
      81           0 :   trunnel_assert(idx < 32);
      82           0 :   inp->challenge[idx] = elt;
      83           0 :   return 0;
      84             : }
      85             : 
      86             : uint8_t *
      87           0 : auth_challenge_cell_getarray_challenge(auth_challenge_cell_t *inp)
      88             : {
      89           0 :   return inp->challenge;
      90             : }
      91             : const uint8_t  *
      92           0 : auth_challenge_cell_getconstarray_challenge(const auth_challenge_cell_t *inp)
      93             : {
      94           0 :   return (const uint8_t  *)auth_challenge_cell_getarray_challenge((auth_challenge_cell_t*)inp);
      95             : }
      96             : uint16_t
      97           0 : auth_challenge_cell_get_n_methods(const auth_challenge_cell_t *inp)
      98             : {
      99           0 :   return inp->n_methods;
     100             : }
     101             : int
     102           2 : auth_challenge_cell_set_n_methods(auth_challenge_cell_t *inp, uint16_t val)
     103             : {
     104           2 :   inp->n_methods = val;
     105           2 :   return 0;
     106             : }
     107             : size_t
     108           2 : auth_challenge_cell_getlen_methods(const auth_challenge_cell_t *inp)
     109             : {
     110           2 :   return TRUNNEL_DYNARRAY_LEN(&inp->methods);
     111             : }
     112             : 
     113             : uint16_t
     114           9 : auth_challenge_cell_get_methods(auth_challenge_cell_t *inp, size_t idx)
     115             : {
     116           9 :   return TRUNNEL_DYNARRAY_GET(&inp->methods, idx);
     117             : }
     118             : 
     119             : uint16_t
     120           0 : auth_challenge_cell_getconst_methods(const auth_challenge_cell_t *inp, size_t idx)
     121             : {
     122           0 :   return auth_challenge_cell_get_methods((auth_challenge_cell_t*)inp, idx);
     123             : }
     124             : int
     125           0 : auth_challenge_cell_set_methods(auth_challenge_cell_t *inp, size_t idx, uint16_t elt)
     126             : {
     127           0 :   TRUNNEL_DYNARRAY_SET(&inp->methods, idx, elt);
     128           0 :   return 0;
     129             : }
     130             : int
     131           4 : auth_challenge_cell_add_methods(auth_challenge_cell_t *inp, uint16_t elt)
     132             : {
     133             : #if SIZE_MAX >= UINT16_MAX
     134           4 :   if (inp->methods.n_ == UINT16_MAX)
     135           0 :     goto trunnel_alloc_failed;
     136             : #endif
     137           4 :   TRUNNEL_DYNARRAY_ADD(uint16_t, &inp->methods, elt, {});
     138           4 :   return 0;
     139           0 :  trunnel_alloc_failed:
     140           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     141           0 :   return -1;
     142             : }
     143             : 
     144             : uint16_t *
     145           0 : auth_challenge_cell_getarray_methods(auth_challenge_cell_t *inp)
     146             : {
     147           0 :   return inp->methods.elts_;
     148             : }
     149             : const uint16_t  *
     150           0 : auth_challenge_cell_getconstarray_methods(const auth_challenge_cell_t *inp)
     151             : {
     152           0 :   return (const uint16_t  *)auth_challenge_cell_getarray_methods((auth_challenge_cell_t*)inp);
     153             : }
     154             : int
     155           0 : auth_challenge_cell_setlen_methods(auth_challenge_cell_t *inp, size_t newlen)
     156             : {
     157           0 :   uint16_t *newptr;
     158             : #if UINT16_MAX < SIZE_MAX
     159           0 :   if (newlen > UINT16_MAX)
     160           0 :     goto trunnel_alloc_failed;
     161             : #endif
     162           0 :   newptr = trunnel_dynarray_setlen(&inp->methods.allocated_,
     163           0 :                  &inp->methods.n_, inp->methods.elts_, newlen,
     164             :                  sizeof(inp->methods.elts_[0]), (trunnel_free_fn_t) NULL,
     165             :                  &inp->trunnel_error_code_);
     166           0 :   if (newlen != 0 && newptr == NULL)
     167           0 :     goto trunnel_alloc_failed;
     168           0 :   inp->methods.elts_ = newptr;
     169           0 :   return 0;
     170           0 :  trunnel_alloc_failed:
     171           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     172           0 :   return -1;
     173             : }
     174             : const char *
     175           4 : auth_challenge_cell_check(const auth_challenge_cell_t *obj)
     176             : {
     177           4 :   if (obj == NULL)
     178             :     return "Object was NULL";
     179           4 :   if (obj->trunnel_error_code_)
     180             :     return "A set function failed on this object";
     181           4 :   if (TRUNNEL_DYNARRAY_LEN(&obj->methods) != obj->n_methods)
     182           0 :     return "Length mismatch for methods";
     183             :   return NULL;
     184             : }
     185             : 
     186             : ssize_t
     187           2 : auth_challenge_cell_encoded_len(const auth_challenge_cell_t *obj)
     188             : {
     189           2 :   ssize_t result = 0;
     190             : 
     191           2 :   if (NULL != auth_challenge_cell_check(obj))
     192             :      return -1;
     193             : 
     194             : 
     195             :   /* Length of u8 challenge[32] */
     196           2 :   result += 32;
     197             : 
     198             :   /* Length of u16 n_methods */
     199           2 :   result += 2;
     200             : 
     201             :   /* Length of u16 methods[n_methods] */
     202           2 :   result += 2 * TRUNNEL_DYNARRAY_LEN(&obj->methods);
     203           2 :   return result;
     204             : }
     205             : int
     206           0 : auth_challenge_cell_clear_errors(auth_challenge_cell_t *obj)
     207             : {
     208           0 :   int r = obj->trunnel_error_code_;
     209           0 :   obj->trunnel_error_code_ = 0;
     210           0 :   return r;
     211             : }
     212             : ssize_t
     213           2 : auth_challenge_cell_encode(uint8_t *output, const size_t avail, const auth_challenge_cell_t *obj)
     214             : {
     215           2 :   ssize_t result = 0;
     216           2 :   size_t written = 0;
     217           2 :   uint8_t *ptr = output;
     218           2 :   const char *msg;
     219             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     220             :   const ssize_t encoded_len = auth_challenge_cell_encoded_len(obj);
     221             : #endif
     222             : 
     223           2 :   if (NULL != (msg = auth_challenge_cell_check(obj)))
     224           0 :     goto check_failed;
     225             : 
     226             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     227             :   trunnel_assert(encoded_len >= 0);
     228             : #endif
     229             : 
     230             :   /* Encode u8 challenge[32] */
     231           2 :   trunnel_assert(written <= avail);
     232           2 :   if (avail - written < 32)
     233           0 :     goto truncated;
     234           2 :   memcpy(ptr, obj->challenge, 32);
     235           2 :   written += 32; ptr += 32;
     236             : 
     237             :   /* Encode u16 n_methods */
     238           2 :   trunnel_assert(written <= avail);
     239           2 :   if (avail - written < 2)
     240           0 :     goto truncated;
     241           2 :   trunnel_set_uint16(ptr, trunnel_htons(obj->n_methods));
     242           2 :   written += 2; ptr += 2;
     243             : 
     244             :   /* Encode u16 methods[n_methods] */
     245             :   {
     246             : 
     247           2 :     unsigned idx;
     248           6 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->methods); ++idx) {
     249           4 :       trunnel_assert(written <= avail);
     250           4 :       if (avail - written < 2)
     251           0 :         goto truncated;
     252           4 :       trunnel_set_uint16(ptr, trunnel_htons(TRUNNEL_DYNARRAY_GET(&obj->methods, idx)));
     253           4 :       written += 2; ptr += 2;
     254             :     }
     255             :   }
     256             : 
     257             : 
     258           2 :   trunnel_assert(ptr == output + written);
     259             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     260             :   {
     261             :     trunnel_assert(encoded_len >= 0);
     262             :     trunnel_assert((size_t)encoded_len == written);
     263             :   }
     264             : 
     265             : #endif
     266             : 
     267           2 :   return written;
     268             : 
     269           0 :  truncated:
     270           0 :   result = -2;
     271           0 :   goto fail;
     272           0 :  check_failed:
     273           0 :   (void)msg;
     274           0 :   result = -1;
     275           0 :   goto fail;
     276             :  fail:
     277             :   trunnel_assert(result < 0);
     278             :   return result;
     279             : }
     280             : 
     281             : /** As auth_challenge_cell_parse(), but do not allocate the output
     282             :  * object.
     283             :  */
     284             : static ssize_t
     285           6 : auth_challenge_cell_parse_into(auth_challenge_cell_t *obj, const uint8_t *input, const size_t len_in)
     286             : {
     287           6 :   const uint8_t *ptr = input;
     288           6 :   size_t remaining = len_in;
     289           6 :   ssize_t result = 0;
     290           6 :   (void)result;
     291             : 
     292             :   /* Parse u8 challenge[32] */
     293           6 :   CHECK_REMAINING(32, truncated);
     294           6 :   memcpy(obj->challenge, ptr, 32);
     295           6 :   remaining -= 32; ptr += 32;
     296             : 
     297             :   /* Parse u16 n_methods */
     298           6 :   CHECK_REMAINING(2, truncated);
     299           5 :   obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr));
     300           5 :   remaining -= 2; ptr += 2;
     301             : 
     302             :   /* Parse u16 methods[n_methods] */
     303           5 :   TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {});
     304             :   {
     305           5 :     uint16_t elt;
     306           5 :     unsigned idx;
     307          14 :     for (idx = 0; idx < obj->n_methods; ++idx) {
     308          10 :       CHECK_REMAINING(2, truncated);
     309           9 :       elt = trunnel_ntohs(trunnel_get_uint16(ptr));
     310           9 :       remaining -= 2; ptr += 2;
     311           9 :       TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {});
     312             :     }
     313             :   }
     314           4 :   trunnel_assert(ptr + remaining == input + len_in);
     315           4 :   return len_in - remaining;
     316             : 
     317             :  truncated:
     318             :   return -2;
     319             :  trunnel_alloc_failed:
     320             :   return -1;
     321             : }
     322             : 
     323             : ssize_t
     324           6 : auth_challenge_cell_parse(auth_challenge_cell_t **output, const uint8_t *input, const size_t len_in)
     325             : {
     326           6 :   ssize_t result;
     327           6 :   *output = auth_challenge_cell_new();
     328           6 :   if (NULL == *output)
     329             :     return -1;
     330           6 :   result = auth_challenge_cell_parse_into(*output, input, len_in);
     331           6 :   if (result < 0) {
     332           2 :     auth_challenge_cell_free(*output);
     333           2 :     *output = NULL;
     334             :   }
     335             :   return result;
     336             : }
     337             : auth_ctx_t *
     338          28 : auth_ctx_new(void)
     339             : {
     340          28 :   auth_ctx_t *val = trunnel_calloc(1, sizeof(auth_ctx_t));
     341          28 :   if (NULL == val)
     342           0 :     return NULL;
     343             :   return val;
     344             : }
     345             : 
     346             : /** Release all storage held inside 'obj', but do not free 'obj'.
     347             :  */
     348             : static void
     349             : auth_ctx_clear(auth_ctx_t *obj)
     350             : {
     351             :   (void) obj;
     352             : }
     353             : 
     354             : void
     355          28 : auth_ctx_free(auth_ctx_t *obj)
     356             : {
     357          28 :   if (obj == NULL)
     358             :     return;
     359          28 :   auth_ctx_clear(obj);
     360          28 :   trunnel_memwipe(obj, sizeof(auth_ctx_t));
     361          28 :   trunnel_free_(obj);
     362             : }
     363             : 
     364             : uint8_t
     365           0 : auth_ctx_get_is_ed(const auth_ctx_t *inp)
     366             : {
     367           0 :   return inp->is_ed;
     368             : }
     369             : int
     370           0 : auth_ctx_set_is_ed(auth_ctx_t *inp, uint8_t val)
     371             : {
     372           0 :   inp->is_ed = val;
     373           0 :   return 0;
     374             : }
     375             : certs_cell_cert_t *
     376         338 : certs_cell_cert_new(void)
     377             : {
     378         338 :   certs_cell_cert_t *val = trunnel_calloc(1, sizeof(certs_cell_cert_t));
     379         338 :   if (NULL == val)
     380           0 :     return NULL;
     381             :   return val;
     382             : }
     383             : 
     384             : /** Release all storage held inside 'obj', but do not free 'obj'.
     385             :  */
     386             : static void
     387         338 : certs_cell_cert_clear(certs_cell_cert_t *obj)
     388             : {
     389         338 :   (void) obj;
     390         338 :   TRUNNEL_DYNARRAY_WIPE(&obj->body);
     391         338 :   TRUNNEL_DYNARRAY_CLEAR(&obj->body);
     392         338 : }
     393             : 
     394             : void
     395         342 : certs_cell_cert_free(certs_cell_cert_t *obj)
     396             : {
     397         342 :   if (obj == NULL)
     398             :     return;
     399         338 :   certs_cell_cert_clear(obj);
     400         338 :   trunnel_memwipe(obj, sizeof(certs_cell_cert_t));
     401         338 :   trunnel_free_(obj);
     402             : }
     403             : 
     404             : uint8_t
     405           0 : certs_cell_cert_get_cert_type(const certs_cell_cert_t *inp)
     406             : {
     407           0 :   return inp->cert_type;
     408             : }
     409             : int
     410           0 : certs_cell_cert_set_cert_type(certs_cell_cert_t *inp, uint8_t val)
     411             : {
     412           0 :   inp->cert_type = val;
     413           0 :   return 0;
     414             : }
     415             : uint16_t
     416           0 : certs_cell_cert_get_cert_len(const certs_cell_cert_t *inp)
     417             : {
     418           0 :   return inp->cert_len;
     419             : }
     420             : int
     421           3 : certs_cell_cert_set_cert_len(certs_cell_cert_t *inp, uint16_t val)
     422             : {
     423           3 :   inp->cert_len = val;
     424           3 :   return 0;
     425             : }
     426             : size_t
     427           2 : certs_cell_cert_getlen_body(const certs_cell_cert_t *inp)
     428             : {
     429           2 :   return TRUNNEL_DYNARRAY_LEN(&inp->body);
     430             : }
     431             : 
     432             : uint8_t
     433           0 : certs_cell_cert_get_body(certs_cell_cert_t *inp, size_t idx)
     434             : {
     435           0 :   return TRUNNEL_DYNARRAY_GET(&inp->body, idx);
     436             : }
     437             : 
     438             : uint8_t
     439           0 : certs_cell_cert_getconst_body(const certs_cell_cert_t *inp, size_t idx)
     440             : {
     441           0 :   return certs_cell_cert_get_body((certs_cell_cert_t*)inp, idx);
     442             : }
     443             : int
     444           0 : certs_cell_cert_set_body(certs_cell_cert_t *inp, size_t idx, uint8_t elt)
     445             : {
     446           0 :   TRUNNEL_DYNARRAY_SET(&inp->body, idx, elt);
     447           0 :   return 0;
     448             : }
     449             : int
     450           0 : certs_cell_cert_add_body(certs_cell_cert_t *inp, uint8_t elt)
     451             : {
     452             : #if SIZE_MAX >= UINT16_MAX
     453           0 :   if (inp->body.n_ == UINT16_MAX)
     454           0 :     goto trunnel_alloc_failed;
     455             : #endif
     456           0 :   TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->body, elt, {});
     457           0 :   return 0;
     458           0 :  trunnel_alloc_failed:
     459           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     460           0 :   return -1;
     461             : }
     462             : 
     463             : uint8_t *
     464         316 : certs_cell_cert_getarray_body(certs_cell_cert_t *inp)
     465             : {
     466         316 :   return inp->body.elts_;
     467             : }
     468             : const uint8_t  *
     469           0 : certs_cell_cert_getconstarray_body(const certs_cell_cert_t *inp)
     470             : {
     471           0 :   return (const uint8_t  *)certs_cell_cert_getarray_body((certs_cell_cert_t*)inp);
     472             : }
     473             : int
     474         179 : certs_cell_cert_setlen_body(certs_cell_cert_t *inp, size_t newlen)
     475             : {
     476         179 :   uint8_t *newptr;
     477             : #if UINT16_MAX < SIZE_MAX
     478         179 :   if (newlen > UINT16_MAX)
     479           0 :     goto trunnel_alloc_failed;
     480             : #endif
     481         358 :   newptr = trunnel_dynarray_setlen(&inp->body.allocated_,
     482         179 :                  &inp->body.n_, inp->body.elts_, newlen,
     483             :                  sizeof(inp->body.elts_[0]), (trunnel_free_fn_t) NULL,
     484             :                  &inp->trunnel_error_code_);
     485         179 :   if (newlen != 0 && newptr == NULL)
     486           0 :     goto trunnel_alloc_failed;
     487         179 :   inp->body.elts_ = newptr;
     488         179 :   return 0;
     489           0 :  trunnel_alloc_failed:
     490           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     491           0 :   return -1;
     492             : }
     493             : const char *
     494         679 : certs_cell_cert_check(const certs_cell_cert_t *obj)
     495             : {
     496         679 :   if (obj == NULL)
     497             :     return "Object was NULL";
     498         679 :   if (obj->trunnel_error_code_)
     499             :     return "A set function failed on this object";
     500         679 :   if (TRUNNEL_DYNARRAY_LEN(&obj->body) != obj->cert_len)
     501           0 :     return "Length mismatch for body";
     502             :   return NULL;
     503             : }
     504             : 
     505             : ssize_t
     506          14 : certs_cell_cert_encoded_len(const certs_cell_cert_t *obj)
     507             : {
     508          14 :   ssize_t result = 0;
     509             : 
     510          14 :   if (NULL != certs_cell_cert_check(obj))
     511             :      return -1;
     512             : 
     513             : 
     514             :   /* Length of u8 cert_type */
     515          14 :   result += 1;
     516             : 
     517             :   /* Length of u16 cert_len */
     518          14 :   result += 2;
     519             : 
     520             :   /* Length of u8 body[cert_len] */
     521          14 :   result += TRUNNEL_DYNARRAY_LEN(&obj->body);
     522          14 :   return result;
     523             : }
     524             : int
     525           0 : certs_cell_cert_clear_errors(certs_cell_cert_t *obj)
     526             : {
     527           0 :   int r = obj->trunnel_error_code_;
     528           0 :   obj->trunnel_error_code_ = 0;
     529           0 :   return r;
     530             : }
     531             : ssize_t
     532         274 : certs_cell_cert_encode(uint8_t *output, const size_t avail, const certs_cell_cert_t *obj)
     533             : {
     534         274 :   ssize_t result = 0;
     535         274 :   size_t written = 0;
     536         274 :   uint8_t *ptr = output;
     537         274 :   const char *msg;
     538             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     539             :   const ssize_t encoded_len = certs_cell_cert_encoded_len(obj);
     540             : #endif
     541             : 
     542         274 :   if (NULL != (msg = certs_cell_cert_check(obj)))
     543           0 :     goto check_failed;
     544             : 
     545             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     546             :   trunnel_assert(encoded_len >= 0);
     547             : #endif
     548             : 
     549             :   /* Encode u8 cert_type */
     550         274 :   trunnel_assert(written <= avail);
     551         274 :   if (avail - written < 1)
     552           0 :     goto truncated;
     553         274 :   trunnel_set_uint8(ptr, (obj->cert_type));
     554         274 :   written += 1; ptr += 1;
     555             : 
     556             :   /* Encode u16 cert_len */
     557         274 :   trunnel_assert(written <= avail);
     558         274 :   if (avail - written < 2)
     559           0 :     goto truncated;
     560         274 :   trunnel_set_uint16(ptr, trunnel_htons(obj->cert_len));
     561         274 :   written += 2; ptr += 2;
     562             : 
     563             :   /* Encode u8 body[cert_len] */
     564             :   {
     565         274 :     size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->body);
     566         274 :     trunnel_assert(obj->cert_len == elt_len);
     567         274 :     trunnel_assert(written <= avail);
     568         274 :     if (avail - written < elt_len)
     569           0 :       goto truncated;
     570         274 :     if (elt_len)
     571         274 :       memcpy(ptr, obj->body.elts_, elt_len);
     572         274 :     written += elt_len; ptr += elt_len;
     573             :   }
     574             : 
     575             : 
     576         274 :   trunnel_assert(ptr == output + written);
     577             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     578             :   {
     579             :     trunnel_assert(encoded_len >= 0);
     580             :     trunnel_assert((size_t)encoded_len == written);
     581             :   }
     582             : 
     583             : #endif
     584             : 
     585         274 :   return written;
     586             : 
     587           0 :  truncated:
     588           0 :   result = -2;
     589           0 :   goto fail;
     590           0 :  check_failed:
     591           0 :   (void)msg;
     592           0 :   result = -1;
     593           0 :   goto fail;
     594             :  fail:
     595             :   trunnel_assert(result < 0);
     596             :   return result;
     597             : }
     598             : 
     599             : /** As certs_cell_cert_parse(), but do not allocate the output object.
     600             :  */
     601             : static ssize_t
     602         167 : certs_cell_cert_parse_into(certs_cell_cert_t *obj, const uint8_t *input, const size_t len_in)
     603             : {
     604         167 :   const uint8_t *ptr = input;
     605         167 :   size_t remaining = len_in;
     606         167 :   ssize_t result = 0;
     607         167 :   (void)result;
     608             : 
     609             :   /* Parse u8 cert_type */
     610         167 :   CHECK_REMAINING(1, truncated);
     611         166 :   obj->cert_type = (trunnel_get_uint8(ptr));
     612         166 :   remaining -= 1; ptr += 1;
     613             : 
     614             :   /* Parse u16 cert_len */
     615         166 :   CHECK_REMAINING(2, truncated);
     616         166 :   obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr));
     617         166 :   remaining -= 2; ptr += 2;
     618             : 
     619             :   /* Parse u8 body[cert_len] */
     620         166 :   CHECK_REMAINING(obj->cert_len, truncated);
     621         162 :   TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {});
     622         162 :   obj->body.n_ = obj->cert_len;
     623         162 :   if (obj->cert_len)
     624         162 :     memcpy(obj->body.elts_, ptr, obj->cert_len);
     625         162 :   ptr += obj->cert_len; remaining -= obj->cert_len;
     626         162 :   trunnel_assert(ptr + remaining == input + len_in);
     627         162 :   return len_in - remaining;
     628             : 
     629             :  truncated:
     630             :   return -2;
     631           0 :  trunnel_alloc_failed:
     632           0 :   return -1;
     633             : }
     634             : 
     635             : ssize_t
     636         167 : certs_cell_cert_parse(certs_cell_cert_t **output, const uint8_t *input, const size_t len_in)
     637             : {
     638         167 :   ssize_t result;
     639         167 :   *output = certs_cell_cert_new();
     640         167 :   if (NULL == *output)
     641             :     return -1;
     642         167 :   result = certs_cell_cert_parse_into(*output, input, len_in);
     643         167 :   if (result < 0) {
     644           5 :     certs_cell_cert_free(*output);
     645           5 :     *output = NULL;
     646             :   }
     647             :   return result;
     648             : }
     649             : rsa_ed_crosscert_t *
     650         197 : rsa_ed_crosscert_new(void)
     651             : {
     652         197 :   rsa_ed_crosscert_t *val = trunnel_calloc(1, sizeof(rsa_ed_crosscert_t));
     653         197 :   if (NULL == val)
     654           0 :     return NULL;
     655             :   return val;
     656             : }
     657             : 
     658             : /** Release all storage held inside 'obj', but do not free 'obj'.
     659             :  */
     660             : static void
     661         197 : rsa_ed_crosscert_clear(rsa_ed_crosscert_t *obj)
     662             : {
     663         197 :   (void) obj;
     664         197 :   TRUNNEL_DYNARRAY_WIPE(&obj->sig);
     665         197 :   TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
     666         197 : }
     667             : 
     668             : void
     669         199 : rsa_ed_crosscert_free(rsa_ed_crosscert_t *obj)
     670             : {
     671         199 :   if (obj == NULL)
     672             :     return;
     673         197 :   rsa_ed_crosscert_clear(obj);
     674         197 :   trunnel_memwipe(obj, sizeof(rsa_ed_crosscert_t));
     675         197 :   trunnel_free_(obj);
     676             : }
     677             : 
     678             : size_t
     679           0 : rsa_ed_crosscert_getlen_ed_key(const rsa_ed_crosscert_t *inp)
     680             : {
     681           0 :   (void)inp;  return 32;
     682             : }
     683             : 
     684             : uint8_t
     685           0 : rsa_ed_crosscert_get_ed_key(rsa_ed_crosscert_t *inp, size_t idx)
     686             : {
     687           0 :   trunnel_assert(idx < 32);
     688           0 :   return inp->ed_key[idx];
     689             : }
     690             : 
     691             : uint8_t
     692           0 : rsa_ed_crosscert_getconst_ed_key(const rsa_ed_crosscert_t *inp, size_t idx)
     693             : {
     694           0 :   return rsa_ed_crosscert_get_ed_key((rsa_ed_crosscert_t*)inp, idx);
     695             : }
     696             : int
     697           0 : rsa_ed_crosscert_set_ed_key(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
     698             : {
     699           0 :   trunnel_assert(idx < 32);
     700           0 :   inp->ed_key[idx] = elt;
     701           0 :   return 0;
     702             : }
     703             : 
     704             : uint8_t *
     705          84 : rsa_ed_crosscert_getarray_ed_key(rsa_ed_crosscert_t *inp)
     706             : {
     707          84 :   return inp->ed_key;
     708             : }
     709             : const uint8_t  *
     710           0 : rsa_ed_crosscert_getconstarray_ed_key(const rsa_ed_crosscert_t *inp)
     711             : {
     712           0 :   return (const uint8_t  *)rsa_ed_crosscert_getarray_ed_key((rsa_ed_crosscert_t*)inp);
     713             : }
     714             : uint32_t
     715          83 : rsa_ed_crosscert_get_expiration(const rsa_ed_crosscert_t *inp)
     716             : {
     717          83 :   return inp->expiration;
     718             : }
     719             : int
     720           0 : rsa_ed_crosscert_set_expiration(rsa_ed_crosscert_t *inp, uint32_t val)
     721             : {
     722           0 :   inp->expiration = val;
     723           0 :   return 0;
     724             : }
     725             : const uint8_t *
     726          81 : rsa_ed_crosscert_get_end_of_signed(const rsa_ed_crosscert_t *inp)
     727             : {
     728          81 :   return inp->end_of_signed;
     729             : }
     730             : uint8_t
     731          81 : rsa_ed_crosscert_get_sig_len(const rsa_ed_crosscert_t *inp)
     732             : {
     733          81 :   return inp->sig_len;
     734             : }
     735             : int
     736           0 : rsa_ed_crosscert_set_sig_len(rsa_ed_crosscert_t *inp, uint8_t val)
     737             : {
     738           0 :   inp->sig_len = val;
     739           0 :   return 0;
     740             : }
     741             : size_t
     742         192 : rsa_ed_crosscert_getlen_sig(const rsa_ed_crosscert_t *inp)
     743             : {
     744         192 :   return TRUNNEL_DYNARRAY_LEN(&inp->sig);
     745             : }
     746             : 
     747             : uint8_t
     748           0 : rsa_ed_crosscert_get_sig(rsa_ed_crosscert_t *inp, size_t idx)
     749             : {
     750           0 :   return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
     751             : }
     752             : 
     753             : uint8_t
     754           0 : rsa_ed_crosscert_getconst_sig(const rsa_ed_crosscert_t *inp, size_t idx)
     755             : {
     756           0 :   return rsa_ed_crosscert_get_sig((rsa_ed_crosscert_t*)inp, idx);
     757             : }
     758             : int
     759           0 : rsa_ed_crosscert_set_sig(rsa_ed_crosscert_t *inp, size_t idx, uint8_t elt)
     760             : {
     761           0 :   TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
     762           0 :   return 0;
     763             : }
     764             : int
     765           0 : rsa_ed_crosscert_add_sig(rsa_ed_crosscert_t *inp, uint8_t elt)
     766             : {
     767             : #if SIZE_MAX >= UINT8_MAX
     768           0 :   if (inp->sig.n_ == UINT8_MAX)
     769           0 :     goto trunnel_alloc_failed;
     770             : #endif
     771           0 :   TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
     772           0 :   return 0;
     773           0 :  trunnel_alloc_failed:
     774           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     775           0 :   return -1;
     776             : }
     777             : 
     778             : uint8_t *
     779         192 : rsa_ed_crosscert_getarray_sig(rsa_ed_crosscert_t *inp)
     780             : {
     781         192 :   return inp->sig.elts_;
     782             : }
     783             : const uint8_t  *
     784           0 : rsa_ed_crosscert_getconstarray_sig(const rsa_ed_crosscert_t *inp)
     785             : {
     786           0 :   return (const uint8_t  *)rsa_ed_crosscert_getarray_sig((rsa_ed_crosscert_t*)inp);
     787             : }
     788             : int
     789         222 : rsa_ed_crosscert_setlen_sig(rsa_ed_crosscert_t *inp, size_t newlen)
     790             : {
     791         222 :   uint8_t *newptr;
     792             : #if UINT8_MAX < SIZE_MAX
     793         222 :   if (newlen > UINT8_MAX)
     794           0 :     goto trunnel_alloc_failed;
     795             : #endif
     796         444 :   newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
     797         222 :                  &inp->sig.n_, inp->sig.elts_, newlen,
     798             :                  sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
     799             :                  &inp->trunnel_error_code_);
     800         222 :   if (newlen != 0 && newptr == NULL)
     801           0 :     goto trunnel_alloc_failed;
     802         222 :   inp->sig.elts_ = newptr;
     803         222 :   return 0;
     804           0 :  trunnel_alloc_failed:
     805           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     806           0 :   return -1;
     807             : }
     808             : const char *
     809         333 : rsa_ed_crosscert_check(const rsa_ed_crosscert_t *obj)
     810             : {
     811         333 :   if (obj == NULL)
     812             :     return "Object was NULL";
     813         333 :   if (obj->trunnel_error_code_)
     814             :     return "A set function failed on this object";
     815         333 :   if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len)
     816           0 :     return "Length mismatch for sig";
     817             :   return NULL;
     818             : }
     819             : 
     820             : ssize_t
     821         111 : rsa_ed_crosscert_encoded_len(const rsa_ed_crosscert_t *obj)
     822             : {
     823         111 :   ssize_t result = 0;
     824             : 
     825         111 :   if (NULL != rsa_ed_crosscert_check(obj))
     826             :      return -1;
     827             : 
     828             : 
     829             :   /* Length of u8 ed_key[32] */
     830         111 :   result += 32;
     831             : 
     832             :   /* Length of u32 expiration */
     833         111 :   result += 4;
     834             : 
     835             :   /* Length of u8 sig_len */
     836         111 :   result += 1;
     837             : 
     838             :   /* Length of u8 sig[sig_len] */
     839         111 :   result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
     840         111 :   return result;
     841             : }
     842             : int
     843           0 : rsa_ed_crosscert_clear_errors(rsa_ed_crosscert_t *obj)
     844             : {
     845           0 :   int r = obj->trunnel_error_code_;
     846           0 :   obj->trunnel_error_code_ = 0;
     847           0 :   return r;
     848             : }
     849             : ssize_t
     850         222 : rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crosscert_t *obj)
     851             : {
     852         222 :   ssize_t result = 0;
     853         222 :   size_t written = 0;
     854         222 :   uint8_t *ptr = output;
     855         222 :   const char *msg;
     856             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     857             :   const ssize_t encoded_len = rsa_ed_crosscert_encoded_len(obj);
     858             : #endif
     859             : 
     860         222 :   if (NULL != (msg = rsa_ed_crosscert_check(obj)))
     861           0 :     goto check_failed;
     862             : 
     863             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     864             :   trunnel_assert(encoded_len >= 0);
     865             : #endif
     866             : 
     867             :   /* Encode u8 ed_key[32] */
     868         222 :   trunnel_assert(written <= avail);
     869         222 :   if (avail - written < 32)
     870           0 :     goto truncated;
     871         222 :   memcpy(ptr, obj->ed_key, 32);
     872         222 :   written += 32; ptr += 32;
     873             : 
     874             :   /* Encode u32 expiration */
     875         222 :   trunnel_assert(written <= avail);
     876         222 :   if (avail - written < 4)
     877           0 :     goto truncated;
     878         222 :   trunnel_set_uint32(ptr, trunnel_htonl(obj->expiration));
     879         222 :   written += 4; ptr += 4;
     880             : 
     881             :   /* Encode u8 sig_len */
     882         222 :   trunnel_assert(written <= avail);
     883         222 :   if (avail - written < 1)
     884           0 :     goto truncated;
     885         222 :   trunnel_set_uint8(ptr, (obj->sig_len));
     886         222 :   written += 1; ptr += 1;
     887             : 
     888             :   /* Encode u8 sig[sig_len] */
     889             :   {
     890         222 :     size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
     891         222 :     trunnel_assert(obj->sig_len == elt_len);
     892         222 :     trunnel_assert(written <= avail);
     893         222 :     if (avail - written < elt_len)
     894           0 :       goto truncated;
     895         222 :     if (elt_len)
     896         222 :       memcpy(ptr, obj->sig.elts_, elt_len);
     897         222 :     written += elt_len; ptr += elt_len;
     898             :   }
     899             : 
     900             : 
     901         222 :   trunnel_assert(ptr == output + written);
     902             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     903             :   {
     904             :     trunnel_assert(encoded_len >= 0);
     905             :     trunnel_assert((size_t)encoded_len == written);
     906             :   }
     907             : 
     908             : #endif
     909             : 
     910         222 :   return written;
     911             : 
     912           0 :  truncated:
     913           0 :   result = -2;
     914           0 :   goto fail;
     915           0 :  check_failed:
     916           0 :   (void)msg;
     917           0 :   result = -1;
     918           0 :   goto fail;
     919             :  fail:
     920             :   trunnel_assert(result < 0);
     921             :   return result;
     922             : }
     923             : 
     924             : /** As rsa_ed_crosscert_parse(), but do not allocate the output
     925             :  * object.
     926             :  */
     927             : static ssize_t
     928          86 : rsa_ed_crosscert_parse_into(rsa_ed_crosscert_t *obj, const uint8_t *input, const size_t len_in)
     929             : {
     930          86 :   const uint8_t *ptr = input;
     931          86 :   size_t remaining = len_in;
     932          86 :   ssize_t result = 0;
     933          86 :   (void)result;
     934             : 
     935             :   /* Parse u8 ed_key[32] */
     936          86 :   CHECK_REMAINING(32, truncated);
     937          85 :   memcpy(obj->ed_key, ptr, 32);
     938          85 :   remaining -= 32; ptr += 32;
     939             : 
     940             :   /* Parse u32 expiration */
     941          85 :   CHECK_REMAINING(4, truncated);
     942          85 :   obj->expiration = trunnel_ntohl(trunnel_get_uint32(ptr));
     943          85 :   remaining -= 4; ptr += 4;
     944          85 :   obj->end_of_signed = ptr;
     945             : 
     946             :   /* Parse u8 sig_len */
     947          85 :   CHECK_REMAINING(1, truncated);
     948          85 :   obj->sig_len = (trunnel_get_uint8(ptr));
     949          85 :   remaining -= 1; ptr += 1;
     950             : 
     951             :   /* Parse u8 sig[sig_len] */
     952          85 :   CHECK_REMAINING(obj->sig_len, truncated);
     953          84 :   TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
     954          84 :   obj->sig.n_ = obj->sig_len;
     955          84 :   if (obj->sig_len)
     956          84 :     memcpy(obj->sig.elts_, ptr, obj->sig_len);
     957          84 :   ptr += obj->sig_len; remaining -= obj->sig_len;
     958          84 :   trunnel_assert(ptr + remaining == input + len_in);
     959          84 :   return len_in - remaining;
     960             : 
     961             :  truncated:
     962             :   return -2;
     963           0 :  trunnel_alloc_failed:
     964           0 :   return -1;
     965             : }
     966             : 
     967             : ssize_t
     968          86 : rsa_ed_crosscert_parse(rsa_ed_crosscert_t **output, const uint8_t *input, const size_t len_in)
     969             : {
     970          86 :   ssize_t result;
     971          86 :   *output = rsa_ed_crosscert_new();
     972          86 :   if (NULL == *output)
     973             :     return -1;
     974          86 :   result = rsa_ed_crosscert_parse_into(*output, input, len_in);
     975          86 :   if (result < 0) {
     976           2 :     rsa_ed_crosscert_free(*output);
     977           2 :     *output = NULL;
     978             :   }
     979             :   return result;
     980             : }
     981             : auth1_t *
     982          37 : auth1_new(void)
     983             : {
     984          37 :   auth1_t *val = trunnel_calloc(1, sizeof(auth1_t));
     985          37 :   if (NULL == val)
     986           0 :     return NULL;
     987             :   return val;
     988             : }
     989             : 
     990             : /** Release all storage held inside 'obj', but do not free 'obj'.
     991             :  */
     992             : static void
     993          37 : auth1_clear(auth1_t *obj)
     994             : {
     995          37 :   (void) obj;
     996          37 :   TRUNNEL_DYNARRAY_WIPE(&obj->sig);
     997          37 :   TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
     998          37 : }
     999             : 
    1000             : void
    1001          37 : auth1_free(auth1_t *obj)
    1002             : {
    1003          37 :   if (obj == NULL)
    1004             :     return;
    1005          37 :   auth1_clear(obj);
    1006          37 :   trunnel_memwipe(obj, sizeof(auth1_t));
    1007          37 :   trunnel_free_(obj);
    1008             : }
    1009             : 
    1010             : size_t
    1011           0 : auth1_getlen_type(const auth1_t *inp)
    1012             : {
    1013           0 :   (void)inp;  return 8;
    1014             : }
    1015             : 
    1016             : uint8_t
    1017           0 : auth1_get_type(auth1_t *inp, size_t idx)
    1018             : {
    1019           0 :   trunnel_assert(idx < 8);
    1020           0 :   return inp->type[idx];
    1021             : }
    1022             : 
    1023             : uint8_t
    1024           0 : auth1_getconst_type(const auth1_t *inp, size_t idx)
    1025             : {
    1026           0 :   return auth1_get_type((auth1_t*)inp, idx);
    1027             : }
    1028             : int
    1029           0 : auth1_set_type(auth1_t *inp, size_t idx, uint8_t elt)
    1030             : {
    1031           0 :   trunnel_assert(idx < 8);
    1032           0 :   inp->type[idx] = elt;
    1033           0 :   return 0;
    1034             : }
    1035             : 
    1036             : uint8_t *
    1037          28 : auth1_getarray_type(auth1_t *inp)
    1038             : {
    1039          28 :   return inp->type;
    1040             : }
    1041             : const uint8_t  *
    1042           0 : auth1_getconstarray_type(const auth1_t *inp)
    1043             : {
    1044           0 :   return (const uint8_t  *)auth1_getarray_type((auth1_t*)inp);
    1045             : }
    1046             : size_t
    1047           0 : auth1_getlen_cid(const auth1_t *inp)
    1048             : {
    1049           0 :   (void)inp;  return 32;
    1050             : }
    1051             : 
    1052             : uint8_t
    1053           0 : auth1_get_cid(auth1_t *inp, size_t idx)
    1054             : {
    1055           0 :   trunnel_assert(idx < 32);
    1056           0 :   return inp->cid[idx];
    1057             : }
    1058             : 
    1059             : uint8_t
    1060           0 : auth1_getconst_cid(const auth1_t *inp, size_t idx)
    1061             : {
    1062           0 :   return auth1_get_cid((auth1_t*)inp, idx);
    1063             : }
    1064             : int
    1065           0 : auth1_set_cid(auth1_t *inp, size_t idx, uint8_t elt)
    1066             : {
    1067           0 :   trunnel_assert(idx < 32);
    1068           0 :   inp->cid[idx] = elt;
    1069           0 :   return 0;
    1070             : }
    1071             : 
    1072             : uint8_t *
    1073           0 : auth1_getarray_cid(auth1_t *inp)
    1074             : {
    1075           0 :   return inp->cid;
    1076             : }
    1077             : const uint8_t  *
    1078           0 : auth1_getconstarray_cid(const auth1_t *inp)
    1079             : {
    1080           0 :   return (const uint8_t  *)auth1_getarray_cid((auth1_t*)inp);
    1081             : }
    1082             : size_t
    1083           0 : auth1_getlen_sid(const auth1_t *inp)
    1084             : {
    1085           0 :   (void)inp;  return 32;
    1086             : }
    1087             : 
    1088             : uint8_t
    1089           0 : auth1_get_sid(auth1_t *inp, size_t idx)
    1090             : {
    1091           0 :   trunnel_assert(idx < 32);
    1092           0 :   return inp->sid[idx];
    1093             : }
    1094             : 
    1095             : uint8_t
    1096           0 : auth1_getconst_sid(const auth1_t *inp, size_t idx)
    1097             : {
    1098           0 :   return auth1_get_sid((auth1_t*)inp, idx);
    1099             : }
    1100             : int
    1101           0 : auth1_set_sid(auth1_t *inp, size_t idx, uint8_t elt)
    1102             : {
    1103           0 :   trunnel_assert(idx < 32);
    1104           0 :   inp->sid[idx] = elt;
    1105           0 :   return 0;
    1106             : }
    1107             : 
    1108             : uint8_t *
    1109           0 : auth1_getarray_sid(auth1_t *inp)
    1110             : {
    1111           0 :   return inp->sid;
    1112             : }
    1113             : const uint8_t  *
    1114           0 : auth1_getconstarray_sid(const auth1_t *inp)
    1115             : {
    1116           0 :   return (const uint8_t  *)auth1_getarray_sid((auth1_t*)inp);
    1117             : }
    1118             : size_t
    1119           0 : auth1_getlen_u1_cid_ed(const auth1_t *inp)
    1120             : {
    1121           0 :   (void)inp;  return 32;
    1122             : }
    1123             : 
    1124             : uint8_t
    1125           0 : auth1_get_u1_cid_ed(auth1_t *inp, size_t idx)
    1126             : {
    1127           0 :   trunnel_assert(idx < 32);
    1128           0 :   return inp->u1_cid_ed[idx];
    1129             : }
    1130             : 
    1131             : uint8_t
    1132           0 : auth1_getconst_u1_cid_ed(const auth1_t *inp, size_t idx)
    1133             : {
    1134           0 :   return auth1_get_u1_cid_ed((auth1_t*)inp, idx);
    1135             : }
    1136             : int
    1137           0 : auth1_set_u1_cid_ed(auth1_t *inp, size_t idx, uint8_t elt)
    1138             : {
    1139           0 :   trunnel_assert(idx < 32);
    1140           0 :   inp->u1_cid_ed[idx] = elt;
    1141           0 :   return 0;
    1142             : }
    1143             : 
    1144             : uint8_t *
    1145           0 : auth1_getarray_u1_cid_ed(auth1_t *inp)
    1146             : {
    1147           0 :   return inp->u1_cid_ed;
    1148             : }
    1149             : const uint8_t  *
    1150           0 : auth1_getconstarray_u1_cid_ed(const auth1_t *inp)
    1151             : {
    1152           0 :   return (const uint8_t  *)auth1_getarray_u1_cid_ed((auth1_t*)inp);
    1153             : }
    1154             : size_t
    1155           0 : auth1_getlen_u1_sid_ed(const auth1_t *inp)
    1156             : {
    1157           0 :   (void)inp;  return 32;
    1158             : }
    1159             : 
    1160             : uint8_t
    1161           0 : auth1_get_u1_sid_ed(auth1_t *inp, size_t idx)
    1162             : {
    1163           0 :   trunnel_assert(idx < 32);
    1164           0 :   return inp->u1_sid_ed[idx];
    1165             : }
    1166             : 
    1167             : uint8_t
    1168           0 : auth1_getconst_u1_sid_ed(const auth1_t *inp, size_t idx)
    1169             : {
    1170           0 :   return auth1_get_u1_sid_ed((auth1_t*)inp, idx);
    1171             : }
    1172             : int
    1173           0 : auth1_set_u1_sid_ed(auth1_t *inp, size_t idx, uint8_t elt)
    1174             : {
    1175           0 :   trunnel_assert(idx < 32);
    1176           0 :   inp->u1_sid_ed[idx] = elt;
    1177           0 :   return 0;
    1178             : }
    1179             : 
    1180             : uint8_t *
    1181           0 : auth1_getarray_u1_sid_ed(auth1_t *inp)
    1182             : {
    1183           0 :   return inp->u1_sid_ed;
    1184             : }
    1185             : const uint8_t  *
    1186           0 : auth1_getconstarray_u1_sid_ed(const auth1_t *inp)
    1187             : {
    1188           0 :   return (const uint8_t  *)auth1_getarray_u1_sid_ed((auth1_t*)inp);
    1189             : }
    1190             : size_t
    1191           0 : auth1_getlen_slog(const auth1_t *inp)
    1192             : {
    1193           0 :   (void)inp;  return 32;
    1194             : }
    1195             : 
    1196             : uint8_t
    1197           0 : auth1_get_slog(auth1_t *inp, size_t idx)
    1198             : {
    1199           0 :   trunnel_assert(idx < 32);
    1200           0 :   return inp->slog[idx];
    1201             : }
    1202             : 
    1203             : uint8_t
    1204           0 : auth1_getconst_slog(const auth1_t *inp, size_t idx)
    1205             : {
    1206           0 :   return auth1_get_slog((auth1_t*)inp, idx);
    1207             : }
    1208             : int
    1209           0 : auth1_set_slog(auth1_t *inp, size_t idx, uint8_t elt)
    1210             : {
    1211           0 :   trunnel_assert(idx < 32);
    1212           0 :   inp->slog[idx] = elt;
    1213           0 :   return 0;
    1214             : }
    1215             : 
    1216             : uint8_t *
    1217           0 : auth1_getarray_slog(auth1_t *inp)
    1218             : {
    1219           0 :   return inp->slog;
    1220             : }
    1221             : const uint8_t  *
    1222           0 : auth1_getconstarray_slog(const auth1_t *inp)
    1223             : {
    1224           0 :   return (const uint8_t  *)auth1_getarray_slog((auth1_t*)inp);
    1225             : }
    1226             : size_t
    1227           0 : auth1_getlen_clog(const auth1_t *inp)
    1228             : {
    1229           0 :   (void)inp;  return 32;
    1230             : }
    1231             : 
    1232             : uint8_t
    1233           0 : auth1_get_clog(auth1_t *inp, size_t idx)
    1234             : {
    1235           0 :   trunnel_assert(idx < 32);
    1236           0 :   return inp->clog[idx];
    1237             : }
    1238             : 
    1239             : uint8_t
    1240           0 : auth1_getconst_clog(const auth1_t *inp, size_t idx)
    1241             : {
    1242           0 :   return auth1_get_clog((auth1_t*)inp, idx);
    1243             : }
    1244             : int
    1245           0 : auth1_set_clog(auth1_t *inp, size_t idx, uint8_t elt)
    1246             : {
    1247           0 :   trunnel_assert(idx < 32);
    1248           0 :   inp->clog[idx] = elt;
    1249           0 :   return 0;
    1250             : }
    1251             : 
    1252             : uint8_t *
    1253           0 : auth1_getarray_clog(auth1_t *inp)
    1254             : {
    1255           0 :   return inp->clog;
    1256             : }
    1257             : const uint8_t  *
    1258           0 : auth1_getconstarray_clog(const auth1_t *inp)
    1259             : {
    1260           0 :   return (const uint8_t  *)auth1_getarray_clog((auth1_t*)inp);
    1261             : }
    1262             : size_t
    1263           0 : auth1_getlen_scert(const auth1_t *inp)
    1264             : {
    1265           0 :   (void)inp;  return 32;
    1266             : }
    1267             : 
    1268             : uint8_t
    1269           0 : auth1_get_scert(auth1_t *inp, size_t idx)
    1270             : {
    1271           0 :   trunnel_assert(idx < 32);
    1272           0 :   return inp->scert[idx];
    1273             : }
    1274             : 
    1275             : uint8_t
    1276           0 : auth1_getconst_scert(const auth1_t *inp, size_t idx)
    1277             : {
    1278           0 :   return auth1_get_scert((auth1_t*)inp, idx);
    1279             : }
    1280             : int
    1281           0 : auth1_set_scert(auth1_t *inp, size_t idx, uint8_t elt)
    1282             : {
    1283           0 :   trunnel_assert(idx < 32);
    1284           0 :   inp->scert[idx] = elt;
    1285           0 :   return 0;
    1286             : }
    1287             : 
    1288             : uint8_t *
    1289           0 : auth1_getarray_scert(auth1_t *inp)
    1290             : {
    1291           0 :   return inp->scert;
    1292             : }
    1293             : const uint8_t  *
    1294           0 : auth1_getconstarray_scert(const auth1_t *inp)
    1295             : {
    1296           0 :   return (const uint8_t  *)auth1_getarray_scert((auth1_t*)inp);
    1297             : }
    1298             : size_t
    1299           0 : auth1_getlen_tlssecrets(const auth1_t *inp)
    1300             : {
    1301           0 :   (void)inp;  return 32;
    1302             : }
    1303             : 
    1304             : uint8_t
    1305           0 : auth1_get_tlssecrets(auth1_t *inp, size_t idx)
    1306             : {
    1307           0 :   trunnel_assert(idx < 32);
    1308           0 :   return inp->tlssecrets[idx];
    1309             : }
    1310             : 
    1311             : uint8_t
    1312           0 : auth1_getconst_tlssecrets(const auth1_t *inp, size_t idx)
    1313             : {
    1314           0 :   return auth1_get_tlssecrets((auth1_t*)inp, idx);
    1315             : }
    1316             : int
    1317           0 : auth1_set_tlssecrets(auth1_t *inp, size_t idx, uint8_t elt)
    1318             : {
    1319           0 :   trunnel_assert(idx < 32);
    1320           0 :   inp->tlssecrets[idx] = elt;
    1321           0 :   return 0;
    1322             : }
    1323             : 
    1324             : uint8_t *
    1325           0 : auth1_getarray_tlssecrets(auth1_t *inp)
    1326             : {
    1327           0 :   return inp->tlssecrets;
    1328             : }
    1329             : const uint8_t  *
    1330           0 : auth1_getconstarray_tlssecrets(const auth1_t *inp)
    1331             : {
    1332           0 :   return (const uint8_t  *)auth1_getarray_tlssecrets((auth1_t*)inp);
    1333             : }
    1334             : const uint8_t *
    1335           0 : auth1_get_end_of_fixed_part(const auth1_t *inp)
    1336             : {
    1337           0 :   return inp->end_of_fixed_part;
    1338             : }
    1339             : size_t
    1340           0 : auth1_getlen_rand(const auth1_t *inp)
    1341             : {
    1342           0 :   (void)inp;  return 24;
    1343             : }
    1344             : 
    1345             : uint8_t
    1346           0 : auth1_get_rand(auth1_t *inp, size_t idx)
    1347             : {
    1348           0 :   trunnel_assert(idx < 24);
    1349           0 :   return inp->rand[idx];
    1350             : }
    1351             : 
    1352             : uint8_t
    1353           0 : auth1_getconst_rand(const auth1_t *inp, size_t idx)
    1354             : {
    1355           0 :   return auth1_get_rand((auth1_t*)inp, idx);
    1356             : }
    1357             : int
    1358           0 : auth1_set_rand(auth1_t *inp, size_t idx, uint8_t elt)
    1359             : {
    1360           0 :   trunnel_assert(idx < 24);
    1361           0 :   inp->rand[idx] = elt;
    1362           0 :   return 0;
    1363             : }
    1364             : 
    1365             : uint8_t *
    1366           0 : auth1_getarray_rand(auth1_t *inp)
    1367             : {
    1368           0 :   return inp->rand;
    1369             : }
    1370             : const uint8_t  *
    1371           0 : auth1_getconstarray_rand(const auth1_t *inp)
    1372             : {
    1373           0 :   return (const uint8_t  *)auth1_getarray_rand((auth1_t*)inp);
    1374             : }
    1375             : const uint8_t *
    1376           0 : auth1_get_end_of_signed(const auth1_t *inp)
    1377             : {
    1378           0 :   return inp->end_of_signed;
    1379             : }
    1380             : size_t
    1381          19 : auth1_getlen_sig(const auth1_t *inp)
    1382             : {
    1383          19 :   return TRUNNEL_DYNARRAY_LEN(&inp->sig);
    1384             : }
    1385             : 
    1386             : uint8_t
    1387           0 : auth1_get_sig(auth1_t *inp, size_t idx)
    1388             : {
    1389           0 :   return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
    1390             : }
    1391             : 
    1392             : uint8_t
    1393           0 : auth1_getconst_sig(const auth1_t *inp, size_t idx)
    1394             : {
    1395           0 :   return auth1_get_sig((auth1_t*)inp, idx);
    1396             : }
    1397             : int
    1398           0 : auth1_set_sig(auth1_t *inp, size_t idx, uint8_t elt)
    1399             : {
    1400           0 :   TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
    1401           0 :   return 0;
    1402             : }
    1403             : int
    1404           0 : auth1_add_sig(auth1_t *inp, uint8_t elt)
    1405             : {
    1406           0 :   TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
    1407           0 :   return 0;
    1408           0 :  trunnel_alloc_failed:
    1409           0 :   TRUNNEL_SET_ERROR_CODE(inp);
    1410           0 :   return -1;
    1411             : }
    1412             : 
    1413             : uint8_t *
    1414          22 : auth1_getarray_sig(auth1_t *inp)
    1415             : {
    1416          22 :   return inp->sig.elts_;
    1417             : }
    1418             : const uint8_t  *
    1419           0 : auth1_getconstarray_sig(const auth1_t *inp)
    1420             : {
    1421           0 :   return (const uint8_t  *)auth1_getarray_sig((auth1_t*)inp);
    1422             : }
    1423             : int
    1424          36 : auth1_setlen_sig(auth1_t *inp, size_t newlen)
    1425             : {
    1426          36 :   uint8_t *newptr;
    1427          72 :   newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
    1428          36 :                  &inp->sig.n_, inp->sig.elts_, newlen,
    1429             :                  sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
    1430             :                  &inp->trunnel_error_code_);
    1431          36 :   if (newlen != 0 && newptr == NULL)
    1432           0 :     goto trunnel_alloc_failed;
    1433          36 :   inp->sig.elts_ = newptr;
    1434          36 :   return 0;
    1435           0 :  trunnel_alloc_failed:
    1436           0 :   TRUNNEL_SET_ERROR_CODE(inp);
    1437           0 :   return -1;
    1438             : }
    1439             : const char *
    1440          74 : auth1_check(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
    1441             : {
    1442          74 :   if (obj == NULL)
    1443             :     return "Object was NULL";
    1444          74 :   if (obj->trunnel_error_code_)
    1445             :     return "A set function failed on this object";
    1446          74 :   if (auth_ctx_ctx == NULL)
    1447             :     return "Context was NULL";
    1448          74 :   switch (auth_ctx_ctx->is_ed) {
    1449             : 
    1450             :     case 0:
    1451             :       break;
    1452             : 
    1453             :     case 1:
    1454             :       break;
    1455             : 
    1456             :     default:
    1457             :         return "Bad tag for union";
    1458          74 :       break;
    1459             :   }
    1460          74 :   return NULL;
    1461             : }
    1462             : 
    1463             : ssize_t
    1464          27 : auth1_encoded_len(const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
    1465             : {
    1466          27 :   ssize_t result = 0;
    1467             : 
    1468          27 :   if (NULL != auth1_check(obj, auth_ctx_ctx))
    1469             :      return -1;
    1470             : 
    1471             : 
    1472             :   /* Length of u8 type[8] */
    1473          27 :   result += 8;
    1474             : 
    1475             :   /* Length of u8 cid[32] */
    1476          27 :   result += 32;
    1477             : 
    1478             :   /* Length of u8 sid[32] */
    1479          27 :   result += 32;
    1480          27 :   switch (auth_ctx_ctx->is_ed) {
    1481             : 
    1482             :     case 0:
    1483             :       break;
    1484             : 
    1485           7 :     case 1:
    1486             : 
    1487             :       /* Length of u8 u1_cid_ed[32] */
    1488           7 :       result += 32;
    1489             : 
    1490             :       /* Length of u8 u1_sid_ed[32] */
    1491           7 :       result += 32;
    1492           7 :       break;
    1493             : 
    1494             :     default:
    1495           0 :       trunnel_assert(0);
    1496             :       break;
    1497             :   }
    1498             : 
    1499             :   /* Length of u8 slog[32] */
    1500          27 :   result += 32;
    1501             : 
    1502             :   /* Length of u8 clog[32] */
    1503          27 :   result += 32;
    1504             : 
    1505             :   /* Length of u8 scert[32] */
    1506          27 :   result += 32;
    1507             : 
    1508             :   /* Length of u8 tlssecrets[32] */
    1509          27 :   result += 32;
    1510             : 
    1511             :   /* Length of u8 rand[24] */
    1512          27 :   result += 24;
    1513             : 
    1514             :   /* Length of u8 sig[] */
    1515          27 :   result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
    1516          27 :   return result;
    1517             : }
    1518             : int
    1519           0 : auth1_clear_errors(auth1_t *obj)
    1520             : {
    1521           0 :   int r = obj->trunnel_error_code_;
    1522           0 :   obj->trunnel_error_code_ = 0;
    1523           0 :   return r;
    1524             : }
    1525             : ssize_t
    1526          47 : auth1_encode(uint8_t *output, const size_t avail, const auth1_t *obj, const auth_ctx_t *auth_ctx_ctx)
    1527             : {
    1528          47 :   ssize_t result = 0;
    1529          47 :   size_t written = 0;
    1530          47 :   uint8_t *ptr = output;
    1531          47 :   const char *msg;
    1532             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1533             :   const ssize_t encoded_len = auth1_encoded_len(obj, auth_ctx_ctx);
    1534             : #endif
    1535             : 
    1536          47 :   if (NULL != (msg = auth1_check(obj, auth_ctx_ctx)))
    1537           0 :     goto check_failed;
    1538             : 
    1539             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1540             :   trunnel_assert(encoded_len >= 0);
    1541             : #endif
    1542             : 
    1543             :   /* Encode u8 type[8] */
    1544          47 :   trunnel_assert(written <= avail);
    1545          47 :   if (avail - written < 8)
    1546           0 :     goto truncated;
    1547          47 :   memcpy(ptr, obj->type, 8);
    1548          47 :   written += 8; ptr += 8;
    1549             : 
    1550             :   /* Encode u8 cid[32] */
    1551          47 :   trunnel_assert(written <= avail);
    1552          47 :   if (avail - written < 32)
    1553           0 :     goto truncated;
    1554          47 :   memcpy(ptr, obj->cid, 32);
    1555          47 :   written += 32; ptr += 32;
    1556             : 
    1557             :   /* Encode u8 sid[32] */
    1558          47 :   trunnel_assert(written <= avail);
    1559          47 :   if (avail - written < 32)
    1560           0 :     goto truncated;
    1561          47 :   memcpy(ptr, obj->sid, 32);
    1562          47 :   written += 32; ptr += 32;
    1563             : 
    1564             :   /* Encode union u1[auth_ctx.is_ed] */
    1565          47 :   trunnel_assert(written <= avail);
    1566          47 :   switch (auth_ctx_ctx->is_ed) {
    1567             : 
    1568             :     case 0:
    1569             :       break;
    1570             : 
    1571             :     case 1:
    1572             : 
    1573             :       /* Encode u8 u1_cid_ed[32] */
    1574          11 :       trunnel_assert(written <= avail);
    1575          11 :       if (avail - written < 32)
    1576           0 :         goto truncated;
    1577          11 :       memcpy(ptr, obj->u1_cid_ed, 32);
    1578          11 :       written += 32; ptr += 32;
    1579             : 
    1580             :       /* Encode u8 u1_sid_ed[32] */
    1581          11 :       trunnel_assert(written <= avail);
    1582          11 :       if (avail - written < 32)
    1583           0 :         goto truncated;
    1584          11 :       memcpy(ptr, obj->u1_sid_ed, 32);
    1585          11 :       written += 32; ptr += 32;
    1586          11 :       break;
    1587             : 
    1588             :     default:
    1589           0 :       trunnel_assert(0);
    1590             :       break;
    1591             :   }
    1592             : 
    1593             :   /* Encode u8 slog[32] */
    1594          47 :   trunnel_assert(written <= avail);
    1595          47 :   if (avail - written < 32)
    1596           0 :     goto truncated;
    1597          47 :   memcpy(ptr, obj->slog, 32);
    1598          47 :   written += 32; ptr += 32;
    1599             : 
    1600             :   /* Encode u8 clog[32] */
    1601          47 :   trunnel_assert(written <= avail);
    1602          47 :   if (avail - written < 32)
    1603           0 :     goto truncated;
    1604          47 :   memcpy(ptr, obj->clog, 32);
    1605          47 :   written += 32; ptr += 32;
    1606             : 
    1607             :   /* Encode u8 scert[32] */
    1608          47 :   trunnel_assert(written <= avail);
    1609          47 :   if (avail - written < 32)
    1610           0 :     goto truncated;
    1611          47 :   memcpy(ptr, obj->scert, 32);
    1612          47 :   written += 32; ptr += 32;
    1613             : 
    1614             :   /* Encode u8 tlssecrets[32] */
    1615          47 :   trunnel_assert(written <= avail);
    1616          47 :   if (avail - written < 32)
    1617           0 :     goto truncated;
    1618          47 :   memcpy(ptr, obj->tlssecrets, 32);
    1619          47 :   written += 32; ptr += 32;
    1620             : 
    1621             :   /* Encode u8 rand[24] */
    1622          47 :   trunnel_assert(written <= avail);
    1623          47 :   if (avail - written < 24)
    1624           0 :     goto truncated;
    1625          47 :   memcpy(ptr, obj->rand, 24);
    1626          47 :   written += 24; ptr += 24;
    1627             : 
    1628             :   /* Encode u8 sig[] */
    1629             :   {
    1630          47 :     size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
    1631          47 :     trunnel_assert(written <= avail);
    1632          47 :     if (avail - written < elt_len)
    1633           0 :       goto truncated;
    1634          47 :     if (elt_len)
    1635          20 :       memcpy(ptr, obj->sig.elts_, elt_len);
    1636          47 :     written += elt_len; ptr += elt_len;
    1637             :   }
    1638             : 
    1639             : 
    1640          47 :   trunnel_assert(ptr == output + written);
    1641             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1642             :   {
    1643             :     trunnel_assert(encoded_len >= 0);
    1644             :     trunnel_assert((size_t)encoded_len == written);
    1645             :   }
    1646             : 
    1647             : #endif
    1648             : 
    1649          47 :   return written;
    1650             : 
    1651           0 :  truncated:
    1652           0 :   result = -2;
    1653           0 :   goto fail;
    1654           0 :  check_failed:
    1655           0 :   (void)msg;
    1656           0 :   result = -1;
    1657           0 :   goto fail;
    1658             :  fail:
    1659             :   trunnel_assert(result < 0);
    1660             :   return result;
    1661             : }
    1662             : 
    1663             : /** As auth1_parse(), but do not allocate the output object.
    1664             :  */
    1665             : static ssize_t
    1666           9 : auth1_parse_into(auth1_t *obj, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
    1667             : {
    1668           9 :   const uint8_t *ptr = input;
    1669           9 :   size_t remaining = len_in;
    1670           9 :   ssize_t result = 0;
    1671           9 :   (void)result;
    1672           9 :   if (auth_ctx_ctx == NULL)
    1673             :     return -1;
    1674             : 
    1675             :   /* Parse u8 type[8] */
    1676           9 :   CHECK_REMAINING(8, truncated);
    1677           9 :   memcpy(obj->type, ptr, 8);
    1678           9 :   remaining -= 8; ptr += 8;
    1679             : 
    1680             :   /* Parse u8 cid[32] */
    1681           9 :   CHECK_REMAINING(32, truncated);
    1682           9 :   memcpy(obj->cid, ptr, 32);
    1683           9 :   remaining -= 32; ptr += 32;
    1684             : 
    1685             :   /* Parse u8 sid[32] */
    1686           9 :   CHECK_REMAINING(32, truncated);
    1687           9 :   memcpy(obj->sid, ptr, 32);
    1688           9 :   remaining -= 32; ptr += 32;
    1689             : 
    1690             :   /* Parse union u1[auth_ctx.is_ed] */
    1691           9 :   switch (auth_ctx_ctx->is_ed) {
    1692             : 
    1693             :     case 0:
    1694             :       break;
    1695             : 
    1696           4 :     case 1:
    1697             : 
    1698             :       /* Parse u8 u1_cid_ed[32] */
    1699           4 :       CHECK_REMAINING(32, truncated);
    1700           4 :       memcpy(obj->u1_cid_ed, ptr, 32);
    1701           4 :       remaining -= 32; ptr += 32;
    1702             : 
    1703             :       /* Parse u8 u1_sid_ed[32] */
    1704           4 :       CHECK_REMAINING(32, truncated);
    1705           4 :       memcpy(obj->u1_sid_ed, ptr, 32);
    1706           4 :       remaining -= 32; ptr += 32;
    1707           4 :       break;
    1708             : 
    1709           0 :     default:
    1710           0 :       goto fail;
    1711           9 :       break;
    1712             :   }
    1713             : 
    1714             :   /* Parse u8 slog[32] */
    1715           9 :   CHECK_REMAINING(32, truncated);
    1716           9 :   memcpy(obj->slog, ptr, 32);
    1717           9 :   remaining -= 32; ptr += 32;
    1718             : 
    1719             :   /* Parse u8 clog[32] */
    1720           9 :   CHECK_REMAINING(32, truncated);
    1721           9 :   memcpy(obj->clog, ptr, 32);
    1722           9 :   remaining -= 32; ptr += 32;
    1723             : 
    1724             :   /* Parse u8 scert[32] */
    1725           9 :   CHECK_REMAINING(32, truncated);
    1726           9 :   memcpy(obj->scert, ptr, 32);
    1727           9 :   remaining -= 32; ptr += 32;
    1728             : 
    1729             :   /* Parse u8 tlssecrets[32] */
    1730           9 :   CHECK_REMAINING(32, truncated);
    1731           9 :   memcpy(obj->tlssecrets, ptr, 32);
    1732           9 :   remaining -= 32; ptr += 32;
    1733           9 :   obj->end_of_fixed_part = ptr;
    1734             : 
    1735             :   /* Parse u8 rand[24] */
    1736           9 :   CHECK_REMAINING(24, truncated);
    1737           9 :   memcpy(obj->rand, ptr, 24);
    1738           9 :   remaining -= 24; ptr += 24;
    1739           9 :   obj->end_of_signed = ptr;
    1740             : 
    1741             :   /* Parse u8 sig[] */
    1742           9 :   TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, remaining, {});
    1743           9 :   obj->sig.n_ = remaining;
    1744           9 :   if (remaining)
    1745           2 :     memcpy(obj->sig.elts_, ptr, remaining);
    1746           9 :   ptr += remaining; remaining -= remaining;
    1747           9 :   trunnel_assert(ptr + remaining == input + len_in);
    1748           9 :   return len_in - remaining;
    1749             : 
    1750             :  truncated:
    1751             :   return -2;
    1752           0 :  trunnel_alloc_failed:
    1753           0 :   return -1;
    1754           0 :  fail:
    1755           0 :   result = -1;
    1756           0 :   return result;
    1757             : }
    1758             : 
    1759             : ssize_t
    1760           9 : auth1_parse(auth1_t **output, const uint8_t *input, const size_t len_in, const auth_ctx_t *auth_ctx_ctx)
    1761             : {
    1762           9 :   ssize_t result;
    1763           9 :   *output = auth1_new();
    1764           9 :   if (NULL == *output)
    1765             :     return -1;
    1766           9 :   result = auth1_parse_into(*output, input, len_in, auth_ctx_ctx);
    1767           9 :   if (result < 0) {
    1768           0 :     auth1_free(*output);
    1769           0 :     *output = NULL;
    1770             :   }
    1771             :   return result;
    1772             : }
    1773             : certs_cell_t *
    1774          94 : certs_cell_new(void)
    1775             : {
    1776          94 :   certs_cell_t *val = trunnel_calloc(1, sizeof(certs_cell_t));
    1777          94 :   if (NULL == val)
    1778           0 :     return NULL;
    1779             :   return val;
    1780             : }
    1781             : 
    1782             : /** Release all storage held inside 'obj', but do not free 'obj'.
    1783             :  */
    1784             : static void
    1785          94 : certs_cell_clear(certs_cell_t *obj)
    1786             : {
    1787          94 :   (void) obj;
    1788             :   {
    1789             : 
    1790          94 :     unsigned idx;
    1791         422 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
    1792         328 :       certs_cell_cert_free(TRUNNEL_DYNARRAY_GET(&obj->certs, idx));
    1793             :     }
    1794             :   }
    1795          94 :   TRUNNEL_DYNARRAY_WIPE(&obj->certs);
    1796          94 :   TRUNNEL_DYNARRAY_CLEAR(&obj->certs);
    1797          94 : }
    1798             : 
    1799             : void
    1800         105 : certs_cell_free(certs_cell_t *obj)
    1801             : {
    1802         105 :   if (obj == NULL)
    1803             :     return;
    1804          94 :   certs_cell_clear(obj);
    1805          94 :   trunnel_memwipe(obj, sizeof(certs_cell_t));
    1806          94 :   trunnel_free_(obj);
    1807             : }
    1808             : 
    1809             : uint8_t
    1810           0 : certs_cell_get_n_certs(const certs_cell_t *inp)
    1811             : {
    1812           0 :   return inp->n_certs;
    1813             : }
    1814             : int
    1815           0 : certs_cell_set_n_certs(certs_cell_t *inp, uint8_t val)
    1816             : {
    1817           0 :   inp->n_certs = val;
    1818           0 :   return 0;
    1819             : }
    1820             : size_t
    1821          10 : certs_cell_getlen_certs(const certs_cell_t *inp)
    1822             : {
    1823          10 :   return TRUNNEL_DYNARRAY_LEN(&inp->certs);
    1824             : }
    1825             : 
    1826             : struct certs_cell_cert_st *
    1827         189 : certs_cell_get_certs(certs_cell_t *inp, size_t idx)
    1828             : {
    1829         189 :   return TRUNNEL_DYNARRAY_GET(&inp->certs, idx);
    1830             : }
    1831             : 
    1832             :  const struct certs_cell_cert_st *
    1833           0 : certs_cell_getconst_certs(const certs_cell_t *inp, size_t idx)
    1834             : {
    1835           0 :   return certs_cell_get_certs((certs_cell_t*)inp, idx);
    1836             : }
    1837             : int
    1838           4 : certs_cell_set_certs(certs_cell_t *inp, size_t idx, struct certs_cell_cert_st * elt)
    1839             : {
    1840           4 :   certs_cell_cert_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->certs, idx);
    1841           4 :   if (oldval && oldval != elt)
    1842           4 :     certs_cell_cert_free(oldval);
    1843           4 :   return certs_cell_set0_certs(inp, idx, elt);
    1844             : }
    1845             : int
    1846           8 : certs_cell_set0_certs(certs_cell_t *inp, size_t idx, struct certs_cell_cert_st * elt)
    1847             : {
    1848           8 :   TRUNNEL_DYNARRAY_SET(&inp->certs, idx, elt);
    1849           8 :   return 0;
    1850             : }
    1851             : int
    1852         171 : certs_cell_add_certs(certs_cell_t *inp, struct certs_cell_cert_st * elt)
    1853             : {
    1854             : #if SIZE_MAX >= UINT8_MAX
    1855         171 :   if (inp->certs.n_ == UINT8_MAX)
    1856           0 :     goto trunnel_alloc_failed;
    1857             : #endif
    1858         171 :   TRUNNEL_DYNARRAY_ADD(struct certs_cell_cert_st *, &inp->certs, elt, {});
    1859         171 :   return 0;
    1860           0 :  trunnel_alloc_failed:
    1861           0 :   TRUNNEL_SET_ERROR_CODE(inp);
    1862           0 :   return -1;
    1863             : }
    1864             : 
    1865             : struct certs_cell_cert_st * *
    1866           0 : certs_cell_getarray_certs(certs_cell_t *inp)
    1867             : {
    1868           0 :   return inp->certs.elts_;
    1869             : }
    1870             : const struct certs_cell_cert_st *  const  *
    1871           0 : certs_cell_getconstarray_certs(const certs_cell_t *inp)
    1872             : {
    1873           0 :   return (const struct certs_cell_cert_st *  const  *)certs_cell_getarray_certs((certs_cell_t*)inp);
    1874             : }
    1875             : int
    1876           5 : certs_cell_setlen_certs(certs_cell_t *inp, size_t newlen)
    1877             : {
    1878           5 :   struct certs_cell_cert_st * *newptr;
    1879             : #if UINT8_MAX < SIZE_MAX
    1880           5 :   if (newlen > UINT8_MAX)
    1881           0 :     goto trunnel_alloc_failed;
    1882             : #endif
    1883          10 :   newptr = trunnel_dynarray_setlen(&inp->certs.allocated_,
    1884           5 :                  &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           5 :   if (newlen != 0 && newptr == NULL)
    1888           0 :     goto trunnel_alloc_failed;
    1889           5 :   inp->certs.elts_ = newptr;
    1890           5 :   return 0;
    1891           0 :  trunnel_alloc_failed:
    1892           0 :   TRUNNEL_SET_ERROR_CODE(inp);
    1893           0 :   return -1;
    1894             : }
    1895             : const char *
    1896         106 : certs_cell_check(const certs_cell_t *obj)
    1897             : {
    1898         106 :   if (obj == NULL)
    1899             :     return "Object was NULL";
    1900         106 :   if (obj->trunnel_error_code_)
    1901             :     return "A set function failed on this object";
    1902             :   {
    1903             :     const char *msg;
    1904             : 
    1905             :     unsigned idx;
    1906         497 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
    1907         391 :       if (NULL != (msg = certs_cell_cert_check(TRUNNEL_DYNARRAY_GET(&obj->certs, idx))))
    1908           0 :         return msg;
    1909             :     }
    1910             :   }
    1911         106 :   if (TRUNNEL_DYNARRAY_LEN(&obj->certs) != obj->n_certs)
    1912           0 :     return "Length mismatch for certs";
    1913             :   return NULL;
    1914             : }
    1915             : 
    1916             : ssize_t
    1917           4 : certs_cell_encoded_len(const certs_cell_t *obj)
    1918             : {
    1919           4 :   ssize_t result = 0;
    1920             : 
    1921           4 :   if (NULL != certs_cell_check(obj))
    1922             :      return -1;
    1923             : 
    1924             : 
    1925             :   /* Length of u8 n_certs */
    1926             :   result += 1;
    1927             : 
    1928             :   /* Length of struct certs_cell_cert certs[n_certs] */
    1929             :   {
    1930             : 
    1931             :     unsigned idx;
    1932          18 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
    1933          14 :       result += certs_cell_cert_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->certs, idx));
    1934             :     }
    1935             :   }
    1936             :   return result;
    1937             : }
    1938             : int
    1939           0 : certs_cell_clear_errors(certs_cell_t *obj)
    1940             : {
    1941           0 :   int r = obj->trunnel_error_code_;
    1942           0 :   obj->trunnel_error_code_ = 0;
    1943           0 :   return r;
    1944             : }
    1945             : ssize_t
    1946          75 : certs_cell_encode(uint8_t *output, const size_t avail, const certs_cell_t *obj)
    1947             : {
    1948          75 :   ssize_t result = 0;
    1949          75 :   size_t written = 0;
    1950          75 :   uint8_t *ptr = output;
    1951          75 :   const char *msg;
    1952             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1953             :   const ssize_t encoded_len = certs_cell_encoded_len(obj);
    1954             : #endif
    1955             : 
    1956          75 :   if (NULL != (msg = certs_cell_check(obj)))
    1957           0 :     goto check_failed;
    1958             : 
    1959             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1960             :   trunnel_assert(encoded_len >= 0);
    1961             : #endif
    1962             : 
    1963             :   /* Encode u8 n_certs */
    1964          75 :   trunnel_assert(written <= avail);
    1965          75 :   if (avail - written < 1)
    1966           0 :     goto truncated;
    1967          75 :   trunnel_set_uint8(ptr, (obj->n_certs));
    1968          75 :   written += 1; ptr += 1;
    1969             : 
    1970             :   /* Encode struct certs_cell_cert certs[n_certs] */
    1971             :   {
    1972             : 
    1973          75 :     unsigned idx;
    1974         349 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->certs); ++idx) {
    1975         274 :       trunnel_assert(written <= avail);
    1976         274 :       result = certs_cell_cert_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->certs, idx));
    1977         274 :       if (result < 0)
    1978           0 :         goto fail; /* XXXXXXX !*/
    1979         274 :       written += result; ptr += result;
    1980             :     }
    1981             :   }
    1982             : 
    1983             : 
    1984          75 :   trunnel_assert(ptr == output + written);
    1985             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1986             :   {
    1987             :     trunnel_assert(encoded_len >= 0);
    1988             :     trunnel_assert((size_t)encoded_len == written);
    1989             :   }
    1990             : 
    1991             : #endif
    1992             : 
    1993          75 :   return written;
    1994             : 
    1995           0 :  truncated:
    1996           0 :   result = -2;
    1997           0 :   goto fail;
    1998           0 :  check_failed:
    1999           0 :   (void)msg;
    2000           0 :   result = -1;
    2001           0 :   goto fail;
    2002           0 :  fail:
    2003           0 :   trunnel_assert(result < 0);
    2004             :   return result;
    2005             : }
    2006             : 
    2007             : /** As certs_cell_parse(), but do not allocate the output object.
    2008             :  */
    2009             : static ssize_t
    2010          46 : certs_cell_parse_into(certs_cell_t *obj, const uint8_t *input, const size_t len_in)
    2011             : {
    2012          46 :   const uint8_t *ptr = input;
    2013          46 :   size_t remaining = len_in;
    2014          46 :   ssize_t result = 0;
    2015          46 :   (void)result;
    2016             : 
    2017             :   /* Parse u8 n_certs */
    2018          46 :   CHECK_REMAINING(1, truncated);
    2019          46 :   obj->n_certs = (trunnel_get_uint8(ptr));
    2020          46 :   remaining -= 1; ptr += 1;
    2021             : 
    2022             :   /* Parse struct certs_cell_cert certs[n_certs] */
    2023          46 :   TRUNNEL_DYNARRAY_EXPAND(certs_cell_cert_t *, &obj->certs, obj->n_certs, {});
    2024             :   {
    2025          46 :     certs_cell_cert_t * elt;
    2026          46 :     unsigned idx;
    2027         208 :     for (idx = 0; idx < obj->n_certs; ++idx) {
    2028         167 :       result = certs_cell_cert_parse(&elt, ptr, remaining);
    2029         167 :       if (result < 0)
    2030           5 :         goto relay_fail;
    2031         162 :       trunnel_assert((size_t)result <= remaining);
    2032         162 :       remaining -= result; ptr += result;
    2033         162 :       TRUNNEL_DYNARRAY_ADD(certs_cell_cert_t *, &obj->certs, elt, {certs_cell_cert_free(elt);});
    2034             :     }
    2035             :   }
    2036          41 :   trunnel_assert(ptr + remaining == input + len_in);
    2037          41 :   return len_in - remaining;
    2038             : 
    2039           0 :  truncated:
    2040           0 :   return -2;
    2041           5 :  relay_fail:
    2042           5 :   trunnel_assert(result < 0);
    2043             :   return result;
    2044             :  trunnel_alloc_failed:
    2045             :   return -1;
    2046             : }
    2047             : 
    2048             : ssize_t
    2049          46 : certs_cell_parse(certs_cell_t **output, const uint8_t *input, const size_t len_in)
    2050             : {
    2051          46 :   ssize_t result;
    2052          46 :   *output = certs_cell_new();
    2053          46 :   if (NULL == *output)
    2054             :     return -1;
    2055          46 :   result = certs_cell_parse_into(*output, input, len_in);
    2056          46 :   if (result < 0) {
    2057           5 :     certs_cell_free(*output);
    2058           5 :     *output = NULL;
    2059             :   }
    2060             :   return result;
    2061             : }

Generated by: LCOV version 1.14