summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-08-01 16:43:44 +0000
committerNick Mathewson <nickm@torproject.org>2007-08-01 16:43:44 +0000
commita4e7dffc948bcbdcb8e3484f13f328afec281424 (patch)
treeedd2ab16eefb2e141586c9fe48633dd8470a9c81
parent64d3e6cf659b92abf73cfab4845cdaba35509adc (diff)
downloadtor-a4e7dffc948bcbdcb8e3484f13f328afec281424.tar.gz
tor-a4e7dffc948bcbdcb8e3484f13f328afec281424.zip
r13886@Kushana: nickm | 2007-08-01 09:43:06 -0700
Unit tests and debugging for detached signature manipulation. svn:r11015
-rw-r--r--src/or/dirvote.c6
-rw-r--r--src/or/routerparse.c26
-rw-r--r--src/or/test.c90
3 files changed, 112 insertions, 10 deletions
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 481cb1c07a..8034b7d48d 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -884,6 +884,7 @@ networkstatus_get_detached_signatures(networkstatus_vote_t *consensus)
smartlist_t *elements;
char buf[4096];
char *result = NULL;
+ int n_sigs = 0;
tor_assert(consensus);
tor_assert(! consensus->is_vote);
@@ -911,8 +912,9 @@ networkstatus_get_detached_signatures(networkstatus_vote_t *consensus)
{
char sk[HEX_DIGEST_LEN+1];
char id[HEX_DIGEST_LEN+1];
- if (!v->signature || !v->good_signature)
+ if (!v->signature) // XXXX020 || !v->good_signature)
continue;
+ ++n_sigs;
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),
@@ -928,6 +930,8 @@ networkstatus_get_detached_signatures(networkstatus_vote_t *consensus)
SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
smartlist_free(elements);
+ if (!n_sigs)
+ tor_free(result);
return result;
}
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 0f510289dc..41ca710df0 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -345,7 +345,7 @@ static token_rule_t networkstatus_detached_signature_token_table[] = {
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 ),
+ T1N("directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
END_OF_TABLE
};
@@ -2127,23 +2127,35 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
}
tok = find_first_by_keyword(tokens, K_CONSENSUS_DIGEST);
- if (strlen(tok->args[0]) != HEX_DIGEST_LEN)
+ if (strlen(tok->args[0]) != HEX_DIGEST_LEN) {
+ log_warn(LD_DIR, "Wrong length on consensus-digest in detached "
+ "networkstatus signatures");
goto err;
+ }
if (base16_decode(sigs->networkstatus_digest, DIGEST_LEN,
- tok->args[0], strlen(tok->args[0])) < 0)
+ tok->args[0], strlen(tok->args[0])) < 0) {
+ log_warn(LD_DIR, "Bad encoding on on consensus-digest in detached "
+ "networkstatus signatures");
goto err;
+ }
tok = find_first_by_keyword(tokens, K_VALID_AFTER);
- if (parse_iso_time(tok->args[0], &sigs->valid_after))
+ if (parse_iso_time(tok->args[0], &sigs->valid_after)) {
+ log_warn(LD_DIR, "Bad valid-after in detached networkstatus signatures");
goto err;
+ }
tok = find_first_by_keyword(tokens, K_FRESH_UNTIL);
- if (parse_iso_time(tok->args[0], &sigs->fresh_until))
+ if (parse_iso_time(tok->args[0], &sigs->fresh_until)) {
+ log_warn(LD_DIR, "Bad fresh-until in detached networkstatus signatures");
goto err;
+ }
tok = find_first_by_keyword(tokens, K_VALID_UNTIL);
- if (parse_iso_time(tok->args[0], &sigs->valid_until))
+ if (parse_iso_time(tok->args[0], &sigs->valid_until)) {
+ log_warn(LD_DIR, "Bad valid-until in detached networkstatus signatures");
goto err;
+ }
sigs->signatures = smartlist_create();
SMARTLIST_FOREACH(tokens, directory_token_t *, _tok,
@@ -2194,7 +2206,7 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
sigs = NULL;
done:
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
- return NULL;
+ return sigs;
}
/** Parse the addr policy in the string <b>s</b> and return it. If
diff --git a/src/or/test.c b/src/or/test.c
index d731fb24f0..286b91e3b7 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -1283,7 +1283,7 @@ test_smartlist(void)
smartlist_t *sl;
char *cp;
- /* XXXX test sort_strings, sort_digests, uniq_strings, uniq_digests */
+ /* XXXX test sort_digests, uniq_strings, uniq_digests */
/* Test smartlist add, del_keeporder, insert, get. */
sl = smartlist_create();
@@ -2724,7 +2724,93 @@ test_v3_networkstatus(void)
test_assert(voter->good_signature);
test_assert(!voter->bad_signature);
- /* XXXX020 frob with detached signatures */
+ {
+ char *consensus_text2, *consensus_text3;
+ networkstatus_vote_t *con2, *con3;
+ char *detached_text1, *addition1, *detached_text2, *addition2;
+ ns_detached_signatures_t *dsig1, *dsig2;
+ size_t sz;
+ /* Compute the other two signed consensuses. */
+ smartlist_shuffle(votes);
+ consensus_text2 = networkstatus_compute_consensus(votes, 3,
+ cert2->identity_key,
+ sign_skey_2);
+ smartlist_shuffle(votes);
+ consensus_text3 = networkstatus_compute_consensus(votes, 3,
+ cert1->identity_key,
+ sign_skey_1);
+ test_assert(consensus_text2);
+ test_assert(consensus_text3);
+ con2 = networkstatus_parse_vote_from_string(consensus_text2, 0);
+ con3 = networkstatus_parse_vote_from_string(consensus_text3, 0);
+ test_assert(con2);
+ test_assert(con3);
+
+ /* All three should have the same digest. */
+ test_memeq(con->networkstatus_digest, con2->networkstatus_digest,
+ DIGEST_LEN);
+ test_memeq(con->networkstatus_digest, con3->networkstatus_digest,
+ DIGEST_LEN);
+
+ /* Extract a detached signature from con3. */
+ detached_text1 = networkstatus_get_detached_signatures(con3);
+ tor_assert(detached_text1);
+ /* Try to parse it. */
+ dsig1 = networkstatus_parse_detached_signatures(detached_text1, NULL);
+ tor_assert(dsig1);
+
+ /* Are parsed values as expected? */
+ test_eq(dsig1->valid_after, con3->valid_after);
+ test_eq(dsig1->fresh_until, con3->fresh_until);
+ test_eq(dsig1->valid_until, con3->valid_until);
+ test_memeq(dsig1->networkstatus_digest, con3->networkstatus_digest,
+ DIGEST_LEN);
+ test_eq(1, smartlist_len(dsig1->signatures));
+ voter = smartlist_get(dsig1->signatures, 0);
+ test_memeq(voter->identity_digest, cert1->cache_info.identity_digest,
+ DIGEST_LEN);
+
+ /* Try adding it to con2. */
+ detached_text2 = networkstatus_get_detached_signatures(con2);
+ addition1 = NULL;
+ test_eq(1, networkstatus_add_detached_signatures(con2, dsig1, &addition1));
+ sz = strlen(detached_text2)+strlen(addition1)+1;
+ detached_text2 = tor_realloc(detached_text2, sz);
+ strlcat(detached_text2, addition1, sz);
+ //printf("\n<%s>\n", detached_text2);
+ dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
+ test_assert(dsig2);
+ /*
+ printf("\n");
+ SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
+ char hd[64];
+ base16_encode(hd, sizeof(hd), vi->identity_digest, DIGEST_LEN);
+ printf("%s\n", hd);
+ });
+ */
+ test_eq(2, smartlist_len(dsig2->signatures));
+
+ /* Add to con. */
+ test_eq(2, networkstatus_add_detached_signatures(con, dsig2, &addition2));
+ /* Check signatures */
+ test_assert(!networkstatus_check_voter_signature(con,
+ smartlist_get(con->voters, 0),
+ cert2));
+ test_assert(!networkstatus_check_voter_signature(con,
+ smartlist_get(con->voters, 2),
+ cert1));
+
+ networkstatus_vote_free(con2);
+ networkstatus_vote_free(con3);
+ tor_free(consensus_text2);
+ tor_free(consensus_text3);
+ tor_free(detached_text1);
+ tor_free(detached_text2);
+ ns_detached_signatures_free(dsig1);
+ ns_detached_signatures_free(dsig2);
+ tor_free(addition1);
+ tor_free(addition2);
+ }
smartlist_free(votes);
tor_free(v1_text);