diff options
author | David Goulet <dgoulet@torproject.org> | 2017-07-21 13:57:10 -0400 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2017-08-24 13:03:28 -0400 |
commit | b91693f7c3099c691d0e5dbb60ac55df14b7bd68 (patch) | |
tree | 9bdff12a287841022fe79830276c8c6a087fd38f | |
parent | 6eb125d14bf69e9dad427fe4b1005477177acc04 (diff) | |
download | tor-b91693f7c3099c691d0e5dbb60ac55df14b7bd68.tar.gz tor-b91693f7c3099c691d0e5dbb60ac55df14b7bd68.zip |
prop224: Build ESTABLISH_RENDEZVOUS cell and logic
Add a function to build the cell.
Add a the logic to send the cell when the rendezvous circuit opens.
Signed-off-by: David Goulet <dgoulet@torproject.org>
-rw-r--r-- | src/or/hs_cell.c | 17 | ||||
-rw-r--r-- | src/or/hs_cell.h | 2 | ||||
-rw-r--r-- | src/or/hs_circuit.c | 51 | ||||
-rw-r--r-- | src/or/hs_circuit.h | 1 | ||||
-rw-r--r-- | src/or/hs_client.c | 4 |
5 files changed, 74 insertions, 1 deletions
diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c index 889cf7749b..64e164c061 100644 --- a/src/or/hs_cell.c +++ b/src/or/hs_cell.c @@ -847,3 +847,20 @@ hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, return cell_len; } +/* Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The + * encoded cell is put in cell_out which must be of at least + * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the + * caller should clear up the content of the cell. + * + * This function can't fail. */ +ssize_t +hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, + uint8_t *cell_out) +{ + tor_assert(rendezvous_cookie); + tor_assert(cell_out); + + memcpy(cell_out, rendezvous_cookie, HS_REND_COOKIE_LEN); + return HS_REND_COOKIE_LEN; +} + diff --git a/src/or/hs_cell.h b/src/or/hs_cell.h index a72009510c..29e451cf0f 100644 --- a/src/or/hs_cell.h +++ b/src/or/hs_cell.h @@ -93,6 +93,8 @@ ssize_t hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie, uint8_t *cell_out); ssize_t hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, uint8_t *cell_out); +ssize_t hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, + uint8_t *cell_out); /* Parse cell API. */ ssize_t hs_cell_parse_intro_established(const uint8_t *payload, diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c index 95100e9b3a..ee453d0d52 100644 --- a/src/or/hs_circuit.c +++ b/src/or/hs_circuit.c @@ -1084,3 +1084,54 @@ hs_circ_send_introduce1(origin_circuit_t *intro_circ, return ret; } +/* Send an ESTABLISH_RENDEZVOUS cell along the rendezvous circuit circ. On + * success, 0 is returned else -1 and the circuit is marked for close. */ +int +hs_circ_send_establish_rendezvous(origin_circuit_t *circ) +{ + ssize_t cell_len = 0; + uint8_t cell[RELAY_PAYLOAD_SIZE] = {0}; + + tor_assert(circ); + tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND); + + log_info(LD_REND, "Send an ESTABLISH_RENDEZVOUS cell on circuit %u", + TO_CIRCUIT(circ)->n_circ_id); + + /* Set timestamp_dirty, because circuit_expire_building expects it, + * and the rend cookie also means we've used the circ. */ + TO_CIRCUIT(circ)->timestamp_dirty = time(NULL); + + /* We've attempted to use this circuit. Probe it if we fail */ + pathbias_count_use_attempt(circ); + + /* Generate the RENDEZVOUS_COOKIE and place it in the identifier so we can + * complete the handshake when receiving the acknowledgement. */ + crypto_rand((char *) circ->hs_ident->rendezvous_cookie, HS_REND_COOKIE_LEN); + /* Generate the client keypair. No need to be extra strong, not long term */ + curve25519_keypair_generate(&circ->hs_ident->rendezvous_client_kp, 0); + + cell_len = + hs_cell_build_establish_rendezvous(circ->hs_ident->rendezvous_cookie, + cell); + if (BUG(cell_len < 0)) { + goto err; + } + + if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ), + RELAY_COMMAND_ESTABLISH_RENDEZVOUS, + (const char *) cell, cell_len, + circ->cpath->prev) < 0) { + /* Circuit has been marked for close */ + log_warn(LD_REND, "Unable to send ESTABLISH_RENDEZVOUS cell on " + "circuit %u", TO_CIRCUIT(circ)->n_circ_id); + memwipe(cell, 0, cell_len); + goto err; + } + + memwipe(cell, 0, cell_len); + return 0; + err: + return -1; +} + diff --git a/src/or/hs_circuit.h b/src/or/hs_circuit.h index f35ebf17db..3b0e3aca1c 100644 --- a/src/or/hs_circuit.h +++ b/src/or/hs_circuit.h @@ -48,6 +48,7 @@ int hs_circ_send_introduce1(origin_circuit_t *intro_circ, origin_circuit_t *rend_circ, const hs_desc_intro_point_t *ip, const uint8_t *subcredential); +int hs_circ_send_establish_rendezvous(origin_circuit_t *circ); /* e2e circuit API. */ diff --git a/src/or/hs_client.c b/src/or/hs_client.c index b06f3d9355..8865bb5fb5 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -381,7 +381,9 @@ client_rendezvous_circ_has_opened(origin_circuit_t *circ) safe_str_client( extend_info_describe(circ->build_state->chosen_exit))); - /* XXX Send ESTABLISH REND cell. */ + /* Ignore returned value, nothing we can really do. On failure, the circuit + * will be marked for close. */ + hs_circ_send_establish_rendezvous(circ); } /* ========== */ |