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

[or-cvs] r10936: Code to add signatures to a pending consensus directory. (in tor/trunk: . src/or)



Author: nickm
Date: 2007-07-26 16:26:59 -0400 (Thu, 26 Jul 2007)
New Revision: 10936

Modified:
   tor/trunk/
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
   tor/trunk/src/or/routerparse.c
   tor/trunk/src/or/test.c
Log:
 r13921@catbus:  nickm | 2007-07-26 16:26:48 -0400
 Code to add signatures to a pending consensus directory.



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

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-07-26 20:26:53 UTC (rev 10935)
+++ tor/trunk/src/or/dirvote.c	2007-07-26 20:26:59 UTC (rev 10936)
@@ -698,15 +698,17 @@
   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 ||
+                                voter->signature,
+                                voter->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);
+  /* XXXX020 did anything rely on this?
+   * also, rename so it's no longer called "pending". */
+  // tor_free(voter->signature);
   return 0;
 }
 
@@ -730,7 +732,7 @@
       ++n_unknown;
       continue;
     }
-    if (voter->pending_signature) {
+    if (voter->signature) {
       tor_assert(!voter->good_signature && !voter->bad_signature);
       if (!ds->v3_cert ||
           networkstatus_check_voter_signature(consensus, voter,
@@ -752,6 +754,93 @@
   return 0;
 }
 
+/** DOCDOC */
+int
+networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
+                                       networkstatus_vote_t *src,
+                                       char **new_signatures_out)
+{
+  smartlist_t *added_signatures, *sigs;
+  int r;
+  tor_assert(target);
+  tor_assert(src);
+  tor_assert(! target->is_vote);
+  tor_assert(! src->is_vote);
+  tor_assert(new_signatures_out);
+
+  *new_signatures_out = NULL;
+
+  /* Are they the same consensus? */
+  if (memcmp(target->networkstatus_digest, src->networkstatus_digest,
+             DIGEST_LEN))
+    return -1;
+  if (target == src)
+    return 0;
+
+  added_signatures = smartlist_create();
+
+  /* For each voter in src... */
+  SMARTLIST_FOREACH(src->voters, networkstatus_voter_info_t *, src_voter,
+    {
+      networkstatus_voter_info_t *target_voter =
+        networkstatus_get_voter_by_id(target, src_voter->identity_digest);
+      authority_cert_t *cert;
+      /* If the target a doesn't know about this voter, then forget it. */
+      if (!target_voter)
+        continue;
+
+      /* If the target already has a good signature from this voter, then skip
+       * this one. */
+      if (target_voter->good_signature)
+        continue;
+
+      /* If this signature is no good, then skip. */
+      cert = authority_cert_get_by_digests(src_voter->identity_digest,
+                                           src_voter->signing_key_digest);
+      if (cert) {
+        networkstatus_check_voter_signature(target, src_voter, cert);
+      }
+      /* If this signature is good, then replace and add. */
+      if (src_voter->good_signature || !target_voter->signature) {
+        tor_free(target_voter->signature);
+        target_voter->signature =
+          tor_memdup(src_voter->signature, src_voter->signature_len);
+        memcpy(target_voter->signing_key_digest, src_voter->signing_key_digest,
+               DIGEST_LEN);
+        target_voter->signature_len = src_voter->signature_len;
+        target_voter->good_signature = 1;
+        target_voter->bad_signature = 0;
+        smartlist_add(added_signatures, target_voter);
+      }
+    });
+
+  sigs = smartlist_create();
+  SMARTLIST_FOREACH(added_signatures, networkstatus_voter_info_t *, v,
+    {
+      char buf[4096];
+      char sk[HEX_DIGEST_LEN+1];
+      char ik[HEX_DIGEST_LEN+1];
+      tor_assert(v->signature);
+
+      base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
+      base16_encode(ik, sizeof(ik), v->identity_digest, DIGEST_LEN);
+      tor_snprintf(buf, sizeof(buf), "directory-signature %s %s\n"
+                   "-----BEGIN SIGNATURE-----", ik, sk);
+      smartlist_add(sigs, tor_strdup(buf));
+      base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
+      strlcat(buf, "-----END SIGNATURE-----", sizeof(buf));
+      smartlist_add(sigs, tor_strdup(buf));
+    });
+
+  *new_signatures_out = smartlist_join_strings(sigs, "", 0, NULL);
+  SMARTLIST_FOREACH(sigs, char *, cp, tor_free(cp));
+  smartlist_free(sigs);
+  r = smartlist_len(added_signatures);
+  smartlist_free(added_signatures);
+  return r;
+}
+
+
 /* =====
  * Certificate functions
  * ===== */
@@ -876,6 +965,8 @@
 static smartlist_t *pending_vote_list = NULL;
 /** DOCDOC */
 static char *pending_consensus_body = NULL;
+/** DOCDOC */
+static networkstatus_vote_t *pending_consensus = NULL;
 
 /** DOCDOC */
 void
@@ -988,6 +1079,7 @@
   int n_votes, n_voters;
   smartlist_t *votes = NULL;
   char *consensus_body = NULL;
+  networkstatus_vote_t *consensus = NULL;
   authority_cert_t *my_cert;
 
   if (!pending_vote_list)
@@ -1011,13 +1103,26 @@
         my_cert->identity_key,
         get_my_v3_authority_signing_key());
 
+  consensus = networkstatus_parse_vote_from_string(consensus_body, 0);
+  if (!consensus) {
+    log_warn(LD_DIR, "Couldn't parse consensus we generated!");
+    goto err;
+  }
+
   tor_free(pending_consensus_body);
   pending_consensus_body = consensus_body;
 
+  if (pending_consensus)
+    networkstatus_vote_free(pending_consensus);
+  pending_consensus = consensus;
+
   return 0;
  err:
   if (votes)
     smartlist_free(votes);
+  tor_free(consensus_body);
+  networkstatus_vote_free(consensus);
+
   return -1;
 }
 

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-07-26 20:26:53 UTC (rev 10935)
+++ tor/trunk/src/or/or.h	2007-07-26 20:26:59 UTC (rev 10936)
@@ -1330,8 +1330,8 @@
   char vote_digest[DIGEST_LEN];
   char signing_key_digest[DIGEST_LEN]; /* This part is _not_ signed. */
 
