mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
prop224: Service v3 descriptor creation and logic
This commit adds the functionality for a service to build its descriptor. Also, a global call to build all descriptors for all services is added to the service scheduled events. Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
c4ba4d4cc8
commit
00a02a3a59
@ -1532,6 +1532,41 @@ circuit_get_next_service_intro_circ(origin_circuit_t *start)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return the first service rendezvous circuit originating from the global
|
||||
* circuit list after <b>start</b> or at the start of the list if <b>start</b>
|
||||
* is NULL. Return NULL if no circuit is found.
|
||||
*
|
||||
* A service rendezvous point circuit has a purpose of either
|
||||
* CIRCUIT_PURPOSE_S_CONNECT_REND or CIRCUIT_PURPOSE_S_REND_JOINED. This does
|
||||
* not return a circuit marked for close and its state must be open. */
|
||||
origin_circuit_t *
|
||||
circuit_get_next_service_rp_circ(origin_circuit_t *start)
|
||||
{
|
||||
int idx = 0;
|
||||
smartlist_t *lst = circuit_get_global_list();
|
||||
|
||||
if (start) {
|
||||
idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
|
||||
}
|
||||
|
||||
for ( ; idx < smartlist_len(lst); ++idx) {
|
||||
circuit_t *circ = smartlist_get(lst, idx);
|
||||
|
||||
/* Ignore a marked for close circuit or purpose not matching a service
|
||||
* intro point or if the state is not open. */
|
||||
if (circ->marked_for_close || circ->state != CIRCUIT_STATE_OPEN ||
|
||||
(circ->purpose != CIRCUIT_PURPOSE_S_CONNECT_REND &&
|
||||
circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED)) {
|
||||
continue;
|
||||
}
|
||||
/* The purposes we are looking for are only for origin circuits so the
|
||||
* following is valid. */
|
||||
return TO_ORIGIN_CIRCUIT(circ);
|
||||
}
|
||||
/* Not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Return the first circuit originating here in global_circuitlist after
|
||||
* <b>start</b> whose purpose is <b>purpose</b>, and where <b>digest</b> (if
|
||||
* set) matches the private key digest of the rend data associated with the
|
||||
|
@ -48,6 +48,7 @@ origin_circuit_t *circuit_get_ready_rend_circ_by_rend_data(
|
||||
origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
|
||||
const uint8_t *digest, uint8_t purpose);
|
||||
origin_circuit_t *circuit_get_next_service_intro_circ(origin_circuit_t *start);
|
||||
origin_circuit_t *circuit_get_next_service_rp_circ(origin_circuit_t *start);
|
||||
origin_circuit_t *circuit_get_next_service_hsdir_circ(origin_circuit_t *start);
|
||||
origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose,
|
||||
extend_info_t *info, int flags);
|
||||
|
@ -1280,11 +1280,6 @@ circuit_build_needed_circs(time_t now)
|
||||
if (router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN)
|
||||
connection_ap_rescan_and_attach_pending();
|
||||
|
||||
/* make sure any hidden services have enough intro points
|
||||
* HS intro point streams only require an internal circuit */
|
||||
if (router_have_consensus_path() != CONSENSUS_PATH_UNKNOWN)
|
||||
rend_consider_services_intro_points();
|
||||
|
||||
circuit_expire_old_circs_as_needed(now);
|
||||
|
||||
if (!options->DisablePredictedCircuits)
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "hs_descriptor.h"
|
||||
|
||||
#include "or.h"
|
||||
#include "circuitbuild.h"
|
||||
#include "ed25519_cert.h" /* Trunnel interface. */
|
||||
#include "parsecommon.h"
|
||||
#include "rendcache.h"
|
||||
@ -362,6 +363,14 @@ encode_link_specifiers(const smartlist_t *specs)
|
||||
link_specifier_set_ls_len(ls, legacy_id_len);
|
||||
break;
|
||||
}
|
||||
case LS_ED25519_ID:
|
||||
{
|
||||
size_t ed25519_id_len = link_specifier_getlen_un_ed25519_id(ls);
|
||||
uint8_t *ed25519_id_array = link_specifier_getarray_un_ed25519_id(ls);
|
||||
memcpy(ed25519_id_array, spec->u.ed25519_id, ed25519_id_len);
|
||||
link_specifier_set_ls_len(ls, ed25519_id_len);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tor_assert(0);
|
||||
}
|
||||
@ -1143,6 +1152,15 @@ decode_link_specifiers(const char *encoded)
|
||||
memcpy(hs_spec->u.legacy_id, link_specifier_getarray_un_legacy_id(ls),
|
||||
sizeof(hs_spec->u.legacy_id));
|
||||
break;
|
||||
case LS_ED25519_ID:
|
||||
/* Both are known at compile time so let's make sure they are the same
|
||||
* else we can copy memory out of bound. */
|
||||
tor_assert(link_specifier_getlen_un_ed25519_id(ls) ==
|
||||
sizeof(hs_spec->u.ed25519_id));
|
||||
memcpy(hs_spec->u.ed25519_id,
|
||||
link_specifier_getconstarray_un_ed25519_id(ls),
|
||||
sizeof(hs_spec->u.ed25519_id));
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
@ -2398,7 +2416,7 @@ hs_desc_intro_point_free(hs_desc_intro_point_t *ip)
|
||||
}
|
||||
if (ip->link_specifiers) {
|
||||
SMARTLIST_FOREACH(ip->link_specifiers, hs_desc_link_specifier_t *,
|
||||
ls, tor_free(ls));
|
||||
ls, hs_desc_link_specifier_free(ls));
|
||||
smartlist_free(ip->link_specifiers);
|
||||
}
|
||||
tor_cert_free(ip->auth_key_cert);
|
||||
@ -2408,3 +2426,73 @@ hs_desc_intro_point_free(hs_desc_intro_point_t *ip)
|
||||
tor_free(ip);
|
||||
}
|
||||
|
||||
/* Free the given descriptor link specifier. */
|
||||
void
|
||||
hs_desc_link_specifier_free(hs_desc_link_specifier_t *ls)
|
||||
{
|
||||
if (ls == NULL) {
|
||||
return;
|
||||
}
|
||||
tor_free(ls);
|
||||
}
|
||||
|
||||
/* Return a newly allocated descriptor link specifier using the given extend
|
||||
* info and requested type. Return NULL on error. */
|
||||
hs_desc_link_specifier_t *
|
||||
hs_desc_link_specifier_new(const extend_info_t *info, uint8_t type)
|
||||
{
|
||||
hs_desc_link_specifier_t *ls = NULL;
|
||||
|
||||
tor_assert(info);
|
||||
|
||||
ls = tor_malloc_zero(sizeof(*ls));
|
||||
ls->type = type;
|
||||
switch (ls->type) {
|
||||
case LS_IPV4:
|
||||
if (info->addr.family != AF_INET) {
|
||||
goto err;
|
||||
}
|
||||
tor_addr_copy(&ls->u.ap.addr, &info->addr);
|
||||
ls->u.ap.port = info->port;
|
||||
break;
|
||||
case LS_IPV6:
|
||||
if (info->addr.family != AF_INET6) {
|
||||
goto err;
|
||||
}
|
||||
tor_addr_copy(&ls->u.ap.addr, &info->addr);
|
||||
ls->u.ap.port = info->port;
|
||||
break;
|
||||
case LS_LEGACY_ID:
|
||||
memcpy(ls->u.legacy_id, info->identity_digest, sizeof(ls->u.legacy_id));
|
||||
break;
|
||||
case LS_ED25519_ID:
|
||||
memcpy(ls->u.ed25519_id, info->ed_identity.pubkey,
|
||||
sizeof(ls->u.ed25519_id));
|
||||
break;
|
||||
default:
|
||||
/* Unknown type is code flow error. */
|
||||
tor_assert(0);
|
||||
}
|
||||
|
||||
return ls;
|
||||
err:
|
||||
tor_free(ls);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* From the given descriptor, remove and free every introduction point. */
|
||||
void
|
||||
hs_descriptor_free_intro_points(hs_descriptor_t *desc)
|
||||
{
|
||||
smartlist_t *ips;
|
||||
|
||||
tor_assert(desc);
|
||||
|
||||
ips = desc->encrypted_data.intro_points;
|
||||
if (ips) {
|
||||
SMARTLIST_FOREACH(ips, hs_desc_intro_point_t *,
|
||||
ip, hs_desc_intro_point_free(ip));
|
||||
smartlist_clear(ips);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,9 @@
|
||||
/* The latest descriptor format version we support. */
|
||||
#define HS_DESC_SUPPORTED_FORMAT_VERSION_MAX 3
|
||||
|
||||
/* Default lifetime of a descriptor in seconds. The valus is set at 3 hours
|
||||
* which is 180 minutes or 10800 seconds. */
|
||||
#define HS_DESC_DEFAULT_LIFETIME (3 * 60 * 60)
|
||||
/* Maximum lifetime of a descriptor in seconds. The value is set at 12 hours
|
||||
* which is 720 minutes or 43200 seconds. */
|
||||
#define HS_DESC_MAX_LIFETIME (12 * 60 * 60)
|
||||
@ -65,12 +68,14 @@ typedef struct hs_desc_link_specifier_t {
|
||||
* specification. */
|
||||
uint8_t type;
|
||||
|
||||
/* It's either an address/port or a legacy identity fingerprint. */
|
||||
/* It must be one of these types, can't be more than one. */
|
||||
union {
|
||||
/* IP address and port of the relay use to extend. */
|
||||
tor_addr_port_t ap;
|
||||
/* Legacy identity. A 20-byte SHA1 identity fingerprint. */
|
||||
uint8_t legacy_id[DIGEST_LEN];
|
||||
/* ed25519 identity. A 32-byte key. */
|
||||
uint8_t ed25519_id[ED25519_PUBKEY_LEN];
|
||||
} u;
|
||||
} hs_desc_link_specifier_t;
|
||||
|
||||
@ -201,6 +206,11 @@ void hs_descriptor_free(hs_descriptor_t *desc);
|
||||
void hs_desc_plaintext_data_free(hs_desc_plaintext_data_t *desc);
|
||||
void hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc);
|
||||
|
||||
void hs_desc_link_specifier_free(hs_desc_link_specifier_t *ls);
|
||||
hs_desc_link_specifier_t *hs_desc_link_specifier_new(
|
||||
const extend_info_t *info, uint8_t type);
|
||||
void hs_descriptor_free_intro_points(hs_descriptor_t *desc);
|
||||
|
||||
int hs_desc_encode_descriptor(const hs_descriptor_t *desc,
|
||||
const ed25519_keypair_t *signing_kp,
|
||||
char **encoded_out);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "hs/cell_introduce1.h"
|
||||
|
||||
#include "hs_circuitmap.h"
|
||||
#include "hs_descriptor.h"
|
||||
#include "hs_intropoint.h"
|
||||
#include "hs_common.h"
|
||||
|
||||
@ -594,3 +595,16 @@ hs_intro_received_introduce1(or_circuit_t *circ, const uint8_t *request,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Free the given intropoint object ip. */
|
||||
void
|
||||
hs_intro_free_content(hs_intropoint_t *ip)
|
||||
{
|
||||
if (ip == NULL) {
|
||||
return;
|
||||
}
|
||||
tor_cert_free(ip->auth_key_cert);
|
||||
SMARTLIST_FOREACH(ip->link_specifiers, hs_desc_link_specifier_t *, ls,
|
||||
hs_desc_link_specifier_free(ls));
|
||||
smartlist_free(ip->link_specifiers);
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
||||
#include "torcert.h"
|
||||
|
||||
/* Authentication key type in an ESTABLISH_INTRO cell. */
|
||||
enum hs_intro_auth_key_type {
|
||||
typedef enum {
|
||||
HS_INTRO_AUTH_KEY_TYPE_LEGACY0 = 0x00,
|
||||
HS_INTRO_AUTH_KEY_TYPE_LEGACY1 = 0x01,
|
||||
HS_INTRO_AUTH_KEY_TYPE_ED25519 = 0x02,
|
||||
};
|
||||
} hs_intro_auth_key_type_t;
|
||||
|
||||
/* INTRODUCE_ACK status code. */
|
||||
typedef enum {
|
||||
@ -30,6 +30,9 @@ typedef enum {
|
||||
/* Object containing introduction point common data between the service and
|
||||
* the client side. */
|
||||
typedef struct hs_intropoint_t {
|
||||
/* Does this intro point only supports legacy ID ?. */
|
||||
unsigned int is_only_legacy : 1;
|
||||
|
||||
/* Authentication key certificate from the descriptor. */
|
||||
tor_cert_t *auth_key_cert;
|
||||
/* A list of link specifier. */
|
||||
@ -47,6 +50,9 @@ MOCK_DECL(int, hs_intro_send_intro_established_cell,(or_circuit_t *circ));
|
||||
/* also used by rendservice.c */
|
||||
int hs_intro_circuit_is_suitable_for_establish_intro(const or_circuit_t *circ);
|
||||
|
||||
hs_intropoint_t *hs_intro_new(void);
|
||||
void hs_intro_free_content(hs_intropoint_t *ip);
|
||||
|
||||
#ifdef HS_INTROPOINT_PRIVATE
|
||||
|
||||
#include "hs/cell_establish_intro.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,8 +38,12 @@ typedef struct hs_service_intro_point_t {
|
||||
* which is published in the descriptor. */
|
||||
ed25519_keypair_t auth_key_kp;
|
||||
|
||||
/* Encryption private key. */
|
||||
curve25519_secret_key_t enc_key_sk;
|
||||
/* Encryption keypair for the "ntor" type. */
|
||||
curve25519_keypair_t enc_key_kp;
|
||||
|
||||
/* Legacy key if that intro point doesn't support v3. This should be used if
|
||||
* the base object legacy flag is set. */
|
||||
crypto_pk_t *legacy_key;
|
||||
|
||||
/* Amount of INTRODUCE2 cell accepted from this intro point. */
|
||||
uint64_t introduce2_count;
|
||||
|
@ -3983,10 +3983,9 @@ rend_max_intro_circs_per_period(unsigned int n_intro_points_wanted)
|
||||
* This is called once a second by the main loop.
|
||||
*/
|
||||
void
|
||||
rend_consider_services_intro_points(void)
|
||||
rend_consider_services_intro_points(time_t now)
|
||||
{
|
||||
int i;
|
||||
time_t now;
|
||||
const or_options_t *options = get_options();
|
||||
/* Are we in single onion mode? */
|
||||
const int allow_direct = rend_service_allow_non_anonymous_connection(
|
||||
@ -4003,7 +4002,6 @@ rend_consider_services_intro_points(void)
|
||||
|
||||
exclude_nodes = smartlist_new();
|
||||
retry_nodes = smartlist_new();
|
||||
now = time(NULL);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(rend_service_list, rend_service_t *, service) {
|
||||
int r;
|
||||
|
@ -149,7 +149,7 @@ void rend_service_free_staging_list(void);
|
||||
int rend_service_load_all_keys(const smartlist_t *service_list);
|
||||
void rend_services_add_filenames_to_lists(smartlist_t *open_lst,
|
||||
smartlist_t *stat_lst);
|
||||
void rend_consider_services_intro_points(void);
|
||||
void rend_consider_services_intro_points(time_t now);
|
||||
void rend_consider_services_upload(time_t now);
|
||||
void rend_hsdir_routers_changed(void);
|
||||
void rend_consider_descriptor_republication(void);
|
||||
|
Loading…
Reference in New Issue
Block a user