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

[or-cvs] r10937: We can have multiple authority certificates for an authority (in tor/trunk: . src/or)



Author: nickm
Date: 2007-07-26 16:49:04 -0400 (Thu, 26 Jul 2007)
New Revision: 10937

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
Log:
 r13924@catbus:  nickm | 2007-07-26 16:46:45 -0400
 We can have multiple authority certificates for an authority at a time: make the code reflect that.



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

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-07-26 20:26:59 UTC (rev 10936)
+++ tor/trunk/src/or/dirvote.c	2007-07-26 20:49:04 UTC (rev 10937)
@@ -726,20 +726,19 @@
 
   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->signature) {
-      tor_assert(!voter->good_signature && !voter->bad_signature);
-      if (!ds->v3_cert ||
-          networkstatus_check_voter_signature(consensus, voter,
-                                              ds->v3_cert) < 0) {
-        ++n_missing_key;
+    if (!voter->good_signature && !voter->bad_signature && voter->signature) {
+      /* we can try to check the signature. */
+      authority_cert_t *cert =
+        authority_cert_get_by_digests(voter->identity_digest,
+                                      voter->signing_key_digest);
+      if (! cert) {
+        ++n_unknown;
         continue;
       }
+      if (networkstatus_check_voter_signature(consensus, voter, cert) < 0) {
+        ++n_missing_key; /* XXXX020 what, really? */
+        continue;
+      }
     }
     if (voter->good_signature)
       ++n_good;
@@ -840,7 +839,6 @@
   return r;
 }
 
-
 /* =====
  * Certificate functions
  * ===== */

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-07-26 20:26:59 UTC (rev 10936)
+++ tor/trunk/src/or/or.h	2007-07-26 20:49:04 UTC (rev 10937)
@@ -1408,6 +1408,7 @@
   signed_descriptor_t cache_info;
   crypto_pk_env_t *identity_key;
   crypto_pk_env_t *signing_key;
+  char signing_key_digest[DIGEST_LEN];
   time_t expires;
 } authority_cert_t;
 
@@ -3275,8 +3276,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 */
+  smartlist_t *v3_certs; /**< V3 key certificates for this authority */
 
   int n_networkstatus_failures; /**< How many times have we asked for this
                                  * server's network-status unsuccessfully? */

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-07-26 20:26:59 UTC (rev 10936)
+++ tor/trunk/src/or/routerlist.c	2007-07-26 20:49:04 UTC (rev 10937)
@@ -207,6 +207,7 @@
 
   for (s = contents; *s; s = eos) {
     authority_cert_t *cert = authority_cert_parse_from_string(s, &eos);
+    int found;
     if (!cert)
       break;
     ds = trusteddirserver_get_by_v3_auth_digest(
@@ -217,22 +218,28 @@
       authority_cert_free(cert);
       continue;
     }
+    if (!ds->v3_certs)
+      ds->v3_certs = smartlist_create();
 
-    if (ds->v3_cert) {
-      if (ds->v3_cert->expires < cert->expires) {
-        authority_cert_free(ds->v3_cert);
-        ds->v3_cert = NULL; /* redundant, but let's be safe. */
-      } else {
-        /* This also covers the case where the certificate is the same
-         * as the one we have. */
-        authority_cert_free(cert);
-        continue;
-      }
-    }
+    SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c,
+      {
+        if (memcmp(c->cache_info.signed_descriptor_digest,
+                   cert->cache_info.signed_descriptor_digest,
+                   DIGEST_LEN)) {
+          /* we already have this one. continue. */
+          authority_cert_free(cert);
+          found = 1;
+          break;
+        }
+      });
 
+    if (found)
+      continue;
+
     cert->cache_info.signed_descriptor_body = tor_strndup(s, eos-s);
     cert->cache_info.signed_descriptor_len = eos-s;
-    ds->v3_cert = cert;
+    smartlist_add(ds->v3_certs, cert);
+
     if (!from_store)
       trusted_dir_servers_certs_changed = 1;
   }
@@ -250,11 +257,14 @@
                get_options()->DataDirectory);
   SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
   {
-      if (ds->v3_cert) {
-        sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
-        c->bytes = ds->v3_cert->cache_info.signed_descriptor_body;
-        c->len = ds->v3_cert->cache_info.signed_descriptor_len;
-        smartlist_add(chunks, c);
+      if (ds->v3_certs) {
+        SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
+          {
+            sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
+            c->bytes = cert->cache_info.signed_descriptor_body;
+            c->len = cert->cache_info.signed_descriptor_len;
+            smartlist_add(chunks, c);
+          });
       }
   });
   if (write_chunks_to_file(filename, chunks, 0)) {
@@ -271,16 +281,15 @@
 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)
+  if (!ds || !ds->v3_certs)
     return NULL;
-  crypto_pk_get_digest(ds->v3_cert->signing_key, d);
-  if (memcmp(d, sk_digest, DIGEST_LEN))
-    return NULL;
+  SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
+    if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN))
+      return cert; );
 
-  return ds->v3_cert;
+  return NULL;
 }
 
 /* Router descriptor storage.
@@ -3705,8 +3714,11 @@
 static void
 trusted_dir_server_free(trusted_dir_server_t *ds)
 {
-  if (ds->v3_cert)
-    authority_cert_free(ds->v3_cert);
+  if (ds->v3_certs) {
+    SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
+                      authority_cert_free(cert));
+    smartlist_free(ds->v3_certs);
+  }
   tor_free(ds->nickname);
   tor_free(ds->description);
   tor_free(ds->address);

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-07-26 20:26:59 UTC (rev 10936)
+++ tor/trunk/src/or/routerparse.c	2007-07-26 20:49:04 UTC (rev 10937)
@@ -1306,6 +1306,7 @@
   char *eos;
   size_t len;
   trusted_dir_server_t *ds;
+  int found;
 
   s = eat_whitespace(s);
   eos = strstr(s, "\n-----END SIGNATURE-----\n");
@@ -1340,6 +1341,8 @@
   tor_assert(tok && tok->key);
   cert->signing_key = tok->key;
   tok->key = NULL;
+  if (crypto_pk_get_digest(cert->signing_key, cert->signing_key_digest))
+    goto err;
 
   tok = find_first_by_keyword(tokens, K_DIR_IDENTITY_KEY);
   tor_assert(tok && tok->key);
@@ -1385,13 +1388,22 @@
   /* If we already have this cert, don't bother checking the signature. */
   ds = trusteddirserver_get_by_v3_auth_digest(
                                      cert->cache_info.identity_digest);
-  if (ds && ds->v3_cert &&
-      ds->v3_cert->cache_info.signed_descriptor_len == len &&
-      ds->v3_cert->cache_info.signed_descriptor_body &&
-      ! memcmp(s, ds->v3_cert->cache_info.signed_descriptor_body, len)) {
-    log_debug(LD_DIR, "We already checked the signature on this certificate;"
-              " no need to do so again.");
-  } else {
+  found = 0;
+  if (ds && ds->v3_certs) {
+    SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c,
+      {
+        /* XXXX020 can we just compare signed_descriptor_digest ? */
+        if (c->cache_info.signed_descriptor_len == len &&
+            c->cache_info.signed_descriptor_body &&
+            !memcmp(s, c->cache_info.signed_descriptor_body, len)) {
+          log_debug(LD_DIR, "We already checked the signature on this "
+                    "certificate; no need to do so again.");
+          found = 1;
+          break;
+        }
+      });
+  }
+  if (!found) {
     if (check_signature_token(digest, tok, cert->identity_key, 0,
                               "key certificate")) {
       goto err;