[or-cvs] r10587: Unit tests and debugging for vote generation and parsing cod (in tor/trunk: . src/or)

nickm at seul.org nickm at seul.org
Wed Jun 13 18:16:05 UTC 2007


Author: nickm
Date: 2007-06-13 14:16:05 -0400 (Wed, 13 Jun 2007)
New Revision: 10587

Modified:
   tor/trunk/
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerparse.c
   tor/trunk/src/or/test.c
Log:
 r13387 at catbus:  nickm | 2007-06-13 14:15:49 -0400
 Unit tests and debugging for vote generation and parsing code.



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

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2007-06-13 18:16:01 UTC (rev 10586)
+++ tor/trunk/src/or/dirserv.c	2007-06-13 18:16:05 UTC (rev 10587)
@@ -5,6 +5,7 @@
 const char dirserv_c_id[] =
   "$Id$";
 
+#define DIRSERV_PRIVATE
 #include "or.h"
 
 /**
@@ -1592,7 +1593,6 @@
   return NULL;
 }
 
-
 /** Helper: write the router-status information in <b>rs</b> into <b>buf</b>,
  * which has at least <b>buf_len</b> free characters.  Do NUL-termination.
  * Use the same format as in network-status documents.  If <b>platform</b> is
@@ -1827,7 +1827,7 @@
   v3_out->server_versions = server_versions;
   v3_out->known_flags = smartlist_create();
   smartlist_split_string(v3_out->known_flags,
-                "Authority Exit Fast Guard Running Stable Valid V2Dir",
+                "Authority Exit Fast Guard Running Stable V2Dir Valid",
                 0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
   if (listbadexits)
     smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
@@ -1853,8 +1853,9 @@
   return v3_out;
 }
 
-static char *
-format_networkstatus_vote(crypto_pk_env_t *private_key,
+/* private DOCDOC */
+char *
+format_networkstatus_vote(crypto_pk_env_t *private_signing_key,
                           networkstatus_vote_t *v3_ns)
 {
 /** Longest status flag name that we generate. */
@@ -1890,7 +1891,7 @@
   networkstatus_voter_info_t *voter;
   /* XXX check that everything gets freed */
 
-  tor_assert(private_key);
+  tor_assert(private_signing_key);
 
   voter = smartlist_get(v3_ns->voters, 0);
 
@@ -1950,11 +1951,13 @@
                  "valid-after %s\n"
                  "fresh-until %s\n"
                  "valid-until %s\n"
+                 "voting-delay %d %d\n"
                  "%s" /* versions */
-                 "known-flags %s"
+                 "known-flags %s\n"
                  "dir-source %s %s %s %s %d %d\n"
                  "contact %s\n",
                  published, va, fu, vu,
+                 v3_ns->vote_seconds, v3_ns->dist_seconds,
                  version_lines,
                  flags,
                  voter->nickname, fingerprint, voter->address,
@@ -1988,7 +1991,8 @@
     }
     outp += strlen(outp);
 
-    if (crypto_pk_get_fingerprint(private_key, signing_key_fingerprint, 0)<0) {
+    if (crypto_pk_get_fingerprint(private_signing_key,
+                                  signing_key_fingerprint, 0)<0) {
       log_warn(LD_BUG, "Unable to get fingerprint for signing key");
       goto err;
     }
@@ -2000,8 +2004,11 @@
     outp += strlen(outp);
   }
 
+  if (router_get_networkstatus_v3_hash(status, digest)<0)
+    goto err;
   note_crypto_pk_op(SIGN_DIR);
-  if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
+  if (router_append_dirobj_signature(outp,endp-outp,digest,
+                                     private_signing_key)<0) {
     log_warn(LD_BUG, "Unable to sign networkstatus vote.");
     goto err;
   }
