Ejemplo n.º 1
0
ssize_t
trn_cell_introduce1_parse(trn_cell_introduce1_t **output, const uint8_t *input, const size_t len_in)
{
  ssize_t result;
  *output = trn_cell_introduce1_new();
  if (NULL == *output)
    return -1;
  result = trn_cell_introduce1_parse_into(*output, input, len_in);
  if (result < 0) {
    trn_cell_introduce1_free(*output);
    *output = NULL;
  }
  return result;
}
Ejemplo n.º 2
0
static trn_cell_introduce1_t *
helper_create_introduce1_cell(void)
{
  trn_cell_introduce1_t *cell = NULL;
  ed25519_keypair_t auth_key_kp;

  /* Generate the auth_key of the cell. */
  if (ed25519_keypair_generate(&auth_key_kp, 0) < 0) {
    goto err;
  }

  cell = trn_cell_introduce1_new();
  tt_assert(cell);

  /* Set the auth key. */
  {
    size_t auth_key_len = sizeof(auth_key_kp.pubkey);
    trn_cell_introduce1_set_auth_key_type(cell,
                                     TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
    trn_cell_introduce1_set_auth_key_len(cell, auth_key_len);
    trn_cell_introduce1_setlen_auth_key(cell, auth_key_len);
    uint8_t *auth_key_ptr = trn_cell_introduce1_getarray_auth_key(cell);
    memcpy(auth_key_ptr, auth_key_kp.pubkey.pubkey, auth_key_len);
  }

  /* Set the cell extensions to none. */
  {
    trn_cell_extension_t *ext = trn_cell_extension_new();
    trn_cell_extension_set_num(ext, 0);
    trn_cell_introduce1_set_extensions(cell, ext);
  }

  /* Set the encrypted section to some data. */
  {
    size_t enc_len = 128;
    trn_cell_introduce1_setlen_encrypted(cell, enc_len);
    uint8_t *enc_ptr = trn_cell_introduce1_getarray_encrypted(cell);
    memset(enc_ptr, 'a', enc_len);
  }

  return cell;
 err:
 done:
  trn_cell_introduce1_free(cell);
  return NULL;
}
Ejemplo n.º 3
0
static void
test_received_introduce1_handling(void *arg)
{
  int ret;
  uint8_t *request = NULL, buf[128];
  trn_cell_introduce1_t *cell = NULL;
  or_circuit_t *circ = NULL;

  (void) arg;

  MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);

  hs_circuitmap_init();

  /* Too small request length. An INTRODUCE1 expect at the very least a
   * DIGEST_LEN size. */
  {
    memset(buf, 0, sizeof(buf));
    circ = helper_create_intro_circuit();
    ret = hs_intro_received_introduce1(circ, buf, DIGEST_LEN - 1);
    tt_int_op(ret, OP_EQ, -1);
    circuit_free_(TO_CIRCUIT(circ));
  }

  /* We have a unit test only for the suitability of a circuit to receive an
   * INTRODUCE1 cell so from now on we'll only test the handling of a cell. */

  /* Bad request. */
  {
    circ = helper_create_intro_circuit();
    uint8_t test[2]; /* Too small request. */
    memset(test, 0, sizeof(test));
    ret = handle_introduce1(circ, test, sizeof(test));
    tor_free(circ->p_chan);
    circuit_free_(TO_CIRCUIT(circ));
    tt_int_op(ret, OP_EQ, -1);
  }

  /* Valid case. */
  {
    cell = helper_create_introduce1_cell();
    ssize_t request_len = trn_cell_introduce1_encoded_len(cell);
    tt_int_op((int)request_len, OP_GT, 0);
    request = tor_malloc_zero(request_len);
    ssize_t encoded_len =
      trn_cell_introduce1_encode(request, request_len, cell);
    tt_int_op((int)encoded_len, OP_GT, 0);

    circ = helper_create_intro_circuit();
    or_circuit_t *service_circ = helper_create_intro_circuit();
    circuit_change_purpose(TO_CIRCUIT(service_circ),
                           CIRCUIT_PURPOSE_INTRO_POINT);
    /* Register the circuit in the map for the auth key of the cell. */
    ed25519_public_key_t auth_key;
    const uint8_t *cell_auth_key =
      trn_cell_introduce1_getconstarray_auth_key(cell);
    memcpy(auth_key.pubkey, cell_auth_key, ED25519_PUBKEY_LEN);
    hs_circuitmap_register_intro_circ_v3_relay_side(service_circ, &auth_key);
    ret = hs_intro_received_introduce1(circ, request, request_len);
    circuit_free_(TO_CIRCUIT(circ));
    circuit_free_(TO_CIRCUIT(service_circ));
    tt_int_op(ret, OP_EQ, 0);
  }

  /* Valid legacy cell. */
  {
    tor_free(request);
    trn_cell_introduce1_free(cell);
    cell = helper_create_introduce1_cell();
    uint8_t *legacy_key_id = trn_cell_introduce1_getarray_legacy_key_id(cell);
    memset(legacy_key_id, 'a', DIGEST_LEN);
    /* Add an arbitrary amount of data for the payload of a v2 cell. */
    size_t request_len = trn_cell_introduce1_encoded_len(cell) + 256;
    tt_size_op(request_len, OP_GT, 0);
    request = tor_malloc_zero(request_len + 256);
    ssize_t encoded_len =
      trn_cell_introduce1_encode(request, request_len, cell);
    tt_int_op((int)encoded_len, OP_GT, 0);

    circ = helper_create_intro_circuit();
    or_circuit_t *service_circ = helper_create_intro_circuit();
    circuit_change_purpose(TO_CIRCUIT(service_circ),
                           CIRCUIT_PURPOSE_INTRO_POINT);
    /* Register the circuit in the map for the auth key of the cell. */
    uint8_t token[REND_TOKEN_LEN];
    memcpy(token, legacy_key_id, sizeof(token));
    hs_circuitmap_register_intro_circ_v2_relay_side(service_circ, token);
    ret = hs_intro_received_introduce1(circ, request, request_len);
    circuit_free_(TO_CIRCUIT(circ));
    circuit_free_(TO_CIRCUIT(service_circ));
    tt_int_op(ret, OP_EQ, 0);
  }

 done:
  trn_cell_introduce1_free(cell);
  tor_free(request);
  hs_circuitmap_free_all();
  UNMOCK(relay_send_command_from_edge_);
}
Ejemplo n.º 4
0
static void
test_introduce1_validation(void *arg)
{
  int ret;
  trn_cell_introduce1_t *cell = NULL;

  (void) arg;

  /* Create our decoy cell that we'll modify as we go to test the validation
   * function of that parsed cell. */
  cell = helper_create_introduce1_cell();
  tt_assert(cell);

  /* It should NOT be a legacy cell which will trigger a BUG(). */
  memset(cell->legacy_key_id, 'a', sizeof(cell->legacy_key_id));
  tor_capture_bugs_(1);
  ret = validate_introduce1_parsed_cell(cell);
  tor_end_capture_bugs_();
  tt_int_op(ret, OP_EQ, -1);
  /* Reset legacy ID and make sure it's correct. */
  memset(cell->legacy_key_id, 0, sizeof(cell->legacy_key_id));
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, 0);

  /* Non existing auth key type. */
  cell->auth_key_type = 42;
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, -1);
  /* Reset is to correct value and make sure it's correct. */
  cell->auth_key_type = TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519;
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, 0);

  /* Really bad key length. */
  cell->auth_key_len = 0;
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, -1);
  cell->auth_key_len = UINT16_MAX;
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, -1);
  /* Correct size, let's try that. */
  cell->auth_key_len = sizeof(ed25519_public_key_t);
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, 0);
  /* Set an invalid size of the auth key buffer. */
  trn_cell_introduce1_setlen_auth_key(cell, 3);
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, -1);
  /* Reset auth key buffer and make sure it works. */
  trn_cell_introduce1_setlen_auth_key(cell, sizeof(ed25519_public_key_t));
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, 0);

  /* Empty encrypted section. */
  trn_cell_introduce1_setlen_encrypted(cell, 0);
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, -1);
  /* Reset it to some non zero bytes and validate. */
  trn_cell_introduce1_setlen_encrypted(cell, 1);
  ret = validate_introduce1_parsed_cell(cell);
  tt_int_op(ret, OP_EQ, 0);

 done:
  trn_cell_introduce1_free(cell);
}