From: Nick Mathewson Date: Mon, 2 Jun 2025 14:08:00 +0000 (-0400) Subject: Add cell format and crypto alg to circ_params X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5535d84aeaacff79f056edd4432de30c5b63bc5;p=thirdparty%2Ftor.git Add cell format and crypto alg to circ_params This allows them to be negotiated as part of the handshake. --- diff --git a/src/core/crypto/onion_crypto.c b/src/core/crypto/onion_crypto.c index f32633879b..787238b278 100644 --- a/src/core/crypto/onion_crypto.c +++ b/src/core/crypto/onion_crypto.c @@ -57,6 +57,18 @@ static const size_t NTOR3_CIRC_VERIFICATION_LEN = 14; #define NTOR3_VERIFICATION_ARGS \ NTOR3_CIRC_VERIFICATION, NTOR3_CIRC_VERIFICATION_LEN +/** Set `params` to a set of defaults. + * + * These defaults will only change later on if we're using a handshake that has + * parameter negotiation. */ +static void +circuit_params_init(circuit_params_t *params) +{ + memset(params, 0, sizeof(*params)); + params->crypto_alg = RELAY_CRYPTO_ALG_TOR1; + params->cell_fmt = RELAY_CELL_FORMAT_V0; +} + /** 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, @@ -283,7 +295,7 @@ onion_skin_server_handshake(int type, } *keys_len_out = keys_out_needed; - memset(params_out, 0, sizeof(*params_out)); + circuit_params_init(params_out); switch (type) { case ONION_HANDSHAKE_TYPE_TAP: @@ -471,7 +483,7 @@ onion_skin_client_handshake(int type, } *keys_len_out = keys_out_needed; - memset(params_out, 0, sizeof(*params_out)); + circuit_params_init(params_out); switch (type) { case ONION_HANDSHAKE_TYPE_TAP: diff --git a/src/core/crypto/onion_crypto.h b/src/core/crypto/onion_crypto.h index 7d19961fc6..5e64726b08 100644 --- a/src/core/crypto/onion_crypto.h +++ b/src/core/crypto/onion_crypto.h @@ -13,6 +13,7 @@ #define TOR_ONION_CRYPTO_H #include "lib/crypt_ops/crypto_ed25519.h" +#include "core/crypto/relay_crypto.h" typedef struct server_onion_keys_t { uint8_t my_identity[DIGEST_LEN]; @@ -34,6 +35,11 @@ typedef struct circuit_params_t { bool cc_enabled; /** The number of cells in a sendme increment. Only used if cc_enabled=1. */ uint8_t sendme_inc_cells; + + /** Which algorithm did we negotiate? */ + relay_crypto_alg_t crypto_alg; + /** Which cell format did we negotiate? */ + relay_cell_fmt_t cell_fmt; } circuit_params_t; int onion_skin_create(int type, diff --git a/src/core/mainloop/cpuworker.c b/src/core/mainloop/cpuworker.c index 6714bc2f94..8a37a23261 100644 --- a/src/core/mainloop/cpuworker.c +++ b/src/core/mainloop/cpuworker.c @@ -213,7 +213,9 @@ typedef struct cpuworker_reply_t { /** The created cell to send back. */ created_cell_t created_cell; /** The keys to use on this circuit. */ - uint8_t keys[CPATH_KEY_MATERIAL_LEN]; + uint8_t keys[MAX_RELAY_KEY_MATERIAL_LEN]; + /** Length of the generated key material. */ + size_t keys_len; /** Input to use for authenticating introduce1 cells. */ uint8_t rend_auth_material[DIGEST_LEN]; /** Negotiated circuit parameters. */ @@ -451,12 +453,12 @@ cpuworker_onion_handshake_replyfn(void *work_) } } - // TODO CGO: Initialize this from a real handshake. - circ->relay_cell_format = RELAY_CELL_FORMAT_V0; + circ->relay_cell_format = rpl.circ_params.cell_fmt; if (onionskin_answer(circ, &rpl.created_cell, - (const char*)rpl.keys, sizeof(rpl.keys), + rpl.circ_params.crypto_alg, + (const char*)rpl.keys, rpl.keys_len, rpl.rend_auth_material) < 0) { log_warn(LD_OR,"onionskin_answer failed. Closing."); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); @@ -498,18 +500,17 @@ cpuworker_onion_handshake_threadfn(void *state_, void *work_) rpl.handshake_type = cc->handshake_type; if (req.timed) tor_gettimeofday(&tv_start); - size_t keys_len = sizeof(rpl.keys); + rpl.keys_len = sizeof(rpl.keys); n = onion_skin_server_handshake(cc->handshake_type, cc->onionskin, cc->handshake_len, onion_keys, &req.circ_ns_params, cell_out->reply, sizeof(cell_out->reply), - rpl.keys, &keys_len, + rpl.keys, &rpl.keys_len, rpl.rend_auth_material, &rpl.circ_params); - // XXXX Will be wrong for cgo. - tor_assert(keys_len == CPATH_KEY_MATERIAL_LEN); + if (n < 0) { /* failure */ log_debug(LD_OR,"onion_skin_server_handshake failed."); diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index 1cab888779..ee8715a745 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -1258,7 +1258,7 @@ int circuit_finish_handshake(origin_circuit_t *circ, const created_cell_t *reply) { - char keys[CPATH_KEY_MATERIAL_LEN]; + char keys[MAX_RELAY_KEY_MATERIAL_LEN]; crypt_path_t *hop; int rv; @@ -1279,9 +1279,10 @@ circuit_finish_handshake(origin_circuit_t *circ, tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS); circuit_params_t params; + size_t keylen = sizeof(keys); { const char *msg = NULL; - size_t keylen = sizeof(keys); + if (onion_skin_client_handshake(hop->handshake_state.tag, &hop->handshake_state, reply->reply, reply->handshake_len, @@ -1291,18 +1292,16 @@ circuit_finish_handshake(origin_circuit_t *circ, &msg) < 0) { if (msg) log_warn(LD_CIRC,"onion_skin_client_handshake failed: %s", msg); - // XXXX This will be wrong for CGO. - tor_assert(keylen == sizeof(keys)); return -END_CIRC_REASON_TORPROTOCOL; } } onion_handshake_state_release(&hop->handshake_state); - - if (cpath_init_circuit_crypto(RELAY_CRYPTO_ALG_TOR1, - hop, keys, sizeof(keys))<0) { + if (cpath_init_circuit_crypto(params.crypto_alg, + hop, keys, keylen)<0) { return -END_CIRC_REASON_TORPROTOCOL; } + hop->relay_cell_format = params.cell_fmt; if (params.cc_enabled) { int circ_len = circuit_get_cpath_len(circ); diff --git a/src/core/or/command.c b/src/core/or/command.c index 5684844592..3bbe278441 100644 --- a/src/core/or/command.c +++ b/src/core/or/command.c @@ -392,6 +392,7 @@ command_process_create_cell(cell_t *cell, channel_t *chan) created_cell.handshake_len = len; if (onionskin_answer(circ, &created_cell, + RELAY_CRYPTO_ALG_TOR1, (const char *)keys, sizeof(keys), rend_circ_nonce)<0) { log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing."); diff --git a/src/core/or/crypt_path.c b/src/core/or/crypt_path.c index b734d34578..8f66caa498 100644 --- a/src/core/or/crypt_path.c +++ b/src/core/or/crypt_path.c @@ -71,7 +71,7 @@ cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice) hop->package_window = circuit_initial_package_window(); hop->deliver_window = CIRCWINDOW_START; - // TODO CGO: Initialize this from a real decision. + // This can get changed later on by circuit negotiation. hop->relay_cell_format = RELAY_CELL_FORMAT_V0; return 0; diff --git a/src/feature/relay/circuitbuild_relay.c b/src/feature/relay/circuitbuild_relay.c index 921235bc88..2f8467f68c 100644 --- a/src/feature/relay/circuitbuild_relay.c +++ b/src/feature/relay/circuitbuild_relay.c @@ -535,6 +535,7 @@ circuit_extend(const relay_msg_t *rmsg, struct circuit_t *circ) int onionskin_answer(struct or_circuit_t *circ, const created_cell_t *created_cell, + relay_crypto_alg_t crypto_alg, const char *keys, size_t keys_len, const uint8_t *rend_circ_nonce) { @@ -556,9 +557,6 @@ onionskin_answer(struct or_circuit_t *circ, return -1; } - // XXXX: This will be wrong for cgo. - tor_assert(keys_len == CPATH_KEY_MATERIAL_LEN); - if (created_cell_format(&cell, created_cell) < 0) { log_warn(LD_BUG,"couldn't format created cell (type=%d, len=%d).", (int)created_cell->cell_type, (int)created_cell->handshake_len); @@ -571,7 +569,7 @@ onionskin_answer(struct or_circuit_t *circ, log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.", (unsigned int)get_uint32(keys), (unsigned int)get_uint32(keys+20)); - if (relay_crypto_init(RELAY_CRYPTO_ALG_TOR1, + if (relay_crypto_init(crypto_alg, &circ->crypto, keys, keys_len)<0) { log_warn(LD_BUG,"Circuit initialization failed."); return -1; diff --git a/src/feature/relay/circuitbuild_relay.h b/src/feature/relay/circuitbuild_relay.h index 0148aa5581..529cc7fb30 100644 --- a/src/feature/relay/circuitbuild_relay.h +++ b/src/feature/relay/circuitbuild_relay.h @@ -15,6 +15,7 @@ #include "lib/cc/torint.h" #include "lib/log/log.h" #include "core/or/relay_msg_st.h" +#include "core/crypto/relay_crypto.h" #include "app/config/config.h" @@ -39,6 +40,7 @@ int circuit_extend(const relay_msg_t *msg, struct circuit_t *circ); int onionskin_answer(struct or_circuit_t *circ, const struct created_cell_t *created_cell, + relay_crypto_alg_t crypto_alg, const char *keys, size_t keys_len, const uint8_t *rend_circ_nonce); @@ -56,11 +58,13 @@ circuit_extend(const relay_msg_t *msg, struct circuit_t *circ) static inline int onionskin_answer(struct or_circuit_t *circ, const struct created_cell_t *created_cell, + relay_crypto_alg_t crypto_alg, const char *keys, size_t keys_len, const uint8_t *rend_circ_nonce) { (void)circ; (void)created_cell; + (void)crypto_alg; (void)keys; (void)keys_len; (void)rend_circ_nonce; diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c index 3448bb0180..62af0bf48c 100644 --- a/src/test/test_circuitbuild.c +++ b/src/test/test_circuitbuild.c @@ -1532,6 +1532,7 @@ test_onionskin_answer(void *arg) /* Circuit must be non-NULL */ tor_capture_bugs_(1); tt_int_op(onionskin_answer(NULL, created_cell, + RELAY_CRYPTO_ALG_TOR1, keys, CPATH_KEY_MATERIAL_LEN, rend_circ_nonce), OP_EQ, -1); tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1); @@ -1543,6 +1544,7 @@ test_onionskin_answer(void *arg) /* Created cell must be non-NULL */ tor_capture_bugs_(1); tt_int_op(onionskin_answer(or_circ, NULL, + RELAY_CRYPTO_ALG_TOR1, keys, CPATH_KEY_MATERIAL_LEN, rend_circ_nonce), OP_EQ, -1); tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1); @@ -1554,6 +1556,7 @@ test_onionskin_answer(void *arg) /* Keys must be non-NULL */ tor_capture_bugs_(1); tt_int_op(onionskin_answer(or_circ, created_cell, + RELAY_CRYPTO_ALG_TOR1, NULL, CPATH_KEY_MATERIAL_LEN, rend_circ_nonce), OP_EQ, -1); tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1); @@ -1565,6 +1568,7 @@ test_onionskin_answer(void *arg) /* The rend circuit nonce must be non-NULL */ tor_capture_bugs_(1); tt_int_op(onionskin_answer(or_circ, created_cell, + RELAY_CRYPTO_ALG_TOR1, keys, CPATH_KEY_MATERIAL_LEN, NULL), OP_EQ, -1); tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1); @@ -1579,6 +1583,7 @@ test_onionskin_answer(void *arg) /* Fail when formatting the created cell */ tt_int_op(onionskin_answer(or_circ, created_cell, + RELAY_CRYPTO_ALG_TOR1, keys, CPATH_KEY_MATERIAL_LEN, rend_circ_nonce), OP_EQ, -1); expect_log_msg("couldn't format created cell (type=0, len=0).\n");