From f3134997ccbb525cd09a8144ed6daeeb3245326a Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Thu, 1 Apr 2021 12:54:48 +0200 Subject: trunnel description take two --- trunnel/stfe.c | 2236 ++++++++++++++++++++++++++++++++++---------------- trunnel/stfe.h | 930 +++++++++++++-------- trunnel/stfe.trunnel | 79 +- 3 files changed, 2144 insertions(+), 1101 deletions(-) diff --git a/trunnel/stfe.c b/trunnel/stfe.c index 58ecd66..7bf2652 100644 --- a/trunnel/stfe.c +++ b/trunnel/stfe.c @@ -28,150 +28,122 @@ int stfe_deadcode_dummy__ = 0; } \ } while (0) -ed25519_v1_t * -ed25519_v1_new(void) +hash_t * +hash_new(void) { - ed25519_v1_t *val = trunnel_calloc(1, sizeof(ed25519_v1_t)); + hash_t *val = trunnel_calloc(1, sizeof(hash_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) +hash_clear(hash_t *obj) { (void) obj; } void -ed25519_v1_free(ed25519_v1_t *obj) +hash_free(hash_t *obj) { if (obj == NULL) return; - ed25519_v1_clear(obj); - trunnel_memwipe(obj, sizeof(ed25519_v1_t)); + hash_clear(obj); + trunnel_memwipe(obj, sizeof(hash_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) +hash_getlen_hash(const hash_t *inp) { (void)inp; return 32; } uint8_t -ed25519_v1_get_pubkey(ed25519_v1_t *inp, size_t idx) +hash_get_hash(hash_t *inp, size_t idx) { trunnel_assert(idx < 32); - return inp->pubkey[idx]; + return inp->hash[idx]; } uint8_t -ed25519_v1_getconst_pubkey(const ed25519_v1_t *inp, size_t idx) +hash_getconst_hash(const hash_t *inp, size_t idx) { - return ed25519_v1_get_pubkey((ed25519_v1_t*)inp, idx); + return hash_get_hash((hash_t*)inp, idx); } int -ed25519_v1_set_pubkey(ed25519_v1_t *inp, size_t idx, uint8_t elt) +hash_set_hash(hash_t *inp, size_t idx, uint8_t elt) { trunnel_assert(idx < 32); - inp->pubkey[idx] = elt; + inp->hash[idx] = elt; return 0; } uint8_t * -ed25519_v1_getarray_pubkey(ed25519_v1_t *inp) +hash_getarray_hash(hash_t *inp) { - return inp->pubkey; + return inp->hash; } const uint8_t * -ed25519_v1_getconstarray_pubkey(const ed25519_v1_t *inp) +hash_getconstarray_hash(const hash_t *inp) { - return (const uint8_t *)ed25519_v1_getarray_pubkey((ed25519_v1_t*)inp); + return (const uint8_t *)hash_getarray_hash((hash_t*)inp); } const char * -ed25519_v1_check(const ed25519_v1_t *obj) +hash_check(const hash_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) +hash_encoded_len(const hash_t *obj) { ssize_t result = 0; - if (NULL != ed25519_v1_check(obj)) + if (NULL != hash_check(obj)) return -1; - /* Length of u64 format IN [T_ED25519_V1] */ - result += 8; - - /* Length of u8 pubkey[32] */ + /* Length of u8 hash[32] */ result += 32; return result; } int -ed25519_v1_clear_errors(ed25519_v1_t *obj) +hash_clear_errors(hash_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) +hash_encode(uint8_t *output, const size_t avail, const hash_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); + const ssize_t encoded_len = hash_encoded_len(obj); #endif - if (NULL != (msg = ed25519_v1_check(obj))) + if (NULL != (msg = hash_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] */ + /* Encode u8 hash[32] */ trunnel_assert(written <= avail); if (avail - written < 32) goto truncated; - memcpy(ptr, obj->pubkey, 32); + memcpy(ptr, obj->hash, 32); written += 32; ptr += 32; @@ -198,47 +170,37 @@ ed25519_v1_encode(uint8_t *output, const size_t avail, const ed25519_v1_t *obj) return result; } -/** As ed25519_v1_parse(), but do not allocate the output object. +/** As hash_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) +hash_parse_into(hash_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] */ + /* Parse u8 hash[32] */ CHECK_REMAINING(32, truncated); - memcpy(obj->pubkey, ptr, 32); + memcpy(obj->hash, 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) +hash_parse(hash_t **output, const uint8_t *input, const size_t len_in) { ssize_t result; - *output = ed25519_v1_new(); + *output = hash_new(); if (NULL == *output) return -1; - result = ed25519_v1_parse_into(*output, input, len_in); + result = hash_parse_into(*output, input, len_in); if (result < 0) { - ed25519_v1_free(*output); + hash_free(*output); *output = NULL; } return result; @@ -805,301 +767,170 @@ req_get_proof_by_hash_v1_parse(req_get_proof_by_hash_v1_t **output, const uint8_ } return result; } -signed_tree_head_v1_t * -signed_tree_head_v1_new(void) +sigident_ed25519_t * +sigident_ed25519_new(void) { - signed_tree_head_v1_t *val = trunnel_calloc(1, sizeof(signed_tree_head_v1_t)); + sigident_ed25519_t *val = trunnel_calloc(1, sizeof(sigident_ed25519_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) +sigident_ed25519_clear(sigident_ed25519_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) +sigident_ed25519_free(sigident_ed25519_t *obj) { if (obj == NULL) return; - signed_tree_head_v1_clear(obj); - trunnel_memwipe(obj, sizeof(signed_tree_head_v1_t)); + sigident_ed25519_clear(obj); + trunnel_memwipe(obj, sizeof(sigident_ed25519_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) +sigident_ed25519_getlen_signature(const sigident_ed25519_t *inp) { - (void)inp; return 32; + (void)inp; return 64; } uint8_t -signed_tree_head_v1_get_root_hash(signed_tree_head_v1_t *inp, size_t idx) +sigident_ed25519_get_signature(sigident_ed25519_t *inp, size_t idx) { - trunnel_assert(idx < 32); - return inp->root_hash[idx]; + trunnel_assert(idx < 64); + return inp->signature[idx]; } uint8_t -signed_tree_head_v1_getconst_root_hash(const signed_tree_head_v1_t *inp, size_t idx) +sigident_ed25519_getconst_signature(const sigident_ed25519_t *inp, size_t idx) { - return signed_tree_head_v1_get_root_hash((signed_tree_head_v1_t*)inp, idx); + return sigident_ed25519_get_signature((sigident_ed25519_t*)inp, idx); } int -signed_tree_head_v1_set_root_hash(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt) +sigident_ed25519_set_signature(sigident_ed25519_t *inp, size_t idx, uint8_t elt) { - trunnel_assert(idx < 32); - inp->root_hash[idx] = elt; + trunnel_assert(idx < 64); + inp->signature[idx] = elt; return 0; } uint8_t * -signed_tree_head_v1_getarray_root_hash(signed_tree_head_v1_t *inp) +sigident_ed25519_getarray_signature(sigident_ed25519_t *inp) { - return inp->root_hash; + return inp->signature; } 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) +sigident_ed25519_getconstarray_signature(const sigident_ed25519_t *inp) { - inp->length = val; - return 0; + return (const uint8_t *)sigident_ed25519_getarray_signature((sigident_ed25519_t*)inp); } size_t -signed_tree_head_v1_getlen_sigident(const signed_tree_head_v1_t *inp) +sigident_ed25519_getlen_identifier(const sigident_ed25519_t *inp) { - return TRUNNEL_DYNARRAY_LEN(&inp->sigident); + (void)inp; return 32; } uint8_t -signed_tree_head_v1_get_sigident(signed_tree_head_v1_t *inp, size_t idx) +sigident_ed25519_get_identifier(sigident_ed25519_t *inp, size_t idx) { - return TRUNNEL_DYNARRAY_GET(&inp->sigident, idx); + trunnel_assert(idx < 32); + return inp->identifier[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) +sigident_ed25519_getconst_identifier(const sigident_ed25519_t *inp, size_t idx) { - TRUNNEL_DYNARRAY_SET(&inp->sigident, idx, elt); - return 0; + return sigident_ed25519_get_identifier((sigident_ed25519_t*)inp, idx); } int -signed_tree_head_v1_add_sigident(signed_tree_head_v1_t *inp, uint8_t elt) +sigident_ed25519_set_identifier(sigident_ed25519_t *inp, size_t idx, 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, {}); + trunnel_assert(idx < 32); + inp->identifier[idx] = 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) +sigident_ed25519_getarray_identifier(sigident_ed25519_t *inp) { - return inp->sigident.elts_; + return inp->identifier; } 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) +sigident_ed25519_getconstarray_identifier(const sigident_ed25519_t *inp) { - 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; + return (const uint8_t *)sigident_ed25519_getarray_identifier((sigident_ed25519_t*)inp); } const char * -signed_tree_head_v1_check(const signed_tree_head_v1_t *obj) +sigident_ed25519_check(const sigident_ed25519_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) +sigident_ed25519_encoded_len(const sigident_ed25519_t *obj) { ssize_t result = 0; - if (NULL != signed_tree_head_v1_check(obj)) + if (NULL != sigident_ed25519_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 signature[64] */ + result += 64; - /* Length of u8 root_hash[32] */ + /* Length of u8 identifier[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) +sigident_ed25519_clear_errors(sigident_ed25519_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) +sigident_ed25519_encode(uint8_t *output, const size_t avail, const sigident_ed25519_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); + const ssize_t encoded_len = sigident_ed25519_encoded_len(obj); #endif - if (NULL != (msg = signed_tree_head_v1_check(obj))) + if (NULL != (msg = sigident_ed25519_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 */ + /* Encode u8 signature[64] */ trunnel_assert(written <= avail); - if (avail - written < 8) + if (avail - written < 64) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->tree_size)); - written += 8; ptr += 8; + memcpy(ptr, obj->signature, 64); + written += 64; ptr += 64; - /* Encode u8 root_hash[32] */ + /* Encode u8 identifier[32] */ trunnel_assert(written <= avail); if (avail - written < 32) goto truncated; - memcpy(ptr, obj->root_hash, 32); + memcpy(ptr, obj->identifier, 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 @@ -1124,364 +955,1191 @@ signed_tree_head_v1_encode(uint8_t *output, const size_t avail, const signed_tre return result; } -/** As signed_tree_head_v1_parse(), but do not allocate the output +/** As sigident_ed25519_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) +sigident_ed25519_parse_into(sigident_ed25519_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 signature[64] */ + CHECK_REMAINING(64, truncated); + memcpy(obj->signature, ptr, 64); + remaining -= 64; ptr += 64; - /* Parse u8 root_hash[32] */ + /* Parse u8 identifier[32] */ CHECK_REMAINING(32, truncated); - memcpy(obj->root_hash, ptr, 32); + memcpy(obj->identifier, 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) +sigident_ed25519_parse(sigident_ed25519_t **output, const uint8_t *input, const size_t len_in) { ssize_t result; - *output = signed_tree_head_v1_new(); + *output = sigident_ed25519_new(); if (NULL == *output) return -1; - result = signed_tree_head_v1_parse_into(*output, input, len_in); + result = sigident_ed25519_parse_into(*output, input, len_in); if (result < 0) { - signed_tree_head_v1_free(*output); + sigident_ed25519_free(*output); *output = NULL; } return result; } -consistency_proof_v1_t * -consistency_proof_v1_new(void) +signed_checksum32_ed25519_t * +signed_checksum32_ed25519_new(void) { - consistency_proof_v1_t *val = trunnel_calloc(1, sizeof(consistency_proof_v1_t)); + signed_checksum32_ed25519_t *val = trunnel_calloc(1, sizeof(signed_checksum32_ed25519_t)); if (NULL == val) return NULL; - val->format = T_CONSISTENCY_PROOF_V1; + val->length = 1; return val; } /** Release all storage held inside 'obj', but do not free 'obj'. */ static void -consistency_proof_v1_clear(consistency_proof_v1_t *obj) +signed_checksum32_ed25519_clear(signed_checksum32_ed25519_t *obj) { (void) obj; - ed25519_v1_free(obj->identifier); - obj->identifier = NULL; - TRUNNEL_DYNARRAY_WIPE(&obj->hashes); - TRUNNEL_DYNARRAY_CLEAR(&obj->hashes); + TRUNNEL_DYNARRAY_WIPE(&obj->identifier); + TRUNNEL_DYNARRAY_CLEAR(&obj->identifier); } void -consistency_proof_v1_free(consistency_proof_v1_t *obj) +signed_checksum32_ed25519_free(signed_checksum32_ed25519_t *obj) { if (obj == NULL) return; - consistency_proof_v1_clear(obj); - trunnel_memwipe(obj, sizeof(consistency_proof_v1_t)); + signed_checksum32_ed25519_clear(obj); + trunnel_memwipe(obj, sizeof(signed_checksum32_ed25519_t)); trunnel_free_(obj); } -uint64_t -consistency_proof_v1_get_format(const consistency_proof_v1_t *inp) +size_t +signed_checksum32_ed25519_getlen_checksum(const signed_checksum32_ed25519_t *inp) { - return inp->format; + (void)inp; return 32; } -int -consistency_proof_v1_set_format(consistency_proof_v1_t *inp, uint64_t val) -{ - if (! ((val == T_CONSISTENCY_PROOF_V1))) { + +uint8_t +signed_checksum32_ed25519_get_checksum(signed_checksum32_ed25519_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->checksum[idx]; +} + +uint8_t +signed_checksum32_ed25519_getconst_checksum(const signed_checksum32_ed25519_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_get_checksum((signed_checksum32_ed25519_t*)inp, idx); +} +int +signed_checksum32_ed25519_set_checksum(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->checksum[idx] = elt; + return 0; +} + +uint8_t * +signed_checksum32_ed25519_getarray_checksum(signed_checksum32_ed25519_t *inp) +{ + return inp->checksum; +} +const uint8_t * +signed_checksum32_ed25519_getconstarray_checksum(const signed_checksum32_ed25519_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_getarray_checksum((signed_checksum32_ed25519_t*)inp); +} +uint64_t +signed_checksum32_ed25519_get_length(const signed_checksum32_ed25519_t *inp) +{ + return inp->length; +} +int +signed_checksum32_ed25519_set_length(signed_checksum32_ed25519_t *inp, uint64_t val) +{ + if (! (((val >= 1 && val <= 128)))) { TRUNNEL_SET_ERROR_CODE(inp); return -1; } - inp->format = val; + inp->length = val; + return 0; +} +size_t +signed_checksum32_ed25519_getlen_identifier(const signed_checksum32_ed25519_t *inp) +{ + return TRUNNEL_DYNARRAY_LEN(&inp->identifier); +} + +uint8_t +signed_checksum32_ed25519_get_identifier(signed_checksum32_ed25519_t *inp, size_t idx) +{ + return TRUNNEL_DYNARRAY_GET(&inp->identifier, idx); +} + +uint8_t +signed_checksum32_ed25519_getconst_identifier(const signed_checksum32_ed25519_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_get_identifier((signed_checksum32_ed25519_t*)inp, idx); +} +int +signed_checksum32_ed25519_set_identifier(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->identifier, idx, elt); + return 0; +} +int +signed_checksum32_ed25519_add_identifier(signed_checksum32_ed25519_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_getarray_identifier(signed_checksum32_ed25519_t *inp) +{ + return inp->identifier.elts_; +} +const uint8_t * +signed_checksum32_ed25519_getconstarray_identifier(const signed_checksum32_ed25519_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_getarray_identifier((signed_checksum32_ed25519_t*)inp); +} +int +signed_checksum32_ed25519_setlen_identifier(signed_checksum32_ed25519_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_getlen_signature(const signed_checksum32_ed25519_t *inp) +{ + (void)inp; return 64; +} + +uint8_t +signed_checksum32_ed25519_get_signature(signed_checksum32_ed25519_t *inp, size_t idx) +{ + trunnel_assert(idx < 64); + return inp->signature[idx]; +} + +uint8_t +signed_checksum32_ed25519_getconst_signature(const signed_checksum32_ed25519_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_get_signature((signed_checksum32_ed25519_t*)inp, idx); +} +int +signed_checksum32_ed25519_set_signature(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 64); + inp->signature[idx] = elt; + return 0; +} + +uint8_t * +signed_checksum32_ed25519_getarray_signature(signed_checksum32_ed25519_t *inp) +{ + return inp->signature; +} +const uint8_t * +signed_checksum32_ed25519_getconstarray_signature(const signed_checksum32_ed25519_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_getarray_signature((signed_checksum32_ed25519_t*)inp); +} +size_t +signed_checksum32_ed25519_getlen_namespace(const signed_checksum32_ed25519_t *inp) +{ + (void)inp; return 32; +} + +uint8_t +signed_checksum32_ed25519_get_namespace(signed_checksum32_ed25519_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->namespace[idx]; +} + +uint8_t +signed_checksum32_ed25519_getconst_namespace(const signed_checksum32_ed25519_t *inp, size_t idx) +{ + return signed_checksum32_ed25519_get_namespace((signed_checksum32_ed25519_t*)inp, idx); +} +int +signed_checksum32_ed25519_set_namespace(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->namespace[idx] = elt; return 0; } -struct ed25519_v1_st * -consistency_proof_v1_get_identifier(consistency_proof_v1_t *inp) + +uint8_t * +signed_checksum32_ed25519_getarray_namespace(signed_checksum32_ed25519_t *inp) +{ + return inp->namespace; +} +const uint8_t * +signed_checksum32_ed25519_getconstarray_namespace(const signed_checksum32_ed25519_t *inp) +{ + return (const uint8_t *)signed_checksum32_ed25519_getarray_namespace((signed_checksum32_ed25519_t*)inp); +} +const char * +signed_checksum32_ed25519_check(const signed_checksum32_ed25519_t *obj) +{ + if (obj == NULL) + return "Object was NULL"; + if (obj->trunnel_error_code_) + return "A set function failed on this object"; + if (! ((obj->length >= 1 && obj->length <= 128))) + return "Integer out of bounds"; + if (TRUNNEL_DYNARRAY_LEN(&obj->identifier) != obj->length) + return "Length mismatch for identifier"; + return NULL; +} + +ssize_t +signed_checksum32_ed25519_encoded_len(const signed_checksum32_ed25519_t *obj) +{ + ssize_t result = 0; + + if (NULL != signed_checksum32_ed25519_check(obj)) + return -1; + + + /* Length of u8 checksum[32] */ + result += 32; + + /* Length of u64 length IN [1..128] */ + result += 8; + + /* Length of u8 identifier[length] */ + result += TRUNNEL_DYNARRAY_LEN(&obj->identifier); + + /* Length of u8 signature[64] */ + result += 64; + + /* Length of u8 namespace[32] */ + result += 32; + return result; +} +int +signed_checksum32_ed25519_clear_errors(signed_checksum32_ed25519_t *obj) +{ + int r = obj->trunnel_error_code_; + obj->trunnel_error_code_ = 0; + return r; +} +ssize_t +signed_checksum32_ed25519_encode(uint8_t *output, const size_t avail, const signed_checksum32_ed25519_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_encoded_len(obj); +#endif + + if (NULL != (msg = signed_checksum32_ed25519_check(obj))) + goto check_failed; + +#ifdef TRUNNEL_CHECK_ENCODED_LEN + trunnel_assert(encoded_len >= 0); +#endif + + /* 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..128] */ + 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 u8 namespace[32] */ + trunnel_assert(written <= avail); + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->namespace, 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 signed_checksum32_ed25519_parse(), but do not allocate the + * output object. + */ +static ssize_t +signed_checksum32_ed25519_parse_into(signed_checksum32_ed25519_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 u8 checksum[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->checksum, ptr, 32); + remaining -= 32; ptr += 32; + + /* Parse u64 length IN [1..128] */ + CHECK_REMAINING(8, truncated); + obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! ((obj->length >= 1 && obj->length <= 128))) + 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 u8 namespace[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->namespace, ptr, 32); + remaining -= 32; ptr += 32; + 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_checksum32_ed25519_parse(signed_checksum32_ed25519_t **output, const uint8_t *input, const size_t len_in) +{ + ssize_t result; + *output = signed_checksum32_ed25519_new(); + if (NULL == *output) + return -1; + result = signed_checksum32_ed25519_parse_into(*output, input, len_in); + if (result < 0) { + signed_checksum32_ed25519_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->magic = MAGIC_V1; + 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; + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + hash_free(TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)); + } + } + 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_magic(const consistency_proof_v1_t *inp) +{ + return inp->magic; +} +int +consistency_proof_v1_set_magic(consistency_proof_v1_t *inp, uint64_t val) +{ + if (! ((val == MAGIC_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->magic = val; + return 0; +} +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; +} +size_t +consistency_proof_v1_getlen_identifier(const consistency_proof_v1_t *inp) +{ + (void)inp; return 32; +} + +uint8_t +consistency_proof_v1_get_identifier(consistency_proof_v1_t *inp, size_t idx) +{ + trunnel_assert(idx < 32); + return inp->identifier[idx]; +} + +uint8_t +consistency_proof_v1_getconst_identifier(const consistency_proof_v1_t *inp, size_t idx) +{ + return consistency_proof_v1_get_identifier((consistency_proof_v1_t*)inp, idx); +} +int +consistency_proof_v1_set_identifier(consistency_proof_v1_t *inp, size_t idx, uint8_t elt) +{ + trunnel_assert(idx < 32); + inp->identifier[idx] = elt; + return 0; +} + +uint8_t * +consistency_proof_v1_getarray_identifier(consistency_proof_v1_t *inp) +{ + return inp->identifier; +} +const uint8_t * +consistency_proof_v1_getconstarray_identifier(const consistency_proof_v1_t *inp) +{ + return (const uint8_t *)consistency_proof_v1_getarray_identifier((consistency_proof_v1_t*)inp); +} +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_n_items(const consistency_proof_v1_t *inp) +{ + return inp->n_items; +} +int +consistency_proof_v1_set_n_items(consistency_proof_v1_t *inp, uint64_t val) +{ + inp->n_items = val; + return 0; +} +size_t +consistency_proof_v1_getlen_hashes(const consistency_proof_v1_t *inp) +{ + return TRUNNEL_DYNARRAY_LEN(&inp->hashes); +} + +struct hash_st * +consistency_proof_v1_get_hashes(consistency_proof_v1_t *inp, size_t idx) +{ + return TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); +} + + const struct hash_st * +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, struct hash_st * elt) +{ + hash_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); + if (oldval && oldval != elt) + hash_free(oldval); + return consistency_proof_v1_set0_hashes(inp, idx, elt); +} +int +consistency_proof_v1_set0_hashes(consistency_proof_v1_t *inp, size_t idx, struct hash_st * elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->hashes, idx, elt); + return 0; +} +int +consistency_proof_v1_add_hashes(consistency_proof_v1_t *inp, struct hash_st * elt) +{ +#if SIZE_MAX >= UINT64_MAX + if (inp->hashes.n_ == UINT64_MAX) + goto trunnel_alloc_failed; +#endif + TRUNNEL_DYNARRAY_ADD(struct hash_st *, &inp->hashes, elt, {}); + return 0; + trunnel_alloc_failed: + TRUNNEL_SET_ERROR_CODE(inp); + return -1; +} + +struct hash_st * * +consistency_proof_v1_getarray_hashes(consistency_proof_v1_t *inp) +{ + return inp->hashes.elts_; +} +const struct hash_st * const * +consistency_proof_v1_getconstarray_hashes(const consistency_proof_v1_t *inp) +{ + return (const struct hash_st * const *)consistency_proof_v1_getarray_hashes((consistency_proof_v1_t*)inp); +} +int +consistency_proof_v1_setlen_hashes(consistency_proof_v1_t *inp, size_t newlen) +{ + struct hash_st * *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) hash_free, + &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->magic == MAGIC_V1)) + return "Integer out of bounds"; + if (! (obj->format == T_CONSISTENCY_PROOF_V1)) + return "Integer out of bounds"; + { + const char *msg; + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + if (NULL != (msg = hash_check(TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)))) + return msg; + } + } + if (TRUNNEL_DYNARRAY_LEN(&obj->hashes) != obj->n_items) + 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 magic IN [MAGIC_V1] */ + result += 8; + + /* Length of u64 format IN [T_CONSISTENCY_PROOF_V1] */ + result += 8; + + /* Length of u8 identifier[32] */ + result += 32; + + /* Length of u64 old_size */ + result += 8; + + /* Length of u64 new_size */ + result += 8; + + /* Length of u64 n_items */ + result += 8; + + /* Length of struct hash hashes[n_items] */ + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + result += hash_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)); + } + } + 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 magic IN [MAGIC_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->magic)); + written += 8; ptr += 8; + + /* 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 u8 identifier[32] */ + trunnel_assert(written <= avail); + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->identifier, 32); + written += 32; ptr += 32; + + /* 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 n_items */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->n_items)); + written += 8; ptr += 8; + + /* Encode struct hash hashes[n_items] */ + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + trunnel_assert(written <= avail); + result = hash_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)); + 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 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 magic IN [MAGIC_V1] */ + CHECK_REMAINING(8, truncated); + obj->magic = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->magic == MAGIC_V1)) + goto fail; + + /* 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 u8 identifier[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->identifier, ptr, 32); + remaining -= 32; ptr += 32; + + /* 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 n_items */ + CHECK_REMAINING(8, truncated); + obj->n_items = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + + /* Parse struct hash hashes[n_items] */ + TRUNNEL_DYNARRAY_EXPAND(hash_t *, &obj->hashes, obj->n_items, {}); + { + hash_t * elt; + unsigned idx; + for (idx = 0; idx < obj->n_items; ++idx) { + result = hash_parse(&elt, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + TRUNNEL_DYNARRAY_ADD(hash_t *, &obj->hashes, elt, {hash_free(elt);}); + } + } + 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) { - return inp->identifier; + 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; } -const struct ed25519_v1_st * -consistency_proof_v1_getconst_identifier(const consistency_proof_v1_t *inp) +entries_v1_t * +entries_v1_new(void) { - return consistency_proof_v1_get_identifier((consistency_proof_v1_t*) inp); + entries_v1_t *val = trunnel_calloc(1, sizeof(entries_v1_t)); + if (NULL == val) + return NULL; + val->magic = MAGIC_V1; + val->format = T_ENTRIES_V1; + return val; } -int -consistency_proof_v1_set_identifier(consistency_proof_v1_t *inp, struct ed25519_v1_st *val) + +/** Release all storage held inside 'obj', but do not free 'obj'. + */ +static void +entries_v1_clear(entries_v1_t *obj) { - if (inp->identifier && inp->identifier != val) - ed25519_v1_free(inp->identifier); - return consistency_proof_v1_set0_identifier(inp, val); + (void) obj; + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->checksums); ++idx) { + signed_checksum32_ed25519_free(TRUNNEL_DYNARRAY_GET(&obj->checksums, idx)); + } + } + TRUNNEL_DYNARRAY_WIPE(&obj->checksums); + TRUNNEL_DYNARRAY_CLEAR(&obj->checksums); } -int -consistency_proof_v1_set0_identifier(consistency_proof_v1_t *inp, struct ed25519_v1_st *val) + +void +entries_v1_free(entries_v1_t *obj) { - inp->identifier = val; - return 0; + if (obj == NULL) + return; + entries_v1_clear(obj); + trunnel_memwipe(obj, sizeof(entries_v1_t)); + trunnel_free_(obj); } + uint64_t -consistency_proof_v1_get_old_size(const consistency_proof_v1_t *inp) +entries_v1_get_magic(const entries_v1_t *inp) { - return inp->old_size; + return inp->magic; } int -consistency_proof_v1_set_old_size(consistency_proof_v1_t *inp, uint64_t val) +entries_v1_set_magic(entries_v1_t *inp, uint64_t val) { - inp->old_size = val; + if (! ((val == MAGIC_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->magic = val; return 0; } uint64_t -consistency_proof_v1_get_new_size(const consistency_proof_v1_t *inp) +entries_v1_get_format(const entries_v1_t *inp) { - return inp->new_size; + return inp->format; } int -consistency_proof_v1_set_new_size(consistency_proof_v1_t *inp, uint64_t val) +entries_v1_set_format(entries_v1_t *inp, uint64_t val) { - inp->new_size = val; + if (! ((val == T_ENTRIES_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->format = val; return 0; } uint64_t -consistency_proof_v1_get_length(const consistency_proof_v1_t *inp) +entries_v1_get_n_items(const entries_v1_t *inp) { - return inp->length; + return inp->n_items; } int -consistency_proof_v1_set_length(consistency_proof_v1_t *inp, uint64_t val) +entries_v1_set_n_items(entries_v1_t *inp, uint64_t val) { - inp->length = val; + inp->n_items = val; return 0; } size_t -consistency_proof_v1_getlen_hashes(const consistency_proof_v1_t *inp) +entries_v1_getlen_checksums(const entries_v1_t *inp) { - return TRUNNEL_DYNARRAY_LEN(&inp->hashes); + return TRUNNEL_DYNARRAY_LEN(&inp->checksums); } -uint8_t -consistency_proof_v1_get_hashes(consistency_proof_v1_t *inp, size_t idx) +struct signed_checksum32_ed25519_st * +entries_v1_get_checksums(entries_v1_t *inp, size_t idx) { - return TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); + return TRUNNEL_DYNARRAY_GET(&inp->checksums, idx); } -uint8_t -consistency_proof_v1_getconst_hashes(const consistency_proof_v1_t *inp, size_t idx) + const struct signed_checksum32_ed25519_st * +entries_v1_getconst_checksums(const entries_v1_t *inp, size_t idx) { - return consistency_proof_v1_get_hashes((consistency_proof_v1_t*)inp, idx); + return entries_v1_get_checksums((entries_v1_t*)inp, idx); } int -consistency_proof_v1_set_hashes(consistency_proof_v1_t *inp, size_t idx, uint8_t elt) +entries_v1_set_checksums(entries_v1_t *inp, size_t idx, struct signed_checksum32_ed25519_st * elt) { - TRUNNEL_DYNARRAY_SET(&inp->hashes, idx, elt); + signed_checksum32_ed25519_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->checksums, idx); + if (oldval && oldval != elt) + signed_checksum32_ed25519_free(oldval); + return entries_v1_set0_checksums(inp, idx, elt); +} +int +entries_v1_set0_checksums(entries_v1_t *inp, size_t idx, struct signed_checksum32_ed25519_st * elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->checksums, idx, elt); return 0; } int -consistency_proof_v1_add_hashes(consistency_proof_v1_t *inp, uint8_t elt) +entries_v1_add_checksums(entries_v1_t *inp, struct signed_checksum32_ed25519_st * elt) { #if SIZE_MAX >= UINT64_MAX - if (inp->hashes.n_ == UINT64_MAX) + if (inp->checksums.n_ == UINT64_MAX) goto trunnel_alloc_failed; #endif - TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->hashes, elt, {}); + TRUNNEL_DYNARRAY_ADD(struct signed_checksum32_ed25519_st *, &inp->checksums, 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) +struct signed_checksum32_ed25519_st * * +entries_v1_getarray_checksums(entries_v1_t *inp) { - return inp->hashes.elts_; + return inp->checksums.elts_; } -const uint8_t * -consistency_proof_v1_getconstarray_hashes(const consistency_proof_v1_t *inp) +const struct signed_checksum32_ed25519_st * const * +entries_v1_getconstarray_checksums(const entries_v1_t *inp) { - return (const uint8_t *)consistency_proof_v1_getarray_hashes((consistency_proof_v1_t*)inp); + return (const struct signed_checksum32_ed25519_st * const *)entries_v1_getarray_checksums((entries_v1_t*)inp); } int -consistency_proof_v1_setlen_hashes(consistency_proof_v1_t *inp, size_t newlen) +entries_v1_setlen_checksums(entries_v1_t *inp, size_t newlen) { - uint8_t *newptr; + struct signed_checksum32_ed25519_st * *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, + newptr = trunnel_dynarray_setlen(&inp->checksums.allocated_, + &inp->checksums.n_, inp->checksums.elts_, newlen, + sizeof(inp->checksums.elts_[0]), (trunnel_free_fn_t) signed_checksum32_ed25519_free, &inp->trunnel_error_code_); if (newlen != 0 && newptr == NULL) goto trunnel_alloc_failed; - inp->hashes.elts_ = newptr; + inp->checksums.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) +entries_v1_check(const entries_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)) + if (! (obj->magic == MAGIC_V1)) + return "Integer out of bounds"; + if (! (obj->format == T_ENTRIES_V1)) return "Integer out of bounds"; { const char *msg; - if (NULL != (msg = ed25519_v1_check(obj->identifier))) - return msg; + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->checksums); ++idx) { + if (NULL != (msg = signed_checksum32_ed25519_check(TRUNNEL_DYNARRAY_GET(&obj->checksums, idx)))) + return msg; + } } - if (TRUNNEL_DYNARRAY_LEN(&obj->hashes) != obj->length) - return "Length mismatch for hashes"; + if (TRUNNEL_DYNARRAY_LEN(&obj->checksums) != obj->n_items) + return "Length mismatch for checksums"; return NULL; } ssize_t -consistency_proof_v1_encoded_len(const consistency_proof_v1_t *obj) +entries_v1_encoded_len(const entries_v1_t *obj) { ssize_t result = 0; - if (NULL != consistency_proof_v1_check(obj)) + if (NULL != entries_v1_check(obj)) return -1; - /* Length of u64 format IN [T_CONSISTENCY_PROOF_V1] */ + /* Length of u64 magic IN [MAGIC_V1] */ result += 8; - /* Length of struct ed25519_v1 identifier */ - result += ed25519_v1_encoded_len(obj->identifier); - - /* Length of u64 old_size */ + /* Length of u64 format IN [T_ENTRIES_V1] */ result += 8; - /* Length of u64 new_size */ + /* Length of u64 n_items */ result += 8; - /* Length of u64 length */ - result += 8; + /* Length of struct signed_checksum32_ed25519 checksums[n_items] */ + { - /* Length of u8 hashes[length] */ - result += TRUNNEL_DYNARRAY_LEN(&obj->hashes); + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->checksums); ++idx) { + result += signed_checksum32_ed25519_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->checksums, idx)); + } + } return result; } int -consistency_proof_v1_clear_errors(consistency_proof_v1_t *obj) +entries_v1_clear_errors(entries_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) +entries_v1_encode(uint8_t *output, const size_t avail, const 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 = consistency_proof_v1_encoded_len(obj); + const ssize_t encoded_len = entries_v1_encoded_len(obj); #endif - if (NULL != (msg = consistency_proof_v1_check(obj))) + if (NULL != (msg = entries_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 */ + /* Encode u64 magic IN [MAGIC_V1] */ trunnel_assert(written <= avail); if (avail - written < 8) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->old_size)); + trunnel_set_uint64(ptr, trunnel_htonll(obj->magic)); written += 8; ptr += 8; - /* Encode u64 new_size */ + /* Encode u64 format IN [T_ENTRIES_V1] */ trunnel_assert(written <= avail); if (avail - written < 8) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->new_size)); + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); written += 8; ptr += 8; - /* Encode u64 length */ + /* Encode u64 n_items */ trunnel_assert(written <= avail); if (avail - written < 8) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + trunnel_set_uint64(ptr, trunnel_htonll(obj->n_items)); written += 8; ptr += 8; - /* Encode u8 hashes[length] */ + /* Encode struct signed_checksum32_ed25519 checksums[n_items] */ { - 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; + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->checksums); ++idx) { + trunnel_assert(written <= avail); + result = signed_checksum32_ed25519_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->checksums, idx)); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + } } @@ -1508,53 +2166,49 @@ consistency_proof_v1_encode(uint8_t *output, const size_t avail, const consisten return result; } -/** As consistency_proof_v1_parse(), but do not allocate the output - * object. +/** As entries_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) +entries_v1_parse_into(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 format IN [T_CONSISTENCY_PROOF_V1] */ + /* Parse u64 magic IN [MAGIC_V1] */ CHECK_REMAINING(8, truncated); - obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); + obj->magic = trunnel_ntohll(trunnel_get_uint64(ptr)); remaining -= 8; ptr += 8; - if (! (obj->format == T_CONSISTENCY_PROOF_V1)) + if (! (obj->magic == MAGIC_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 */ + /* Parse u64 format IN [T_ENTRIES_V1] */ CHECK_REMAINING(8, truncated); - obj->new_size = trunnel_ntohll(trunnel_get_uint64(ptr)); + obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); remaining -= 8; ptr += 8; + if (! (obj->format == T_ENTRIES_V1)) + goto fail; - /* Parse u64 length */ + /* Parse u64 n_items */ CHECK_REMAINING(8, truncated); - obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + obj->n_items = 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; + /* Parse struct signed_checksum32_ed25519 checksums[n_items] */ + TRUNNEL_DYNARRAY_EXPAND(signed_checksum32_ed25519_t *, &obj->checksums, obj->n_items, {}); + { + signed_checksum32_ed25519_t * elt; + unsigned idx; + for (idx = 0; idx < obj->n_items; ++idx) { + result = signed_checksum32_ed25519_parse(&elt, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + TRUNNEL_DYNARRAY_ADD(signed_checksum32_ed25519_t *, &obj->checksums, elt, {signed_checksum32_ed25519_free(elt);}); + } + } trunnel_assert(ptr + remaining == input + len_in); return len_in - remaining; @@ -1571,15 +2225,15 @@ consistency_proof_v1_parse_into(consistency_proof_v1_t *obj, const uint8_t *inpu } ssize_t -consistency_proof_v1_parse(consistency_proof_v1_t **output, const uint8_t *input, const size_t len_in) +entries_v1_parse(entries_v1_t **output, const uint8_t *input, const size_t len_in) { ssize_t result; - *output = consistency_proof_v1_new(); + *output = entries_v1_new(); if (NULL == *output) return -1; - result = consistency_proof_v1_parse_into(*output, input, len_in); + result = entries_v1_parse_into(*output, input, len_in); if (result < 0) { - consistency_proof_v1_free(*output); + entries_v1_free(*output); *output = NULL; } return result; @@ -1590,6 +2244,7 @@ inclusion_proof_v1_new(void) inclusion_proof_v1_t *val = trunnel_calloc(1, sizeof(inclusion_proof_v1_t)); if (NULL == val) return NULL; + val->magic = MAGIC_V1; val->format = T_INCLUSION_PROOF_V1; return val; } @@ -1600,8 +2255,13 @@ static void inclusion_proof_v1_clear(inclusion_proof_v1_t *obj) { (void) obj; - ed25519_v1_free(obj->identifier); - obj->identifier = NULL; + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + hash_free(TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)); + } + } TRUNNEL_DYNARRAY_WIPE(&obj->hashes); TRUNNEL_DYNARRAY_CLEAR(&obj->hashes); } @@ -1616,6 +2276,21 @@ inclusion_proof_v1_free(inclusion_proof_v1_t *obj) trunnel_free_(obj); } +uint64_t +inclusion_proof_v1_get_magic(const inclusion_proof_v1_t *inp) +{ + return inp->magic; +} +int +inclusion_proof_v1_set_magic(inclusion_proof_v1_t *inp, uint64_t val) +{ + if (! ((val == MAGIC_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->magic = val; + return 0; +} uint64_t inclusion_proof_v1_get_format(const inclusion_proof_v1_t *inp) { @@ -1631,29 +2306,42 @@ inclusion_proof_v1_set_format(inclusion_proof_v1_t *inp, uint64_t val) inp->format = val; return 0; } -struct ed25519_v1_st * -inclusion_proof_v1_get_identifier(inclusion_proof_v1_t *inp) +size_t +inclusion_proof_v1_getlen_identifier(const inclusion_proof_v1_t *inp) { - return inp->identifier; + (void)inp; return 32; } -const struct ed25519_v1_st * -inclusion_proof_v1_getconst_identifier(const inclusion_proof_v1_t *inp) + +uint8_t +inclusion_proof_v1_get_identifier(inclusion_proof_v1_t *inp, size_t idx) { - return inclusion_proof_v1_get_identifier((inclusion_proof_v1_t*) inp); + trunnel_assert(idx < 32); + return inp->identifier[idx]; } -int -inclusion_proof_v1_set_identifier(inclusion_proof_v1_t *inp, struct ed25519_v1_st *val) + +uint8_t +inclusion_proof_v1_getconst_identifier(const inclusion_proof_v1_t *inp, size_t idx) { - if (inp->identifier && inp->identifier != val) - ed25519_v1_free(inp->identifier); - return inclusion_proof_v1_set0_identifier(inp, val); + return inclusion_proof_v1_get_identifier((inclusion_proof_v1_t*)inp, idx); } int -inclusion_proof_v1_set0_identifier(inclusion_proof_v1_t *inp, struct ed25519_v1_st *val) +inclusion_proof_v1_set_identifier(inclusion_proof_v1_t *inp, size_t idx, uint8_t elt) { - inp->identifier = val; + trunnel_assert(idx < 32); + inp->identifier[idx] = elt; return 0; } + +uint8_t * +inclusion_proof_v1_getarray_identifier(inclusion_proof_v1_t *inp) +{ + return inp->identifier; +} +const uint8_t * +inclusion_proof_v1_getconstarray_identifier(const inclusion_proof_v1_t *inp) +{ + return (const uint8_t *)inclusion_proof_v1_getarray_identifier((inclusion_proof_v1_t*)inp); +} uint64_t inclusion_proof_v1_get_tree_size(const inclusion_proof_v1_t *inp) { @@ -1677,14 +2365,14 @@ inclusion_proof_v1_set_leaf_index(inclusion_proof_v1_t *inp, uint64_t val) return 0; } uint64_t -inclusion_proof_v1_get_length(const inclusion_proof_v1_t *inp) +inclusion_proof_v1_get_n_items(const inclusion_proof_v1_t *inp) { - return inp->length; + return inp->n_items; } int -inclusion_proof_v1_set_length(inclusion_proof_v1_t *inp, uint64_t val) +inclusion_proof_v1_set_n_items(inclusion_proof_v1_t *inp, uint64_t val) { - inp->length = val; + inp->n_items = val; return 0; } size_t @@ -1693,58 +2381,66 @@ inclusion_proof_v1_getlen_hashes(const inclusion_proof_v1_t *inp) return TRUNNEL_DYNARRAY_LEN(&inp->hashes); } -uint8_t +struct hash_st * inclusion_proof_v1_get_hashes(inclusion_proof_v1_t *inp, size_t idx) { return TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); } -uint8_t + const struct hash_st * 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) +inclusion_proof_v1_set_hashes(inclusion_proof_v1_t *inp, size_t idx, struct hash_st * elt) +{ + hash_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->hashes, idx); + if (oldval && oldval != elt) + hash_free(oldval); + return inclusion_proof_v1_set0_hashes(inp, idx, elt); +} +int +inclusion_proof_v1_set0_hashes(inclusion_proof_v1_t *inp, size_t idx, struct hash_st * elt) { TRUNNEL_DYNARRAY_SET(&inp->hashes, idx, elt); return 0; } int -inclusion_proof_v1_add_hashes(inclusion_proof_v1_t *inp, uint8_t elt) +inclusion_proof_v1_add_hashes(inclusion_proof_v1_t *inp, struct hash_st * 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, {}); + TRUNNEL_DYNARRAY_ADD(struct hash_st *, &inp->hashes, elt, {}); return 0; trunnel_alloc_failed: TRUNNEL_SET_ERROR_CODE(inp); return -1; } -uint8_t * +struct hash_st * * inclusion_proof_v1_getarray_hashes(inclusion_proof_v1_t *inp) { return inp->hashes.elts_; } -const uint8_t * +const struct hash_st * const * 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); + return (const struct hash_st * const *)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; + struct hash_st * *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, + sizeof(inp->hashes.elts_[0]), (trunnel_free_fn_t) hash_free, &inp->trunnel_error_code_); if (newlen != 0 && newptr == NULL) goto trunnel_alloc_failed; @@ -1761,14 +2457,20 @@ inclusion_proof_v1_check(const inclusion_proof_v1_t *obj) return "Object was NULL"; if (obj->trunnel_error_code_) return "A set function failed on this object"; + if (! (obj->magic == MAGIC_V1)) + return "Integer out of bounds"; 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; + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + if (NULL != (msg = hash_check(TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)))) + return msg; + } } - if (TRUNNEL_DYNARRAY_LEN(&obj->hashes) != obj->length) + if (TRUNNEL_DYNARRAY_LEN(&obj->hashes) != obj->n_items) return "Length mismatch for hashes"; return NULL; } @@ -1782,11 +2484,14 @@ inclusion_proof_v1_encoded_len(const inclusion_proof_v1_t *obj) return -1; + /* Length of u64 magic IN [MAGIC_V1] */ + result += 8; + /* 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 u8 identifier[32] */ + result += 32; /* Length of u64 tree_size */ result += 8; @@ -1794,11 +2499,17 @@ inclusion_proof_v1_encoded_len(const inclusion_proof_v1_t *obj) /* Length of u64 leaf_index */ result += 8; - /* Length of u64 length */ + /* Length of u64 n_items */ result += 8; - /* Length of u8 hashes[length] */ - result += TRUNNEL_DYNARRAY_LEN(&obj->hashes); + /* Length of struct hash hashes[n_items] */ + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + result += hash_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)); + } + } return result; } int @@ -1826,6 +2537,13 @@ inclusion_proof_v1_encode(uint8_t *output, const size_t avail, const inclusion_p trunnel_assert(encoded_len >= 0); #endif + /* Encode u64 magic IN [MAGIC_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->magic)); + written += 8; ptr += 8; + /* Encode u64 format IN [T_INCLUSION_PROOF_V1] */ trunnel_assert(written <= avail); if (avail - written < 8) @@ -1833,12 +2551,12 @@ inclusion_proof_v1_encode(uint8_t *output, const size_t avail, const inclusion_p trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); written += 8; ptr += 8; - /* Encode struct ed25519_v1 identifier */ + /* Encode u8 identifier[32] */ trunnel_assert(written <= avail); - result = ed25519_v1_encode(ptr, avail - written, obj->identifier); - if (result < 0) - goto fail; /* XXXXXXX !*/ - written += result; ptr += result; + if (avail - written < 32) + goto truncated; + memcpy(ptr, obj->identifier, 32); + written += 32; ptr += 32; /* Encode u64 tree_size */ trunnel_assert(written <= avail); @@ -1854,23 +2572,24 @@ inclusion_proof_v1_encode(uint8_t *output, const size_t avail, const inclusion_p trunnel_set_uint64(ptr, trunnel_htonll(obj->leaf_index)); written += 8; ptr += 8; - /* Encode u64 length */ + /* Encode u64 n_items */ trunnel_assert(written <= avail); if (avail - written < 8) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + trunnel_set_uint64(ptr, trunnel_htonll(obj->n_items)); written += 8; ptr += 8; - /* Encode u8 hashes[length] */ + /* Encode struct hash hashes[n_items] */ { - 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; + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->hashes); ++idx) { + trunnel_assert(written <= avail); + result = hash_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->hashes, idx)); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + } } @@ -1908,6 +2627,13 @@ inclusion_proof_v1_parse_into(inclusion_proof_v1_t *obj, const uint8_t *input, c ssize_t result = 0; (void)result; + /* Parse u64 magic IN [MAGIC_V1] */ + CHECK_REMAINING(8, truncated); + obj->magic = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->magic == MAGIC_V1)) + goto fail; + /* Parse u64 format IN [T_INCLUSION_PROOF_V1] */ CHECK_REMAINING(8, truncated); obj->format = trunnel_ntohll(trunnel_get_uint64(ptr)); @@ -1915,12 +2641,10 @@ inclusion_proof_v1_parse_into(inclusion_proof_v1_t *obj, const uint8_t *input, c 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 u8 identifier[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->identifier, ptr, 32); + remaining -= 32; ptr += 32; /* Parse u64 tree_size */ CHECK_REMAINING(8, truncated); @@ -1932,18 +2656,25 @@ inclusion_proof_v1_parse_into(inclusion_proof_v1_t *obj, const uint8_t *input, c obj->leaf_index = trunnel_ntohll(trunnel_get_uint64(ptr)); remaining -= 8; ptr += 8; - /* Parse u64 length */ + /* Parse u64 n_items */ CHECK_REMAINING(8, truncated); - obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + obj->n_items = 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; + /* Parse struct hash hashes[n_items] */ + TRUNNEL_DYNARRAY_EXPAND(hash_t *, &obj->hashes, obj->n_items, {}); + { + hash_t * elt; + unsigned idx; + for (idx = 0; idx < obj->n_items; ++idx) { + result = hash_parse(&elt, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + TRUNNEL_DYNARRAY_ADD(hash_t *, &obj->hashes, elt, {hash_free(elt);}); + } + } trunnel_assert(ptr + remaining == input + len_in); return len_in - remaining; @@ -1979,6 +2710,7 @@ request_v1_new(void) request_v1_t *val = trunnel_calloc(1, sizeof(request_v1_t)); if (NULL == val) return NULL; + val->magic = MAGIC_V1; val->format = T_GET_CONSISTENCY_PROOF_V1; return val; } @@ -2007,6 +2739,21 @@ request_v1_free(request_v1_t *obj) trunnel_free_(obj); } +uint64_t +request_v1_get_magic(const request_v1_t *inp) +{ + return inp->magic; +} +int +request_v1_set_magic(request_v1_t *inp, uint64_t val) +{ + if (! ((val == MAGIC_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->magic = val; + return 0; +} uint64_t request_v1_get_format(const request_v1_t *inp) { @@ -2098,6 +2845,8 @@ request_v1_check(const request_v1_t *obj) return "Object was NULL"; if (obj->trunnel_error_code_) return "A set function failed on this object"; + if (! (obj->magic == MAGIC_V1)) + return "Integer out of bounds"; 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) { @@ -2142,6 +2891,9 @@ request_v1_encoded_len(const request_v1_t *obj) return -1; + /* Length of u64 magic IN [MAGIC_V1] */ + result += 8; + /* 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) { @@ -2195,6 +2947,13 @@ request_v1_encode(uint8_t *output, const size_t avail, const request_v1_t *obj) trunnel_assert(encoded_len >= 0); #endif + /* Encode u64 magic IN [MAGIC_V1] */ + trunnel_assert(written <= avail); + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->magic)); + written += 8; ptr += 8; + /* 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) @@ -2275,6 +3034,13 @@ request_v1_parse_into(request_v1_t *obj, const uint8_t *input, const size_t len_ ssize_t result = 0; (void)result; + /* Parse u64 magic IN [MAGIC_V1] */ + CHECK_REMAINING(8, truncated); + obj->magic = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->magic == MAGIC_V1)) + goto fail; + /* 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)); @@ -2346,351 +3112,359 @@ request_v1_parse(request_v1_t **output, const uint8_t *input, const size_t len_i } return result; } -signed_checksum32_ed25519_v1_t * -signed_checksum32_ed25519_v1_new(void) +signed_tree_head_v1_t * +signed_tree_head_v1_new(void) { - signed_checksum32_ed25519_v1_t *val = trunnel_calloc(1, sizeof(signed_checksum32_ed25519_v1_t)); + signed_tree_head_v1_t *val = trunnel_calloc(1, sizeof(signed_tree_head_v1_t)); if (NULL == val) return NULL; - val->format = T_SIGNED_CHECKSUM32_ED25519_V1; - val->length = 1; + val->magic = MAGIC_V1; + val->format = T_SIGNED_TREE_HEAD_V1; 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) +signed_tree_head_v1_clear(signed_tree_head_v1_t *obj) { (void) obj; - TRUNNEL_DYNARRAY_WIPE(&obj->identifier); - TRUNNEL_DYNARRAY_CLEAR(&obj->identifier); - ed25519_v1_free(obj->namespace); - obj->namespace = NULL; + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->signatures); ++idx) { + sigident_ed25519_free(TRUNNEL_DYNARRAY_GET(&obj->signatures, idx)); + } + } + TRUNNEL_DYNARRAY_WIPE(&obj->signatures); + TRUNNEL_DYNARRAY_CLEAR(&obj->signatures); } void -signed_checksum32_ed25519_v1_free(signed_checksum32_ed25519_v1_t *obj) +signed_tree_head_v1_free(signed_tree_head_v1_t *obj) { if (obj == NULL) return; - signed_checksum32_ed25519_v1_clear(obj); - trunnel_memwipe(obj, sizeof(signed_checksum32_ed25519_v1_t)); + signed_tree_head_v1_clear(obj); + trunnel_memwipe(obj, sizeof(signed_tree_head_v1_t)); trunnel_free_(obj); } uint64_t -signed_checksum32_ed25519_v1_get_format(const signed_checksum32_ed25519_v1_t *inp) +signed_tree_head_v1_get_magic(const signed_tree_head_v1_t *inp) +{ + return inp->magic; +} +int +signed_tree_head_v1_set_magic(signed_tree_head_v1_t *inp, uint64_t val) +{ + if (! ((val == MAGIC_V1))) { + TRUNNEL_SET_ERROR_CODE(inp); + return -1; + } + inp->magic = val; + return 0; +} +uint64_t +signed_tree_head_v1_get_format(const signed_tree_head_v1_t *inp) { return inp->format; } int -signed_checksum32_ed25519_v1_set_format(signed_checksum32_ed25519_v1_t *inp, uint64_t val) +signed_tree_head_v1_set_format(signed_tree_head_v1_t *inp, uint64_t val) { - if (! ((val == T_SIGNED_CHECKSUM32_ED25519_V1))) { + 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_checksum32_ed25519_v1_getlen_checksum(const signed_checksum32_ed25519_v1_t *inp) +signed_tree_head_v1_getlen_root_hash(const signed_tree_head_v1_t *inp) { (void)inp; return 32; } uint8_t -signed_checksum32_ed25519_v1_get_checksum(signed_checksum32_ed25519_v1_t *inp, size_t idx) +signed_tree_head_v1_get_root_hash(signed_tree_head_v1_t *inp, size_t idx) { trunnel_assert(idx < 32); - return inp->checksum[idx]; + return inp->root_hash[idx]; } uint8_t -signed_checksum32_ed25519_v1_getconst_checksum(const signed_checksum32_ed25519_v1_t *inp, size_t idx) +signed_tree_head_v1_getconst_root_hash(const signed_tree_head_v1_t *inp, size_t idx) { - return signed_checksum32_ed25519_v1_get_checksum((signed_checksum32_ed25519_v1_t*)inp, idx); + return signed_tree_head_v1_get_root_hash((signed_tree_head_v1_t*)inp, idx); } int -signed_checksum32_ed25519_v1_set_checksum(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt) +signed_tree_head_v1_set_root_hash(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt) { trunnel_assert(idx < 32); - inp->checksum[idx] = elt; + inp->root_hash[idx] = elt; return 0; } uint8_t * -signed_checksum32_ed25519_v1_getarray_checksum(signed_checksum32_ed25519_v1_t *inp) +signed_tree_head_v1_getarray_root_hash(signed_tree_head_v1_t *inp) { - return inp->checksum; + return inp->root_hash; } const uint8_t * -signed_checksum32_ed25519_v1_getconstarray_checksum(const signed_checksum32_ed25519_v1_t *inp) +signed_tree_head_v1_getconstarray_root_hash(const signed_tree_head_v1_t *inp) { - return (const uint8_t *)signed_checksum32_ed25519_v1_getarray_checksum((signed_checksum32_ed25519_v1_t*)inp); + return (const uint8_t *)signed_tree_head_v1_getarray_root_hash((signed_tree_head_v1_t*)inp); } uint64_t -signed_checksum32_ed25519_v1_get_length(const signed_checksum32_ed25519_v1_t *inp) +signed_tree_head_v1_get_n_items(const signed_tree_head_v1_t *inp) { - return inp->length; + return inp->n_items; } int -signed_checksum32_ed25519_v1_set_length(signed_checksum32_ed25519_v1_t *inp, uint64_t val) +signed_tree_head_v1_set_n_items(signed_tree_head_v1_t *inp, uint64_t val) { - if (! (((val >= 1 && val <= 127)))) { - TRUNNEL_SET_ERROR_CODE(inp); - return -1; - } - inp->length = val; + inp->n_items = val; return 0; } size_t -signed_checksum32_ed25519_v1_getlen_identifier(const signed_checksum32_ed25519_v1_t *inp) +signed_tree_head_v1_getlen_signatures(const signed_tree_head_v1_t *inp) { - return TRUNNEL_DYNARRAY_LEN(&inp->identifier); + return TRUNNEL_DYNARRAY_LEN(&inp->signatures); } -uint8_t -signed_checksum32_ed25519_v1_get_identifier(signed_checksum32_ed25519_v1_t *inp, size_t idx) +struct sigident_ed25519_st * +signed_tree_head_v1_get_signatures(signed_tree_head_v1_t *inp, size_t idx) { - return TRUNNEL_DYNARRAY_GET(&inp->identifier, idx); + return TRUNNEL_DYNARRAY_GET(&inp->signatures, idx); } -uint8_t -signed_checksum32_ed25519_v1_getconst_identifier(const signed_checksum32_ed25519_v1_t *inp, size_t idx) + const struct sigident_ed25519_st * +signed_tree_head_v1_getconst_signatures(const signed_tree_head_v1_t *inp, size_t idx) { - return signed_checksum32_ed25519_v1_get_identifier((signed_checksum32_ed25519_v1_t*)inp, idx); + return signed_tree_head_v1_get_signatures((signed_tree_head_v1_t*)inp, idx); } int -signed_checksum32_ed25519_v1_set_identifier(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt) +signed_tree_head_v1_set_signatures(signed_tree_head_v1_t *inp, size_t idx, struct sigident_ed25519_st * elt) { - TRUNNEL_DYNARRAY_SET(&inp->identifier, idx, elt); + sigident_ed25519_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->signatures, idx); + if (oldval && oldval != elt) + sigident_ed25519_free(oldval); + return signed_tree_head_v1_set0_signatures(inp, idx, elt); +} +int +signed_tree_head_v1_set0_signatures(signed_tree_head_v1_t *inp, size_t idx, struct sigident_ed25519_st * elt) +{ + TRUNNEL_DYNARRAY_SET(&inp->signatures, idx, elt); return 0; } int -signed_checksum32_ed25519_v1_add_identifier(signed_checksum32_ed25519_v1_t *inp, uint8_t elt) +signed_tree_head_v1_add_signatures(signed_tree_head_v1_t *inp, struct sigident_ed25519_st * elt) { #if SIZE_MAX >= UINT64_MAX - if (inp->identifier.n_ == UINT64_MAX) + if (inp->signatures.n_ == UINT64_MAX) goto trunnel_alloc_failed; #endif - TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->identifier, elt, {}); + TRUNNEL_DYNARRAY_ADD(struct sigident_ed25519_st *, &inp->signatures, 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) +struct sigident_ed25519_st * * +signed_tree_head_v1_getarray_signatures(signed_tree_head_v1_t *inp) { - return inp->identifier.elts_; + return inp->signatures.elts_; } -const uint8_t * -signed_checksum32_ed25519_v1_getconstarray_identifier(const signed_checksum32_ed25519_v1_t *inp) +const struct sigident_ed25519_st * const * +signed_tree_head_v1_getconstarray_signatures(const signed_tree_head_v1_t *inp) { - return (const uint8_t *)signed_checksum32_ed25519_v1_getarray_identifier((signed_checksum32_ed25519_v1_t*)inp); + return (const struct sigident_ed25519_st * const *)signed_tree_head_v1_getarray_signatures((signed_tree_head_v1_t*)inp); } int -signed_checksum32_ed25519_v1_setlen_identifier(signed_checksum32_ed25519_v1_t *inp, size_t newlen) +signed_tree_head_v1_setlen_signatures(signed_tree_head_v1_t *inp, size_t newlen) { - uint8_t *newptr; + struct sigident_ed25519_st * *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, + newptr = trunnel_dynarray_setlen(&inp->signatures.allocated_, + &inp->signatures.n_, inp->signatures.elts_, newlen, + sizeof(inp->signatures.elts_[0]), (trunnel_free_fn_t) sigident_ed25519_free, &inp->trunnel_error_code_); if (newlen != 0 && newptr == NULL) goto trunnel_alloc_failed; - inp->identifier.elts_ = newptr; + inp->signatures.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) +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_CHECKSUM32_ED25519_V1)) + if (! (obj->magic == MAGIC_V1)) return "Integer out of bounds"; - if (! ((obj->length >= 1 && obj->length <= 127))) + if (! (obj->format == T_SIGNED_TREE_HEAD_V1)) 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; + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->signatures); ++idx) { + if (NULL != (msg = sigident_ed25519_check(TRUNNEL_DYNARRAY_GET(&obj->signatures, idx)))) + return msg; + } } + if (TRUNNEL_DYNARRAY_LEN(&obj->signatures) != obj->n_items) + return "Length mismatch for signatures"; return NULL; } ssize_t -signed_checksum32_ed25519_v1_encoded_len(const signed_checksum32_ed25519_v1_t *obj) +signed_tree_head_v1_encoded_len(const signed_tree_head_v1_t *obj) { ssize_t result = 0; - if (NULL != signed_checksum32_ed25519_v1_check(obj)) + if (NULL != signed_tree_head_v1_check(obj)) return -1; - /* Length of u64 format IN [T_SIGNED_CHECKSUM32_ED25519_V1] */ + /* Length of u64 magic IN [MAGIC_V1] */ result += 8; - /* Length of u8 checksum[32] */ - result += 32; + /* Length of u64 format IN [T_SIGNED_TREE_HEAD_V1] */ + result += 8; - /* Length of u64 length IN [1..127] */ + /* Length of u64 timestamp */ result += 8; - /* Length of u8 identifier[length] */ - result += TRUNNEL_DYNARRAY_LEN(&obj->identifier); + /* Length of u64 tree_size */ + result += 8; - /* Length of u8 signature[64] */ - result += 64; + /* Length of u8 root_hash[32] */ + result += 32; + + /* Length of u64 n_items */ + result += 8; - /* Length of struct ed25519_v1 namespace */ - result += ed25519_v1_encoded_len(obj->namespace); + /* Length of struct sigident_ed25519 signatures[n_items] */ + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->signatures); ++idx) { + result += sigident_ed25519_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->signatures, idx)); + } + } return result; } int -signed_checksum32_ed25519_v1_clear_errors(signed_checksum32_ed25519_v1_t *obj) +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_checksum32_ed25519_v1_encode(uint8_t *output, const size_t avail, const signed_checksum32_ed25519_v1_t *obj) +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_checksum32_ed25519_v1_encoded_len(obj); + const ssize_t encoded_len = signed_tree_head_v1_encoded_len(obj); #endif - if (NULL != (msg = signed_checksum32_ed25519_v1_check(obj))) + 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_CHECKSUM32_ED25519_V1] */ + /* Encode u64 magic IN [MAGIC_V1] */ trunnel_assert(written <= avail); if (avail - written < 8) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + trunnel_set_uint64(ptr, trunnel_htonll(obj->magic)); written += 8; ptr += 8; - /* Encode u8 checksum[32] */ + /* Encode u64 format IN [T_SIGNED_TREE_HEAD_V1] */ trunnel_assert(written <= avail); - if (avail - written < 32) + if (avail - written < 8) goto truncated; - memcpy(ptr, obj->checksum, 32); - written += 32; ptr += 32; + trunnel_set_uint64(ptr, trunnel_htonll(obj->format)); + written += 8; ptr += 8; - /* Encode u64 length IN [1..127] */ + /* Encode u64 timestamp */ trunnel_assert(written <= avail); if (avail - written < 8) goto truncated; - trunnel_set_uint64(ptr, trunnel_htonll(obj->length)); + trunnel_set_uint64(ptr, trunnel_htonll(obj->timestamp)); 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 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 signature[64] */ + /* Encode u8 root_hash[32] */ trunnel_assert(written <= avail); - if (avail - written < 64) + if (avail - written < 32) goto truncated; - memcpy(ptr, obj->signature, 64); - written += 64; ptr += 64; + memcpy(ptr, obj->root_hash, 32); + written += 32; ptr += 32; - /* Encode struct ed25519_v1 namespace */ + /* Encode u64 n_items */ trunnel_assert(written <= avail); - result = ed25519_v1_encode(ptr, avail - written, obj->namespace); - if (result < 0) - goto fail; /* XXXXXXX !*/ - written += result; ptr += result; + if (avail - written < 8) + goto truncated; + trunnel_set_uint64(ptr, trunnel_htonll(obj->n_items)); + written += 8; ptr += 8; + + /* Encode struct sigident_ed25519 signatures[n_items] */ + { + + unsigned idx; + for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->signatures); ++idx) { + trunnel_assert(written <= avail); + result = sigident_ed25519_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->signatures, idx)); + if (result < 0) + goto fail; /* XXXXXXX !*/ + written += result; ptr += result; + } + } trunnel_assert(ptr == output + written); @@ -2716,55 +3490,65 @@ signed_checksum32_ed25519_v1_encode(uint8_t *output, const size_t avail, const s return result; } -/** As signed_checksum32_ed25519_v1_parse(), but do not allocate the - * output object. +/** As signed_tree_head_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) +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_CHECKSUM32_ED25519_V1] */ + /* Parse u64 magic IN [MAGIC_V1] */ + CHECK_REMAINING(8, truncated); + obj->magic = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; + if (! (obj->magic == MAGIC_V1)) + goto fail; + + /* 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_CHECKSUM32_ED25519_V1)) + if (! (obj->format == T_SIGNED_TREE_HEAD_V1)) goto fail; - /* Parse u8 checksum[32] */ - CHECK_REMAINING(32, truncated); - memcpy(obj->checksum, ptr, 32); - remaining -= 32; ptr += 32; + /* Parse u64 timestamp */ + CHECK_REMAINING(8, truncated); + obj->timestamp = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; - /* Parse u64 length IN [1..127] */ + /* Parse u64 tree_size */ CHECK_REMAINING(8, truncated); - obj->length = trunnel_ntohll(trunnel_get_uint64(ptr)); + obj->tree_size = 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 root_hash[32] */ + CHECK_REMAINING(32, truncated); + memcpy(obj->root_hash, ptr, 32); + remaining -= 32; ptr += 32; - /* Parse u8 signature[64] */ - CHECK_REMAINING(64, truncated); - memcpy(obj->signature, ptr, 64); - remaining -= 64; ptr += 64; + /* Parse u64 n_items */ + CHECK_REMAINING(8, truncated); + obj->n_items = trunnel_ntohll(trunnel_get_uint64(ptr)); + remaining -= 8; ptr += 8; - /* 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; + /* Parse struct sigident_ed25519 signatures[n_items] */ + TRUNNEL_DYNARRAY_EXPAND(sigident_ed25519_t *, &obj->signatures, obj->n_items, {}); + { + sigident_ed25519_t * elt; + unsigned idx; + for (idx = 0; idx < obj->n_items; ++idx) { + result = sigident_ed25519_parse(&elt, ptr, remaining); + if (result < 0) + goto relay_fail; + trunnel_assert((size_t)result <= remaining); + remaining -= result; ptr += result; + TRUNNEL_DYNARRAY_ADD(sigident_ed25519_t *, &obj->signatures, elt, {sigident_ed25519_free(elt);}); + } + } trunnel_assert(ptr + remaining == input + len_in); return len_in - remaining; @@ -2781,15 +3565,15 @@ signed_checksum32_ed25519_v1_parse_into(signed_checksum32_ed25519_v1_t *obj, con } ssize_t -signed_checksum32_ed25519_v1_parse(signed_checksum32_ed25519_v1_t **output, const uint8_t *input, const size_t len_in) +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_checksum32_ed25519_v1_new(); + *output = signed_tree_head_v1_new(); if (NULL == *output) return -1; - result = signed_checksum32_ed25519_v1_parse_into(*output, input, len_in); + result = signed_tree_head_v1_parse_into(*output, input, len_in); if (result < 0) { - signed_checksum32_ed25519_v1_free(*output); + signed_tree_head_v1_free(*output); *output = NULL; } return result; diff --git a/trunnel/stfe.h b/trunnel/stfe.h index c92d1e4..26ffb09 100644 --- a/trunnel/stfe.h +++ b/trunnel/stfe.h @@ -8,22 +8,21 @@ #include #include "trunnel.h" +#define MAGIC_V1 6004501466958485041 #define T_GET_ENTRIES_V1 1 #define T_GET_PROOF_BY_HASH_V1 2 #define T_GET_CONSISTENCY_PROOF_V1 3 -#define T_INCLUSION_PROOF_V1 4 -#define T_CONSISTENCY_PROOF_V1 5 -#define T_SIGNED_TREE_HEAD_V1 6 -#define T_SIGNED_CHECKSUM32_ED25519_V1 7 -#define T_ED25519_V1 8 -#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_ED25519_V1) -struct ed25519_v1_st { - uint64_t format; - uint8_t pubkey[32]; +#define T_ENTRIES_V1 4 +#define T_INCLUSION_PROOF_V1 5 +#define T_CONSISTENCY_PROOF_V1 6 +#define T_SIGNED_TREE_HEAD_V1 7 +#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_HASH) +struct hash_st { + uint8_t hash[32]; uint8_t trunnel_error_code_; }; #endif -typedef struct ed25519_v1_st ed25519_v1_t; +typedef struct hash_st hash_t; #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_REQ_GET_CONSISTENCY_PROOF_V1) struct req_get_consistency_proof_v1_st { uint64_t old_size; @@ -48,44 +47,64 @@ struct req_get_proof_by_hash_v1_st { }; #endif typedef struct req_get_proof_by_hash_v1_st req_get_proof_by_hash_v1_t; -#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SIGNED_TREE_HEAD_V1) -struct signed_tree_head_v1_st { - uint64_t format; - uint64_t timestamp; - uint64_t tree_size; - uint8_t root_hash[32]; +#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SIGIDENT_ED25519) +struct sigident_ed25519_st { + uint8_t signature[64]; + uint8_t identifier[32]; + uint8_t trunnel_error_code_; +}; +#endif +typedef struct sigident_ed25519_st sigident_ed25519_t; +#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SIGNED_CHECKSUM32_ED25519) +struct signed_checksum32_ed25519_st { + uint8_t checksum[32]; uint64_t length; - TRUNNEL_DYNARRAY_HEAD(, uint8_t) sigident; + TRUNNEL_DYNARRAY_HEAD(, uint8_t) identifier; + uint8_t signature[64]; + uint8_t namespace[32]; uint8_t trunnel_error_code_; }; #endif -typedef struct signed_tree_head_v1_st signed_tree_head_v1_t; +typedef struct signed_checksum32_ed25519_st signed_checksum32_ed25519_t; #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_CONSISTENCY_PROOF_V1) struct consistency_proof_v1_st { + uint64_t magic; uint64_t format; - struct ed25519_v1_st *identifier; + uint8_t identifier[32]; uint64_t old_size; uint64_t new_size; - uint64_t length; - TRUNNEL_DYNARRAY_HEAD(, uint8_t) hashes; + uint64_t n_items; + TRUNNEL_DYNARRAY_HEAD(, struct hash_st *) hashes; uint8_t trunnel_error_code_; }; #endif typedef struct consistency_proof_v1_st consistency_proof_v1_t; +#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_ENTRIES_V1) +struct entries_v1_st { + uint64_t magic; + uint64_t format; + uint64_t n_items; + TRUNNEL_DYNARRAY_HEAD(, struct signed_checksum32_ed25519_st *) checksums; + uint8_t trunnel_error_code_; +}; +#endif +typedef struct entries_v1_st entries_v1_t; #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_INCLUSION_PROOF_V1) struct inclusion_proof_v1_st { + uint64_t magic; uint64_t format; - struct ed25519_v1_st *identifier; + uint8_t identifier[32]; uint64_t tree_size; uint64_t leaf_index; - uint64_t length; - TRUNNEL_DYNARRAY_HEAD(, uint8_t) hashes; + uint64_t n_items; + TRUNNEL_DYNARRAY_HEAD(, struct hash_st *) hashes; uint8_t trunnel_error_code_; }; #endif typedef struct inclusion_proof_v1_st inclusion_proof_v1_t; #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_REQUEST_V1) struct request_v1_st { + uint64_t magic; uint64_t format; struct req_get_entries_v1_st *request_get_entries; struct req_get_proof_by_hash_v1_st *request_get_proof_by_hash; @@ -94,82 +113,74 @@ struct request_v1_st { }; #endif typedef struct request_v1_st request_v1_t; -#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SIGNED_CHECKSUM32_ED25519_V1) -struct signed_checksum32_ed25519_v1_st { +#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SIGNED_TREE_HEAD_V1) +struct signed_tree_head_v1_st { + uint64_t magic; uint64_t format; - uint8_t checksum[32]; - uint64_t length; - TRUNNEL_DYNARRAY_HEAD(, uint8_t) identifier; - uint8_t signature[64]; - struct ed25519_v1_st *namespace; + uint64_t timestamp; + uint64_t tree_size; + uint8_t root_hash[32]; + uint64_t n_items; + TRUNNEL_DYNARRAY_HEAD(, struct sigident_ed25519_st *) signatures; uint8_t trunnel_error_code_; }; #endif -typedef struct signed_checksum32_ed25519_v1_st signed_checksum32_ed25519_v1_t; -/** Return a newly allocated ed25519_v1 with all elements set to zero. +typedef struct signed_tree_head_v1_st signed_tree_head_v1_t; +/** Return a newly allocated hash with all elements set to zero. */ -ed25519_v1_t *ed25519_v1_new(void); -/** Release all storage held by the ed25519_v1 in 'victim'. (Do - * nothing if 'victim' is NULL.) +hash_t *hash_new(void); +/** Release all storage held by the hash in 'victim'. (Do nothing if + * 'victim' is NULL.) */ -void ed25519_v1_free(ed25519_v1_t *victim); -/** Try to parse a ed25519_v1 from the buffer in 'input', using up to +void hash_free(hash_t *victim); +/** Try to parse a hash from the buffer in 'input', using up to * 'len_in' bytes from the input buffer. On success, return the number - * of bytes consumed and set *output to the newly allocated - * ed25519_v1_t. On failure, return -2 if the input appears truncated, - * and -1 if the input is otherwise invalid. - */ -ssize_t ed25519_v1_parse(ed25519_v1_t **output, const uint8_t *input, const size_t len_in); -/** Return the number of bytes we expect to need to encode the - * ed25519_v1 in 'obj'. On failure, return a negative value. Note that - * this value may be an overestimate, and can even be an underestimate - * for certain unencodeable objects. - */ -ssize_t ed25519_v1_encoded_len(const ed25519_v1_t *obj); -/** Try to encode the ed25519_v1 from 'input' into the buffer at - * 'output', using up to 'avail' bytes of the output buffer. On - * success, return the number of bytes used. On failure, return -2 if - * the buffer was not long enough, and -1 if the input was invalid. - */ -ssize_t ed25519_v1_encode(uint8_t *output, size_t avail, const ed25519_v1_t *input); -/** Check whether the internal state of the ed25519_v1 in 'obj' is + * of bytes consumed and set *output to the newly allocated hash_t. On + * failure, return -2 if the input appears truncated, and -1 if the + * input is otherwise invalid. + */ +ssize_t hash_parse(hash_t **output, const uint8_t *input, const size_t len_in); +/** Return the number of bytes we expect to need to encode the hash in + * 'obj'. On failure, return a negative value. Note that this value + * may be an overestimate, and can even be an underestimate for + * certain unencodeable objects. + */ +ssize_t hash_encoded_len(const hash_t *obj); +/** Try to encode the hash from 'input' into the buffer at 'output', + * using up to 'avail' bytes of the output buffer. On success, return + * the number of bytes used. On failure, return -2 if the buffer was + * not long enough, and -1 if the input was invalid. + */ +ssize_t hash_encode(uint8_t *output, size_t avail, const hash_t *input); +/** Check whether the internal state of the hash in 'obj' is * consistent. Return NULL if it is, and a short message if it is not. */ -const char *ed25519_v1_check(const ed25519_v1_t *obj); +const char *hash_check(const hash_t *obj); /** Clear any errors that were set on the object 'obj' by its setter * functions. Return true iff errors were cleared. */ -int ed25519_v1_clear_errors(ed25519_v1_t *obj); -/** Return the value of the format field of the ed25519_v1_t in 'inp' +int hash_clear_errors(hash_t *obj); +/** Return the (constant) length of the array holding the hash field + * of the hash_t in 'inp'. */ -uint64_t ed25519_v1_get_format(const ed25519_v1_t *inp); -/** Set the value of the format field of the ed25519_v1_t in 'inp' to - * 'val'. Return 0 on success; return -1 and set the error code on - * 'inp' on failure. +size_t hash_getlen_hash(const hash_t *inp); +/** Return the element at position 'idx' of the fixed array field hash + * of the hash_t in 'inp'. */ -int ed25519_v1_set_format(ed25519_v1_t *inp, uint64_t val); -/** Return the (constant) length of the array holding the pubkey field - * of the ed25519_v1_t in 'inp'. +uint8_t hash_get_hash(hash_t *inp, size_t idx); +/** As hash_get_hash, but take and return a const pointer */ -size_t ed25519_v1_getlen_pubkey(const ed25519_v1_t *inp); -/** Return the element at position 'idx' of the fixed array field - * pubkey of the ed25519_v1_t in 'inp'. +uint8_t hash_getconst_hash(const hash_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field hash + * of the hash_t in 'inp', so that it will hold the value 'elt'. */ -uint8_t ed25519_v1_get_pubkey(ed25519_v1_t *inp, size_t idx); -/** As ed25519_v1_get_pubkey, but take and return a const pointer +int hash_set_hash(hash_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field hash of 'inp'. */ -uint8_t ed25519_v1_getconst_pubkey(const ed25519_v1_t *inp, size_t idx); -/** Change the element at position 'idx' of the fixed array field - * pubkey of the ed25519_v1_t in 'inp', so that it will hold the value - * 'elt'. - */ -int ed25519_v1_set_pubkey(ed25519_v1_t *inp, size_t idx, uint8_t elt); -/** Return a pointer to the 32-element array field pubkey of 'inp'. - */ -uint8_t * ed25519_v1_getarray_pubkey(ed25519_v1_t *inp); -/** As ed25519_v1_get_pubkey, but take and return a const pointer +uint8_t * hash_getarray_hash(hash_t *inp); +/** As hash_get_hash, but take and return a const pointer */ -const uint8_t * ed25519_v1_getconstarray_pubkey(const ed25519_v1_t *inp); +const uint8_t * hash_getconstarray_hash(const hash_t *inp); /** Return a newly allocated req_get_consistency_proof_v1 with all * elements set to zero. */ @@ -350,136 +361,243 @@ uint8_t * req_get_proof_by_hash_v1_getarray_leaf_hash(req_get_proof_by_hash_v1_t * const pointer */ const uint8_t * req_get_proof_by_hash_v1_getconstarray_leaf_hash(const req_get_proof_by_hash_v1_t *inp); -/** Return a newly allocated signed_tree_head_v1 with all elements set - * to zero. +/** Return a newly allocated sigident_ed25519 with all elements set to + * zero. */ -signed_tree_head_v1_t *signed_tree_head_v1_new(void); -/** Release all storage held by the signed_tree_head_v1 in 'victim'. - * (Do nothing if 'victim' is NULL.) +sigident_ed25519_t *sigident_ed25519_new(void); +/** Release all storage held by the sigident_ed25519 in 'victim'. (Do + * nothing if 'victim' is NULL.) */ -void signed_tree_head_v1_free(signed_tree_head_v1_t *victim); -/** Try to parse a signed_tree_head_v1 from the buffer in 'input', - * using up to 'len_in' bytes from the input buffer. On success, - * return the number of bytes consumed and set *output to the newly - * allocated signed_tree_head_v1_t. On failure, return -2 if the input - * appears truncated, and -1 if the input is otherwise invalid. +void sigident_ed25519_free(sigident_ed25519_t *victim); +/** Try to parse a sigident_ed25519 from the buffer in 'input', using + * up to 'len_in' bytes from the input buffer. On success, return the + * number of bytes consumed and set *output to the newly allocated + * sigident_ed25519_t. On failure, return -2 if the input appears + * truncated, and -1 if the input is otherwise invalid. */ -ssize_t signed_tree_head_v1_parse(signed_tree_head_v1_t **output, const uint8_t *input, const size_t len_in); +ssize_t sigident_ed25519_parse(sigident_ed25519_t **output, const uint8_t *input, const size_t len_in); /** Return the number of bytes we expect to need to encode the - * signed_tree_head_v1 in 'obj'. On failure, return a negative value. + * sigident_ed25519 in 'obj'. On failure, return a negative value. * Note that this value may be an overestimate, and can even be an * underestimate for certain unencodeable objects. */ -ssize_t signed_tree_head_v1_encoded_len(const signed_tree_head_v1_t *obj); -/** Try to encode the signed_tree_head_v1 from 'input' into the buffer - * at 'output', using up to 'avail' bytes of the output buffer. On +ssize_t sigident_ed25519_encoded_len(const sigident_ed25519_t *obj); +/** Try to encode the sigident_ed25519 from 'input' into the buffer at + * 'output', using up to 'avail' bytes of the output buffer. On * success, return the number of bytes used. On failure, return -2 if * the buffer was not long enough, and -1 if the input was invalid. */ -ssize_t signed_tree_head_v1_encode(uint8_t *output, size_t avail, const signed_tree_head_v1_t *input); -/** Check whether the internal state of the signed_tree_head_v1 in - * 'obj' is consistent. Return NULL if it is, and a short message if - * it is not. +ssize_t sigident_ed25519_encode(uint8_t *output, size_t avail, const sigident_ed25519_t *input); +/** Check whether the internal state of the sigident_ed25519 in 'obj' + * is consistent. Return NULL if it is, and a short message if it is + * not. */ -const char *signed_tree_head_v1_check(const signed_tree_head_v1_t *obj); +const char *sigident_ed25519_check(const sigident_ed25519_t *obj); /** Clear any errors that were set on the object 'obj' by its setter * functions. Return true iff errors were cleared. */ -int signed_tree_head_v1_clear_errors(signed_tree_head_v1_t *obj); -/** Return the value of the format field of the signed_tree_head_v1_t - * in 'inp' +int sigident_ed25519_clear_errors(sigident_ed25519_t *obj); +/** Return the (constant) length of the array holding the signature + * field of the sigident_ed25519_t in 'inp'. */ -uint64_t signed_tree_head_v1_get_format(const signed_tree_head_v1_t *inp); -/** Set the value of the format field of the signed_tree_head_v1_t in - * 'inp' to 'val'. Return 0 on success; return -1 and set the error - * code on 'inp' on failure. +size_t sigident_ed25519_getlen_signature(const sigident_ed25519_t *inp); +/** Return the element at position 'idx' of the fixed array field + * signature of the sigident_ed25519_t in 'inp'. */ -int signed_tree_head_v1_set_format(signed_tree_head_v1_t *inp, uint64_t val); -/** Return the value of the timestamp field of the - * signed_tree_head_v1_t in 'inp' +uint8_t sigident_ed25519_get_signature(sigident_ed25519_t *inp, size_t idx); +/** As sigident_ed25519_get_signature, but take and return a const + * pointer */ -uint64_t signed_tree_head_v1_get_timestamp(const signed_tree_head_v1_t *inp); -/** Set the value of the timestamp field of the signed_tree_head_v1_t - * in 'inp' to 'val'. Return 0 on success; return -1 and set the error - * code on 'inp' on failure. +uint8_t sigident_ed25519_getconst_signature(const sigident_ed25519_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * signature of the sigident_ed25519_t in 'inp', so that it will hold + * the value 'elt'. */ -int signed_tree_head_v1_set_timestamp(signed_tree_head_v1_t *inp, uint64_t val); -/** Return the value of the tree_size field of the - * signed_tree_head_v1_t in 'inp' +int sigident_ed25519_set_signature(sigident_ed25519_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 64-element array field signature of 'inp'. */ -uint64_t signed_tree_head_v1_get_tree_size(const signed_tree_head_v1_t *inp); -/** Set the value of the tree_size field of the signed_tree_head_v1_t - * in 'inp' to 'val'. Return 0 on success; return -1 and set the error - * code on 'inp' on failure. +uint8_t * sigident_ed25519_getarray_signature(sigident_ed25519_t *inp); +/** As sigident_ed25519_get_signature, but take and return a const + * pointer */ -int signed_tree_head_v1_set_tree_size(signed_tree_head_v1_t *inp, uint64_t val); -/** Return the (constant) length of the array holding the root_hash - * field of the signed_tree_head_v1_t in 'inp'. +const uint8_t * sigident_ed25519_getconstarray_signature(const sigident_ed25519_t *inp); +/** Return the (constant) length of the array holding the identifier + * field of the sigident_ed25519_t in 'inp'. */ -size_t signed_tree_head_v1_getlen_root_hash(const signed_tree_head_v1_t *inp); +size_t sigident_ed25519_getlen_identifier(const sigident_ed25519_t *inp); /** Return the element at position 'idx' of the fixed array field - * root_hash of the signed_tree_head_v1_t in 'inp'. + * identifier of the sigident_ed25519_t in 'inp'. */ -uint8_t signed_tree_head_v1_get_root_hash(signed_tree_head_v1_t *inp, size_t idx); -/** As signed_tree_head_v1_get_root_hash, but take and return a const +uint8_t sigident_ed25519_get_identifier(sigident_ed25519_t *inp, size_t idx); +/** As sigident_ed25519_get_identifier, but take and return a const * pointer */ -uint8_t signed_tree_head_v1_getconst_root_hash(const signed_tree_head_v1_t *inp, size_t idx); +uint8_t sigident_ed25519_getconst_identifier(const sigident_ed25519_t *inp, size_t idx); /** Change the element at position 'idx' of the fixed array field - * root_hash of the signed_tree_head_v1_t in 'inp', so that it will - * hold the value 'elt'. + * identifier of the sigident_ed25519_t in 'inp', so that it will hold + * the value 'elt'. */ -int signed_tree_head_v1_set_root_hash(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt); -/** Return a pointer to the 32-element array field root_hash of 'inp'. +int sigident_ed25519_set_identifier(sigident_ed25519_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field identifier of + * 'inp'. */ -uint8_t * signed_tree_head_v1_getarray_root_hash(signed_tree_head_v1_t *inp); -/** As signed_tree_head_v1_get_root_hash, but take and return a const +uint8_t * sigident_ed25519_getarray_identifier(sigident_ed25519_t *inp); +/** As sigident_ed25519_get_identifier, but take and return a const * pointer */ -const uint8_t * signed_tree_head_v1_getconstarray_root_hash(const signed_tree_head_v1_t *inp); -/** Return the value of the length field of the signed_tree_head_v1_t - * in 'inp' +const uint8_t * sigident_ed25519_getconstarray_identifier(const sigident_ed25519_t *inp); +/** Return a newly allocated signed_checksum32_ed25519 with all + * elements set to zero. */ -uint64_t signed_tree_head_v1_get_length(const signed_tree_head_v1_t *inp); -/** Set the value of the length field of the signed_tree_head_v1_t in - * 'inp' to 'val'. Return 0 on success; return -1 and set the error - * code on 'inp' on failure. +signed_checksum32_ed25519_t *signed_checksum32_ed25519_new(void); +/** Release all storage held by the signed_checksum32_ed25519 in + * 'victim'. (Do nothing if 'victim' is NULL.) */ -int signed_tree_head_v1_set_length(signed_tree_head_v1_t *inp, uint64_t val); -/** Return the length of the dynamic array holding the sigident field - * of the signed_tree_head_v1_t in 'inp'. +void signed_checksum32_ed25519_free(signed_checksum32_ed25519_t *victim); +/** Try to parse a signed_checksum32_ed25519 from the buffer in + * 'input', using up to 'len_in' bytes from the input buffer. On + * success, return the number of bytes consumed and set *output to the + * newly allocated signed_checksum32_ed25519_t. On failure, return -2 + * if the input appears truncated, and -1 if the input is otherwise + * invalid. + */ +ssize_t signed_checksum32_ed25519_parse(signed_checksum32_ed25519_t **output, const uint8_t *input, const size_t len_in); +/** Return the number of bytes we expect to need to encode the + * signed_checksum32_ed25519 in 'obj'. On failure, return a negative + * value. Note that this value may be an overestimate, and can even be + * an underestimate for certain unencodeable objects. + */ +ssize_t signed_checksum32_ed25519_encoded_len(const signed_checksum32_ed25519_t *obj); +/** Try to encode the signed_checksum32_ed25519 from 'input' into the + * buffer at 'output', using up to 'avail' bytes of the output buffer. + * On success, return the number of bytes used. On failure, return -2 + * if the buffer was not long enough, and -1 if the input was invalid. + */ +ssize_t signed_checksum32_ed25519_encode(uint8_t *output, size_t avail, const signed_checksum32_ed25519_t *input); +/** Check whether the internal state of the signed_checksum32_ed25519 + * in 'obj' is consistent. Return NULL if it is, and a short message + * if it is not. + */ +const char *signed_checksum32_ed25519_check(const signed_checksum32_ed25519_t *obj); +/** Clear any errors that were set on the object 'obj' by its setter + * functions. Return true iff errors were cleared. + */ +int signed_checksum32_ed25519_clear_errors(signed_checksum32_ed25519_t *obj); +/** Return the (constant) length of the array holding the checksum + * field of the signed_checksum32_ed25519_t in 'inp'. + */ +size_t signed_checksum32_ed25519_getlen_checksum(const signed_checksum32_ed25519_t *inp); +/** Return the element at position 'idx' of the fixed array field + * checksum of the signed_checksum32_ed25519_t in 'inp'. */ -size_t signed_tree_head_v1_getlen_sigident(const signed_tree_head_v1_t *inp); +uint8_t signed_checksum32_ed25519_get_checksum(signed_checksum32_ed25519_t *inp, size_t idx); +/** As signed_checksum32_ed25519_get_checksum, but take and return a + * const pointer + */ +uint8_t signed_checksum32_ed25519_getconst_checksum(const signed_checksum32_ed25519_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * checksum of the signed_checksum32_ed25519_t in 'inp', so that it + * will hold the value 'elt'. + */ +int signed_checksum32_ed25519_set_checksum(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field checksum of 'inp'. + */ +uint8_t * signed_checksum32_ed25519_getarray_checksum(signed_checksum32_ed25519_t *inp); +/** As signed_checksum32_ed25519_get_checksum, but take and return a + * const pointer + */ +const uint8_t * signed_checksum32_ed25519_getconstarray_checksum(const signed_checksum32_ed25519_t *inp); +/** Return the value of the length field of the + * signed_checksum32_ed25519_t in 'inp' + */ +uint64_t signed_checksum32_ed25519_get_length(const signed_checksum32_ed25519_t *inp); +/** Set the value of the length field of the + * signed_checksum32_ed25519_t in 'inp' to 'val'. Return 0 on success; + * return -1 and set the error code on 'inp' on failure. + */ +int signed_checksum32_ed25519_set_length(signed_checksum32_ed25519_t *inp, uint64_t val); +/** Return the length of the dynamic array holding the identifier + * field of the signed_checksum32_ed25519_t in 'inp'. + */ +size_t signed_checksum32_ed25519_getlen_identifier(const signed_checksum32_ed25519_t *inp); /** Return the element at position 'idx' of the dynamic array field - * sigident of the signed_tree_head_v1_t in 'inp'. + * identifier of the signed_checksum32_ed25519_t in 'inp'. */ -uint8_t signed_tree_head_v1_get_sigident(signed_tree_head_v1_t *inp, size_t idx); -/** As signed_tree_head_v1_get_sigident, but take and return a const - * pointer +uint8_t signed_checksum32_ed25519_get_identifier(signed_checksum32_ed25519_t *inp, size_t idx); +/** As signed_checksum32_ed25519_get_identifier, but take and return a + * const pointer */ -uint8_t signed_tree_head_v1_getconst_sigident(const signed_tree_head_v1_t *inp, size_t idx); +uint8_t signed_checksum32_ed25519_getconst_identifier(const signed_checksum32_ed25519_t *inp, size_t idx); /** Change the element at position 'idx' of the dynamic array field - * sigident of the signed_tree_head_v1_t in 'inp', so that it will - * hold the value 'elt'. + * identifier of the signed_checksum32_ed25519_t in 'inp', so that it + * will hold the value 'elt'. */ -int signed_tree_head_v1_set_sigident(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt); -/** Append a new element 'elt' to the dynamic array field sigident of - * the signed_tree_head_v1_t in 'inp'. +int signed_checksum32_ed25519_set_identifier(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt); +/** Append a new element 'elt' to the dynamic array field identifier + * of the signed_checksum32_ed25519_t in 'inp'. */ -int signed_tree_head_v1_add_sigident(signed_tree_head_v1_t *inp, uint8_t elt); -/** Return a pointer to the variable-length array field sigident of +int signed_checksum32_ed25519_add_identifier(signed_checksum32_ed25519_t *inp, uint8_t elt); +/** Return a pointer to the variable-length array field identifier of * 'inp'. */ -uint8_t * signed_tree_head_v1_getarray_sigident(signed_tree_head_v1_t *inp); -/** As signed_tree_head_v1_get_sigident, but take and return a const - * pointer +uint8_t * signed_checksum32_ed25519_getarray_identifier(signed_checksum32_ed25519_t *inp); +/** As signed_checksum32_ed25519_get_identifier, but take and return a + * const pointer */ -const uint8_t * signed_tree_head_v1_getconstarray_sigident(const signed_tree_head_v1_t *inp); -/** Change the length of the variable-length array field sigident of +const uint8_t * signed_checksum32_ed25519_getconstarray_identifier(const signed_checksum32_ed25519_t *inp); +/** Change the length of the variable-length array field identifier of * 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success; * return -1 and set the error code on 'inp' on failure. */ -int signed_tree_head_v1_setlen_sigident(signed_tree_head_v1_t *inp, size_t newlen); +int signed_checksum32_ed25519_setlen_identifier(signed_checksum32_ed25519_t *inp, size_t newlen); +/** Return the (constant) length of the array holding the signature + * field of the signed_checksum32_ed25519_t in 'inp'. + */ +size_t signed_checksum32_ed25519_getlen_signature(const signed_checksum32_ed25519_t *inp); +/** Return the element at position 'idx' of the fixed array field + * signature of the signed_checksum32_ed25519_t in 'inp'. + */ +uint8_t signed_checksum32_ed25519_get_signature(signed_checksum32_ed25519_t *inp, size_t idx); +/** As signed_checksum32_ed25519_get_signature, but take and return a + * const pointer + */ +uint8_t signed_checksum32_ed25519_getconst_signature(const signed_checksum32_ed25519_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * signature of the signed_checksum32_ed25519_t in 'inp', so that it + * will hold the value 'elt'. + */ +int signed_checksum32_ed25519_set_signature(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 64-element array field signature of 'inp'. + */ +uint8_t * signed_checksum32_ed25519_getarray_signature(signed_checksum32_ed25519_t *inp); +/** As signed_checksum32_ed25519_get_signature, but take and return a + * const pointer + */ +const uint8_t * signed_checksum32_ed25519_getconstarray_signature(const signed_checksum32_ed25519_t *inp); +/** Return the (constant) length of the array holding the namespace + * field of the signed_checksum32_ed25519_t in 'inp'. + */ +size_t signed_checksum32_ed25519_getlen_namespace(const signed_checksum32_ed25519_t *inp); +/** Return the element at position 'idx' of the fixed array field + * namespace of the signed_checksum32_ed25519_t in 'inp'. + */ +uint8_t signed_checksum32_ed25519_get_namespace(signed_checksum32_ed25519_t *inp, size_t idx); +/** As signed_checksum32_ed25519_get_namespace, but take and return a + * const pointer + */ +uint8_t signed_checksum32_ed25519_getconst_namespace(const signed_checksum32_ed25519_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * namespace of the signed_checksum32_ed25519_t in 'inp', so that it + * will hold the value 'elt'. + */ +int signed_checksum32_ed25519_set_namespace(signed_checksum32_ed25519_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field namespace of 'inp'. + */ +uint8_t * signed_checksum32_ed25519_getarray_namespace(signed_checksum32_ed25519_t *inp); +/** As signed_checksum32_ed25519_get_namespace, but take and return a + * const pointer + */ +const uint8_t * signed_checksum32_ed25519_getconstarray_namespace(const signed_checksum32_ed25519_t *inp); /** Return a newly allocated consistency_proof_v1 with all elements * set to zero. */ @@ -516,6 +634,15 @@ const char *consistency_proof_v1_check(const consistency_proof_v1_t *obj); * functions. Return true iff errors were cleared. */ int consistency_proof_v1_clear_errors(consistency_proof_v1_t *obj); +/** Return the value of the magic field of the consistency_proof_v1_t + * in 'inp' + */ +uint64_t consistency_proof_v1_get_magic(const consistency_proof_v1_t *inp); +/** Set the value of the magic field of the consistency_proof_v1_t in + * 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. + */ +int consistency_proof_v1_set_magic(consistency_proof_v1_t *inp, uint64_t val); /** Return the value of the format field of the consistency_proof_v1_t * in 'inp' */ @@ -525,24 +652,31 @@ uint64_t consistency_proof_v1_get_format(const consistency_proof_v1_t *inp); * code on 'inp' on failure. */ int consistency_proof_v1_set_format(consistency_proof_v1_t *inp, uint64_t val); -/** Return the value of the identifier field of the - * consistency_proof_v1_t in 'inp' +/** Return the (constant) length of the array holding the identifier + * field of the consistency_proof_v1_t in 'inp'. */ -struct ed25519_v1_st * consistency_proof_v1_get_identifier(consistency_proof_v1_t *inp); +size_t consistency_proof_v1_getlen_identifier(const consistency_proof_v1_t *inp); +/** Return the element at position 'idx' of the fixed array field + * identifier of the consistency_proof_v1_t in 'inp'. + */ +uint8_t consistency_proof_v1_get_identifier(consistency_proof_v1_t *inp, size_t idx); /** As consistency_proof_v1_get_identifier, but take and return a * const pointer */ -const struct ed25519_v1_st * consistency_proof_v1_getconst_identifier(const consistency_proof_v1_t *inp); -/** Set the value of the identifier field of the - * consistency_proof_v1_t in 'inp' to 'val'. Free the old value if - * any. Steals the referenceto 'val'.Return 0 on success; return -1 - * and set the error code on 'inp' on failure. +uint8_t consistency_proof_v1_getconst_identifier(const consistency_proof_v1_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * identifier of the consistency_proof_v1_t in 'inp', so that it will + * hold the value 'elt'. */ -int consistency_proof_v1_set_identifier(consistency_proof_v1_t *inp, struct ed25519_v1_st *val); -/** As consistency_proof_v1_set_identifier, but does not free the - * previous value. +int consistency_proof_v1_set_identifier(consistency_proof_v1_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field identifier of + * 'inp'. */ -int consistency_proof_v1_set0_identifier(consistency_proof_v1_t *inp, struct ed25519_v1_st *val); +uint8_t * consistency_proof_v1_getarray_identifier(consistency_proof_v1_t *inp); +/** As consistency_proof_v1_get_identifier, but take and return a + * const pointer + */ +const uint8_t * consistency_proof_v1_getconstarray_identifier(const consistency_proof_v1_t *inp); /** Return the value of the old_size field of the * consistency_proof_v1_t in 'inp' */ @@ -561,15 +695,15 @@ uint64_t consistency_proof_v1_get_new_size(const consistency_proof_v1_t *inp); * code on 'inp' on failure. */ int consistency_proof_v1_set_new_size(consistency_proof_v1_t *inp, uint64_t val); -/** Return the value of the length field of the consistency_proof_v1_t - * in 'inp' +/** Return the value of the n_items field of the + * consistency_proof_v1_t in 'inp' */ -uint64_t consistency_proof_v1_get_length(const consistency_proof_v1_t *inp); -/** Set the value of the length field of the consistency_proof_v1_t in - * 'inp' to 'val'. Return 0 on success; return -1 and set the error +uint64_t consistency_proof_v1_get_n_items(const consistency_proof_v1_t *inp); +/** Set the value of the n_items field of the consistency_proof_v1_t + * in 'inp' to 'val'. Return 0 on success; return -1 and set the error * code on 'inp' on failure. */ -int consistency_proof_v1_set_length(consistency_proof_v1_t *inp, uint64_t val); +int consistency_proof_v1_set_n_items(consistency_proof_v1_t *inp, uint64_t val); /** Return the length of the dynamic array holding the hashes field of * the consistency_proof_v1_t in 'inp'. */ @@ -577,33 +711,132 @@ size_t consistency_proof_v1_getlen_hashes(const consistency_proof_v1_t *inp); /** Return the element at position 'idx' of the dynamic array field * hashes of the consistency_proof_v1_t in 'inp'. */ -uint8_t consistency_proof_v1_get_hashes(consistency_proof_v1_t *inp, size_t idx); +struct hash_st * consistency_proof_v1_get_hashes(consistency_proof_v1_t *inp, size_t idx); /** As consistency_proof_v1_get_hashes, but take and return a const * pointer */ -uint8_t consistency_proof_v1_getconst_hashes(const consistency_proof_v1_t *inp, size_t idx); + const struct hash_st * consistency_proof_v1_getconst_hashes(const consistency_proof_v1_t *inp, size_t idx); /** Change the element at position 'idx' of the dynamic array field * hashes of the consistency_proof_v1_t in 'inp', so that it will hold - * the value 'elt'. + * the value 'elt'. Free the previous value, if any. + */ +int consistency_proof_v1_set_hashes(consistency_proof_v1_t *inp, size_t idx, struct hash_st * elt); +/** As consistency_proof_v1_set_hashes, but does not free the previous + * value. */ -int consistency_proof_v1_set_hashes(consistency_proof_v1_t *inp, size_t idx, uint8_t elt); +int consistency_proof_v1_set0_hashes(consistency_proof_v1_t *inp, size_t idx, struct hash_st * elt); /** Append a new element 'elt' to the dynamic array field hashes of * the consistency_proof_v1_t in 'inp'. */ -int consistency_proof_v1_add_hashes(consistency_proof_v1_t *inp, uint8_t elt); +int consistency_proof_v1_add_hashes(consistency_proof_v1_t *inp, struct hash_st * elt); /** Return a pointer to the variable-length array field hashes of * 'inp'. */ -uint8_t * consistency_proof_v1_getarray_hashes(consistency_proof_v1_t *inp); +struct hash_st * * consistency_proof_v1_getarray_hashes(consistency_proof_v1_t *inp); /** As consistency_proof_v1_get_hashes, but take and return a const * pointer */ -const uint8_t * consistency_proof_v1_getconstarray_hashes(const consistency_proof_v1_t *inp); +const struct hash_st * const * consistency_proof_v1_getconstarray_hashes(const consistency_proof_v1_t *inp); /** Change the length of the variable-length array field hashes of - * 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success; - * return -1 and set the error code on 'inp' on failure. + * 'inp' to 'newlen'.Fill extra elements with NULL; free removed + * elements. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. */ int consistency_proof_v1_setlen_hashes(consistency_proof_v1_t *inp, size_t newlen); +/** Return a newly allocated entries_v1 with all elements set to zero. + */ +entries_v1_t *entries_v1_new(void); +/** Release all storage held by the entries_v1 in 'victim'. (Do + * nothing if 'victim' is NULL.) + */ +void entries_v1_free(entries_v1_t *victim); +/** Try to parse a entries_v1 from the buffer in 'input', using up to + * 'len_in' bytes from the input buffer. On success, return the number + * of bytes consumed and set *output to the newly allocated + * entries_v1_t. On failure, return -2 if the input appears truncated, + * and -1 if the input is otherwise invalid. + */ +ssize_t entries_v1_parse(entries_v1_t **output, const uint8_t *input, const size_t len_in); +/** Return the number of bytes we expect to need to encode the + * entries_v1 in 'obj'. On failure, return a negative value. Note that + * this value may be an overestimate, and can even be an underestimate + * for certain unencodeable objects. + */ +ssize_t entries_v1_encoded_len(const entries_v1_t *obj); +/** Try to encode the entries_v1 from 'input' into the buffer at + * 'output', using up to 'avail' bytes of the output buffer. On + * success, return the number of bytes used. On failure, return -2 if + * the buffer was not long enough, and -1 if the input was invalid. + */ +ssize_t entries_v1_encode(uint8_t *output, size_t avail, const entries_v1_t *input); +/** Check whether the internal state of the entries_v1 in 'obj' is + * consistent. Return NULL if it is, and a short message if it is not. + */ +const char *entries_v1_check(const entries_v1_t *obj); +/** Clear any errors that were set on the object 'obj' by its setter + * functions. Return true iff errors were cleared. + */ +int entries_v1_clear_errors(entries_v1_t *obj); +/** Return the value of the magic field of the entries_v1_t in 'inp' + */ +uint64_t entries_v1_get_magic(const entries_v1_t *inp); +/** Set the value of the magic field of the entries_v1_t in 'inp' to + * 'val'. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. + */ +int entries_v1_set_magic(entries_v1_t *inp, uint64_t val); +/** Return the value of the format field of the entries_v1_t in 'inp' + */ +uint64_t entries_v1_get_format(const entries_v1_t *inp); +/** Set the value of the format field of the entries_v1_t in 'inp' to + * 'val'. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. + */ +int entries_v1_set_format(entries_v1_t *inp, uint64_t val); +/** Return the value of the n_items field of the entries_v1_t in 'inp' + */ +uint64_t entries_v1_get_n_items(const entries_v1_t *inp); +/** Set the value of the n_items field of the entries_v1_t in 'inp' to + * 'val'. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. + */ +int entries_v1_set_n_items(entries_v1_t *inp, uint64_t val); +/** Return the length of the dynamic array holding the checksums field + * of the entries_v1_t in 'inp'. + */ +size_t entries_v1_getlen_checksums(const entries_v1_t *inp); +/** Return the element at position 'idx' of the dynamic array field + * checksums of the entries_v1_t in 'inp'. + */ +struct signed_checksum32_ed25519_st * entries_v1_get_checksums(entries_v1_t *inp, size_t idx); +/** As entries_v1_get_checksums, but take and return a const pointer + */ + const struct signed_checksum32_ed25519_st * entries_v1_getconst_checksums(const entries_v1_t *inp, size_t idx); +/** Change the element at position 'idx' of the dynamic array field + * checksums of the entries_v1_t in 'inp', so that it will hold the + * value 'elt'. Free the previous value, if any. + */ +int entries_v1_set_checksums(entries_v1_t *inp, size_t idx, struct signed_checksum32_ed25519_st * elt); +/** As entries_v1_set_checksums, but does not free the previous value. + */ +int entries_v1_set0_checksums(entries_v1_t *inp, size_t idx, struct signed_checksum32_ed25519_st * elt); +/** Append a new element 'elt' to the dynamic array field checksums of + * the entries_v1_t in 'inp'. + */ +int entries_v1_add_checksums(entries_v1_t *inp, struct signed_checksum32_ed25519_st * elt); +/** Return a pointer to the variable-length array field checksums of + * 'inp'. + */ +struct signed_checksum32_ed25519_st * * entries_v1_getarray_checksums(entries_v1_t *inp); +/** As entries_v1_get_checksums, but take and return a const pointer + */ +const struct signed_checksum32_ed25519_st * const * entries_v1_getconstarray_checksums(const entries_v1_t *inp); +/** Change the length of the variable-length array field checksums of + * 'inp' to 'newlen'.Fill extra elements with NULL; free removed + * elements. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. + */ +int entries_v1_setlen_checksums(entries_v1_t *inp, size_t newlen); /** Return a newly allocated inclusion_proof_v1 with all elements set * to zero. */ @@ -640,6 +873,15 @@ const char *inclusion_proof_v1_check(const inclusion_proof_v1_t *obj); * functions. Return true iff errors were cleared. */ int inclusion_proof_v1_clear_errors(inclusion_proof_v1_t *obj); +/** Return the value of the magic field of the inclusion_proof_v1_t in + * 'inp' + */ +uint64_t inclusion_proof_v1_get_magic(const inclusion_proof_v1_t *inp); +/** Set the value of the magic field of the inclusion_proof_v1_t in + * 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. + */ +int inclusion_proof_v1_set_magic(inclusion_proof_v1_t *inp, uint64_t val); /** Return the value of the format field of the inclusion_proof_v1_t * in 'inp' */ @@ -649,24 +891,31 @@ uint64_t inclusion_proof_v1_get_format(const inclusion_proof_v1_t *inp); * code on 'inp' on failure. */ int inclusion_proof_v1_set_format(inclusion_proof_v1_t *inp, uint64_t val); -/** Return the value of the identifier field of the - * inclusion_proof_v1_t in 'inp' +/** Return the (constant) length of the array holding the identifier + * field of the inclusion_proof_v1_t in 'inp'. */ -struct ed25519_v1_st * inclusion_proof_v1_get_identifier(inclusion_proof_v1_t *inp); +size_t inclusion_proof_v1_getlen_identifier(const inclusion_proof_v1_t *inp); +/** Return the element at position 'idx' of the fixed array field + * identifier of the inclusion_proof_v1_t in 'inp'. + */ +uint8_t inclusion_proof_v1_get_identifier(inclusion_proof_v1_t *inp, size_t idx); /** As inclusion_proof_v1_get_identifier, but take and return a const * pointer */ -const struct ed25519_v1_st * inclusion_proof_v1_getconst_identifier(const inclusion_proof_v1_t *inp); -/** Set the value of the identifier field of the inclusion_proof_v1_t - * in 'inp' to 'val'. Free the old value if any. Steals the - * referenceto 'val'.Return 0 on success; return -1 and set the error - * code on 'inp' on failure. +uint8_t inclusion_proof_v1_getconst_identifier(const inclusion_proof_v1_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * identifier of the inclusion_proof_v1_t in 'inp', so that it will + * hold the value 'elt'. */ -int inclusion_proof_v1_set_identifier(inclusion_proof_v1_t *inp, struct ed25519_v1_st *val); -/** As inclusion_proof_v1_set_identifier, but does not free the - * previous value. +int inclusion_proof_v1_set_identifier(inclusion_proof_v1_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field identifier of + * 'inp'. */ -int inclusion_proof_v1_set0_identifier(inclusion_proof_v1_t *inp, struct ed25519_v1_st *val); +uint8_t * inclusion_proof_v1_getarray_identifier(inclusion_proof_v1_t *inp); +/** As inclusion_proof_v1_get_identifier, but take and return a const + * pointer + */ +const uint8_t * inclusion_proof_v1_getconstarray_identifier(const inclusion_proof_v1_t *inp); /** Return the value of the tree_size field of the * inclusion_proof_v1_t in 'inp' */ @@ -685,15 +934,15 @@ uint64_t inclusion_proof_v1_get_leaf_index(const inclusion_proof_v1_t *inp); * code on 'inp' on failure. */ int inclusion_proof_v1_set_leaf_index(inclusion_proof_v1_t *inp, uint64_t val); -/** Return the value of the length field of the inclusion_proof_v1_t +/** Return the value of the n_items field of the inclusion_proof_v1_t * in 'inp' */ -uint64_t inclusion_proof_v1_get_length(const inclusion_proof_v1_t *inp); -/** Set the value of the length field of the inclusion_proof_v1_t in +uint64_t inclusion_proof_v1_get_n_items(const inclusion_proof_v1_t *inp); +/** Set the value of the n_items field of the inclusion_proof_v1_t in * 'inp' to 'val'. Return 0 on success; return -1 and set the error * code on 'inp' on failure. */ -int inclusion_proof_v1_set_length(inclusion_proof_v1_t *inp, uint64_t val); +int inclusion_proof_v1_set_n_items(inclusion_proof_v1_t *inp, uint64_t val); /** Return the length of the dynamic array holding the hashes field of * the inclusion_proof_v1_t in 'inp'. */ @@ -701,31 +950,36 @@ size_t inclusion_proof_v1_getlen_hashes(const inclusion_proof_v1_t *inp); /** Return the element at position 'idx' of the dynamic array field * hashes of the inclusion_proof_v1_t in 'inp'. */ -uint8_t inclusion_proof_v1_get_hashes(inclusion_proof_v1_t *inp, size_t idx); +struct hash_st * inclusion_proof_v1_get_hashes(inclusion_proof_v1_t *inp, size_t idx); /** As inclusion_proof_v1_get_hashes, but take and return a const * pointer */ -uint8_t inclusion_proof_v1_getconst_hashes(const inclusion_proof_v1_t *inp, size_t idx); + const struct hash_st * inclusion_proof_v1_getconst_hashes(const inclusion_proof_v1_t *inp, size_t idx); /** Change the element at position 'idx' of the dynamic array field * hashes of the inclusion_proof_v1_t in 'inp', so that it will hold - * the value 'elt'. + * the value 'elt'. Free the previous value, if any. */ -int inclusion_proof_v1_set_hashes(inclusion_proof_v1_t *inp, size_t idx, uint8_t elt); +int inclusion_proof_v1_set_hashes(inclusion_proof_v1_t *inp, size_t idx, struct hash_st * elt); +/** As inclusion_proof_v1_set_hashes, but does not free the previous + * value. + */ +int inclusion_proof_v1_set0_hashes(inclusion_proof_v1_t *inp, size_t idx, struct hash_st * elt); /** Append a new element 'elt' to the dynamic array field hashes of * the inclusion_proof_v1_t in 'inp'. */ -int inclusion_proof_v1_add_hashes(inclusion_proof_v1_t *inp, uint8_t elt); +int inclusion_proof_v1_add_hashes(inclusion_proof_v1_t *inp, struct hash_st * elt); /** Return a pointer to the variable-length array field hashes of * 'inp'. */ -uint8_t * inclusion_proof_v1_getarray_hashes(inclusion_proof_v1_t *inp); +struct hash_st * * inclusion_proof_v1_getarray_hashes(inclusion_proof_v1_t *inp); /** As inclusion_proof_v1_get_hashes, but take and return a const * pointer */ -const uint8_t * inclusion_proof_v1_getconstarray_hashes(const inclusion_proof_v1_t *inp); +const struct hash_st * const * inclusion_proof_v1_getconstarray_hashes(const inclusion_proof_v1_t *inp); /** Change the length of the variable-length array field hashes of - * 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success; - * return -1 and set the error code on 'inp' on failure. + * 'inp' to 'newlen'.Fill extra elements with NULL; free removed + * elements. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. */ int inclusion_proof_v1_setlen_hashes(inclusion_proof_v1_t *inp, size_t newlen); /** Return a newly allocated request_v1 with all elements set to zero. @@ -762,6 +1016,14 @@ const char *request_v1_check(const request_v1_t *obj); * functions. Return true iff errors were cleared. */ int request_v1_clear_errors(request_v1_t *obj); +/** Return the value of the magic field of the request_v1_t in 'inp' + */ +uint64_t request_v1_get_magic(const request_v1_t *inp); +/** Set the value of the magic field of the request_v1_t in 'inp' to + * 'val'. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. + */ +int request_v1_set_magic(request_v1_t *inp, uint64_t val); /** Return the value of the format field of the request_v1_t in 'inp' */ uint64_t request_v1_get_format(const request_v1_t *inp); @@ -824,162 +1086,150 @@ int request_v1_set_request_get_consistency_proof(request_v1_t *inp, struct req_g * the previous value. */ int request_v1_set0_request_get_consistency_proof(request_v1_t *inp, struct req_get_consistency_proof_v1_st *val); -/** Return a newly allocated signed_checksum32_ed25519_v1 with all - * elements set to zero. +/** Return a newly allocated signed_tree_head_v1 with all elements set + * to zero. */ -signed_checksum32_ed25519_v1_t *signed_checksum32_ed25519_v1_new(void); -/** Release all storage held by the signed_checksum32_ed25519_v1 in - * 'victim'. (Do nothing if 'victim' is NULL.) +signed_tree_head_v1_t *signed_tree_head_v1_new(void); +/** Release all storage held by the signed_tree_head_v1 in 'victim'. + * (Do nothing if 'victim' is NULL.) */ -void signed_checksum32_ed25519_v1_free(signed_checksum32_ed25519_v1_t *victim); -/** Try to parse a signed_checksum32_ed25519_v1 from the buffer in - * 'input', using up to 'len_in' bytes from the input buffer. On - * success, return the number of bytes consumed and set *output to the - * newly allocated signed_checksum32_ed25519_v1_t. On failure, return - * -2 if the input appears truncated, and -1 if the input is otherwise - * invalid. +void signed_tree_head_v1_free(signed_tree_head_v1_t *victim); +/** Try to parse a signed_tree_head_v1 from the buffer in 'input', + * using up to 'len_in' bytes from the input buffer. On success, + * return the number of bytes consumed and set *output to the newly + * allocated signed_tree_head_v1_t. On failure, return -2 if the input + * appears truncated, and -1 if the input is otherwise invalid. */ -ssize_t signed_checksum32_ed25519_v1_parse(signed_checksum32_ed25519_v1_t **output, const uint8_t *input, const size_t len_in); +ssize_t signed_tree_head_v1_parse(signed_tree_head_v1_t **output, const uint8_t *input, const size_t len_in); /** Return the number of bytes we expect to need to encode the - * signed_checksum32_ed25519_v1 in 'obj'. On failure, return a - * negative value. Note that this value may be an overestimate, and - * can even be an underestimate for certain unencodeable objects. + * signed_tree_head_v1 in 'obj'. On failure, return a negative value. + * Note that this value may be an overestimate, and can even be an + * underestimate for certain unencodeable objects. */ -ssize_t signed_checksum32_ed25519_v1_encoded_len(const signed_checksum32_ed25519_v1_t *obj); -/** Try to encode the signed_checksum32_ed25519_v1 from 'input' into - * the buffer at 'output', using up to 'avail' bytes of the output - * buffer. On success, return the number of bytes used. On failure, - * return -2 if the buffer was not long enough, and -1 if the input - * was invalid. +ssize_t signed_tree_head_v1_encoded_len(const signed_tree_head_v1_t *obj); +/** Try to encode the signed_tree_head_v1 from 'input' into the buffer + * at 'output', using up to 'avail' bytes of the output buffer. On + * success, return the number of bytes used. On failure, return -2 if + * the buffer was not long enough, and -1 if the input was invalid. */ -ssize_t signed_checksum32_ed25519_v1_encode(uint8_t *output, size_t avail, const signed_checksum32_ed25519_v1_t *input); -/** Check whether the internal state of the - * signed_checksum32_ed25519_v1 in 'obj' is consistent. Return NULL if - * it is, and a short message if it is not. +ssize_t signed_tree_head_v1_encode(uint8_t *output, size_t avail, const signed_tree_head_v1_t *input); +/** Check whether the internal state of the signed_tree_head_v1 in + * 'obj' is consistent. Return NULL if it is, and a short message if + * it is not. */ -const char *signed_checksum32_ed25519_v1_check(const signed_checksum32_ed25519_v1_t *obj); +const char *signed_tree_head_v1_check(const signed_tree_head_v1_t *obj); /** Clear any errors that were set on the object 'obj' by its setter * functions. Return true iff errors were cleared. */ -int signed_checksum32_ed25519_v1_clear_errors(signed_checksum32_ed25519_v1_t *obj); -/** Return the value of the format field of the - * signed_checksum32_ed25519_v1_t in 'inp' - */ -uint64_t signed_checksum32_ed25519_v1_get_format(const signed_checksum32_ed25519_v1_t *inp); -/** Set the value of the format field of the - * signed_checksum32_ed25519_v1_t in 'inp' to 'val'. Return 0 on - * success; return -1 and set the error code on 'inp' on failure. - */ -int signed_checksum32_ed25519_v1_set_format(signed_checksum32_ed25519_v1_t *inp, uint64_t val); -/** Return the (constant) length of the array holding the checksum - * field of the signed_checksum32_ed25519_v1_t in 'inp'. - */ -size_t signed_checksum32_ed25519_v1_getlen_checksum(const signed_checksum32_ed25519_v1_t *inp); -/** Return the element at position 'idx' of the fixed array field - * checksum of the signed_checksum32_ed25519_v1_t in 'inp'. +int signed_tree_head_v1_clear_errors(signed_tree_head_v1_t *obj); +/** Return the value of the magic field of the signed_tree_head_v1_t + * in 'inp' */ -uint8_t signed_checksum32_ed25519_v1_get_checksum(signed_checksum32_ed25519_v1_t *inp, size_t idx); -/** As signed_checksum32_ed25519_v1_get_checksum, but take and return - * a const pointer +uint64_t signed_tree_head_v1_get_magic(const signed_tree_head_v1_t *inp); +/** Set the value of the magic field of the signed_tree_head_v1_t in + * 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. */ -uint8_t signed_checksum32_ed25519_v1_getconst_checksum(const signed_checksum32_ed25519_v1_t *inp, size_t idx); -/** Change the element at position 'idx' of the fixed array field - * checksum of the signed_checksum32_ed25519_v1_t in 'inp', so that it - * will hold the value 'elt'. +int signed_tree_head_v1_set_magic(signed_tree_head_v1_t *inp, uint64_t val); +/** Return the value of the format field of the signed_tree_head_v1_t + * in 'inp' */ -int signed_checksum32_ed25519_v1_set_checksum(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt); -/** Return a pointer to the 32-element array field checksum of 'inp'. +uint64_t signed_tree_head_v1_get_format(const signed_tree_head_v1_t *inp); +/** Set the value of the format field of the signed_tree_head_v1_t in + * 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. */ -uint8_t * signed_checksum32_ed25519_v1_getarray_checksum(signed_checksum32_ed25519_v1_t *inp); -/** As signed_checksum32_ed25519_v1_get_checksum, but take and return - * a const pointer +int signed_tree_head_v1_set_format(signed_tree_head_v1_t *inp, uint64_t val); +/** Return the value of the timestamp field of the + * signed_tree_head_v1_t in 'inp' */ -const uint8_t * signed_checksum32_ed25519_v1_getconstarray_checksum(const signed_checksum32_ed25519_v1_t *inp); -/** Return the value of the length field of the - * signed_checksum32_ed25519_v1_t in 'inp' +uint64_t signed_tree_head_v1_get_timestamp(const signed_tree_head_v1_t *inp); +/** Set the value of the timestamp field of the signed_tree_head_v1_t + * in 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. */ -uint64_t signed_checksum32_ed25519_v1_get_length(const signed_checksum32_ed25519_v1_t *inp); -/** Set the value of the length field of the - * signed_checksum32_ed25519_v1_t in 'inp' to 'val'. Return 0 on - * success; return -1 and set the error code on 'inp' on failure. +int signed_tree_head_v1_set_timestamp(signed_tree_head_v1_t *inp, uint64_t val); +/** Return the value of the tree_size field of the + * signed_tree_head_v1_t in 'inp' */ -int signed_checksum32_ed25519_v1_set_length(signed_checksum32_ed25519_v1_t *inp, uint64_t val); -/** Return the length of the dynamic array holding the identifier - * field of the signed_checksum32_ed25519_v1_t in 'inp'. +uint64_t signed_tree_head_v1_get_tree_size(const signed_tree_head_v1_t *inp); +/** Set the value of the tree_size field of the signed_tree_head_v1_t + * in 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. */ -size_t signed_checksum32_ed25519_v1_getlen_identifier(const signed_checksum32_ed25519_v1_t *inp); -/** Return the element at position 'idx' of the dynamic array field - * identifier of the signed_checksum32_ed25519_v1_t in 'inp'. +int signed_tree_head_v1_set_tree_size(signed_tree_head_v1_t *inp, uint64_t val); +/** Return the (constant) length of the array holding the root_hash + * field of the signed_tree_head_v1_t in 'inp'. */ -uint8_t signed_checksum32_ed25519_v1_get_identifier(signed_checksum32_ed25519_v1_t *inp, size_t idx); -/** As signed_checksum32_ed25519_v1_get_identifier, but take and - * return a const pointer +size_t signed_tree_head_v1_getlen_root_hash(const signed_tree_head_v1_t *inp); +/** Return the element at position 'idx' of the fixed array field + * root_hash of the signed_tree_head_v1_t in 'inp'. */ -uint8_t signed_checksum32_ed25519_v1_getconst_identifier(const signed_checksum32_ed25519_v1_t *inp, size_t idx); -/** Change the element at position 'idx' of the dynamic array field - * identifier of the signed_checksum32_ed25519_v1_t in 'inp', so that - * it will hold the value 'elt'. +uint8_t signed_tree_head_v1_get_root_hash(signed_tree_head_v1_t *inp, size_t idx); +/** As signed_tree_head_v1_get_root_hash, but take and return a const + * pointer */ -int signed_checksum32_ed25519_v1_set_identifier(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt); -/** Append a new element 'elt' to the dynamic array field identifier - * of the signed_checksum32_ed25519_v1_t in 'inp'. +uint8_t signed_tree_head_v1_getconst_root_hash(const signed_tree_head_v1_t *inp, size_t idx); +/** Change the element at position 'idx' of the fixed array field + * root_hash of the signed_tree_head_v1_t in 'inp', so that it will + * hold the value 'elt'. */ -int signed_checksum32_ed25519_v1_add_identifier(signed_checksum32_ed25519_v1_t *inp, uint8_t elt); -/** Return a pointer to the variable-length array field identifier of - * 'inp'. +int signed_tree_head_v1_set_root_hash(signed_tree_head_v1_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the 32-element array field root_hash of 'inp'. */ -uint8_t * signed_checksum32_ed25519_v1_getarray_identifier(signed_checksum32_ed25519_v1_t *inp); -/** As signed_checksum32_ed25519_v1_get_identifier, but take and - * return a const pointer +uint8_t * signed_tree_head_v1_getarray_root_hash(signed_tree_head_v1_t *inp); +/** As signed_tree_head_v1_get_root_hash, but take and return a const + * pointer */ -const uint8_t * signed_checksum32_ed25519_v1_getconstarray_identifier(const signed_checksum32_ed25519_v1_t *inp); -/** Change the length of the variable-length array field identifier of - * 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on success; - * return -1 and set the error code on 'inp' on failure. +const uint8_t * signed_tree_head_v1_getconstarray_root_hash(const signed_tree_head_v1_t *inp); +/** Return the value of the n_items field of the signed_tree_head_v1_t + * in 'inp' */ -int signed_checksum32_ed25519_v1_setlen_identifier(signed_checksum32_ed25519_v1_t *inp, size_t newlen); -/** Return the (constant) length of the array holding the signature - * field of the signed_checksum32_ed25519_v1_t in 'inp'. +uint64_t signed_tree_head_v1_get_n_items(const signed_tree_head_v1_t *inp); +/** Set the value of the n_items field of the signed_tree_head_v1_t in + * 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. */ -size_t signed_checksum32_ed25519_v1_getlen_signature(const signed_checksum32_ed25519_v1_t *inp); -/** Return the element at position 'idx' of the fixed array field - * signature of the signed_checksum32_ed25519_v1_t in 'inp'. +int signed_tree_head_v1_set_n_items(signed_tree_head_v1_t *inp, uint64_t val); +/** Return the length of the dynamic array holding the signatures + * field of the signed_tree_head_v1_t in 'inp'. */ -uint8_t signed_checksum32_ed25519_v1_get_signature(signed_checksum32_ed25519_v1_t *inp, size_t idx); -/** As signed_checksum32_ed25519_v1_get_signature, but take and return - * a const pointer +size_t signed_tree_head_v1_getlen_signatures(const signed_tree_head_v1_t *inp); +/** Return the element at position 'idx' of the dynamic array field + * signatures of the signed_tree_head_v1_t in 'inp'. */ -uint8_t signed_checksum32_ed25519_v1_getconst_signature(const signed_checksum32_ed25519_v1_t *inp, size_t idx); -/** Change the element at position 'idx' of the fixed array field - * signature of the signed_checksum32_ed25519_v1_t in 'inp', so that - * it will hold the value 'elt'. +struct sigident_ed25519_st * signed_tree_head_v1_get_signatures(signed_tree_head_v1_t *inp, size_t idx); +/** As signed_tree_head_v1_get_signatures, but take and return a const + * pointer */ -int signed_checksum32_ed25519_v1_set_signature(signed_checksum32_ed25519_v1_t *inp, size_t idx, uint8_t elt); -/** Return a pointer to the 64-element array field signature of 'inp'. + const struct sigident_ed25519_st * signed_tree_head_v1_getconst_signatures(const signed_tree_head_v1_t *inp, size_t idx); +/** Change the element at position 'idx' of the dynamic array field + * signatures of the signed_tree_head_v1_t in 'inp', so that it will + * hold the value 'elt'. Free the previous value, if any. */ -uint8_t * signed_checksum32_ed25519_v1_getarray_signature(signed_checksum32_ed25519_v1_t *inp); -/** As signed_checksum32_ed25519_v1_get_signature, but take and return - * a const pointer +int signed_tree_head_v1_set_signatures(signed_tree_head_v1_t *inp, size_t idx, struct sigident_ed25519_st * elt); +/** As signed_tree_head_v1_set_signatures, but does not free the + * previous value. */ -const uint8_t * signed_checksum32_ed25519_v1_getconstarray_signature(const signed_checksum32_ed25519_v1_t *inp); -/** Return the value of the namespace field of the - * signed_checksum32_ed25519_v1_t in 'inp' +int signed_tree_head_v1_set0_signatures(signed_tree_head_v1_t *inp, size_t idx, struct sigident_ed25519_st * elt); +/** Append a new element 'elt' to the dynamic array field signatures + * of the signed_tree_head_v1_t in 'inp'. */ -struct ed25519_v1_st * signed_checksum32_ed25519_v1_get_namespace(signed_checksum32_ed25519_v1_t *inp); -/** As signed_checksum32_ed25519_v1_get_namespace, but take and return - * a const pointer +int signed_tree_head_v1_add_signatures(signed_tree_head_v1_t *inp, struct sigident_ed25519_st * elt); +/** Return a pointer to the variable-length array field signatures of + * 'inp'. */ -const struct ed25519_v1_st * signed_checksum32_ed25519_v1_getconst_namespace(const signed_checksum32_ed25519_v1_t *inp); -/** Set the value of the namespace field of the - * signed_checksum32_ed25519_v1_t in 'inp' to 'val'. Free the old - * value if any. Steals the referenceto 'val'.Return 0 on success; - * return -1 and set the error code on 'inp' on failure. +struct sigident_ed25519_st * * signed_tree_head_v1_getarray_signatures(signed_tree_head_v1_t *inp); +/** As signed_tree_head_v1_get_signatures, but take and return a const + * pointer */ -int signed_checksum32_ed25519_v1_set_namespace(signed_checksum32_ed25519_v1_t *inp, struct ed25519_v1_st *val); -/** As signed_checksum32_ed25519_v1_set_namespace, but does not free - * the previous value. +const struct sigident_ed25519_st * const * signed_tree_head_v1_getconstarray_signatures(const signed_tree_head_v1_t *inp); +/** Change the length of the variable-length array field signatures of + * 'inp' to 'newlen'.Fill extra elements with NULL; free removed + * elements. Return 0 on success; return -1 and set the error code on + * 'inp' on failure. */ -int signed_checksum32_ed25519_v1_set0_namespace(signed_checksum32_ed25519_v1_t *inp, struct ed25519_v1_st *val); +int signed_tree_head_v1_setlen_signatures(signed_tree_head_v1_t *inp, size_t newlen); #endif diff --git a/trunnel/stfe.trunnel b/trunnel/stfe.trunnel index eb82942..8a26d92 100644 --- a/trunnel/stfe.trunnel +++ b/trunnel/stfe.trunnel @@ -1,11 +1,15 @@ +/* always POST for consistency? */ + +const MAGIC_V1 = 0x535446455f5f5631; /* "STFE__V1" */ + const T_GET_ENTRIES_V1 = 1; const T_GET_PROOF_BY_HASH_V1 = 2; const T_GET_CONSISTENCY_PROOF_V1 = 3; -const T_INCLUSION_PROOF_V1 = 4; -const T_CONSISTENCY_PROOF_V1 = 5; -const T_SIGNED_TREE_HEAD_V1 = 6; -const T_SIGNED_CHECKSUM32_ED25519_V1 = 7; -const T_ED25519_V1 = 8; + +const T_ENTRIES_V1 = 4; +const T_INCLUSION_PROOF_V1 = 5; +const T_CONSISTENCY_PROOF_V1 = 6; +const T_SIGNED_TREE_HEAD_V1 = 7; struct req_get_entries_v1 { u64 start_size; @@ -23,6 +27,7 @@ struct req_get_consistency_proof_v1 { }; struct request_v1 { + u64 magic IN [ MAGIC_V1 ]; u64 format IN [ T_GET_ENTRIES_V1, T_GET_PROOF_BY_HASH_V1, T_GET_CONSISTENCY_PROOF_V1 ]; union request[format] { @@ -33,53 +38,57 @@ struct request_v1 { }; } +struct sigident_ed25519 { + u8 signature[64]; + u8 identifier[32]; +}; + +struct hash { + u8 hash[32]; +}; + +struct signed_checksum32_ed25519 { + u8 checksum[32]; + u64 length IN [ 1..128 ]; + u8 identifier[length]; + u8 signature[64]; + u8 namespace[32]; +}; + +struct entries_v1 { + u64 magic IN [ MAGIC_V1 ]; + u64 format IN [ T_ENTRIES_V1 ]; + u64 n_items; + struct signed_checksum32_ed25519 checksums[n_items]; +}; + struct inclusion_proof_v1 { + u64 magic IN [ MAGIC_V1 ]; u64 format IN [ T_INCLUSION_PROOF_V1 ]; - struct ed25519_v1 identifier; + u8 identifier[32]; u64 tree_size; u64 leaf_index; - u64 length; /* TODO: constraint: multiple of 32 */ - u8 hashes[length]; + u64 n_items; + struct hash hashes[n_items]; }; struct consistency_proof_v1 { + u64 magic IN [ MAGIC_V1 ]; u64 format IN [ T_CONSISTENCY_PROOF_V1 ]; - struct ed25519_v1 identifier; + u8 identifier[32]; u64 old_size; u64 new_size; - u64 length; /* TODO: constraint: multiple of 32 */ - u8 hashes[length]; + u64 n_items; + struct hash hashes[n_items]; }; -/* Not used -struct sigident { - u8 signature[64]; - struct ed25519_v1 identifier; -}; */ - struct signed_tree_head_v1 { + u64 magic IN [ MAGIC_V1 ]; u64 format IN [ T_SIGNED_TREE_HEAD_V1 ]; u64 timestamp; u64 tree_size; u8 root_hash[32]; - u64 length; /* TODO: constraint: multiple of 104 */ - u8 sigident[length]; - /* Alternatively, if we would chose to replace length with n_items: u64 n_items; - struct sigident[n_items]; */ -}; - -struct signed_checksum32_ed25519_v1 { - u64 format IN [ T_SIGNED_CHECKSUM32_ED25519_V1 ]; - u8 checksum[32]; - u64 length IN [ 1..127 ]; /* The spec contradicts itself on this point -- is it 127 or 128? */ - u8 identifier[length]; - u8 signature[64]; - struct ed25519_v1 namespace; -}; - -struct ed25519_v1 { - u64 format IN [ T_ED25519_V1 ]; - u8 pubkey[32]; + struct sigident_ed25519 signatures[n_items]; }; -- cgit v1.2.3