-  char *pending_signature;
-  int pending_signature_len;
+  char *signature;
+  int signature_len;
   unsigned int bad_signature : 1;
   unsigned int good_signature : 1;
 } networkstatus_voter_info_t;
@@ -2792,6 +2792,9 @@
                                        networkstatus_vote_t *vote,
                                        const char *identity);
 int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus);
+int networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
+                                           networkstatus_vote_t *src,
+                                           char **new_signatures_out);
 
 /* cert manipulation */
 void authority_cert_free(authority_cert_t *cert);
@@ -3272,6 +3275,7 @@
   /** What kind of authority is this? (Bitfield.) */
   authority_type_t type;
 
+  /* XXXX020 this should be a list. */
   authority_cert_t *v3_cert; /**< V3 key certificate for this authority */
 
   int n_networkstatus_failures; /**< How many times have we asked for this
@@ -3299,6 +3303,8 @@
      const char *digest);
 trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(
      const char *digest);
+authority_cert_t *authority_cert_get_by_digests(const char *id_digest,
+                                                const char *sk_digest);
 void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
 void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
                                     int must_be_running);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-07-26 20:26:53 UTC (rev 10935)
+++ tor/trunk/src/or/routerlist.c	2007-07-26 20:26:59 UTC (rev 10936)
@@ -266,6 +266,23 @@
   trusted_dir_servers_certs_changed = 0;
 }
 
+/** DOCDOC */
+authority_cert_t *
+authority_cert_get_by_digests(const char *id_digest,
+                              const char *sk_digest)
+{
+  char d[DIGEST_LEN];
+  trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest);
+
+  if (!ds || !ds->v3_cert)
+    return NULL;
+  crypto_pk_get_digest(ds->v3_cert->signing_key, d);
+  if (memcmp(d, sk_digest, DIGEST_LEN))
+    return NULL;
+
+  return ds->v3_cert;
+}
+
 /* Router descriptor storage.
  *
  * Routerdescs are stored in a big file, named "cached-routers".  As new

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-07-26 20:26:53 UTC (rev 10935)
+++ tor/trunk/src/or/routerparse.c	2007-07-26 20:26:59 UTC (rev 10936)
@@ -2046,9 +2046,9 @@
         goto err;
       v->good_signature = 1;
     } else {
-      v->pending_signature = tor_memdup(tok->object_body,
+      v->signature = tor_memdup(tok->object_body,
                                         tok->object_size);
-      v->pending_signature_len = tok->object_size;
+      v->signature_len = tok->object_size;
     }
   });
   /* XXXX020 enforce: vote must have at least one signature. */

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2007-07-26 20:26:53 UTC (rev 10935)
+++ tor/trunk/src/or/test.c	2007-07-26 20:26:59 UTC (rev 10936)
@@ -2672,18 +2672,18 @@
   /* 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->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->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->signature);
   test_assert(voter->good_signature);
   test_assert(!voter->bad_signature);