tor
master
|
Functions to queue create cells, wrap the various onionskin types, and parse and create the CREATE cell and its allies. More...
#include "or.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "config.h"
#include "cpuworker.h"
#include "crypto_util.h"
#include "networkstatus.h"
#include "onion.h"
#include "onion_fast.h"
#include "onion_ntor.h"
#include "onion_tap.h"
#include "relay.h"
#include "rephist.h"
#include "router.h"
#include "ed25519_cert.h"
Data Structures | |
struct | onion_queue_t |
Macros | |
#define | ONIONQUEUE_WAIT_CUTOFF 5 |
#define | WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60) |
#define | DEFAULT_NUM_NTORS_PER_TAP 10 |
#define | MIN_NUM_NTORS_PER_TAP 1 |
#define | MAX_NUM_NTORS_PER_TAP 100000 |
#define | MAX_KEYS_TMP_LEN 128 |
#define | NTOR_CREATE_MAGIC "ntorNTORntorNTOR" |
Typedefs | |
typedef struct onion_queue_t | onion_queue_t |
Functions | |
int | onion_pending_add (or_circuit_t *circ, create_cell_t *onionskin) |
or_circuit_t * | onion_next_task (create_cell_t **onionskin_out) |
int | onion_num_pending (uint16_t handshake_type) |
void | onion_pending_remove (or_circuit_t *circ) |
void | clear_pending_onions (void) |
server_onion_keys_t * | server_onion_keys_new (void) |
void | server_onion_keys_free_ (server_onion_keys_t *keys) |
void | onion_handshake_state_release (onion_handshake_state_t *state) |
int | onion_skin_create (int type, const extend_info_t *node, onion_handshake_state_t *state_out, uint8_t *onion_skin_out) |
int | onion_skin_server_handshake (int type, const uint8_t *onion_skin, size_t onionskin_len, const server_onion_keys_t *keys, uint8_t *reply_out, uint8_t *keys_out, size_t keys_out_len, uint8_t *rend_nonce_out) |
int | onion_skin_client_handshake (int type, const onion_handshake_state_t *handshake_state, const uint8_t *reply, size_t reply_len, uint8_t *keys_out, size_t keys_out_len, uint8_t *rend_authenticator_out, const char **msg_out) |
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) |
int | create_cell_parse (create_cell_t *cell_out, const cell_t *cell_in) |
int | created_cell_parse (created_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 | extended_cell_parse (extended_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_len) |
int | create_cell_format (cell_t *cell_out, const create_cell_t *cell_in) |
int | create_cell_format_relayed (cell_t *cell_out, const create_cell_t *cell_in) |
int | created_cell_format (cell_t *cell_out, const created_cell_t *cell_in) |
int | extend_cell_format (uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extend_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) |
Functions to queue create cells, wrap the various onionskin types, and parse and create the CREATE cell and its allies.
This module has a few functions, all related to the CREATE/CREATED handshake that we use on links in order to create a circuit, and the related EXTEND/EXTENDED handshake that we use over circuits in order to extend them an additional hop.
In this module, we provide a set of abstractions to create a uniform interface over the three circuit extension handshakes that Tor has used over the years (TAP, CREATE_FAST, and ntor). These handshakes are implemented in onion_tap.c, onion_fast.c, and onion_ntor.c respectively.
All[*] of these handshakes follow a similar pattern: a client, knowing some key from the relay it wants to extend through, generates the first part of a handshake. A relay receives that handshake, and sends a reply. Once the client handles the reply, it knows that it is talking to the right relay, and it shares some freshly negotiated key material with that relay.
We sometimes call the client's part of the handshake an "onionskin". We do this because historically, Onion Routing used a multi-layer structure called an "onion" to construct circuits. Each layer of the onion contained key material chosen by the client, the identity of the next relay in the circuit, and a smaller onion, encrypted with the key of the next relay. When we changed Tor to use a telescoping circuit extension design, it corresponded to sending each layer of the onion separately – as a series of onionskins.
Clients invoke these functions when creating or extending a circuit, from circuitbuild.c.
Relays invoke these functions when they receive a CREATE or EXTEND cell in command.c or relay.c, in order to queue the pending request. They also invoke them from cpuworker.c, which handles dispatching onionskin requests to different worker threads.
This module also handles:
[*] The CREATE_FAST handshake is weaker than described here; see onion_fast.c for more information.
#define NTOR_CREATE_MAGIC "ntorNTORntorNTOR" |
Magic string which, in a CREATE or EXTEND cell, indicates that a seeming TAP payload is really an ntor payload. We'd do away with this if every relay supported EXTEND2, but we want to be able to extend from A to B with ntor even when A doesn't understand EXTEND2 and so can't generate a CREATE2 cell.
#define ONIONQUEUE_WAIT_CUTOFF 5 |
5 seconds on the onion queue til we just send back a destroy
typedef struct onion_queue_t onion_queue_t |
Type for a linked list of circuits that are waiting for a free CPU worker to process a waiting onion handshake.
void clear_pending_onions | ( | void | ) |
Remove all circuits from the pending list. Called from tor_free_all.
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 | ||
) |
Write the various parameters into the create cell. Separate from create_cell_parse() to make unit testing easier.
int create_cell_parse | ( | create_cell_t * | cell_out, |
const cell_t * | cell_in | ||
) |
Parse a CREATE, CREATE_FAST, or CREATE2 cell from cell_in into cell_out. Return 0 on success, -1 on failure. (We reject some syntactically valid CREATE2 cells that we can't generate or react to.)
int created_cell_format | ( | cell_t * | cell_out, |
const created_cell_t * | cell_in | ||
) |
Fill cell_out with a correctly formatted version of the CREATED{,_FAST,2} cell in cell_in. Return 0 on success, -1 on failure.
int created_cell_parse | ( | created_cell_t * | cell_out, |
const cell_t * | cell_in | ||
) |
Parse a CREATED, CREATED_FAST, or CREATED2 cell from cell_in into cell_out. Return 0 on success, -1 on failure.
int extend_cell_format | ( | uint8_t * | command_out, |
uint16_t * | len_out, | ||
uint8_t * | payload_out, | ||
const extend_cell_t * | cell_in | ||
) |
Format the EXTEND{,2} cell in cell_in, storing its relay payload in payload_out, the number of bytes used in *len_out, and the relay command in *command_out. The payload_out must have RELAY_PAYLOAD_SIZE bytes available. Return 0 on success, -1 on failure.
int extend_cell_parse | ( | extend_cell_t * | cell_out, |
const uint8_t | command, | ||
const uint8_t * | payload, | ||
size_t | payload_length | ||
) |
Parse an EXTEND or EXTEND2 cell (according to command) from the payload_length bytes of payload into cell_out. Return 0 on success, -1 on failure.
int extended_cell_format | ( | uint8_t * | command_out, |
uint16_t * | len_out, | ||
uint8_t * | payload_out, | ||
const extended_cell_t * | cell_in | ||
) |
Format the EXTENDED{,2} cell in cell_in, storing its relay payload in payload_out, the number of bytes used in *len_out, and the relay command in *command_out. The payload_out must have RELAY_PAYLOAD_SIZE bytes available. Return 0 on success, -1 on failure.
int extended_cell_parse | ( | extended_cell_t * | cell_out, |
const uint8_t | command, | ||
const uint8_t * | payload, | ||
size_t | payload_len | ||
) |
Parse an EXTENDED or EXTENDED2 cell (according to command) from the payload_length bytes of payload into cell_out. Return 0 on success, -1 on failure.
void onion_handshake_state_release | ( | onion_handshake_state_t * | state | ) |
Release whatever storage is held in state, depending on its type, and clear its pointer.
or_circuit_t* onion_next_task | ( | create_cell_t ** | onionskin_out | ) |
Remove the highest priority item from ol_list[] and return it, or return NULL if the lists are empty.
int onion_num_pending | ( | uint16_t | handshake_type | ) |
Return the number of handshake_type-style create requests pending.
int onion_pending_add | ( | or_circuit_t * | circ, |
create_cell_t * | onionskin | ||
) |
Add circ to the end of ol_list and return 0, except if ol_list is too long, in which case do nothing and return -1.
void onion_pending_remove | ( | or_circuit_t * | circ | ) |
Go through ol_list, find the onion_queue_t element which points to circ, remove and free that element. Leave circ itself alone.
int onion_skin_client_handshake | ( | int | type, |
const onion_handshake_state_t * | handshake_state, | ||
const uint8_t * | reply, | ||
size_t | reply_len, | ||
uint8_t * | keys_out, | ||
size_t | keys_out_len, | ||
uint8_t * | rend_authenticator_out, | ||
const char ** | msg_out | ||
) |
Perform the final (client-side) step of a circuit-creation handshake of type type, using our state in handshake_state and the server's response in reply. On success, generate keys_out_len bytes worth of key material in keys_out_len, set rend_authenticator_out to the "KH" field that can be used to establish introduction points at this hop, and return 0. On failure, return -1, and set *msg_out to an error message if this is worth complaining to the user about.
int onion_skin_create | ( | int | type, |
const extend_info_t * | node, | ||
onion_handshake_state_t * | state_out, | ||
uint8_t * | onion_skin_out | ||
) |
Perform the first step of a circuit-creation handshake of type type (one of ONION_HANDSHAKE_TYPE_*): generate the initial "onion skin" in onion_skin_out, and store any state information in state_out. Return -1 on failure, and the length of the onionskin on acceptance.
int onion_skin_server_handshake | ( | int | type, |
const uint8_t * | onion_skin, | ||
size_t | onionskin_len, | ||
const server_onion_keys_t * | keys, | ||
uint8_t * | reply_out, | ||
uint8_t * | keys_out, | ||
size_t | keys_out_len, | ||
uint8_t * | rend_nonce_out | ||
) |
Perform the second (server-side) step of a circuit-creation handshake of type type, responding to the client request in onion_skin using the keys in keys. On success, write our response into reply_out, generate keys_out_len bytes worth of key material in keys_out_len, a hidden service nonce to rend_nonce_out, and return the length of the reply. On failure, return -1.
void server_onion_keys_free_ | ( | server_onion_keys_t * | keys | ) |
Release all storage held in keys.
server_onion_keys_t* server_onion_keys_new | ( | void | ) |
Return a new server_onion_keys_t object with all of the keys and other info we might need to do onion handshakes. (We make a copy of our keys for each cpuworker to avoid race conditions with the main thread, and to avoid locking)