diff options
Diffstat (limited to 'src/test/test_hs_service.c')
-rw-r--r-- | src/test/test_hs_service.c | 172 |
1 files changed, 122 insertions, 50 deletions
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index c60ab6c930..49c8d29d27 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Tor Project, Inc. */ +/* Copyright (c) 2016-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,8 +19,9 @@ #define MAINLOOP_PRIVATE #define NETWORKSTATUS_PRIVATE #define STATEFILE_PRIVATE -#define TOR_CHANNEL_INTERNAL_ +#define CHANNEL_OBJECT_PRIVATE #define HS_CLIENT_PRIVATE +#define CRYPT_PATH_PRIVATE #include "test/test.h" #include "test/test_helpers.h" @@ -60,6 +61,7 @@ #include "core/or/cpath_build_state_st.h" #include "core/or/crypt_path_st.h" +#include "core/or/crypt_path.h" #include "feature/nodelist/networkstatus_st.h" #include "feature/nodelist/node_st.h" #include "core/or/origin_circuit_st.h" @@ -170,8 +172,7 @@ test_e2e_rend_circuit_setup(void *arg) tt_int_op(0, OP_EQ, ed25519_secret_key_generate(&sk, 0)); tt_int_op(0, OP_EQ, ed25519_public_key_generate(&service_pk, &sk)); - or_circ->hs_ident = hs_ident_circuit_new(&service_pk, - HS_IDENT_CIRCUIT_RENDEZVOUS); + or_circ->hs_ident = hs_ident_circuit_new(&service_pk); TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN; } @@ -183,9 +184,8 @@ test_e2e_rend_circuit_setup(void *arg) /* Setup the circuit: do the ntor key exchange */ { uint8_t ntor_key_seed[DIGEST256_LEN] = {2}; - retval = hs_circuit_setup_e2e_rend_circ(or_circ, - ntor_key_seed, sizeof(ntor_key_seed), - 1); + retval = hs_circuit_setup_e2e_rend_circ(or_circ, ntor_key_seed, + sizeof(ntor_key_seed), 1); tt_int_op(retval, OP_EQ, 0); } @@ -194,12 +194,12 @@ test_e2e_rend_circuit_setup(void *arg) tt_int_op(retval, OP_EQ, 1); /* Check the digest algo */ - tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.f_digest), + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->pvt_crypto.f_digest), OP_EQ, DIGEST_SHA3_256); - tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.b_digest), + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->pvt_crypto.b_digest), OP_EQ, DIGEST_SHA3_256); - tt_assert(or_circ->cpath->crypto.f_crypto); - tt_assert(or_circ->cpath->crypto.b_crypto); + tt_assert(or_circ->cpath->pvt_crypto.f_crypto); + tt_assert(or_circ->cpath->pvt_crypto.b_crypto); /* Ensure that circ purpose was changed */ tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED); @@ -268,7 +268,7 @@ helper_clone_authorized_client(const hs_service_authorized_client_t *client) /* Helper: Return a newly allocated service object with the identity keypair * sets and the current descriptor. Then register it to the global map. - * Caller should us hs_free_all() to free this service or remove it from the + * Caller should use hs_free_all() to free this service or remove it from the * global map before freeing. */ static hs_service_t * helper_create_service(void) @@ -290,6 +290,20 @@ helper_create_service(void) return service; } +/* Helper: Deallocate a given service object, its child objects and + * remove it from onion service map. + * */ +static void +helper_destroy_service(hs_service_t *service) +{ + if (!service) + return; + + remove_service(get_hs_service_map(), service); + + hs_service_free(service); +} + /* Helper: Return a newly allocated service object with clients. */ static hs_service_t * helper_create_service_with_clients(int num_clients) @@ -315,17 +329,18 @@ helper_create_service_with_clients(int num_clients) static hs_service_intro_point_t * helper_create_service_ip(void) { - hs_desc_link_specifier_t *ls; - hs_service_intro_point_t *ip = service_intro_point_new(NULL, 0, 0); + link_specifier_t *ls; + hs_service_intro_point_t *ip = service_intro_point_new(NULL); tor_assert(ip); /* Add a first unused link specifier. */ - ls = tor_malloc_zero(sizeof(*ls)); - ls->type = LS_IPV4; + ls = link_specifier_new(); + link_specifier_set_ls_type(ls, LS_IPV4); smartlist_add(ip->base.link_specifiers, ls); /* Add a second link specifier used by a test. */ - ls = tor_malloc_zero(sizeof(*ls)); - ls->type = LS_LEGACY_ID; - memset(ls->u.legacy_id, 'A', sizeof(ls->u.legacy_id)); + ls = link_specifier_new(); + link_specifier_set_ls_type(ls, LS_LEGACY_ID); + memset(link_specifier_getarray_un_legacy_id(ls), 'A', + link_specifier_getlen_un_legacy_id(ls)); smartlist_add(ip->base.link_specifiers, ls); return ip; @@ -379,11 +394,11 @@ test_load_keys(void *arg) tt_assert(s); /* Ok we have the service object. Validate few things. */ - tt_assert(!tor_mem_is_zero(s->onion_address, sizeof(s->onion_address))); + tt_assert(!fast_mem_is_zero(s->onion_address, sizeof(s->onion_address))); tt_int_op(hs_address_is_valid(s->onion_address), OP_EQ, 1); - tt_assert(!tor_mem_is_zero((char *) s->keys.identity_sk.seckey, + tt_assert(!fast_mem_is_zero((char *) s->keys.identity_sk.seckey, ED25519_SECKEY_LEN)); - tt_assert(!tor_mem_is_zero((char *) s->keys.identity_pk.pubkey, + tt_assert(!fast_mem_is_zero((char *) s->keys.identity_pk.pubkey, ED25519_PUBKEY_LEN)); /* Check onion address from identity key. */ hs_build_address(&s->keys.identity_pk, s->config.version, addr); @@ -657,13 +672,15 @@ test_service_intro_point(void *arg) (void) arg; + update_approx_time(1481621834); + /* Test simple creation of an object. */ { - time_t now = time(NULL); + time_t now = approx_time(); ip = helper_create_service_ip(); tt_assert(ip); /* Make sure the authentication keypair is not zeroes. */ - tt_int_op(tor_mem_is_zero((const char *) &ip->auth_key_kp, + tt_int_op(fast_mem_is_zero((const char *) &ip->auth_key_kp, sizeof(ed25519_keypair_t)), OP_EQ, 0); /* The introduce2_max MUST be in that range. */ tt_u64_op(ip->introduce2_max, OP_GE, @@ -798,10 +815,11 @@ test_helper_functions(void *arg) const node_t *node = get_node_from_intro_point(ip); tt_ptr_op(node, OP_EQ, &mock_node); SMARTLIST_FOREACH_BEGIN(ip->base.link_specifiers, - hs_desc_link_specifier_t *, ls) { - if (ls->type == LS_LEGACY_ID) { + link_specifier_t *, ls) { + if (link_specifier_get_ls_type(ls) == LS_LEGACY_ID) { /* Change legacy id in link specifier which is not the mock node. */ - memset(ls->u.legacy_id, 'B', sizeof(ls->u.legacy_id)); + memset(link_specifier_getarray_un_legacy_id(ls), 'B', + link_specifier_getlen_un_legacy_id(ls)); } } SMARTLIST_FOREACH_END(ls); node = get_node_from_intro_point(ip); @@ -859,6 +877,10 @@ test_helper_functions(void *arg) done: /* This will free the service and all objects associated to it. */ + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_service_free_all(); UNMOCK(node_get_by_id); } @@ -868,7 +890,7 @@ static void test_intro_circuit_opened(void *arg) { int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; - hs_service_t *service; + hs_service_t *service = NULL; origin_circuit_t *circ = NULL; (void) arg; @@ -916,6 +938,10 @@ test_intro_circuit_opened(void *arg) done: circuit_free_(TO_CIRCUIT(circ)); + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(circuit_mark_for_close_); UNMOCK(relay_send_command_from_edge_); @@ -930,7 +956,7 @@ test_intro_established(void *arg) int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; uint8_t payload[RELAY_PAYLOAD_SIZE] = {0}; origin_circuit_t *circ = NULL; - hs_service_t *service; + hs_service_t *service = NULL; hs_service_intro_point_t *ip = NULL; (void) arg; @@ -985,12 +1011,15 @@ test_intro_established(void *arg) /* Send an empty payload. INTRO_ESTABLISHED cells are basically zeroes. */ ret = hs_service_receive_intro_established(circ, payload, sizeof(payload)); tt_int_op(ret, OP_EQ, 0); - tt_u64_op(ip->circuit_established, OP_EQ, 1); tt_int_op(TO_CIRCUIT(circ)->purpose, OP_EQ, CIRCUIT_PURPOSE_S_INTRO); done: if (circ) circuit_free_(TO_CIRCUIT(circ)); + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(circuit_mark_for_close_); } @@ -1002,7 +1031,7 @@ test_rdv_circuit_opened(void *arg) { int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; origin_circuit_t *circ = NULL; - hs_service_t *service; + hs_service_t *service = NULL; (void) arg; @@ -1033,6 +1062,10 @@ test_rdv_circuit_opened(void *arg) done: circuit_free_(TO_CIRCUIT(circ)); + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(circuit_mark_for_close_); UNMOCK(relay_send_command_from_edge_); @@ -1070,8 +1103,7 @@ test_closing_intro_circs(void *arg) /* Initialize intro circuit */ intro_circ = origin_circuit_init(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, flags); - intro_circ->hs_ident = hs_ident_circuit_new(&service->keys.identity_pk, - HS_IDENT_CIRCUIT_INTRO); + intro_circ->hs_ident = hs_ident_circuit_new(&service->keys.identity_pk); /* Register circuit in the circuitmap . */ hs_circuitmap_register_intro_circ_v3_service_side(intro_circ, &ip->auth_key_kp.pubkey); @@ -1097,8 +1129,7 @@ test_closing_intro_circs(void *arg) /* Now pretend that a new intro point circ was launched and opened. Check * that the intro point will be established correctly. */ intro_circ = origin_circuit_init(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, flags); - intro_circ->hs_ident = hs_ident_circuit_new(&service->keys.identity_pk, - HS_IDENT_CIRCUIT_INTRO); + intro_circ->hs_ident = hs_ident_circuit_new(&service->keys.identity_pk); ed25519_pubkey_copy(&intro_circ->hs_ident->intro_auth_pk, &ip->auth_key_kp.pubkey); /* Register circuit in the circuitmap . */ @@ -1120,6 +1151,10 @@ test_closing_intro_circs(void *arg) circuit_free_(TO_CIRCUIT(intro_circ)); } /* Frees the service object. */ + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(assert_circuit_ok); } @@ -1132,7 +1167,7 @@ test_introduce2(void *arg) int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; uint8_t payload[RELAY_PAYLOAD_SIZE] = {0}; origin_circuit_t *circ = NULL; - hs_service_t *service; + hs_service_t *service = NULL; hs_service_intro_point_t *ip = NULL; (void) arg; @@ -1142,7 +1177,7 @@ test_introduce2(void *arg) MOCK(get_or_state, get_or_state_replacement); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_INTRO, flags); tt_assert(circ); @@ -1199,6 +1234,10 @@ test_introduce2(void *arg) dummy_state = NULL; if (circ) circuit_free_(TO_CIRCUIT(circ)); + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(circuit_mark_for_close_); } @@ -1222,6 +1261,7 @@ test_service_event(void *arg) /* Set a service for this circuit. */ service = helper_create_service(); + tt_assert(service); ed25519_pubkey_copy(&circ->hs_ident->identity_pk, &service->keys.identity_pk); @@ -1253,7 +1293,6 @@ test_service_event(void *arg) * descriptor map so we can retry it. */ ip = helper_create_service_ip(); service_intro_point_add(service->desc_current->intro_points.map, ip); - ip->circuit_established = 1; /* We'll test that, it MUST be 0 after. */ run_housekeeping_event(now); tt_int_op(digest256map_size(service->desc_current->intro_points.map), OP_EQ, 1); @@ -1283,6 +1322,10 @@ test_service_event(void *arg) done: hs_circuitmap_remove_circuit(TO_CIRCUIT(circ)); circuit_free_(TO_CIRCUIT(circ)); + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(circuit_mark_for_close_); } @@ -1293,12 +1336,12 @@ test_rotate_descriptors(void *arg) { int ret; time_t next_rotation_time, now; - hs_service_t *service; + hs_service_t *service = NULL; hs_service_descriptor_t *desc_next; (void) arg; - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); hs_init(); MOCK(get_or_state, get_or_state_replacement); @@ -1385,6 +1428,10 @@ test_rotate_descriptors(void *arg) tt_assert(service->desc_next); done: + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); UNMOCK(get_or_state); UNMOCK(circuit_mark_for_close_); @@ -1397,9 +1444,8 @@ static void test_build_update_descriptors(void *arg) { int ret; - time_t now = time(NULL); node_t *node; - hs_service_t *service; + hs_service_t *service = NULL; hs_service_intro_point_t *ip_cur, *ip_next; routerinfo_t ri; @@ -1412,7 +1458,7 @@ test_build_update_descriptors(void *arg) MOCK(networkstatus_get_reasonably_live_consensus, mock_networkstatus_get_reasonably_live_consensus); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC", &mock_ns.valid_after); @@ -1423,7 +1469,8 @@ test_build_update_descriptors(void *arg) voting_schedule_recalculate_timing(get_options(), mock_ns.valid_after); update_approx_time(mock_ns.valid_after+1); - now = mock_ns.valid_after+1; + + time_t now = mock_ns.valid_after+1; /* Create a service without a current descriptor to trigger a build. */ service = helper_create_service(); @@ -1547,9 +1594,9 @@ test_build_update_descriptors(void *arg) tt_int_op(smartlist_len(ip_cur->base.link_specifiers), OP_EQ, 3); /* Make sure we have a valid encryption keypair generated when we pick an * intro point in the update process. */ - tt_assert(!tor_mem_is_zero((char *) ip_cur->enc_key_kp.seckey.secret_key, + tt_assert(!fast_mem_is_zero((char *) ip_cur->enc_key_kp.seckey.secret_key, CURVE25519_SECKEY_LEN)); - tt_assert(!tor_mem_is_zero((char *) ip_cur->enc_key_kp.pubkey.public_key, + tt_assert(!fast_mem_is_zero((char *) ip_cur->enc_key_kp.pubkey.public_key, CURVE25519_PUBKEY_LEN)); tt_u64_op(ip_cur->time_to_expire, OP_GE, now + INTRO_POINT_LIFETIME_MIN_SECONDS); @@ -1615,6 +1662,10 @@ test_build_update_descriptors(void *arg) tt_u64_op(service->desc_next->next_upload_time, OP_EQ, 0); done: + if (service) { + remove_service(get_hs_service_map(), service); + hs_service_free(service); + } hs_free_all(); nodelist_free_all(); } @@ -1627,6 +1678,7 @@ test_build_descriptors(void *arg) { int ret; time_t now = time(NULL); + hs_service_t *last_service = NULL; (void) arg; @@ -1637,7 +1689,7 @@ test_build_descriptors(void *arg) MOCK(networkstatus_get_reasonably_live_consensus, mock_networkstatus_get_reasonably_live_consensus); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC", &mock_ns.valid_after); @@ -1651,19 +1703,27 @@ test_build_descriptors(void *arg) * is disabled. */ { hs_service_t *service = helper_create_service(); + last_service = service; service_descriptor_free(service->desc_current); service->desc_current = NULL; build_all_descriptors(now); + tt_assert(service->desc_current); + tt_assert(service->desc_current->desc); + hs_desc_superencrypted_data_t *superencrypted; superencrypted = &service->desc_current->desc->superencrypted_data; tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16); + + helper_destroy_service(service); + last_service = NULL; } /* Generate a valid number of fake auth clients when the number of * clients is zero. */ { hs_service_t *service = helper_create_service_with_clients(0); + last_service = service; service_descriptor_free(service->desc_current); service->desc_current = NULL; @@ -1671,12 +1731,16 @@ test_build_descriptors(void *arg) hs_desc_superencrypted_data_t *superencrypted; superencrypted = &service->desc_current->desc->superencrypted_data; tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16); + + helper_destroy_service(service); + last_service = NULL; } /* Generate a valid number of fake auth clients when the number of * clients is not a multiple of 16. */ { hs_service_t *service = helper_create_service_with_clients(20); + last_service = service; service_descriptor_free(service->desc_current); service->desc_current = NULL; @@ -1684,12 +1748,16 @@ test_build_descriptors(void *arg) hs_desc_superencrypted_data_t *superencrypted; superencrypted = &service->desc_current->desc->superencrypted_data; tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32); + + helper_destroy_service(service); + last_service = NULL; } /* Do not generate any fake desc client when the number of clients is * a multiple of 16 but not zero. */ { hs_service_t *service = helper_create_service_with_clients(32); + last_service = service; service_descriptor_free(service->desc_current); service->desc_current = NULL; @@ -1697,9 +1765,13 @@ test_build_descriptors(void *arg) hs_desc_superencrypted_data_t *superencrypted; superencrypted = &service->desc_current->desc->superencrypted_data; tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32); + + helper_destroy_service(service); + last_service = NULL; } done: + helper_destroy_service(last_service); hs_free_all(); } @@ -1718,7 +1790,7 @@ test_upload_descriptors(void *arg) MOCK(networkstatus_get_reasonably_live_consensus, mock_networkstatus_get_reasonably_live_consensus); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", &mock_ns.valid_after); @@ -1848,9 +1920,9 @@ test_rendezvous1_parsing(void *arg) } /* Send out the RENDEZVOUS1 and make sure that our mock func worked */ - tt_assert(tor_mem_is_zero(rend1_payload, 32)); + tt_assert(fast_mem_is_zero(rend1_payload, 32)); hs_circ_service_rp_has_opened(service, service_circ); - tt_assert(!tor_mem_is_zero(rend1_payload, 32)); + tt_assert(!fast_mem_is_zero(rend1_payload, 32)); tt_int_op(rend1_payload_len, OP_EQ, HS_LEGACY_RENDEZVOUS_CELL_SIZE); /******************************/ |