[or-cvs] Track routers by hash of identity key; use hex hash of iden...

Nick Mathewson nickm at seul.org
Thu Jul 1 01:17:02 UTC 2004


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv28148/src/or

Modified Files:
	circuitbuild.c connection.c connection_or.c directory.c or.h 
	router.c routerlist.c routerparse.c 
Log Message:
Track routers by hash of identity key; use hex hash of identity key in place of nickname; accept (and use) hash of identity key in EXTEND cells.

Index: circuitbuild.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuitbuild.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- circuitbuild.c	20 May 2004 19:12:28 -0000	1.2
+++ circuitbuild.c	1 Jul 2004 01:16:58 -0000	1.3
@@ -292,7 +292,9 @@
   routerinfo_t *router;
   int r;
   int circ_id_type;
-  char payload[2+4+ONIONSKIN_CHALLENGE_LEN];
+  char payload[2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN];
+  char *onionskin;
+  int payload_len;
 
   tor_assert(circ && CIRCUIT_IS_ORIGIN(circ));
 
@@ -352,7 +354,17 @@
 
     *(uint32_t*)payload = htonl(hop->addr);
     *(uint16_t*)(payload+4) = htons(hop->port);
-    if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), payload+6) < 0) {
+    if (strncmp(router->platform, "Tor 0.0.7", 9)) {
+      /* Before 0.0.8, we didn't support the long payload format. */
+      memcpy(payload+2+4, hop->identity_digest, DIGEST_LEN);
+      onionskin = payload+2+4+DIGEST_LEN;
+      payload_len = 2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN;
+    } else {
+      onionskin = payload+2+4;
+      payload_len = 2+4+ONIONSKIN_CHALLENGE_LEN;
+    }
+
+    if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), onionskin) < 0) {
       log_fn(LOG_WARN,"onion_skin_create failed.");
       return -1;
     }
@@ -361,7 +373,7 @@
     /* send it to hop->prev, because it will transfer
      * it to a create cell and then send to hop */
     if(connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTEND,
-                               payload, sizeof(payload), hop->prev) < 0)
+                               payload, payload_len, hop->prev) < 0)
       return 0; /* circuit is closed */
 
     hop->state = CPATH_STATE_AWAITING_KEYS;
@@ -377,16 +389,42 @@
   connection_t *n_conn;
   int circ_id_type;
   cell_t newcell;
+  relay_header_t rh;
+  int old_format;
+  char *onionskin;
 
   if(circ->n_conn) {
     log_fn(LOG_WARN,"n_conn already set. Bug/attack. Closing.");
     return -1;
   }
 
+  relay_header_unpack(&rh, cell->payload);
+
+  if (rh.length == 4+2+ONIONSKIN_CHALLENGE_LEN) {
+    old_format = 1;
+  } else if (rh.length == 4+2+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN) {
+    old_format = 0;
+  } else {
+    log_fn(LOG_WARN, "Wrong length on extend cell. Closing circuit.");
+    circuit_mark_for_close(circ);
+    return 0;
+  }
+
   circ->n_addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
   circ->n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4));
 
-  n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
+  if (old_format) {
+    n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
+    onionskin = cell->payload+RELAY_HEADER_SIZE+4+2;
+  } else {
+    /* XXXX Roger: in this case, we should create the connnection if
+     * n_conn is null. */
+    n_conn = connection_get_by_identity_digest(
+                         cell->payload+RELAY_HEADER_SIZE+4+2,
+                         CONN_TYPE_OR);
+    onionskin = cell->payload+RELAY_HEADER_SIZE+4+2+DIGEST_LEN;
+  }
+
   if(!n_conn || n_conn->type != CONN_TYPE_OR) {
     /* I've disabled making connections through OPs, but it's definitely
      * possible here. I'm not sure if it would be a bug or a feature.
@@ -426,8 +464,7 @@
   newcell.command = CELL_CREATE;
   newcell.circ_id = circ->n_circ_id;
 
-  memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+2+4,
-         ONIONSKIN_CHALLENGE_LEN);
+  memcpy(newcell.payload, onionskin, ONIONSKIN_CHALLENGE_LEN);
 
   connection_or_write_cell_to_buf(&newcell, circ->n_conn);
   return 0;
@@ -1079,6 +1116,7 @@
 
   hop->port = choice->or_port;
   hop->addr = choice->addr;
+  memcpy(hop->identity_digest, choice->identity_digest, DIGEST_LEN);
 
   hop->package_window = CIRCWINDOW_START;
   hop->deliver_window = CIRCWINDOW_START;

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.232
retrieving revision 1.233
diff -u -d -r1.232 -r1.233
--- connection.c	17 Jun 2004 18:13:09 -0000	1.232
+++ connection.c	1 Jul 2004 01:16:58 -0000	1.233
@@ -979,6 +979,25 @@
   return NULL;
 }
 
+connection_t *connection_get_by_identity_digest(const char *digest, int type)
+{
+  int i, n;
+  connection_t *conn, *best=NULL;
+  connection_t **carray;
+
+  get_connection_array(&carray,&n);
+  for(i=0;i<n;i++) {
+    conn = carray[i];
+    if (conn->type != type)
+      continue;
+    if (!memcmp(conn->identity_digest, digest, DIGEST_LEN)
+        && !conn->marked_for_close
+        && (!best || best->timestamp_created < conn->timestamp_created))
+      best = conn;
+  }
+  return best;
+}
+
 /** Return a connection of type <b>type</b> that is not marked for
  * close.
  */

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -d -r1.109 -r1.110
--- connection_or.c	12 May 2004 22:56:26 -0000	1.109
+++ connection_or.c	1 Jul 2004 01:16:58 -0000	1.110
@@ -107,11 +107,34 @@
   conn->port = router->or_port;
   conn->receiver_bucket = conn->bandwidth = router->bandwidthburst;
   conn->identity_pkey = crypto_pk_dup_key(router->identity_pkey);
+  crypto_pk_get_digest(conn->identity_pkey, conn->identity_digest);
   conn->nickname = tor_strdup(router->nickname);
   tor_free(conn->address);
   conn->address = tor_strdup(router->address);
 }
 
