]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Add cell format and crypto alg to circ_params
authorNick Mathewson <nickm@torproject.org>
Mon, 2 Jun 2025 14:08:00 +0000 (10:08 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 10 Jun 2025 23:06:47 +0000 (19:06 -0400)
This allows them to be negotiated as part of the handshake.

src/core/crypto/onion_crypto.c
src/core/crypto/onion_crypto.h
src/core/mainloop/cpuworker.c
src/core/or/circuitbuild.c
src/core/or/command.c
src/core/or/crypt_path.c
src/feature/relay/circuitbuild_relay.c
src/feature/relay/circuitbuild_relay.h
src/test/test_circuitbuild.c

index f32633879bbf1e31a1eb835ef347a063e78d7c93..787238b278d08b84d9bdd178ac8460c6dfd19155 100644 (file)
@@ -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:
index 7d19961fc61a8f712d3c3882f52771001dff6962..5e64726b0804289f782c42c53706399ba00aed5f 100644 (file)
@@ -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,
index 6714bc2f945663190e32c4ca29ee0822d81b3760..8a37a23261df43b1fe486509c8b4a3bc3fb17b38 100644 (file)
@@ -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.");
index 1cab8887792fc8dc5e874058ea0d47fd57047f37..ee8715a745d3b6ddd717f628f223793ace4ae79b 100644 (file)
@@ -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);
index 5684844592fc4db9a73fc3061a4d54011aea425f..3bbe278441b25cc9626778094a84fd24c586e42b 100644 (file)
@@ -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.");
index b734d3457818bc819d0182c6ef4fdfe311519362..8f66caa498468fe7c111c2a35524c08d2f355f63 100644 (file)
@@ -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;
index 921235bc889cf75e5a909f6385807d4c6198091c..2f8467f68cbfd257ab43e2b5cb29ecb72a40c7f9 100644 (file)
@@ -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;
index 0148aa5581f1f20510c1812a52d255dd7d1425a8..529cc7fb30133fc193bbddc01b717d273074d919 100644 (file)
@@ -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;
index 3448bb0180e0f6fbcad9b9109838cb170d29989b..62af0bf48c92b1a58e67d98b12a4997786aefef0 100644 (file)
@@ -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");