Exemple #1
0
/** Extract the authentication key from an ESTABLISH_INTRO or INTRODUCE1 using
 * the given <b>cell_type</b> from <b>cell</b> and place it in
 * <b>auth_key_out</b>. */
STATIC void
get_auth_key_from_cell(ed25519_public_key_t *auth_key_out,
                       unsigned int cell_type, const void *cell)
{
  size_t auth_key_len;
  const uint8_t *key_array;

  tor_assert(auth_key_out);
  tor_assert(cell);

  switch (cell_type) {
  case RELAY_COMMAND_ESTABLISH_INTRO:
  {
    const trn_cell_establish_intro_t *c_cell = cell;
    key_array = trn_cell_establish_intro_getconstarray_auth_key(c_cell);
    auth_key_len = trn_cell_establish_intro_getlen_auth_key(c_cell);
    break;
  }
  case RELAY_COMMAND_INTRODUCE1:
  {
    const trn_cell_introduce1_t *c_cell = cell;
    key_array = trn_cell_introduce1_getconstarray_auth_key(cell);
    auth_key_len = trn_cell_introduce1_getlen_auth_key(c_cell);
    break;
  }
  default:
    /* Getting here is really bad as it means we got a unknown cell type from
     * this file where every call has an hardcoded value. */
    tor_assert(0); /* LCOV_EXCL_LINE */
  }
  tor_assert(key_array);
  tor_assert(auth_key_len == sizeof(auth_key_out->pubkey));
  memcpy(auth_key_out->pubkey, key_array, auth_key_len);
}
Exemple #2
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_);
}