Beispiel #1
0
/** As trn_cell_introduce_ack_parse(), but do not allocate the output
 * object.
 */
static ssize_t
trn_cell_introduce_ack_parse_into(trn_cell_introduce_ack_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 status IN [0, 1, 2] */
  CHECK_REMAINING(2, truncated);
  obj->status = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;
  if (! (obj->status == 0 || obj->status == 1 || obj->status == 2))
    goto fail;

  /* Parse struct trn_cell_extension extensions */
  result = trn_cell_extension_parse(&obj->extensions, 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;
 fail:
  result = -1;
  return result;
}
Beispiel #2
0
/** As trn_cell_introduce1_parse(), but do not allocate the output
 * object.
 */
static ssize_t
trn_cell_introduce1_parse_into(trn_cell_introduce1_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 legacy_key_id[TRUNNEL_SHA1_LEN] */
  CHECK_REMAINING(TRUNNEL_SHA1_LEN, truncated);
  memcpy(obj->legacy_key_id, ptr, TRUNNEL_SHA1_LEN);
  remaining -= TRUNNEL_SHA1_LEN; ptr += TRUNNEL_SHA1_LEN;

  /* Parse u8 auth_key_type IN [0, 1, 2] */
  CHECK_REMAINING(1, truncated);
  obj->auth_key_type = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;
  if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2))
    goto fail;

  /* Parse u16 auth_key_len */
  CHECK_REMAINING(2, truncated);
  obj->auth_key_len = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u8 auth_key[auth_key_len] */
  CHECK_REMAINING(obj->auth_key_len, truncated);
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->auth_key, obj->auth_key_len, {});
  obj->auth_key.n_ = obj->auth_key_len;
  if (obj->auth_key_len)
    memcpy(obj->auth_key.elts_, ptr, obj->auth_key_len);
  ptr += obj->auth_key_len; remaining -= obj->auth_key_len;

  /* Parse struct trn_cell_extension extensions */
  result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
  if (result < 0)
    goto relay_fail;
  trunnel_assert((size_t)result <= remaining);
  remaining -= result; ptr += result;

  /* Parse u8 encrypted[] */
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->encrypted, remaining, {});
  obj->encrypted.n_ = remaining;
  if (remaining)
    memcpy(obj->encrypted.elts_, ptr, remaining);
  ptr += remaining; remaining -= remaining;
  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;
}
Beispiel #3
0
/** As certs_cell_cert_parse(), but do not allocate the output object.
 */
static ssize_t
certs_cell_cert_parse_into(certs_cell_cert_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 cert_type */
  CHECK_REMAINING(1, truncated);
  obj->cert_type = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;

  /* Parse u16 cert_len */
  CHECK_REMAINING(2, truncated);
  obj->cert_len = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u8 body[cert_len] */
  CHECK_REMAINING(obj->cert_len, truncated);
  TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->body, obj->cert_len, {});
  obj->body.n_ = obj->cert_len;
  memcpy(obj->body.elts_, ptr, obj->cert_len);
  ptr += obj->cert_len; remaining -= obj->cert_len;
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
}
Beispiel #4
0
/** As auth_challenge_cell_parse(), but do not allocate the output
 * object.
 */
static ssize_t
auth_challenge_cell_parse_into(auth_challenge_cell_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 challenge[32] */
  CHECK_REMAINING(32, truncated);
  memcpy(obj->challenge, ptr, 32);
  remaining -= 32; ptr += 32;

  /* Parse u16 n_methods */
  CHECK_REMAINING(2, truncated);
  obj->n_methods = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u16 methods[n_methods] */
  TRUNNEL_DYNARRAY_EXPAND(uint16_t, &obj->methods, obj->n_methods, {});
  {
    uint16_t elt;
    unsigned idx;
    for (idx = 0; idx < obj->n_methods; ++idx) {
      CHECK_REMAINING(2, truncated);
      elt = trunnel_ntohs(trunnel_get_uint16(ptr));
      remaining -= 2; ptr += 2;
      TRUNNEL_DYNARRAY_ADD(uint16_t, &obj->methods, elt, {});
    }
  }
  trunnel_assert(ptr + remaining == input + len_in);
  return len_in - remaining;

 truncated:
  return -2;
 trunnel_alloc_failed:
  return -1;
}
Beispiel #5
0
/** As ed25519_cert_extension_parse(), but do not allocate the output
 * object.
 */
static ssize_t
ed25519_cert_extension_parse_into(ed25519_cert_extension_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 ext_length */
  CHECK_REMAINING(2, truncated);
  obj->ext_length = trunnel_ntohs(trunnel_get_uint16(ptr));
  remaining -= 2; ptr += 2;

  /* Parse u8 ext_type */
  CHECK_REMAINING(1, truncated);
  obj->ext_type = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;

  /* Parse u8 ext_flags */
  CHECK_REMAINING(1, truncated);
  obj->ext_flags = (trunnel_get_uint8(ptr));
  remaining -= 1; ptr += 1;
  {
    size_t remaining_after;
    CHECK_REMAINING(obj->ext_length, truncated);
    remaining_after = remaining - obj->ext_length;
    remaining = obj->ext_length;

    /* Parse union un[ext_type] */
    switch (obj->ext_type) {

      case CERTEXT_SIGNED_WITH_KEY:

        /* Parse u8 un_signing_key[32] */
        CHECK_REMAINING(32, fail);
        memcpy(obj->un_signing_key, ptr, 32);
        remaining -= 32; ptr += 32;
        break;

      default:

        /* Parse u8 un_unparsed[] */
        TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->un_unparsed, remaining, {});
        obj->un_unparsed.n_ = remaining;
        memcpy(obj->un_unparsed.elts_, ptr, remaining);
        ptr += remaining; remaining -= remaining;
        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;
}