/** 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); }
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_); }