aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_hs_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test_hs_cache.c')
-rw-r--r--src/test/test_hs_cache.c190
1 files changed, 173 insertions, 17 deletions
diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c
index 742fa349d9..df96b2c791 100644
--- a/src/test/test_hs_cache.c
+++ b/src/test/test_hs_cache.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 */
/**
@@ -10,6 +10,7 @@
#define DIRCACHE_PRIVATE
#define DIRCLIENT_PRIVATE
#define HS_CACHE_PRIVATE
+#define CHANNEL_OBJECT_PRIVATE
#include "trunnel/ed25519_cert.h"
#include "feature/hs/hs_cache.h"
@@ -19,8 +20,14 @@
#include "feature/nodelist/networkstatus.h"
#include "core/mainloop/connection.h"
#include "core/proto/proto_http.h"
+#include "core/or/circuitlist.h"
+#include "core/or/channel.h"
#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/or/edge_connection_st.h"
+#include "core/or/or_circuit_st.h"
+#include "core/or/or_connection_st.h"
#include "feature/dircommon/dir_connection_st.h"
#include "feature/nodelist/networkstatus_st.h"
@@ -232,22 +239,31 @@ helper_fetch_desc_from_hsdir(const ed25519_public_key_t *blinded_key)
/* The dir conn we are going to simulate */
dir_connection_t *conn = NULL;
+ edge_connection_t *edge_conn = NULL;
+ or_circuit_t *or_circ = NULL;
/* First extract the blinded public key that we are going to use in our
query, and then build the actual query string. */
{
char hsdir_cache_key[ED25519_BASE64_LEN+1];
- retval = ed25519_public_to_base64(hsdir_cache_key,
- blinded_key);
- tt_int_op(retval, OP_EQ, 0);
+ ed25519_public_to_base64(hsdir_cache_key, blinded_key);
tor_asprintf(&hsdir_query_str, GET("/tor/hs/3/%s"), hsdir_cache_key);
}
/* Simulate an HTTP GET request to the HSDir */
conn = dir_connection_new(AF_INET);
+ tt_assert(conn);
+ TO_CONN(conn)->linked = 1; /* Signal that it is encrypted. */
tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001);
- TO_CONN(conn)->linked = 1;/* Pretend the conn is encrypted :) */
+
+ /* Pretend this conn is anonymous. */
+ edge_conn = edge_connection_new(CONN_TYPE_EXIT, AF_INET);
+ TO_CONN(conn)->linked_conn = TO_CONN(edge_conn);
+ or_circ = or_circuit_new(0, NULL);
+ or_circ->p_chan = tor_malloc_zero(sizeof(channel_t));
+ edge_conn->on_circuit = TO_CIRCUIT(or_circ);
+
retval = directory_handle_command_get(conn, hsdir_query_str,
NULL, 0);
tt_int_op(retval, OP_EQ, 0);
@@ -264,8 +280,11 @@ helper_fetch_desc_from_hsdir(const ed25519_public_key_t *blinded_key)
done:
tor_free(hsdir_query_str);
- if (conn)
+ if (conn) {
+ tor_free(or_circ->p_chan);
+ connection_free_minimal(TO_CONN(conn)->linked_conn);
connection_free_minimal(TO_CONN(conn));
+ }
return received_desc;
}
@@ -351,7 +370,7 @@ test_hsdir_revision_counter_check(void *arg)
hs_descriptor_t *published_desc = NULL;
char *published_desc_str = NULL;
- uint8_t subcredential[DIGEST256_LEN];
+ hs_subcredential_t subcredential;
char *received_desc_str = NULL;
hs_descriptor_t *received_desc = NULL;
@@ -388,12 +407,12 @@ test_hsdir_revision_counter_check(void *arg)
const ed25519_public_key_t *blinded_key;
blinded_key = &published_desc->plaintext_data.blinded_pubkey;
- hs_get_subcredential(&signing_kp.pubkey, blinded_key, subcredential);
+ hs_get_subcredential(&signing_kp.pubkey, blinded_key, &subcredential);
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
retval = hs_desc_decode_descriptor(received_desc_str,
- subcredential, NULL, &received_desc);
- tt_int_op(retval, OP_EQ, 0);
+ &subcredential, NULL, &received_desc);
+ tt_int_op(retval, OP_EQ, HS_DESC_DECODE_OK);
tt_assert(received_desc);
/* Check that the revision counter is correct */
@@ -425,8 +444,8 @@ test_hsdir_revision_counter_check(void *arg)
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
retval = hs_desc_decode_descriptor(received_desc_str,
- subcredential, NULL, &received_desc);
- tt_int_op(retval, OP_EQ, 0);
+ &subcredential, NULL, &received_desc);
+ tt_int_op(retval, OP_EQ, HS_DESC_DECODE_OK);
tt_assert(received_desc);
/* Check that the revision counter is the latest */
@@ -458,7 +477,7 @@ test_client_cache(void *arg)
ed25519_keypair_t signing_kp;
hs_descriptor_t *published_desc = NULL;
char *published_desc_str = NULL;
- uint8_t wanted_subcredential[DIGEST256_LEN];
+ hs_subcredential_t wanted_subcredential;
response_handler_args_t *args = NULL;
dir_connection_t *conn = NULL;
@@ -487,8 +506,10 @@ test_client_cache(void *arg)
retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
NULL, &published_desc_str);
tt_int_op(retval, OP_EQ, 0);
- memcpy(wanted_subcredential, published_desc->subcredential, DIGEST256_LEN);
- tt_assert(!tor_mem_is_zero((char*)wanted_subcredential, DIGEST256_LEN));
+ memcpy(&wanted_subcredential, &published_desc->subcredential,
+ sizeof(hs_subcredential_t));
+ tt_assert(!fast_mem_is_zero((char*)wanted_subcredential.subcred,
+ DIGEST256_LEN));
}
/* Test handle_response_fetch_hsdesc_v3() */
@@ -522,8 +543,9 @@ test_client_cache(void *arg)
const hs_descriptor_t *cached_desc = NULL;
cached_desc = hs_cache_lookup_as_client(&signing_kp.pubkey);
tt_assert(cached_desc);
- tt_mem_op(cached_desc->subcredential, OP_EQ, wanted_subcredential,
- DIGEST256_LEN);
+ tt_mem_op(cached_desc->subcredential.subcred,
+ OP_EQ, wanted_subcredential.subcred,
+ SUBCRED_LEN);
}
/* Progress time to next TP and check that desc was cleaned */
@@ -550,6 +572,136 @@ test_client_cache(void *arg)
}
}
+/** Test that we can store HS descriptors in the client HS cache. */
+static void
+test_client_cache_decrypt(void *arg)
+{
+ int ret;
+ char *desc_encoded = NULL;
+ uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
+ curve25519_keypair_t client_kp;
+ ed25519_keypair_t service_kp;
+ hs_descriptor_t *desc = NULL;
+ const hs_descriptor_t *search_desc;
+ const char *search_desc_encoded;
+
+ (void) arg;
+
+ /* Initialize HSDir cache subsystem */
+ hs_init();
+
+ MOCK(networkstatus_get_reasonably_live_consensus,
+ mock_networkstatus_get_reasonably_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 a valid descriptor with normal values. */
+ {
+ ret = ed25519_keypair_generate(&service_kp, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ ret = curve25519_keypair_generate(&client_kp, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ crypto_rand((char *) descriptor_cookie, sizeof(descriptor_cookie));
+
+ desc = hs_helper_build_hs_desc_with_client_auth(descriptor_cookie,
+ &client_kp.pubkey,
+ &service_kp);
+ tt_assert(desc);
+ ret = hs_desc_encode_descriptor(desc, &service_kp, descriptor_cookie,
+ &desc_encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ }
+
+ /* Put it in the cache. Should not be decrypted since the client
+ * authorization creds were not added to the global map. */
+ ret = hs_cache_store_as_client(desc_encoded, &service_kp.pubkey);
+ tt_int_op(ret, OP_EQ, HS_DESC_DECODE_NEED_CLIENT_AUTH);
+
+ /* We should not be able to decrypt anything. */
+ ret = hs_cache_client_new_auth_parse(&service_kp.pubkey);
+ tt_int_op(ret, OP_EQ, false);
+
+ /* Add client auth to global map. */
+ hs_helper_add_client_auth(&service_kp.pubkey, &client_kp.seckey);
+
+ /* We should not be able to decrypt anything. */
+ ret = hs_cache_client_new_auth_parse(&service_kp.pubkey);
+ tt_int_op(ret, OP_EQ, true);
+
+ /* Lookup the cache to make sure it is usable and there. */
+ search_desc = hs_cache_lookup_as_client(&service_kp.pubkey);
+ tt_assert(search_desc);
+ search_desc_encoded = hs_cache_lookup_encoded_as_client(&service_kp.pubkey);
+ tt_mem_op(search_desc_encoded, OP_EQ, desc_encoded, strlen(desc_encoded));
+
+ done:
+ hs_descriptor_free(desc);
+ tor_free(desc_encoded);
+
+ hs_free_all();
+
+ UNMOCK(networkstatus_get_reasonably_live_consensus);
+}
+
+static void
+test_client_cache_remove(void *arg)
+{
+ int ret;
+ ed25519_keypair_t service_kp;
+ hs_descriptor_t *desc1 = NULL;
+
+ (void) arg;
+
+ hs_init();
+
+ MOCK(networkstatus_get_reasonably_live_consensus,
+ mock_networkstatus_get_reasonably_live_consensus);
+
+ /* Set consensus time. Lookup will not return the entry if it has expired
+ * and it is checked against the consensus valid_after 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));
+
+ /* Build a 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, HS_DESC_DECODE_OK);
+ tor_free(encoded);
+ tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey));
+ }
+
+ /* Remove the cached entry. */
+ hs_cache_remove_as_client(&service_kp.pubkey);
+ tt_assert(!hs_cache_lookup_as_client(&service_kp.pubkey));
+
+ done:
+ hs_descriptor_free(desc1);
+ hs_free_all();
+
+ UNMOCK(networkstatus_get_reasonably_live_consensus);
+}
+
struct testcase_t hs_cache[] = {
/* Encoding tests. */
{ "directory", test_directory, TT_FORK,
@@ -562,6 +714,10 @@ struct testcase_t hs_cache[] = {
NULL, NULL },
{ "client_cache", test_client_cache, TT_FORK,
NULL, NULL },
+ { "client_cache_decrypt", test_client_cache_decrypt, TT_FORK,
+ NULL, NULL },
+ { "client_cache_remove", test_client_cache_remove, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};