diff options
Diffstat (limited to 'src/test/test_hs_client.c')
-rw-r--r-- | src/test/test_hs_client.c | 135 |
1 files changed, 121 insertions, 14 deletions
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index 2f2bb45581..b777dafdfb 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -14,6 +14,7 @@ #define CIRCUITBUILD_PRIVATE #define CIRCUITLIST_PRIVATE #define CONNECTION_PRIVATE +#define CRYPT_PATH_PRIVATE #include "test/test.h" #include "test/test_helpers.h" @@ -36,6 +37,7 @@ #include "feature/hs/hs_config.h" #include "feature/hs/hs_ident.h" #include "feature/hs/hs_cache.h" +#include "feature/rend/rendcache.h" #include "core/or/circuitlist.h" #include "core/or/circuitbuild.h" #include "core/mainloop/connection.h" @@ -44,6 +46,7 @@ #include "core/or/cpath_build_state_st.h" #include "core/or/crypt_path_st.h" +#include "core/or/crypt_path.h" #include "feature/dircommon/dir_connection_st.h" #include "core/or/entry_connection_st.h" #include "core/or/extend_info_st.h" @@ -157,8 +160,7 @@ helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out, or_circ->rend_data = rend_data_dup(conn_rend_data); } else { /* prop224: Setup hs ident on the circuit */ - 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; @@ -241,12 +243,14 @@ test_e2e_rend_circuit_setup_legacy(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_SHA1); - 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_SHA1); - 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_C_REND_JOINED); @@ -311,12 +315,14 @@ test_e2e_rend_circuit_setup(void *arg) tt_int_op(retval, OP_EQ, 1); /* Check that the crypt path has prop224 algorithm parameters */ - 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_C_REND_JOINED); @@ -395,7 +401,7 @@ test_client_pick_intro(void *arg) tt_assert(fetched_desc); tt_mem_op(fetched_desc->subcredential, OP_EQ, desc->subcredential, DIGEST256_LEN); - tt_assert(!tor_mem_is_zero((char*)fetched_desc->subcredential, + tt_assert(!fast_mem_is_zero((char*)fetched_desc->subcredential, DIGEST256_LEN)); tor_free(encoded); } @@ -403,6 +409,9 @@ test_client_pick_intro(void *arg) /* 2) Mark all intro points except _the chosen one_ as failed. Then query the * desc and get a random intro: check that we got _the chosen one_. */ { + /* Tell hs_get_extend_info_from_lspecs() to skip the private address check. + */ + get_options_mutable()->ExtendAllowPrivateAddresses = 1; /* Pick the chosen intro point and get its ei */ hs_desc_intro_point_t *chosen_intro_point = smartlist_get(desc->encrypted_data.intro_points, 0); @@ -430,7 +439,7 @@ test_client_pick_intro(void *arg) for (int i = 0; i < 64; ++i) { extend_info_t *ip = client_get_random_intro(&service_kp.pubkey); tor_assert(ip); - tt_assert(!tor_mem_is_zero((char*)ip->identity_digest, DIGEST_LEN)); + tt_assert(!fast_mem_is_zero((char*)ip->identity_digest, DIGEST_LEN)); tt_mem_op(ip->identity_digest, OP_EQ, chosen_intro_ei->identity_digest, DIGEST_LEN); extend_info_free(ip); @@ -476,6 +485,18 @@ test_client_pick_intro(void *arg) SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points, hs_desc_intro_point_t *, ip) { extend_info_t *intro_ei = desc_intro_point_to_extend_info(ip); + /* desc_intro_point_to_extend_info() doesn't return IPv6 intro points + * yet, because we can't extend to them. See #24404, #24451, and #24181. + */ + if (intro_ei == NULL) { + /* Pretend we're making a direct connection, and that we can use IPv6 + */ + get_options_mutable()->ClientUseIPv6 = 1; + intro_ei = hs_get_extend_info_from_lspecs(ip->link_specifiers, + &ip->onion_key, 1); + tt_assert(tor_addr_family(&intro_ei->addr) == AF_INET6); + } + tt_assert(intro_ei); if (intro_ei) { const char *ptr; char ip_addr[TOR_ADDR_BUF_LEN]; @@ -942,8 +963,7 @@ test_close_intro_circuits_new_desc(void *arg) const hs_desc_intro_point_t *ip = smartlist_get(desc1->encrypted_data.intro_points, 0); tt_assert(ip); - ocirc->hs_ident = hs_ident_circuit_new(&service_kp.pubkey, - HS_IDENT_CIRCUIT_INTRO); + ocirc->hs_ident = hs_ident_circuit_new(&service_kp.pubkey); ed25519_pubkey_copy(ô->hs_ident->intro_auth_pk, &ip->auth_key_cert->signed_key); } @@ -986,6 +1006,91 @@ test_close_intro_circuits_new_desc(void *arg) UNMOCK(networkstatus_get_live_consensus); } +static void +test_close_intro_circuits_cache_clean(void *arg) +{ + int ret; + ed25519_keypair_t service_kp; + circuit_t *circ = NULL; + origin_circuit_t *ocirc = NULL; + hs_descriptor_t *desc1 = NULL; + + (void) arg; + + hs_init(); + rend_cache_init(); + + /* This is needed because of the client cache expiration timestamp is based + * on having a consensus. See cached_client_descriptor_has_expired(). */ + MOCK(networkstatus_get_live_consensus, + mock_networkstatus_get_live_consensus); + + /* Set consensus time */ + parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", + &mock_ns.valid_after); + parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC", + &mock_ns.fresh_until); + parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC", + &mock_ns.valid_until); + + /* Generate service keypair */ + tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0)); + + /* Create and add to the global list a dummy client introduction circuits. + * We'll then make sure the hs_ident is attached to a dummy descriptor. */ + circ = dummy_origin_circuit_new(0); + tt_assert(circ); + circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING; + ocirc = TO_ORIGIN_CIRCUIT(circ); + + /* Build the first descriptor and cache it. */ + { + char *encoded; + desc1 = hs_helper_build_hs_desc_with_ip(&service_kp); + tt_assert(desc1); + ret = hs_desc_encode_descriptor(desc1, &service_kp, NULL, &encoded); + tt_int_op(ret, OP_EQ, 0); + tt_assert(encoded); + + /* Store it */ + ret = hs_cache_store_as_client(encoded, &service_kp.pubkey); + tt_int_op(ret, OP_EQ, 0); + tor_free(encoded); + tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey)); + } + + /* We'll pick one introduction point and associate it with the circuit. */ + { + const hs_desc_intro_point_t *ip = + smartlist_get(desc1->encrypted_data.intro_points, 0); + tt_assert(ip); + ocirc->hs_ident = hs_ident_circuit_new(&service_kp.pubkey); + ed25519_pubkey_copy(ô->hs_ident->intro_auth_pk, + &ip->auth_key_cert->signed_key); + } + + /* Before we are about to clean up the intro circuits, make sure it is + * actually there. */ + tt_assert(circuit_get_next_intro_circ(NULL, true)); + + /* Cleanup the client cache. The ns valid after time is what decides if the + * descriptor has expired so put it in the future enough (72h) so we are + * sure to always expire. */ + mock_ns.valid_after = approx_time() + (72 * 24 * 60 * 60); + hs_cache_clean_as_client(0); + + /* Once stored, our intro circuit should be closed because it is related to + * an old introduction point that doesn't exists anymore. */ + tt_assert(!circuit_get_next_intro_circ(NULL, true)); + + done: + circuit_free(circ); + hs_descriptor_free(desc1); + hs_free_all(); + rend_cache_free_all(); + UNMOCK(networkstatus_get_live_consensus); +} + struct testcase_t hs_client_tests[] = { { "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy, TT_FORK, NULL, NULL }, @@ -1005,6 +1110,8 @@ struct testcase_t hs_client_tests[] = { TT_FORK, NULL, NULL }, { "close_intro_circuits_new_desc", test_close_intro_circuits_new_desc, TT_FORK, NULL, NULL }, + { "close_intro_circuits_cache_clean", test_close_intro_circuits_cache_clean, + TT_FORK, NULL, NULL }, END_OF_TESTCASES }; |