@@ -2009,7 +2016,8 @@
   {
     networkstatus_vote_t *v;
     if (!(v = networkstatus_parse_vote_from_string(status, 1))) {
-      log_err(LD_BUG,"Generated a networkstatus vote we couldn't parse.");
+      log_err(LD_BUG,"Generated a networkstatus vote we couldn't parse: "
+              "<<%s>>", status);
       goto err;
     }
     networkstatus_vote_free(v);

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-06-13 18:16:01 UTC (rev 10586)
+++ tor/trunk/src/or/dirvote.c	2007-06-13 18:16:05 UTC (rev 10587)
@@ -732,3 +732,4 @@
 
   return out;
 }
+

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-06-13 18:16:01 UTC (rev 10586)
+++ tor/trunk/src/or/or.h	2007-06-13 18:16:05 UTC (rev 10587)
@@ -2747,6 +2747,12 @@
 void dirserv_free_all(void);
 void cached_dir_decref(cached_dir_t *d);
 
+#ifdef DIRSERV_PRIVATE
+char *
+format_networkstatus_vote(crypto_pk_env_t *private_key,
+                          networkstatus_vote_t *v3_ns);
+#endif
+
 /********************************* dirvote.c ************************/
 
 void networkstatus_vote_free(networkstatus_vote_t *ns);

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-06-13 18:16:01 UTC (rev 10586)
+++ tor/trunk/src/or/routerparse.c	2007-06-13 18:16:05 UTC (rev 10587)
@@ -296,7 +296,7 @@
   T1("fresh-until",            K_FRESH_UNTIL,      CONCAT_ARGS, NO_OBJ ),
   T1("valid-until",            K_VALID_UNTIL,      CONCAT_ARGS, NO_OBJ ),
   T1("voting-delay",           K_VOTING_DELAY,     GE(2),       NO_OBJ ),
-  T1("known-flags",            K_KNOWN_FLAGS,      CONCAT_ARGS, NO_OBJ ),
+  T1("known-flags",            K_KNOWN_FLAGS,      ARGS,        NO_OBJ ),
   T( "fingerprint",            K_FINGERPRINT,      CONCAT_ARGS, NO_OBJ ),
 
   CERTIFICATE_MEMBERS
@@ -304,7 +304,6 @@
   T0N("opt",                 K_OPT,             CONCAT_ARGS, OBJ_OK ),
   T1( "contact",             K_CONTACT,         CONCAT_ARGS, NO_OBJ ),
   T1( "dir-source",          K_DIR_SOURCE,      GE(6),       NO_OBJ ),
-  T1( "dir-options",         K_DIR_OPTIONS,     ARGS,        NO_OBJ ),
   T1( "known-flags",         K_KNOWN_FLAGS,     CONCAT_ARGS, NO_OBJ ),
   T01("client-versions",     K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
   T01("server-versions",     K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
@@ -1842,7 +1841,7 @@
   if (!ok)
     goto err;
   ns->dist_seconds =
-    (int) tor_parse_long(tok->args[0], 10, 0, INT_MAX, &ok, NULL);
+    (int) tor_parse_long(tok->args[1], 10, 0, INT_MAX, &ok, NULL);
   if (!ok)
     goto err;
 
@@ -1860,8 +1859,10 @@
   inorder = 1;
   for (i = 0; i < tok->n_args; ++i) {
     smartlist_add(ns->known_flags, tok->args[i]);
-    if (i>0 && strcmp(tok->args[i-1], tok->args[i])>= 0)
+    if (i>0 && strcmp(tok->args[i-1], tok->args[i])>= 0) {
+      log_warn(LD_DIR, "%s >= %s", tok->args[i-1], tok->args[i]);
       inorder = 0;
+    }
   }
   tok->n_args = 0; /* suppress free of args members, but not of args itself. */
   if (!inorder) {
@@ -1895,6 +1896,7 @@
                  escaped(tok->args[3]));
         goto err;
       }
+      voter->addr = ntohl(in.s_addr);
       voter->dir_port = (uint64_t)
         (int) tor_parse_long(tok->args[4], 10, 0, 65535, &ok, NULL);
       if (!ok)
@@ -2039,6 +2041,7 @@
       v->pending_signature_len = tok->object_size;
     }
   });
