Commit 2e071322 authored by Nick Mathewson's avatar Nick Mathewson 🦞
Browse files

r13252@catbus: nickm | 2007-06-04 18:57:21 -0400

 Code to check signatures on consensus directories.


svn:r10492
parent 8b0e6a44
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ Things we'd like to do in 0.2.0.x:
        o Code to generate votes
        o Code to generate consensus from a list of votes
        - Add a signature to a consensus.
        - Code to check signatures on a consensus
        o Code to check signatures on a consensus
        - Push/pull documents as appropriate.
        o Have clients know which authorities are v3 authorities, and what
          their keys are.
+62 −0
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
    int j;
    SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
    {
      tor_assert(v->is_vote);
      smartlist_add(va_times, &v->valid_after);
      smartlist_add(fu_times, &v->fresh_until);
      smartlist_add(vu_times, &v->valid_until);
@@ -629,3 +630,64 @@ networkstatus_compute_consensus(smartlist_t *votes,
  return result;
}

/** DOCDOC */
int
networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
{
  int n_good = 0;
  int n_missing_key = 0;
  int n_bad = 0;
  int n_unknown = 0;

  tor_assert(! consensus->is_vote);

  SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, voter,
  {
    trusted_dir_server_t *ds =
      trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
    if (!ds) {
      ++n_unknown;
      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)) {
        ++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);
  });

  /* XXXX020 actually use the result. */

  return 0;
}
+5 −1
Original line number Diff line number Diff line
@@ -1314,7 +1314,8 @@ typedef struct networkstatus_voter_info_t {

  char *pending_signature;
  int pending_signature_len;
  int bad_signature;
  unsigned int bad_signature : 1;
  unsigned int good_signature : 1;
} networkstatus_voter_info_t;

/*XXXX020 rename to networkstatus_t once it works. */
@@ -1336,6 +1337,8 @@ typedef struct networkstatus_vote_t {

  struct authority_cert_t *cert; /* vote only. */

  char networkstatus_digest[DIGEST_LEN];

  smartlist_t *routerstatus_list; /* holds vote_routerstatus_t if is_vote,
                                   * otherwise just routerstatus_t. */
} networkstatus_vote_t;
@@ -2732,6 +2735,7 @@ char *networkstatus_compute_consensus(smartlist_t *votes,
networkstatus_voter_info_t *networkstatus_get_voter_by_id(
                                       networkstatus_vote_t *vote,
                                       const char *identity);
int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus);

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

+2 −0
Original line number Diff line number Diff line
@@ -1801,6 +1801,7 @@ networkstatus_parse_vote_from_string(const char *s, int is_vote)
  }

  ns = tor_malloc_zero(sizeof(networkstatus_vote_t));
  memcpy(ns->networkstatus_digest, ns_digest, DIGEST_LEN);

  if (is_vote) {
    const char *end_of_cert = NULL;
@@ -2036,6 +2037,7 @@ networkstatus_parse_vote_from_string(const char *s, int is_vote)
      if (check_signature_token(ns_digest, tok, ns->cert->signing_key, 0,
                                "network-status vote"))
        goto err;
      v->good_signature = 1;
    } else {
      v->pending_signature = tor_memdup(tok->object_body,
                                        tok->object_size);