[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor/master] Canonicity update for ed25519.



commit cd741cc595d705daef3aa9158bc7822fff935846
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date:   Fri Nov 11 12:38:11 2016 -0500

    Canonicity update for ed25519.
    
    If a node can prove its Ed25519 identity, don't consider connections
    to it canonical unless they match both identities.
    
    Includes link handshake changes needed to avoid crashing with bug
    warnings, since the tests now reach more parts of the code.
    
    Closes ticket 20355
---
 src/or/connection_or.c         | 41 ++++++++++++++++++++++++++++++++++++++++-
 src/test/test_link_handshake.c |  4 ++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 953e9df..088900c 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -75,6 +75,9 @@ static void connection_or_mark_bad_for_new_circs(or_connection_t *or_conn);
 
 static void connection_or_change_state(or_connection_t *conn, uint8_t state);
 
+static void connection_or_check_canonicity(or_connection_t *conn,
+                                           int started_here);
+
 /**************************************************************/
 
 /** Global map between Extended ORPort identifiers and OR
@@ -869,13 +872,38 @@ connection_or_init_conn_from_address(or_connection_t *conn,
             ed25519_fmt(ed_id),
             started_here);
 
-  const node_t *r = node_get_by_id(id_digest);
   connection_or_set_identity_digest(conn, id_digest, ed_id);
   connection_or_update_token_buckets_helper(conn, 1, get_options());
 
   conn->base_.port = port;
   tor_addr_copy(&conn->base_.addr, addr);
   tor_addr_copy(&conn->real_addr, addr);
+
+  connection_or_check_canonicity(conn, started_here);
+}
+
+/** Check whether the identity of <b>conn</b> matches a known node.  If it
+ * does, check whether the address of conn matches the expected address, and
+ * update the connection's is_canonical flag, nickname, and address fields as
+ * appropriate. */
+static void
+connection_or_check_canonicity(or_connection_t *conn, int started_here)
+{
+  const char *id_digest = conn->identity_digest;
+  const ed25519_public_key_t *ed_id = NULL;
+  const tor_addr_t *addr = &conn->real_addr;
+  if (conn->chan)
+    ed_id = & TLS_CHAN_TO_BASE(conn->chan)->ed25519_identity;
+
+  const node_t *r = node_get_by_id(id_digest);
+  if (r &&
+      node_supports_ed25519_link_authentication(r) &&
+      ! node_ed25519_id_matches(r, ed_id)) {
+    /* If this node is capable of proving an ed25519 ID,
+     * we can't call this a canonical connection unless both IDs match. */
+     r = NULL;
+  }
+
   if (r) {
     tor_addr_port_t node_ap;
     node_get_pref_orport(r, &node_ap);
@@ -897,10 +925,12 @@ connection_or_init_conn_from_address(or_connection_t *conn,
       tor_addr_copy(&conn->base_.addr, &node_ap.addr);
       conn->base_.port = node_ap.port;
     }
+    tor_free(conn->nickname);
     conn->nickname = tor_strdup(node_get_nickname(r));
     tor_free(conn->base_.address);
     conn->base_.address = tor_addr_to_str_dup(&node_ap.addr);
   } else {
+    tor_free(conn->nickname);
     conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
     conn->nickname[0] = '$';
     base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
@@ -1589,6 +1619,7 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
   const or_options_t *options = get_options();
   channel_tls_t *chan_tls = conn->chan;
   channel_t *chan = channel_tls_to_base(chan_tls);
+  int changed_identity = 0;
   tor_assert(chan);
 
   const int expected_rsa_key =
@@ -1619,6 +1650,7 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
      * we do -- remember it for future attempts. */
     learned_router_identity(&conn->base_.addr, conn->base_.port,
                             (const char*)rsa_peer_id, ed_peer_id);
+    changed_identity = 1;
   }
 
   const int rsa_mismatch = expected_rsa_key &&
@@ -1706,6 +1738,13 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
              "connection.");
     connection_or_set_identity_digest(conn,
                                       (const char*)rsa_peer_id, ed_peer_id);
+    changed_identity = 1;
+  }
+
+  if (changed_identity) {
+    /* If we learned an identity for this connection, then we might have
+     * just discovered it to be canonical. */
+    connection_or_check_canonicity(conn, conn->handshake_state->started_here);
   }
 
   if (authdir_mode_tests_reachability(options)) {
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index 9931702..421f3aa 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -117,6 +117,9 @@ test_link_handshake_certs_ok(void *arg)
   crypto_pk_t *key1 = NULL, *key2 = NULL;
   const int with_ed = !strcmp((const char *)arg, "Ed25519");
 
+  tor_addr_from_ipv4h(&c1->base_.addr, 0x7f000001);
+  tor_addr_from_ipv4h(&c2->base_.addr, 0x7f000001);
+
   scheduler_init();
 
   MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
@@ -354,6 +357,7 @@ recv_certs_setup(const struct testcase_t *test)
   d->chan = tor_malloc_zero(sizeof(*d->chan));
   d->c->chan = d->chan;
   d->c->base_.address = tor_strdup("HaveAnAddress");
+  tor_addr_from_ipv4h(&d->c->base_.addr, 0x801f0127);
   d->c->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
   d->chan->conn = d->c;
   tt_int_op(connection_init_or_handshake_state(d->c, 1), ==, 0);



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits