diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/include.am | 2 | ||||
-rw-r--r-- | src/test/rend_test_helpers.c | 16 | ||||
-rw-r--r-- | src/test/rend_test_helpers.h | 1 | ||||
-rw-r--r-- | src/test/test.c | 1 | ||||
-rw-r--r-- | src/test/test.h | 1 | ||||
-rw-r--r-- | src/test/test_connection.c | 93 | ||||
-rw-r--r-- | src/test/test_connection.h | 13 | ||||
-rw-r--r-- | src/test/test_helpers.c | 96 | ||||
-rw-r--r-- | src/test/test_helpers.h | 9 | ||||
-rw-r--r-- | src/test/test_hs_client.c | 286 | ||||
-rw-r--r-- | src/test/test_hs_service.c | 94 | ||||
-rw-r--r-- | src/test/test_rendcache.c | 16 |
12 files changed, 514 insertions, 114 deletions
diff --git a/src/test/include.am b/src/test/include.am index 29ba1ce7c9..e7a2e0278b 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -115,6 +115,7 @@ src_test_test_SOURCES = \ src/test/test_extorport.c \ src/test/test_hs.c \ src/test/test_hs_service.c \ + src/test/test_hs_client.c \ src/test/test_hs_intropoint.c \ src/test/test_handles.c \ src/test/test_hs_cache.c \ @@ -270,6 +271,7 @@ noinst_HEADERS+= \ src/test/test.h \ src/test/test_helpers.h \ src/test/test_dir_common.h \ + src/test/test_connection.h \ src/test/test_descriptors.inc \ src/test/example_extrainfo.inc \ src/test/failing_routerdescs.inc \ diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c index f7880046fb..095bfecf21 100644 --- a/src/test/rend_test_helpers.c +++ b/src/test/rend_test_helpers.c @@ -71,3 +71,19 @@ create_descriptor(rend_service_descriptor_t **generated, char **service_id, crypto_pk_free(pk2); } +rend_data_t * +mock_rend_data(const char *onion_address) +{ + rend_data_v2_t *v2_data = tor_malloc_zero(sizeof(*v2_data)); + rend_data_t *rend_query = &v2_data->base_; + rend_query->version = 2; + + strlcpy(v2_data->onion_address, onion_address, + sizeof(v2_data->onion_address)); + v2_data->auth_type = REND_NO_AUTH; + rend_query->hsdirs_fp = smartlist_new(); + smartlist_add(rend_query->hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", + DIGEST_LEN)); + return rend_query; +} + diff --git a/src/test/rend_test_helpers.h b/src/test/rend_test_helpers.h index 486adba436..6f0ef114de 100644 --- a/src/test/rend_test_helpers.h +++ b/src/test/rend_test_helpers.h @@ -10,6 +10,7 @@ void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points); void create_descriptor(rend_service_descriptor_t **generated, char **service_id, int intro_points); +rend_data_t *mock_rend_data(const char *onion_address); #endif diff --git a/src/test/test.c b/src/test/test.c index 68f5f90fd7..31b3db3a4f 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1215,6 +1215,7 @@ struct testgroup_t testgroups[] = { { "hs_cache/", hs_cache }, { "hs_descriptor/", hs_descriptor }, { "hs_service/", hs_service_tests }, + { "hs_client/", hs_client_tests }, { "hs_intropoint/", hs_intropoint_tests }, { "introduce/", introduce_tests }, { "keypin/", keypin_tests }, diff --git a/src/test/test.h b/src/test/test.h index 6abaf39e6f..4de0da99fb 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -209,6 +209,7 @@ extern struct testcase_t hs_tests[]; extern struct testcase_t hs_cache[]; extern struct testcase_t hs_descriptor[]; extern struct testcase_t hs_service_tests[]; +extern struct testcase_t hs_client_tests[]; extern struct testcase_t hs_intropoint_tests[]; extern struct testcase_t introduce_tests[]; extern struct testcase_t keypin_tests[]; diff --git a/src/test/test_connection.c b/src/test/test_connection.c index 7e5193b203..f2529026f9 100644 --- a/src/test/test_connection.c +++ b/src/test/test_connection.c @@ -17,9 +17,8 @@ #include "rendcache.h" #include "directory.h" -static void test_conn_lookup_addr_helper(const char *address, - int family, - tor_addr_t *addr); +#include "test_connection.h" +#include "test_helpers.h" static void * test_conn_get_basic_setup(const struct testcase_t *tc); static int test_conn_get_basic_teardown(const struct testcase_t *tc, @@ -62,48 +61,7 @@ static int test_conn_get_rsrc_teardown(const struct testcase_t *tc, #define TEST_CONN_UNATTACHED_STATE (AP_CONN_STATE_CIRCUIT_WAIT) #define TEST_CONN_ATTACHED_STATE (AP_CONN_STATE_CONNECT_WAIT) -#define TEST_CONN_FD_INIT 50 -static int mock_connection_connect_sockaddr_called = 0; -static int fake_socket_number = TEST_CONN_FD_INIT; - -static int -mock_connection_connect_sockaddr(connection_t *conn, - const struct sockaddr *sa, - socklen_t sa_len, - const struct sockaddr *bindaddr, - socklen_t bindaddr_len, - int *socket_error) -{ - (void)sa_len; - (void)bindaddr; - (void)bindaddr_len; - - tor_assert(conn); - tor_assert(sa); - tor_assert(socket_error); - - mock_connection_connect_sockaddr_called++; - - conn->s = fake_socket_number++; - tt_assert(SOCKET_OK(conn->s)); - /* We really should call tor_libevent_initialize() here. Because we don't, - * we are relying on other parts of the code not checking if the_event_base - * (and therefore event->ev_base) is NULL. */ - tt_assert(connection_add_connecting(conn) == 0); - - done: - /* Fake "connected" status */ - return 1; -} - -static int -fake_close_socket(evutil_socket_t sock) -{ - (void)sock; - return 0; -} - -static void +void test_conn_lookup_addr_helper(const char *address, int family, tor_addr_t *addr) { int rv = 0; @@ -122,51 +80,6 @@ test_conn_lookup_addr_helper(const char *address, int family, tor_addr_t *addr) tor_addr_make_null(addr, TEST_CONN_FAMILY); } -static connection_t * -test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose) -{ - connection_t *conn = NULL; - tor_addr_t addr; - int socket_err = 0; - int in_progress = 0; - - MOCK(connection_connect_sockaddr, - mock_connection_connect_sockaddr); - MOCK(tor_close_socket, fake_close_socket); - - init_connection_lists(); - - conn = connection_new(type, TEST_CONN_FAMILY); - tt_assert(conn); - - test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &addr); - tt_assert(!tor_addr_is_null(&addr)); - - tor_addr_copy_tight(&conn->addr, &addr); - conn->port = TEST_CONN_PORT; - mock_connection_connect_sockaddr_called = 0; - in_progress = connection_connect(conn, TEST_CONN_ADDRESS_PORT, &addr, - TEST_CONN_PORT, &socket_err); - tt_assert(mock_connection_connect_sockaddr_called == 1); - tt_assert(!socket_err); - tt_assert(in_progress == 0 || in_progress == 1); - - /* fake some of the attributes so the connection looks OK */ - conn->state = state; - conn->purpose = purpose; - assert_connection_ok(conn, time(NULL)); - - UNMOCK(connection_connect_sockaddr); - UNMOCK(tor_close_socket); - return conn; - - /* On failure */ - done: - UNMOCK(connection_connect_sockaddr); - UNMOCK(tor_close_socket); - return NULL; -} - static void * test_conn_get_basic_setup(const struct testcase_t *tc) { diff --git a/src/test/test_connection.h b/src/test/test_connection.h new file mode 100644 index 0000000000..392783b53b --- /dev/null +++ b/src/test/test_connection.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** Some constants used by test_connection and helpers */ +#define TEST_CONN_FAMILY (AF_INET) +#define TEST_CONN_ADDRESS "127.0.0.1" +#define TEST_CONN_PORT (12345) +#define TEST_CONN_ADDRESS_PORT "127.0.0.1:12345" +#define TEST_CONN_FD_INIT 50 + +void test_conn_lookup_addr_helper(const char *address, + int family, tor_addr_t *addr); + diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index 9fada5a675..22d9de3f5b 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -7,9 +7,14 @@ */ #define ROUTERLIST_PRIVATE +#define CONNECTION_PRIVATE +#define MAIN_PRIVATE + #include "orconfig.h" #include "or.h" +#include "connection.h" +#include "main.h" #include "relay.h" #include "routerlist.h" #include "nodelist.h" @@ -17,6 +22,7 @@ #include "test.h" #include "test_helpers.h" +#include "test_connection.h" #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS DISABLE_GCC_WARNING(overlength-strings) @@ -143,3 +149,93 @@ mock_tor_addr_lookup__fail_on_bad_addrs(const char *name, return tor_addr_lookup__real(name, family, out); } +/*********** Helper funcs for making new connections/streams *****************/ + +/* Helper for test_conn_get_connection() */ +static int +fake_close_socket(evutil_socket_t sock) +{ + (void)sock; + return 0; +} + +static int mock_connection_connect_sockaddr_called = 0; +static int fake_socket_number = TEST_CONN_FD_INIT; + +/* Helper for test_conn_get_connection() */ +static int +mock_connection_connect_sockaddr(connection_t *conn, + const struct sockaddr *sa, + socklen_t sa_len, + const struct sockaddr *bindaddr, + socklen_t bindaddr_len, + int *socket_error) +{ + (void)sa_len; + (void)bindaddr; + (void)bindaddr_len; + + tor_assert(conn); + tor_assert(sa); + tor_assert(socket_error); + + mock_connection_connect_sockaddr_called++; + + conn->s = fake_socket_number++; + tt_assert(SOCKET_OK(conn->s)); + /* We really should call tor_libevent_initialize() here. Because we don't, + * we are relying on other parts of the code not checking if the_event_base + * (and therefore event->ev_base) is NULL. */ + tt_assert(connection_add_connecting(conn) == 0); + + done: + /* Fake "connected" status */ + return 1; +} + +/** Create and return a new connection/stream */ +connection_t * +test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose) +{ + connection_t *conn = NULL; + tor_addr_t addr; + int socket_err = 0; + int in_progress = 0; + + MOCK(connection_connect_sockaddr, + mock_connection_connect_sockaddr); + MOCK(tor_close_socket, fake_close_socket); + + init_connection_lists(); + + conn = connection_new(type, TEST_CONN_FAMILY); + tt_assert(conn); + + test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &addr); + tt_assert(!tor_addr_is_null(&addr)); + + tor_addr_copy_tight(&conn->addr, &addr); + conn->port = TEST_CONN_PORT; + mock_connection_connect_sockaddr_called = 0; + in_progress = connection_connect(conn, TEST_CONN_ADDRESS_PORT, &addr, + TEST_CONN_PORT, &socket_err); + tt_assert(mock_connection_connect_sockaddr_called == 1); + tt_assert(!socket_err); + tt_assert(in_progress == 0 || in_progress == 1); + + /* fake some of the attributes so the connection looks OK */ + conn->state = state; + conn->purpose = purpose; + assert_connection_ok(conn, time(NULL)); + + UNMOCK(connection_connect_sockaddr); + UNMOCK(tor_close_socket); + return conn; + + /* On failure */ + done: + UNMOCK(connection_connect_sockaddr); + UNMOCK(tor_close_socket); + return NULL; +} + diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h index 4621631cc1..96a4b594eb 100644 --- a/src/test/test_helpers.h +++ b/src/test/test_helpers.h @@ -1,9 +1,11 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TEST_HELPERS_H #define TOR_TEST_HELPERS_H +#include "or.h" + const char *get_yesterday_date_str(void); circuit_t * dummy_origin_circuit_new(int num_cells); @@ -20,7 +22,10 @@ void connection_write_to_buf_mock(const char *string, size_t len, int mock_tor_addr_lookup__fail_on_bad_addrs(const char *name, uint16_t family, tor_addr_t *out); +connection_t *test_conn_get_connection(uint8_t state, + uint8_t type, uint8_t purpose); + extern const char TEST_DESCRIPTORS[]; -#endif +#endif /* TOR_TEST_HELPERS_H */ diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c new file mode 100644 index 0000000000..77fee88eda --- /dev/null +++ b/src/test/test_hs_client.c @@ -0,0 +1,286 @@ +/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file test_hs_client.c + * \brief Test prop224 HS client functionality. + */ + +#define CRYPTO_PRIVATE +#define MAIN_PRIVATE +#define TOR_CHANNEL_INTERNAL_ +#define CIRCUITBUILD_PRIVATE +#define CIRCUITLIST_PRIVATE +#define CONNECTION_PRIVATE + +#include "test.h" +#include "test_helpers.h" +#include "log_test_helpers.h" +#include "rend_test_helpers.h" + +#include "config.h" +#include "crypto.h" +#include "channeltls.h" + +#include "hs_circuit.h" +#include "hs_ident.h" +#include "circuitlist.h" +#include "circuitbuild.h" +#include "connection.h" +#include "connection_edge.h" + +static int +mock_connection_ap_handshake_send_begin(entry_connection_t *ap_conn) +{ + (void) ap_conn; + return 0; +} + +/* Test helper function: Setup a circuit and a stream with the same hidden + * service destination, and put them in <b>circ_out</b> and + * <b>conn_out</b>. Make the stream wait for circuits to be established to the + * hidden service. */ +static int +helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out, + connection_t **conn_out, + int is_legacy) +{ + int retval; + channel_tls_t *n_chan=NULL; + rend_data_t *conn_rend_data = NULL; + origin_circuit_t *or_circ = NULL; + connection_t *conn = NULL; + ed25519_public_key_t service_pk; + + /* Make a dummy connection stream and make it wait for our circuit */ + conn = test_conn_get_connection(AP_CONN_STATE_CIRCUIT_WAIT, + CONN_TYPE_AP /* ??? */, + 0); + if (is_legacy) { + /* Legacy: Setup rend_data of stream */ + char service_id[REND_SERVICE_ID_LEN_BASE32+1] = {0}; + TO_EDGE_CONN(conn)->rend_data = mock_rend_data(service_id); + conn_rend_data = TO_EDGE_CONN(conn)->rend_data; + } else { + /* prop224: Setup hs conn identifier on the stream */ + ed25519_secret_key_t sk; + 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)); + + /* Setup hs_conn_identifier of stream */ + TO_EDGE_CONN(conn)->hs_ident = hs_ident_edge_conn_new(&service_pk); + } + + /* Make it wait for circuit */ + connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn)); + + /* This is needed to silence a BUG warning from + connection_edge_update_circuit_isolation() */ + TO_ENTRY_CONN(conn)->original_dest_address = + tor_strdup(TO_ENTRY_CONN(conn)->socks_request->address); + + /****************************************************/ + + /* Now make dummy circuit */ + or_circ = origin_circuit_new(); + + or_circ->base_.purpose = CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED; + + or_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t)); + or_circ->build_state->is_internal = 1; + + if (is_legacy) { + /* Legacy: Setup rend data and final cpath */ + or_circ->build_state->pending_final_cpath = + tor_malloc_zero(sizeof(crypt_path_t)); + or_circ->build_state->pending_final_cpath->magic = CRYPT_PATH_MAGIC; + or_circ->build_state->pending_final_cpath->rend_dh_handshake_state = + crypto_dh_new(DH_TYPE_REND); + tt_assert( + or_circ->build_state->pending_final_cpath->rend_dh_handshake_state); + retval = crypto_dh_generate_public( + or_circ->build_state->pending_final_cpath->rend_dh_handshake_state); + tt_int_op(retval, ==, 0); + 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); + } + + TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN; + + /* fake n_chan */ + n_chan = tor_malloc_zero(sizeof(channel_tls_t)); + n_chan->base_.global_identifier = 1; + or_circ->base_.n_chan = &(n_chan->base_); + + *circ_out = or_circ; + *conn_out = conn; + + return 0; + + done: + /* something failed */ + return -1; +} + +/* Test: Ensure that setting up legacy e2e rendezvous circuits works + * correctly. */ +static void +test_e2e_rend_circuit_setup_legacy(void *arg) +{ + int retval; + origin_circuit_t *or_circ = NULL; + connection_t *conn = NULL; + + (void) arg; + + /** In this test we create a v2 legacy HS stream and a circuit with the same + * hidden service destination. We make the stream wait for circuits to be + * established to the hidden service, and then we complete the circuit using + * the hs_circuit_setup_e2e_rend_circ_legacy_client() function. We then + * check that the end-to-end cpath was setup correctly and that the stream + * was attached to the circuit as expected. */ + + MOCK(connection_ap_handshake_send_begin, + mock_connection_ap_handshake_send_begin); + + /* Setup */ + retval = helper_get_circ_and_stream_for_test( &or_circ, &conn, 1); + tt_int_op(retval, OP_EQ, 0); + tt_assert(or_circ); + tt_assert(conn); + + /* Check number of hops */ + retval = cpath_get_n_hops(&or_circ->cpath); + tt_int_op(retval, ==, 0); + + /* Check that our stream is not attached on any circuits */ + tt_assert(!TO_EDGE_CONN(conn)->on_circuit); + + /********************************************** */ + + /* Make a good RENDEZVOUS1 cell body because it needs to pass key exchange + * digest verification... */ + uint8_t rend_cell_body[DH_KEY_LEN+DIGEST_LEN] = {2}; + { + char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN]; + crypto_dh_t *dh_state = + or_circ->build_state->pending_final_cpath->rend_dh_handshake_state; + /* compute and overwrite digest of cell body with the right value */ + retval = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh_state, + (char*)rend_cell_body, DH_KEY_LEN, + keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN); + tt_int_op(retval, OP_GT, 0); + memcpy(rend_cell_body+DH_KEY_LEN, keys, DIGEST_LEN); + } + + /* Setup the circuit */ + retval = hs_circuit_setup_e2e_rend_circ_legacy_client(or_circ, + rend_cell_body); + tt_int_op(retval, OP_EQ, 0); + + /**********************************************/ + + /* See that a hop was added to the circuit's cpath */ + retval = cpath_get_n_hops(&or_circ->cpath); + tt_int_op(retval, OP_EQ, 1); + + /* Check the digest algo */ + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->f_digest), + OP_EQ, DIGEST_SHA1); + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->b_digest), + OP_EQ, DIGEST_SHA1); + tt_assert(or_circ->cpath->f_crypto); + tt_assert(or_circ->cpath->b_crypto); + + /* Ensure that circ purpose was changed */ + tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_REND_JOINED); + + /* Test that stream got attached */ + tt_ptr_op(TO_EDGE_CONN(conn)->on_circuit, OP_EQ, TO_CIRCUIT(or_circ)); + + done: + connection_free_(conn); + tor_free(TO_CIRCUIT(or_circ)->n_chan); + circuit_free(TO_CIRCUIT(or_circ)); +} + +/* Test: Ensure that setting up v3 rendezvous circuits works correctly. */ +static void +test_e2e_rend_circuit_setup(void *arg) +{ + uint8_t ntor_key_seed[DIGEST256_LEN] = {0}; + origin_circuit_t *or_circ; + int retval; + connection_t *conn = NULL; + + (void) arg; + + /** In this test we create a prop224 v3 HS stream and a circuit with the same + * hidden service destination. We make the stream wait for circuits to be + * established to the hidden service, and then we complete the circuit using + * the hs_circuit_setup_e2e_rend_circ() function. We then check that the + * end-to-end cpath was setup correctly and that the stream was attached to + * the circuit as expected. */ + + MOCK(connection_ap_handshake_send_begin, + mock_connection_ap_handshake_send_begin); + + /* Setup */ + retval = helper_get_circ_and_stream_for_test( &or_circ, &conn, 0); + tt_int_op(retval, OP_EQ, 0); + tt_assert(or_circ); + tt_assert(conn); + + /* Check number of hops: There should be no hops yet to this circ */ + retval = cpath_get_n_hops(&or_circ->cpath); + tt_int_op(retval, ==, 0); + tt_assert(!or_circ->cpath); + + /* Check that our stream is not attached on any circuits */ + tt_assert(!TO_EDGE_CONN(conn)->on_circuit); + + /**********************************************/ + + /* Setup the circuit */ + retval = hs_circuit_setup_e2e_rend_circ(or_circ, + ntor_key_seed, sizeof(ntor_key_seed), + 0); + tt_int_op(retval, OP_EQ, 0); + + /**********************************************/ + + /* See that a hop was added to the circuit's cpath */ + retval = cpath_get_n_hops(&or_circ->cpath); + 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->f_digest), + OP_EQ, DIGEST_SHA3_256); + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->b_digest), + OP_EQ, DIGEST_SHA3_256); + tt_assert(or_circ->cpath->f_crypto); + tt_assert(or_circ->cpath->b_crypto); + + /* Ensure that circ purpose was changed */ + tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_REND_JOINED); + + /* Test that stream got attached */ + tt_ptr_op(TO_EDGE_CONN(conn)->on_circuit, OP_EQ, TO_CIRCUIT(or_circ)); + + done: + connection_free_(conn); + tor_free(TO_CIRCUIT(or_circ)->n_chan); + circuit_free(TO_CIRCUIT(or_circ)); +} + +struct testcase_t hs_client_tests[] = { + { "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy, + TT_FORK, NULL, NULL }, + { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, + TT_FORK, NULL, NULL }, + END_OF_TESTCASES +}; + diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index fcfb3b992d..17772f1df0 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -6,20 +6,34 @@ * \brief Test hidden service functionality. */ +#define CIRCUITBUILD_PRIVATE +#define CIRCUITLIST_PRIVATE +#define CONNECTION_PRIVATE +#define CRYPTO_PRIVATE #define HS_COMMON_PRIVATE -#define HS_SERVICE_PRIVATE #define HS_INTROPOINT_PRIVATE +#define MAIN_PRIVATE +#define TOR_CHANNEL_INTERNAL_ #include "test.h" #include "log_test_helpers.h" -#include "crypto.h" - -#include "hs/cell_establish_intro.h" +#include "rend_test_helpers.h" + +#include "or.h" +#include "channeltls.h" +#include "circuitbuild.h" +#include "circuitlist.h" +#include "circuituse.h" +#include "config.h" +#include "connection.h" +#include "hs_circuit.h" #include "hs_common.h" -#include "hs_service.h" +#include "hs_ident.h" #include "hs_intropoint.h" - #include "hs_ntor.h" +#include "hs_service.h" +#include "main.h" +#include "rendservice.h" /** We simulate the creation of an outgoing ESTABLISH_INTRO cell, and then we * parse it from the receiver side. */ @@ -235,6 +249,72 @@ test_time_period(void *arg) ; } +/* Test: Ensure that setting up rendezvous circuits works correctly. */ +static void +test_e2e_rend_circuit_setup(void *arg) +{ + ed25519_public_key_t service_pk; + origin_circuit_t *or_circ; + int retval; + + /** In this test we create a v3 prop224 service-side rendezvous circuit. + * We simulate an HS ntor key exchange with a client, and check that + * the circuit was setup correctly and is ready to accept rendezvous data */ + + (void) arg; + + /* Now make dummy circuit */ + { + or_circ = origin_circuit_new(); + + or_circ->base_.purpose = CIRCUIT_PURPOSE_S_CONNECT_REND; + + or_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t)); + or_circ->build_state->is_internal = 1; + + /* prop224: Setup hs conn identifier on the stream */ + ed25519_secret_key_t sk; + 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); + + TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN; + } + + /* Check number of hops */ + retval = cpath_get_n_hops(&or_circ->cpath); + tt_int_op(retval, OP_EQ, 0); + + /* 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); + tt_int_op(retval, OP_EQ, 0); + } + + /* See that a hop was added to the circuit's cpath */ + retval = cpath_get_n_hops(&or_circ->cpath); + tt_int_op(retval, OP_EQ, 1); + + /* Check the digest algo */ + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->f_digest), + OP_EQ, DIGEST_SHA3_256); + tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->b_digest), + OP_EQ, DIGEST_SHA3_256); + tt_assert(or_circ->cpath->f_crypto); + tt_assert(or_circ->cpath->b_crypto); + + /* Ensure that circ purpose was changed */ + tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED); + + done: + circuit_free(TO_CIRCUIT(or_circ)); +} + struct testcase_t hs_service_tests[] = { { "gen_establish_intro_cell", test_gen_establish_intro_cell, TT_FORK, NULL, NULL }, @@ -244,6 +324,8 @@ struct testcase_t hs_service_tests[] = { NULL, NULL }, { "time_period", test_time_period, TT_FORK, NULL, NULL }, + { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK, + NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c index feba8f664e..c1c178930a 100644 --- a/src/test/test_rendcache.c +++ b/src/test/test_rendcache.c @@ -21,22 +21,6 @@ static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \ REND_CACHE_MAX_SKEW + 60); static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 60; -static rend_data_t * -mock_rend_data(const char *onion_address) -{ - rend_data_v2_t *v2_data = tor_malloc_zero(sizeof(*v2_data)); - rend_data_t *rend_query = &v2_data->base_; - rend_query->version = 2; - - strlcpy(v2_data->onion_address, onion_address, - sizeof(v2_data->onion_address)); - v2_data->auth_type = REND_NO_AUTH; - rend_query->hsdirs_fp = smartlist_new(); - smartlist_add(rend_query->hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", - DIGEST_LEN)); - return rend_query; -} - static void test_rend_cache_lookup_entry(void *data) { |