diff options
author | George Kadianakis <desnacked@riseup.net> | 2017-09-25 15:00:06 +0300 |
---|---|---|
committer | George Kadianakis <desnacked@riseup.net> | 2017-09-25 15:00:06 +0300 |
commit | 03b3f5486ae169dd53e2b5fc1bca1c9ba7c8f5da (patch) | |
tree | b72e9cf832133560dfa65272fc3b2c22c1e0610b | |
parent | a3f5a246693cca2f6a51e418e6edf8fae2fe75b5 (diff) | |
download | tor-03b3f5486ae169dd53e2b5fc1bca1c9ba7c8f5da.tar.gz tor-03b3f5486ae169dd53e2b5fc1bca1c9ba7c8f5da.zip |
prop224: Add test for parsing RENDEZVOUS1 cell.
Just making sure that added padding does not screw up cell parsing.
-rw-r--r-- | src/or/hs_circuit.c | 6 | ||||
-rw-r--r-- | src/or/hs_circuit.h | 10 | ||||
-rw-r--r-- | src/or/hs_client.c | 2 | ||||
-rw-r--r-- | src/or/hs_client.h | 3 | ||||
-rw-r--r-- | src/test/test_hs_service.c | 131 |
5 files changed, 148 insertions, 4 deletions
diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c index 01e987c402..e1e513c5f4 100644 --- a/src/or/hs_circuit.c +++ b/src/or/hs_circuit.c @@ -5,6 +5,8 @@ * \file hs_circuit.c **/ +#define HS_CIRCUIT_PRIVATE + #include "or.h" #include "circpathbias.h" #include "circuitbuild.h" @@ -18,10 +20,10 @@ #include "router.h" #include "hs_cell.h" -#include "hs_circuit.h" #include "hs_ident.h" #include "hs_ntor.h" #include "hs_service.h" +#include "hs_circuit.h" /* Trunnel. */ #include "ed25519_cert.h" @@ -235,7 +237,7 @@ count_opened_desc_intro_point_circuits(const hs_service_t *service, /* From a given service, rendezvous cookie and handshake info, create a * rendezvous point circuit identifier. This can't fail. */ -static hs_ident_circuit_t * +STATIC hs_ident_circuit_t * create_rp_circuit_identifier(const hs_service_t *service, const uint8_t *rendezvous_cookie, const curve25519_public_key_t *server_pk, diff --git a/src/or/hs_circuit.h b/src/or/hs_circuit.h index 9085e3fb0b..0a1186dbaa 100644 --- a/src/or/hs_circuit.h +++ b/src/or/hs_circuit.h @@ -59,5 +59,15 @@ int hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, int hs_circuit_setup_e2e_rend_circ_legacy_client(origin_circuit_t *circ, const uint8_t *rend_cell_body); +#ifdef HS_CIRCUIT_PRIVATE + +STATIC hs_ident_circuit_t * +create_rp_circuit_identifier(const hs_service_t *service, + const uint8_t *rendezvous_cookie, + const curve25519_public_key_t *server_pk, + const hs_ntor_rend_cell_keys_t *keys); + +#endif + #endif /* !defined(TOR_HS_CIRCUIT_H) */ diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 77fbf548ed..e29f8beca7 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -845,7 +845,7 @@ handle_introduce_ack(origin_circuit_t *circ, const uint8_t *payload, /* Called when we get a RENDEZVOUS2 cell on the rendezvous circuit circ. The * encoded cell is in payload of length payload_len. Return 0 on success or a * negative value on error. On error, the circuit is marked for close. */ -static int +STATIC int handle_rendezvous2(origin_circuit_t *circ, const uint8_t *payload, size_t payload_len) { diff --git a/src/or/hs_client.h b/src/or/hs_client.h index 4eee1174bd..08ab7736b6 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -77,6 +77,9 @@ client_get_random_intro(const ed25519_public_key_t *service_pk); STATIC extend_info_t * desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip); +STATIC int handle_rendezvous2(origin_circuit_t *circ, const uint8_t *payload, + size_t payload_len); + #endif /* defined(HS_CLIENT_PRIVATE) */ #endif /* !defined(TOR_HS_CLIENT_H) */ diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index ca6af43ba7..859476b703 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -14,10 +14,12 @@ #define HS_COMMON_PRIVATE #define HS_SERVICE_PRIVATE #define HS_INTROPOINT_PRIVATE +#define HS_CIRCUIT_PRIVATE #define MAIN_PRIVATE #define NETWORKSTATUS_PRIVATE #define STATEFILE_PRIVATE #define TOR_CHANNEL_INTERNAL_ +#define HS_CLIENT_PRIVATE #include "test.h" #include "test_helpers.h" @@ -37,11 +39,12 @@ #include "hs_common.h" #include "hs_config.h" -#include "hs_circuit.h" #include "hs_ident.h" #include "hs_intropoint.h" #include "hs_ntor.h" +#include "hs_circuit.h" #include "hs_service.h" +#include "hs_client.h" #include "main.h" #include "rendservice.h" #include "statefile.h" @@ -1366,6 +1369,130 @@ test_revision_counter_state(void *arg) service_descriptor_free(desc_two); } +/** Global vars used by test_rendezvous1_parsing() */ +char rend1_payload[RELAY_PAYLOAD_SIZE]; +size_t rend1_payload_len = 0; + +/** Mock for relay_send_command_from_edge() to send a RENDEZVOUS1 cell. Instead + * of sending it to the network, instead save it to the global `rend1_payload` + * variable so that we can inspect it in the test_rendezvous1_parsing() + * test. */ +static int +mock_relay_send_rendezvous1(streamid_t stream_id, circuit_t *circ, + uint8_t relay_command, const char *payload, + size_t payload_len, + crypt_path_t *cpath_layer, + const char *filename, int lineno) +{ + (void) stream_id; + (void) circ; + (void) relay_command; + (void) cpath_layer; + (void) filename; + (void) lineno; + + memcpy(rend1_payload, payload, payload_len); + rend1_payload_len = payload_len; + + return 0; +} + +/** Send a RENDEZVOUS1 as a service, and parse it as a client. */ +static void +test_rendezvous1_parsing(void *arg) +{ + int retval; + static const char *test_addr = + "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad.onion"; + hs_service_t *service = NULL; + origin_circuit_t *service_circ = NULL; + origin_circuit_t *client_circ = NULL; + ed25519_keypair_t ip_auth_kp; + curve25519_keypair_t ephemeral_kp; + curve25519_keypair_t client_kp; + curve25519_keypair_t ip_enc_kp; + int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; + + (void) arg; + + MOCK(relay_send_command_from_edge_, mock_relay_send_rendezvous1); + + { + /* Let's start by setting up the service that will start the rend */ + service = tor_malloc_zero(sizeof(hs_service_t)); + ed25519_secret_key_generate(&service->keys.identity_sk, 0); + ed25519_public_key_generate(&service->keys.identity_pk, + &service->keys.identity_sk); + memcpy(service->onion_address, test_addr, sizeof(service->onion_address)); + tt_assert(service); + } + + { + /* Now let's set up the service rendezvous circuit and its keys. */ + service_circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_CONNECT_REND, + flags); + tor_free(service_circ->hs_ident); + hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys; + uint8_t rendezvous_cookie[HS_REND_COOKIE_LEN]; + curve25519_keypair_generate(&ip_enc_kp, 0); + curve25519_keypair_generate(&ephemeral_kp, 0); + curve25519_keypair_generate(&client_kp, 0); + ed25519_keypair_generate(&ip_auth_kp, 0); + retval = hs_ntor_service_get_rendezvous1_keys(&ip_auth_kp.pubkey, + &ip_enc_kp, + &ephemeral_kp, + &client_kp.pubkey, + &hs_ntor_rend_cell_keys); + tt_int_op(retval, OP_EQ, 0); + + memset(rendezvous_cookie, 2, sizeof(rendezvous_cookie)); + service_circ->hs_ident = + create_rp_circuit_identifier(service, rendezvous_cookie, + &ephemeral_kp.pubkey, + &hs_ntor_rend_cell_keys); + } + + /* Send out the RENDEZVOUS1 and make sure that our mock func worked */ + tt_assert(tor_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_int_op(rend1_payload_len, OP_EQ, HS_LEGACY_RENDEZVOUS_CELL_SIZE); + + /******************************/ + + /** Now let's create the client rendezvous circuit */ + client_circ = + helper_create_origin_circuit(CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED, + flags); + /* fix up its circ ident */ + ed25519_pubkey_copy(&client_circ->hs_ident->intro_auth_pk, + &ip_auth_kp.pubkey); + memcpy(&client_circ->hs_ident->rendezvous_client_kp, + &client_kp, sizeof(client_circ->hs_ident->rendezvous_client_kp)); + memcpy(&client_circ->hs_ident->intro_enc_pk.public_key, + &ip_enc_kp.pubkey.public_key, + sizeof(client_circ->hs_ident->intro_enc_pk.public_key)); + + /* Now parse the rendezvous2 circuit and make sure it was fine. We are + * skipping 20 bytes off its payload, since that's the rendezvous cookie + * which is only present in REND1. */ + retval = handle_rendezvous2(client_circ, + (uint8_t*)rend1_payload+20, + rend1_payload_len-20); + tt_int_op(retval, OP_EQ, 0); + + /* TODO: We are only simulating client/service here. We could also simulate + * the rendezvous point by plugging in rend_mid_establish_rendezvous(). We + * would need an extra circuit and some more stuff but it's doable. */ + + done: + circuit_free(TO_CIRCUIT(service_circ)); + circuit_free(TO_CIRCUIT(client_circ)); + hs_service_free(service); + hs_free_all(); + UNMOCK(relay_send_command_from_edge_); +} + struct testcase_t hs_service_tests[] = { { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK, NULL, NULL }, @@ -1395,6 +1522,8 @@ struct testcase_t hs_service_tests[] = { NULL, NULL }, { "revision_counter_state", test_revision_counter_state, TT_FORK, NULL, NULL }, + { "rendezvous1_parsing", test_rendezvous1_parsing, TT_FORK, + NULL, NULL }, END_OF_TESTCASES }; |