From d4337d27e4c4d1bf58bde6a2e34f860d70f0ca5f Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 1 Apr 2021 10:56:19 +0200 Subject: express doc/format.md in trunnel --- trunnel/stfe.c | 2796 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2796 insertions(+) create mode 100644 trunnel/stfe.c (limited to 'trunnel/stfe.c') diff --git a/trunnel/stfe.c b/trunnel/stfe.c new file mode 100644 index 0000000..58ecd66 --- /dev/null +++ b/trunnel/stfe.c @@ -0,0 +1,2796 @@ +/* stfe.c -- generated by Trunnel v1.5.3. + * https://gitweb.torproject.org/trunnel.git + * You probably shouldn't edit this file. + */ +#include +#include "trunnel-impl.h" + +#include "stfe.h" + +#define TRUNNEL_SET_ERROR_CODE(obj) \ + do { \ + (obj)->trunnel_error_code_ = 1; \ + } while (0) + +#if defined(__COVERITY__) || defined(__clang_analyzer__) +/* If we're running a static analysis tool, we don't want it to complain + * that some of our remaining-bytes checks are dead-code. */ +int stfe_deadcode_dummy__ = 0; +#define OR_DEADCODE_DUMMY || stfe_deadcode_dummy__ +#else +#define OR_DEADCODE_DUMMY +#endif + +#define CHECK_REMAINING(nbytes, label) \ + do { \ + if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \ + goto label; \ + } \ + } while (0) + +ed25519_v1_t * +ed25519_v1_new(void) +{ + ed25519_v1_t *val = trunnel_calloc(1, sizeof(ed25519_v1_t)); + if (NULL == val) + return NULL; + val->format = T_ED25519_V1; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +ed25519_v1_clear(ed25519_v1_t *obj) +{ + (void) obj; +} + +void +ed25519_v1_free(ed25519_v1_t *obj) +{ + if (obj == NULL) + return; + ed25519_v1_clear(obj); + trunnel_memwipe(obj, sizeof(ed25519_v1_t)); + trunnel_free_(obj); +} + +uint64_t +ed25519_v1_get_format(const ed25519_v1_t *inp) +{ + return inp->format; +} +int +ed25519_v1_set_format(ed25519_v1_t *inp, uint64_t val) +{ + if (! ((val == T_ED25519_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; + return 0; +} +size_t +ed25519_v1_getlen_pubkey(const ed25519_v1_t *inp) +{ + (void)inp; return 32; +} + +uint8_t +ed25519_v1_get_pubkey(ed25519_v1_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->pubkey[idx]; +} + +uint8_t +ed25519_v1_getconst_pubkey(const ed25519_v1_t *inp, size_t idx) +{ + return ed25519_v1_get_pubkey((ed25519_v1_t*)inp, idx); +} +int +ed25519_v1_set_pubkey(ed25519_v1_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->pubkey[idx] = elt; + return 0; +} + +uint8_t * +ed25519_v1_getarray_pubkey(ed25519_v1_t *inp) +{ + return inp->pubkey; +} +const uint8_t * +ed25519_v1_getconstarray_pubkey(const ed25519_v1_t *inp) +{ + return (const uint8_t *)ed25519_v1_getarray_pubkey((ed25519_v1_t*)inp); +} +const char * +ed25519_v1_check(const ed25519_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! (obj->format == T_ED25519_V1)) + return "Integer out of bounds"; + return NULL; +} + +ssize_t +ed25519_v1_encoded_len(const ed25519_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != ed25519_v1_check(obj)) + return -1; + + + /* Length of u64 format IN [T_ED25519_V1] */ + result += 8; + + /* Length of u8 pubkey[32] */ + result += 32; + return result; +} +int +ed25519_v1_clear_errors(ed25519_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +ed25519_v1_encode(uint8_t *output, const size_t avail, const ed25519_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = ed25519_v1_encoded_len(obj); +#endif + + if (NULL != (msg = ed25519_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 format IN [T_ED25519_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; + + /* Encode u8 pubkey[32] */ + trunnel_assert(written <= avail); + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->pubkey, 32); + written += 32; ptr += 32; + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As ed25519_v1_parse(), but do not allocate the output object. + */ +static ssize_t +ed25519_v1_parse_into(ed25519_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 format IN [T_ED25519_V1] */ + CHECK_REMAINING(8, truncated); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->format == T_ED25519_V1)) + goto fail; + + /* Parse u8 pubkey[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->pubkey, ptr, 32); + remaining -= 32; ptr += 32; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; + fail: + result = -1; + return result; +} + +ssize_t +ed25519_v1_parse(ed25519_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = ed25519_v1_new(); + if (NULL == *output) + return -1; + result = ed25519_v1_parse_into(*output, input, len_in); + if (result < 0) { + ed25519_v1_free(*output); + *output = NULL; + } + return result; +} +req_get_consistency_proof_v1_t * +req_get_consistency_proof_v1_new(void) +{ + req_get_consistency_proof_v1_t *val = trunnel_calloc(1, sizeof(req_get_consistency_proof_v1_t)); + if (NULL == val) + return NULL; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +req_get_consistency_proof_v1_clear(req_get_consistency_proof_v1_t *obj) +{ + (void) obj; +} + +void +req_get_consistency_proof_v1_free(req_get_consistency_proof_v1_t *obj) +{ + if (obj == NULL) + return; + req_get_consistency_proof_v1_clear(obj); + trunnel_memwipe(obj, sizeof(req_get_consistency_proof_v1_t)); + trunnel_free_(obj); +} + +uint64_t +req_get_consistency_proof_v1_get_old_size(const req_get_consistency_proof_v1_t *inp) +{ + return inp->old_size; +} +int +req_get_consistency_proof_v1_set_old_size(req_get_consistency_proof_v1_t *inp, uint64_t val) +{ + inp->old_size = val; + return 0; +} +uint64_t +req_get_consistency_proof_v1_get_new_size(const req_get_consistency_proof_v1_t *inp) +{ + return inp->new_size; +} +int +req_get_consistency_proof_v1_set_new_size(req_get_consistency_proof_v1_t *inp, uint64_t val) +{ + inp->new_size = val; + return 0; +} +const char * +req_get_consistency_proof_v1_check(const req_get_consistency_proof_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + return NULL; +} + +ssize_t +req_get_consistency_proof_v1_encoded_len(const req_get_consistency_proof_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != req_get_consistency_proof_v1_check(obj)) + return -1; + + + /* Length of u64 old_size */ + result += 8; + + /* Length of u64 new_size */ + result += 8; + return result; +} +int +req_get_consistency_proof_v1_clear_errors(req_get_consistency_proof_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +req_get_consistency_proof_v1_encode(uint8_t *output, const size_t avail, const req_get_consistency_proof_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = req_get_consistency_proof_v1_encoded_len(obj); +#endif + + if (NULL != (msg = req_get_consistency_proof_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 old_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->old_size)); + written += 8; ptr += 8; + + /* Encode u64 new_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->new_size)); + written += 8; ptr += 8; + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As req_get_consistency_proof_v1_parse(), but do not allocate the + * output object. + */ +static ssize_t +req_get_consistency_proof_v1_parse_into(req_get_consistency_proof_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 old_size */ + CHECK_REMAINING(8, truncated); + obj->old_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 new_size */ + CHECK_REMAINING(8, truncated); + obj->new_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; +} + +ssize_t +req_get_consistency_proof_v1_parse(req_get_consistency_proof_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = req_get_consistency_proof_v1_new(); + if (NULL == *output) + return -1; + result = req_get_consistency_proof_v1_parse_into(*output, input, len_in); + if (result < 0) { + req_get_consistency_proof_v1_free(*output); + *output = NULL; + } + return result; +} +req_get_entries_v1_t * +req_get_entries_v1_new(void) +{ + req_get_entries_v1_t *val = trunnel_calloc(1, sizeof(req_get_entries_v1_t)); + if (NULL == val) + return NULL; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +req_get_entries_v1_clear(req_get_entries_v1_t *obj) +{ + (void) obj; +} + +void +req_get_entries_v1_free(req_get_entries_v1_t *obj) +{ + if (obj == NULL) + return; + req_get_entries_v1_clear(obj); + trunnel_memwipe(obj, sizeof(req_get_entries_v1_t)); + trunnel_free_(obj); +} + +uint64_t +req_get_entries_v1_get_start_size(const req_get_entries_v1_t *inp) +{ + return inp->start_size; +} +int +req_get_entries_v1_set_start_size(req_get_entries_v1_t *inp, uint64_t val) +{ + inp->start_size = val; + return 0; +} +uint64_t +req_get_entries_v1_get_end_size(const req_get_entries_v1_t *inp) +{ + return inp->end_size; +} +int +req_get_entries_v1_set_end_size(req_get_entries_v1_t *inp, uint64_t val) +{ + inp->end_size = val; + return 0; +} +const char * +req_get_entries_v1_check(const req_get_entries_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + return NULL; +} + +ssize_t +req_get_entries_v1_encoded_len(const req_get_entries_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != req_get_entries_v1_check(obj)) + return -1; + + + /* Length of u64 start_size */ + result += 8; + + /* Length of u64 end_size */ + result += 8; + return result; +} +int +req_get_entries_v1_clear_errors(req_get_entries_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +req_get_entries_v1_encode(uint8_t *output, const size_t avail, const req_get_entries_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = req_get_entries_v1_encoded_len(obj); +#endif + + if (NULL != (msg = req_get_entries_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 start_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->start_size)); + written += 8; ptr += 8; + + /* Encode u64 end_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->end_size)); + written += 8; ptr += 8; + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As req_get_entries_v1_parse(), but do not allocate the output + * object. + */ +static ssize_t +req_get_entries_v1_parse_into(req_get_entries_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 start_size */ + CHECK_REMAINING(8, truncated); + obj->start_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 end_size */ + CHECK_REMAINING(8, truncated); + obj->end_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; +} + +ssize_t +req_get_entries_v1_parse(req_get_entries_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = req_get_entries_v1_new(); + if (NULL == *output) + return -1; + result = req_get_entries_v1_parse_into(*output, input, len_in); + if (result < 0) { + req_get_entries_v1_free(*output); + *output = NULL; + } + return result; +} +req_get_proof_by_hash_v1_t * +req_get_proof_by_hash_v1_new(void) +{ + req_get_proof_by_hash_v1_t *val = trunnel_calloc(1, sizeof(req_get_proof_by_hash_v1_t)); + if (NULL == val) + return NULL; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +req_get_proof_by_hash_v1_clear(req_get_proof_by_hash_v1_t *obj) +{ + (void) obj; +} + +void +req_get_proof_by_hash_v1_free(req_get_proof_by_hash_v1_t *obj) +{ + if (obj == NULL) + return; + req_get_proof_by_hash_v1_clear(obj); + trunnel_memwipe(obj, sizeof(req_get_proof_by_hash_v1_t)); + trunnel_free_(obj); +} + +uint64_t +req_get_proof_by_hash_v1_get_tree_size(const req_get_proof_by_hash_v1_t *inp) +{ + return inp->tree_size; +} +int +req_get_proof_by_hash_v1_set_tree_size(req_get_proof_by_hash_v1_t *inp, uint64_t val) +{ + inp->tree_size = val; + return 0; +} +size_t +req_get_proof_by_hash_v1_getlen_leaf_hash(const req_get_proof_by_hash_v1_t *inp) +{ + (void)inp; return 32; +} + +uint8_t +req_get_proof_by_hash_v1_get_leaf_hash(req_get_proof_by_hash_v1_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->leaf_hash[idx]; +} + +uint8_t +req_get_proof_by_hash_v1_getconst_leaf_hash(const req_get_proof_by_hash_v1_t *inp, size_t idx) +{ + return req_get_proof_by_hash_v1_get_leaf_hash((req_get_proof_by_hash_v1_t*)inp, idx); +} +int +req_get_proof_by_hash_v1_set_leaf_hash(req_get_proof_by_hash_v1_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->leaf_hash[idx] = elt; + return 0; +} + +uint8_t * +req_get_proof_by_hash_v1_getarray_leaf_hash(req_get_proof_by_hash_v1_t *inp) +{ + return inp->leaf_hash; +} +const uint8_t * +req_get_proof_by_hash_v1_getconstarray_leaf_hash(const req_get_proof_by_hash_v1_t *inp) +{ + return (const uint8_t *)req_get_proof_by_hash_v1_getarray_leaf_hash((req_get_proof_by_hash_v1_t*)inp); +} +const char * +req_get_proof_by_hash_v1_check(const req_get_proof_by_hash_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + return NULL; +} + +ssize_t +req_get_proof_by_hash_v1_encoded_len(const req_get_proof_by_hash_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != req_get_proof_by_hash_v1_check(obj)) + return -1; + + + /* Length of u64 tree_size */ + result += 8; + + /* Length of u8 leaf_hash[32] */ + result += 32; + return result; +} +int +req_get_proof_by_hash_v1_clear_errors(req_get_proof_by_hash_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +req_get_proof_by_hash_v1_encode(uint8_t *output, const size_t avail, const req_get_proof_by_hash_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = req_get_proof_by_hash_v1_encoded_len(obj); +#endif + + if (NULL != (msg = req_get_proof_by_hash_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 tree_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->tree_size)); + written += 8; ptr += 8; + + /* Encode u8 leaf_hash[32] */ + trunnel_assert(written <= avail); + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->leaf_hash, 32); + written += 32; ptr += 32; + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As req_get_proof_by_hash_v1_parse(), but do not allocate the + * output object. + */ +static ssize_t +req_get_proof_by_hash_v1_parse_into(req_get_proof_by_hash_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 tree_size */ + CHECK_REMAINING(8, truncated); + obj->tree_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u8 leaf_hash[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->leaf_hash, ptr, 32); + remaining -= 32; ptr += 32; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; +} + +ssize_t +req_get_proof_by_hash_v1_parse(req_get_proof_by_hash_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = req_get_proof_by_hash_v1_new(); + if (NULL == *output) + return -1; + result = req_get_proof_by_hash_v1_parse_into(*output, input, len_in); + if (result < 0) { + req_get_proof_by_hash_v1_free(*output); + *output = NULL; + } + return result; +} +signed_tree_head_v1_t * +signed_tree_head_v1_new(void) +{ + signed_tree_head_v1_t *val = trunnel_calloc(1, sizeof(signed_tree_head_v1_t)); + if (NULL == val) + return NULL; + val->format = T_SIGNED_TREE_HEAD_V1; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +signed_tree_head_v1_clear(signed_tree_head_v1_t *obj) +{ + (void) obj; + TRUNNEL_DYNARRAY_WIPE(&obj->sigident); + TRUNNEL_DYNARRAY_CLEAR(&obj->sigident); +} + +void +signed_tree_head_v1_free(signed_tree_head_v1_t *obj) +{ + if (obj == NULL) + return; + signed_tree_head_v1_clear(obj); + trunnel_memwipe(obj, sizeof(signed_tree_head_v1_t)); + trunnel_free_(obj); +} + +uint64_t +signed_tree_head_v1_get_format(const signed_tree_head_v1_t *inp) +{ + return inp->format; +} +int +signed_tree_head_v1_set_format(signed_tree_head_v1_t *inp, uint64_t val) +{ + if (! ((val == T_SIGNED_TREE_HEAD_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; + return 0; +} +uint64_t +signed_tree_head_v1_get_timestamp(const signed_tree_head_v1_t *inp) +{ + return inp->timestamp; +} +int +signed_tree_head_v1_set_timestamp(signed_tree_head_v1_t *inp, uint64_t val) +{ + inp->timestamp = val; + return 0; +} +uint64_t +signed_tree_head_v1_get_tree_size(const signed_tree_head_v1_t *inp) +{ + return inp->tree_size; +} +int +signed_tree_head_v1_set_tree_size(signed_tree_head_v1_t *inp, uint64_t val) +{ + inp->tree_size = val; + return 0; +} +size_t +signed_tree_head_v1_getlen_root_hash(const signed_tree_head_v1_t *inp) +{ + (void)inp; return 32; +} + +uint8_t +signed_tree_head_v1_get_root_hash(signed_tree_head_v1_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->root_hash[idx]; +} + +uint8_t +signed_tree_head_v1_getconst_root_hash(const signed_tree_head_v1_t *inp, size_t idx) +{ + return signed_tree_head_v1_get_root_hash((signed_tree_head_v1_t*)inp, idx); +} +int +signed_tree_head_v1_set_root_hash(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->root_hash[idx] = elt; + return 0; +} + +uint8_t * +signed_tree_head_v1_getarray_root_hash(signed_tree_head_v1_t *inp) +{ + return inp->root_hash; +} +const uint8_t * +signed_tree_head_v1_getconstarray_root_hash(const signed_tree_head_v1_t *inp) +{ + return (const uint8_t *)signed_tree_head_v1_getarray_root_hash((signed_tree_head_v1_t*)inp); +} +uint64_t +signed_tree_head_v1_get_length(const signed_tree_head_v1_t *inp) +{ + return inp->length; +} +int +signed_tree_head_v1_set_length(signed_tree_head_v1_t *inp, uint64_t val) +{ + inp->length = val; + return 0; +} +size_t +signed_tree_head_v1_getlen_sigident(const signed_tree_head_v1_t *inp) +{ + return TRUNNEL_DYNARRAY_LEN(&inp->sigident); +} + +uint8_t +signed_tree_head_v1_get_sigident(signed_tree_head_v1_t *inp, size_t idx) +{ + return TRUNNEL_DYNARRAY_GET(&inp->sigident, idx); +} + +uint8_t +signed_tree_head_v1_getconst_sigident(const signed_tree_head_v1_t *inp, size_t idx) +{ + return signed_tree_head_v1_get_sigident((signed_tree_head_v1_t*)inp, idx); +} +int +signed_tree_head_v1_set_sigident(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->sigident, idx, elt); + return 0; +} +int +signed_tree_head_v1_add_sigident(signed_tree_head_v1_t *inp, uint8_t elt) +{ +#if SIZE_MAX >= UINT64_MAX + if (inp->sigident.n_ == UINT64_MAX) + goto trunnel_alloc_failed; +#endif + TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sigident, elt, {}); + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} + +uint8_t * +signed_tree_head_v1_getarray_sigident(signed_tree_head_v1_t *inp) +{ + return inp->sigident.elts_; +} +const uint8_t * +signed_tree_head_v1_getconstarray_sigident(const signed_tree_head_v1_t *inp) +{ + return (const uint8_t *)signed_tree_head_v1_getarray_sigident((signed_tree_head_v1_t*)inp); +} +int +signed_tree_head_v1_setlen_sigident(signed_tree_head_v1_t *inp, size_t newlen) +{ + uint8_t *newptr; +#if UINT64_MAX < SIZE_MAX + if (newlen > UINT64_MAX) + goto trunnel_alloc_failed; +#endif + newptr = trunnel_dynarray_setlen(&inp->sigident.allocated_, + &inp->sigident.n_, inp->sigident.elts_, newlen, + sizeof(inp->sigident.elts_[0]), (trunnel_free_fn_t) NULL, + &inp->trunnel_error_code_); + if (newlen != 0 && newptr == NULL) + goto trunnel_alloc_failed; + inp->sigident.elts_ = newptr; + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} +const char * +signed_tree_head_v1_check(const signed_tree_head_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! (obj->format == T_SIGNED_TREE_HEAD_V1)) + return "Integer out of bounds"; + if (TRUNNEL_DYNARRAY_LEN(&obj->sigident) != obj->length) + return "Length mismatch for sigident"; + return NULL; +} + +ssize_t +signed_tree_head_v1_encoded_len(const signed_tree_head_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != signed_tree_head_v1_check(obj)) + return -1; + + + /* Length of u64 format IN [T_SIGNED_TREE_HEAD_V1] */ + result += 8; + + /* Length of u64 timestamp */ + result += 8; + + /* Length of u64 tree_size */ + result += 8; + + /* Length of u8 root_hash[32] */ + result += 32; + + /* Length of u64 length */ + result += 8; + + /* Length of u8 sigident[length] */ + result += TRUNNEL_DYNARRAY_LEN(&obj->sigident); + return result; +} +int +signed_tree_head_v1_clear_errors(signed_tree_head_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +signed_tree_head_v1_encode(uint8_t *output, const size_t avail, const signed_tree_head_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = signed_tree_head_v1_encoded_len(obj); +#endif + + if (NULL != (msg = signed_tree_head_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 format IN [T_SIGNED_TREE_HEAD_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; + + /* Encode u64 timestamp */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->timestamp)); + written += 8; ptr += 8; + + /* Encode u64 tree_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->tree_size)); + written += 8; ptr += 8; + + /* Encode u8 root_hash[32] */ + trunnel_assert(written <= avail); + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->root_hash, 32); + written += 32; ptr += 32; + + /* Encode u64 length */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + written += 8; ptr += 8; + + /* Encode u8 sigident[length] */ + { + size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sigident); + trunnel_assert(obj->length == elt_len); + trunnel_assert(written <= avail); + if (avail - written < elt_len) + goto truncated; + if (elt_len) + memcpy(ptr, obj->sigident.elts_, elt_len); + written += elt_len; ptr += elt_len; + } + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As signed_tree_head_v1_parse(), but do not allocate the output + * object. + */ +static ssize_t +signed_tree_head_v1_parse_into(signed_tree_head_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 format IN [T_SIGNED_TREE_HEAD_V1] */ + CHECK_REMAINING(8, truncated); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->format == T_SIGNED_TREE_HEAD_V1)) + goto fail; + + /* Parse u64 timestamp */ + CHECK_REMAINING(8, truncated); + obj->timestamp = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 tree_size */ + CHECK_REMAINING(8, truncated); + obj->tree_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u8 root_hash[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->root_hash, ptr, 32); + remaining -= 32; ptr += 32; + + /* Parse u64 length */ + CHECK_REMAINING(8, truncated); + obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u8 sigident[length] */ + CHECK_REMAINING(obj->length, truncated); + TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sigident, obj->length, {}); + obj->sigident.n_ = obj->length; + if (obj->length) + memcpy(obj->sigident.elts_, ptr, obj->length); + ptr += obj->length; remaining -= obj->length; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; + trunnel_alloc_failed: + return -1; + fail: + result = -1; + return result; +} + +ssize_t +signed_tree_head_v1_parse(signed_tree_head_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = signed_tree_head_v1_new(); + if (NULL == *output) + return -1; + result = signed_tree_head_v1_parse_into(*output, input, len_in); + if (result < 0) { + signed_tree_head_v1_free(*output); + *output = NULL; + } + return result; +} +consistency_proof_v1_t * +consistency_proof_v1_new(void) +{ + consistency_proof_v1_t *val = trunnel_calloc(1, sizeof(consistency_proof_v1_t)); + if (NULL == val) + return NULL; + val->format = T_CONSISTENCY_PROOF_V1; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +consistency_proof_v1_clear(consistency_proof_v1_t *obj) +{ + (void) obj; + ed25519_v1_free(obj->identifier); + obj->identifier = NULL; + TRUNNEL_DYNARRAY_WIPE(&obj->hashes); + TRUNNEL_DYNARRAY_CLEAR(&obj->hashes); +} + +void +consistency_proof_v1_free(consistency_proof_v1_t *obj) +{ + if (obj == NULL) + return; + consistency_proof_v1_clear(obj); + trunnel_memwipe(obj, sizeof(consistency_proof_v1_t)); + trunnel_free_(obj); +} + +uint64_t +consistency_proof_v1_get_format(const consistency_proof_v1_t *inp) +{ + return inp->format; +} +int +consistency_proof_v1_set_format(consistency_proof_v1_t *inp, uint64_t val) +{ + if (! ((val == T_CONSISTENCY_PROOF_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; + return 0; +} +struct ed25519_v1_st * +consistency_proof_v1_get_identifier(consistency_proof_v1_t *inp) +{ + return inp->identifier; +} +const struct ed25519_v1_st * +consistency_proof_v1_getconst_identifier(const consistency_proof_v1_t *inp) +{ + return consistency_proof_v1_get_identifier((consistency_proof_v1_t*) inp); +} +int +consistency_proof_v1_set_identifier(consistency_proof_v1_t *inp, struct ed25519_v1_st *val) +{ + if (inp->identifier && inp->identifier != val) + ed25519_v1_free(inp->identifier); + return consistency_proof_v1_set0_identifier(inp, val); +} +int +consistency_proof_v1_set0_identifier(consistency_proof_v1_t *inp, struct ed25519_v1_st *val) +{ + inp->identifier = val; + return 0; +} +uint64_t +consistency_proof_v1_get_old_size(const consistency_proof_v1_t *inp) +{ + return inp->old_size; +} +int +consistency_proof_v1_set_old_size(consistency_proof_v1_t *inp, uint64_t val) +{ + inp->old_size = val; + return 0; +} +uint64_t +consistency_proof_v1_get_new_size(const consistency_proof_v1_t *inp) +{ + return inp->new_size; +} +int +consistency_proof_v1_set_new_size(consistency_proof_v1_t *inp, uint64_t val) +{ + inp->new_size = val; + return 0; +} +uint64_t +consistency_proof_v1_get_length(const consistency_proof_v1_t *inp) +{ + return inp->length; +} +int +consistency_proof_v1_set_length(consistency_proof_v1_t *inp, uint64_t val) +{ + inp->length = val; + return 0; +} +size_t +consistency_proof_v1_getlen_hashes(const consistency_proof_v1_t *inp) +{ + return TRUNNEL_DYNARRAY_LEN(&inp->hashes); +} + +uint8_t +consistency_proof_v1_get_hashes(consistency_proof_v1_t *inp, size_t idx) +{ + return TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); +} + +uint8_t +consistency_proof_v1_getconst_hashes(const consistency_proof_v1_t *inp, size_t idx) +{ + return consistency_proof_v1_get_hashes((consistency_proof_v1_t*)inp, idx); +} +int +consistency_proof_v1_set_hashes(consistency_proof_v1_t *inp, size_t idx, uint8_t elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->hashes, idx, elt); + return 0; +} +int +consistency_proof_v1_add_hashes(consistency_proof_v1_t *inp, uint8_t elt) +{ +#if SIZE_MAX >= UINT64_MAX + if (inp->hashes.n_ == UINT64_MAX) + goto trunnel_alloc_failed; +#endif + TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->hashes, elt, {}); + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} + +uint8_t * +consistency_proof_v1_getarray_hashes(consistency_proof_v1_t *inp) +{ + return inp->hashes.elts_; +} +const uint8_t * +consistency_proof_v1_getconstarray_hashes(const consistency_proof_v1_t *inp) +{ + return (const uint8_t *)consistency_proof_v1_getarray_hashes((consistency_proof_v1_t*)inp); +} +int +consistency_proof_v1_setlen_hashes(consistency_proof_v1_t *inp, size_t newlen) +{ + uint8_t *newptr; +#if UINT64_MAX < SIZE_MAX + if (newlen > UINT64_MAX) + goto trunnel_alloc_failed; +#endif + newptr = trunnel_dynarray_setlen(&inp->hashes.allocated_, + &inp->hashes.n_, inp->hashes.elts_, newlen, + sizeof(inp->hashes.elts_[0]), (trunnel_free_fn_t) NULL, + &inp->trunnel_error_code_); + if (newlen != 0 && newptr == NULL) + goto trunnel_alloc_failed; + inp->hashes.elts_ = newptr; + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} +const char * +consistency_proof_v1_check(const consistency_proof_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! (obj->format == T_CONSISTENCY_PROOF_V1)) + return "Integer out of bounds"; + { + const char *msg; + if (NULL != (msg = ed25519_v1_check(obj->identifier))) + return msg; + } + if (TRUNNEL_DYNARRAY_LEN(&obj->hashes) != obj->length) + return "Length mismatch for hashes"; + return NULL; +} + +ssize_t +consistency_proof_v1_encoded_len(const consistency_proof_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != consistency_proof_v1_check(obj)) + return -1; + + + /* Length of u64 format IN [T_CONSISTENCY_PROOF_V1] */ + result += 8; + + /* Length of struct ed25519_v1 identifier */ + result += ed25519_v1_encoded_len(obj->identifier); + + /* Length of u64 old_size */ + result += 8; + + /* Length of u64 new_size */ + result += 8; + + /* Length of u64 length */ + result += 8; + + /* Length of u8 hashes[length] */ + result += TRUNNEL_DYNARRAY_LEN(&obj->hashes); + return result; +} +int +consistency_proof_v1_clear_errors(consistency_proof_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +consistency_proof_v1_encode(uint8_t *output, const size_t avail, const consistency_proof_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = consistency_proof_v1_encoded_len(obj); +#endif + + if (NULL != (msg = consistency_proof_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 format IN [T_CONSISTENCY_PROOF_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; + + /* Encode struct ed25519_v1 identifier */ + trunnel_assert(written <= avail); + result = ed25519_v1_encode(ptr, avail - written, obj->identifier); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + + /* Encode u64 old_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->old_size)); + written += 8; ptr += 8; + + /* Encode u64 new_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->new_size)); + written += 8; ptr += 8; + + /* Encode u64 length */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + written += 8; ptr += 8; + + /* Encode u8 hashes[length] */ + { + size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->hashes); + trunnel_assert(obj->length == elt_len); + trunnel_assert(written <= avail); + if (avail - written < elt_len) + goto truncated; + if (elt_len) + memcpy(ptr, obj->hashes.elts_, elt_len); + written += elt_len; ptr += elt_len; + } + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As consistency_proof_v1_parse(), but do not allocate the output + * object. + */ +static ssize_t +consistency_proof_v1_parse_into(consistency_proof_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 format IN [T_CONSISTENCY_PROOF_V1] */ + CHECK_REMAINING(8, truncated); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->format == T_CONSISTENCY_PROOF_V1)) + goto fail; + + /* Parse struct ed25519_v1 identifier */ + result = ed25519_v1_parse(&obj->identifier, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + + /* Parse u64 old_size */ + CHECK_REMAINING(8, truncated); + obj->old_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 new_size */ + CHECK_REMAINING(8, truncated); + obj->new_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 length */ + CHECK_REMAINING(8, truncated); + obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u8 hashes[length] */ + CHECK_REMAINING(obj->length, truncated); + TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->hashes, obj->length, {}); + obj->hashes.n_ = obj->length; + if (obj->length) + memcpy(obj->hashes.elts_, ptr, obj->length); + ptr += obj->length; remaining -= obj->length; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; + relay_fail: + trunnel_assert(result < 0); + return result; + trunnel_alloc_failed: + return -1; + fail: + result = -1; + return result; +} + +ssize_t +consistency_proof_v1_parse(consistency_proof_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = consistency_proof_v1_new(); + if (NULL == *output) + return -1; + result = consistency_proof_v1_parse_into(*output, input, len_in); + if (result < 0) { + consistency_proof_v1_free(*output); + *output = NULL; + } + return result; +} +inclusion_proof_v1_t * +inclusion_proof_v1_new(void) +{ + inclusion_proof_v1_t *val = trunnel_calloc(1, sizeof(inclusion_proof_v1_t)); + if (NULL == val) + return NULL; + val->format = T_INCLUSION_PROOF_V1; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +inclusion_proof_v1_clear(inclusion_proof_v1_t *obj) +{ + (void) obj; + ed25519_v1_free(obj->identifier); + obj->identifier = NULL; + TRUNNEL_DYNARRAY_WIPE(&obj->hashes); + TRUNNEL_DYNARRAY_CLEAR(&obj->hashes); +} + +void +inclusion_proof_v1_free(inclusion_proof_v1_t *obj) +{ + if (obj == NULL) + return; + inclusion_proof_v1_clear(obj); + trunnel_memwipe(obj, sizeof(inclusion_proof_v1_t)); + trunnel_free_(obj); +} + +uint64_t +inclusion_proof_v1_get_format(const inclusion_proof_v1_t *inp) +{ + return inp->format; +} +int +inclusion_proof_v1_set_format(inclusion_proof_v1_t *inp, uint64_t val) +{ + if (! ((val == T_INCLUSION_PROOF_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; + return 0; +} +struct ed25519_v1_st * +inclusion_proof_v1_get_identifier(inclusion_proof_v1_t *inp) +{ + return inp->identifier; +} +const struct ed25519_v1_st * +inclusion_proof_v1_getconst_identifier(const inclusion_proof_v1_t *inp) +{ + return inclusion_proof_v1_get_identifier((inclusion_proof_v1_t*) inp); +} +int +inclusion_proof_v1_set_identifier(inclusion_proof_v1_t *inp, struct ed25519_v1_st *val) +{ + if (inp->identifier && inp->identifier != val) + ed25519_v1_free(inp->identifier); + return inclusion_proof_v1_set0_identifier(inp, val); +} +int +inclusion_proof_v1_set0_identifier(inclusion_proof_v1_t *inp, struct ed25519_v1_st *val) +{ + inp->identifier = val; + return 0; +} +uint64_t +inclusion_proof_v1_get_tree_size(const inclusion_proof_v1_t *inp) +{ + return inp->tree_size; +} +int +inclusion_proof_v1_set_tree_size(inclusion_proof_v1_t *inp, uint64_t val) +{ + inp->tree_size = val; + return 0; +} +uint64_t +inclusion_proof_v1_get_leaf_index(const inclusion_proof_v1_t *inp) +{ + return inp->leaf_index; +} +int +inclusion_proof_v1_set_leaf_index(inclusion_proof_v1_t *inp, uint64_t val) +{ + inp->leaf_index = val; + return 0; +} +uint64_t +inclusion_proof_v1_get_length(const inclusion_proof_v1_t *inp) +{ + return inp->length; +} +int +inclusion_proof_v1_set_length(inclusion_proof_v1_t *inp, uint64_t val) +{ + inp->length = val; + return 0; +} +size_t +inclusion_proof_v1_getlen_hashes(const inclusion_proof_v1_t *inp) +{ + return TRUNNEL_DYNARRAY_LEN(&inp->hashes); +} + +uint8_t +inclusion_proof_v1_get_hashes(inclusion_proof_v1_t *inp, size_t idx) +{ + return TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); +} + +uint8_t +inclusion_proof_v1_getconst_hashes(const inclusion_proof_v1_t *inp, size_t idx) +{ + return inclusion_proof_v1_get_hashes((inclusion_proof_v1_t*)inp, idx); +} +int +inclusion_proof_v1_set_hashes(inclusion_proof_v1_t *inp, size_t idx, uint8_t elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->hashes, idx, elt); + return 0; +} +int +inclusion_proof_v1_add_hashes(inclusion_proof_v1_t *inp, uint8_t elt) +{ +#if SIZE_MAX >= UINT64_MAX + if (inp->hashes.n_ == UINT64_MAX) + goto trunnel_alloc_failed; +#endif + TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->hashes, elt, {}); + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} + +uint8_t * +inclusion_proof_v1_getarray_hashes(inclusion_proof_v1_t *inp) +{ + return inp->hashes.elts_; +} +const uint8_t * +inclusion_proof_v1_getconstarray_hashes(const inclusion_proof_v1_t *inp) +{ + return (const uint8_t *)inclusion_proof_v1_getarray_hashes((inclusion_proof_v1_t*)inp); +} +int +inclusion_proof_v1_setlen_hashes(inclusion_proof_v1_t *inp, size_t newlen) +{ + uint8_t *newptr; +#if UINT64_MAX < SIZE_MAX + if (newlen > UINT64_MAX) + goto trunnel_alloc_failed; +#endif + newptr = trunnel_dynarray_setlen(&inp->hashes.allocated_, + &inp->hashes.n_, inp->hashes.elts_, newlen, + sizeof(inp->hashes.elts_[0]), (trunnel_free_fn_t) NULL, + &inp->trunnel_error_code_); + if (newlen != 0 && newptr == NULL) + goto trunnel_alloc_failed; + inp->hashes.elts_ = newptr; + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} +const char * +inclusion_proof_v1_check(const inclusion_proof_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! (obj->format == T_INCLUSION_PROOF_V1)) + return "Integer out of bounds"; + { + const char *msg; + if (NULL != (msg = ed25519_v1_check(obj->identifier))) + return msg; + } + if (TRUNNEL_DYNARRAY_LEN(&obj->hashes) != obj->length) + return "Length mismatch for hashes"; + return NULL; +} + +ssize_t +inclusion_proof_v1_encoded_len(const inclusion_proof_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != inclusion_proof_v1_check(obj)) + return -1; + + + /* Length of u64 format IN [T_INCLUSION_PROOF_V1] */ + result += 8; + + /* Length of struct ed25519_v1 identifier */ + result += ed25519_v1_encoded_len(obj->identifier); + + /* Length of u64 tree_size */ + result += 8; + + /* Length of u64 leaf_index */ + result += 8; + + /* Length of u64 length */ + result += 8; + + /* Length of u8 hashes[length] */ + result += TRUNNEL_DYNARRAY_LEN(&obj->hashes); + return result; +} +int +inclusion_proof_v1_clear_errors(inclusion_proof_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +inclusion_proof_v1_encode(uint8_t *output, const size_t avail, const inclusion_proof_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = inclusion_proof_v1_encoded_len(obj); +#endif + + if (NULL != (msg = inclusion_proof_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 format IN [T_INCLUSION_PROOF_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; + + /* Encode struct ed25519_v1 identifier */ + trunnel_assert(written <= avail); + result = ed25519_v1_encode(ptr, avail - written, obj->identifier); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + + /* Encode u64 tree_size */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->tree_size)); + written += 8; ptr += 8; + + /* Encode u64 leaf_index */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->leaf_index)); + written += 8; ptr += 8; + + /* Encode u64 length */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + written += 8; ptr += 8; + + /* Encode u8 hashes[length] */ + { + size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->hashes); + trunnel_assert(obj->length == elt_len); + trunnel_assert(written <= avail); + if (avail - written < elt_len) + goto truncated; + if (elt_len) + memcpy(ptr, obj->hashes.elts_, elt_len); + written += elt_len; ptr += elt_len; + } + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As inclusion_proof_v1_parse(), but do not allocate the output + * object. + */ +static ssize_t +inclusion_proof_v1_parse_into(inclusion_proof_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 format IN [T_INCLUSION_PROOF_V1] */ + CHECK_REMAINING(8, truncated); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->format == T_INCLUSION_PROOF_V1)) + goto fail; + + /* Parse struct ed25519_v1 identifier */ + result = ed25519_v1_parse(&obj->identifier, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + + /* Parse u64 tree_size */ + CHECK_REMAINING(8, truncated); + obj->tree_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 leaf_index */ + CHECK_REMAINING(8, truncated); + obj->leaf_index = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u64 length */ + CHECK_REMAINING(8, truncated); + obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse u8 hashes[length] */ + CHECK_REMAINING(obj->length, truncated); + TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->hashes, obj->length, {}); + obj->hashes.n_ = obj->length; + if (obj->length) + memcpy(obj->hashes.elts_, ptr, obj->length); + ptr += obj->length; remaining -= obj->length; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; + relay_fail: + trunnel_assert(result < 0); + return result; + trunnel_alloc_failed: + return -1; + fail: + result = -1; + return result; +} + +ssize_t +inclusion_proof_v1_parse(inclusion_proof_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = inclusion_proof_v1_new(); + if (NULL == *output) + return -1; + result = inclusion_proof_v1_parse_into(*output, input, len_in); + if (result < 0) { + inclusion_proof_v1_free(*output); + *output = NULL; + } + return result; +} +request_v1_t * +request_v1_new(void) +{ + request_v1_t *val = trunnel_calloc(1, sizeof(request_v1_t)); + if (NULL == val) + return NULL; + val->format = T_GET_CONSISTENCY_PROOF_V1; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +request_v1_clear(request_v1_t *obj) +{ + (void) obj; + req_get_entries_v1_free(obj->request_get_entries); + obj->request_get_entries = NULL; + req_get_proof_by_hash_v1_free(obj->request_get_proof_by_hash); + obj->request_get_proof_by_hash = NULL; + req_get_consistency_proof_v1_free(obj->request_get_consistency_proof); + obj->request_get_consistency_proof = NULL; +} + +void +request_v1_free(request_v1_t *obj) +{ + if (obj == NULL) + return; + request_v1_clear(obj); + trunnel_memwipe(obj, sizeof(request_v1_t)); + trunnel_free_(obj); +} + +uint64_t +request_v1_get_format(const request_v1_t *inp) +{ + return inp->format; +} +int +request_v1_set_format(request_v1_t *inp, uint64_t val) +{ + if (! ((val == T_GET_CONSISTENCY_PROOF_V1 || val == T_GET_ENTRIES_V1 || val == T_GET_PROOF_BY_HASH_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; + return 0; +} +struct req_get_entries_v1_st * +request_v1_get_request_get_entries(request_v1_t *inp) +{ + return inp->request_get_entries; +} +const struct req_get_entries_v1_st * +request_v1_getconst_request_get_entries(const request_v1_t *inp) +{ + return request_v1_get_request_get_entries((request_v1_t*) inp); +} +int +request_v1_set_request_get_entries(request_v1_t *inp, struct req_get_entries_v1_st *val) +{ + if (inp->request_get_entries && inp->request_get_entries != val) + req_get_entries_v1_free(inp->request_get_entries); + return request_v1_set0_request_get_entries(inp, val); +} +int +request_v1_set0_request_get_entries(request_v1_t *inp, struct req_get_entries_v1_st *val) +{ + inp->request_get_entries = val; + return 0; +} +struct req_get_proof_by_hash_v1_st * +request_v1_get_request_get_proof_by_hash(request_v1_t *inp) +{ + return inp->request_get_proof_by_hash; +} +const struct req_get_proof_by_hash_v1_st * +request_v1_getconst_request_get_proof_by_hash(const request_v1_t *inp) +{ + return request_v1_get_request_get_proof_by_hash((request_v1_t*) inp); +} +int +request_v1_set_request_get_proof_by_hash(request_v1_t *inp, struct req_get_proof_by_hash_v1_st *val) +{ + if (inp->request_get_proof_by_hash && inp->request_get_proof_by_hash != val) + req_get_proof_by_hash_v1_free(inp->request_get_proof_by_hash); + return request_v1_set0_request_get_proof_by_hash(inp, val); +} +int +request_v1_set0_request_get_proof_by_hash(request_v1_t *inp, struct req_get_proof_by_hash_v1_st *val) +{ + inp->request_get_proof_by_hash = val; + return 0; +} +struct req_get_consistency_proof_v1_st * +request_v1_get_request_get_consistency_proof(request_v1_t *inp) +{ + return inp->request_get_consistency_proof; +} +const struct req_get_consistency_proof_v1_st * +request_v1_getconst_request_get_consistency_proof(const request_v1_t *inp) +{ + return request_v1_get_request_get_consistency_proof((request_v1_t*) inp); +} +int +request_v1_set_request_get_consistency_proof(request_v1_t *inp, struct req_get_consistency_proof_v1_st *val) +{ + if (inp->request_get_consistency_proof && inp->request_get_consistency_proof != val) + req_get_consistency_proof_v1_free(inp->request_get_consistency_proof); + return request_v1_set0_request_get_consistency_proof(inp, val); +} +int +request_v1_set0_request_get_consistency_proof(request_v1_t *inp, struct req_get_consistency_proof_v1_st *val) +{ + inp->request_get_consistency_proof = val; + return 0; +} +const char * +request_v1_check(const request_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! (obj->format == T_GET_CONSISTENCY_PROOF_V1 || obj->format == T_GET_ENTRIES_V1 || obj->format == T_GET_PROOF_BY_HASH_V1)) + return "Integer out of bounds"; + switch (obj->format) { + + case T_GET_ENTRIES_V1: + { + const char *msg; + if (NULL != (msg = req_get_entries_v1_check(obj->request_get_entries))) + return msg; + } + break; + + case T_GET_PROOF_BY_HASH_V1: + { + const char *msg; + if (NULL != (msg = req_get_proof_by_hash_v1_check(obj->request_get_proof_by_hash))) + return msg; + } + break; + + case T_GET_CONSISTENCY_PROOF_V1: + { + const char *msg; + if (NULL != (msg = req_get_consistency_proof_v1_check(obj->request_get_consistency_proof))) + return msg; + } + break; + + default: + return "Bad tag for union"; + break; + } + return NULL; +} + +ssize_t +request_v1_encoded_len(const request_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != request_v1_check(obj)) + return -1; + + + /* Length of u64 format IN [T_GET_CONSISTENCY_PROOF_V1, T_GET_ENTRIES_V1, T_GET_PROOF_BY_HASH_V1] */ + result += 8; + switch (obj->format) { + + case T_GET_ENTRIES_V1: + + /* Length of struct req_get_entries_v1 request_get_entries */ + result += req_get_entries_v1_encoded_len(obj->request_get_entries); + break; + + case T_GET_PROOF_BY_HASH_V1: + + /* Length of struct req_get_proof_by_hash_v1 request_get_proof_by_hash */ + result += req_get_proof_by_hash_v1_encoded_len(obj->request_get_proof_by_hash); + break; + + case T_GET_CONSISTENCY_PROOF_V1: + + /* Length of struct req_get_consistency_proof_v1 request_get_consistency_proof */ + result += req_get_consistency_proof_v1_encoded_len(obj->request_get_consistency_proof); + break; + + default: + trunnel_assert(0); + break; + } + return result; +} +int +request_v1_clear_errors(request_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +request_v1_encode(uint8_t *output, const size_t avail, const request_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = request_v1_encoded_len(obj); +#endif + + if (NULL != (msg = request_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 format IN [T_GET_CONSISTENCY_PROOF_V1, T_GET_ENTRIES_V1, T_GET_PROOF_BY_HASH_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; + + /* Encode union request[format] */ + trunnel_assert(written <= avail); + switch (obj->format) { + + case T_GET_ENTRIES_V1: + + /* Encode struct req_get_entries_v1 request_get_entries */ + trunnel_assert(written <= avail); + result = req_get_entries_v1_encode(ptr, avail - written, obj->request_get_entries); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + break; + + case T_GET_PROOF_BY_HASH_V1: + + /* Encode struct req_get_proof_by_hash_v1 request_get_proof_by_hash */ + trunnel_assert(written <= avail); + result = req_get_proof_by_hash_v1_encode(ptr, avail - written, obj->request_get_proof_by_hash); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + break; + + case T_GET_CONSISTENCY_PROOF_V1: + + /* Encode struct req_get_consistency_proof_v1 request_get_consistency_proof */ + trunnel_assert(written <= avail); + result = req_get_consistency_proof_v1_encode(ptr, avail - written, obj->request_get_consistency_proof); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + break; + + default: + trunnel_assert(0); + break; + } + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As request_v1_parse(), but do not allocate the output object. + */ +static ssize_t +request_v1_parse_into(request_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 format IN [T_GET_CONSISTENCY_PROOF_V1, T_GET_ENTRIES_V1, T_GET_PROOF_BY_HASH_V1] */ + CHECK_REMAINING(8, truncated); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->format == T_GET_CONSISTENCY_PROOF_V1 || obj->format == T_GET_ENTRIES_V1 || obj->format == T_GET_PROOF_BY_HASH_V1)) + goto fail; + + /* Parse union request[format] */ + switch (obj->format) { + + case T_GET_ENTRIES_V1: + + /* Parse struct req_get_entries_v1 request_get_entries */ + result = req_get_entries_v1_parse(&obj->request_get_entries, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + break; + + case T_GET_PROOF_BY_HASH_V1: + + /* Parse struct req_get_proof_by_hash_v1 request_get_proof_by_hash */ + result = req_get_proof_by_hash_v1_parse(&obj->request_get_proof_by_hash, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + break; + + case T_GET_CONSISTENCY_PROOF_V1: + + /* Parse struct req_get_consistency_proof_v1 request_get_consistency_proof */ + result = req_get_consistency_proof_v1_parse(&obj->request_get_consistency_proof, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + break; + + default: + goto fail; + break; + } + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; + relay_fail: + trunnel_assert(result < 0); + return result; + fail: + result = -1; + return result; +} + +ssize_t +request_v1_parse(request_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = request_v1_new(); + if (NULL == *output) + return -1; + result = request_v1_parse_into(*output, input, len_in); + if (result < 0) { + request_v1_free(*output); + *output = NULL; + } + return result; +} +signed_checksum32_ed25519_v1_t * +signed_checksum32_ed25519_v1_new(void) +{ + signed_checksum32_ed25519_v1_t *val = trunnel_calloc(1, sizeof(signed_checksum32_ed25519_v1_t)); + if (NULL == val) + return NULL; + val->format = T_SIGNED_CHECKSUM32_ED25519_V1; + val->length = 1; + return val; +} + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +signed_checksum32_ed25519_v1_clear(signed_checksum32_ed25519_v1_t *obj) +{ + (void) obj; + TRUNNEL_DYNARRAY_WIPE(&obj->identifier); + TRUNNEL_DYNARRAY_CLEAR(&obj->identifier); + ed25519_v1_free(obj->namespace); + obj->namespace = NULL; +} + +void +signed_checksum32_ed25519_v1_free(signed_checksum32_ed25519_v1_t *obj) +{ + if (obj == NULL) + return; + signed_checksum32_ed25519_v1_clear(obj); + trunnel_memwipe(obj, sizeof(signed_checksum32_ed25519_v1_t)); + trunnel_free_(obj); +} + +uint64_t +signed_checksum32_ed25519_v1_get_format(const signed_checksum32_ed25519_v1_t *inp) +{ + return inp->format; +} +int +signed_checksum32_ed25519_v1_set_format(signed_checksum32_ed25519_v1_t *inp, uint64_t val) +{ + if (! ((val == T_SIGNED_CHECKSUM32_ED25519_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; + return 0; +} +size_t +signed_checksum32_ed25519_v1_getlen_checksum(const signed_checksum32_ed25519_v1_t *inp) +{ + (void)inp; return 32; +} + +uint8_t +signed_checksum32_ed25519_v1_get_checksum(signed_checksum32_ed25519_v1_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->checksum[idx]; +} + +uint8_t +signed_checksum32_ed25519_v1_getconst_checksum(const signed_checksum32_ed25519_v1_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_v1_get_checksum((signed_checksum32_ed25519_v1_t*)inp, idx); +} +int +signed_checksum32_ed25519_v1_set_checksum(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->checksum[idx] = elt; + return 0; +} + +uint8_t * +signed_checksum32_ed25519_v1_getarray_checksum(signed_checksum32_ed25519_v1_t *inp) +{ + return inp->checksum; +} +const uint8_t * +signed_checksum32_ed25519_v1_getconstarray_checksum(const signed_checksum32_ed25519_v1_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_v1_getarray_checksum((signed_checksum32_ed25519_v1_t*)inp); +} +uint64_t +signed_checksum32_ed25519_v1_get_length(const signed_checksum32_ed25519_v1_t *inp) +{ + return inp->length; +} +int +signed_checksum32_ed25519_v1_set_length(signed_checksum32_ed25519_v1_t *inp, uint64_t val) +{ + if (! (((val >= 1 && val <= 127)))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->length = val; + return 0; +} +size_t +signed_checksum32_ed25519_v1_getlen_identifier(const signed_checksum32_ed25519_v1_t *inp) +{ + return TRUNNEL_DYNARRAY_LEN(&inp->identifier); +} + +uint8_t +signed_checksum32_ed25519_v1_get_identifier(signed_checksum32_ed25519_v1_t *inp, size_t idx) +{ + return TRUNNEL_DYNARRAY_GET(&inp->identifier, idx); +} + +uint8_t +signed_checksum32_ed25519_v1_getconst_identifier(const signed_checksum32_ed25519_v1_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_v1_get_identifier((signed_checksum32_ed25519_v1_t*)inp, idx); +} +int +signed_checksum32_ed25519_v1_set_identifier(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->identifier, idx, elt); + return 0; +} +int +signed_checksum32_ed25519_v1_add_identifier(signed_checksum32_ed25519_v1_t *inp, uint8_t elt) +{ +#if SIZE_MAX >= UINT64_MAX + if (inp->identifier.n_ == UINT64_MAX) + goto trunnel_alloc_failed; +#endif + TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->identifier, elt, {}); + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} + +uint8_t * +signed_checksum32_ed25519_v1_getarray_identifier(signed_checksum32_ed25519_v1_t *inp) +{ + return inp->identifier.elts_; +} +const uint8_t * +signed_checksum32_ed25519_v1_getconstarray_identifier(const signed_checksum32_ed25519_v1_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_v1_getarray_identifier((signed_checksum32_ed25519_v1_t*)inp); +} +int +signed_checksum32_ed25519_v1_setlen_identifier(signed_checksum32_ed25519_v1_t *inp, size_t newlen) +{ + uint8_t *newptr; +#if UINT64_MAX < SIZE_MAX + if (newlen > UINT64_MAX) + goto trunnel_alloc_failed; +#endif + newptr = trunnel_dynarray_setlen(&inp->identifier.allocated_, + &inp->identifier.n_, inp->identifier.elts_, newlen, + sizeof(inp->identifier.elts_[0]), (trunnel_free_fn_t) NULL, + &inp->trunnel_error_code_); + if (newlen != 0 && newptr == NULL) + goto trunnel_alloc_failed; + inp->identifier.elts_ = newptr; + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} +size_t +signed_checksum32_ed25519_v1_getlen_signature(const signed_checksum32_ed25519_v1_t *inp) +{ + (void)inp; return 64; +} + +uint8_t +signed_checksum32_ed25519_v1_get_signature(signed_checksum32_ed25519_v1_t *inp, size_t idx) +{ + trunnel_assert(idx < 64); + return inp->signature[idx]; +} + +uint8_t +signed_checksum32_ed25519_v1_getconst_signature(const signed_checksum32_ed25519_v1_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_v1_get_signature((signed_checksum32_ed25519_v1_t*)inp, idx); +} +int +signed_checksum32_ed25519_v1_set_signature(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 64); + inp->signature[idx] = elt; + return 0; +} + +uint8_t * +signed_checksum32_ed25519_v1_getarray_signature(signed_checksum32_ed25519_v1_t *inp) +{ + return inp->signature; +} +const uint8_t * +signed_checksum32_ed25519_v1_getconstarray_signature(const signed_checksum32_ed25519_v1_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_v1_getarray_signature((signed_checksum32_ed25519_v1_t*)inp); +} +struct ed25519_v1_st * +signed_checksum32_ed25519_v1_get_namespace(signed_checksum32_ed25519_v1_t *inp) +{ + return inp->namespace; +} +const struct ed25519_v1_st * +signed_checksum32_ed25519_v1_getconst_namespace(const signed_checksum32_ed25519_v1_t *inp) +{ + return signed_checksum32_ed25519_v1_get_namespace((signed_checksum32_ed25519_v1_t*) inp); +} +int +signed_checksum32_ed25519_v1_set_namespace(signed_checksum32_ed25519_v1_t *inp, struct ed25519_v1_st *val) +{ + if (inp->namespace && inp->namespace != val) + ed25519_v1_free(inp->namespace); + return signed_checksum32_ed25519_v1_set0_namespace(inp, val); +} +int +signed_checksum32_ed25519_v1_set0_namespace(signed_checksum32_ed25519_v1_t *inp, struct ed25519_v1_st *val) +{ + inp->namespace = val; + return 0; +} +const char * +signed_checksum32_ed25519_v1_check(const signed_checksum32_ed25519_v1_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! (obj->format == T_SIGNED_CHECKSUM32_ED25519_V1)) + return "Integer out of bounds"; + if (! ((obj->length >= 1 && obj->length <= 127))) + return "Integer out of bounds"; + if (TRUNNEL_DYNARRAY_LEN(&obj->identifier) != obj->length) + return "Length mismatch for identifier"; + { + const char *msg; + if (NULL != (msg = ed25519_v1_check(obj->namespace))) + return msg; + } + return NULL; +} + +ssize_t +signed_checksum32_ed25519_v1_encoded_len(const signed_checksum32_ed25519_v1_t *obj) +{ + ssize_t result = 0; + + if (NULL != signed_checksum32_ed25519_v1_check(obj)) + return -1; + + + /* Length of u64 format IN [T_SIGNED_CHECKSUM32_ED25519_V1] */ + result += 8; + + /* Length of u8 checksum[32] */ + result += 32; + + /* Length of u64 length IN [1..127] */ + result += 8; + + /* Length of u8 identifier[length] */ + result += TRUNNEL_DYNARRAY_LEN(&obj->identifier); + + /* Length of u8 signature[64] */ + result += 64; + + /* Length of struct ed25519_v1 namespace */ + result += ed25519_v1_encoded_len(obj->namespace); + return result; +} +int +signed_checksum32_ed25519_v1_clear_errors(signed_checksum32_ed25519_v1_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +signed_checksum32_ed25519_v1_encode(uint8_t *output, const size_t avail, const signed_checksum32_ed25519_v1_t *obj) +{ + ssize_t result = 0; + size_t written = 0; + uint8_t *ptr = output; + const char *msg; +#ifdef TRUNNEL_CHECK_ENCODED_LEN + const ssize_t encoded_len = signed_checksum32_ed25519_v1_encoded_len(obj); +#endif + + if (NULL != (msg = signed_checksum32_ed25519_v1_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* Encode u64 format IN [T_SIGNED_CHECKSUM32_ED25519_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; + + /* Encode u8 checksum[32] */ + trunnel_assert(written <= avail); + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->checksum, 32); + written += 32; ptr += 32; + + /* Encode u64 length IN [1..127] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + written += 8; ptr += 8; + + /* Encode u8 identifier[length] */ + { + size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->identifier); + trunnel_assert(obj->length == elt_len); + trunnel_assert(written <= avail); + if (avail - written < elt_len) + goto truncated; + if (elt_len) + memcpy(ptr, obj->identifier.elts_, elt_len); + written += elt_len; ptr += elt_len; + } + + /* Encode u8 signature[64] */ + trunnel_assert(written <= avail); + if (avail - written < 64) + goto truncated; + memcpy(ptr, obj->signature, 64); + written += 64; ptr += 64; + + /* Encode struct ed25519_v1 namespace */ + trunnel_assert(written <= avail); + result = ed25519_v1_encode(ptr, avail - written, obj->namespace); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + + + trunnel_assert(ptr == output + written); +#ifdef TRUNNEL_CHECK_ENCODED_LEN + { + trunnel_assert(encoded_len >= 0); + trunnel_assert((size_t)encoded_len == written); + } + +#endif + + return written; + + truncated: + result = -2; + goto fail; + check_failed: + (void)msg; + result = -1; + goto fail; + fail: + trunnel_assert(result < 0); + return result; +} + +/** As signed_checksum32_ed25519_v1_parse(), but do not allocate the + * output object. + */ +static ssize_t +signed_checksum32_ed25519_v1_parse_into(signed_checksum32_ed25519_v1_t *obj, const uint8_t *input, const size_t len_in) +{ + const uint8_t *ptr = input; + size_t remaining = len_in; + ssize_t result = 0; + (void)result; + + /* Parse u64 format IN [T_SIGNED_CHECKSUM32_ED25519_V1] */ + CHECK_REMAINING(8, truncated); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->format == T_SIGNED_CHECKSUM32_ED25519_V1)) + goto fail; + + /* Parse u8 checksum[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->checksum, ptr, 32); + remaining -= 32; ptr += 32; + + /* Parse u64 length IN [1..127] */ + CHECK_REMAINING(8, truncated); + obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! ((obj->length >= 1 && obj->length <= 127))) + goto fail; + + /* Parse u8 identifier[length] */ + CHECK_REMAINING(obj->length, truncated); + TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->identifier, obj->length, {}); + obj->identifier.n_ = obj->length; + if (obj->length) + memcpy(obj->identifier.elts_, ptr, obj->length); + ptr += obj->length; remaining -= obj->length; + + /* Parse u8 signature[64] */ + CHECK_REMAINING(64, truncated); + memcpy(obj->signature, ptr, 64); + remaining -= 64; ptr += 64; + + /* Parse struct ed25519_v1 namespace */ + result = ed25519_v1_parse(&obj->namespace, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + trunnel_assert(ptr + remaining == input + len_in); + return len_in - remaining; + + truncated: + return -2; + relay_fail: + trunnel_assert(result < 0); + return result; + trunnel_alloc_failed: + return -1; + fail: + result = -1; + return result; +} + +ssize_t +signed_checksum32_ed25519_v1_parse(signed_checksum32_ed25519_v1_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = signed_checksum32_ed25519_v1_new(); + if (NULL == *output) + return -1; + result = signed_checksum32_ed25519_v1_parse_into(*output, input, len_in); + if (result < 0) { + signed_checksum32_ed25519_v1_free(*output); + *output = NULL; + } + return result; +} -- cgit v1.2.3