Tor  0.4.8.0-alpha-dev
extendinfo.c
Go to the documentation of this file.
1 /* Copyright (c) 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * @file extendinfo.c
9  * @brief Functions for creating and using extend_info_t objects.
10  *
11  * An extend_info_t is the information we hold about a relay in order to
12  * extend a circuit to it.
13  **/
14 
15 #include "core/or/or.h"
16 #include "core/or/extendinfo.h"
17 
18 #include "app/config/config.h"
19 #include "core/or/policies.h"
22 #include "feature/relay/router.h"
25 
26 #include "core/or/extend_info_st.h"
30 
31 /** Allocate a new extend_info object based on the various arguments. */
33 extend_info_new(const char *nickname,
34  const char *rsa_id_digest,
35  const ed25519_public_key_t *ed_id,
36  crypto_pk_t *onion_key,
37  const curve25519_public_key_t *ntor_key,
38  const tor_addr_t *addr, uint16_t port,
39  const protover_summary_flags_t *pv,
40  bool for_exit_use)
41 {
42  extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
43  if (rsa_id_digest)
44  memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN);
45  if (ed_id && !ed25519_public_key_is_zero(ed_id))
46  memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t));
47  if (nickname)
48  strlcpy(info->nickname, nickname, sizeof(info->nickname));
49  if (onion_key)
50  info->onion_key = crypto_pk_dup_key(onion_key);
51  if (ntor_key)
52  memcpy(&info->curve25519_onion_key, ntor_key,
53  sizeof(curve25519_public_key_t));
54  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
55  tor_addr_make_unspec(&info->orports[i].addr);
56  }
57 
58  if (addr) {
59  extend_info_add_orport(info, addr, port);
60  }
61 
62  if (pv && for_exit_use) {
65  }
66 
67  return info;
68 }
69 
70 /**
71  * Add another address:port pair to a given extend_info_t, if there is
72  * room. Return 0 on success, -1 on failure.
73  **/
74 int
76  const tor_addr_t *addr,
77  uint16_t port)
78 {
79  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
80  if (tor_addr_is_unspec(&ei->orports[i].addr)) {
81  tor_addr_copy(&ei->orports[i].addr, addr);
82  ei->orports[i].port = port;
83  return 0;
84  }
85  }
86  return -1;
87 }
88 
89 /** Allocate and return a new extend_info that can be used to build a
90  * circuit to or through the node <b>node</b>. Use the primary address
91  * of the node (i.e. its IPv4 address) unless
92  * <b>for_direct_connect</b> is true, in which case the preferred
93  * address is used instead. May return NULL if there is not enough
94  * info about <b>node</b> to extend to it--for example, if the preferred
95  * routerinfo_t or microdesc_t is missing, or if for_direct_connect is
96  * true and none of the node's addresses is allowed by tor's firewall
97  * and IP version config.
98  **/
100 extend_info_from_node(const node_t *node, int for_direct_connect,
101  bool for_exit)
102 {
103  crypto_pk_t *rsa_pubkey = NULL;
104  extend_info_t *info = NULL;
105  tor_addr_port_t ap;
106  int valid_addr = 0;
107 
108  if (!node_has_preferred_descriptor(node, for_direct_connect)) {
109  return NULL;
110  }
111 
112  /* Choose a preferred address first, but fall back to an allowed address. */
113  if (for_direct_connect)
114  reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
115  else {
116  node_get_prim_orport(node, &ap);
117  }
118  valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
119 
120  if (valid_addr)
121  log_debug(LD_CIRC, "using %s for %s",
122  fmt_addrport(&ap.addr, ap.port),
123  node->ri ? node->ri->nickname : node->rs->nickname);
124  else
125  log_warn(LD_CIRC, "Could not choose valid address for %s",
126  node->ri ? node->ri->nickname : node->rs->nickname);
127 
128  /* Every node we connect or extend to must support ntor */
129  if (!node_has_curve25519_onion_key(node)) {
130  log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
131  "Attempted to create extend_info for a node that does not support "
132  "ntor: %s", node_describe(node));
133  return NULL;
134  }
135 
136  const ed25519_public_key_t *ed_pubkey = NULL;
137 
138  /* Don't send the ed25519 pubkey unless the target node actually supports
139  * authenticating with it. */
141  log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node));
142  ed_pubkey = node_get_ed25519_id(node);
143  } else if (node_get_ed25519_id(node)) {
144  log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't "
145  "be able to authenticate it.",
146  node_describe(node));
147  }
148 
149  /* Retrieve the curve25519 pubkey. */
150  const curve25519_public_key_t *curve_pubkey =
152  rsa_pubkey = node_get_rsa_onion_key(node);
153 
154  if (valid_addr && node->ri) {
155  info = extend_info_new(node->ri->nickname,
156  node->identity,
157  ed_pubkey,
158  rsa_pubkey,
159  curve_pubkey,
160  &ap.addr,
161  ap.port,
162  &node->ri->pv,
163  for_exit);
164  } else if (valid_addr && node->rs && node->md) {
165  info = extend_info_new(node->rs->nickname,
166  node->identity,
167  ed_pubkey,
168  rsa_pubkey,
169  curve_pubkey,
170  &ap.addr,
171  ap.port,
172  &node->rs->pv,
173  for_exit);
174  }
175 
176  crypto_pk_free(rsa_pubkey);
177  return info;
178 }
179 
180 /** Release storage held by an extend_info_t struct. */
181 void
183 {
184  if (!info)
185  return;
186  crypto_pk_free(info->onion_key);
187  tor_free(info);
188 }
189 
190 /** Allocate and return a new extend_info_t with the same contents as
191  * <b>info</b>. */
194 {
195  extend_info_t *newinfo;
196  tor_assert(info);
197  newinfo = tor_malloc(sizeof(extend_info_t));
198  memcpy(newinfo, info, sizeof(extend_info_t));
199  if (info->onion_key)
200  newinfo->onion_key = crypto_pk_dup_key(info->onion_key);
201  else
202  newinfo->onion_key = NULL;
203  return newinfo;
204 }
205 
206 /* Does ei have a valid TAP key? */
207 int
208 extend_info_supports_tap(const extend_info_t* ei)
209 {
210  tor_assert(ei);
211  /* Valid TAP keys are not NULL */
212  return ei->onion_key != NULL;
213 }
214 
215 /* Does ei have a valid ntor key? */
216 int
217 extend_info_supports_ntor(const extend_info_t* ei)
218 {
219  tor_assert(ei);
220  /* Valid ntor keys have at least one non-zero byte */
221  return !fast_mem_is_zero(
222  (const char*)ei->curve25519_onion_key.public_key,
224 }
225 
226 /** Return true if we can use the Ntor v3 handshake with `ei` */
227 int
229 {
230  tor_assert(ei);
231  return extend_info_supports_ntor(ei) &&
233 }
234 
235 /* Does ei have an onion key which it would prefer to use?
236  * Currently, we prefer ntor keys*/
237 int
238 extend_info_has_preferred_onion_key(const extend_info_t* ei)
239 {
240  tor_assert(ei);
241  return extend_info_supports_ntor(ei);
242 }
243 
244 /** Return true iff the given address can be used to extend to. */
245 int
247 {
248  tor_assert(addr);
249 
250  /* Check if we have a private address and if we can extend to it. */
251  if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
252  !get_options()->ExtendAllowPrivateAddresses) {
253  goto disallow;
254  }
255  /* Allowed! */
256  return 1;
257  disallow:
258  return 0;
259 }
260 
261 /**
262  * Return true if @a addr : @a port is a listed ORPort in @a ei.
263  **/
264 bool
266  const tor_addr_t *addr, uint16_t port)
267 {
268  IF_BUG_ONCE(ei == NULL) {
269  return false;
270  }
271 
272  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
273  const tor_addr_port_t *ei_ap = &ei->orports[i];
274  if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port)
275  return true;
276  }
277  return false;
278 }
279 
280 /**
281  * If the extend_info @a ei has an orport of the chosen family, then return
282  * that orport. Otherwise, return NULL.
283  **/
284 const tor_addr_port_t *
285 extend_info_get_orport(const extend_info_t *ei, int family)
286 {
287  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
288  if (tor_addr_is_unspec(&ei->orports[i].addr))
289  continue;
290  if (tor_addr_family(&ei->orports[i].addr) == family)
291  return &ei->orports[i];
292  }
293  return NULL;
294 }
295 
296 /**
297  * Chose an addr_port_t within @a ei to connect to.
298  **/
299 const tor_addr_port_t *
301 {
302  IF_BUG_ONCE(!ei) {
303  return NULL;
304  }
305  const or_options_t *options = get_options();
306  if (!server_mode(options)) {
307  // If we aren't a server, just pick the first address we built into
308  // this extendinfo.
309  return &ei->orports[0];
310  }
311 
312  const bool ipv6_ok = router_can_extend_over_ipv6(options);
313 
314  // Use 'usable' to collect the usable orports, then pick one.
315  const tor_addr_port_t *usable[EXTEND_INFO_MAX_ADDRS];
316  int n_usable = 0;
317  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
318  const tor_addr_port_t *a = &ei->orports[i];
319  const int family = tor_addr_family(&a->addr);
320  if (family == AF_INET || (ipv6_ok && family == AF_INET6)) {
321  usable[n_usable++] = a;
322  }
323  }
324 
325  if (n_usable == 0) {
326  // Need to bail out early, since nothing will work.
327  return NULL;
328  }
329 
331  const int idx = crypto_fast_rng_get_uint(rng, n_usable);
332 
333  return usable[idx];
334 }
335 
336 /**
337  * Return true if any orport address in @a ei is an internal address.
338  **/
339 bool
341 {
342  IF_BUG_ONCE(ei == NULL) {
343  return false;
344  }
345 
346  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
347  if (! tor_addr_is_unspec(&ei->orports[i].addr) &&
348  tor_addr_is_internal(&ei->orports[i].addr, 0))
349  return true;
350  }
351  return false;
352 }
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
Definition: address.c:933
const char * fmt_addrport(const tor_addr_t *addr, uint16_t port)
Definition: address.c:1199
void tor_addr_make_unspec(tor_addr_t *a)
Definition: address.c:225
int tor_addr_is_multicast(const tor_addr_t *a)
Definition: address.c:1624
static sa_family_t tor_addr_family(const tor_addr_t *a)
Definition: address.h:187
#define tor_addr_eq(a, b)
Definition: address.h:280
static bool tor_addr_is_unspec(const tor_addr_t *a)
Definition: address.h:196
const or_options_t * get_options(void)
Definition: config.c:926
Header file for config.c.
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
Common functions for using (pseudo-)random number generators.
crypto_fast_rng_t * get_thread_fast_rng(void)
unsigned crypto_fast_rng_get_uint(crypto_fast_rng_t *rng, unsigned limit)
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
const char * node_describe(const node_t *node)
Definition: describe.c:160
Header file for describe.c.
#define DIGEST_LEN
Definition: digest_sizes.h:20
Extend-info structure.
#define EXTEND_INFO_MAX_ADDRS
void extend_info_free_(extend_info_t *info)
Definition: extendinfo.c:182
const tor_addr_port_t * extend_info_get_orport(const extend_info_t *ei, int family)
Definition: extendinfo.c:285
int extend_info_add_orport(extend_info_t *ei, const tor_addr_t *addr, uint16_t port)
Definition: extendinfo.c:75
extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect, bool for_exit)
Definition: extendinfo.c:100
int extend_info_supports_ntor_v3(const extend_info_t *ei)
Definition: extendinfo.c:228
const tor_addr_port_t * extend_info_pick_orport(const extend_info_t *ei)
Definition: extendinfo.c:300
bool extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
Definition: extendinfo.c:340
extend_info_t * extend_info_dup(extend_info_t *info)
Definition: extendinfo.c:193
bool extend_info_has_orport(const extend_info_t *ei, const tor_addr_t *addr, uint16_t port)
Definition: extendinfo.c:265
int extend_info_addr_is_allowed(const tor_addr_t *addr)
Definition: extendinfo.c:246
extend_info_t * extend_info_new(const char *nickname, const char *rsa_id_digest, const ed25519_public_key_t *ed_id, crypto_pk_t *onion_key, const curve25519_public_key_t *ntor_key, const tor_addr_t *addr, uint16_t port, const protover_summary_flags_t *pv, bool for_exit_use)
Definition: extendinfo.c:33
Header for core/or/extendinfo.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_CIRC
Definition: log.h:82
#define tor_free(p)
Definition: malloc.h:56
Node information structure.
void node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out)
Definition: nodelist.c:1821
int node_has_preferred_descriptor(const node_t *node, int for_direct_connect)
Definition: nodelist.c:1500
bool node_supports_ed25519_link_authentication(const node_t *node, bool compatible_with_us)
Definition: nodelist.c:1235
const ed25519_public_key_t * node_get_ed25519_id(const node_t *node)
Definition: nodelist.c:1150
const curve25519_public_key_t * node_get_curve25519_onion_key(const node_t *node)
Definition: nodelist.c:2016
int node_has_curve25519_onion_key(const node_t *node)
Definition: nodelist.c:2009
Header file for nodelist.c.
Master header file for Tor-specific functionality.
void reachable_addr_choose_from_node(const node_t *node, firewall_connection_t fw_connection, int pref_only, tor_addr_port_t *ap)
Definition: policies.c:988
Header file for policies.c.
bool router_can_extend_over_ipv6(const or_options_t *options)
Definition: router.c:1594
Header file for router.c.
Router descriptor structure.
int server_mode(const or_options_t *options)
Definition: routermode.c:34
Header file for routermode.c.
Routerstatus (consensus entry) structure.
tor_addr_port_t orports[EXTEND_INFO_MAX_ADDRS]
ed25519_public_key_t ed_identity
char identity_digest[DIGEST_LEN]
char nickname[MAX_HEX_NICKNAME_LEN+1]
crypto_pk_t * onion_key
bool exit_supports_congestion_control
curve25519_public_key_t curve25519_onion_key
Definition: node_st.h:34
char identity[DIGEST_LEN]
Definition: node_st.h:46
unsigned int supports_congestion_control
Definition: or.h:733
protover_summary_flags_t pv
Definition: routerinfo_st.h:93
char * nickname
Definition: routerinfo_st.h:22
protover_summary_flags_t pv
char nickname[MAX_NICKNAME_LEN+1]
#define tor_assert(expr)
Definition: util_bug.h:102
#define IF_BUG_ONCE(cond)
Definition: util_bug.h:246
int fast_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:74
#define CURVE25519_PUBKEY_LEN
Definition: x25519_sizes.h:20