Trunnel-side: start migrating extend/extend2 to trunnel
This commit is contained in:
parent
b5e75ae7dd
commit
1be671f505
|
@ -28,6 +28,281 @@ int edcert_deadcode_dummy__ = 0;
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
create2_cell_body_t *
|
||||
create2_cell_body_new(void)
|
||||
{
|
||||
create2_cell_body_t *val = trunnel_calloc(1, sizeof(create2_cell_body_t));
|
||||
if (NULL == val)
|
||||
return NULL;
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Release all storage held inside 'obj', but do not free 'obj'.
|
||||
*/
|
||||
static void
|
||||
create2_cell_body_clear(create2_cell_body_t *obj)
|
||||
{
|
||||
(void) obj;
|
||||
TRUNNEL_DYNARRAY_WIPE(&obj->handshake_data);
|
||||
TRUNNEL_DYNARRAY_CLEAR(&obj->handshake_data);
|
||||
}
|
||||
|
||||
void
|
||||
create2_cell_body_free(create2_cell_body_t *obj)
|
||||
{
|
||||
if (obj == NULL)
|
||||
return;
|
||||
create2_cell_body_clear(obj);
|
||||
trunnel_memwipe(obj, sizeof(create2_cell_body_t));
|
||||
trunnel_free_(obj);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
create2_cell_body_get_handshake_type(create2_cell_body_t *inp)
|
||||
{
|
||||
return inp->handshake_type;
|
||||
}
|
||||
int
|
||||
create2_cell_body_set_handshake_type(create2_cell_body_t *inp, uint16_t val)
|
||||
{
|
||||
inp->handshake_type = val;
|
||||
return 0;
|
||||
}
|
||||
uint16_t
|
||||
create2_cell_body_get_handshake_len(create2_cell_body_t *inp)
|
||||
{
|
||||
return inp->handshake_len;
|
||||
}
|
||||
int
|
||||
create2_cell_body_set_handshake_len(create2_cell_body_t *inp, uint16_t val)
|
||||
{
|
||||
inp->handshake_len = val;
|
||||
return 0;
|
||||
}
|
||||
size_t
|
||||
create2_cell_body_getlen_handshake_data(const create2_cell_body_t *inp)
|
||||
{
|
||||
return TRUNNEL_DYNARRAY_LEN(&inp->handshake_data);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
create2_cell_body_get_handshake_data(create2_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
return TRUNNEL_DYNARRAY_GET(&inp->handshake_data, idx);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
create2_cell_body_getconst_handshake_data(const create2_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
return create2_cell_body_get_handshake_data((create2_cell_body_t*)inp, idx);
|
||||
}
|
||||
int
|
||||
create2_cell_body_set_handshake_data(create2_cell_body_t *inp, size_t idx, uint8_t elt)
|
||||
{
|
||||
TRUNNEL_DYNARRAY_SET(&inp->handshake_data, idx, elt);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
create2_cell_body_add_handshake_data(create2_cell_body_t *inp, uint8_t elt)
|
||||
{
|
||||
#if SIZE_MAX >= UINT16_MAX
|
||||
if (inp->handshake_data.n_ == UINT16_MAX)
|
||||
goto trunnel_alloc_failed;
|
||||
#endif
|
||||
TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->handshake_data, elt, {});
|
||||
return 0;
|
||||
trunnel_alloc_failed:
|
||||
TRUNNEL_SET_ERROR_CODE(inp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
create2_cell_body_getarray_handshake_data(create2_cell_body_t *inp)
|
||||
{
|
||||
return inp->handshake_data.elts_;
|
||||
}
|
||||
const uint8_t *
|
||||
create2_cell_body_getconstarray_handshake_data(const create2_cell_body_t *inp)
|
||||
{
|
||||
return (const uint8_t *)create2_cell_body_getarray_handshake_data((create2_cell_body_t*)inp);
|
||||
}
|
||||
int
|
||||
create2_cell_body_setlen_handshake_data(create2_cell_body_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->handshake_data.allocated_,
|
||||
&inp->handshake_data.n_, inp->handshake_data.elts_, newlen,
|
||||
sizeof(inp->handshake_data.elts_[0]), (trunnel_free_fn_t) NULL,
|
||||
&inp->trunnel_error_code_);
|
||||
if (newlen != 0 && newptr == NULL)
|
||||
goto trunnel_alloc_failed;
|
||||
inp->handshake_data.elts_ = newptr;
|
||||
return 0;
|
||||
trunnel_alloc_failed:
|
||||
TRUNNEL_SET_ERROR_CODE(inp);
|
||||
return -1;
|
||||
}
|
||||
const char *
|
||||
create2_cell_body_check(const create2_cell_body_t *obj)
|
||||
{
|
||||
if (obj == NULL)
|
||||
return "Object was NULL";
|
||||
if (obj->trunnel_error_code_)
|
||||
return "A set function failed on this object";
|
||||
if (TRUNNEL_DYNARRAY_LEN(&obj->handshake_data) != obj->handshake_len)
|
||||
return "Length mismatch for handshake_data";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
create2_cell_body_encoded_len(const create2_cell_body_t *obj)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
|
||||
if (NULL != create2_cell_body_check(obj))
|
||||
return -1;
|
||||
|
||||
|
||||
/* Length of u16 handshake_type */
|
||||
result += 2;
|
||||
|
||||
/* Length of u16 handshake_len */
|
||||
result += 2;
|
||||
|
||||
/* Length of u8 handshake_data[handshake_len] */
|
||||
result += TRUNNEL_DYNARRAY_LEN(&obj->handshake_data);
|
||||
return result;
|
||||
}
|
||||
int
|
||||
create2_cell_body_clear_errors(create2_cell_body_t *obj)
|
||||
{
|
||||
int r = obj->trunnel_error_code_;
|
||||
obj->trunnel_error_code_ = 0;
|
||||
return r;
|
||||
}
|
||||
ssize_t
|
||||
create2_cell_body_encode(uint8_t *output, const size_t avail, const create2_cell_body_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 = create2_cell_body_encoded_len(obj);
|
||||
#endif
|
||||
|
||||
if (NULL != (msg = create2_cell_body_check(obj)))
|
||||
goto check_failed;
|
||||
|
||||
#ifdef TRUNNEL_CHECK_ENCODED_LEN
|
||||
trunnel_assert(encoded_len >= 0);
|
||||
#endif
|
||||
|
||||
/* Encode u16 handshake_type */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 2)
|
||||
goto truncated;
|
||||
trunnel_set_uint16(ptr, trunnel_htons(obj->handshake_type));
|
||||
written += 2; ptr += 2;
|
||||
|
||||
/* Encode u16 handshake_len */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 2)
|
||||
goto truncated;
|
||||
trunnel_set_uint16(ptr, trunnel_htons(obj->handshake_len));
|
||||
written += 2; ptr += 2;
|
||||
|
||||
/* Encode u8 handshake_data[handshake_len] */
|
||||
{
|
||||
size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->handshake_data);
|
||||
trunnel_assert(obj->handshake_len == elt_len);
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < elt_len)
|
||||
goto truncated;
|
||||
if (elt_len)
|
||||
memcpy(ptr, obj->handshake_data.elts_, elt_len);
|
||||
written += elt_len; ptr += elt_len;
|
||||
}
|
||||
|
||||
|
||||
trunnel_assert(ptr == output + written);
|
||||
#ifdef TRUNNEL_CHECK_ENCODED_LEN
|
||||
{
|
||||
trunnel_assert(encoded_len >= 0);
|
||||
trunnel_assert((size_t)encoded_len == written);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return written;
|
||||
|
||||
truncated:
|
||||
result = -2;
|
||||
goto fail;
|
||||
check_failed:
|
||||
(void)msg;
|
||||
result = -1;
|
||||
goto fail;
|
||||
fail:
|
||||
trunnel_assert(result < 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** As create2_cell_body_parse(), but do not allocate the output
|
||||
* object.
|
||||
*/
|
||||
static ssize_t
|
||||
create2_cell_body_parse_into(create2_cell_body_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 u16 handshake_type */
|
||||
CHECK_REMAINING(2, truncated);
|
||||
obj->handshake_type = trunnel_ntohs(trunnel_get_uint16(ptr));
|
||||
remaining -= 2; ptr += 2;
|
||||
|
||||
/* Parse u16 handshake_len */
|
||||
CHECK_REMAINING(2, truncated);
|
||||
obj->handshake_len = trunnel_ntohs(trunnel_get_uint16(ptr));
|
||||
remaining -= 2; ptr += 2;
|
||||
|
||||
/* Parse u8 handshake_data[handshake_len] */
|
||||
CHECK_REMAINING(obj->handshake_len, truncated);
|
||||
TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->handshake_data, obj->handshake_len, {});
|
||||
obj->handshake_data.n_ = obj->handshake_len;
|
||||
if (obj->handshake_len)
|
||||
memcpy(obj->handshake_data.elts_, ptr, obj->handshake_len);
|
||||
ptr += obj->handshake_len; remaining -= obj->handshake_len;
|
||||
trunnel_assert(ptr + remaining == input + len_in);
|
||||
return len_in - remaining;
|
||||
|
||||
truncated:
|
||||
return -2;
|
||||
trunnel_alloc_failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
create2_cell_body_parse(create2_cell_body_t **output, const uint8_t *input, const size_t len_in)
|
||||
{
|
||||
ssize_t result;
|
||||
*output = create2_cell_body_new();
|
||||
if (NULL == *output)
|
||||
return -1;
|
||||
result = create2_cell_body_parse_into(*output, input, len_in);
|
||||
if (result < 0) {
|
||||
create2_cell_body_free(*output);
|
||||
*output = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
ed25519_cert_extension_t *
|
||||
ed25519_cert_extension_new(void)
|
||||
{
|
||||
|
@ -430,6 +705,287 @@ ed25519_cert_extension_parse(ed25519_cert_extension_t **output, const uint8_t *i
|
|||
}
|
||||
return result;
|
||||
}
|
||||
extend1_cell_body_t *
|
||||
extend1_cell_body_new(void)
|
||||
{
|
||||
extend1_cell_body_t *val = trunnel_calloc(1, sizeof(extend1_cell_body_t));
|
||||
if (NULL == val)
|
||||
return NULL;
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Release all storage held inside 'obj', but do not free 'obj'.
|
||||
*/
|
||||
static void
|
||||
extend1_cell_body_clear(extend1_cell_body_t *obj)
|
||||
{
|
||||
(void) obj;
|
||||
}
|
||||
|
||||
void
|
||||
extend1_cell_body_free(extend1_cell_body_t *obj)
|
||||
{
|
||||
if (obj == NULL)
|
||||
return;
|
||||
extend1_cell_body_clear(obj);
|
||||
trunnel_memwipe(obj, sizeof(extend1_cell_body_t));
|
||||
trunnel_free_(obj);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
extend1_cell_body_get_ipv4addr(extend1_cell_body_t *inp)
|
||||
{
|
||||
return inp->ipv4addr;
|
||||
}
|
||||
int
|
||||
extend1_cell_body_set_ipv4addr(extend1_cell_body_t *inp, uint32_t val)
|
||||
{
|
||||
inp->ipv4addr = val;
|
||||
return 0;
|
||||
}
|
||||
uint16_t
|
||||
extend1_cell_body_get_port(extend1_cell_body_t *inp)
|
||||
{
|
||||
return inp->port;
|
||||
}
|
||||
int
|
||||
extend1_cell_body_set_port(extend1_cell_body_t *inp, uint16_t val)
|
||||
{
|
||||
inp->port = val;
|
||||
return 0;
|
||||
}
|
||||
size_t
|
||||
extend1_cell_body_getlen_onionskin(const extend1_cell_body_t *inp)
|
||||
{
|
||||
(void)inp; return 186;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
extend1_cell_body_get_onionskin(extend1_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
trunnel_assert(idx < 186);
|
||||
return inp->onionskin[idx];
|
||||
}
|
||||
|
||||
uint8_t
|
||||
extend1_cell_body_getconst_onionskin(const extend1_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
return extend1_cell_body_get_onionskin((extend1_cell_body_t*)inp, idx);
|
||||
}
|
||||
int
|
||||
extend1_cell_body_set_onionskin(extend1_cell_body_t *inp, size_t idx, uint8_t elt)
|
||||
{
|
||||
trunnel_assert(idx < 186);
|
||||
inp->onionskin[idx] = elt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
extend1_cell_body_getarray_onionskin(extend1_cell_body_t *inp)
|
||||
{
|
||||
return inp->onionskin;
|
||||
}
|
||||
const uint8_t *
|
||||
extend1_cell_body_getconstarray_onionskin(const extend1_cell_body_t *inp)
|
||||
{
|
||||
return (const uint8_t *)extend1_cell_body_getarray_onionskin((extend1_cell_body_t*)inp);
|
||||
}
|
||||
size_t
|
||||
extend1_cell_body_getlen_identity(const extend1_cell_body_t *inp)
|
||||
{
|
||||
(void)inp; return 20;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
extend1_cell_body_get_identity(extend1_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
trunnel_assert(idx < 20);
|
||||
return inp->identity[idx];
|
||||
}
|
||||
|
||||
uint8_t
|
||||
extend1_cell_body_getconst_identity(const extend1_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
return extend1_cell_body_get_identity((extend1_cell_body_t*)inp, idx);
|
||||
}
|
||||
int
|
||||
extend1_cell_body_set_identity(extend1_cell_body_t *inp, size_t idx, uint8_t elt)
|
||||
{
|
||||
trunnel_assert(idx < 20);
|
||||
inp->identity[idx] = elt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
extend1_cell_body_getarray_identity(extend1_cell_body_t *inp)
|
||||
{
|
||||
return inp->identity;
|
||||
}
|
||||
const uint8_t *
|
||||
extend1_cell_body_getconstarray_identity(const extend1_cell_body_t *inp)
|
||||
{
|
||||
return (const uint8_t *)extend1_cell_body_getarray_identity((extend1_cell_body_t*)inp);
|
||||
}
|
||||
const char *
|
||||
extend1_cell_body_check(const extend1_cell_body_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
|
||||
extend1_cell_body_encoded_len(const extend1_cell_body_t *obj)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
|
||||
if (NULL != extend1_cell_body_check(obj))
|
||||
return -1;
|
||||
|
||||
|
||||
/* Length of u32 ipv4addr */
|
||||
result += 4;
|
||||
|
||||
/* Length of u16 port */
|
||||
result += 2;
|
||||
|
||||
/* Length of u8 onionskin[186] */
|
||||
result += 186;
|
||||
|
||||
/* Length of u8 identity[20] */
|
||||
result += 20;
|
||||
return result;
|
||||
}
|
||||
int
|
||||
extend1_cell_body_clear_errors(extend1_cell_body_t *obj)
|
||||
{
|
||||
int r = obj->trunnel_error_code_;
|
||||
obj->trunnel_error_code_ = 0;
|
||||
return r;
|
||||
}
|
||||
ssize_t
|
||||
extend1_cell_body_encode(uint8_t *output, const size_t avail, const extend1_cell_body_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 = extend1_cell_body_encoded_len(obj);
|
||||
#endif
|
||||
|
||||
if (NULL != (msg = extend1_cell_body_check(obj)))
|
||||
goto check_failed;
|
||||
|
||||
#ifdef TRUNNEL_CHECK_ENCODED_LEN
|
||||
trunnel_assert(encoded_len >= 0);
|
||||
#endif
|
||||
|
||||
/* Encode u32 ipv4addr */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 4)
|
||||
goto truncated;
|
||||
trunnel_set_uint32(ptr, trunnel_htonl(obj->ipv4addr));
|
||||
written += 4; ptr += 4;
|
||||
|
||||
/* Encode u16 port */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 2)
|
||||
goto truncated;
|
||||
trunnel_set_uint16(ptr, trunnel_htons(obj->port));
|
||||
written += 2; ptr += 2;
|
||||
|
||||
/* Encode u8 onionskin[186] */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 186)
|
||||
goto truncated;
|
||||
memcpy(ptr, obj->onionskin, 186);
|
||||
written += 186; ptr += 186;
|
||||
|
||||
/* Encode u8 identity[20] */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 20)
|
||||
goto truncated;
|
||||
memcpy(ptr, obj->identity, 20);
|
||||
written += 20; ptr += 20;
|
||||
|
||||
|
||||
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 extend1_cell_body_parse(), but do not allocate the output
|
||||
* object.
|
||||
*/
|
||||
static ssize_t
|
||||
extend1_cell_body_parse_into(extend1_cell_body_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 u32 ipv4addr */
|
||||
CHECK_REMAINING(4, truncated);
|
||||
obj->ipv4addr = trunnel_ntohl(trunnel_get_uint32(ptr));
|
||||
remaining -= 4; ptr += 4;
|
||||
|
||||
/* Parse u16 port */
|
||||
CHECK_REMAINING(2, truncated);
|
||||
obj->port = trunnel_ntohs(trunnel_get_uint16(ptr));
|
||||
remaining -= 2; ptr += 2;
|
||||
|
||||
/* Parse u8 onionskin[186] */
|
||||
CHECK_REMAINING(186, truncated);
|
||||
memcpy(obj->onionskin, ptr, 186);
|
||||
remaining -= 186; ptr += 186;
|
||||
|
||||
/* Parse u8 identity[20] */
|
||||
CHECK_REMAINING(20, truncated);
|
||||
memcpy(obj->identity, ptr, 20);
|
||||
remaining -= 20; ptr += 20;
|
||||
trunnel_assert(ptr + remaining == input + len_in);
|
||||
return len_in - remaining;
|
||||
|
||||
truncated:
|
||||
return -2;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
extend1_cell_body_parse(extend1_cell_body_t **output, const uint8_t *input, const size_t len_in)
|
||||
{
|
||||
ssize_t result;
|
||||
*output = extend1_cell_body_new();
|
||||
if (NULL == *output)
|
||||
return -1;
|
||||
result = extend1_cell_body_parse_into(*output, input, len_in);
|
||||
if (result < 0) {
|
||||
extend1_cell_body_free(*output);
|
||||
*output = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
link_specifier_t *
|
||||
link_specifier_new(void)
|
||||
{
|
||||
|
@ -1528,6 +2084,343 @@ ed25519_cert_parse(ed25519_cert_t **output, const uint8_t *input, const size_t l
|
|||
}
|
||||
return result;
|
||||
}
|
||||
extend2_cell_body_t *
|
||||
extend2_cell_body_new(void)
|
||||
{
|
||||
extend2_cell_body_t *val = trunnel_calloc(1, sizeof(extend2_cell_body_t));
|
||||
if (NULL == val)
|
||||
return NULL;
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Release all storage held inside 'obj', but do not free 'obj'.
|
||||
*/
|
||||
static void
|
||||
extend2_cell_body_clear(extend2_cell_body_t *obj)
|
||||
{
|
||||
(void) obj;
|
||||
{
|
||||
|
||||
unsigned idx;
|
||||
for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->ls); ++idx) {
|
||||
link_specifier_free(TRUNNEL_DYNARRAY_GET(&obj->ls, idx));
|
||||
}
|
||||
}
|
||||
TRUNNEL_DYNARRAY_WIPE(&obj->ls);
|
||||
TRUNNEL_DYNARRAY_CLEAR(&obj->ls);
|
||||
create2_cell_body_free(obj->create2);
|
||||
obj->create2 = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
extend2_cell_body_free(extend2_cell_body_t *obj)
|
||||
{
|
||||
if (obj == NULL)
|
||||
return;
|
||||
extend2_cell_body_clear(obj);
|
||||
trunnel_memwipe(obj, sizeof(extend2_cell_body_t));
|
||||
trunnel_free_(obj);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
extend2_cell_body_get_n_spec(extend2_cell_body_t *inp)
|
||||
{
|
||||
return inp->n_spec;
|
||||
}
|
||||
int
|
||||
extend2_cell_body_set_n_spec(extend2_cell_body_t *inp, uint8_t val)
|
||||
{
|
||||
inp->n_spec = val;
|
||||
return 0;
|
||||
}
|
||||
size_t
|
||||
extend2_cell_body_getlen_ls(const extend2_cell_body_t *inp)
|
||||
{
|
||||
return TRUNNEL_DYNARRAY_LEN(&inp->ls);
|
||||
}
|
||||
|
||||
struct link_specifier_st *
|
||||
extend2_cell_body_get_ls(extend2_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
return TRUNNEL_DYNARRAY_GET(&inp->ls, idx);
|
||||
}
|
||||
|
||||
const struct link_specifier_st *
|
||||
extend2_cell_body_getconst_ls(const extend2_cell_body_t *inp, size_t idx)
|
||||
{
|
||||
return extend2_cell_body_get_ls((extend2_cell_body_t*)inp, idx);
|
||||
}
|
||||
int
|
||||
extend2_cell_body_set_ls(extend2_cell_body_t *inp, size_t idx, struct link_specifier_st * elt)
|
||||
{
|
||||
link_specifier_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->ls, idx);
|
||||
if (oldval && oldval != elt)
|
||||
link_specifier_free(oldval);
|
||||
return extend2_cell_body_set0_ls(inp, idx, elt);
|
||||
}
|
||||
int
|
||||
extend2_cell_body_set0_ls(extend2_cell_body_t *inp, size_t idx, struct link_specifier_st * elt)
|
||||
{
|
||||
TRUNNEL_DYNARRAY_SET(&inp->ls, idx, elt);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
extend2_cell_body_add_ls(extend2_cell_body_t *inp, struct link_specifier_st * elt)
|
||||
{
|
||||
#if SIZE_MAX >= UINT8_MAX
|
||||
if (inp->ls.n_ == UINT8_MAX)
|
||||
goto trunnel_alloc_failed;
|
||||
#endif
|
||||
TRUNNEL_DYNARRAY_ADD(struct link_specifier_st *, &inp->ls, elt, {});
|
||||
return 0;
|
||||
trunnel_alloc_failed:
|
||||
TRUNNEL_SET_ERROR_CODE(inp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct link_specifier_st * *
|
||||
extend2_cell_body_getarray_ls(extend2_cell_body_t *inp)
|
||||
{
|
||||
return inp->ls.elts_;
|
||||
}
|
||||
const struct link_specifier_st * const *
|
||||
extend2_cell_body_getconstarray_ls(const extend2_cell_body_t *inp)
|
||||
{
|
||||
return (const struct link_specifier_st * const *)extend2_cell_body_getarray_ls((extend2_cell_body_t*)inp);
|
||||
}
|
||||
int
|
||||
extend2_cell_body_setlen_ls(extend2_cell_body_t *inp, size_t newlen)
|
||||
{
|
||||
struct link_specifier_st * *newptr;
|
||||
#if UINT8_MAX < SIZE_MAX
|
||||
if (newlen > UINT8_MAX)
|
||||
goto trunnel_alloc_failed;
|
||||
#endif
|
||||
newptr = trunnel_dynarray_setlen(&inp->ls.allocated_,
|
||||
&inp->ls.n_, inp->ls.elts_, newlen,
|
||||
sizeof(inp->ls.elts_[0]), (trunnel_free_fn_t) link_specifier_free,
|
||||
&inp->trunnel_error_code_);
|
||||
if (newlen != 0 && newptr == NULL)
|
||||
goto trunnel_alloc_failed;
|
||||
inp->ls.elts_ = newptr;
|
||||
return 0;
|
||||
trunnel_alloc_failed:
|
||||
TRUNNEL_SET_ERROR_CODE(inp);
|
||||
return -1;
|
||||
}
|
||||
struct create2_cell_body_st *
|
||||
extend2_cell_body_get_create2(extend2_cell_body_t *inp)
|
||||
{
|
||||
return inp->create2;
|
||||
}
|
||||
const struct create2_cell_body_st *
|
||||
extend2_cell_body_getconst_create2(const extend2_cell_body_t *inp)
|
||||
{
|
||||
return extend2_cell_body_get_create2((extend2_cell_body_t*) inp);
|
||||
}
|
||||
int
|
||||
extend2_cell_body_set_create2(extend2_cell_body_t *inp, struct create2_cell_body_st *val)
|
||||
{
|
||||
if (inp->create2 && inp->create2 != val)
|
||||
create2_cell_body_free(inp->create2);
|
||||
return extend2_cell_body_set0_create2(inp, val);
|
||||
}
|
||||
int
|
||||
extend2_cell_body_set0_create2(extend2_cell_body_t *inp, struct create2_cell_body_st *val)
|
||||
{
|
||||
inp->create2 = val;
|
||||
return 0;
|
||||
}
|
||||
const char *
|
||||
extend2_cell_body_check(const extend2_cell_body_t *obj)
|
||||
{
|
||||
if (obj == NULL)
|
||||
return "Object was NULL";
|
||||
if (obj->trunnel_error_code_)
|
||||
return "A set function failed on this object";
|
||||
{
|
||||
const char *msg;
|
||||
|
||||
unsigned idx;
|
||||
for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->ls); ++idx) {
|
||||
if (NULL != (msg = link_specifier_check(TRUNNEL_DYNARRAY_GET(&obj->ls, idx))))
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
if (TRUNNEL_DYNARRAY_LEN(&obj->ls) != obj->n_spec)
|
||||
return "Length mismatch for ls";
|
||||
{
|
||||
const char *msg;
|
||||
if (NULL != (msg = create2_cell_body_check(obj->create2)))
|
||||
return msg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
extend2_cell_body_encoded_len(const extend2_cell_body_t *obj)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
|
||||
if (NULL != extend2_cell_body_check(obj))
|
||||
return -1;
|
||||
|
||||
|
||||
/* Length of u8 n_spec */
|
||||
result += 1;
|
||||
|
||||
/* Length of struct link_specifier ls[n_spec] */
|
||||
{
|
||||
|
||||
unsigned idx;
|
||||
for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->ls); ++idx) {
|
||||
result += link_specifier_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->ls, idx));
|
||||
}
|
||||
}
|
||||
|
||||
/* Length of struct create2_cell_body create2 */
|
||||
result += create2_cell_body_encoded_len(obj->create2);
|
||||
return result;
|
||||
}
|
||||
int
|
||||
extend2_cell_body_clear_errors(extend2_cell_body_t *obj)
|
||||
{
|
||||
int r = obj->trunnel_error_code_;
|
||||
obj->trunnel_error_code_ = 0;
|
||||
return r;
|
||||
}
|
||||
ssize_t
|
||||
extend2_cell_body_encode(uint8_t *output, const size_t avail, const extend2_cell_body_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 = extend2_cell_body_encoded_len(obj);
|
||||
#endif
|
||||
|
||||
if (NULL != (msg = extend2_cell_body_check(obj)))
|
||||
goto check_failed;
|
||||
|
||||
#ifdef TRUNNEL_CHECK_ENCODED_LEN
|
||||
trunnel_assert(encoded_len >= 0);
|
||||
#endif
|
||||
|
||||
/* Encode u8 n_spec */
|
||||
trunnel_assert(written <= avail);
|
||||
if (avail - written < 1)
|
||||
goto truncated;
|
||||
trunnel_set_uint8(ptr, (obj->n_spec));
|
||||
written += 1; ptr += 1;
|
||||
|
||||
/* Encode struct link_specifier ls[n_spec] */
|
||||
{
|
||||
|
||||
unsigned idx;
|
||||
for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->ls); ++idx) {
|
||||
trunnel_assert(written <= avail);
|
||||
result = link_specifier_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->ls, idx));
|
||||
if (result < 0)
|
||||
goto fail; /* XXXXXXX !*/
|
||||
written += result; ptr += result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Encode struct create2_cell_body create2 */
|
||||
trunnel_assert(written <= avail);
|
||||
result = create2_cell_body_encode(ptr, avail - written, obj->create2);
|
||||
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 extend2_cell_body_parse(), but do not allocate the output
|
||||
* object.
|
||||
*/
|
||||
static ssize_t
|
||||
extend2_cell_body_parse_into(extend2_cell_body_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 n_spec */
|
||||
CHECK_REMAINING(1, truncated);
|
||||
obj->n_spec = (trunnel_get_uint8(ptr));
|
||||
remaining -= 1; ptr += 1;
|
||||
|
||||
/* Parse struct link_specifier ls[n_spec] */
|
||||
TRUNNEL_DYNARRAY_EXPAND(link_specifier_t *, &obj->ls, obj->n_spec, {});
|
||||
{
|
||||
link_specifier_t * elt;
|
||||
unsigned idx;
|
||||
for (idx = 0; idx < obj->n_spec; ++idx) {
|
||||
result = link_specifier_parse(&elt, ptr, remaining);
|
||||
if (result < 0)
|
||||
goto relay_fail;
|
||||
trunnel_assert((size_t)result <= remaining);
|
||||
remaining -= result; ptr += result;
|
||||
TRUNNEL_DYNARRAY_ADD(link_specifier_t *, &obj->ls, elt, {link_specifier_free(elt);});
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse struct create2_cell_body create2 */
|
||||
result = create2_cell_body_parse(&obj->create2, ptr, remaining);
|
||||
if (result < 0)
|
||||
goto relay_fail;
|
||||
trunnel_assert((size_t)result <= remaining);
|
||||
remaining -= result; ptr += result;
|
||||
trunnel_assert(ptr + remaining == input + len_in);
|
||||
return len_in - remaining;
|
||||
|
||||
truncated:
|
||||
return -2;
|
||||
relay_fail:
|
||||
trunnel_assert(result < 0);
|
||||
return result;
|
||||
trunnel_alloc_failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
extend2_cell_body_parse(extend2_cell_body_t **output, const uint8_t *input, const size_t len_in)
|
||||
{
|
||||
ssize_t result;
|
||||
*output = extend2_cell_body_new();
|
||||
if (NULL == *output)
|
||||
return -1;
|
||||
result = extend2_cell_body_parse_into(*output, input, len_in);
|
||||
if (result < 0) {
|
||||
extend2_cell_body_free(*output);
|
||||
*output = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
link_specifier_list_t *
|
||||
link_specifier_list_new(void)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,15 @@
|
|||
#define LS_IPV6 1
|
||||
#define LS_LEGACY_ID 2
|
||||
#define LS_ED25519_ID 3
|
||||
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_CREATE2_CELL_BODY)
|
||||
struct create2_cell_body_st {
|
||||
uint16_t handshake_type;
|
||||
uint16_t handshake_len;
|
||||
TRUNNEL_DYNARRAY_HEAD(, uint8_t) handshake_data;
|
||||
uint8_t trunnel_error_code_;
|
||||
};
|
||||
#endif
|
||||
typedef struct create2_cell_body_st create2_cell_body_t;
|
||||
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_ED25519_CERT_EXTENSION)
|
||||
struct ed25519_cert_extension_st {
|
||||
uint16_t ext_length;
|
||||
|
@ -25,6 +34,16 @@ struct ed25519_cert_extension_st {
|
|||
};
|
||||
#endif
|
||||
typedef struct ed25519_cert_extension_st ed25519_cert_extension_t;
|
||||
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_EXTEND1_CELL_BODY)
|
||||
struct extend1_cell_body_st {
|
||||
uint32_t ipv4addr;
|
||||
uint16_t port;
|
||||
uint8_t onionskin[186];
|
||||
uint8_t identity[20];
|
||||
uint8_t trunnel_error_code_;
|
||||
};
|
||||
#endif
|
||||
typedef struct extend1_cell_body_st extend1_cell_body_t;
|
||||
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_LINK_SPECIFIER)
|
||||
struct link_specifier_st {
|
||||
uint8_t ls_type;
|
||||
|
@ -54,6 +73,15 @@ struct ed25519_cert_st {
|
|||
};
|
||||
#endif
|
||||
typedef struct ed25519_cert_st ed25519_cert_t;
|
||||
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_EXTEND2_CELL_BODY)
|
||||
struct extend2_cell_body_st {
|
||||
uint8_t n_spec;
|
||||
TRUNNEL_DYNARRAY_HEAD(, struct link_specifier_st *) ls;
|
||||
struct create2_cell_body_st *create2;
|
||||
uint8_t trunnel_error_code_;
|
||||
};
|
||||
#endif
|
||||
typedef struct extend2_cell_body_st extend2_cell_body_t;
|
||||
#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_LINK_SPECIFIER_LIST)
|
||||
struct link_specifier_list_st {
|
||||
uint8_t n_spec;
|
||||
|
@ -62,6 +90,95 @@ struct link_specifier_list_st {
|
|||
};
|
||||
#endif
|
||||
typedef struct link_specifier_list_st link_specifier_list_t;
|
||||
/** Return a newly allocated create2_cell_body with all elements set
|
||||
* to zero.
|
||||
*/
|
||||
create2_cell_body_t *create2_cell_body_new(void);
|
||||
/** Release all storage held by the create2_cell_body in 'victim'. (Do
|
||||
* nothing if 'victim' is NULL.)
|
||||
*/
|
||||
void create2_cell_body_free(create2_cell_body_t *victim);
|
||||
/** Try to parse a create2_cell_body 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
|
||||
* create2_cell_body_t. On failure, return -2 if the input appears
|
||||
* truncated, and -1 if the input is otherwise invalid.
|
||||
*/
|
||||
ssize_t create2_cell_body_parse(create2_cell_body_t **output, const uint8_t *input, const size_t len_in);
|
||||
/** Return the number of bytes we expect to need to encode the
|
||||
* create2_cell_body 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 create2_cell_body_encoded_len(const create2_cell_body_t *obj);
|
||||
/** Try to encode the create2_cell_body 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 create2_cell_body_encode(uint8_t *output, size_t avail, const create2_cell_body_t *input);
|
||||
/** Check whether the internal state of the create2_cell_body in 'obj'
|
||||
* is consistent. Return NULL if it is, and a short message if it is
|
||||
* not.
|
||||
*/
|
||||
const char *create2_cell_body_check(const create2_cell_body_t *obj);
|
||||
/** Clear any errors that were set on the object 'obj' by its setter
|
||||
* functions. Return true iff errors were cleared.
|
||||
*/
|
||||
int create2_cell_body_clear_errors(create2_cell_body_t *obj);
|
||||
/** Return the value of the handshake_type field of the
|
||||
* create2_cell_body_t in 'inp'
|
||||
*/
|
||||
uint16_t create2_cell_body_get_handshake_type(create2_cell_body_t *inp);
|
||||
/** Set the value of the handshake_type field of the
|
||||
* create2_cell_body_t in 'inp' to 'val'. Return 0 on success; return
|
||||
* -1 and set the error code on 'inp' on failure.
|
||||
*/
|
||||
int create2_cell_body_set_handshake_type(create2_cell_body_t *inp, uint16_t val);
|
||||
/** Return the value of the handshake_len field of the
|
||||
* create2_cell_body_t in 'inp'
|
||||
*/
|
||||
uint16_t create2_cell_body_get_handshake_len(create2_cell_body_t *inp);
|
||||
/** Set the value of the handshake_len field of the
|
||||
* create2_cell_body_t in 'inp' to 'val'. Return 0 on success; return
|
||||
* -1 and set the error code on 'inp' on failure.
|
||||
*/
|
||||
int create2_cell_body_set_handshake_len(create2_cell_body_t *inp, uint16_t val);
|
||||
/** Return the length of the dynamic array holding the handshake_data
|
||||
* field of the create2_cell_body_t in 'inp'.
|
||||
*/
|
||||
size_t create2_cell_body_getlen_handshake_data(const create2_cell_body_t *inp);
|
||||
/** Return the element at position 'idx' of the dynamic array field
|
||||
* handshake_data of the create2_cell_body_t in 'inp'.
|
||||
*/
|
||||
uint8_t create2_cell_body_get_handshake_data(create2_cell_body_t *inp, size_t idx);
|
||||
/** As create2_cell_body_get_handshake_data, but take and return a
|
||||
* const pointer
|
||||
*/
|
||||
uint8_t create2_cell_body_getconst_handshake_data(const create2_cell_body_t *inp, size_t idx);
|
||||
/** Change the element at position 'idx' of the dynamic array field
|
||||
* handshake_data of the create2_cell_body_t in 'inp', so that it will
|
||||
* hold the value 'elt'.
|
||||
*/
|
||||
int create2_cell_body_set_handshake_data(create2_cell_body_t *inp, size_t idx, uint8_t elt);
|
||||
/** Append a new element 'elt' to the dynamic array field
|
||||
* handshake_data of the create2_cell_body_t in 'inp'.
|
||||
*/
|
||||
int create2_cell_body_add_handshake_data(create2_cell_body_t *inp, uint8_t elt);
|
||||
/** Return a pointer to the variable-length array field handshake_data
|
||||
* of 'inp'.
|
||||
*/
|
||||
uint8_t * create2_cell_body_getarray_handshake_data(create2_cell_body_t *inp);
|
||||
/** As create2_cell_body_get_handshake_data, but take and return a
|
||||
* const pointer
|
||||
*/
|
||||
const uint8_t * create2_cell_body_getconstarray_handshake_data(const create2_cell_body_t *inp);
|
||||
/** Change the length of the variable-length array field
|
||||
* handshake_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 create2_cell_body_setlen_handshake_data(create2_cell_body_t *inp, size_t newlen);
|
||||
/** Return a newly allocated ed25519_cert_extension with all elements
|
||||
* set to zero.
|
||||
*/
|
||||
|
@ -184,6 +301,109 @@ const uint8_t * ed25519_cert_extension_getconstarray_un_unparsed(const ed25519_
|
|||
* success; return -1 and set the error code on 'inp' on failure.
|
||||
*/
|
||||
int ed25519_cert_extension_setlen_un_unparsed(ed25519_cert_extension_t *inp, size_t newlen);
|
||||
/** Return a newly allocated extend1_cell_body with all elements set
|
||||
* to zero.
|
||||
*/
|
||||
extend1_cell_body_t *extend1_cell_body_new(void);
|
||||
/** Release all storage held by the extend1_cell_body in 'victim'. (Do
|
||||
* nothing if 'victim' is NULL.)
|
||||
*/
|
||||
void extend1_cell_body_free(extend1_cell_body_t *victim);
|
||||
/** Try to parse a extend1_cell_body 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
|
||||
* extend1_cell_body_t. On failure, return -2 if the input appears
|
||||
* truncated, and -1 if the input is otherwise invalid.
|
||||
*/
|
||||
ssize_t extend1_cell_body_parse(extend1_cell_body_t **output, const uint8_t *input, const size_t len_in);
|
||||
/** Return the number of bytes we expect to need to encode the
|
||||
* extend1_cell_body 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 extend1_cell_body_encoded_len(const extend1_cell_body_t *obj);
|
||||
/** Try to encode the extend1_cell_body 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 extend1_cell_body_encode(uint8_t *output, size_t avail, const extend1_cell_body_t *input);
|
||||
/** Check whether the internal state of the extend1_cell_body in 'obj'
|
||||
* is consistent. Return NULL if it is, and a short message if it is
|
||||
* not.
|
||||
*/
|
||||
const char *extend1_cell_body_check(const extend1_cell_body_t *obj);
|
||||
/** Clear any errors that were set on the object 'obj' by its setter
|
||||
* functions. Return true iff errors were cleared.
|
||||
*/
|
||||
int extend1_cell_body_clear_errors(extend1_cell_body_t *obj);
|
||||
/** Return the value of the ipv4addr field of the extend1_cell_body_t
|
||||
* in 'inp'
|
||||
*/
|
||||
uint32_t extend1_cell_body_get_ipv4addr(extend1_cell_body_t *inp);
|
||||
/** Set the value of the ipv4addr field of the extend1_cell_body_t in
|
||||
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
|
||||
* code on 'inp' on failure.
|
||||
*/
|
||||
int extend1_cell_body_set_ipv4addr(extend1_cell_body_t *inp, uint32_t val);
|
||||
/** Return the value of the port field of the extend1_cell_body_t in
|
||||
* 'inp'
|
||||
*/
|
||||
uint16_t extend1_cell_body_get_port(extend1_cell_body_t *inp);
|
||||
/** Set the value of the port field of the extend1_cell_body_t in
|
||||
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
|
||||
* code on 'inp' on failure.
|
||||
*/
|
||||
int extend1_cell_body_set_port(extend1_cell_body_t *inp, uint16_t val);
|
||||
/** Return the (constant) length of the array holding the onionskin
|
||||
* field of the extend1_cell_body_t in 'inp'.
|
||||
*/
|
||||
size_t extend1_cell_body_getlen_onionskin(const extend1_cell_body_t *inp);
|
||||
/** Return the element at position 'idx' of the fixed array field
|
||||
* onionskin of the extend1_cell_body_t in 'inp'.
|
||||
*/
|
||||
uint8_t extend1_cell_body_get_onionskin(extend1_cell_body_t *inp, size_t idx);
|
||||
/** As extend1_cell_body_get_onionskin, but take and return a const
|
||||
* pointer
|
||||
*/
|
||||
uint8_t extend1_cell_body_getconst_onionskin(const extend1_cell_body_t *inp, size_t idx);
|
||||
/** Change the element at position 'idx' of the fixed array field
|
||||
* onionskin of the extend1_cell_body_t in 'inp', so that it will hold
|
||||
* the value 'elt'.
|
||||
*/
|
||||
int extend1_cell_body_set_onionskin(extend1_cell_body_t *inp, size_t idx, uint8_t elt);
|
||||
/** Return a pointer to the 186-element array field onionskin of
|
||||
* 'inp'.
|
||||
*/
|
||||
uint8_t * extend1_cell_body_getarray_onionskin(extend1_cell_body_t *inp);
|
||||
/** As extend1_cell_body_get_onionskin, but take and return a const
|
||||
* pointer
|
||||
*/
|
||||
const uint8_t * extend1_cell_body_getconstarray_onionskin(const extend1_cell_body_t *inp);
|
||||
/** Return the (constant) length of the array holding the identity
|
||||
* field of the extend1_cell_body_t in 'inp'.
|
||||
*/
|
||||
size_t extend1_cell_body_getlen_identity(const extend1_cell_body_t *inp);
|
||||
/** Return the element at position 'idx' of the fixed array field
|
||||
* identity of the extend1_cell_body_t in 'inp'.
|
||||
*/
|
||||
uint8_t extend1_cell_body_get_identity(extend1_cell_body_t *inp, size_t idx);
|
||||
/** As extend1_cell_body_get_identity, but take and return a const
|
||||
* pointer
|
||||
*/
|
||||
uint8_t extend1_cell_body_getconst_identity(const extend1_cell_body_t *inp, size_t idx);
|
||||
/** Change the element at position 'idx' of the fixed array field
|
||||
* identity of the extend1_cell_body_t in 'inp', so that it will hold
|
||||
* the value 'elt'.
|
||||
*/
|
||||
int extend1_cell_body_set_identity(extend1_cell_body_t *inp, size_t idx, uint8_t elt);
|
||||
/** Return a pointer to the 20-element array field identity of 'inp'.
|
||||
*/
|
||||
uint8_t * extend1_cell_body_getarray_identity(extend1_cell_body_t *inp);
|
||||
/** As extend1_cell_body_get_identity, but take and return a const
|
||||
* pointer
|
||||
*/
|
||||
const uint8_t * extend1_cell_body_getconstarray_identity(const extend1_cell_body_t *inp);
|
||||
/** Return a newly allocated link_specifier with all elements set to
|
||||
* zero.
|
||||
*/
|
||||
|
@ -536,6 +756,104 @@ uint8_t * ed25519_cert_getarray_signature(ed25519_cert_t *inp);
|
|||
/** As ed25519_cert_get_signature, but take and return a const pointer
|
||||
*/
|
||||
const uint8_t * ed25519_cert_getconstarray_signature(const ed25519_cert_t *inp);
|
||||
/** Return a newly allocated extend2_cell_body with all elements set
|
||||
* to zero.
|
||||
*/
|
||||
extend2_cell_body_t *extend2_cell_body_new(void);
|
||||
/** Release all storage held by the extend2_cell_body in 'victim'. (Do
|
||||
* nothing if 'victim' is NULL.)
|
||||
*/
|
||||
void extend2_cell_body_free(extend2_cell_body_t *victim);
|
||||
/** Try to parse a extend2_cell_body 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
|
||||
* extend2_cell_body_t. On failure, return -2 if the input appears
|
||||
* truncated, and -1 if the input is otherwise invalid.
|
||||
*/
|
||||
ssize_t extend2_cell_body_parse(extend2_cell_body_t **output, const uint8_t *input, const size_t len_in);
|
||||
/** Return the number of bytes we expect to need to encode the
|
||||
* extend2_cell_body 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 extend2_cell_body_encoded_len(const extend2_cell_body_t *obj);
|
||||
/** Try to encode the extend2_cell_body 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 extend2_cell_body_encode(uint8_t *output, size_t avail, const extend2_cell_body_t *input);
|
||||
/** Check whether the internal state of the extend2_cell_body in 'obj'
|
||||
* is consistent. Return NULL if it is, and a short message if it is
|
||||
* not.
|
||||
*/
|
||||
const char *extend2_cell_body_check(const extend2_cell_body_t *obj);
|
||||
/** Clear any errors that were set on the object 'obj' by its setter
|
||||
* functions. Return true iff errors were cleared.
|
||||
*/
|
||||
int extend2_cell_body_clear_errors(extend2_cell_body_t *obj);
|
||||
/** Return the value of the n_spec field of the extend2_cell_body_t in
|
||||
* 'inp'
|
||||
*/
|
||||
uint8_t extend2_cell_body_get_n_spec(extend2_cell_body_t *inp);
|
||||
/** Set the value of the n_spec field of the extend2_cell_body_t in
|
||||
* 'inp' to 'val'. Return 0 on success; return -1 and set the error
|
||||
* code on 'inp' on failure.
|
||||
*/
|
||||
int extend2_cell_body_set_n_spec(extend2_cell_body_t *inp, uint8_t val);
|
||||
/** Return the length of the dynamic array holding the ls field of the
|
||||
* extend2_cell_body_t in 'inp'.
|
||||
*/
|
||||
size_t extend2_cell_body_getlen_ls(const extend2_cell_body_t *inp);
|
||||
/** Return the element at position 'idx' of the dynamic array field ls
|
||||
* of the extend2_cell_body_t in 'inp'.
|
||||
*/
|
||||
struct link_specifier_st * extend2_cell_body_get_ls(extend2_cell_body_t *inp, size_t idx);
|
||||
/** As extend2_cell_body_get_ls, but take and return a const pointer
|
||||
*/
|
||||
const struct link_specifier_st * extend2_cell_body_getconst_ls(const extend2_cell_body_t *inp, size_t idx);
|
||||
/** Change the element at position 'idx' of the dynamic array field ls
|
||||
* of the extend2_cell_body_t in 'inp', so that it will hold the value
|
||||
* 'elt'. Free the previous value, if any.
|
||||
*/
|
||||
int extend2_cell_body_set_ls(extend2_cell_body_t *inp, size_t idx, struct link_specifier_st * elt);
|
||||
/** As extend2_cell_body_set_ls, but does not free the previous value.
|
||||
*/
|
||||
int extend2_cell_body_set0_ls(extend2_cell_body_t *inp, size_t idx, struct link_specifier_st * elt);
|
||||
/** Append a new element 'elt' to the dynamic array field ls of the
|
||||
* extend2_cell_body_t in 'inp'.
|
||||
*/
|
||||
int extend2_cell_body_add_ls(extend2_cell_body_t *inp, struct link_specifier_st * elt);
|
||||
/** Return a pointer to the variable-length array field ls of 'inp'.
|
||||
*/
|
||||
struct link_specifier_st * * extend2_cell_body_getarray_ls(extend2_cell_body_t *inp);
|
||||
/** As extend2_cell_body_get_ls, but take and return a const pointer
|
||||
*/
|
||||
const struct link_specifier_st * const * extend2_cell_body_getconstarray_ls(const extend2_cell_body_t *inp);
|
||||
/** Change the length of the variable-length array field ls 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 extend2_cell_body_setlen_ls(extend2_cell_body_t *inp, size_t newlen);
|
||||
/** Return the value of the create2 field of the extend2_cell_body_t
|
||||
* in 'inp'
|
||||
*/
|
||||
struct create2_cell_body_st * extend2_cell_body_get_create2(extend2_cell_body_t *inp);
|
||||
/** As extend2_cell_body_get_create2, but take and return a const
|
||||
* pointer
|
||||
*/
|
||||
const struct create2_cell_body_st * extend2_cell_body_getconst_create2(const extend2_cell_body_t *inp);
|
||||
/** Set the value of the create2 field of the extend2_cell_body_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.
|
||||
*/
|
||||
int extend2_cell_body_set_create2(extend2_cell_body_t *inp, struct create2_cell_body_st *val);
|
||||
/** As extend2_cell_body_set_create2, but does not free the previous
|
||||
* value.
|
||||
*/
|
||||
int extend2_cell_body_set0_create2(extend2_cell_body_t *inp, struct create2_cell_body_st *val);
|
||||
/** Return a newly allocated link_specifier_list with all elements set
|
||||
* to zero.
|
||||
*/
|
||||
|
|
|
@ -23,40 +23,6 @@ struct ed25519_cert_extension {
|
|||
};
|
||||
}
|
||||
|
||||
/*
|
||||
struct cert_revocation {
|
||||
u8 prefix[8];
|
||||
u8 version IN [1];
|
||||
u8 keytype;
|
||||
u8 identity_key[32];
|
||||
u8 revoked_key[32];
|
||||
u64 published;
|
||||
u8 n_extensions;
|
||||
struct cert_extension ext[n_extensions];
|
||||
u8 signature[64];
|
||||
}
|
||||
|
||||
struct crosscert_ed_rsa {
|
||||
u8 ed_key[32];
|
||||
u32 expiration_date;
|
||||
u8 signature[128];
|
||||
}
|
||||
|
||||
struct auth02_cell {
|
||||
u8 type[8];
|
||||
u8 cid[32];
|
||||
u8 sid[32];
|
||||
u8 cid_ed[32];
|
||||
u8 sid_ed[32];
|
||||
u8 slog[32];
|
||||
u8 clog[32];
|
||||
u8 scert[32];
|
||||
u8 tlssecrets[32];
|
||||
u8 rand[24];
|
||||
u8 sig[64];
|
||||
}
|
||||
*/
|
||||
|
||||
const LS_IPV4 = 0x00;
|
||||
const LS_IPV6 = 0x01;
|
||||
const LS_LEGACY_ID = 0x02;
|
||||
|
@ -79,3 +45,22 @@ struct link_specifier_list {
|
|||
u8 n_spec;
|
||||
struct link_specifier spec[n_spec];
|
||||
}
|
||||
|
||||
struct extend1_cell_body {
|
||||
u32 ipv4addr;
|
||||
u16 port;
|
||||
u8 onionskin[186];
|
||||
u8 identity[20];
|
||||
}
|
||||
|
||||
struct create2_cell_body {
|
||||
u16 handshake_type;
|
||||
u16 handshake_len;
|
||||
u8 handshake_data[handshake_len];
|
||||
}
|
||||
|
||||
struct extend2_cell_body {
|
||||
u8 n_spec;
|
||||
struct link_specifier ls[n_spec];
|
||||
struct create2_cell_body create2;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue