aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-09-18 02:22:21 +0000
committerNick Mathewson <nickm@torproject.org>2005-09-18 02:22:21 +0000
commite86893e87b11e8cd7392ae22587ba2ab2d631dbf (patch)
tree5b60c3d7712595c969311eed61f662f51ea351b0
parentf8a80e8d599d87ea18cb72b7b22441612f1e26ac (diff)
downloadtor-e86893e87b11e8cd7392ae22587ba2ab2d631dbf.tar
tor-e86893e87b11e8cd7392ae22587ba2ab2d631dbf.tar.gz
Move to new base64 digest functions. Switch to new router digest calculation. Make sure there are no duplicates in router status lists.
svn:r5088
-rw-r--r--src/or/dirserv.c19
-rw-r--r--src/or/routerparse.c47
-rw-r--r--src/or/test.c10
3 files changed, 36 insertions, 40 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index e62978f14..ee9fc3998 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1124,7 +1124,6 @@ static cached_dir_t the_v2_networkstatus = { NULL, NULL, 0, 0, 0 };
static int
generate_v2_networkstatus(void)
{
-#define BASE64_DIGEST_LEN 27
#define LONGEST_STATUS_FLAG_NAME_LEN 7
#define N_STATUS_FLAGS 6
#define RS_ENTRY_LEN \
@@ -1216,8 +1215,8 @@ generate_v2_networkstatus(void)
int f_running;
int f_named = naming && ri->is_named;
int f_valid = ri->is_verified;
- char identity64[128];
- char digest64[128];
+ char identity64[BASE64_DIGEST_LEN+1];
+ char digest64[BASE64_DIGEST_LEN+1];
if (options->AuthoritativeDir) {
ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
@@ -1226,18 +1225,8 @@ generate_v2_networkstatus(void)
format_iso_time(published, ri->published_on);
- if (base64_encode(identity64, sizeof(identity64),
- ri->identity_digest, DIGEST_LEN)<0) {
- log_fn(LOG_WARN, "Unable to encode router identity digest.");
- goto done;
- }
- if (base64_encode(digest64, sizeof(digest64),
- ri->signed_descriptor_digest, DIGEST_LEN)<0) {
- log_fn(LOG_WARN, "Unable to encode router descriptor digest.");
- goto done;
- }
- identity64[BASE64_DIGEST_LEN] = '\0';
- digest64[BASE64_DIGEST_LEN] = '\0';
+ digest_to_base64(identity64, ri->identity_digest);
+ digest_to_base64(digest64, ri->signed_descriptor_digest);
in.s_addr = htonl(ri->addr);
tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index ffcf5c010..b3f780c7b 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -748,7 +748,7 @@ router_parse_entry_from_string(const char *s, const char *end)
router = tor_malloc_zero(sizeof(routerinfo_t));
router->signed_descriptor = tor_strndup(s, end-s);
router->signed_descriptor_len = end-s;
- crypto_digest(router->signed_descriptor_digest, s, end-s);
+ memcpy(router->signed_descriptor_digest, digest, DIGEST_LEN);
ports_set = bw_set = 0;
if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
@@ -957,12 +957,9 @@ find_start_of_next_routerstatus(const char *s)
static routerstatus_t *
routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
{
-#define BASE64_DIGEST_LEN 27
const char *eos;
routerstatus_t *rs = NULL;
directory_token_t *tok;
- char base64buf_in[BASE64_DIGEST_LEN+3];
- char base64buf_out[256];
char timebuf[ISO_TIME_LEN+1];
struct in_addr in;
@@ -1000,33 +997,15 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
}
strlcpy(rs->nickname, tok->args[0], sizeof(rs->nickname));
- if (strlen(tok->args[1]) != BASE64_DIGEST_LEN) {
- log_fn(LOG_WARN, "Digest '%s' is wrong length in router status; skipping.",
- tok->args[1]);
- goto err;
- }
- memcpy(base64buf_in, tok->args[1], BASE64_DIGEST_LEN);
- memcpy(base64buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
- if (base64_decode(base64buf_out, sizeof(base64buf_out),
- base64buf_in, sizeof(base64buf_in)-1) != DIGEST_LEN) {
+ if (digest_from_base64(rs->identity_digest, tok->args[1])) {
log_fn(LOG_WARN, "Error decoding digest '%s'", tok->args[1]);
goto err;
}
- memcpy(rs->identity_digest, base64buf_out, DIGEST_LEN);
- if (strlen(tok->args[2]) != BASE64_DIGEST_LEN) {
- log_fn(LOG_WARN, "Digest '%s' is wrong length in router status; skipping.",
- tok->args[2]);
- goto err;
- }
- memcpy(base64buf_in, tok->args[2], BASE64_DIGEST_LEN);
- memcpy(base64buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
- if (base64_decode(base64buf_out, sizeof(base64buf_out),
- base64buf_in, sizeof(base64buf_in)-1) != DIGEST_LEN) {
+ if (digest_from_base64(rs->descriptor_digest, tok->args[2])) {
log_fn(LOG_WARN, "Error decoding digest '%s'", tok->args[2]);
goto err;
}
- memcpy(rs->descriptor_digest, base64buf_out, DIGEST_LEN);
if (tor_snprintf(timebuf, sizeof(timebuf), "%s %s",
tok->args[3], tok->args[4]) < 0 ||
@@ -1083,6 +1062,12 @@ _compare_routerstatus_entries(const void **_a, const void **_b)
return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
}
+void
+sort_routerstatus_entries(smartlist_t *sl)
+{
+ smartlist_sort(sl, _compare_routerstatus_entries);
+}
+
/** Given a versioned (v2 or later) network-status object in <b>s</b>, try to
* parse it and return the result. Return NULL on failure. Check the
* signature of the network status, but do not (yet) check the signing key for
@@ -1098,6 +1083,7 @@ networkstatus_parse_from_string(const char *s)
char tmp_digest[DIGEST_LEN];
struct in_addr in;
directory_token_t *tok;
+ int i;
if (router_get_networkstatus_v2_hash(s, ns_digest)) {
log_fn(LOG_WARN, "Unable to compute digest of network-status");
@@ -1209,7 +1195,6 @@ networkstatus_parse_from_string(const char *s)
}
if ((tok = find_first_by_keyword(tokens, K_DIR_OPTIONS))) {
- int i;
for (i=0; i < tok->n_args; ++i) {
if (!strcmp(tok->args[i], "Names"))
ns->binds_names = 1;
@@ -1227,6 +1212,18 @@ networkstatus_parse_from_string(const char *s)
}
smartlist_sort(ns->entries, _compare_routerstatus_entries);
+ /* Kill duplicate entries. */
+ for (i=0; i < smartlist_len(ns->entries)-1; ++i) {
+ routerstatus_t *rs1 = smartlist_get(ns->entries, i);
+ routerstatus_t *rs2 = smartlist_get(ns->entries, i+1);
+ if (!memcmp(rs1->identity_digest,
+ rs2->identity_digest, DIGEST_LEN)) {
+ log_fn(LOG_WARN, "Network-status has two entries for the same router. Dropping one.");
+ smartlist_del_keeporder(ns->entries, i--);
+ routerstatus_free(rs1);
+ }
+ }
+
if (tokenize_string(s, NULL, tokens, NETSTATUS)) {
log_fn(LOG_WARN, "Error tokenizing network-status footer.");
goto err;
diff --git a/src/or/test.c b/src/or/test.c
index b76a43939..5007589eb 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -511,6 +511,16 @@ test_crypto(void)
test_eq(j, 71);
test_assert(data2[i] == '\0');
+ crypto_rand(data1, DIGEST_LEN);
+ memset(data2, 100, 1024);
+ digest_to_base64(data2, data1);
+ test_eq(BASE64_DIGEST_LEN, strlen(data2));
+ test_eq(100, data2[BASE64_DIGEST_LEN+2]);
+ memset(data3, 99, 1024);
+ digest_from_base64(data3, data2);
+ test_memeq(data1, data3, DIGEST_LEN);
+ test_eq(99, data3[DIGEST_LEN+1]);
+
/* Base32 tests */
strcpy(data1, "5chrs");
/* bit pattern is: [35 63 68 72 73] ->