Commit e86893e8 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Move to new base64 digest functions. Switch to new router digest calculation....

Move to new base64 digest functions.  Switch to new router digest calculation. Make sure there are no duplicates in router status lists.


svn:r5088
parent f8a80e8d
Loading
Loading
Loading
Loading
+4 −15
Original line number Diff line number Diff line
@@ -1124,7 +1124,6 @@ static cached_dir_t the_v2_networkstatus = { NULL, NULL, 0, 0, 0 };
static int
generate_v2_networkstatus(void)
{
#define BASE64_DIGEST_LEN 27
#define LONGEST_STATUS_FLAG_NAME_LEN 7
#define N_STATUS_FLAGS 6
#define RS_ENTRY_LEN                                                    \
@@ -1216,8 +1215,8 @@ generate_v2_networkstatus(void)
      int f_running;
      int f_named = naming && ri->is_named;
      int f_valid = ri->is_verified;
      char identity64[128];
      char digest64[128];
      char identity64[BASE64_DIGEST_LEN+1];
      char digest64[BASE64_DIGEST_LEN+1];

      if (options->AuthoritativeDir) {
        ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
@@ -1226,18 +1225,8 @@ generate_v2_networkstatus(void)

      format_iso_time(published, ri->published_on);

      if (base64_encode(identity64, sizeof(identity64),
                        ri->identity_digest, DIGEST_LEN)<0) {
        log_fn(LOG_WARN, "Unable to encode router identity digest.");
        goto done;
      }
      if (base64_encode(digest64, sizeof(digest64),
                        ri->signed_descriptor_digest, DIGEST_LEN)<0) {
        log_fn(LOG_WARN, "Unable to encode router descriptor digest.");
        goto done;
      }
      identity64[BASE64_DIGEST_LEN] = '\0';
      digest64[BASE64_DIGEST_LEN] = '\0';
      digest_to_base64(identity64, ri->identity_digest);
      digest_to_base64(digest64, ri->signed_descriptor_digest);

      in.s_addr = htonl(ri->addr);
      tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
+22 −25
Original line number Diff line number Diff line
@@ -748,7 +748,7 @@ router_parse_entry_from_string(const char *s, const char *end)
  router = tor_malloc_zero(sizeof(routerinfo_t));
  router->signed_descriptor = tor_strndup(s, end-s);
  router->signed_descriptor_len = end-s;
  crypto_digest(router->signed_descriptor_digest, s, end-s);
  memcpy(router->signed_descriptor_digest, digest, DIGEST_LEN);
  ports_set = bw_set = 0;

  if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
@@ -957,12 +957,9 @@ find_start_of_next_routerstatus(const char *s)
static routerstatus_t *
routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
{
#define BASE64_DIGEST_LEN 27
  const char *eos;
  routerstatus_t *rs = NULL;
  directory_token_t *tok;
  char base64buf_in[BASE64_DIGEST_LEN+3];
  char base64buf_out[256];
  char timebuf[ISO_TIME_LEN+1];
  struct in_addr in;

@@ -1000,33 +997,15 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
  }
  strlcpy(rs->nickname, tok->args[0], sizeof(rs->nickname));

  if (strlen(tok->args[1]) != BASE64_DIGEST_LEN) {
    log_fn(LOG_WARN, "Digest '%s' is wrong length in router status; skipping.",
           tok->args[1]);
    goto err;
  }
  memcpy(base64buf_in, tok->args[1], BASE64_DIGEST_LEN);
  memcpy(base64buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
  if (base64_decode(base64buf_out, sizeof(base64buf_out),
                    base64buf_in, sizeof(base64buf_in)-1) != DIGEST_LEN) {
  if (digest_from_base64(rs->identity_digest, tok->args[1])) {
    log_fn(LOG_WARN, "Error decoding digest '%s'", tok->args[1]);
    goto err;
  }
  memcpy(rs->identity_digest, base64buf_out, DIGEST_LEN);

  if (strlen(tok->args[2]) != BASE64_DIGEST_LEN) {
    log_fn(LOG_WARN, "Digest '%s' is wrong length in router status; skipping.",
           tok->args[2]);
    goto err;
  }
  memcpy(base64buf_in, tok->args[2], BASE64_DIGEST_LEN);
  memcpy(base64buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
  if (base64_decode(base64buf_out, sizeof(base64buf_out),
                    base64buf_in, sizeof(base64buf_in)-1) != DIGEST_LEN) {
  if (digest_from_base64(rs->descriptor_digest, tok->args[2])) {
    log_fn(LOG_WARN, "Error decoding digest '%s'", tok->args[2]);
    goto err;
  }
  memcpy(rs->descriptor_digest, base64buf_out, DIGEST_LEN);

  if (tor_snprintf(timebuf, sizeof(timebuf), "%s %s",
                   tok->args[3], tok->args[4]) < 0 ||
@@ -1083,6 +1062,12 @@ _compare_routerstatus_entries(const void **_a, const void **_b)
  return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
}

void
sort_routerstatus_entries(smartlist_t *sl)
{
  smartlist_sort(sl, _compare_routerstatus_entries);
}

/** Given a versioned (v2 or later) network-status object in <b>s</b>, try to
 * parse it and return the result.  Return NULL on failure.  Check the
 * signature of the network status, but do not (yet) check the signing key for
@@ -1098,6 +1083,7 @@ networkstatus_parse_from_string(const char *s)
  char tmp_digest[DIGEST_LEN];
  struct in_addr in;
  directory_token_t *tok;
  int i;

  if (router_get_networkstatus_v2_hash(s, ns_digest)) {
    log_fn(LOG_WARN, "Unable to compute digest of network-status");
@@ -1209,7 +1195,6 @@ networkstatus_parse_from_string(const char *s)
  }

  if ((tok = find_first_by_keyword(tokens, K_DIR_OPTIONS))) {
    int i;
    for (i=0; i < tok->n_args; ++i) {
      if (!strcmp(tok->args[i], "Names"))
        ns->binds_names = 1;
@@ -1227,6 +1212,18 @@ networkstatus_parse_from_string(const char *s)
  }
  smartlist_sort(ns->entries, _compare_routerstatus_entries);

  /* Kill duplicate entries. */
  for (i=0; i < smartlist_len(ns->entries)-1; ++i) {
    routerstatus_t *rs1 = smartlist_get(ns->entries, i);
    routerstatus_t *rs2 = smartlist_get(ns->entries, i+1);
    if (!memcmp(rs1->identity_digest,
                rs2->identity_digest, DIGEST_LEN)) {
      log_fn(LOG_WARN, "Network-status has two entries for the same router. Dropping one.");
      smartlist_del_keeporder(ns->entries, i--);
      routerstatus_free(rs1);
    }
  }

  if (tokenize_string(s, NULL, tokens, NETSTATUS)) {
    log_fn(LOG_WARN, "Error tokenizing network-status footer.");
    goto err;
+10 −0
Original line number Diff line number Diff line
@@ -511,6 +511,16 @@ test_crypto(void)
  test_eq(j, 71);
  test_assert(data2[i] == '\0');

  crypto_rand(data1, DIGEST_LEN);
  memset(data2, 100, 1024);
  digest_to_base64(data2, data1);
  test_eq(BASE64_DIGEST_LEN, strlen(data2));
  test_eq(100, data2[BASE64_DIGEST_LEN+2]);
  memset(data3, 99, 1024);
  digest_from_base64(data3, data2);
  test_memeq(data1, data3, DIGEST_LEN);
  test_eq(99, data3[DIGEST_LEN+1]);

  /* Base32 tests */
  strcpy(data1, "5chrs");
  /* bit pattern is:  [35 63 68 72 73] ->