Tor  0.4.8.0-alpha-dev
onion.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 onion.c
9  * \brief Functions to queue create cells,
10  * and parse and create the CREATE cell and its allies.
11  *
12  * This module has a few functions, all related to the CREATE/CREATED
13  * handshake that we use on links in order to create a circuit, and the
14  * related EXTEND/EXTENDED handshake that we use over circuits in order to
15  * extend them an additional hop.
16  *
17  * Clients invoke these functions when creating or extending a circuit,
18  * from circuitbuild.c.
19  *
20  * Relays invoke these functions when they receive a CREATE or EXTEND
21  * cell in command.c or relay.c, in order to queue the pending request.
22  * They also invoke them from cpuworker.c, which handles dispatching
23  * onionskin requests to different worker threads.
24  *
25  * <br>
26  *
27  * This module also handles:
28  * <ul>
29  * <li> Queueing incoming onionskins on the relay side before passing
30  * them to worker threads.
31  * <li>Expiring onionskins on the relay side if they have waited for
32  * too long.
33  * <li>Packaging private keys on the server side in order to pass
34  * them to worker threads.
35  * <li>Encoding and decoding CREATE, CREATED, CREATE2, and CREATED2 cells.
36  * <li>Encoding and decodign EXTEND, EXTENDED, EXTEND2, and EXTENDED2
37  * relay cells.
38  * </ul>
39  **/
40 
41 #include "core/or/or.h"
42 
43 #include "app/config/config.h"
45 #include "core/crypto/onion_fast.h"
46 #include "core/crypto/onion_ntor.h"
47 #include "core/crypto/onion_tap.h"
48 #include "core/or/onion.h"
50 
51 #include "core/or/cell_st.h"
52 
53 // trunnel
54 #include "trunnel/ed25519_cert.h"
55 
56 /** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. If
57  * <b>unknown_ok</b> is true, allow cells with handshake types we don't
58  * recognize. */
59 static int
60 check_create_cell(const create_cell_t *cell, int unknown_ok)
61 {
62  switch (cell->cell_type) {
63  case CELL_CREATE:
64  if (cell->handshake_type != ONION_HANDSHAKE_TYPE_TAP &&
65  cell->handshake_type != ONION_HANDSHAKE_TYPE_NTOR)
66  return -1;
67  break;
68  case CELL_CREATE_FAST:
69  if (cell->handshake_type != ONION_HANDSHAKE_TYPE_FAST)
70  return -1;
71  break;
72  case CELL_CREATE2:
73  break;
74  default:
75  return -1;
76  }
77 
78  switch (cell->handshake_type) {
79  case ONION_HANDSHAKE_TYPE_TAP:
80  if (cell->handshake_len != TAP_ONIONSKIN_CHALLENGE_LEN)
81  return -1;
82  break;
83  case ONION_HANDSHAKE_TYPE_FAST:
84  if (cell->handshake_len != CREATE_FAST_LEN)
85  return -1;
86  break;
87  case ONION_HANDSHAKE_TYPE_NTOR:
88  if (cell->handshake_len != NTOR_ONIONSKIN_LEN)
89  return -1;
90  break;
91  case ONION_HANDSHAKE_TYPE_NTOR_V3:
92  /* ntor v3 has variable length fields that are checked
93  * elsewhere. Fall through to always valid here. */
94  break;
95  default:
96  if (! unknown_ok)
97  return -1;
98  }
99 
100  return 0;
101 }
102 
103 /** Write the various parameters into the create cell. Separate from
104  * create_cell_parse() to make unit testing easier.
105  */
106 void
107 create_cell_init(create_cell_t *cell_out, uint8_t cell_type,
108  uint16_t handshake_type, uint16_t handshake_len,
109  const uint8_t *onionskin)
110 {
111  memset(cell_out, 0, sizeof(*cell_out));
112 
113  cell_out->cell_type = cell_type;
114  cell_out->handshake_type = handshake_type;
115  cell_out->handshake_len = handshake_len;
116  memcpy(cell_out->onionskin, onionskin, handshake_len);
117 }
118 
119 /** Helper: parse the CREATE2 payload at <b>p</b>, which could be up to
120  * <b>p_len</b> bytes long, and use it to fill the fields of
121  * <b>cell_out</b>. Return 0 on success and -1 on failure.
122  *
123  * Note that part of the body of an EXTEND2 cell is a CREATE2 payload, so
124  * this function is also used for parsing those.
125  */
126 static int
127 parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
128 {
129  uint16_t handshake_type, handshake_len;
130 
131  if (p_len < 4)
132  return -1;
133 
134  handshake_type = ntohs(get_uint16(p));
135  handshake_len = ntohs(get_uint16(p+2));
136 
137  if (handshake_len > CELL_PAYLOAD_SIZE - 4 || handshake_len > p_len - 4)
138  return -1;
139  if (handshake_type == ONION_HANDSHAKE_TYPE_FAST)
140  return -1;
141 
142  create_cell_init(cell_out, CELL_CREATE2, handshake_type, handshake_len,
143  p+4);
144  return 0;
145 }
146 
147 /** Magic string which, in a CREATE or EXTEND cell, indicates that a seeming
148  * TAP payload is really an ntor payload. We'd do away with this if every
149  * relay supported EXTEND2, but we want to be able to extend from A to B with
150  * ntor even when A doesn't understand EXTEND2 and so can't generate a
151  * CREATE2 cell.
152  **/
153 #define NTOR_CREATE_MAGIC "ntorNTORntorNTOR"
154 
155 /** Parse a CREATE, CREATE_FAST, or CREATE2 cell from <b>cell_in</b> into
156  * <b>cell_out</b>. Return 0 on success, -1 on failure. (We reject some
157  * syntactically valid CREATE2 cells that we can't generate or react to.) */
158 int
159 create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
160 {
161  switch (cell_in->command) {
162  case CELL_CREATE:
163  if (tor_memeq(cell_in->payload, NTOR_CREATE_MAGIC, 16)) {
164  create_cell_init(cell_out, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR,
165  NTOR_ONIONSKIN_LEN, cell_in->payload+16);
166  } else {
167  create_cell_init(cell_out, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP,
168  TAP_ONIONSKIN_CHALLENGE_LEN, cell_in->payload);
169  }
170  break;
171  case CELL_CREATE_FAST:
172  create_cell_init(cell_out, CELL_CREATE_FAST, ONION_HANDSHAKE_TYPE_FAST,
173  CREATE_FAST_LEN, cell_in->payload);
174  break;
175  case CELL_CREATE2:
176  if (parse_create2_payload(cell_out, cell_in->payload,
177  CELL_PAYLOAD_SIZE) < 0)
178  return -1;
179  break;
180  default:
181  return -1;
182  }
183 
184  return check_create_cell(cell_out, 0);
185 }
186 
187 /** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
188 static int
190 {
191  switch (cell->cell_type) {
192  case CELL_CREATED:
193  if (cell->handshake_len != TAP_ONIONSKIN_REPLY_LEN &&
194  cell->handshake_len != NTOR_REPLY_LEN)
195  return -1;
196  break;
197  case CELL_CREATED_FAST:
198  if (cell->handshake_len != CREATED_FAST_LEN)
199  return -1;
200  break;
201  case CELL_CREATED2:
202  if (cell->handshake_len > RELAY_PAYLOAD_SIZE-2)
203  return -1;
204  break;
205  }
206 
207  return 0;
208 }
209 
210 /** Parse a CREATED, CREATED_FAST, or CREATED2 cell from <b>cell_in</b> into
211  * <b>cell_out</b>. Return 0 on success, -1 on failure. */
212 int
213 created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
214 {
215  memset(cell_out, 0, sizeof(*cell_out));
216 
217  switch (cell_in->command) {
218  case CELL_CREATED:
219  cell_out->cell_type = CELL_CREATED;
220  cell_out->handshake_len = TAP_ONIONSKIN_REPLY_LEN;
221  memcpy(cell_out->reply, cell_in->payload, TAP_ONIONSKIN_REPLY_LEN);
222  break;
223  case CELL_CREATED_FAST:
224  cell_out->cell_type = CELL_CREATED_FAST;
225  cell_out->handshake_len = CREATED_FAST_LEN;
226  memcpy(cell_out->reply, cell_in->payload, CREATED_FAST_LEN);
227  break;
228  case CELL_CREATED2:
229  {
230  const uint8_t *p = cell_in->payload;
231  cell_out->cell_type = CELL_CREATED2;
232  cell_out->handshake_len = ntohs(get_uint16(p));
233  if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 2)
234  return -1;
235  memcpy(cell_out->reply, p+2, cell_out->handshake_len);
236  break;
237  }
238  }
239 
240  return check_created_cell(cell_out);
241 }
242 
243 /** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
244 static int
246 {
247  const bool is_extend2 = (cell->cell_type == RELAY_COMMAND_EXTEND2);
248 
249  if (tor_digest_is_zero((const char*)cell->node_id))
250  return -1;
251  if (!tor_addr_port_is_valid_ap(&cell->orport_ipv4, 0)) {
252  /* EXTEND cells must have an IPv4 address. */
253  if (!is_extend2) {
254  return -1;
255  }
256  /* EXTEND2 cells must have at least one IP address.
257  * It can be IPv4 or IPv6. */
258  if (!tor_addr_port_is_valid_ap(&cell->orport_ipv6, 0)) {
259  return -1;
260  }
261  }
262  if (cell->create_cell.cell_type == CELL_CREATE) {
263  if (cell->cell_type != RELAY_COMMAND_EXTEND)
264  return -1;
265  } else if (cell->create_cell.cell_type == CELL_CREATE2) {
266  if (cell->cell_type != RELAY_COMMAND_EXTEND2 &&
267  cell->cell_type != RELAY_COMMAND_EXTEND)
268  return -1;
269  } else {
270  /* In particular, no CREATE_FAST cells are allowed */
271  return -1;
272  }
273  if (cell->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_FAST)
274  return -1;
275 
276  return check_create_cell(&cell->create_cell, 1);
277 }
278 
279 static int
280 extend_cell_from_extend1_cell_body(extend_cell_t *cell_out,
281  const extend1_cell_body_t *cell)
282 {
283  tor_assert(cell_out);
284  tor_assert(cell);
285  memset(cell_out, 0, sizeof(*cell_out));
286  tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
287  tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
288 
289  cell_out->cell_type = RELAY_COMMAND_EXTEND;
290  tor_addr_from_ipv4h(&cell_out->orport_ipv4.addr, cell->ipv4addr);
291  cell_out->orport_ipv4.port = cell->port;
292  if (tor_memeq(cell->onionskin, NTOR_CREATE_MAGIC, 16)) {
293  cell_out->create_cell.cell_type = CELL_CREATE2;
294  cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_NTOR;
296  memcpy(cell_out->create_cell.onionskin, cell->onionskin + 16,
298  } else {
299  cell_out->create_cell.cell_type = CELL_CREATE;
300  cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
301  cell_out->create_cell.handshake_len = TAP_ONIONSKIN_CHALLENGE_LEN;
302  memcpy(cell_out->create_cell.onionskin, cell->onionskin,
303  TAP_ONIONSKIN_CHALLENGE_LEN);
304  }
305  memcpy(cell_out->node_id, cell->identity, DIGEST_LEN);
306  return 0;
307 }
308 
309 static int
310 create_cell_from_create2_cell_body(create_cell_t *cell_out,
311  const create2_cell_body_t *cell)
312 {
313  tor_assert(cell_out);
314  tor_assert(cell);
315  memset(cell_out, 0, sizeof(create_cell_t));
316  if (BUG(cell->handshake_len > sizeof(cell_out->onionskin))) {
317  /* This should be impossible because there just isn't enough room in the
318  * input cell to make the handshake_len this large and provide a
319  * handshake_data to match. */
320  return -1;
321  }
322 
323  cell_out->cell_type = CELL_CREATE2;
324  cell_out->handshake_type = cell->handshake_type;
325  cell_out->handshake_len = cell->handshake_len;
326  memcpy(cell_out->onionskin,
327  create2_cell_body_getconstarray_handshake_data(cell),
328  cell->handshake_len);
329  return 0;
330 }
331 
332 static int
333 extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
334  const extend2_cell_body_t *cell)
335 {
336  tor_assert(cell_out);
337  tor_assert(cell);
338  int found_ipv4 = 0, found_ipv6 = 0, found_rsa_id = 0, found_ed_id = 0;
339  memset(cell_out, 0, sizeof(*cell_out));
340  tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
341  tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
342  cell_out->cell_type = RELAY_COMMAND_EXTEND2;
343 
344  unsigned i;
345  for (i = 0; i < cell->n_spec; ++i) {
346  const link_specifier_t *ls = extend2_cell_body_getconst_ls(cell, i);
347  switch (ls->ls_type) {
348  case LS_IPV4:
349  if (found_ipv4)
350  continue;
351  found_ipv4 = 1;
352  tor_addr_from_ipv4h(&cell_out->orport_ipv4.addr, ls->un_ipv4_addr);
353  cell_out->orport_ipv4.port = ls->un_ipv4_port;
354  break;
355  case LS_IPV6:
356  if (found_ipv6)
357  continue;
358  found_ipv6 = 1;
359  tor_addr_from_ipv6_bytes(&cell_out->orport_ipv6.addr,
360  ls->un_ipv6_addr);
361  cell_out->orport_ipv6.port = ls->un_ipv6_port;
362  break;
363  case LS_LEGACY_ID:
364  if (found_rsa_id)
365  return -1;
366  found_rsa_id = 1;
367  memcpy(cell_out->node_id, ls->un_legacy_id, 20);
368  break;
369  case LS_ED25519_ID:
370  if (found_ed_id)
371  return -1;
372  found_ed_id = 1;
373  memcpy(cell_out->ed_pubkey.pubkey, ls->un_ed25519_id, 32);
374  break;
375  default:
376  /* Ignore this, whatever it is. */
377  break;
378  }
379  }
380 
381  /* EXTEND2 cells must have an RSA ID */
382  if (!found_rsa_id)
383  return -1;
384 
385  /* EXTEND2 cells must have at least one IP address */
386  if (!found_ipv4 && !found_ipv6)
387  return -1;
388 
389  return create_cell_from_create2_cell_body(&cell_out->create_cell,
390  cell->create2);
391 }
392 
393 /** Parse an EXTEND or EXTEND2 cell (according to <b>command</b>) from the
394  * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
395  * 0 on success, -1 on failure. */
396 MOCK_IMPL(int,
398  const uint8_t command,
399  const uint8_t *payload,
400  size_t payload_length))
401 {
402 
403  tor_assert(cell_out);
404  tor_assert(payload);
405 
406  if (payload_length > RELAY_PAYLOAD_SIZE)
407  return -1;
408 
409  switch (command) {
410  case RELAY_COMMAND_EXTEND:
411  {
412  extend1_cell_body_t *cell = NULL;
413  if (extend1_cell_body_parse(&cell, payload, payload_length)<0 ||
414  cell == NULL) {
415  if (cell)
416  extend1_cell_body_free(cell);
417  return -1;
418  }
419  int r = extend_cell_from_extend1_cell_body(cell_out, cell);
420  extend1_cell_body_free(cell);
421  if (r < 0)
422  return r;
423  }
424  break;
425  case RELAY_COMMAND_EXTEND2:
426  {
427  extend2_cell_body_t *cell = NULL;
428  if (extend2_cell_body_parse(&cell, payload, payload_length) < 0 ||
429  cell == NULL) {
430  if (cell)
431  extend2_cell_body_free(cell);
432  return -1;
433  }
434  int r = extend_cell_from_extend2_cell_body(cell_out, cell);
435  extend2_cell_body_free(cell);
436  if (r < 0)
437  return r;
438  }
439  break;
440  default:
441  return -1;
442  }
443 
444  return check_extend_cell(cell_out);
445 }
446 
447 /** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
448 static int
450 {
451  tor_assert(cell);
452  if (cell->created_cell.cell_type == CELL_CREATED) {
453  if (cell->cell_type != RELAY_COMMAND_EXTENDED)
454  return -1;
455  } else if (cell->created_cell.cell_type == CELL_CREATED2) {
456  if (cell->cell_type != RELAY_COMMAND_EXTENDED2)
457  return -1;
458  } else {
459  return -1;
460  }
461 
462  return check_created_cell(&cell->created_cell);
463 }
464 
465 /** Parse an EXTENDED or EXTENDED2 cell (according to <b>command</b>) from the
466  * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
467  * 0 on success, -1 on failure. */
468 int
470  const uint8_t command, const uint8_t *payload,
471  size_t payload_len)
472 {
473  tor_assert(cell_out);
474  tor_assert(payload);
475 
476  memset(cell_out, 0, sizeof(*cell_out));
477  if (payload_len > RELAY_PAYLOAD_SIZE)
478  return -1;
479 
480  switch (command) {
481  case RELAY_COMMAND_EXTENDED:
482  if (payload_len != TAP_ONIONSKIN_REPLY_LEN)
483  return -1;
484  cell_out->cell_type = RELAY_COMMAND_EXTENDED;
485  cell_out->created_cell.cell_type = CELL_CREATED;
486  cell_out->created_cell.handshake_len = TAP_ONIONSKIN_REPLY_LEN;
487  memcpy(cell_out->created_cell.reply, payload, TAP_ONIONSKIN_REPLY_LEN);
488  break;
489  case RELAY_COMMAND_EXTENDED2:
490  {
491  cell_out->cell_type = RELAY_COMMAND_EXTENDED2;
492  cell_out->created_cell.cell_type = CELL_CREATED2;
493  cell_out->created_cell.handshake_len = ntohs(get_uint16(payload));
494  if (cell_out->created_cell.handshake_len > RELAY_PAYLOAD_SIZE - 2 ||
495  cell_out->created_cell.handshake_len > payload_len - 2)
496  return -1;
497  memcpy(cell_out->created_cell.reply, payload+2,
498  cell_out->created_cell.handshake_len);
499  }
500  break;
501  default:
502  return -1;
503  }
504 
505  return check_extended_cell(cell_out);
506 }
507 
508 /** Fill <b>cell_out</b> with a correctly formatted version of the
509  * CREATE{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
510  * failure. This is a cell we didn't originate if <b>relayed</b> is true. */
511 static int
512 create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in,
513  int relayed)
514 {
515  uint8_t *p;
516  size_t space;
517  if (check_create_cell(cell_in, relayed) < 0)
518  return -1;
519 
520  memset(cell_out->payload, 0, sizeof(cell_out->payload));
521  cell_out->command = cell_in->cell_type;
522 
523  p = cell_out->payload;
524  space = sizeof(cell_out->payload);
525 
526  switch (cell_in->cell_type) {
527  case CELL_CREATE:
528  if (BUG(cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR_V3)) {
529  log_warn(LD_BUG, "Create cells cannot contain ntorv3.");
530  return -1;
531  }
532 
533  if (cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
534  memcpy(p, NTOR_CREATE_MAGIC, 16);
535  p += 16;
536  space -= 16;
537  }
538  FALLTHROUGH;
539  case CELL_CREATE_FAST:
540  tor_assert(cell_in->handshake_len <= space);
541  memcpy(p, cell_in->onionskin, cell_in->handshake_len);
542  break;
543  case CELL_CREATE2:
544  tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-4);
545  set_uint16(cell_out->payload, htons(cell_in->handshake_type));
546  set_uint16(cell_out->payload+2, htons(cell_in->handshake_len));
547  memcpy(cell_out->payload + 4, cell_in->onionskin, cell_in->handshake_len);
548  break;
549  default:
550  return -1;
551  }
552 
553  return 0;
554 }
555 
556 int
557 create_cell_format(cell_t *cell_out, const create_cell_t *cell_in)
558 {
559  return create_cell_format_impl(cell_out, cell_in, 0);
560 }
561 
562 int
563 create_cell_format_relayed(cell_t *cell_out, const create_cell_t *cell_in)
564 {
565  return create_cell_format_impl(cell_out, cell_in, 1);
566 }
567 
568 /** Fill <b>cell_out</b> with a correctly formatted version of the
569  * CREATED{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
570  * failure. */
571 int
572 created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
573 {
574  if (check_created_cell(cell_in) < 0)
575  return -1;
576 
577  memset(cell_out->payload, 0, sizeof(cell_out->payload));
578  cell_out->command = cell_in->cell_type;
579 
580  switch (cell_in->cell_type) {
581  case CELL_CREATED:
582  case CELL_CREATED_FAST:
583  tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload));
584  memcpy(cell_out->payload, cell_in->reply, cell_in->handshake_len);
585  break;
586  case CELL_CREATED2:
587  tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-2);
588  set_uint16(cell_out->payload, htons(cell_in->handshake_len));
589  memcpy(cell_out->payload + 2, cell_in->reply, cell_in->handshake_len);
590  break;
591  default:
592  return -1;
593  }
594  return 0;
595 }
596 
597 /** Return true iff we are configured (by torrc or by the networkstatus
598  * parameters) to use Ed25519 identities in our Extend2 cells. */
599 static int
601  const or_options_t *options)
602 {
603  if (options->ExtendByEd25519ID != -1)
604  return options->ExtendByEd25519ID; /* The user has an opinion. */
605 
606  return (int) networkstatus_get_param(ns, "ExtendByEd25519ID",
607  0 /* default */,
608  0 /* min */,
609  1 /*max*/);
610 }
611 
612 /** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
613  * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
614  * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
615  * RELAY_PAYLOAD_SIZE bytes available. Return 0 on success, -1 on failure. */
616 int
617 extend_cell_format(uint8_t *command_out, uint16_t *len_out,
618  uint8_t *payload_out, const extend_cell_t *cell_in)
619 {
620  uint8_t *p;
621  if (check_extend_cell(cell_in) < 0)
622  return -1;
623 
624  p = payload_out;
625 
626  memset(p, 0, RELAY_PAYLOAD_SIZE);
627 
628  switch (cell_in->cell_type) {
629  case RELAY_COMMAND_EXTEND:
630  {
631  if (BUG(cell_in->create_cell.handshake_type ==
632  ONION_HANDSHAKE_TYPE_NTOR_V3)) {
633  log_warn(LD_BUG, "Extend cells cannot contain ntorv3!");
634  return -1;
635  }
636  *command_out = RELAY_COMMAND_EXTEND;
637  *len_out = 6 + TAP_ONIONSKIN_CHALLENGE_LEN + DIGEST_LEN;
638  set_uint32(p, tor_addr_to_ipv4n(&cell_in->orport_ipv4.addr));
639  set_uint16(p+4, htons(cell_in->orport_ipv4.port));
640  if (cell_in->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
641  memcpy(p+6, NTOR_CREATE_MAGIC, 16);
642  memcpy(p+22, cell_in->create_cell.onionskin, NTOR_ONIONSKIN_LEN);
643  } else {
644  memcpy(p+6, cell_in->create_cell.onionskin,
645  TAP_ONIONSKIN_CHALLENGE_LEN);
646  }
647  memcpy(p+6+TAP_ONIONSKIN_CHALLENGE_LEN, cell_in->node_id, DIGEST_LEN);
648  }
649  break;
650  case RELAY_COMMAND_EXTEND2:
651  {
652  uint8_t n_specifiers = 1;
653  *command_out = RELAY_COMMAND_EXTEND2;
654  extend2_cell_body_t *cell = extend2_cell_body_new();
655  link_specifier_t *ls;
656  if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv4, 0)) {
657  /* Maybe IPv4 specifier first. */
658  ++n_specifiers;
659  ls = link_specifier_new();
660  extend2_cell_body_add_ls(cell, ls);
661  ls->ls_type = LS_IPV4;
662  ls->ls_len = 6;
663  ls->un_ipv4_addr = tor_addr_to_ipv4h(&cell_in->orport_ipv4.addr);
664  ls->un_ipv4_port = cell_in->orport_ipv4.port;
665  }
666  {
667  /* Then RSA id */
668  ls = link_specifier_new();
669  extend2_cell_body_add_ls(cell, ls);
670  ls->ls_type = LS_LEGACY_ID;
671  ls->ls_len = DIGEST_LEN;
672  memcpy(ls->un_legacy_id, cell_in->node_id, DIGEST_LEN);
673  }
676  /* Then, maybe, the ed25519 id! */
677  ++n_specifiers;
678  ls = link_specifier_new();
679  extend2_cell_body_add_ls(cell, ls);
680  ls->ls_type = LS_ED25519_ID;
681  ls->ls_len = 32;
682  memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
683  }
684  if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv6, 0)) {
685  /* Then maybe IPv6 specifier. */
686  ++n_specifiers;
687  ls = link_specifier_new();
688  extend2_cell_body_add_ls(cell, ls);
689  ls->ls_type = LS_IPV6;
690  ls->ls_len = 18;
691  tor_addr_copy_ipv6_bytes(ls->un_ipv6_addr,
692  &cell_in->orport_ipv6.addr);
693  ls->un_ipv6_port = cell_in->orport_ipv6.port;
694  }
695  cell->n_spec = n_specifiers;
696 
697  /* Now, the handshake */
698  cell->create2 = create2_cell_body_new();
699  cell->create2->handshake_type = cell_in->create_cell.handshake_type;
700  cell->create2->handshake_len = cell_in->create_cell.handshake_len;
701  create2_cell_body_setlen_handshake_data(cell->create2,
702  cell_in->create_cell.handshake_len);
703  memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
704  cell_in->create_cell.onionskin,
705  cell_in->create_cell.handshake_len);
706 
707  ssize_t len_encoded = extend2_cell_body_encode(
708  payload_out, RELAY_PAYLOAD_SIZE,
709  cell);
710  extend2_cell_body_free(cell);
711  if (len_encoded < 0 || len_encoded > UINT16_MAX)
712  return -1;
713  *len_out = (uint16_t) len_encoded;
714  }
715  break;
716  default:
717  return -1;
718  }
719 
720  return 0;
721 }
722 
723 /** Format the EXTENDED{,2} cell in <b>cell_in</b>, storing its relay payload
724  * in <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
725  * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
726  * RELAY_PAYLOAD_SIZE bytes available. Return 0 on success, -1 on failure. */
727 int
728 extended_cell_format(uint8_t *command_out, uint16_t *len_out,
729  uint8_t *payload_out, const extended_cell_t *cell_in)
730 {
731  uint8_t *p;
732  if (check_extended_cell(cell_in) < 0)
733  return -1;
734 
735  p = payload_out;
736  memset(p, 0, RELAY_PAYLOAD_SIZE);
737 
738  switch (cell_in->cell_type) {
739  case RELAY_COMMAND_EXTENDED:
740  {
741  *command_out = RELAY_COMMAND_EXTENDED;
742  *len_out = TAP_ONIONSKIN_REPLY_LEN;
743  memcpy(payload_out, cell_in->created_cell.reply,
744  TAP_ONIONSKIN_REPLY_LEN);
745  }
746  break;
747  case RELAY_COMMAND_EXTENDED2:
748  {
749  *command_out = RELAY_COMMAND_EXTENDED2;
750  *len_out = 2 + cell_in->created_cell.handshake_len;
751  set_uint16(payload_out, htons(cell_in->created_cell.handshake_len));
753  return -1;
754  memcpy(payload_out+2, cell_in->created_cell.reply,
755  cell_in->created_cell.handshake_len);
756  }
757  break;
758  default:
759  return -1;
760  }
761 
762  return 0;
763 }
void tor_addr_make_unspec(tor_addr_t *a)
Definition: address.c:225
void tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src)
Definition: address.c:920
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *ipv6_bytes)
Definition: address.c:900
static uint32_t tor_addr_to_ipv4n(const tor_addr_t *a)
Definition: address.h:152
static uint32_t tor_addr_to_ipv4h(const tor_addr_t *a)
Definition: address.h:160
#define tor_addr_from_ipv4h(dest, v4addr)
Definition: address.h:327
static void set_uint16(void *cp, uint16_t v)
Definition: bytes.h:78
static uint16_t get_uint16(const void *cp)
Definition: bytes.h:42
static void set_uint32(void *cp, uint32_t v)
Definition: bytes.h:87
Fixed-size cell structure.
const or_options_t * get_options(void)
Definition: config.c:926
tor_cmdline_mode_t command
Definition: config.c:2449
Header file for config.c.
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define LD_BUG
Definition: log.h:86
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
static int check_created_cell(const created_cell_t *cell)
Definition: onion.c:189
static int should_include_ed25519_id_extend_cells(const networkstatus_t *ns, const or_options_t *options)
Definition: onion.c:600
static int parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
Definition: onion.c:127
#define NTOR_CREATE_MAGIC
Definition: onion.c:153
static int check_create_cell(const create_cell_t *cell, int unknown_ok)
Definition: onion.c:60
static int create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in, int relayed)
Definition: onion.c:512
int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
Definition: onion.c:213
void create_cell_init(create_cell_t *cell_out, uint8_t cell_type, uint16_t handshake_type, uint16_t handshake_len, const uint8_t *onionskin)
Definition: onion.c:107
static int check_extend_cell(const extend_cell_t *cell)
Definition: onion.c:245
int create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
Definition: onion.c:159
int extend_cell_parse(extend_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_length)
Definition: onion.c:400
int created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
Definition: onion.c:572
int extended_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extended_cell_t *cell_in)
Definition: onion.c:728
int extended_cell_parse(extended_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_len)
Definition: onion.c:469
int extend_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extend_cell_t *cell_in)
Definition: onion.c:617
static int check_extended_cell(const extended_cell_t *cell)
Definition: onion.c:449
Header file for onion.c.
Header file for onion_crypto.c.
Header file for onion_fast.c.
Header for onion_ntor.c.
#define NTOR_REPLY_LEN
Definition: onion_ntor.h:25
#define NTOR_ONIONSKIN_LEN
Definition: onion_ntor.h:23
Header file for onion_tap.c.
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
Definition: or.h:456
#define RELAY_PAYLOAD_SIZE
Definition: or.h:485
Definition: cell_st.h:17
uint8_t payload[CELL_PAYLOAD_SIZE]
Definition: cell_st.h:21
uint8_t command
Definition: cell_st.h:19
uint16_t handshake_len
Definition: onion.h:30
uint16_t handshake_type
Definition: onion.h:28
uint8_t onionskin[CELL_PAYLOAD_SIZE - 4]
Definition: onion.h:32
uint8_t cell_type
Definition: onion.h:26
uint16_t handshake_len
Definition: onion.h:40
uint8_t reply[CELL_PAYLOAD_SIZE - 2]
Definition: onion.h:42
uint8_t cell_type
Definition: onion.h:38
tor_addr_port_t orport_ipv4
Definition: onion.h:50
create_cell_t create_cell
Definition: onion.h:60
struct ed25519_public_key_t ed_pubkey
Definition: onion.h:56
uint8_t node_id[DIGEST_LEN]
Definition: onion.h:54
tor_addr_port_t orport_ipv6
Definition: onion.h:52
uint8_t cell_type
Definition: onion.h:48
created_cell_t created_cell
Definition: onion.h:68
uint8_t cell_type
Definition: onion.h:66
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
#define tor_assert(expr)
Definition: util_bug.h:102
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:96