+static void
+connection_or_init_conn_from_address(connection_t *conn,
+                                     uint32_t addr, uint16_t port,
+                                     const char *id_digest)
+{
+  routerinfo_t *r;
+  r = router_get_by_digest(id_digest);
+  if (r) {
+    connection_or_init_conn_from_router(conn,r);
+    return;
+  }
+  conn->addr = addr;
+  conn->port = port;
+  /* This next part isn't really right, but it's good enough for now. */
+  conn->receiver_bucket = conn->bandwidth = options.BandwidthBurst;
+  memcpy(conn->identity_digest, id_digest, DIGEST_LEN);
+  conn->nickname = tor_malloc(HEX_DIGEST_LEN+1);
+  base16_encode(conn->nickname, HEX_DIGEST_LEN+1,
+                conn->identity_digest, DIGEST_LEN);
+  /* Do something about address? Or is it already set? XXXX NMNM */
+}
+
 /** Launch a new OR connection to <b>router</b>.
  *
  * If <b>router</b> is me, do nothing. If we're already connected to <b>router</b>,

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -d -r1.111 -r1.112
--- directory.c	30 Jun 2004 21:48:02 -0000	1.111
+++ directory.c	1 Jul 2004 01:16:58 -0000	1.112
@@ -137,6 +137,7 @@
   conn->nickname = tor_strdup(router->nickname);
   tor_assert(router->identity_pkey);
   conn->identity_pkey = crypto_pk_dup_key(router->identity_pkey);
+  crypto_pk_get_digest(conn->identity_pkey, conn->identity_digest);
 
   conn->purpose = purpose;
 

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.371
retrieving revision 1.372
diff -u -d -r1.371 -r1.372
--- or.h	25 Jun 2004 00:29:31 -0000	1.371
+++ or.h	1 Jul 2004 01:16:58 -0000	1.372
@@ -493,8 +493,9 @@
   char *address; /**< FQDN (or IP) of the guy on the other end.
                   * strdup into this, because free_connection frees it.
                   */
-  crypto_pk_env_t *identity_pkey; /**> Public RSA key for the other side's
+  crypto_pk_env_t *identity_pkey; /**< Public RSA key for the other side's
                                    * signing key. */
+  char identity_digest[DIGEST_LEN]; /**< Hash of identity_pkey */
   char *nickname; /**< Nickname of OR on other side (if any). */
 
 /* Used only by OR connections: */
@@ -569,7 +570,7 @@
 
   crypto_pk_env_t *onion_pkey; /**< Public RSA key for onions. */
   crypto_pk_env_t *identity_pkey;  /**< Public RSA key for signing. */
-
+  char identity_digest[DIGEST_LEN]; /** Digest of identity key */
 
   char *platform; /**< What software/operating system is this OR using? */
 
@@ -633,6 +634,8 @@
   uint32_t addr;
   /** Port of the OR at this step. */
   uint16_t port;
