52#include "trunnel/congestion_control.h"
53#include "trunnel/extension.h"
54#include "trunnel/subproto_request.h"
56#define EXT_TYPE_SUBPROTO 3
58static const uint8_t NTOR3_CIRC_VERIFICATION[] =
"circuit extend";
59static const size_t NTOR3_CIRC_VERIFICATION_LEN = 14;
61#define NTOR3_VERIFICATION_ARGS \
62 NTOR3_CIRC_VERIFICATION, NTOR3_CIRC_VERIFICATION_LEN
71 memset(params, 0,
sizeof(*params));
83 if (!get_master_identity_key())
102 crypto_pk_free(keys->onion_key);
103 crypto_pk_free(keys->last_onion_key);
104 ntor_key_map_free(keys->curve25519_key_map);
115 switch (state->
tag) {
116 case ONION_HANDSHAKE_TYPE_TAP:
118 case ONION_HANDSHAKE_TYPE_FAST:
119 fast_handshake_state_free(state->u.fast);
120 state->u.fast = NULL;
122 case ONION_HANDSHAKE_TYPE_NTOR:
123 ntor_handshake_state_free(state->u.ntor);
124 state->u.ntor = NULL;
126 case ONION_HANDSHAKE_TYPE_NTOR_V3:
127 ntor3_handshake_state_free(state->u.ntor3);
132 log_warn(
LD_BUG,
"called with unknown handshake state type %d",
149 uint8_t *onion_skin_out,
150 size_t onion_skin_out_maxlen)
157 case ONION_HANDSHAKE_TYPE_TAP:
159 case ONION_HANDSHAKE_TYPE_FAST:
165 case ONION_HANDSHAKE_TYPE_NTOR:
168 if (!extend_info_supports_ntor(node))
178 case ONION_HANDSHAKE_TYPE_NTOR_V3:
180 log_warn(
LD_BUG,
"Chose ntorv3 handshake, but no support at node");
184 log_warn(
LD_BUG,
"Chose ntorv3 handshake, but no ed id");
191 log_warn(
LD_BUG,
"Could not create circuit negotiation msg");
194 uint8_t *onion_skin = NULL;
195 size_t onion_skin_len = 0;
199 NTOR3_VERIFICATION_ARGS,
202 &onion_skin, &onion_skin_len);
205 log_warn(
LD_BUG,
"onion skin create failed");
208 IF_BUG_ONCE(onion_skin_len > onion_skin_out_maxlen) {
212 memcpy(onion_skin_out, onion_skin, onion_skin_len);
214 r = (int) onion_skin_len;
220 log_warn(
LD_BUG,
"called with unknown handshake state type %d", type);
227 state_out->
tag = (uint16_t) type;
233subproto_requests_in_order(
const trn_subproto_request_t *a,
234 const trn_subproto_request_t *b)
236 if (a->protocol_id < b->protocol_id) {
238 }
else if (a->protocol_id == b->protocol_id) {
239 return (a->proto_cap_number < b->proto_cap_number);
255 const trn_extension_field_t *field;
256 trn_subproto_request_ext_t *req = NULL;
266 const uint8_t *f = trn_extension_field_getconstarray_field(field);
267 size_t len = trn_extension_field_getlen_field(field);
269 if (trn_subproto_request_ext_parse(&req, f, len) < 0) {
273 const trn_subproto_request_t *prev = NULL;
274 size_t n_requests = trn_subproto_request_ext_getlen_reqs(req);
275 for (
unsigned i = 0; i < n_requests; ++i) {
276 const trn_subproto_request_t *cur =
277 trn_subproto_request_ext_getconst_reqs(req, i);
278 if (prev && !subproto_requests_in_order(prev, cur)) {
283 if (cur->protocol_id == PRT_RELAY &&
297 trn_subproto_request_ext_free(req);
314 size_t param_request_len,
317 uint8_t **resp_msg_out,
318 size_t *resp_msg_len_out)
321 trn_extension_t *ext = NULL;
324 trn_extension_parse(&ext, param_request_msg, param_request_len);
342 resp_msg_out, resp_msg_len_out);
359 trn_extension_free(ext);
367#define MAX_KEYS_TMP_LEN (MAX_RELAY_KEY_MATERIAL_LEN + DIGEST_LEN)
381 const uint8_t *onion_skin,
size_t onionskin_len,
385 size_t reply_out_maxlen,
386 uint8_t *keys_out,
size_t *keys_len_out,
387 uint8_t *rend_nonce_out,
398 case ONION_HANDSHAKE_TYPE_TAP:
400 case ONION_HANDSHAKE_TYPE_FAST:
401 if (reply_out_maxlen < CREATED_FAST_LEN)
403 if (onionskin_len != CREATE_FAST_LEN)
405 if (BUG(*keys_len_out < keys_out_needed)) {
411 r = CREATED_FAST_LEN;
414 case ONION_HANDSHAKE_TYPE_NTOR:
419 if (BUG(*keys_len_out < keys_out_needed)) {
423 size_t keys_tmp_len = keys_out_needed +
DIGEST_LEN;
425 uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
428 onion_skin, keys->curve25519_key_map,
431 reply_out, keys_tmp, keys_tmp_len)<0) {
436 memcpy(keys_out, keys_tmp, keys_out_needed);
437 memcpy(rend_nonce_out, keys_tmp+keys_out_needed,
DIGEST_LEN);
438 memwipe(keys_tmp, 0,
sizeof(keys_tmp));
442 case ONION_HANDSHAKE_TYPE_NTOR_V3: {
443 uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
444 uint8_t *client_msg = NULL;
445 size_t client_msg_len = 0;
446 uint8_t *reply_msg = NULL;
447 size_t reply_msg_len = 0;
452 keys->curve25519_key_map,
454 &keys->my_ed_identity,
455 onion_skin, onionskin_len,
456 NTOR3_VERIFICATION_ARGS,
457 &client_msg, &client_msg_len,
467 &reply_msg_len) < 0) {
468 ntor3_server_handshake_state_free(state);
478 if (BUG(*keys_len_out < keys_out_needed)) {
481 size_t keys_tmp_len = keys_out_needed +
DIGEST_LEN;
484 uint8_t *server_handshake = NULL;
485 size_t server_handshake_len = 0;
488 NTOR3_VERIFICATION_ARGS,
489 reply_msg, reply_msg_len,
490 &server_handshake, &server_handshake_len,
491 keys_tmp, keys_tmp_len) < 0) {
493 ntor3_server_handshake_state_free(state);
498 if (server_handshake_len > reply_out_maxlen) {
500 ntor3_server_handshake_state_free(state);
504 memcpy(keys_out, keys_tmp, keys_out_needed);
505 memcpy(rend_nonce_out, keys_tmp+keys_out_needed,
DIGEST_LEN);
506 memcpy(reply_out, server_handshake, server_handshake_len);
507 memwipe(keys_tmp, 0, keys_tmp_len);
508 memwipe(server_handshake, 0, server_handshake_len);
510 ntor3_server_handshake_state_free(state);
512 r = (int) server_handshake_len;
518 log_warn(
LD_BUG,
"called with unknown handshake state type %d", type);
523 *keys_len_out = keys_out_needed;
537 size_t param_response_len,
541 trn_extension_t *ext = NULL;
544 trn_extension_parse(&ext, param_response_msg, param_response_len);
572 trn_extension_free(ext);
592 const uint8_t *reply,
size_t reply_len,
593 uint8_t *keys_out,
size_t *keys_len_out,
594 uint8_t *rend_authenticator_out,
596 const char **msg_out)
598 if (handshake_state->
tag != type)
607 if (BUG(*keys_len_out < keys_out_needed)) {
610 *keys_len_out = keys_out_needed;
613 case ONION_HANDSHAKE_TYPE_TAP:
615 case ONION_HANDSHAKE_TYPE_FAST:
616 if (reply_len != CREATED_FAST_LEN) {
618 *msg_out =
"TAP reply was not of the correct length.";
622 keys_out, keys_out_needed, msg_out) < 0)
627 case ONION_HANDSHAKE_TYPE_NTOR:
630 *msg_out =
"ntor reply was not of the correct length.";
634 size_t keys_tmp_len = keys_out_needed +
DIGEST_LEN;
635 uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
638 keys_tmp, keys_tmp_len, msg_out) < 0) {
642 memcpy(keys_out, keys_tmp, keys_out_needed);
643 memcpy(rend_authenticator_out, keys_tmp + keys_out_needed,
DIGEST_LEN);
644 memwipe(keys_tmp, 0, keys_tmp_len);
648 case ONION_HANDSHAKE_TYPE_NTOR_V3: {
649 size_t keys_tmp_len = keys_out_needed +
DIGEST_LEN;
650 uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
651 uint8_t *server_msg = NULL;
652 size_t server_msg_len = 0;
654 handshake_state->u.ntor3,
656 NTOR3_VERIFICATION_ARGS,
657 keys_tmp, keys_tmp_len,
658 &server_msg, &server_msg_len);
674 memcpy(keys_out, keys_tmp, keys_out_needed);
675 memcpy(rend_authenticator_out, keys_tmp + keys_out_needed,
DIGEST_LEN);
676 memwipe(keys_tmp, 0, keys_tmp_len);
682 log_warn(
LD_BUG,
"called with unknown handshake state type %d", type);
692const trn_extension_field_t *
698 size_t n_fields = trn_extension_get_num(ext);
702 for (
unsigned i = 0; i < n_fields; ++i) {
703 const trn_extension_field_t *field = trn_extension_getconst_fields(ext, i);
707 if (trn_extension_field_get_field_type(field) == ext_type) {
int client_circ_negotiation_message(const extend_info_t *ei, uint8_t **msg_out, size_t *msg_len_out, circuit_params_t *params_out)
Header file for circuitbuild.c.
int congestion_control_parse_ext_response(const trn_extension_t *ext, circuit_params_t *params_out)
int congestion_control_build_ext_response(const circuit_params_t *our_params, const circuit_params_t *circ_params, uint8_t **msg_out, size_t *msg_len_out)
bool congestion_control_enabled(void)
int congestion_control_parse_ext_request(const trn_extension_t *ext)
Public APIs for congestion control.
Path structures for origin circuits.
int curve25519_keypair_generate(curve25519_keypair_t *keypair_out, int extra_strong)
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
int extend_info_supports_ntor_v3(const extend_info_t *ei)
Header for core/or/extendinfo.c.
static void circuit_params_init(circuit_params_t *params)
static int negotiate_v3_ntor_client_circ_params(const uint8_t *param_response_msg, size_t param_response_len, circuit_params_t *params_out)
const trn_extension_field_t * trn_extension_find(const trn_extension_t *ext, uint8_t ext_type)
int onion_skin_create(int type, const extend_info_t *node, onion_handshake_state_t *state_out, uint8_t *onion_skin_out, size_t onion_skin_out_maxlen)
void server_onion_keys_free_(server_onion_keys_t *keys)
void onion_handshake_state_release(onion_handshake_state_t *state)
int onion_skin_server_handshake(int type, const uint8_t *onion_skin, size_t onionskin_len, const server_onion_keys_t *keys, const circuit_params_t *our_ns_params, uint8_t *reply_out, size_t reply_out_maxlen, uint8_t *keys_out, size_t *keys_len_out, uint8_t *rend_nonce_out, circuit_params_t *params_out)
static int negotiate_v3_ntor_server_circ_params(const uint8_t *param_request_msg, size_t param_request_len, const circuit_params_t *our_ns_params, circuit_params_t *params_out, uint8_t **resp_msg_out, size_t *resp_msg_len_out)
static int relay_process_subproto_ext(const trn_extension_t *ext, circuit_params_t *params_out)
server_onion_keys_t * server_onion_keys_new(void)
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_len_out, uint8_t *rend_authenticator_out, circuit_params_t *params_out, const char **msg_out)
Header file for onion_crypto.c.
int fast_client_handshake(const fast_handshake_state_t *handshake_state, const uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len, const char **msg_out)
int fast_server_handshake(const uint8_t *key_in, uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len)
int fast_onionskin_create(fast_handshake_state_t **handshake_state_out, uint8_t *handshake_out)
Header file for onion_fast.c.
int onion_skin_ntor_client_handshake(const ntor_handshake_state_t *handshake_state, const uint8_t *handshake_reply, uint8_t *key_out, size_t key_out_len, const char **msg_out)
int onion_skin_ntor_server_handshake(const uint8_t *onion_skin, const di_digest256_map_t *private_keys, const curve25519_keypair_t *junk_keys, const uint8_t *my_node_id, uint8_t *handshake_reply_out, uint8_t *key_out, size_t key_out_len)
int onion_skin_ntor_create(const uint8_t *router_id, const curve25519_public_key_t *router_key, ntor_handshake_state_t **handshake_state_out, uint8_t *onion_skin_out)
#define NTOR_ONIONSKIN_LEN
int onion_ntor3_client_handshake(const ntor3_handshake_state_t *handshake_state, const uint8_t *handshake_reply, size_t reply_len, const uint8_t *verification, size_t verification_len, uint8_t *keys_out, size_t keys_out_len, uint8_t **message_out, size_t *message_len_out)
int onion_skin_ntor3_server_handshake_part1(const di_digest256_map_t *private_keys, const curve25519_keypair_t *junk_key, const ed25519_public_key_t *my_id, const uint8_t *client_handshake, size_t client_handshake_len, const uint8_t *verification, size_t verification_len, uint8_t **client_message_out, size_t *client_message_len_out, ntor3_server_handshake_state_t **state_out)
int onion_skin_ntor3_create(const ed25519_public_key_t *relay_id, const curve25519_public_key_t *relay_key, const uint8_t *verification, const size_t verification_len, const uint8_t *message, const size_t message_len, ntor3_handshake_state_t **handshake_state_out, uint8_t **onion_skin_out, size_t *onion_skin_len_out)
int onion_skin_ntor3_server_handshake_part2(const ntor3_server_handshake_state_t *state, const uint8_t *verification, size_t verification_len, const uint8_t *server_message, size_t server_message_len, uint8_t **handshake_out, size_t *handshake_len_out, uint8_t *keys_out, size_t keys_out_len)
Header for core/crypto/onion_ntor_v3.c.
struct ntor3_server_handshake_state_t ntor3_server_handshake_state_t
Master header file for Tor-specific functionality.
Headers and type declarations for protover.c.
#define PROTOVER_RELAY_CRYPT_CGO
Header for relay_crypto.c.
ssize_t relay_crypto_key_material_len(relay_crypto_alg_t alg)
@ RELAY_CRYPTO_ALG_CGO_RELAY
const uint8_t * router_get_my_id_digest(void)
void dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last)
di_digest256_map_t * construct_ntor_key_map(void)
Header file for router.c.
relay_cell_fmt_t cell_fmt
relay_crypto_alg_t crypto_alg
ed25519_public_key_t ed_identity
char identity_digest[DIGEST_LEN]
curve25519_public_key_t curve25519_onion_key
circuit_params_t chosen_params
#define tor_fragile_assert()
#define IF_BUG_ONCE(cond)