53#include "trunnel/ed25519_cert.h"
64 case CELL_CREATE_FAST:
75 case ONION_HANDSHAKE_TYPE_TAP:
77 case ONION_HANDSHAKE_TYPE_FAST:
81 case ONION_HANDSHAKE_TYPE_NTOR:
85 case ONION_HANDSHAKE_TYPE_NTOR_V3:
102 uint16_t handshake_type, uint16_t handshake_len,
103 const uint8_t *onionskin)
105 memset(cell_out, 0,
sizeof(*cell_out));
110 memcpy(cell_out->
onionskin, onionskin, handshake_len);
123 uint16_t handshake_type, handshake_len;
133 if (handshake_type == ONION_HANDSHAKE_TYPE_FAST)
147#define NTOR_CREATE_MAGIC "ntorNTORntorNTOR"
158 case CELL_CREATE_FAST:
160 CREATE_FAST_LEN, cell_in->
payload);
181 case CELL_CREATED_FAST:
199 memset(cell_out, 0,
sizeof(*cell_out));
204 case CELL_CREATED_FAST:
207 memcpy(cell_out->
reply, cell_in->
payload, CREATED_FAST_LEN);
211 const uint8_t *p = cell_in->
payload;
228 const bool is_extend2 = (cell->
cell_type == RELAY_COMMAND_EXTEND2);
232 if (!tor_addr_port_is_valid_ap(&cell->
orport_ipv4, 0)) {
239 if (!tor_addr_port_is_valid_ap(&cell->
orport_ipv6, 0)) {
246 if (cell->
cell_type != RELAY_COMMAND_EXTEND2)
261 const create2_cell_body_t *cell)
266 if (BUG(cell->handshake_len >
sizeof(cell_out->
onionskin))) {
277 create2_cell_body_getconstarray_handshake_data(cell),
278 cell->handshake_len);
284 const extend2_cell_body_t *cell)
288 int found_ipv4 = 0, found_ipv6 = 0, found_rsa_id = 0, found_ed_id = 0;
289 memset(cell_out, 0,
sizeof(*cell_out));
292 cell_out->
cell_type = RELAY_COMMAND_EXTEND2;
295 for (i = 0; i < cell->n_spec; ++i) {
296 const link_specifier_t *ls = extend2_cell_body_getconst_ls(cell, i);
297 switch (ls->ls_type) {
317 memcpy(cell_out->
node_id, ls->un_legacy_id, 20);
323 memcpy(cell_out->
ed_pubkey.pubkey, ls->un_ed25519_id, 32);
336 if (!found_ipv4 && !found_ipv6)
339 return create_cell_from_create2_cell_body(&cell_out->
create_cell,
349 const uint8_t *payload,
350 size_t payload_length))
360 case RELAY_COMMAND_EXTEND:
363 case RELAY_COMMAND_EXTEND2:
365 extend2_cell_body_t *cell = NULL;
366 if (extend2_cell_body_parse(&cell, payload, payload_length) < 0 ||
369 extend2_cell_body_free(cell);
372 int r = extend_cell_from_extend2_cell_body(cell_out, cell);
373 extend2_cell_body_free(cell);
391 if (cell->
cell_type != RELAY_COMMAND_EXTENDED)
394 if (cell->
cell_type != RELAY_COMMAND_EXTENDED2)
408 const uint8_t
command,
const uint8_t *payload,
414 memset(cell_out, 0,
sizeof(*cell_out));
419 case RELAY_COMMAND_EXTENDED:
421 case RELAY_COMMAND_EXTENDED2:
423 cell_out->
cell_type = RELAY_COMMAND_EXTENDED2;
456 space =
sizeof(cell_out->
payload);
460 if (BUG(cell_in->
handshake_type == ONION_HANDSHAKE_TYPE_NTOR_V3)) {
461 log_warn(
LD_BUG,
"Create cells cannot contain ntorv3.");
471 case CELL_CREATE_FAST:
514 case CELL_CREATED_FAST:
561 case RELAY_COMMAND_EXTEND:
563 case RELAY_COMMAND_EXTEND2:
565 uint8_t n_specifiers = 1;
566 *command_out = RELAY_COMMAND_EXTEND2;
567 extend2_cell_body_t *cell = extend2_cell_body_new();
568 link_specifier_t *ls;
569 if (tor_addr_port_is_valid_ap(&cell_in->
orport_ipv4, 0)) {
572 ls = link_specifier_new();
573 extend2_cell_body_add_ls(cell, ls);
574 ls->ls_type = LS_IPV4;
581 ls = link_specifier_new();
582 extend2_cell_body_add_ls(cell, ls);
583 ls->ls_type = LS_LEGACY_ID;
591 ls = link_specifier_new();
592 extend2_cell_body_add_ls(cell, ls);
593 ls->ls_type = LS_ED25519_ID;
595 memcpy(ls->un_ed25519_id, cell_in->
ed_pubkey.pubkey, 32);
597 if (tor_addr_port_is_valid_ap(&cell_in->
orport_ipv6, 0)) {
600 ls = link_specifier_new();
601 extend2_cell_body_add_ls(cell, ls);
602 ls->ls_type = LS_IPV6;
608 cell->n_spec = n_specifiers;
611 cell->create2 = create2_cell_body_new();
614 create2_cell_body_setlen_handshake_data(cell->create2,
616 memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
620 ssize_t len_encoded = extend2_cell_body_encode(
623 extend2_cell_body_free(cell);
624 if (len_encoded < 0 || len_encoded > UINT16_MAX)
626 *len_out = (uint16_t) len_encoded;
652 case RELAY_COMMAND_EXTENDED:
654 case RELAY_COMMAND_EXTENDED2:
656 *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_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)
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)
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
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)