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

[or-cvs] r10944: Code to implement detached signature documents. (in tor/trunk: . src/or)



Author: nickm
Date: 2007-07-27 14:33:28 -0400 (Fri, 27 Jul 2007)
New Revision: 10944

Modified:
   tor/trunk/
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerparse.c
Log:
 r13936@catbus:  nickm | 2007-07-27 12:23:26 -0400
 Code to implement detached signature documents.



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

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-07-27 14:41:08 UTC (rev 10943)
+++ tor/trunk/src/or/dirvote.c	2007-07-27 18:33:28 UTC (rev 10944)
@@ -754,32 +754,21 @@
 }
 
 /** DOCDOC */
-int
-networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
-                                       networkstatus_vote_t *src,
-                                       char **new_signatures_out)
+static int
+networkstatus_add_signatures_impl(networkstatus_vote_t *target,
+                                  smartlist_t *src_voter_list,
+                                  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(!target->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,
+  SMARTLIST_FOREACH(src_voter_list, networkstatus_voter_info_t *, src_voter,
     {
       networkstatus_voter_info_t *target_voter =
         networkstatus_get_voter_by_id(target, src_voter->identity_digest);
@@ -793,11 +782,13 @@
       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);
+      /* Try checking the signature if we haven't already. */
+      if (!src_voter->good_signature && !src_voter->bad_signature) {
+        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) {
@@ -824,10 +815,10 @@
       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);
+                   "-----BEGIN SIGNATURE-----\n", ik, sk);
       smartlist_add(sigs, tor_strdup(buf));
       base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
-      strlcat(buf, "-----END SIGNATURE-----", sizeof(buf));
+      strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
       smartlist_add(sigs, tor_strdup(buf));
     });
 
@@ -839,6 +830,116 @@
   return r;
 }
 
+/** DOCDOC */
+int
+networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
+                                       networkstatus_vote_t *src,
+                                       char **new_signatures_out)
+{
+  tor_assert(src);
+  tor_assert(! src->is_vote);
+
+  *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;
+
+  return networkstatus_add_signatures_impl(target, src->voters,
+                                           new_signatures_out);
+}
+
+/** DOCDOC */
+int
+networkstatus_add_detached_signatures(networkstatus_vote_t *target,
+                                      ns_detached_signatures_t *sigs,
+                                      char **new_signatures_out)
+{
+  tor_assert(sigs);
+
+  *new_signatures_out = NULL;
+
+  /* Are they the same consensus? */
+  if (memcmp(target->networkstatus_digest, sigs->networkstatus_digest,
+             DIGEST_LEN))
+    return -1;
+
+  return networkstatus_add_signatures_impl(target, sigs->signatures,
+                                           new_signatures_out);
+}
+
+/** DOCDOC */
+char *
+networkstatus_get_detached_signatures(networkstatus_vote_t *consensus)
+{
+  smartlist_t *elements;
+  char buf[4096];
+  char *result = NULL;
+  tor_assert(consensus);
+  tor_assert(! consensus->is_vote);
+
+  elements = smartlist_create();
+
+  {
+    char va_buf[ISO_TIME_LEN+1], fu_buf[ISO_TIME_LEN+1],
+      vu_buf[ISO_TIME_LEN+1];
+    char d[HEX_DIGEST_LEN+1];
+
+    base16_encode(d, sizeof(d), consensus->networkstatus_digest, DIGEST_LEN);
+    format_iso_time(va_buf, consensus->valid_after);
+    format_iso_time(fu_buf, consensus->fresh_until);
+    format_iso_time(vu_buf, consensus->valid_until);
+
+    tor_snprintf(buf, sizeof(buf),
+                 "consensus-digest %s\n"
+                 "valid-after %s\n"
+                 "fresh-until %s\n"
+                 "valid-until %s\n", d, va_buf, fu_buf, vu_buf);
+    smartlist_add(elements, tor_strdup(buf));
+  }
+
+  SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, v,
+    {
+      char sk[HEX_DIGEST_LEN+1];
+      char id[HEX_DIGEST_LEN+1];
+      if (!v->signature || !v->good_signature)
+        continue;
+      base16_encode(sk, sizeof(sk), v->signing_key_digest, DIGEST_LEN);
+      base16_encode(id, sizeof(id), v->identity_digest, DIGEST_LEN);
+      tor_snprintf(buf, sizeof(buf),
+                   "directory-signature %s %s\n-----BEGIN SIGNATURE-----\n",
+                   id, sk);
+      smartlist_add(elements, tor_strdup(buf));
+      base64_encode(buf, sizeof(buf), v->signature, v->signature_len);
+      strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf));
+      smartlist_add(elements, tor_strdup(buf));
+    });
+
+  result = smartlist_join_strings(elements, "", 0, NULL);
+
+  SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
+  smartlist_free(elements);
+  return result;
+}
+
+/** DOCDOC */
+void
+ns_detached_signatures_free(ns_detached_signatures_t *s)
+{
+  if (s->signatures) {
+    SMARTLIST_FOREACH(s->signatures, networkstatus_voter_info_t *, v,
+      {
+        tor_free(v->signature);
+        tor_free(v);
+      });
+    smartlist_free(s->signatures);
+  }
+  tor_free(s);
+}
+
 /* =====
  * Certificate functions
  * ===== */

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-07-27 14:41:08 UTC (rev 10943)
+++ tor/trunk/src/or/or.h	2007-07-27 18:33:28 UTC (rev 10944)
@@ -1361,6 +1361,16 @@
                                    * otherwise just routerstatus_t. */
 } networkstatus_vote_t;
 
