commit 6eb125d14bf69e9dad427fe4b1005477177acc04 Author: David Goulet dgoulet@torproject.org Date: Fri Jul 21 13:56:10 2017 -0400
prop224: Client has opened circuit logic
Make a single entry point for the entire HS subsystem when a client circuit opens (every HS version).
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/circuituse.c | 4 +- src/or/hs_client.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/or/hs_client.h | 2 + 3 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 21cc9c540..5b35155ee 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1636,7 +1636,7 @@ circuit_has_opened(origin_circuit_t *circ)
switch (TO_CIRCUIT(circ)->purpose) { case CIRCUIT_PURPOSE_C_ESTABLISH_REND: - rend_client_rendcirc_has_opened(circ); + hs_client_circuit_has_opened(circ); /* Start building an intro circ if we don't have one yet. */ connection_ap_attach_pending(1); /* This isn't a call to circuit_try_attaching_streams because a @@ -1648,7 +1648,7 @@ circuit_has_opened(origin_circuit_t *circ) * state. */ break; case CIRCUIT_PURPOSE_C_INTRODUCING: - rend_client_introcirc_has_opened(circ); + hs_client_circuit_has_opened(circ); break; case CIRCUIT_PURPOSE_C_GENERAL: /* Tell any AP connections that have been waiting for a new diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 3f951a21a..b06f3d935 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -308,6 +308,82 @@ send_introduce1(origin_circuit_t *intro_circ, return status; }
+/* Using the introduction circuit circ, setup the authentication key of the + * intro point this circuit has extended to. */ +static void +setup_intro_circ_auth_key(origin_circuit_t *circ) +{ + const hs_descriptor_t *desc; + + tor_assert(circ); + + desc = hs_cache_lookup_as_client(&circ->hs_ident->identity_pk); + if (BUG(desc == NULL)) { + /* Opening intro circuit without the descriptor is no good... */ + goto end; + } + + /* We will go over every intro point and try to find which one is linked to + * that circuit. Those lists are small so it's not that expensive. */ + SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points, + const hs_desc_intro_point_t *, ip) { + SMARTLIST_FOREACH_BEGIN(ip->link_specifiers, + const hs_desc_link_specifier_t *, lspec) { + /* Not all tor node have an ed25519 identity key so we still rely on the + * legacy identity digest. */ + if (lspec->type != LS_LEGACY_ID) { + continue; + } + if (fast_memneq(circ->build_state->chosen_exit->identity_digest, + lspec->u.legacy_id, DIGEST_LEN)) { + break; + } + /* We got it, copy its authentication key to the identifier. */ + ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk, + &ip->auth_key_cert->signed_key); + goto end; + } SMARTLIST_FOREACH_END(lspec); + } SMARTLIST_FOREACH_END(ip); + + /* Reaching this point means we didn't find any intro point for this circuit + * which is not suppose to happen. */ + tor_assert_nonfatal_unreached(); + + end: + return; +} + +/* Called when an introduction circuit has opened. */ +static void +client_intro_circ_has_opened(origin_circuit_t *circ) +{ + tor_assert(circ); + tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_INTRODUCING); + log_info(LD_REND, "Introduction circuit %u has opened. Attaching streams.", + (unsigned int) TO_CIRCUIT(circ)->n_circ_id); + + /* This is an introduction circuit so we'll attach the correct + * authentication key to the circuit identifier so it can be identified + * properly later on. */ + setup_intro_circ_auth_key(circ); + + connection_ap_attach_pending(1); +} + +/* Called when a rendezvous circuit has opened. */ +static void +client_rendezvous_circ_has_opened(origin_circuit_t *circ) +{ + tor_assert(circ); + tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND); + + log_info(LD_REND, "Rendezvous circuit has opened to %s.", + safe_str_client( + extend_info_describe(circ->build_state->chosen_exit))); + + /* XXX Send ESTABLISH REND cell. */ +} + /* ========== */ /* Public API */ /* ========== */ @@ -430,3 +506,33 @@ hs_client_send_introduce1(origin_circuit_t *intro_circ, rend_circ); }
+/* Called when the client circuit circ has been established. It can be either + * an introduction or rendezvous circuit. This function handles all hidden + * service versions. */ +void +hs_client_circuit_has_opened(origin_circuit_t *circ) +{ + tor_assert(circ); + + /* Handle both version. v2 uses rend_data and v3 uses the hs circuit + * identifier hs_ident. Can't be both. */ + switch (TO_CIRCUIT(circ)->purpose) { + case CIRCUIT_PURPOSE_C_INTRODUCING: + if (circ->hs_ident) { + client_intro_circ_has_opened(circ); + } else { + rend_client_introcirc_has_opened(circ); + } + break; + case CIRCUIT_PURPOSE_C_ESTABLISH_REND: + if (circ->hs_ident) { + client_rendezvous_circ_has_opened(circ); + } else { + rend_client_rendcirc_has_opened(circ); + } + break; + default: + tor_assert_nonfatal_unreached(); + } +} + diff --git a/src/or/hs_client.h b/src/or/hs_client.h index d8348ddb3..a716fc02e 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -25,5 +25,7 @@ int hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk); int hs_client_send_introduce1(origin_circuit_t *intro_circ, origin_circuit_t *rend_circ);
+void hs_client_circuit_has_opened(origin_circuit_t *circ); + #endif /* TOR_HS_CLIENT_H */
tor-commits@lists.torproject.org