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