summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-06-13 22:39:08 +0000
committerNick Mathewson <nickm@torproject.org>2007-06-13 22:39:08 +0000
commit649a80232283155f568f1e05464ffbf2b20647bd (patch)
tree94c29a200a2399cba0b06f927a77946dc500a154 /src
parentc2ea3e9aea5aa852c6778039ef107548f04c4cfc (diff)
downloadtor-649a80232283155f568f1e05464ffbf2b20647bd.tar.gz
tor-649a80232283155f568f1e05464ffbf2b20647bd.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/or/dirvote.c65
-rw-r--r--src/or/or.h6
-rw-r--r--src/or/test.c76
3 files changed, 112 insertions, 35 deletions
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index d2950551f0..a061d53219 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -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;
@@ -648,6 +647,37 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/** 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. */
diff --git a/src/or/or.h b/src/or/or.h
index f2fe563b5b..dd3106f7f9 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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);
diff --git a/src/or/test.c b/src/or/test.c
index 8aeb91070c..d65a230b66 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -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 */