diff --git a/src/or/circuituse.c b/src/or/circuituse.c index af061527d6..4d450f1147 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1636,11 +1636,11 @@ circuit_has_opened(origin_circuit_t *circ) break; case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO: /* at the service, waiting for introductions */ - rend_service_intro_has_opened(circ); + hs_service_circuit_has_opened(circ); break; case CIRCUIT_PURPOSE_S_CONNECT_REND: /* at the service, connecting to rend point */ - rend_service_rendezvous_has_opened(circ); + hs_service_circuit_has_opened(circ); break; case CIRCUIT_PURPOSE_TESTING: circuit_testing_opened(circ); diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c new file mode 100644 index 0000000000..e15f4e3e55 --- /dev/null +++ b/src/or/hs_cell.c @@ -0,0 +1,163 @@ +/* Copyright (c) 2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file hs_cell.c + * \brief Hidden service API for cell creation and handling. + **/ + +#include "or.h" +#include "rendservice.h" + +#include "hs_cell.h" + +/* Trunnel. */ +#include "hs/cell_common.h" +#include "hs/cell_establish_intro.h" + +/* Build a legacy ESTABLISH_INTRO cell with the given circuit nonce and RSA + * encryption key. The encoded cell is put in cell_out that MUST at least be + * of the size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on + * success else a negative value and cell_out is untouched. */ +static ssize_t +build_legacy_establish_intro(const char *circ_nonce, crypto_pk_t *enc_key, + uint8_t *cell_out) +{ + ssize_t cell_len; + char buf[RELAY_PAYLOAD_SIZE] = {0}; + + tor_assert(circ_nonce); + tor_assert(enc_key); + tor_assert(cell_out); + + cell_len = rend_service_encode_establish_intro_cell(buf, sizeof(buf), + enc_key, circ_nonce); + tor_assert(cell_len <= RELAY_PAYLOAD_SIZE); + if (cell_len >= 0) { + memcpy(cell_out, buf, cell_len); + } + return cell_len; +} + +/* ========== */ +/* Public API */ +/* ========== */ + +/* Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point + * object. The encoded cell is put in cell_out that MUST at least be of the + * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else + * a negative value and cell_out is untouched. This function also supports + * legacy cell creation. */ +ssize_t +hs_cell_build_establish_intro(const char *circ_nonce, + const hs_service_intro_point_t *ip, + uint8_t *cell_out) +{ + ssize_t cell_len = -1; + uint16_t sig_len = ED25519_SIG_LEN; + trn_cell_extension_t *ext; + trn_cell_establish_intro_t *cell = NULL; + + tor_assert(circ_nonce); + tor_assert(ip); + + /* Quickly handle the legacy IP. */ + if (ip->base.is_only_legacy) { + tor_assert(ip->legacy_key); + cell_len = build_legacy_establish_intro(circ_nonce, ip->legacy_key, + cell_out); + tor_assert(cell_len <= RELAY_PAYLOAD_SIZE); + /* Success or not we are done here. */ + goto done; + } + + /* Set extension data. None used here. */ + ext = trn_cell_extension_new(); + trn_cell_extension_set_num(ext, 0); + cell = trn_cell_establish_intro_new(); + trn_cell_establish_intro_set_extensions(cell, ext); + /* Set signature size. Array is then allocated in the cell. We need to do + * this early so we can use trunnel API to get the signature length. */ + trn_cell_establish_intro_set_sig_len(cell, sig_len); + trn_cell_establish_intro_setlen_sig(cell, sig_len); + + /* Set AUTH_KEY_TYPE: 2 means ed25519 */ + trn_cell_establish_intro_set_auth_key_type(cell, + HS_INTRO_AUTH_KEY_TYPE_ED25519); + + /* Set AUTH_KEY and AUTH_KEY_LEN field. Must also set byte-length of + * AUTH_KEY to match */ + { + uint16_t auth_key_len = ED25519_PUBKEY_LEN; + trn_cell_establish_intro_set_auth_key_len(cell, auth_key_len); + trn_cell_establish_intro_setlen_auth_key(cell, auth_key_len); + /* We do this call _after_ setting the length because it's reallocated at + * that point only. */ + uint8_t *auth_key_ptr = trn_cell_establish_intro_getarray_auth_key(cell); + memcpy(auth_key_ptr, ip->auth_key_kp.pubkey.pubkey, auth_key_len); + } + + /* Calculate HANDSHAKE_AUTH field (MAC). */ + { + ssize_t tmp_cell_enc_len = 0; + ssize_t tmp_cell_mac_offset = + sig_len + sizeof(cell->sig_len) + + trn_cell_establish_intro_getlen_handshake_mac(cell); + uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0}; + uint8_t mac[TRUNNEL_SHA3_256_LEN], *handshake_ptr; + + /* We first encode the current fields we have in the cell so we can + * compute the MAC using the raw bytes. */ + tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc, + sizeof(tmp_cell_enc), + cell); + if (BUG(tmp_cell_enc_len < 0)) { + goto done; + } + /* Sanity check. */ + tor_assert(tmp_cell_enc_len > tmp_cell_mac_offset); + + /* Circuit nonce is always DIGEST_LEN according to tor-spec.txt. */ + crypto_mac_sha3_256(mac, sizeof(mac), + (uint8_t *) circ_nonce, DIGEST_LEN, + tmp_cell_enc, tmp_cell_enc_len - tmp_cell_mac_offset); + handshake_ptr = trn_cell_establish_intro_getarray_handshake_mac(cell); + memcpy(handshake_ptr, mac, sizeof(mac)); + } + + /* Calculate the cell signature SIG. */ + { + ssize_t tmp_cell_enc_len = 0; + ssize_t tmp_cell_sig_offset = (sig_len + sizeof(cell->sig_len)); + uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0}, *sig_ptr; + ed25519_signature_t sig; + + /* We first encode the current fields we have in the cell so we can + * compute the signature from the raw bytes of the cell. */ + tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc, + sizeof(tmp_cell_enc), + cell); + if (BUG(tmp_cell_enc_len < 0)) { + goto done; + } + + if (ed25519_sign_prefixed(&sig, tmp_cell_enc, + tmp_cell_enc_len - tmp_cell_sig_offset, + ESTABLISH_INTRO_SIG_PREFIX, &ip->auth_key_kp)) { + log_warn(LD_BUG, "Unable to make signature for ESTABLISH_INTRO cell."); + goto done; + } + /* Copy the signature into the cell. */ + sig_ptr = trn_cell_establish_intro_getarray_sig(cell); + memcpy(sig_ptr, sig.sig, sig_len); + } + + /* Encode the cell. Can't be bigger than a standard cell. */ + cell_len = trn_cell_establish_intro_encode(cell_out, RELAY_PAYLOAD_SIZE, + cell); + + done: + trn_cell_establish_intro_free(cell); + return cell_len; +} + diff --git a/src/or/hs_cell.h b/src/or/hs_cell.h new file mode 100644 index 0000000000..9cc6109ebf --- /dev/null +++ b/src/or/hs_cell.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file hs_cell.h + * \brief Header file containing cell data for the whole HS subsytem. + **/ + +#ifndef TOR_HS_CELL_H +#define TOR_HS_CELL_H + +#include "hs_service.h" + +ssize_t hs_cell_build_establish_intro(const char *circ_nonce, + const hs_service_intro_point_t *ip, + uint8_t *cell_out); + +#endif /* TOR_HS_CELL_H */ + diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c index 482ba30f35..01fd864839 100644 --- a/src/or/hs_circuit.c +++ b/src/or/hs_circuit.c @@ -6,13 +6,16 @@ **/ #include "or.h" +#include "circpathbias.h" #include "circuitbuild.h" #include "circuitlist.h" #include "circuituse.h" #include "config.h" +#include "relay.h" #include "rephist.h" #include "router.h" +#include "hs_cell.h" #include "hs_circuit.h" #include "hs_ident.h" #include "hs_ntor.h" @@ -195,6 +198,48 @@ register_intro_circ(const hs_service_intro_point_t *ip, } } +/* Return the number of opened introduction circuit for the given circuit that + * is matching its identity key. */ +static unsigned int +count_opened_desc_intro_point_circuits(const hs_service_t *service, + const hs_service_descriptor_t *desc) +{ + unsigned int count = 0; + + tor_assert(service); + tor_assert(desc); + + DIGEST256MAP_FOREACH(desc->intro_points.map, key, + const hs_service_intro_point_t *, ip) { + circuit_t *circ; + origin_circuit_t *ocirc; + if (ip->base.is_only_legacy) { + uint8_t digest[DIGEST_LEN]; + if (BUG(crypto_pk_get_digest(ip->legacy_key, (char *) digest) < 0)) { + continue; + } + ocirc = hs_circuitmap_get_intro_circ_v2_service_side(digest); + } else { + ocirc = + hs_circuitmap_get_intro_circ_v3_service_side(&ip->auth_key_kp.pubkey); + } + if (ocirc == NULL) { + continue; + } + circ = TO_CIRCUIT(ocirc); + tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO || + circ->purpose == CIRCUIT_PURPOSE_S_INTRO); + /* Having a circuit not for the requested service is really bad. */ + tor_assert(ed25519_pubkey_eq(&service->keys.identity_pk, + ô->hs_ident->identity_pk)); + /* Only count opened circuit and skip circuit that will be closed. */ + if (!circ->marked_for_close && circ->state == CIRCUIT_STATE_OPEN) { + count++; + } + } DIGEST256MAP_FOREACH_END; + return count; +} + /* From a given service and service intro point, create an introduction point * circuit identifier. This can't fail. */ static hs_ident_circuit_t * @@ -213,6 +258,60 @@ create_intro_circuit_identifier(const hs_service_t *service, return ident; } +/* For a given introduction point and an introduction circuit, send the + * ESTABLISH_INTRO cell. The service object is used for logging. This can fail + * and if so, the circuit is closed and the intro point object is flagged + * that the circuit is not established anymore which is important for the + * retry mechanism. */ +static void +send_establish_intro(const hs_service_t *service, + hs_service_intro_point_t *ip, origin_circuit_t *circ) +{ + ssize_t cell_len; + uint8_t payload[RELAY_PAYLOAD_SIZE]; + + tor_assert(service); + tor_assert(ip); + tor_assert(circ); + + /* Encode establish intro cell. */ + cell_len = hs_cell_build_establish_intro(circ->cpath->prev->rend_circ_nonce, + ip, payload); + if (cell_len < 0) { + log_warn(LD_REND, "Unable to encode ESTABLISH_INTRO cell for service %s " + "on circuit %u. Closing circuit.", + safe_str_client(service->onion_address), + TO_CIRCUIT(circ)->n_circ_id); + goto err; + } + + /* Send the cell on the circuit. */ + if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ), + RELAY_COMMAND_ESTABLISH_INTRO, + (char *) payload, cell_len, + circ->cpath->prev) < 0) { + log_info(LD_REND, "Unable to send ESTABLISH_INTRO cell for service %s " + "on circuit %u.", + safe_str_client(service->onion_address), + TO_CIRCUIT(circ)->n_circ_id); + /* On error, the circuit has been closed. */ + goto done; + } + + /* Record the attempt to use this circuit. */ + pathbias_count_use_attempt(circ); + goto done; + + err: + circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); + done: + memwipe(payload, 0, sizeof(payload)); +} + +/* ========== */ +/* Public API */ +/* ========== */ + /* For a given service and a service intro point, launch a circuit to the * extend info ei. If the service is a single onion, a one-hop circuit will be * requested. Return 0 if the circuit was successfully launched and tagged @@ -266,6 +365,69 @@ hs_circ_launch_intro_point(hs_service_t *service, return ret; } +/* Called when a service introduction point circuit is done building. Given + * the service and intro point object, this function will send the + * ESTABLISH_INTRO cell on the circuit. Return 0 on success. Return 1 if the + * circuit has been repurposed to General because we already have too many + * opened. */ +int +hs_circ_service_intro_has_opened(hs_service_t *service, + hs_service_intro_point_t *ip, + const hs_service_descriptor_t *desc, + origin_circuit_t *circ) +{ + int ret = 0; + unsigned int num_intro_circ, num_needed_circ; + + tor_assert(service); + tor_assert(ip); + tor_assert(desc); + tor_assert(circ); + + num_intro_circ = count_opened_desc_intro_point_circuits(service, desc); + num_needed_circ = service->config.num_intro_points; + if (num_intro_circ > num_needed_circ) { + /* There are too many opened valid intro circuit for what the service + * needs so repurpose this one. */ + + /* XXX: Legacy code checks options->ExcludeNodes and if not NULL it just + * closes the circuit. I have NO idea why it does that so it hasn't been + * added here. I can only assume in case our ExcludeNodes list changes but + * in that case, all circuit are flagged unusable (config.c). --dgoulet */ + + log_info(LD_CIRC | LD_REND, "Introduction circuit just opened but we " + "have enough for service %s. Repurposing " + "it to general and leaving internal.", + safe_str_client(service->onion_address)); + tor_assert(circ->build_state->is_internal); + /* Remove it from the circuitmap. */ + hs_circuitmap_remove_circuit(TO_CIRCUIT(circ)); + /* Cleaning up the hidden service identifier and repurpose. */ + hs_ident_circuit_free(circ->hs_ident); + circ->hs_ident = NULL; + circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_GENERAL); + /* Inform that this circuit just opened for this new purpose. */ + circuit_has_opened(circ); + /* This return value indicate to the caller that the IP object should be + * removed from the service because it's corresponding circuit has just + * been repurposed. */ + ret = 1; + goto done; + } + + log_info(LD_REND, "Introduction circuit %u established for service %s.", + TO_CIRCUIT(circ)->n_circ_id, + safe_str_client(service->onion_address)); + circuit_log_path(LOG_INFO, LD_REND, circ); + + /* Time to send an ESTABLISH_INTRO cell on this circuit. On error, this call + * makes sure the circuit gets closed. */ + send_establish_intro(service, ip, circ); + + done: + return ret; +} + /* Circuit circ just finished the rend ntor key exchange. Use the key * exchange output material at ntor_key_seed and setup circ to * serve as a rendezvous end-to-end circuit between the client and the @@ -273,7 +435,7 @@ hs_circ_launch_intro_point(hs_service_t *service, * and the other side is the client. * * Return 0 if the operation went well; in case of error return -1. */ -int + int hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, const uint8_t *ntor_key_seed, size_t seed_len, int is_service_side) diff --git a/src/or/hs_circuit.h b/src/or/hs_circuit.h index 8738438eb2..35eab75695 100644 --- a/src/or/hs_circuit.h +++ b/src/or/hs_circuit.h @@ -16,10 +16,19 @@ #include "hs_service.h" /* Circuit API. */ +int hs_circ_service_intro_has_opened(hs_service_t *service, + hs_service_intro_point_t *ip, + const hs_service_descriptor_t *desc, + origin_circuit_t *circ); int hs_circ_launch_intro_point(hs_service_t *service, const hs_service_intro_point_t *ip, extend_info_t *ei, time_t now); +/* Cell API. */ +void hs_circ_send_establish_intro(const hs_service_t *service, + hs_service_intro_point_t *ip, + origin_circuit_t *circ); + /* e2e circuit API. */ int hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, diff --git a/src/or/hs_service.c b/src/or/hs_service.c index 06ab7b9836..4cd808133c 100644 --- a/src/or/hs_service.c +++ b/src/or/hs_service.c @@ -12,6 +12,7 @@ #include "circpathbias.h" #include "circuitbuild.h" #include "circuitlist.h" +#include "circuituse.h" #include "config.h" #include "main.h" #include "networkstatus.h" @@ -338,13 +339,72 @@ service_intro_point_new(const extend_info_t *ei, unsigned int is_legacy) static void service_intro_point_add(digest256map_t *map, hs_service_intro_point_t *ip) { - uint8_t key[DIGEST256_LEN] = {0}; - tor_assert(map); tor_assert(ip); - memcpy(key, ip->auth_key_kp.pubkey.pubkey, sizeof(key)); - digest256map_set(map, key, ip); + digest256map_set(map, ip->auth_key_kp.pubkey.pubkey, ip); +} + +/* For a given service, remove the intro point from that service which will + * look in both descriptors. */ +static void +service_intro_point_remove(const hs_service_t *service, + const hs_service_intro_point_t *ip) +{ + tor_assert(service); + tor_assert(ip); + + /* Trying all descriptors. */ + FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { + /* We'll try to remove the descriptor on both descriptors which is not + * very expensive to do instead of doing loopup + remove. */ + digest256map_remove(desc->intro_points.map, + ip->auth_key_kp.pubkey.pubkey); + } FOR_EACH_DESCRIPTOR_END; +} + +/* For a given service and authentication key, return the intro point or NULL + * if not found. This will check both descriptors in the service. */ +static hs_service_intro_point_t * +service_intro_point_find(const hs_service_t *service, + const ed25519_public_key_t *auth_key) +{ + hs_service_intro_point_t *ip = NULL; + + tor_assert(service); + tor_assert(auth_key); + + /* Trying all descriptors. */ + FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { + if ((ip = digest256map_get(desc->intro_points.map, + auth_key->pubkey)) != NULL) { + break; + } + } FOR_EACH_DESCRIPTOR_END; + + return ip; +} + +/* For a given service and intro point, return the descriptor for which the + * intro point is assigned to. NULL is returned if not found. */ +static hs_service_descriptor_t * +service_desc_find_by_intro(const hs_service_t *service, + const hs_service_intro_point_t *ip) +{ + hs_service_descriptor_t *descp = NULL; + + tor_assert(service); + tor_assert(ip); + + FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { + if (digest256map_get(desc->intro_points.map, + ip->auth_key_kp.pubkey.pubkey)) { + descp = desc; + break; + } + } FOR_EACH_DESCRIPTOR_END; + + return descp; } /* From a given intro point, return the first link specifier of type @@ -790,7 +850,6 @@ service_descriptor_new(void) return sdesc; } -#if 0 /* Copy the descriptor link specifier object from src to dst. */ static void link_specifier_copy(hs_desc_link_specifier_t *dst, @@ -916,8 +975,6 @@ build_desc_intro_points(const hs_service_t *service, } DIGEST256MAP_FOREACH_END; } -#endif /* build_desc_intro_points is disabled because not used */ - /* Populate the descriptor encrypted section fomr the given service object. * This will generate a valid list of introduction points that can be used * after for circuit creation. Return 0 on success else -1 on error. */ @@ -1635,14 +1692,105 @@ run_upload_descriptor_event(time_t now) /* Run v3+ check. */ FOR_EACH_SERVICE_BEGIN(service) { /* XXX: Upload if needed the descriptor(s). Update next upload time. */ - (void) service; + /* XXX: Build the descriptor intro points list with + * build_desc_intro_points() once we have enough circuit opened. */ + build_desc_intro_points(service, NULL, now); } FOR_EACH_SERVICE_END; } +/* Called when the introduction point circuit is done building and ready to be + * used. */ +static void +service_intro_circ_has_opened(origin_circuit_t *circ) +{ + int close_reason; + hs_service_t *service; + hs_service_intro_point_t *ip; + hs_service_descriptor_t *desc = NULL; + + tor_assert(circ); + tor_assert(circ->cpath); + /* Getting here means this is a v3 intro circuit. */ + tor_assert(circ->hs_ident); + tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO); + + /* Get service object from the circuit identifier. */ + service = find_service(hs_service_map, &circ->hs_ident->identity_pk); + if (service == NULL) { + log_warn(LD_REND, "Unknown service identity key %s on the introduction " + "circuit %u. Can't find onion service.", + safe_str_client(ed25519_fmt(&circ->hs_ident->identity_pk)), + TO_CIRCUIT(circ)->n_circ_id); + close_reason = END_CIRC_REASON_NOSUCHSERVICE; + goto err; + } + + /* From the service object, get the intro point object of that circuit. The + * following will query both descriptors intro points list. */ + ip = service_intro_point_find(service, &circ->hs_ident->intro_auth_pk); + if (ip == NULL) { + log_warn(LD_REND, "Unknown authentication key on the introduction " + "circuit %u for service %s", + TO_CIRCUIT(circ)->n_circ_id, + safe_str_client(service->onion_address)); + /* Closing this circuit because we don't recognize the key. */ + close_reason = END_CIRC_REASON_NOSUCHSERVICE; + goto err; + } + /* We can't have an IP object without a descriptor. */ + desc = service_desc_find_by_intro(service, ip); + tor_assert(desc); + + if (hs_circ_service_intro_has_opened(service, ip, desc, circ)) { + /* Getting here means that the circuit has been re-purposed because we + * have enough intro circuit opened. Remove the IP from the service. */ + service_intro_point_remove(service, ip); + service_intro_point_free(ip); + } + + goto done; + + err: + /* Close circuit, we can't use it. */ + circuit_mark_for_close(TO_CIRCUIT(circ), close_reason); + done: + return; +} + +static void +service_rendezvous_circ_has_opened(origin_circuit_t *circ) +{ + tor_assert(circ); + /* XXX: Implement rendezvous support. */ +} + /* ========== */ /* Public API */ /* ========== */ +/* Called when any kind of hidden service circuit is done building thus + * opened. This is the entry point from the circuit subsystem. */ +void +hs_service_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_S_ESTABLISH_INTRO: + (circ->hs_ident) ? service_intro_circ_has_opened(circ) : + rend_service_intro_has_opened(circ); + break; + case CIRCUIT_PURPOSE_S_CONNECT_REND: + (circ->hs_ident) ? service_rendezvous_circ_has_opened(circ) : + rend_service_rendezvous_has_opened(circ); + break; + default: + tor_assert(0); + } +} + /* Load and/or generate keys for all onion services including the client * authorization if any. Return 0 on success, -1 on failure. */ int diff --git a/src/or/hs_service.h b/src/or/hs_service.h index 476fee72ff..96df09493e 100644 --- a/src/or/hs_service.h +++ b/src/or/hs_service.h @@ -103,6 +103,9 @@ typedef struct hs_service_descriptor_t { * hs_service_intropoints_t object indexed by authentication key (the RSA * key if the node is legacy). */ hs_service_intropoints_t intro_points; + + /* The time period number this descriptor has been created for. */ + uint64_t time_period_num; } hs_service_descriptor_t; /* Service key material. */ @@ -228,6 +231,7 @@ void hs_service_stage_services(const smartlist_t *service_list); int hs_service_load_all_keys(void); void hs_service_run_scheduled_events(time_t now); +void hs_service_circuit_has_opened(origin_circuit_t *circ); /* These functions are only used by unit tests and we need to expose them else * hs_service.o ends up with no symbols in libor.a which makes clang throw a diff --git a/src/or/include.am b/src/or/include.am index 15b86ef50b..8db5be095a 100644 --- a/src/or/include.am +++ b/src/or/include.am @@ -54,6 +54,7 @@ LIBTOR_A_SOURCES = \ src/or/ext_orport.c \ src/or/hibernate.c \ src/or/hs_cache.c \ + src/or/hs_cell.c \ src/or/hs_circuit.c \ src/or/hs_circuitmap.c \ src/or/hs_client.c \ @@ -184,11 +185,12 @@ ORHEADERS = \ src/or/entrynodes.h \ src/or/hibernate.h \ src/or/hs_cache.h \ + src/or/hs_cell.h \ + src/or/hs_config.h \ src/or/hs_circuit.h \ src/or/hs_circuitmap.h \ src/or/hs_client.h \ src/or/hs_common.h \ - src/or/hs_config.h \ src/or/hs_descriptor.h \ src/or/hs_ident.h \ src/or/hs_intropoint.h \ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 4641e110d8..8239803fb2 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -3116,10 +3116,11 @@ count_intro_point_circuits(const rend_service_t *service) crypto material. On success, fill cell_body_out and return the number of bytes written. On fail, return -1. */ -STATIC ssize_t -encode_establish_intro_cell_legacy(char *cell_body_out, - size_t cell_body_out_len, - crypto_pk_t *intro_key, char *rend_circ_nonce) +ssize_t +rend_service_encode_establish_intro_cell(char *cell_body_out, + size_t cell_body_out_len, + crypto_pk_t *intro_key, + const char *rend_circ_nonce) { int retval = -1; int r; @@ -3256,7 +3257,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) /* Send the ESTABLISH_INTRO cell */ { ssize_t len; - len = encode_establish_intro_cell_legacy(buf, sizeof(buf), + len = rend_service_encode_establish_intro_cell(buf, sizeof(buf), circuit->intro_key, circuit->cpath->prev->rend_circ_nonce); if (len < 0) { diff --git a/src/or/rendservice.h b/src/or/rendservice.h index 4a06657eab..78f4b92c2e 100644 --- a/src/or/rendservice.h +++ b/src/or/rendservice.h @@ -126,10 +126,6 @@ STATIC int rend_service_verify_single_onion_poison( STATIC int rend_service_poison_new_single_onion_dir( const rend_service_t *s, const or_options_t* options); -STATIC ssize_t encode_establish_intro_cell_legacy(char *cell_body_out, - size_t cell_body_out_len, - crypto_pk_t *intro_key, - char *rend_circ_nonce); #ifdef TOR_UNIT_TESTS STATIC void set_rend_service_list(smartlist_t *new_list); @@ -172,6 +168,10 @@ rend_intro_cell_t * rend_service_begin_parse_intro(const uint8_t *request, char **err_msg_out); int rend_service_parse_intro_plaintext(rend_intro_cell_t *intro, char **err_msg_out); +ssize_t rend_service_encode_establish_intro_cell(char *cell_body_out, + size_t cell_body_out_len, + crypto_pk_t *intro_key, + const char *rend_circ_nonce); int rend_service_validate_intro_late(const rend_intro_cell_t *intro, char **err_msg_out); void rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc); diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index c6197875b5..076d125ffc 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -488,10 +488,10 @@ helper_establish_intro_v2(or_circuit_t *intro_circ) key1 = pk_generate(0); /* Use old circuit_key_material why not */ - cell_len = encode_establish_intro_cell_legacy((char*)cell_body, - sizeof(cell_body), - key1, - (char *) circuit_key_material); + cell_len = rend_service_encode_establish_intro_cell( + (char*)cell_body, + sizeof(cell_body), key1, + (char *) circuit_key_material); tt_int_op(cell_len, >, 0); /* Receive legacy establish_intro */