Commit 649a8023 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

r13409@catbus: nickm | 2007-06-13 18:01:56 -0400

 Test the remainder of the contents of the consensus; fix a bug in geneating addresses on routerstatuses.


svn:r10597
parent c2ea3e9a
Loading
Loading
Loading
Loading
+38 −27
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
const char dirvote_c_id[] =
  "$Id$";

#define DIRVOTE_PRIVATE
#include "or.h"

/**
@@ -347,9 +348,6 @@ networkstatus_compute_consensus(smartlist_t *votes,
      smartlist_free(lst);
    }

    /* XXXX020 we list any flag that _any_ dirserver lists.  possible
     *  problem.
     */
    smartlist_sort_strings(flags);
    smartlist_uniq_strings(flags);

@@ -537,6 +535,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
      memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
      memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
             DIGEST_LEN);
      rs_out.addr = rs->status.addr;
      rs_out.published_on = rs->status.published_on;
      rs_out.dir_port = rs->status.dir_port;
      rs_out.or_port = rs->status.or_port;
@@ -647,6 +646,37 @@ networkstatus_compute_consensus(smartlist_t *votes,
  return result;
}

/** DOCDOC */
/* private */
int
networkstatus_check_voter_signature(networkstatus_vote_t *consensus,
                                    networkstatus_voter_info_t *voter,
                                    authority_cert_t *cert)
{
  char d[DIGEST_LEN];
  char *signed_digest;
  size_t signed_digest_len;
  /*XXXX020 check return*/
  crypto_pk_get_digest(cert->signing_key, d);
  if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) {
    return -1;
  }
  signed_digest_len = crypto_pk_keysize(cert->signing_key);
  signed_digest = tor_malloc(signed_digest_len);
  if (crypto_pk_public_checksig(cert->signing_key,
                                signed_digest,
                                voter->pending_signature,
                                voter->pending_signature_len) != DIGEST_LEN ||
      memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) {
    log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/
    voter->bad_signature = 1;
  } else {
    voter->good_signature = 1;
  }
  tor_free(voter->pending_signature);
  return 0;
}

/** DOCDOC */
int
networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
@@ -655,6 +685,7 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
  int n_missing_key = 0;
  int n_bad = 0;
  int n_unknown = 0;
  int n_no_signature = 0;

  tor_assert(! consensus->is_vote);

@@ -667,40 +698,20 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
      continue;
    }
    if (voter->pending_signature) {
      char d[DIGEST_LEN];
      char *signed_digest;
      size_t signed_digest_len;
      tor_assert(!voter->good_signature && !voter->bad_signature);
      if (!ds->v3_cert) {
        ++n_missing_key;
        continue;
      }
      /*XXXX020 check return*/
      crypto_pk_get_digest(ds->v3_cert->signing_key, d);
      if (memcmp(voter->signing_key_digest, d, DIGEST_LEN)) {
      if (!ds->v3_cert ||
          networkstatus_check_voter_signature(consensus, voter,
                                              ds->v3_cert) < 0) {
        ++n_missing_key;
        continue;
      }
      signed_digest_len = crypto_pk_keysize(ds->v3_cert->signing_key);
      signed_digest = tor_malloc(signed_digest_len);
      if (crypto_pk_public_checksig(ds->v3_cert->signing_key,
                                signed_digest,
                                voter->pending_signature,
                                voter->pending_signature_len) != DIGEST_LEN ||
          memcmp(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) {
        log_warn(LD_DIR, "Got a bad signature."); /*XXXX020 say more*/
        voter->bad_signature = 1;
      } else {
        voter->good_signature = 1;
      }
      tor_free(voter->pending_signature);
    }
    if (voter->good_signature)
      ++n_good;
    else if (voter->bad_signature)
      ++n_bad;
    else
      tor_assert(0);
      ++n_no_signature;
  });

  /* XXXX020 actually use the result. */
+6 −0
Original line number Diff line number Diff line
@@ -2768,6 +2768,12 @@ int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus);
void authority_cert_free(authority_cert_t *cert);
authority_cert_t *authority_cert_dup(authority_cert_t *cert);

#ifdef DIRVOTE_PRIVATE
int networkstatus_check_voter_signature(networkstatus_vote_t *consensus,
                                        networkstatus_voter_info_t *voter,
                                        authority_cert_t *cert);
#endif

/********************************* dns.c ***************************/

int dns_init(void);
+68 −8
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ const char tor_svn_revision[] = "";
#define CONTROL_PRIVATE
#define CRYPTO_PRIVATE
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
#define MEMPOOL_PRIVATE
#define ROUTER_PRIVATE