+/* XXXX020 merge with networkstatus_vote_t ?? */
+/** DOCDOC */
+typedef struct ns_detached_signatures_t {
+  time_t valid_after;
+  time_t fresh_until;
+  time_t valid_until;
+  char networkstatus_digest[DIGEST_LEN];
+  smartlist_t *signatures; /* list of networkstatus_voter_info_t */
+} ns_detached_signatures_t;
+
 /** Contents of a directory of onion routers. */
 typedef struct {
   /** Map from server identity digest to a member of routers. */
@@ -2796,6 +2806,11 @@
 int networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
                                            networkstatus_vote_t *src,
                                            char **new_signatures_out);
+int networkstatus_add_detached_signatures(networkstatus_vote_t *target,
+                                          ns_detached_signatures_t *sigs,
+                                          char **new_signatures_out);
+char *networkstatus_get_detached_signatures(networkstatus_vote_t *consensus);
+void ns_detached_signatures_free(ns_detached_signatures_t *s);
 
 /* cert manipulation */
 void authority_cert_free(authority_cert_t *cert);
@@ -3505,6 +3520,8 @@
 networkstatus_t *networkstatus_parse_from_string(const char *s);
 networkstatus_vote_t *networkstatus_parse_vote_from_string(const char *s,
                                                            int is_vote);
+ns_detached_signatures_t *networkstatus_parse_detached_signatures(
+                                          const char *s, const char *eos);
 
 authority_cert_t *authority_cert_parse_from_string(const char *s,
                                                    const char **end_of_string);

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-07-27 14:41:08 UTC (rev 10943)
+++ tor/trunk/src/or/routerparse.c	2007-07-27 18:33:28 UTC (rev 10944)
@@ -340,6 +340,15 @@
   END_OF_TABLE
 };
 
+static token_rule_t networkstatus_detached_signature_token_table[] = {
+  T1_START("consensus-digest", K_CONSENSUS_DIGEST, GE(1),       NO_OBJ ),
+  T1("valid-after",            K_VALID_AFTER,      CONCAT_ARGS, NO_OBJ ),
+  T1("fresh-until",            K_FRESH_UNTIL,      CONCAT_ARGS, NO_OBJ ),
+  T1("valid-until",            K_VALID_UNTIL,      CONCAT_ARGS, NO_OBJ ),
+  T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2),   NEED_OBJ ),
+  END_OF_TABLE
+};
+
 #undef T
 
 /* static function prototypes */
