aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_hs_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test_hs_client.c')
-rw-r--r--src/test/test_hs_client.c135
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(&ocirc->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(&ocirc->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
};