@@ -2296,7 +2297,7 @@ test_v3_networkstatus(void)
             "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
             DIGEST_LEN);
  test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
  test_eq(rs->addr, 0x099008801);
  test_eq(rs->addr, 0x99008801);
  test_eq(rs->or_port, 443);
  test_eq(rs->dir_port, 8000);
  test_eq(vrs->flags, U64_LITERAL(0));
@@ -2310,7 +2311,7 @@ test_v3_networkstatus(void)
             "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
             DIGEST_LEN);
  test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
  test_eq(rs->addr, 0x099009901);
  test_eq(rs->addr, 0x99009901);
  test_eq(rs->or_port, 443);
  test_eq(rs->dir_port, 0);
  test_eq(vrs->flags, U64_LITERAL(254)); // all flags except "authority."
@@ -2338,7 +2339,8 @@ test_v3_networkstatus(void)
  smartlist_del_keeporder(vote->routerstatus_list, 2);
  tor_free(vrs->version);
  tor_free(vrs);
  /* XXXX020 set some flags in router0 */
  vrs = smartlist_get(vote->routerstatus_list, 0);
  vrs->status.is_fast = 1;
  /* generate and parse. */
  v2_text = format_networkstatus_vote(sign_skey_2, vote);
  test_assert(v2_text);
@@ -2372,7 +2374,9 @@ test_v3_networkstatus(void)
  smartlist_del_keeporder(vote->routerstatus_list, 0);
  tor_free(vrs->version);
  tor_free(vrs);
  /* XXXX020 clear some flags in the remaining entry. */
  vrs = smartlist_get(vote->routerstatus_list, 0);
  memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);

  v3_text = format_networkstatus_vote(sign_skey_3, vote);
  test_assert(v3_text);
  v3 = networkstatus_parse_vote_from_string(v3_text, 1);
@@ -2388,7 +2392,8 @@ test_v3_networkstatus(void)
  test_assert(consensus_text);
  con = networkstatus_parse_vote_from_string(consensus_text, 0);
  test_assert(con);
  // log_notice(LD_GENERAL, "<<%s>>", consensus_text);
  log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
             v1_text, v2_text, v3_text);

  /* Check consensus contents. */
  test_assert(!con->is_vote);
@@ -2419,9 +2424,64 @@ test_v3_networkstatus(void)

  test_assert(!con->cert);
  test_eq(2, smartlist_len(con->routerstatus_list));
  /* XXXX020 test routerstatus_list contents */

  /* XXXX020 Check signatures */
  /* There should be two listed routers: one with identity 3, one with
   * identity 5. */
  /* This one showed up in 2 digests. */
  rs = smartlist_get(con->routerstatus_list, 0);
  test_memeq(rs->identity_digest,
             "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
             DIGEST_LEN);
  test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
  test_assert(!rs->is_authority);
  test_assert(!rs->is_exit);
  test_assert(!rs->is_fast);
  test_assert(!rs->is_possible_guard);
  test_assert(!rs->is_stable);
  test_assert(!rs->is_running);
  test_assert(!rs->is_v2_dir);
  test_assert(!rs->is_valid);
  test_assert(!rs->is_named);
  /* XXXX020 check version */

  rs = smartlist_get(con->routerstatus_list, 1);
  /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'.  */
  test_memeq(rs->identity_digest,
             "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
             DIGEST_LEN);
  test_streq(rs->nickname, "router1");
  test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
  test_eq(rs->published_on, now-1000);
  test_eq(rs->addr, 0x99009901);
  test_eq(rs->or_port, 443);
  test_eq(rs->dir_port, 0);
  test_assert(!rs->is_authority);
  test_assert(rs->is_exit);
  test_assert(rs->is_fast);
  test_assert(rs->is_possible_guard);
  test_assert(rs->is_stable);
  test_assert(rs->is_running);
  test_assert(rs->is_v2_dir);
  test_assert(rs->is_valid);
  test_assert(!rs->is_named);
  /* XXXX020 check version */

  /* Check signatures.  the first voter hasn't got one.  The second one
   * does: validate it. */
  voter = smartlist_get(con->voters, 0);
  test_assert(!voter->pending_signature);
  test_assert(!voter->good_signature);
  test_assert(!voter->bad_signature);

  voter = smartlist_get(con->voters, 1);
  test_assert(voter->pending_signature);
  test_assert(!voter->good_signature);
  test_assert(!voter->bad_signature);
  test_assert(!networkstatus_check_voter_signature(con,
                                               smartlist_get(con->voters, 1),
                                               cert3));
  test_assert(!voter->pending_signature);
  test_assert(voter->good_signature);
  test_assert(!voter->bad_signature);

  /* XXXX020 frob with detached signatures */