54 #include "trunnel/ed25519_cert.h"
68 case CELL_CREATE_FAST:
79 case ONION_HANDSHAKE_TYPE_TAP:
83 case ONION_HANDSHAKE_TYPE_FAST:
87 case ONION_HANDSHAKE_TYPE_NTOR:
104 uint16_t handshake_type, uint16_t handshake_len,
105 const uint8_t *onionskin)
107 memset(cell_out, 0,
sizeof(*cell_out));
112 memcpy(cell_out->
onionskin, onionskin, handshake_len);
125 uint16_t handshake_type, handshake_len;
135 if (handshake_type == ONION_HANDSHAKE_TYPE_FAST)
149 #define NTOR_CREATE_MAGIC "ntorNTORntorNTOR"
164 TAP_ONIONSKIN_CHALLENGE_LEN, cell_in->
payload);
167 case CELL_CREATE_FAST:
169 CREATE_FAST_LEN, cell_in->
payload);
193 case CELL_CREATED_FAST:
211 memset(cell_out, 0,
sizeof(*cell_out));
217 memcpy(cell_out->
reply, cell_in->
payload, TAP_ONIONSKIN_REPLY_LEN);
219 case CELL_CREATED_FAST:
222 memcpy(cell_out->
reply, cell_in->
payload, CREATED_FAST_LEN);
226 const uint8_t *p = cell_in->
payload;
243 const bool is_extend2 = (cell->
cell_type == RELAY_COMMAND_EXTEND2);
247 if (!tor_addr_port_is_valid_ap(&cell->
orport_ipv4, 0)) {
254 if (!tor_addr_port_is_valid_ap(&cell->
orport_ipv6, 0)) {
259 if (cell->
cell_type != RELAY_COMMAND_EXTEND)
262 if (cell->
cell_type != RELAY_COMMAND_EXTEND2 &&
277 const extend1_cell_body_t *cell)
281 memset(cell_out, 0,
sizeof(*cell_out));
285 cell_out->
cell_type = RELAY_COMMAND_EXTEND;
299 TAP_ONIONSKIN_CHALLENGE_LEN);
307 const create2_cell_body_t *cell)
312 if (BUG(cell->handshake_len >
sizeof(cell_out->
onionskin))) {
323 create2_cell_body_getconstarray_handshake_data(cell),
324 cell->handshake_len);
330 const extend2_cell_body_t *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));
338 cell_out->
cell_type = RELAY_COMMAND_EXTEND2;
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) {
363 memcpy(cell_out->
node_id, ls->un_legacy_id, 20);
369 memcpy(cell_out->
ed_pubkey.pubkey, ls->un_ed25519_id, 32);
382 if (!found_ipv4 && !found_ipv6)
385 return create_cell_from_create2_cell_body(&cell_out->
create_cell,
395 const uint8_t *payload,
396 size_t payload_length))
406 case RELAY_COMMAND_EXTEND:
408 extend1_cell_body_t *cell = NULL;
409 if (extend1_cell_body_parse(&cell, payload, payload_length)<0 ||
412 extend1_cell_body_free(cell);
415 int r = extend_cell_from_extend1_cell_body(cell_out, cell);
416 extend1_cell_body_free(cell);
421 case RELAY_COMMAND_EXTEND2:
423 extend2_cell_body_t *cell = NULL;
424 if (extend2_cell_body_parse(&cell, payload, payload_length) < 0 ||
427 extend2_cell_body_free(cell);
430 int r = extend_cell_from_extend2_cell_body(cell_out, cell);
431 extend2_cell_body_free(cell);
449 if (cell->
cell_type != RELAY_COMMAND_EXTENDED)
452 if (cell->
cell_type != RELAY_COMMAND_EXTENDED2)
466 const uint8_t
command,
const uint8_t *payload,
472 memset(cell_out, 0,
sizeof(*cell_out));
477 case RELAY_COMMAND_EXTENDED:
478 if (payload_len != TAP_ONIONSKIN_REPLY_LEN)
480 cell_out->
cell_type = RELAY_COMMAND_EXTENDED;
485 case RELAY_COMMAND_EXTENDED2:
487 cell_out->
cell_type = RELAY_COMMAND_EXTENDED2;
520 space =
sizeof(cell_out->
payload);
530 case CELL_CREATE_FAST:
573 case CELL_CREATED_FAST:
620 case RELAY_COMMAND_EXTEND:
622 *command_out = RELAY_COMMAND_EXTEND;
623 *len_out = 6 + TAP_ONIONSKIN_CHALLENGE_LEN +
DIGEST_LEN;
631 TAP_ONIONSKIN_CHALLENGE_LEN);
636 case RELAY_COMMAND_EXTEND2:
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)) {
645 ls = link_specifier_new();
646 extend2_cell_body_add_ls(cell, ls);
647 ls->ls_type = LS_IPV4;
654 ls = link_specifier_new();
655 extend2_cell_body_add_ls(cell, ls);
656 ls->ls_type = LS_LEGACY_ID;
664 ls = link_specifier_new();
665 extend2_cell_body_add_ls(cell, ls);
666 ls->ls_type = LS_ED25519_ID;
668 memcpy(ls->un_ed25519_id, cell_in->
ed_pubkey.pubkey, 32);
670 if (tor_addr_port_is_valid_ap(&cell_in->
orport_ipv6, 0)) {
673 ls = link_specifier_new();
674 extend2_cell_body_add_ls(cell, ls);
675 ls->ls_type = LS_IPV6;
681 cell->n_spec = n_specifiers;
684 cell->create2 = create2_cell_body_new();
687 create2_cell_body_setlen_handshake_data(cell->create2,
689 memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
693 ssize_t len_encoded = extend2_cell_body_encode(
696 extend2_cell_body_free(cell);
697 if (len_encoded < 0 || len_encoded > UINT16_MAX)
699 *len_out = (uint16_t) len_encoded;
725 case RELAY_COMMAND_EXTENDED:
727 *command_out = RELAY_COMMAND_EXTENDED;
728 *len_out = TAP_ONIONSKIN_REPLY_LEN;
730 TAP_ONIONSKIN_REPLY_LEN);
733 case RELAY_COMMAND_EXTENDED2:
735 *command_out = RELAY_COMMAND_EXTENDED2;
void tor_addr_make_unspec(tor_addr_t *a)
void tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src)
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *ipv6_bytes)
static uint32_t tor_addr_to_ipv4n(const tor_addr_t *a)
static uint32_t tor_addr_to_ipv4h(const tor_addr_t *a)
#define tor_addr_from_ipv4h(dest, v4addr)
static void set_uint16(void *cp, uint16_t v)
static uint16_t get_uint16(const void *cp)
static void set_uint32(void *cp, uint32_t v)
Fixed-size cell structure.
const or_options_t * get_options(void)
tor_cmdline_mode_t command
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)
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)
static int should_include_ed25519_id_extend_cells(const networkstatus_t *ns, const or_options_t *options)
static int parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
#define NTOR_CREATE_MAGIC
static int check_create_cell(const create_cell_t *cell, int unknown_ok)
static int create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in, int relayed)
int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
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)
static int check_extend_cell(const extend_cell_t *cell)
int create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
int extend_cell_parse(extend_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_length)
int created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
int extended_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extended_cell_t *cell_in)
int extended_cell_parse(extended_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_len)
int extend_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extend_cell_t *cell_in)
static int check_extended_cell(const extended_cell_t *cell)
Header file for onion_crypto.c.
Header file for onion_fast.c.
#define NTOR_ONIONSKIN_LEN
Header file for onion_tap.c.
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
#define RELAY_PAYLOAD_SIZE
uint8_t payload[CELL_PAYLOAD_SIZE]
uint8_t onionskin[CELL_PAYLOAD_SIZE - 4]
uint8_t reply[CELL_PAYLOAD_SIZE - 2]
tor_addr_port_t orport_ipv4
create_cell_t create_cell
struct ed25519_public_key_t ed_pubkey
uint8_t node_id[DIGEST_LEN]
tor_addr_port_t orport_ipv6
created_cell_t created_cell
#define MOCK_IMPL(rv, funcname, arglist)
int tor_digest_is_zero(const char *digest)