@@ -2058,8 +2067,7 @@
         goto err;
       v->good_signature = 1;
     } else {
-      v->signature = tor_memdup(tok->object_body,
-                                        tok->object_size);
+      v->signature = tor_memdup(tok->object_body, tok->object_size);
       v->signature_len = tok->object_size;
     }
   });
@@ -2095,6 +2103,97 @@
   return ns;
 }
 
+/** DOCDOC */
+ns_detached_signatures_t *
+networkstatus_parse_detached_signatures(const char *s, const char *eos)
+{
+  /* XXXX020 there is too much duplicate code here. */
+  directory_token_t *tok;
+
+  smartlist_t *tokens = smartlist_create();
+  ns_detached_signatures_t *sigs =
+    tor_malloc_zero(sizeof(ns_detached_signatures_t));
+
+  if (!eos)
+    eos = s + strlen(s);
+
+  if (tokenize_string(s, eos, tokens,
+                      networkstatus_detached_signature_token_table)) {
+    log_warn(LD_DIR, "Error tokenizing detached networkstatus signatures");
+    goto err;
+  }
+
+  tok = find_first_by_keyword(tokens, K_CONSENSUS_DIGEST);
+  if (strlen(tok->args[0]) != HEX_DIGEST_LEN)
+    goto err;
+  if (base16_decode(sigs->networkstatus_digest, DIGEST_LEN,
+                    tok->args[0], strlen(tok->args[0])) < 0)
+    goto err;
+
+  tok = find_first_by_keyword(tokens, K_VALID_AFTER);
+  if (parse_iso_time(tok->args[0], &sigs->valid_after))
+    goto err;
+
+  tok = find_first_by_keyword(tokens, K_FRESH_UNTIL);
+  if (parse_iso_time(tok->args[0], &sigs->fresh_until))
+    goto err;
+
+  tok = find_first_by_keyword(tokens, K_VALID_UNTIL);
+  if (parse_iso_time(tok->args[0], &sigs->valid_until))
+    goto err;
+
+  sigs->signatures = smartlist_create();
+  SMARTLIST_FOREACH(tokens, directory_token_t *, _tok,
+    {
+      char id_digest[DIGEST_LEN];
+      char sk_digest[DIGEST_LEN];
+      networkstatus_voter_info_t *voter;
+
+      tok = _tok;
+      if (tok->tp != K_DIRECTORY_SIGNATURE)
+        continue;
+      tor_assert(tok->n_args >= 2);
+
+      if (!tok->object_type ||
+          strcmp(tok->object_type, "SIGNATURE") ||
+          tok->object_size < 128 || tok->object_size > 512) {
+        log_warn(LD_DIR, "Bad object type or length on directory-signature");
+        goto err;
+      }
+
+      if (strlen(tok->args[0]) != HEX_DIGEST_LEN ||
+          base16_decode(id_digest, sizeof(id_digest),
+                        tok->args[0], HEX_DIGEST_LEN) < 0) {
+        log_warn(LD_DIR, "Error decoding declared identity %s in "
+                 "network-status vote.", escaped(tok->args[0]));
+        goto err;
+      }
+      if (strlen(tok->args[1]) != HEX_DIGEST_LEN ||
+          base16_decode(sk_digest, sizeof(sk_digest),
+                        tok->args[1], HEX_DIGEST_LEN) < 0) {
+        log_warn(LD_DIR, "Error decoding declared identity %s in "
+                 "network-status vote.", escaped(tok->args[1]));
+        goto err;
+      }
+
+      voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
+      memcpy(voter->identity_digest, id_digest, DIGEST_LEN);
+      memcpy(voter->signing_key_digest, sk_digest, DIGEST_LEN);
+      voter->signature = tor_memdup(tok->object_body, tok->object_size);
+      voter->signature_len = tok->object_size;
+
+      smartlist_add(sigs->signatures, voter);
+    });
+
+  goto done;
+ err:
+  ns_detached_signatures_free(sigs);
+  sigs = NULL;
+ done:
+  SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
+  return NULL;
+}
+
 /** Parse the addr policy in the string <b>s</b> and return it.  If
  * assume_action is nonnegative, then insert its action (ADDR_POLICY_ACCEPT or
  * ADDR_POLICY_REJECT) for items that specify no action.