Unverified Commit 579a80d4 authored by teor (Tim Wilson-Brown)'s avatar teor (Tim Wilson-Brown)
Browse files

Clients avoid choosing nodes that can't do ntor

If we know a node's version, and it can't do ntor, consider it not running.
If we have a node's descriptor, and it doesn't have a valid ntor key,
consider it not running.

Refactor these checks so they're consistent between authorities and clients.
parent a76d528b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -7,4 +7,7 @@
      instead, they check specifically for an ntor key.
    - Clients avoid downloading a descriptor if the relay version is
      too old to support ntor.
    - Client code ignores nodes without ntor keys: they will not be
      selected during circuit-building, or as guards, or as directory
      mirrors, or as introduction or rendezvous points.
      Fixes bug 19163; bugfix on 0.2.4.18-rc.
+4 −3
Original line number Diff line number Diff line
@@ -820,8 +820,8 @@ circuit_pick_create_handshake(uint8_t *cell_type_out,

/** Decide whether to use a TAP or ntor handshake for connecting to <b>ei</b>
 * directly, and set *<b>handshake_type_out</b> accordingly. Decide whether,
 * in extending through <b>node</b> to do so, we should use an EXTEND2 or an
 * EXTEND cell to do so, and set *<b>cell_type_out</b> and
 * in extending through <b>node_prev</b> to do so, we should use an EXTEND2 or
 * an EXTEND cell to do so, and set *<b>cell_type_out</b> and
 * *<b>create_cell_type_out</b> accordingly. */
static void
circuit_pick_extend_handshake(uint8_t *cell_type_out,
@@ -837,7 +837,8 @@ circuit_pick_extend_handshake(uint8_t *cell_type_out,
  if (node_prev &&
      *handshake_type_out != ONION_HANDSHAKE_TYPE_TAP &&
      (node_has_curve25519_onion_key(node_prev) ||
       (node_prev->rs && node_prev->rs->version_supports_extend2_cells))) {
       (node_prev->rs &&
        routerstatus_version_supports_ntor(node_prev->rs, 0)))) {
    *cell_type_out = RELAY_COMMAND_EXTEND2;
    *create_cell_type_out = CELL_CREATE2;
  } else {
+1 −3
Original line number Diff line number Diff line
@@ -260,9 +260,7 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg,
   * But just in case a relay doesn't provide or lies about its version, or
   * doesn't include an ntor key in its descriptor, check that it exists,
   * and is non-zero (clients check that it's non-zero before using it). */
  if (router->onion_curve25519_pkey == NULL ||
      tor_mem_is_zero((const char*)router->onion_curve25519_pkey->public_key,
                      CURVE25519_PUBKEY_LEN)) {
  if (!routerinfo_has_curve25519_onion_key(router)) {
    log_fn(severity, LD_DIR,
           "Descriptor from router %s is missing an ntor curve25519 onion "
           "key.", router_describe(router));
+4 −2
Original line number Diff line number Diff line
@@ -2272,8 +2272,10 @@ client_would_use_router(const routerstatus_t *rs, time_t now,
    /* We'd drop it immediately for being too old. */
    return 0;
  }
  if (rs->version_known && !rs->version_supports_extend2_cells) {
    /* We'd ignore it because it doesn't support ntor. */
  if (!routerstatus_version_supports_ntor(rs, 1)) {
    /* We'd ignore it because it doesn't support ntor.
     * If we don't know the version, download the descriptor so we can
     * check if it supports ntor. */
    return 0;
  }
  return 1;
+23 −2
Original line number Diff line number Diff line
@@ -1171,14 +1171,35 @@ node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out)
  }
}

/** Return true iff <b>md</b> has a curve25519 onion key.
 * Use node_has_curve25519_onion_key() instead of calling this directly. */
static int
microdesc_has_curve25519_onion_key(const microdesc_t *md)
{
  if (!md) {
    return 0;
  }

  if (!md->onion_curve25519_pkey) {
    return 0;
  }

  if (tor_mem_is_zero((const char*)md->onion_curve25519_pkey->public_key,
                      CURVE25519_PUBKEY_LEN)) {
    return 0;
  }

  return 1;
}

/** Return true iff <b>node</b> has a curve25519 onion key. */
int
node_has_curve25519_onion_key(const node_t *node)
{
  if (node->ri)
    return node->ri->onion_curve25519_pkey != NULL;
    return routerinfo_has_curve25519_onion_key(node->ri);
  else if (node->md)
    return node->md->onion_curve25519_pkey != NULL;
    return microdesc_has_curve25519_onion_key(node->md);
  else
    return 0;
}
Loading