+  /* XXXX020 enforce: vote must have at least one signature. */
 
   /* XXXX020 check dates for plausibility.  ??? */
 
@@ -2456,7 +2459,7 @@
     *s = next;
   } else {
     tok->object_body = tor_malloc(next-*s); /* really, this is too much RAM. */
-    i = base64_decode(tok->object_body, 256, *s, next-*s);
+    i = base64_decode(tok->object_body, next-*s, *s, next-*s);
     if (i<0) {
       RET_ERR("Malformed object: bad base64-encoded data");
     }

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2007-06-13 18:16:01 UTC (rev 10586)
+++ tor/trunk/src/or/test.c	2007-06-13 18:16:05 UTC (rev 10587)
@@ -29,6 +29,8 @@
  * are typically file-private. */
 #define CONFIG_PRIVATE
 #define CONTROL_PRIVATE
+#define CRYPTO_PRIVATE
+#define DIRSERV_PRIVATE
 #define MEMPOOL_PRIVATE
 #define ROUTER_PRIVATE
 
@@ -2125,9 +2127,157 @@
                                    "Tor 0.2.1.0-dev (r99)"));
 }
 
+extern const char AUTHORITY_CERT_1[];
+extern const char AUTHORITY_IDKEY_1[];
+extern const char AUTHORITY_SIGNKEY_1[];
+extern const char AUTHORITY_CERT_2[];
+extern const char AUTHORITY_IDKEY_2[];
+extern const char AUTHORITY_SIGNKEY_2[];
+
 static void
 test_v3_networkstatus(void)
 {
+  authority_cert_t *cert1, *cert2;//, *cert_tmp;
+  crypto_pk_env_t *id_skey_1, *id_skey_2;
+  crypto_pk_env_t *sign_skey_1, *sign_skey_2;
+
+  time_t now = time(NULL);
+  networkstatus_voter_info_t *voter;
+  networkstatus_vote_t *vote, *v1;
+  vote_routerstatus_t *vrs;
+  routerstatus_t *rs;
+  char *v1_text, *cp;
+
+  add_stream_log(LOG_NOTICE, LOG_ERR, "", stdout);
+
+  /* Parse certificates and keys. */
+  cert1 = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
+  test_assert(cert1);
+  cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL);
+  test_assert(cert2);
+  id_skey_1 = crypto_new_pk_env();
+  id_skey_2 = crypto_new_pk_env();
+  sign_skey_1 = crypto_new_pk_env();
+  sign_skey_2 = crypto_new_pk_env();
+
+  test_assert(!crypto_pk_read_private_key_from_string(id_skey_1,
+                                                      AUTHORITY_IDKEY_1));
+  test_assert(!crypto_pk_read_private_key_from_string(id_skey_2,
+                                                      AUTHORITY_IDKEY_2));
+  test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
+                                                      AUTHORITY_SIGNKEY_1));
+  test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
+                                                      AUTHORITY_SIGNKEY_2));
+
+  test_assert(!crypto_pk_cmp_keys(id_skey_1, cert1->identity_key));
+  test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
+  test_assert(!crypto_pk_cmp_keys(id_skey_2, cert2->identity_key));
+  test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
+
+  /*
+   * Set up a vote; generate it; try to parse it.
+   */
+  vote = tor_malloc_zero(sizeof(networkstatus_vote_t));
+  vote->is_vote = 1;
+  vote->published = now;
+  vote->valid_after = now+100;
+  vote->fresh_until = now+200;
+  vote->valid_until = now+300;
+  vote->vote_seconds = 100;
+  vote->dist_seconds = 200;
+  vote->client_versions = tor_strdup("0.1.2.14,0.1.2.15");
+  vote->server_versions = tor_strdup("0.1.2.14,0.1.2.15,0.1.2.16");
+  vote->known_flags = smartlist_create();
+  smartlist_split_string(vote->known_flags,
+                     "Authority Exit Fast Guard Running Stable V2Dir Valid",
+                     0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+  vote->voters = smartlist_create();
+  voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
+  voter->nickname = tor_strdup("Voter1");
+  voter->address = tor_strdup("1.2.3.4");
+  voter->addr = 0x01020304;
+  voter->dir_port = 80;
+  voter->or_port = 9000;
+  voter->contact = tor_strdup("voter1 at example.com");
+  crypto_pk_get_digest(id_skey_1, voter->identity_digest);
+  smartlist_add(vote->voters, voter);
+  vote->cert = authority_cert_dup(cert1);
+  vote->routerstatus_list = smartlist_create();
+  /* add the first routerstatus. */
+  vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+  rs = &vrs->status;
+  vrs->version = tor_strdup("0.1.2.14");
+  rs->published_on = now-1500;
+  strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
+  memset(rs->identity_digest, 3, DIGEST_LEN);
+  memset(rs->descriptor_digest, 11, DIGEST_LEN);
+  rs->addr = 0x99008801;
+  rs->or_port = 443;
+  rs->dir_port = 8000;
+  /* all flags cleared */
+  smartlist_add(vote->routerstatus_list, vrs);
+  /* add the second routerstatus. */
+  vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+  rs = &vrs->status;
+  vrs->version = tor_strdup("0.2.0.5");
+  rs->published_on = now-1000;
+  strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
+  memset(rs->identity_digest, 5, DIGEST_LEN);
+  memset(rs->descriptor_digest, 2, DIGEST_LEN);
+  rs->addr = 0x99009901;
+  rs->or_port = 443;
+  rs->dir_port = 0;
+  rs->is_exit = rs->is_stable = rs->is_fast = rs->is_running =
+    rs->is_v2_dir = rs->is_possible_guard = 1;
+  // rs->named = rs->is_bad_exit = rs->is_bad_directory = 1;
+  smartlist_add(vote->routerstatus_list, vrs);
+
+  /* dump the vote and try to parse it. */
+  v1_text = format_networkstatus_vote(sign_skey_1, vote);
+  test_assert(v1_text);
+  v1 = networkstatus_parse_vote_from_string(v1_text, 1);
+  test_assert(v1);
+
+  /* Make sure the parsed thing was right. */
+  test_eq(v1->is_vote, 1);
+  test_eq(v1->published, vote->published);
+  test_eq(v1->valid_after, vote->valid_after);
+  test_eq(v1->fresh_until, vote->fresh_until);
+  test_eq(v1->valid_until, vote->valid_until);
+  test_eq(v1->vote_seconds, vote->vote_seconds);
+  test_eq(v1->dist_seconds, vote->dist_seconds);
+  test_streq(v1->client_versions, vote->client_versions);
+  test_streq(v1->server_versions, vote->server_versions);
+  test_assert(v1->voters && smartlist_len(v1->voters));
+  voter = smartlist_get(v1->voters, 0);
+  test_streq(voter->nickname, "Voter1");
+  test_streq(voter->address, "1.2.3.4");
+  test_eq(voter->addr, 0x01020304);
+  test_eq(voter->dir_port, 80);
+  test_eq(voter->or_port, 9000);
+  test_streq(voter->contact, "voter1 at example.com");
+  test_assert(v1->cert);
+  test_assert(!crypto_pk_cmp_keys(id_skey_1, v1->cert->identity_key));
+  test_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
+  cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
+  test_streq(cp, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
+  tor_free(cp);
+  test_eq(smartlist_len(v1->routerstatus_list), 2);
+  /*XXXX020 test contents of v1->routerstatus_list. */
+
+  /* XXXXX020 Generate 2 more votes */
+
+  /* XXXXX020 compute, write, and parse a consensus. */
+
+  tor_free(v1_text);
+  networkstatus_vote_free(vote);
+  networkstatus_vote_free(v1);
+  crypto_free_pk_env(id_skey_1);
+  crypto_free_pk_env(id_skey_2);
+  crypto_free_pk_env(sign_skey_1);
+  crypto_free_pk_env(sign_skey_2);
+  authority_cert_free(cert1);
+  authority_cert_free(cert2);
 }
 
 static void



More information about the tor-commits mailing list