+  /** Identity key digest of the OR at this step. */
+  char identity_digest[DIGEST_LEN];
 
   /** Is the circuit built to this step?  Must be one of:
    *    - CPATH_STATE_CLOSED (The circuit has not been extended to this step)
@@ -1044,6 +1047,7 @@
 
 connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port);
 connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
+connection_t *connection_get_by_identity_digest(const char *digest, int type);
 
 connection_t *connection_get_by_type(int type);
 connection_t *connection_get_by_type_state(int type, int state);
@@ -1341,7 +1345,9 @@
 routerinfo_t *router_choose_random_node(char *preferred, char *excluded,
                                         struct smartlist_t *excludedsmartlist);
 routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
-routerinfo_t *router_get_by_nickname(char *nickname);
+routerinfo_t *router_get_by_nickname(const char *nickname);
+routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
+routerinfo_t *router_get_by_digest(const char *digest);
 void router_get_routerlist(routerlist_t **prouterlist);
 void routerlist_free(routerlist_t *routerlist);
 void routerlist_clear_trusted_directories(void);

Index: router.c
===================================================================
RCS file: /home/or/cvsroot/src/or/router.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- router.c	30 Jun 2004 21:48:02 -0000	1.53
+++ router.c	1 Jul 2004 01:16:59 -0000	1.54
@@ -444,6 +444,10 @@
   ri->published_on = time(NULL);
   ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from main thread */
   ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
+  if (crypto_pk_get_digest(ri->identity_pkey, ri->identity_digest)<0) {
+    routerinfo_free(ri);
+    return -1;
+  }
   get_platform_str(platform, sizeof(platform));
   ri->platform = tor_strdup(platform);
   ri->bandwidthrate = options.BandwidthRate;

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerlist.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- routerlist.c	30 Jun 2004 21:48:02 -0000	1.89
+++ routerlist.c	1 Jul 2004 01:16:59 -0000	1.90
@@ -206,21 +206,59 @@
   return NULL;
 }
 
-/** Return the router in our routerlist whose nickname is <b>nickname</b>
- * (case insensitive).  Return NULL if no such router is known.
+/** Return the router in our routerlist whose (case-insensitive)
+ * nickname or (case-sensitive) hexadecimal key digest is
+ * <b>nickname</b>.  Return NULL if no such router is known.
  */
-routerinfo_t *router_get_by_nickname(char *nickname)
+routerinfo_t *router_get_by_nickname(const char *nickname)
 {
-  int i;
+  int i, maybedigest;
   routerinfo_t *router;
+  char digest[DIGEST_LEN];
 
   tor_assert(nickname);
   if (!routerlist)
     return NULL;
+  maybedigest = (strlen(nickname) == HEX_DIGEST_LEN) &&
+    (base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
 
   for(i=0;i<smartlist_len(routerlist->routers);i++) {
     router = smartlist_get(routerlist->routers, i);
-    if (0 == strcasecmp(router->nickname, nickname))
+    if (0 == strcasecmp(router->nickname, nickname) ||
+        (maybedigest && 0 == memcmp(digest, router->identity_digest,
+                                    DIGEST_LEN)))
+      return router;
+  }
+
+  return NULL;
+}
+
+/** Return the router in our routerlist whose hexadecimal key digest
+ * is <b>hexdigest</b>.  Return NULL if no such router is known. */
+routerinfo_t *router_get_by_hexdigest(const char *hexdigest) {
+  char digest[DIGEST_LEN];
+
+  tor_assert(hexdigest);
+  if (!routerlist)
+    return NULL;
+  if (strlen(hexdigest) != HEX_DIGEST_LEN ||
+      base16_decode(digest,DIGEST_LEN,hexdigest,HEX_DIGEST_LEN) < 0)
+    return NULL;
+
+  return router_get_by_digest(digest);
+}
+
+/** Return the router in our routerlist whose 20-byte key digest
+ * is <b>hexdigest</b>.  Return NULL if no such router is known. */
+routerinfo_t *router_get_by_digest(const char *digest) {
+  int i;
+  routerinfo_t *router;
+
+  tor_assert(digest);
+
+  for(i=0;i<smartlist_len(routerlist->routers);i++) {
+    router = smartlist_get(routerlist->routers, i);
+    if (0 == memcmp(router->identity_digest, digest, DIGEST_LEN))
       return router;
   }
 

Index: routerparse.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerparse.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- routerparse.c	25 Jun 2004 00:29:31 -0000	1.7
+++ routerparse.c	1 Jul 2004 01:16:59 -0000	1.8
@@ -733,11 +733,14 @@
   }
 
   if (!(tok = find_first_by_keyword(tokens, K_SIGNING_KEY))) {
-    log_fn(LOG_WARN, "Missing onion key"); goto err;
+    log_fn(LOG_WARN, "Missing identity key"); goto err;
   }
   /* XXX Check key length */
   router->identity_pkey = tok->key;
   tok->key = NULL; /* Prevent free */
+  if (crypto_pk_get_digest(router->identity_pkey,router->identity_digest)){
+    log_fn(LOG_WARN, "Couldn't calculate key digest"); goto err;
+  }
 
   if ((tok = find_first_by_keyword(tokens, K_PLATFORM))) {
     router->platform = tor_strdup(tok->args[0]);



More information about the tor-commits mailing list