aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-06-04 22:57:23 +0000
committerNick Mathewson <nickm@torproject.org>2007-06-04 22:57:23 +0000
commit2e0713222b3c0049d930aff52c86dd646d424c83 (patch)
tree13e56e0bb9c2ad33dcc4212dff442ed844b12068
parent8b0e6a446697ad3d15a1fe23a8c5c3ed53a60c70 (diff)
downloadtor-2e0713222b3c0049d930aff52c86dd646d424c83.tar
tor-2e0713222b3c0049d930aff52c86dd646d424c83.tar.gz
r13252@catbus: nickm | 2007-06-04 18:57:21 -0400
Code to check signatures on consensus directories. svn:r10492
-rw-r--r--doc/TODO2
-rw-r--r--src/or/dirvote.c62
-rw-r--r--src/or/or.h6
-rw-r--r--src/or/routerparse.c2
4 files changed, 70 insertions, 2 deletions
diff --git a/doc/TODO b/doc/TODO
index f5130aeb0..08d6e04f1 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -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.
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index ea6e8b1f0..bfdafbd51 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -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;
+}
+
diff --git a/src/or/or.h b/src/or/or.h
index cfb6fb7d2..304352be4 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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 ***************************/
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 2eee814d2..47015e531 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -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);