diff options
author | David Goulet <dgoulet@torproject.org> | 2019-03-07 11:20:23 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2019-04-29 12:17:57 -0400 |
commit | 504e05b02999afb6a58ebe4af5770ca8dc136233 (patch) | |
tree | f0cb451d4a2ab2f55e4a287178bce6b1b99e8836 /src | |
parent | cede93b2d83fb810ec8b2152882732ed0a7481dc (diff) | |
download | tor-504e05b02999afb6a58ebe4af5770ca8dc136233.tar.gz tor-504e05b02999afb6a58ebe4af5770ca8dc136233.zip |
prop289: Use a 20 bytes digest instead of 4
To achieve such, this commit also changes the trunnel declaration to use a
union instead of a seperate object for the v1 data.
A constant is added for the digest length so we can use it within the SENDME
code giving us a single reference.
Part of #26288
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/or/sendme.c | 41 | ||||
-rw-r--r-- | src/test/test_sendme.c | 6 | ||||
-rw-r--r-- | src/trunnel/sendme.c | 349 | ||||
-rw-r--r-- | src/trunnel/sendme.h | 107 | ||||
-rw-r--r-- | src/trunnel/sendme.trunnel | 19 |
5 files changed, 146 insertions, 376 deletions
diff --git a/src/core/or/sendme.c b/src/core/or/sendme.c index 980684c827..a333b02b60 100644 --- a/src/core/or/sendme.c +++ b/src/core/or/sendme.c @@ -59,7 +59,8 @@ get_accept_min_version(void) SENDME_ACCEPT_MIN_VERSION_MAX); } -/* Return true iff the given decoded SENDME version 1 cell is valid. +/* Return true iff the given decoded SENDME version 1 cell is valid and + * matches the expected digest on the circuit. * * Validation is done by comparing the digest in the cell from the previous * cell we saw which tells us that the other side has in fact seen that cell. @@ -67,14 +68,12 @@ get_accept_min_version(void) static bool cell_v1_is_valid(const sendme_cell_t *cell, const circuit_t *circ) { - sendme_data_v1_t *data = NULL; + const uint8_t *cell_digest = NULL; tor_assert(cell); + tor_assert(circ); - if (sendme_data_v1_parse(&data, sendme_cell_getconstarray_data(cell), - sendme_cell_getlen_data(cell)) < 0) { - goto invalid; - } + cell_digest = sendme_cell_getconstarray_data_v1_digest(cell); /* We shouldn't have received this SENDME if we have no digests. Log at * protocol warning because it can be tricked by sending many SENDMEs @@ -94,8 +93,7 @@ cell_v1_is_valid(const sendme_cell_t *cell, const circuit_t *circ) /* Compare the digest with the one in the SENDME. This cell is invalid * without a perfect match. */ - if (tor_memcmp(digest, sendme_data_v1_getconstarray_digest(data), - sendme_data_v1_getlen_digest(data))) { + if (tor_memcmp(digest, cell_digest, TRUNNEL_SENDME_V1_DIGEST_LEN)) { tor_free(digest); log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "SENDME v1 cell digest do not match."); @@ -105,10 +103,8 @@ cell_v1_is_valid(const sendme_cell_t *cell, const circuit_t *circ) } /* Validated SENDME v1 cell. */ - sendme_data_v1_free(data); return 1; invalid: - sendme_data_v1_free(data); return 0; } @@ -213,39 +209,26 @@ build_cell_payload_v1(crypto_digest_t *cell_digest, uint8_t *payload) { ssize_t len = -1; sendme_cell_t *cell = NULL; - sendme_data_v1_t *data = NULL; tor_assert(cell_digest); tor_assert(payload); cell = sendme_cell_new(); - data = sendme_data_v1_new(); /* Building a payload for version 1. */ sendme_cell_set_version(cell, 0x01); + /* Set the data length field for v1. */ + sendme_cell_set_data_len(cell, TRUNNEL_SENDME_V1_DIGEST_LEN); /* Copy the digest into the data payload. */ crypto_digest_get_digest(cell_digest, - (char *) sendme_data_v1_getarray_digest(data), - sendme_data_v1_getlen_digest(data)); - - /* Set the length of the data in the cell payload. It is the encoded length - * of the v1 data object. */ - sendme_cell_setlen_data(cell, sendme_data_v1_encoded_len(data)); - /* Encode into the cell's data field using its current length just set. */ - if (sendme_data_v1_encode(sendme_cell_getarray_data(cell), - sendme_cell_getlen_data(cell), data) < 0) { - goto end; - } - /* Set the DATA_LEN field to what we've just encoded. */ - sendme_cell_set_data_len(cell, sendme_cell_getlen_data(cell)); + (char *) sendme_cell_getarray_data_v1_digest(cell), + sendme_cell_get_data_len(cell)); /* Finally, encode the cell into the payload. */ len = sendme_cell_encode(payload, RELAY_PAYLOAD_SIZE, cell); - end: sendme_cell_free(cell); - sendme_data_v1_free(data); return len; } @@ -566,9 +549,9 @@ sendme_note_cell_digest(circuit_t *circ) * recorded. It should never happen in theory as we always record the last * digest for the v1 SENDME. */ if (TO_OR_CIRCUIT(circ)->crypto.sendme_digest) { - digest = tor_malloc_zero(4); + digest = tor_malloc_zero(TRUNNEL_SENDME_V1_DIGEST_LEN); crypto_digest_get_digest(TO_OR_CIRCUIT(circ)->crypto.sendme_digest, - (char *) digest, 4); + (char *) digest, TRUNNEL_SENDME_V1_DIGEST_LEN); if (circ->sendme_last_digests == NULL) { circ->sendme_last_digests = smartlist_new(); } diff --git a/src/test/test_sendme.c b/src/test/test_sendme.c index ad6aac6c0c..92f478df0e 100644 --- a/src/test/test_sendme.c +++ b/src/test/test_sendme.c @@ -156,12 +156,12 @@ test_v1_build_cell(void *arg) circ = TO_CIRCUIT(or_circ); cell_digest = crypto_digest_new(); - crypto_digest_add_bytes(cell_digest, "AAAA", 4); + crypto_digest_add_bytes(cell_digest, "AAAAAAAAAAAAAAAAAAAA", 20); tt_assert(cell_digest); - /* SENDME v1 payload is 7 bytes. See spec. */ + /* SENDME v1 payload is 3 bytes + 20 bytes digest. See spec. */ ret = build_cell_payload_v1(cell_digest, payload); - tt_int_op(ret, OP_EQ, 7); + tt_int_op(ret, OP_EQ, 23); /* Validation. */ diff --git a/src/trunnel/sendme.c b/src/trunnel/sendme.c index 08f9ed5e91..262b915234 100644 --- a/src/trunnel/sendme.c +++ b/src/trunnel/sendme.c @@ -43,8 +43,6 @@ static void sendme_cell_clear(sendme_cell_t *obj) { (void) obj; - TRUNNEL_DYNARRAY_WIPE(&obj->data); - TRUNNEL_DYNARRAY_CLEAR(&obj->data); } void @@ -84,71 +82,40 @@ sendme_cell_set_data_len(sendme_cell_t *inp, uint16_t val) return 0; } size_t -sendme_cell_getlen_data(const sendme_cell_t *inp) +sendme_cell_getlen_data_v1_digest(const sendme_cell_t *inp) { - return TRUNNEL_DYNARRAY_LEN(&inp->data); + (void)inp; return TRUNNEL_SENDME_V1_DIGEST_LEN; } uint8_t -sendme_cell_get_data(sendme_cell_t *inp, size_t idx) +sendme_cell_get_data_v1_digest(sendme_cell_t *inp, size_t idx) { - return TRUNNEL_DYNARRAY_GET(&inp->data, idx); + trunnel_assert(idx < TRUNNEL_SENDME_V1_DIGEST_LEN); + return inp->data_v1_digest[idx]; } uint8_t -sendme_cell_getconst_data(const sendme_cell_t *inp, size_t idx) +sendme_cell_getconst_data_v1_digest(const sendme_cell_t *inp, size_t idx) { - return sendme_cell_get_data((sendme_cell_t*)inp, idx); + return sendme_cell_get_data_v1_digest((sendme_cell_t*)inp, idx); } int -sendme_cell_set_data(sendme_cell_t *inp, size_t idx, uint8_t elt) +sendme_cell_set_data_v1_digest(sendme_cell_t *inp, size_t idx, uint8_t elt) { - TRUNNEL_DYNARRAY_SET(&inp->data, idx, elt); + trunnel_assert(idx < TRUNNEL_SENDME_V1_DIGEST_LEN); + inp->data_v1_digest[idx] = elt; return 0; } -int -sendme_cell_add_data(sendme_cell_t *inp, uint8_t elt) -{ -#if SIZE_MAX >= UINT16_MAX - if (inp->data.n_ == UINT16_MAX) - goto trunnel_alloc_failed; -#endif - TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->data, elt, {}); - return 0; - trunnel_alloc_failed: - TRUNNEL_SET_ERROR_CODE(inp); - return -1; -} uint8_t * -sendme_cell_getarray_data(sendme_cell_t *inp) +sendme_cell_getarray_data_v1_digest(sendme_cell_t *inp) { - return inp->data.elts_; + return inp->data_v1_digest; } const uint8_t * -sendme_cell_getconstarray_data(const sendme_cell_t *inp) +sendme_cell_getconstarray_data_v1_digest(const sendme_cell_t *inp) { - return (const uint8_t *)sendme_cell_getarray_data((sendme_cell_t*)inp); -} -int -sendme_cell_setlen_data(sendme_cell_t *inp, size_t newlen) -{ - uint8_t *newptr; -#if UINT16_MAX < SIZE_MAX - if (newlen > UINT16_MAX) - goto trunnel_alloc_failed; -#endif - newptr = trunnel_dynarray_setlen(&inp->data.allocated_, - &inp->data.n_, inp->data.elts_, newlen, - sizeof(inp->data.elts_[0]), (trunnel_free_fn_t) NULL, - &inp->trunnel_error_code_); - if (newlen != 0 && newptr == NULL) - goto trunnel_alloc_failed; - inp->data.elts_ = newptr; - return 0; - trunnel_alloc_failed: - TRUNNEL_SET_ERROR_CODE(inp); - return -1; + return (const uint8_t *)sendme_cell_getarray_data_v1_digest((sendme_cell_t*)inp); } const char * sendme_cell_check(const sendme_cell_t *obj) @@ -159,8 +126,18 @@ sendme_cell_check(const sendme_cell_t *obj) return "A set function failed on this object"; if (! (obj->version == 0 || obj->version == 1)) return "Integer out of bounds"; - if (TRUNNEL_DYNARRAY_LEN(&obj->data) != obj->data_len) - return "Length mismatch for data"; + switch (obj->version) { + + case 0: + break; + + case 1: + break; + + default: + return "Bad tag for union"; + break; + } return NULL; } @@ -178,9 +155,21 @@ sendme_cell_encoded_len(const sendme_cell_t *obj) /* Length of u16 data_len */ result += 2; + switch (obj->version) { - /* Length of u8 data[data_len] */ - result += TRUNNEL_DYNARRAY_LEN(&obj->data); + case 0: + break; + + case 1: + + /* Length of u8 data_v1_digest[TRUNNEL_SENDME_V1_DIGEST_LEN] */ + result += TRUNNEL_SENDME_V1_DIGEST_LEN; + break; + + default: + trunnel_assert(0); + break; + } return result; } int @@ -201,6 +190,8 @@ sendme_cell_encode(uint8_t *output, const size_t avail, const sendme_cell_t *obj const ssize_t encoded_len = sendme_cell_encoded_len(obj); #endif + uint8_t *backptr_data_len = NULL; + if (NULL != (msg = sendme_cell_check(obj))) goto check_failed; @@ -216,22 +207,43 @@ sendme_cell_encode(uint8_t *output, const size_t avail, const sendme_cell_t *obj written += 1; ptr += 1; /* Encode u16 data_len */ + backptr_data_len = ptr; trunnel_assert(written <= avail); if (avail - written < 2) goto truncated; trunnel_set_uint16(ptr, trunnel_htons(obj->data_len)); written += 2; ptr += 2; - - /* Encode u8 data[data_len] */ { - size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->data); - trunnel_assert(obj->data_len == elt_len); + size_t written_before_union = written; + + /* Encode union data[version] */ trunnel_assert(written <= avail); - if (avail - written < elt_len) - goto truncated; - if (elt_len) - memcpy(ptr, obj->data.elts_, elt_len); - written += elt_len; ptr += elt_len; + switch (obj->version) { + + case 0: + break; + + case 1: + + /* Encode u8 data_v1_digest[TRUNNEL_SENDME_V1_DIGEST_LEN] */ + trunnel_assert(written <= avail); + if (avail - written < TRUNNEL_SENDME_V1_DIGEST_LEN) + goto truncated; + memcpy(ptr, obj->data_v1_digest, TRUNNEL_SENDME_V1_DIGEST_LEN); + written += TRUNNEL_SENDME_V1_DIGEST_LEN; ptr += TRUNNEL_SENDME_V1_DIGEST_LEN; + break; + + default: + trunnel_assert(0); + break; + } + /* Write the length field back to data_len */ + trunnel_assert(written >= written_before_union); +#if UINT16_MAX < SIZE_MAX + if (written - written_before_union > UINT16_MAX) + goto check_failed; +#endif + trunnel_set_uint16(backptr_data_len, trunnel_htons(written - written_before_union)); } @@ -279,21 +291,41 @@ sendme_cell_parse_into(sendme_cell_t *obj, const uint8_t *input, const size_t le CHECK_REMAINING(2, truncated); obj->data_len = trunnel_ntohs(trunnel_get_uint16(ptr)); remaining -= 2; ptr += 2; - - /* Parse u8 data[data_len] */ - CHECK_REMAINING(obj->data_len, truncated); - TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->data, obj->data_len, {}); - obj->data.n_ = obj->data_len; - if (obj->data_len) - memcpy(obj->data.elts_, ptr, obj->data_len); - ptr += obj->data_len; remaining -= obj->data_len; + { + size_t remaining_after; + CHECK_REMAINING(obj->data_len, truncated); + remaining_after = remaining - obj->data_len; + remaining = obj->data_len; + + /* Parse union data[version] */ + switch (obj->version) { + + case 0: + /* Skip to end of union */ + ptr += remaining; remaining = 0; + break; + + case 1: + + /* Parse u8 data_v1_digest[TRUNNEL_SENDME_V1_DIGEST_LEN] */ + CHECK_REMAINING(TRUNNEL_SENDME_V1_DIGEST_LEN, fail); + memcpy(obj->data_v1_digest, ptr, TRUNNEL_SENDME_V1_DIGEST_LEN); + remaining -= TRUNNEL_SENDME_V1_DIGEST_LEN; ptr += TRUNNEL_SENDME_V1_DIGEST_LEN; + break; + + default: + goto fail; + break; + } + if (remaining != 0) + goto fail; + remaining = remaining_after; + } trunnel_assert(ptr + remaining == input + len_in); return len_in - remaining; truncated: return -2; - trunnel_alloc_failed: - return -1; fail: result = -1; return result; @@ -313,180 +345,3 @@ sendme_cell_parse(sendme_cell_t **output, const uint8_t *input, const size_t len } return result; } -sendme_data_v1_t * -sendme_data_v1_new(void) -{ - sendme_data_v1_t *val = trunnel_calloc(1, sizeof(sendme_data_v1_t)); - if (NULL == val) - return NULL; - return val; -} - -/** Release all storage held inside 'obj', but do not free 'obj'. - */ -static void -sendme_data_v1_clear(sendme_data_v1_t *obj) -{ - (void) obj; -} - -void -sendme_data_v1_free(sendme_data_v1_t *obj) -{ - if (obj == NULL) - return; - sendme_data_v1_clear(obj); - trunnel_memwipe(obj, sizeof(sendme_data_v1_t)); - trunnel_free_(obj); -} - -size_t -sendme_data_v1_getlen_digest(const sendme_data_v1_t *inp) -{ - (void)inp; return 4; -} - -uint8_t -sendme_data_v1_get_digest(sendme_data_v1_t *inp, size_t idx) -{ - trunnel_assert(idx < 4); - return inp->digest[idx]; -} - -uint8_t -sendme_data_v1_getconst_digest(const sendme_data_v1_t *inp, size_t idx) -{ - return sendme_data_v1_get_digest((sendme_data_v1_t*)inp, idx); -} -int -sendme_data_v1_set_digest(sendme_data_v1_t *inp, size_t idx, uint8_t elt) -{ - trunnel_assert(idx < 4); - inp->digest[idx] = elt; - return 0; -} - -uint8_t * -sendme_data_v1_getarray_digest(sendme_data_v1_t *inp) -{ - return inp->digest; -} -const uint8_t * -sendme_data_v1_getconstarray_digest(const sendme_data_v1_t *inp) -{ - return (const uint8_t *)sendme_data_v1_getarray_digest((sendme_data_v1_t*)inp); -} -const char * -sendme_data_v1_check(const sendme_data_v1_t *obj) -{ - if (obj == NULL) - return "Object was NULL"; - if (obj->trunnel_error_code_) - return "A set function failed on this object"; - return NULL; -} - -ssize_t -sendme_data_v1_encoded_len(const sendme_data_v1_t *obj) -{ - ssize_t result = 0; - - if (NULL != sendme_data_v1_check(obj)) - return -1; - - - /* Length of u8 digest[4] */ - result += 4; - return result; -} -int -sendme_data_v1_clear_errors(sendme_data_v1_t *obj) -{ - int r = obj->trunnel_error_code_; - obj->trunnel_error_code_ = 0; - return r; -} -ssize_t -sendme_data_v1_encode(uint8_t *output, const size_t avail, const sendme_data_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 = sendme_data_v1_encoded_len(obj); -#endif - - if (NULL != (msg = sendme_data_v1_check(obj))) - goto check_failed; - -#ifdef TRUNNEL_CHECK_ENCODED_LEN - trunnel_assert(encoded_len >= 0); -#endif - - /* Encode u8 digest[4] */ - trunnel_assert(written <= avail); - if (avail - written < 4) - goto truncated; - memcpy(ptr, obj->digest, 4); - written += 4; ptr += 4; - - - 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 sendme_data_v1_parse(), but do not allocate the output object. - */ -static ssize_t -sendme_data_v1_parse_into(sendme_data_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 u8 digest[4] */ - CHECK_REMAINING(4, truncated); - memcpy(obj->digest, ptr, 4); - remaining -= 4; ptr += 4; - trunnel_assert(ptr + remaining == input + len_in); - return len_in - remaining; - - truncated: - return -2; -} - -ssize_t -sendme_data_v1_parse(sendme_data_v1_t **output, const uint8_t *input, const size_t len_in) -{ - ssize_t result; - *output = sendme_data_v1_new(); - if (NULL == *output) - return -1; - result = sendme_data_v1_parse_into(*output, input, len_in); - if (result < 0) { - sendme_data_v1_free(*output); - *output = NULL; - } - return result; -} diff --git a/src/trunnel/sendme.h b/src/trunnel/sendme.h index 8207cb56f7..f3c3dd78c4 100644 --- a/src/trunnel/sendme.h +++ b/src/trunnel/sendme.h @@ -8,22 +8,16 @@ #include <stdint.h> #include "trunnel.h" +#define TRUNNEL_SENDME_V1_DIGEST_LEN 20 #if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SENDME_CELL) struct sendme_cell_st { uint8_t version; uint16_t data_len; - TRUNNEL_DYNARRAY_HEAD(, uint8_t) data; + uint8_t data_v1_digest[TRUNNEL_SENDME_V1_DIGEST_LEN]; uint8_t trunnel_error_code_; }; #endif typedef struct sendme_cell_st sendme_cell_t; -#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_SENDME_DATA_V1) -struct sendme_data_v1_st { - uint8_t digest[4]; - uint8_t trunnel_error_code_; -}; -#endif -typedef struct sendme_data_v1_st sendme_data_v1_t; /** Return a newly allocated sendme_cell with all elements set to * zero. */ @@ -77,94 +71,31 @@ uint16_t sendme_cell_get_data_len(const sendme_cell_t *inp); * 'inp' on failure. */ int sendme_cell_set_data_len(sendme_cell_t *inp, uint16_t val); -/** Return the length of the dynamic array holding the data field of - * the sendme_cell_t in 'inp'. - */ -size_t sendme_cell_getlen_data(const sendme_cell_t *inp); -/** Return the element at position 'idx' of the dynamic array field - * data of the sendme_cell_t in 'inp'. - */ -uint8_t sendme_cell_get_data(sendme_cell_t *inp, size_t idx); -/** As sendme_cell_get_data, but take and return a const pointer - */ -uint8_t sendme_cell_getconst_data(const sendme_cell_t *inp, size_t idx); -/** Change the element at position 'idx' of the dynamic array field - * data of the sendme_cell_t in 'inp', so that it will hold the value - * 'elt'. - */ -int sendme_cell_set_data(sendme_cell_t *inp, size_t idx, uint8_t elt); -/** Append a new element 'elt' to the dynamic array field data of the - * sendme_cell_t in 'inp'. - */ -int sendme_cell_add_data(sendme_cell_t *inp, uint8_t elt); -/** Return a pointer to the variable-length array field data of 'inp'. - */ -uint8_t * sendme_cell_getarray_data(sendme_cell_t *inp); -/** As sendme_cell_get_data, but take and return a const pointer - */ -const uint8_t * sendme_cell_getconstarray_data(const sendme_cell_t *inp); -/** Change the length of the variable-length array field data 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 sendme_cell_setlen_data(sendme_cell_t *inp, size_t newlen); -/** Return a newly allocated sendme_data_v1 with all elements set to - * zero. - */ -sendme_data_v1_t *sendme_data_v1_new(void); -/** Release all storage held by the sendme_data_v1 in 'victim'. (Do - * nothing if 'victim' is NULL.) - */ -void sendme_data_v1_free(sendme_data_v1_t *victim); -/** Try to parse a sendme_data_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 - * sendme_data_v1_t. On failure, return -2 if the input appears - * truncated, and -1 if the input is otherwise invalid. - */ -ssize_t sendme_data_v1_parse(sendme_data_v1_t **output, const uint8_t *input, const size_t len_in); -/** Return the number of bytes we expect to need to encode the - * sendme_data_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 sendme_data_v1_encoded_len(const sendme_data_v1_t *obj); -/** Try to encode the sendme_data_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 sendme_data_v1_encode(uint8_t *output, size_t avail, const sendme_data_v1_t *input); -/** Check whether the internal state of the sendme_data_v1 in 'obj' is - * consistent. Return NULL if it is, and a short message if it is not. - */ -const char *sendme_data_v1_check(const sendme_data_v1_t *obj); -/** Clear any errors that were set on the object 'obj' by its setter - * functions. Return true iff errors were cleared. - */ -int sendme_data_v1_clear_errors(sendme_data_v1_t *obj); -/** Return the (constant) length of the array holding the digest field - * of the sendme_data_v1_t in 'inp'. +/** Return the (constant) length of the array holding the + * data_v1_digest field of the sendme_cell_t in 'inp'. */ -size_t sendme_data_v1_getlen_digest(const sendme_data_v1_t *inp); +size_t sendme_cell_getlen_data_v1_digest(const sendme_cell_t *inp); /** Return the element at position 'idx' of the fixed array field - * digest of the sendme_data_v1_t in 'inp'. + * data_v1_digest of the sendme_cell_t in 'inp'. */ -uint8_t sendme_data_v1_get_digest(sendme_data_v1_t *inp, size_t idx); -/** As sendme_data_v1_get_digest, but take and return a const pointer +uint8_t sendme_cell_get_data_v1_digest(sendme_cell_t *inp, size_t idx); +/** As sendme_cell_get_data_v1_digest, but take and return a const + * pointer */ -uint8_t sendme_data_v1_getconst_digest(const sendme_data_v1_t *inp, size_t idx); +uint8_t sendme_cell_getconst_data_v1_digest(const sendme_cell_t *inp, size_t idx); /** Change the element at position 'idx' of the fixed array field - * digest of the sendme_data_v1_t in 'inp', so that it will hold the - * value 'elt'. + * data_v1_digest of the sendme_cell_t in 'inp', so that it will hold + * the value 'elt'. */ -int sendme_data_v1_set_digest(sendme_data_v1_t *inp, size_t idx, uint8_t elt); -/** Return a pointer to the 4-element array field digest of 'inp'. +int sendme_cell_set_data_v1_digest(sendme_cell_t *inp, size_t idx, uint8_t elt); +/** Return a pointer to the TRUNNEL_SENDME_V1_DIGEST_LEN-element array + * field data_v1_digest of 'inp'. */ -uint8_t * sendme_data_v1_getarray_digest(sendme_data_v1_t *inp); -/** As sendme_data_v1_get_digest, but take and return a const pointer +uint8_t * sendme_cell_getarray_data_v1_digest(sendme_cell_t *inp); +/** As sendme_cell_get_data_v1_digest, but take and return a const + * pointer */ -const uint8_t * sendme_data_v1_getconstarray_digest(const sendme_data_v1_t *inp); +const uint8_t * sendme_cell_getconstarray_data_v1_digest(const sendme_cell_t *inp); #endif diff --git a/src/trunnel/sendme.trunnel b/src/trunnel/sendme.trunnel index 7294a09b47..300963e679 100644 --- a/src/trunnel/sendme.trunnel +++ b/src/trunnel/sendme.trunnel @@ -1,18 +1,19 @@ /* This file contains the SENDME cell definition. */ +/* v1 digest length in bytes. */ +const TRUNNEL_SENDME_V1_DIGEST_LEN = 20; + +/* SENDME cell declaration. */ struct sendme_cell { /* Version field. */ u8 version IN [0x00, 0x01]; - /* The data content depends on the version. */ + /* Length of data contained in this cell. */ u16 data_len; - u8 data[data_len]; -} -/* SENDME version 0. No data. */ - -/* SENDME version 1. Authenticated with digest. */ -struct sendme_data_v1 { - /* A 4 bytes digest. */ - u8 digest[4]; + /* The data content depends on the version. */ + union data[version] with length data_len { + 0x00: ignore; + 0x01: u8 v1_digest[TRUNNEL_SENDME_V1_DIGEST_LEN]; + }; } |