[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r10597: Test the remainder of the contents of the consensus; fix a b (in tor/trunk: . src/or)



Author: nickm
Date: 2007-06-13 18:39:08 -0400 (Wed, 13 Jun 2007)
New Revision: 10597

Modified:
   tor/trunk/
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/test.c
Log:
 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.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r13409] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-06-13 21:05:32 UTC (rev 10596)
+++ tor/trunk/src/or/dirvote.c	2007-06-13 22:39:08 UTC (rev 10597)
@@ -5,6 +5,7 @@
 const char dirvote_c_id[] =
   "$Id$";
 
+#define DIRVOTE_PRIVATE
 #include "or.h"
 
 /**
@@ -347,9 +348,6 @@
       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 @@
       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;
@@ -648,13 +647,45 @@
 }
 
 /** 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)
 {
   int n_good = 0;
   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 @@
       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) {
+      if (!ds->v3_cert ||
+          networkstatus_check_voter_signature(consensus, voter,
+                                              ds->v3_cert) < 0) {
         ++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);
+      ++n_no_signature;
   });
 
   /* XXXX020 actually use the result. */

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-06-13 21:05:32 UTC (rev 10596)
+++ tor/trunk/src/or/or.h	2007-06-13 22:39:08 UTC (rev 10597)
@@ -2768,6 +2768,12 @@
 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);

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2007-06-13 21:05:32 UTC (rev 10596)
+++ tor/trunk/src/or/test.c	2007-06-13 22:39:08 UTC (rev 10597)
@@ -31,6 +31,7 @@
 #define CONTROL_PRIVATE
 #define CRYPTO_PRIVATE
 #define DIRSERV_PRIVATE
+#define DIRVOTE_PRIVATE
 #define MEMPOOL_PRIVATE
 #define ROUTER_PRIVATE
 
@@ -2296,7 +2297,7 @@
              "\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 @@
              "\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 @@
   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 @@
   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_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,10 +2424,65 @@
 
   test_assert(!con->cert);
   test_eq(2, smartlist_len(con->routerstatus_list));
-  /* XXXX020 test routerstatus_list contents */
+  /* 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 */
 
-  /* XXXX020 Check signatures */
+  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 */
 
   smartlist_free(votes);