tor  0.4.0.0-alpha-dev
hs_circuit.c
Go to the documentation of this file.
1 /* Copyright (c) 2017-2018, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
8 #define HS_CIRCUIT_PRIVATE
9 
10 #include "core/or/or.h"
11 #include "app/config/config.h"
12 #include "core/crypto/hs_ntor.h"
13 #include "core/or/circuitbuild.h"
14 #include "core/or/circuitlist.h"
15 #include "core/or/circuituse.h"
16 #include "core/or/policies.h"
17 #include "core/or/relay.h"
18 #include "feature/client/circpathbias.h"
19 #include "feature/hs/hs_cell.h"
20 #include "feature/hs/hs_circuit.h"
22 #include "feature/hs/hs_ident.h"
23 #include "feature/hs/hs_service.h"
27 #include "feature/stats/rephist.h"
31 
32 /* Trunnel. */
33 #include "trunnel/ed25519_cert.h"
34 #include "trunnel/hs/cell_common.h"
35 #include "trunnel/hs/cell_establish_intro.h"
36 
37 #include "core/or/cpath_build_state_st.h"
38 #include "core/or/crypt_path_st.h"
39 #include "feature/nodelist/node_st.h"
40 #include "core/or/origin_circuit_st.h"
41 
42 /* A circuit is about to become an e2e rendezvous circuit. Check
43  * <b>circ_purpose</b> and ensure that it's properly set. Return true iff
44  * circuit purpose is properly set, otherwise return false. */
45 static int
46 circuit_purpose_is_correct_for_rend(unsigned int circ_purpose,
47  int is_service_side)
48 {
49  if (is_service_side) {
50  if (circ_purpose != CIRCUIT_PURPOSE_S_CONNECT_REND) {
51  log_warn(LD_BUG,
52  "HS e2e circuit setup with wrong purpose (%d)", circ_purpose);
53  return 0;
54  }
55  }
56 
57  if (!is_service_side) {
58  if (circ_purpose != CIRCUIT_PURPOSE_C_REND_READY &&
60  log_warn(LD_BUG,
61  "Client e2e circuit setup with wrong purpose (%d)", circ_purpose);
62  return 0;
63  }
64  }
65 
66  return 1;
67 }
68 
69 /* Create and return a crypt path for the final hop of a v3 prop224 rendezvous
70  * circuit. Initialize the crypt path crypto using the output material from the
71  * ntor key exchange at <b>ntor_key_seed</b>.
72  *
73  * If <b>is_service_side</b> is set, we are the hidden service and the final
74  * hop of the rendezvous circuit is the client on the other side. */
75 static crypt_path_t *
76 create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len,
77  int is_service_side)
78 {
79  uint8_t keys[HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN];
80  crypt_path_t *cpath = NULL;
81 
82  /* Do the key expansion */
83  if (hs_ntor_circuit_key_expansion(ntor_key_seed, seed_len,
84  keys, sizeof(keys)) < 0) {
85  goto err;
86  }
87 
88  /* Setup the cpath */
89  cpath = tor_malloc_zero(sizeof(crypt_path_t));
90  cpath->magic = CRYPT_PATH_MAGIC;
91 
92  if (circuit_init_cpath_crypto(cpath, (char*)keys, sizeof(keys),
93  is_service_side, 1) < 0) {
94  tor_free(cpath);
95  goto err;
96  }
97 
98  err:
99  memwipe(keys, 0, sizeof(keys));
100  return cpath;
101 }
102 
103 /* We are a v2 legacy HS client: Create and return a crypt path for the hidden
104  * service on the other side of the rendezvous circuit <b>circ</b>. Initialize
105  * the crypt path crypto using the body of the RENDEZVOUS1 cell at
106  * <b>rend_cell_body</b> (which must be at least DH1024_KEY_LEN+DIGEST_LEN
107  * bytes).
108  */
109 static crypt_path_t *
110 create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
111 {
112  crypt_path_t *hop = NULL;
113  char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN];
114 
115  /* first DH1024_KEY_LEN bytes are g^y from the service. Finish the dh
116  * handshake...*/
117  tor_assert(circ->build_state);
119  hop = circ->build_state->pending_final_cpath;
120 
122  if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->rend_dh_handshake_state,
123  (char*)rend_cell_body, DH1024_KEY_LEN,
124  keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
125  log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
126  goto err;
127  }
128  /* ... and set up cpath. */
130  keys+DIGEST_LEN, sizeof(keys)-DIGEST_LEN,
131  0, 0) < 0)
132  goto err;
133 
134  /* Check whether the digest is right... */
135  if (tor_memneq(keys, rend_cell_body+DH1024_KEY_LEN, DIGEST_LEN)) {
136  log_warn(LD_PROTOCOL, "Incorrect digest of key material.");
137  goto err;
138  }
139 
140  /* clean up the crypto stuff we just made */
141  crypto_dh_free(hop->rend_dh_handshake_state);
142  hop->rend_dh_handshake_state = NULL;
143 
144  goto done;
145 
146  err:
147  hop = NULL;
148 
149  done:
150  memwipe(keys, 0, sizeof(keys));
151  return hop;
152 }
153 
154 /* Append the final <b>hop</b> to the cpath of the rend <b>circ</b>, and mark
155  * <b>circ</b> ready for use to transfer HS relay cells. */
156 static void
157 finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop,
158  int is_service_side)
159 {
160  tor_assert(circ);
161  tor_assert(hop);
162 
163  /* Notify the circuit state machine that we are splicing this circuit */
164  int new_circ_purpose = is_service_side ?
166  circuit_change_purpose(TO_CIRCUIT(circ), new_circ_purpose);
167 
168  /* All is well. Extend the circuit. */
169  hop->state = CPATH_STATE_OPEN;
170  /* Set the windows to default. */
173 
174  /* Now that this circuit has finished connecting to its destination,
175  * make sure circuit_get_open_circ_or_launch is willing to return it
176  * so we can actually use it. */
177  circ->hs_circ_has_timed_out = 0;
178 
179  /* Append the hop to the cpath of this circuit */
180  onion_append_to_cpath(&circ->cpath, hop);
181 
182  /* In legacy code, 'pending_final_cpath' points to the final hop we just
183  * appended to the cpath. We set the original pointer to NULL so that we
184  * don't double free it. */
185  if (circ->build_state) {
186  circ->build_state->pending_final_cpath = NULL;
187  }
188 
189  /* Finally, mark circuit as ready to be used for client streams */
190  if (!is_service_side) {
192  }
193 }
194 
195 /* For a given circuit and a service introduction point object, register the
196  * intro circuit to the circuitmap. This supports legacy intro point. */
197 static void
198 register_intro_circ(const hs_service_intro_point_t *ip,
199  origin_circuit_t *circ)
200 {
201  tor_assert(ip);
202  tor_assert(circ);
203 
204  if (ip->base.is_only_legacy) {
205  hs_circuitmap_register_intro_circ_v2_service_side(circ,
206  ip->legacy_key_digest);
207  } else {
208  hs_circuitmap_register_intro_circ_v3_service_side(circ,
209  &ip->auth_key_kp.pubkey);
210  }
211 }
212 
213 /* Return the number of opened introduction circuit for the given circuit that
214  * is matching its identity key. */
215 static unsigned int
216 count_opened_desc_intro_point_circuits(const hs_service_t *service,
217  const hs_service_descriptor_t *desc)
218 {
219  unsigned int count = 0;
220 
221  tor_assert(service);
222  tor_assert(desc);
223 
224  DIGEST256MAP_FOREACH(desc->intro_points.map, key,
225  const hs_service_intro_point_t *, ip) {
226  const circuit_t *circ;
227  const origin_circuit_t *ocirc = hs_circ_service_get_intro_circ(ip);
228  if (ocirc == NULL) {
229  continue;
230  }
231  circ = TO_CIRCUIT(ocirc);
234  /* Having a circuit not for the requested service is really bad. */
235  tor_assert(ed25519_pubkey_eq(&service->keys.identity_pk,
236  &ocirc->hs_ident->identity_pk));
237  /* Only count opened circuit and skip circuit that will be closed. */
238  if (!circ->marked_for_close && circ->state == CIRCUIT_STATE_OPEN) {
239  count++;
240  }
241  } DIGEST256MAP_FOREACH_END;
242  return count;
243 }
244 
245 /* From a given service, rendezvous cookie and handshake info, create a
246  * rendezvous point circuit identifier. This can't fail. */
247 STATIC hs_ident_circuit_t *
248 create_rp_circuit_identifier(const hs_service_t *service,
249  const uint8_t *rendezvous_cookie,
250  const curve25519_public_key_t *server_pk,
251  const hs_ntor_rend_cell_keys_t *keys)
252 {
253  hs_ident_circuit_t *ident;
254  uint8_t handshake_info[CURVE25519_PUBKEY_LEN + DIGEST256_LEN];
255 
256  tor_assert(service);
257  tor_assert(rendezvous_cookie);
258  tor_assert(server_pk);
259  tor_assert(keys);
260 
261  ident = hs_ident_circuit_new(&service->keys.identity_pk,
262  HS_IDENT_CIRCUIT_RENDEZVOUS);
263  /* Copy the RENDEZVOUS_COOKIE which is the unique identifier. */
264  memcpy(ident->rendezvous_cookie, rendezvous_cookie,
265  sizeof(ident->rendezvous_cookie));
266  /* Build the HANDSHAKE_INFO which looks like this:
267  * SERVER_PK [32 bytes]
268  * AUTH_INPUT_MAC [32 bytes]
269  */
270  memcpy(handshake_info, server_pk->public_key, CURVE25519_PUBKEY_LEN);
271  memcpy(handshake_info + CURVE25519_PUBKEY_LEN, keys->rend_cell_auth_mac,
272  DIGEST256_LEN);
273  tor_assert(sizeof(ident->rendezvous_handshake_info) ==
274  sizeof(handshake_info));
275  memcpy(ident->rendezvous_handshake_info, handshake_info,
276  sizeof(ident->rendezvous_handshake_info));
277  /* Finally copy the NTOR_KEY_SEED for e2e encryption on the circuit. */
278  tor_assert(sizeof(ident->rendezvous_ntor_key_seed) ==
279  sizeof(keys->ntor_key_seed));
280  memcpy(ident->rendezvous_ntor_key_seed, keys->ntor_key_seed,
281  sizeof(ident->rendezvous_ntor_key_seed));
282  return ident;
283 }
284 
285 /* From a given service and service intro point, create an introduction point
286  * circuit identifier. This can't fail. */
287 static hs_ident_circuit_t *
288 create_intro_circuit_identifier(const hs_service_t *service,
289  const hs_service_intro_point_t *ip)
290 {
291  hs_ident_circuit_t *ident;
292 
293  tor_assert(service);
294  tor_assert(ip);
295 
296  ident = hs_ident_circuit_new(&service->keys.identity_pk,
297  HS_IDENT_CIRCUIT_INTRO);
298  ed25519_pubkey_copy(&ident->intro_auth_pk, &ip->auth_key_kp.pubkey);
299 
300  return ident;
301 }
302 
303 /* For a given introduction point and an introduction circuit, send the
304  * ESTABLISH_INTRO cell. The service object is used for logging. This can fail
305  * and if so, the circuit is closed and the intro point object is flagged
306  * that the circuit is not established anymore which is important for the
307  * retry mechanism. */
308 static void
309 send_establish_intro(const hs_service_t *service,
311 {
312  ssize_t cell_len;
313  uint8_t payload[RELAY_PAYLOAD_SIZE];
314 
315  tor_assert(service);
316  tor_assert(ip);
317  tor_assert(circ);
318 
319  /* Encode establish intro cell. */
320  cell_len = hs_cell_build_establish_intro(circ->cpath->prev->rend_circ_nonce,
321  ip, payload);
322  if (cell_len < 0) {
323  log_warn(LD_REND, "Unable to encode ESTABLISH_INTRO cell for service %s "
324  "on circuit %u. Closing circuit.",
325  safe_str_client(service->onion_address),
326  TO_CIRCUIT(circ)->n_circ_id);
327  goto err;
328  }
329 
330  /* Send the cell on the circuit. */
331  if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ),
332  RELAY_COMMAND_ESTABLISH_INTRO,
333  (char *) payload, cell_len,
334  circ->cpath->prev) < 0) {
335  log_info(LD_REND, "Unable to send ESTABLISH_INTRO cell for service %s "
336  "on circuit %u.",
337  safe_str_client(service->onion_address),
338  TO_CIRCUIT(circ)->n_circ_id);
339  /* On error, the circuit has been closed. */
340  goto done;
341  }
342 
343  /* Record the attempt to use this circuit. */
345  goto done;
346 
347  err:
348  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
349  done:
350  memwipe(payload, 0, sizeof(payload));
351 }
352 
353 /* Return a string constant describing the anonymity of service. */
354 static const char *
355 get_service_anonymity_string(const hs_service_t *service)
356 {
357  if (service->config.is_single_onion) {
358  return "single onion";
359  } else {
360  return "hidden";
361  }
362 }
363 
364 /* For a given service, the ntor onion key and a rendezvous cookie, launch a
365  * circuit to the rendezvous point specified by the link specifiers. On
366  * success, a circuit identifier is attached to the circuit with the needed
367  * data. This function will try to open a circuit for a maximum value of
368  * MAX_REND_FAILURES then it will give up. */
369 static void
370 launch_rendezvous_point_circuit(const hs_service_t *service,
371  const hs_service_intro_point_t *ip,
372  const hs_cell_introduce2_data_t *data)
373 {
374  int circ_needs_uptime;
375  time_t now = time(NULL);
376  extend_info_t *info = NULL;
377  origin_circuit_t *circ;
378 
379  tor_assert(service);
380  tor_assert(ip);
381  tor_assert(data);
382 
383  circ_needs_uptime = hs_service_requires_uptime_circ(service->config.ports);
384 
385  /* Get the extend info data structure for the chosen rendezvous point
386  * specified by the given link specifiers. */
387  info = hs_get_extend_info_from_lspecs(data->link_specifiers,
388  &data->onion_pk,
389  service->config.is_single_onion);
390  if (info == NULL) {
391  /* We are done here, we can't extend to the rendezvous point.
392  * If you're running an IPv6-only v3 single onion service on 0.3.2 or with
393  * 0.3.2 clients, and somehow disable the option check, it will fail here.
394  */
395  log_fn(LOG_PROTOCOL_WARN, LD_REND,
396  "Not enough info to open a circuit to a rendezvous point for "
397  "%s service %s.",
398  get_service_anonymity_string(service),
399  safe_str_client(service->onion_address));
400  goto end;
401  }
402 
403  for (int i = 0; i < MAX_REND_FAILURES; i++) {
405  if (circ_needs_uptime) {
406  circ_flags |= CIRCLAUNCH_NEED_UPTIME;
407  }
408  /* Firewall and policies are checked when getting the extend info. */
409  if (service->config.is_single_onion) {
410  circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
411  }
412 
414  circ_flags);
415  if (circ != NULL) {
416  /* Stop retrying, we have a circuit! */
417  break;
418  }
419  }
420  if (circ == NULL) {
421  log_warn(LD_REND, "Giving up on launching a rendezvous circuit to %s "
422  "for %s service %s",
424  get_service_anonymity_string(service),
425  safe_str_client(service->onion_address));
426  goto end;
427  }
428  log_info(LD_REND, "Rendezvous circuit launched to %s with cookie %s "
429  "for %s service %s",
431  safe_str_client(hex_str((const char *) data->rendezvous_cookie,
432  REND_COOKIE_LEN)),
433  get_service_anonymity_string(service),
434  safe_str_client(service->onion_address));
435  tor_assert(circ->build_state);
436  /* Rendezvous circuit have a specific timeout for the time spent on trying
437  * to connect to the rendezvous point. */
439 
440  /* Create circuit identifier and key material. */
441  {
443  curve25519_keypair_t ephemeral_kp;
444  /* No need for extra strong, this is only for this circuit life time. This
445  * key will be used for the RENDEZVOUS1 cell that will be sent on the
446  * circuit once opened. */
447  curve25519_keypair_generate(&ephemeral_kp, 0);
448  if (hs_ntor_service_get_rendezvous1_keys(&ip->auth_key_kp.pubkey,
449  &ip->enc_key_kp,
450  &ephemeral_kp, &data->client_pk,
451  &keys) < 0) {
452  /* This should not really happened but just in case, don't make tor
453  * freak out, close the circuit and move on. */
454  log_info(LD_REND, "Unable to get RENDEZVOUS1 key material for "
455  "service %s",
456  safe_str_client(service->onion_address));
457  circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
458  goto end;
459  }
460  circ->hs_ident = create_rp_circuit_identifier(service,
461  data->rendezvous_cookie,
462  &ephemeral_kp.pubkey, &keys);
463  memwipe(&ephemeral_kp, 0, sizeof(ephemeral_kp));
464  memwipe(&keys, 0, sizeof(keys));
465  tor_assert(circ->hs_ident);
466  }
467 
468  end:
469  extend_info_free(info);
470 }
471 
472 /* Return true iff the given service rendezvous circuit circ is allowed for a
473  * relaunch to the rendezvous point. */
474 static int
475 can_relaunch_service_rendezvous_point(const origin_circuit_t *circ)
476 {
477  tor_assert(circ);
478  /* This is initialized when allocating an origin circuit. */
479  tor_assert(circ->build_state);
481 
482  /* XXX: Retrying under certain condition. This is related to #22455. */
483 
484  /* Avoid to relaunch twice a circuit to the same rendezvous point at the
485  * same time. */
487  log_info(LD_REND, "Rendezvous circuit to %s has already been retried. "
488  "Skipping retry.",
491  goto disallow;
492  }
493 
494  /* We check failure_count >= hs_get_service_max_rend_failures()-1 below, and
495  * the -1 is because we increment the failure count for our current failure
496  * *after* this clause. */
497  int max_rend_failures = hs_get_service_max_rend_failures() - 1;
498 
499  /* A failure count that has reached maximum allowed or circuit that expired,
500  * we skip relaunching. */
501  if (circ->build_state->failure_count > max_rend_failures ||
502  circ->build_state->expiry_time <= time(NULL)) {
503  log_info(LD_REND, "Attempt to build a rendezvous circuit to %s has "
504  "failed with %d attempts and expiry time %ld. "
505  "Giving up building.",
508  circ->build_state->failure_count,
509  (long int) circ->build_state->expiry_time);
510  goto disallow;
511  }
512 
513  /* Allowed to relaunch. */
514  return 1;
515  disallow:
516  return 0;
517 }
518 
519 /* Retry the rendezvous point of circ by launching a new circuit to it. */
520 static void
521 retry_service_rendezvous_point(const origin_circuit_t *circ)
522 {
523  int flags = 0;
524  origin_circuit_t *new_circ;
525  cpath_build_state_t *bstate;
526 
527  tor_assert(circ);
528  /* This is initialized when allocating an origin circuit. */
529  tor_assert(circ->build_state);
531 
532  /* Ease our life. */
533  bstate = circ->build_state;
534 
535  log_info(LD_REND, "Retrying rendezvous point circuit to %s",
537 
538  /* Get the current build state flags for the next circuit. */
539  flags |= (bstate->need_uptime) ? CIRCLAUNCH_NEED_UPTIME : 0;
540  flags |= (bstate->need_capacity) ? CIRCLAUNCH_NEED_CAPACITY : 0;
541  flags |= (bstate->is_internal) ? CIRCLAUNCH_IS_INTERNAL : 0;
542 
543  /* We do NOT add the onehop tunnel flag even though it might be a single
544  * onion service. The reason is that if we failed once to connect to the RP
545  * with a direct connection, we consider that chances are that we will fail
546  * again so try a 3-hop circuit and hope for the best. Because the service
547  * has no anonymity (single onion), this change of behavior won't affect
548  * security directly. */
549 
551  bstate->chosen_exit, flags);
552  if (new_circ == NULL) {
553  log_warn(LD_REND, "Failed to launch rendezvous circuit to %s",
555  goto done;
556  }
557 
558  /* Transfer build state information to the new circuit state in part to
559  * catch any other failures. */
560  new_circ->build_state->failure_count = bstate->failure_count+1;
561  new_circ->build_state->expiry_time = bstate->expiry_time;
562  new_circ->hs_ident = hs_ident_circuit_dup(circ->hs_ident);
563 
564  done:
565  return;
566 }
567 
568 /* Add all possible link specifiers in node to lspecs:
569  * - legacy ID is mandatory thus MUST be present in node;
570  * - include ed25519 link specifier if present in the node, and the node
571  * supports ed25519 link authentication, even if its link versions are not
572  * compatible with us;
573  * - include IPv4 link specifier, if the primary address is not IPv4, log a
574  * BUG() warning, and return an empty smartlist;
575  * - include IPv6 link specifier if present in the node. */
576 static void
577 get_lspecs_from_node(const node_t *node, smartlist_t *lspecs)
578 {
579  link_specifier_t *ls;
580  tor_addr_port_t ap;
581 
582  tor_assert(node);
583  tor_assert(lspecs);
584 
585  /* Get the relay's IPv4 address. */
586  node_get_prim_orport(node, &ap);
587 
588  /* We expect the node's primary address to be a valid IPv4 address.
589  * This conforms to the protocol, which requires either an IPv4 or IPv6
590  * address (or both). */
591  if (BUG(!tor_addr_is_v4(&ap.addr)) ||
592  BUG(!tor_addr_port_is_valid_ap(&ap, 0))) {
593  return;
594  }
595 
596  ls = link_specifier_new();
597  link_specifier_set_ls_type(ls, LS_IPV4);
598  link_specifier_set_un_ipv4_addr(ls, tor_addr_to_ipv4h(&ap.addr));
599  link_specifier_set_un_ipv4_port(ls, ap.port);
600  /* Four bytes IPv4 and two bytes port. */
601  link_specifier_set_ls_len(ls, sizeof(ap.addr.addr.in_addr) +
602  sizeof(ap.port));
603  smartlist_add(lspecs, ls);
604 
605  /* Legacy ID is mandatory and will always be present in node. */
606  ls = link_specifier_new();
607  link_specifier_set_ls_type(ls, LS_LEGACY_ID);
608  memcpy(link_specifier_getarray_un_legacy_id(ls), node->identity,
609  link_specifier_getlen_un_legacy_id(ls));
610  link_specifier_set_ls_len(ls, link_specifier_getlen_un_legacy_id(ls));
611  smartlist_add(lspecs, ls);
612 
613  /* ed25519 ID is only included if the node has it, and the node declares a
614  protocol version that supports ed25519 link authentication, even if that
615  link version is not compatible with us. (We are sending the ed25519 key
616  to another tor, which may support different link versions.) */
617  if (!ed25519_public_key_is_zero(&node->ed25519_id) &&
619  ls = link_specifier_new();
620  link_specifier_set_ls_type(ls, LS_ED25519_ID);
621  memcpy(link_specifier_getarray_un_ed25519_id(ls), &node->ed25519_id,
622  link_specifier_getlen_un_ed25519_id(ls));
623  link_specifier_set_ls_len(ls, link_specifier_getlen_un_ed25519_id(ls));
624  smartlist_add(lspecs, ls);
625  }
626 
627  /* Check for IPv6. If so, include it as well. */
628  if (node_has_ipv6_orport(node)) {
629  ls = link_specifier_new();
630  node_get_pref_ipv6_orport(node, &ap);
631  link_specifier_set_ls_type(ls, LS_IPV6);
632  size_t addr_len = link_specifier_getlen_un_ipv6_addr(ls);
633  const uint8_t *in6_addr = tor_addr_to_in6_addr8(&ap.addr);
634  uint8_t *ipv6_array = link_specifier_getarray_un_ipv6_addr(ls);
635  memcpy(ipv6_array, in6_addr, addr_len);
636  link_specifier_set_un_ipv6_port(ls, ap.port);
637  /* Sixteen bytes IPv6 and two bytes port. */
638  link_specifier_set_ls_len(ls, addr_len + sizeof(ap.port));
639  smartlist_add(lspecs, ls);
640  }
641 }
642 
643 /* Using the given descriptor intro point ip, the node of the
644  * rendezvous point rp_node and the service's subcredential, populate the
645  * already allocated intro1_data object with the needed key material and link
646  * specifiers.
647  *
648  * Return 0 on success or a negative value if we couldn't properly filled the
649  * introduce1 data from the RP node. In other word, it means the RP node is
650  * unusable to use in the introduction. */
651 static int
652 setup_introduce1_data(const hs_desc_intro_point_t *ip,
653  const node_t *rp_node,
654  const uint8_t *subcredential,
655  hs_cell_introduce1_data_t *intro1_data)
656 {
657  int ret = -1;
658  smartlist_t *rp_lspecs;
659 
660  tor_assert(ip);
661  tor_assert(rp_node);
662  tor_assert(subcredential);
663  tor_assert(intro1_data);
664 
665  /* Build the link specifiers from the extend information of the rendezvous
666  * circuit that we've picked previously. */
667  rp_lspecs = smartlist_new();
668  get_lspecs_from_node(rp_node, rp_lspecs);
669  if (smartlist_len(rp_lspecs) == 0) {
670  /* We can't rendezvous without link specifiers. */
671  smartlist_free(rp_lspecs);
672  goto end;
673  }
674 
675  /* Populate the introduce1 data object. */
676  memset(intro1_data, 0, sizeof(hs_cell_introduce1_data_t));
677  if (ip->legacy.key != NULL) {
678  intro1_data->is_legacy = 1;
679  intro1_data->legacy_key = ip->legacy.key;
680  }
681  intro1_data->auth_pk = &ip->auth_key_cert->signed_key;
682  intro1_data->enc_pk = &ip->enc_key;
683  intro1_data->subcredential = subcredential;
684  intro1_data->link_specifiers = rp_lspecs;
685  intro1_data->onion_pk = node_get_curve25519_onion_key(rp_node);
686  if (intro1_data->onion_pk == NULL) {
687  /* We can't rendezvous without the curve25519 onion key. */
688  goto end;
689  }
690  /* Success, we have valid introduce data. */
691  ret = 0;
692 
693  end:
694  return ret;
695 }
696 
697 /* ========== */
698 /* Public API */
699 /* ========== */
700 
701 /* Return an introduction point circuit matching the given intro point object.
702  * NULL is returned is no such circuit can be found. */
704 hs_circ_service_get_intro_circ(const hs_service_intro_point_t *ip)
705 {
706  tor_assert(ip);
707 
708  if (ip->base.is_only_legacy) {
709  return hs_circuitmap_get_intro_circ_v2_service_side(ip->legacy_key_digest);
710  } else {
712  &ip->auth_key_kp.pubkey);
713  }
714 }
715 
716 /* Called when we fail building a rendezvous circuit at some point other than
717  * the last hop: launches a new circuit to the same rendezvous point. This
718  * supports legacy service.
719  *
720  * We currently relaunch connections to rendezvous points if:
721  * - A rendezvous circuit timed out before connecting to RP.
722  * - The rendezvous circuit failed to connect to the RP.
723  *
724  * We avoid relaunching a connection to this rendezvous point if:
725  * - We have already tried MAX_REND_FAILURES times to connect to this RP,
726  * - We've been trying to connect to this RP for more than MAX_REND_TIMEOUT
727  * seconds, or
728  * - We've already retried this specific rendezvous circuit.
729  */
730 void
731 hs_circ_retry_service_rendezvous_point(origin_circuit_t *circ)
732 {
733  tor_assert(circ);
735 
736  /* Check if we are allowed to relaunch to the rendezvous point of circ. */
737  if (!can_relaunch_service_rendezvous_point(circ)) {
738  goto done;
739  }
740 
741  /* Flag the circuit that we are relaunching, to avoid to relaunch twice a
742  * circuit to the same rendezvous point at the same time. */
744 
745  /* Legacy services don't have a hidden service ident. */
746  if (circ->hs_ident) {
747  retry_service_rendezvous_point(circ);
748  } else {
750  }
751 
752  done:
753  return;
754 }
755 
756 /* For a given service and a service intro point, launch a circuit to the
757  * extend info ei. If the service is a single onion, a one-hop circuit will be
758  * requested. Return 0 if the circuit was successfully launched and tagged
759  * with the correct identifier. On error, a negative value is returned. */
760 int
761 hs_circ_launch_intro_point(hs_service_t *service,
762  const hs_service_intro_point_t *ip,
763  extend_info_t *ei)
764 {
765  /* Standard flags for introduction circuit. */
766  int ret = -1, circ_flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
767  origin_circuit_t *circ;
768 
769  tor_assert(service);
770  tor_assert(ip);
771  tor_assert(ei);
772 
773  /* Update circuit flags in case of a single onion service that requires a
774  * direct connection. */
775  if (service->config.is_single_onion) {
776  circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
777  }
778 
779  log_info(LD_REND, "Launching a circuit to intro point %s for service %s.",
781  safe_str_client(service->onion_address));
782 
783  /* Note down the launch for the retry period. Even if the circuit fails to
784  * be launched, we still want to respect the retry period to avoid stress on
785  * the circuit subsystem. */
786  service->state.num_intro_circ_launched++;
788  ei, circ_flags);
789  if (circ == NULL) {
790  goto end;
791  }
792 
793  /* Setup the circuit identifier and attach it to it. */
794  circ->hs_ident = create_intro_circuit_identifier(service, ip);
795  tor_assert(circ->hs_ident);
796  /* Register circuit in the global circuitmap. */
797  register_intro_circ(ip, circ);
798 
799  /* Success. */
800  ret = 0;
801  end:
802  return ret;
803 }
804 
805 /* Called when a service introduction point circuit is done building. Given
806  * the service and intro point object, this function will send the
807  * ESTABLISH_INTRO cell on the circuit. Return 0 on success. Return 1 if the
808  * circuit has been repurposed to General because we already have too many
809  * opened. */
810 int
811 hs_circ_service_intro_has_opened(hs_service_t *service,
813  const hs_service_descriptor_t *desc,
814  origin_circuit_t *circ)
815 {
816  int ret = 0;
817  unsigned int num_intro_circ, num_needed_circ;
818 
819  tor_assert(service);
820  tor_assert(ip);
821  tor_assert(desc);
822  tor_assert(circ);
823 
824  /* Cound opened circuits that have sent ESTABLISH_INTRO cells or are already
825  * established introduction circuits */
826  num_intro_circ = count_opened_desc_intro_point_circuits(service, desc);
827  num_needed_circ = service->config.num_intro_points;
828  if (num_intro_circ > num_needed_circ) {
829  /* There are too many opened valid intro circuit for what the service
830  * needs so repurpose this one. */
831 
832  /* XXX: Legacy code checks options->ExcludeNodes and if not NULL it just
833  * closes the circuit. I have NO idea why it does that so it hasn't been
834  * added here. I can only assume in case our ExcludeNodes list changes but
835  * in that case, all circuit are flagged unusable (config.c). --dgoulet */
836 
837  log_info(LD_CIRC | LD_REND, "Introduction circuit just opened but we "
838  "have enough for service %s. Repurposing "
839  "it to general and leaving internal.",
840  safe_str_client(service->onion_address));
842  /* Remove it from the circuitmap. */
844  /* Cleaning up the hidden service identifier and repurpose. */
845  hs_ident_circuit_free(circ->hs_ident);
846  circ->hs_ident = NULL;
847  if (circuit_should_use_vanguards(TO_CIRCUIT(circ)->purpose))
849  else
851 
852  /* Inform that this circuit just opened for this new purpose. */
853  circuit_has_opened(circ);
854  /* This return value indicate to the caller that the IP object should be
855  * removed from the service because it's corresponding circuit has just
856  * been repurposed. */
857  ret = 1;
858  goto done;
859  }
860 
861  log_info(LD_REND, "Introduction circuit %u established for service %s.",
862  TO_CIRCUIT(circ)->n_circ_id,
863  safe_str_client(service->onion_address));
865 
866  /* Time to send an ESTABLISH_INTRO cell on this circuit. On error, this call
867  * makes sure the circuit gets closed. */
868  send_establish_intro(service, ip, circ);
869 
870  done:
871  return ret;
872 }
873 
874 /* Called when a service rendezvous point circuit is done building. Given the
875  * service and the circuit, this function will send a RENDEZVOUS1 cell on the
876  * circuit using the information in the circuit identifier. If the cell can't
877  * be sent, the circuit is closed. */
878 void
879 hs_circ_service_rp_has_opened(const hs_service_t *service,
880  origin_circuit_t *circ)
881 {
882  size_t payload_len;
883  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
884 
885  tor_assert(service);
886  tor_assert(circ);
887  tor_assert(circ->hs_ident);
888 
889  /* Some useful logging. */
890  log_info(LD_REND, "Rendezvous circuit %u has opened with cookie %s "
891  "for service %s",
892  TO_CIRCUIT(circ)->n_circ_id,
893  hex_str((const char *) circ->hs_ident->rendezvous_cookie,
895  safe_str_client(service->onion_address));
897 
898  /* This can't fail. */
899  payload_len = hs_cell_build_rendezvous1(
900  circ->hs_ident->rendezvous_cookie,
901  sizeof(circ->hs_ident->rendezvous_cookie),
902  circ->hs_ident->rendezvous_handshake_info,
903  sizeof(circ->hs_ident->rendezvous_handshake_info),
904  payload);
905 
906  /* Pad the payload with random bytes so it matches the size of a legacy cell
907  * which is normally always bigger. Also, the size of a legacy cell is
908  * always smaller than the RELAY_PAYLOAD_SIZE so this is safe. */
909  if (payload_len < HS_LEGACY_RENDEZVOUS_CELL_SIZE) {
910  crypto_rand((char *) payload + payload_len,
911  HS_LEGACY_RENDEZVOUS_CELL_SIZE - payload_len);
912  payload_len = HS_LEGACY_RENDEZVOUS_CELL_SIZE;
913  }
914 
915  if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ),
916  RELAY_COMMAND_RENDEZVOUS1,
917  (const char *) payload, payload_len,
918  circ->cpath->prev) < 0) {
919  /* On error, circuit is closed. */
920  log_warn(LD_REND, "Unable to send RENDEZVOUS1 cell on circuit %u "
921  "for service %s",
922  TO_CIRCUIT(circ)->n_circ_id,
923  safe_str_client(service->onion_address));
924  goto done;
925  }
926 
927  /* Setup end-to-end rendezvous circuit between the client and us. */
928  if (hs_circuit_setup_e2e_rend_circ(circ,
929  circ->hs_ident->rendezvous_ntor_key_seed,
930  sizeof(circ->hs_ident->rendezvous_ntor_key_seed),
931  1) < 0) {
932  log_warn(LD_GENERAL, "Failed to setup circ");
933  goto done;
934  }
935 
936  done:
937  memwipe(payload, 0, sizeof(payload));
938 }
939 
940 /* Circ has been expecting an INTRO_ESTABLISHED cell that just arrived. Handle
941  * the INTRO_ESTABLISHED cell payload of length payload_len arriving on the
942  * given introduction circuit circ. The service is only used for logging
943  * purposes. Return 0 on success else a negative value. */
944 int
945 hs_circ_handle_intro_established(const hs_service_t *service,
946  const hs_service_intro_point_t *ip,
947  origin_circuit_t *circ,
948  const uint8_t *payload, size_t payload_len)
949 {
950  int ret = -1;
951 
952  tor_assert(service);
953  tor_assert(ip);
954  tor_assert(circ);
955  tor_assert(payload);
956 
957  if (BUG(TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO)) {
958  goto done;
959  }
960 
961  /* Try to parse the payload into a cell making sure we do actually have a
962  * valid cell. For a legacy node, it's an empty payload so as long as we
963  * have the cell, we are good. */
964  if (!ip->base.is_only_legacy &&
965  hs_cell_parse_intro_established(payload, payload_len) < 0) {
966  log_warn(LD_REND, "Unable to parse the INTRO_ESTABLISHED cell on "
967  "circuit %u for service %s",
968  TO_CIRCUIT(circ)->n_circ_id,
969  safe_str_client(service->onion_address));
970  goto done;
971  }
972 
973  /* Switch the purpose to a fully working intro point. */
975  /* Getting a valid INTRODUCE_ESTABLISHED means we've successfully used the
976  * circuit so update our pathbias subsystem. */
978  /* Success. */
979  ret = 0;
980 
981  done:
982  return ret;
983 }
984 
985 /* We just received an INTRODUCE2 cell on the established introduction circuit
986  * circ. Handle the INTRODUCE2 payload of size payload_len for the given
987  * circuit and service. This cell is associated with the intro point object ip
988  * and the subcredential. Return 0 on success else a negative value. */
989 int
990 hs_circ_handle_introduce2(const hs_service_t *service,
991  const origin_circuit_t *circ,
993  const uint8_t *subcredential,
994  const uint8_t *payload, size_t payload_len)
995 {
996  int ret = -1;
997  time_t elapsed;
999 
1000  tor_assert(service);
1001  tor_assert(circ);
1002  tor_assert(ip);
1003  tor_assert(subcredential);
1004  tor_assert(payload);
1005 
1006  /* Populate the data structure with everything we need for the cell to be
1007  * parsed, decrypted and key material computed correctly. */
1008  data.auth_pk = &ip->auth_key_kp.pubkey;
1009  data.enc_kp = &ip->enc_key_kp;
1010  data.subcredential = subcredential;
1011  data.payload = payload;
1012  data.payload_len = payload_len;
1013  data.link_specifiers = smartlist_new();
1014  data.replay_cache = ip->replay_cache;
1015 
1016  if (hs_cell_parse_introduce2(&data, circ, service) < 0) {
1017  goto done;
1018  }
1019 
1020  /* Check whether we've seen this REND_COOKIE before to detect repeats. */
1022  service->state.replay_cache_rend_cookie,
1023  data.rendezvous_cookie, sizeof(data.rendezvous_cookie),
1024  &elapsed)) {
1025  /* A Tor client will send a new INTRODUCE1 cell with the same REND_COOKIE
1026  * as its previous one if its intro circ times out while in state
1027  * CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT. If we received the first
1028  * INTRODUCE1 cell (the intro-point relay converts it into an INTRODUCE2
1029  * cell), we are already trying to connect to that rend point (and may
1030  * have already succeeded); drop this cell. */
1031  log_info(LD_REND, "We received an INTRODUCE2 cell with same REND_COOKIE "
1032  "field %ld seconds ago. Dropping cell.",
1033  (long int) elapsed);
1034  goto done;
1035  }
1036 
1037  /* At this point, we just confirmed that the full INTRODUCE2 cell is valid
1038  * so increment our counter that we've seen one on this intro point. */
1039  ip->introduce2_count++;
1040 
1041  /* Launch rendezvous circuit with the onion key and rend cookie. */
1042  launch_rendezvous_point_circuit(service, ip, &data);
1043  /* Success. */
1044  ret = 0;
1045 
1046  done:
1047  SMARTLIST_FOREACH(data.link_specifiers, link_specifier_t *, lspec,
1048  link_specifier_free(lspec));
1049  smartlist_free(data.link_specifiers);
1050  memwipe(&data, 0, sizeof(data));
1051  return ret;
1052 }
1053 
1054 /* Circuit <b>circ</b> just finished the rend ntor key exchange. Use the key
1055  * exchange output material at <b>ntor_key_seed</b> and setup <b>circ</b> to
1056  * serve as a rendezvous end-to-end circuit between the client and the
1057  * service. If <b>is_service_side</b> is set, then we are the hidden service
1058  * and the other side is the client.
1059  *
1060  * Return 0 if the operation went well; in case of error return -1. */
1061 int
1062 hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ,
1063  const uint8_t *ntor_key_seed, size_t seed_len,
1064  int is_service_side)
1065 {
1066  if (BUG(!circuit_purpose_is_correct_for_rend(TO_CIRCUIT(circ)->purpose,
1067  is_service_side))) {
1068  return -1;
1069  }
1070 
1071  crypt_path_t *hop = create_rend_cpath(ntor_key_seed, seed_len,
1072  is_service_side);
1073  if (!hop) {
1074  log_warn(LD_REND, "Couldn't get v3 %s cpath!",
1075  is_service_side ? "service-side" : "client-side");
1076  return -1;
1077  }
1078 
1079  finalize_rend_circuit(circ, hop, is_service_side);
1080 
1081  return 0;
1082 }
1083 
1084 /* We are a v2 legacy HS client and we just received a RENDEZVOUS1 cell
1085  * <b>rend_cell_body</b> on <b>circ</b>. Finish up the DH key exchange and then
1086  * extend the crypt path of <b>circ</b> so that the hidden service is on the
1087  * other side. */
1088 int
1089 hs_circuit_setup_e2e_rend_circ_legacy_client(origin_circuit_t *circ,
1090  const uint8_t *rend_cell_body)
1091 {
1092 
1093  if (BUG(!circuit_purpose_is_correct_for_rend(
1094  TO_CIRCUIT(circ)->purpose, 0))) {
1095  return -1;
1096  }
1097 
1098  crypt_path_t *hop = create_rend_cpath_legacy(circ, rend_cell_body);
1099  if (!hop) {
1100  log_warn(LD_GENERAL, "Couldn't get v2 cpath.");
1101  return -1;
1102  }
1103 
1104  finalize_rend_circuit(circ, hop, 0);
1105 
1106  return 0;
1107 }
1108 
1109 /* Given the introduction circuit intro_circ, the rendezvous circuit
1110  * rend_circ, a descriptor intro point object ip and the service's
1111  * subcredential, send an INTRODUCE1 cell on intro_circ.
1112  *
1113  * This will also setup the circuit identifier on rend_circ containing the key
1114  * material for the handshake and e2e encryption. Return 0 on success else
1115  * negative value. Because relay_send_command_from_edge() closes the circuit
1116  * on error, it is possible that intro_circ is closed on error. */
1117 int
1118 hs_circ_send_introduce1(origin_circuit_t *intro_circ,
1119  origin_circuit_t *rend_circ,
1120  const hs_desc_intro_point_t *ip,
1121  const uint8_t *subcredential)
1122 {
1123  int ret = -1;
1124  ssize_t payload_len;
1125  uint8_t payload[RELAY_PAYLOAD_SIZE] = {0};
1126  hs_cell_introduce1_data_t intro1_data;
1127 
1128  tor_assert(intro_circ);
1129  tor_assert(rend_circ);
1130  tor_assert(ip);
1131  tor_assert(subcredential);
1132 
1133  /* It is undefined behavior in hs_cell_introduce1_data_clear() if intro1_data
1134  * has been declared on the stack but not initialized. Here, we set it to 0.
1135  */
1136  memset(&intro1_data, 0, sizeof(hs_cell_introduce1_data_t));
1137 
1138  /* This takes various objects in order to populate the introduce1 data
1139  * object which is used to build the content of the cell. */
1140  const node_t *exit_node = build_state_get_exit_node(rend_circ->build_state);
1141  if (exit_node == NULL) {
1142  log_info(LD_REND, "Unable to get rendezvous point for circuit %u. "
1143  "Failing.", TO_CIRCUIT(intro_circ)->n_circ_id);
1144  goto done;
1145  }
1146 
1147  /* We should never select an invalid rendezvous point in theory but if we
1148  * do, this function will fail to populate the introduce data. */
1149  if (setup_introduce1_data(ip, exit_node, subcredential, &intro1_data) < 0) {
1150  log_warn(LD_REND, "Unable to setup INTRODUCE1 data. The chosen rendezvous "
1151  "point is unusable. Closing circuit.");
1152  goto close;
1153  }
1154 
1155  /* Final step before we encode a cell, we setup the circuit identifier which
1156  * will generate both the rendezvous cookie and client keypair for this
1157  * connection. Those are put in the ident. */
1158  intro1_data.rendezvous_cookie = rend_circ->hs_ident->rendezvous_cookie;
1159  intro1_data.client_kp = &rend_circ->hs_ident->rendezvous_client_kp;
1160 
1161  memcpy(intro_circ->hs_ident->rendezvous_cookie,
1162  rend_circ->hs_ident->rendezvous_cookie,
1163  sizeof(intro_circ->hs_ident->rendezvous_cookie));
1164 
1165  /* From the introduce1 data object, this will encode the INTRODUCE1 cell
1166  * into payload which is then ready to be sent as is. */
1167  payload_len = hs_cell_build_introduce1(&intro1_data, payload);
1168  if (BUG(payload_len < 0)) {
1169  goto close;
1170  }
1171 
1172  if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(intro_circ),
1173  RELAY_COMMAND_INTRODUCE1,
1174  (const char *) payload, payload_len,
1175  intro_circ->cpath->prev) < 0) {
1176  /* On error, circuit is closed. */
1177  log_warn(LD_REND, "Unable to send INTRODUCE1 cell on circuit %u.",
1178  TO_CIRCUIT(intro_circ)->n_circ_id);
1179  goto done;
1180  }
1181 
1182  /* Success. */
1183  ret = 0;
1184  goto done;
1185 
1186  close:
1187  circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_INTERNAL);
1188  done:
1189  hs_cell_introduce1_data_clear(&intro1_data);
1190  memwipe(payload, 0, sizeof(payload));
1191  return ret;
1192 }
1193 
1194 /* Send an ESTABLISH_RENDEZVOUS cell along the rendezvous circuit circ. On
1195  * success, 0 is returned else -1 and the circuit is marked for close. */
1196 int
1197 hs_circ_send_establish_rendezvous(origin_circuit_t *circ)
1198 {
1199  ssize_t cell_len = 0;
1200  uint8_t cell[RELAY_PAYLOAD_SIZE] = {0};
1201 
1202  tor_assert(circ);
1204 
1205  log_info(LD_REND, "Send an ESTABLISH_RENDEZVOUS cell on circuit %u",
1206  TO_CIRCUIT(circ)->n_circ_id);
1207 
1208  /* Set timestamp_dirty, because circuit_expire_building expects it,
1209  * and the rend cookie also means we've used the circ. */
1210  TO_CIRCUIT(circ)->timestamp_dirty = time(NULL);
1211 
1212  /* We've attempted to use this circuit. Probe it if we fail */
1214 
1215  /* Generate the RENDEZVOUS_COOKIE and place it in the identifier so we can
1216  * complete the handshake when receiving the acknowledgement. */
1217  crypto_rand((char *) circ->hs_ident->rendezvous_cookie, HS_REND_COOKIE_LEN);
1218  /* Generate the client keypair. No need to be extra strong, not long term */
1219  curve25519_keypair_generate(&circ->hs_ident->rendezvous_client_kp, 0);
1220 
1221  cell_len =
1222  hs_cell_build_establish_rendezvous(circ->hs_ident->rendezvous_cookie,
1223  cell);
1224  if (BUG(cell_len < 0)) {
1225  goto err;
1226  }
1227 
1228  if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(circ),
1229  RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
1230  (const char *) cell, cell_len,
1231  circ->cpath->prev) < 0) {
1232  /* Circuit has been marked for close */
1233  log_warn(LD_REND, "Unable to send ESTABLISH_RENDEZVOUS cell on "
1234  "circuit %u", TO_CIRCUIT(circ)->n_circ_id);
1235  memwipe(cell, 0, cell_len);
1236  goto err;
1237  }
1238 
1239  memwipe(cell, 0, cell_len);
1240  return 0;
1241  err:
1242  return -1;
1243 }
1244 
1245 /* We are about to close or free this <b>circ</b>. Clean it up from any
1246  * related HS data structures. This function can be called multiple times
1247  * safely for the same circuit. */
1248 void
1249 hs_circ_cleanup(circuit_t *circ)
1250 {
1251  tor_assert(circ);
1252 
1253  /* If it's a service-side intro circ, notify the HS subsystem for the intro
1254  * point circuit closing so it can be dealt with cleanly. */
1256  circ->purpose == CIRCUIT_PURPOSE_S_INTRO) {
1257  hs_service_intro_circ_has_closed(TO_ORIGIN_CIRCUIT(circ));
1258  }
1259 
1260  /* Clear HS circuitmap token for this circ (if any). Very important to be
1261  * done after the HS subsystem has been notified of the close else the
1262  * circuit will not be found.
1263  *
1264  * We do this at the close if possible because from that point on, the
1265  * circuit is good as dead. We can't rely on removing it in the circuit
1266  * free() function because we open a race window between the close and free
1267  * where we can't register a new circuit for the same intro point. */
1268  if (circ->hs_token) {
1270  }
1271 }
#define RELAY_PAYLOAD_SIZE
Definition: or.h:605
#define CIRCLAUNCH_ONEHOP_TUNNEL
Definition: circuituse.h:39
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
int circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data, size_t key_data_len, int reverse, int is_hs_v3)
ed25519_public_key_t signed_key
Definition: torcert.h:25
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
Definition: circuitlist.h:87
unsigned int hs_circ_has_timed_out
void node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out)
Definition: nodelist.c:1624
Common functions for using (pseudo-)random number generators.
Definition: node_st.h:28
Header file containing service data for the HS subsytem.
Headers for crypto_dh.c.
int node_supports_ed25519_link_authentication(const node_t *node, int compatible_with_us)
Definition: nodelist.c:1135
void circuit_try_attaching_streams(origin_circuit_t *circ)
Definition: circuituse.c:1745
const char * extend_info_describe(const extend_info_t *ei)
Definition: describe.c:154
uint16_t marked_for_close
Definition: circuit_st.h:154
void rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
Definition: rendservice.c:3011
#define LD_GENERAL
Definition: log.h:58
struct crypto_dh_t * rend_dh_handshake_state
Definition: crypt_path_st.h:41
crypt_path_t * pending_final_cpath
#define CIRCLAUNCH_NEED_UPTIME
Definition: circuituse.h:41
#define LOG_INFO
Definition: log.h:41
Header file for describe.c.
Header file for nodelist.c.
#define CIRCWINDOW_START
Definition: or.h:501
crypt_path_t * cpath
void node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out)
Definition: nodelist.c:1588
#define MAX_REND_TIMEOUT
Definition: hs_common.h:49
void smartlist_add(smartlist_t *sl, void *element)
const char * safe_str_client(const char *address)
Definition: config.c:1059
unsigned int hs_service_side_rend_circ_has_been_relaunched
#define TO_CIRCUIT(x)
Definition: or.h:947
#define CIRCUIT_PURPOSE_C_REND_READY
Definition: circuitlist.h:84
Header file for config.c.
static uint32_t tor_addr_to_ipv4h(const tor_addr_t *a)
Definition: address.h:152
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
Definition: circuitlist.h:100
struct hs_token_t * hs_token
Definition: circuit_st.h:181
#define tor_free(p)
Definition: malloc.h:52
int replaycache_add_test_and_elapsed(replaycache_t *r, const void *data, size_t len, time_t *elapsed)
Definition: replaycache.c:195
uint8_t purpose
Definition: circuit_st.h:102
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
int tor_addr_is_v4(const tor_addr_t *addr)
Definition: address.c:737
#define MAX_REND_FAILURES
Definition: hs_common.h:46
int circuit_should_use_vanguards(uint8_t purpose)
Definition: circuituse.c:1983
#define DIGEST256_LEN
Definition: digest_sizes.h:23
Header file for policies.c.
origin_circuit_t * hs_circuitmap_get_intro_circ_v3_service_side(const ed25519_public_key_t *auth_key)
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
int32_t circuit_initial_package_window(void)
Definition: circuitlist.c:965
const curve25519_public_key_t * node_get_curve25519_onion_key(const node_t *node)
Definition: nodelist.c:1783
Common functions for cryptographic routines.
tor_assert(buffer)
#define LD_CIRC
Definition: log.h:78
uint8_t state
Definition: circuit_st.h:101
#define DIGEST_LEN
Definition: digest_sizes.h:20
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
char identity[DIGEST_LEN]
Definition: node_st.h:40
Header file containing cell data for the whole HS subsytem.
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
Master header file for Tor-specific functionality.
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:31
const char * hex_str(const char *from, size_t fromlen)
Definition: binascii.c:34
Header file for circuitbuild.c.
Header file for rephist.c.
Header file containing circuit and connection identifier data for the whole HS subsytem.
char rend_circ_nonce[DIGEST_LEN]
Definition: crypt_path_st.h:44
Header file for circuituse.c.
const node_t * build_state_get_exit_node(cpath_build_state_t *state)
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND
Definition: circuitlist.h:82
Header file for hs_circuitmap.c.
#define CIRCUIT_PURPOSE_S_CONNECT_REND
Definition: circuitlist.h:106
#define LD_REND
Definition: log.h:80
Header file for circuitlist.c.
Header file for rendservice.c.
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
Definition: circuitbuild.c:358
#define CIRCLAUNCH_NEED_CAPACITY
Definition: circuituse.h:43
void hs_circuitmap_remove_circuit(circuit_t *circ)
#define CIRCUIT_PURPOSE_S_INTRO
Definition: circuitlist.h:103
#define DH1024_KEY_LEN
Definition: dh_sizes.h:20
#define CIRCUIT_PURPOSE_HS_VANGUARDS
Definition: circuitlist.h:127
Header file containing circuit data for the whole HS subsytem.
struct crypt_path_t * prev
Definition: crypt_path_st.h:61
cpath_build_state_t * build_state
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:163
void circuit_has_opened(origin_circuit_t *circ)
Definition: circuituse.c:1671
struct hs_ident_circuit_t * hs_ident
origin_circuit_t * circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info, int flags)
Definition: circuituse.c:2053
void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop)
int hs_get_service_max_rend_failures(void)
Definition: hs_common.c:229
Header file for relay.c.
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len, uint8_t *keys_out, size_t keys_out_len)
Definition: hs_ntor.c:592
#define CIRCUIT_PURPOSE_C_REND_JOINED
Definition: circuitlist.h:89
uint8_t state
Definition: crypt_path_st.h:54
int curve25519_keypair_generate(curve25519_keypair_t *keypair_out, int extra_strong)
#define log_fn(severity, domain, args,...)
Definition: log.h:255
#define CIRCUIT_PURPOSE_C_GENERAL
Definition: circuitlist.h:71
void pathbias_count_use_attempt(origin_circuit_t *circ)
Definition: circpathbias.c:596
void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
Definition: circuituse.c:3048
#define REND_COOKIE_LEN
Definition: or.h:399
extend_info_t * chosen_exit
#define tor_addr_to_in6_addr8(x)
Definition: address.h:129
ssize_t crypto_dh_compute_secret(int severity, crypto_dh_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_bytes_out)
Definition: crypto_dh.c:79
#define CIRCUIT_PURPOSE_S_REND_JOINED
Definition: circuitlist.h:109
#define LD_PROTOCOL
Definition: log.h:68
ed25519_public_key_t ed25519_id
Definition: node_st.h:47
void pathbias_mark_use_success(origin_circuit_t *circ)
Definition: circpathbias.c:652
#define LD_BUG
Definition: log.h:82
#define CURVE25519_PUBKEY_LEN
Definition: x25519_sizes.h:20