aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-12-12 19:05:36 +0000
committerNick Mathewson <nickm@torproject.org>2008-12-12 19:05:36 +0000
commit5fb2ab1e654ad5c121fff834897ea4cf920774ca (patch)
treedeff2c9449fdfd3e341943eb29d6146dfa4beddf /src
parent69ce955484f69eb43dcdc60ecce182267255aabd (diff)
downloadtor-5fb2ab1e654ad5c121fff834897ea4cf920774ca.tar
tor-5fb2ab1e654ad5c121fff834897ea4cf920774ca.tar.gz
Implement the /tor/keys/fp-sk/ URL format. That mostly finishes the server side of 157.
svn:r17611
Diffstat (limited to 'src')
-rw-r--r--src/or/directory.c68
-rw-r--r--src/or/or.h6
-rw-r--r--src/or/test.c29
3 files changed, 103 insertions, 0 deletions
diff --git a/src/or/directory.c b/src/or/directory.c
index e74119c0e..7463cd942 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2780,6 +2780,17 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
tor_free(d);
});
smartlist_free(fps);
+ } else if (!strcmpstart(url, "/tor/keys/fp-sk/")) {
+ smartlist_t *fp_sks = smartlist_create();
+ dir_split_resource_into_fingerprint_pairs(url+strlen("/tor/keys/fp-sk/"),
+ fp_sks);
+ SMARTLIST_FOREACH(fp_sks, fp_pair_t *, pair, {
+ authority_cert_t *c = authority_cert_get_by_digests(pair->first,
+ pair->second);
+ if (c) smartlist_add(certs, c);
+ tor_free(pair);
+ });
+ smartlist_free(fp_sks);
} else {
write_http_status_line(conn, 400, "Bad request");
goto keys_done;
@@ -3383,6 +3394,63 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
* every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
}
+static int
+_compare_pairs(const void **a, const void **b)
+{
+ const fp_pair_t *fp1 = *a, *fp2 = *b;
+ int r;
+ if ((r = memcmp(fp1->first, fp2->first, DIGEST_LEN)))
+ return r;
+ else
+ return memcmp(fp1->second, fp2->second, DIGEST_LEN);
+}
+
+/** DOCDOC */
+int
+dir_split_resource_into_fingerprint_pairs(const char *res,
+ smartlist_t *pairs_out)
+{
+ smartlist_t *pairs_tmp = smartlist_create();
+ smartlist_t *pairs_result = smartlist_create();
+
+ smartlist_split_string(pairs_tmp, res, "+", 0, 0);
+ if (smartlist_len(pairs_tmp)) {
+ char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
+ size_t last_len = strlen(last);
+ if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
+ last[last_len-2] = '\0';
+ }
+ }
+ SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
+ if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
+ log_info(LD_DIR,
+ "Skipping digest pair %s with non-standard length.", escaped(cp));
+ } else if (cp[HEX_DIGEST_LEN] != '-') {
+ log_info(LD_DIR,
+ "Skipping digest pair %s with missing dash.", escaped(cp));
+ } else {
+ fp_pair_t pair;
+ if (base16_decode(pair.first, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0 ||
+ base16_decode(pair.second,
+ DIGEST_LEN, cp+HEX_DIGEST_LEN+1, HEX_DIGEST_LEN)<0) {
+ log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
+ } else {
+ smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
+ }
+ }
+ tor_free(cp);
+ } SMARTLIST_FOREACH_END(cp);
+ smartlist_free(pairs_tmp);
+
+ /* Uniq-and-sort */
+ smartlist_sort(pairs_result, _compare_pairs);
+ smartlist_uniq(pairs_result, _compare_pairs, _tor_free);
+
+ smartlist_add_all(pairs_out, pairs_result);
+ smartlist_free(pairs_result);
+ return 0;
+}
+
/** Given a directory <b>resource</b> request, containing zero
* or more strings separated by plus signs, followed optionally by ".z", store
* the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
diff --git a/src/or/or.h b/src/or/or.h
index f61258c3d..aa5c92fa9 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3277,6 +3277,12 @@ void directory_initiate_command(const char *address, const tor_addr_t *addr,
int dir_split_resource_into_fingerprints(const char *resource,
smartlist_t *fp_out, int *compresseed_out,
int decode_hex, int sort_uniq);
+typedef struct {
+ char first[DIGEST_LEN];
+ char second[DIGEST_LEN];
+} fp_pair_t;
+int dir_split_resource_into_fingerprint_pairs(const char *res,
+ smartlist_t *pairs_out);
char *directory_dump_request_log(void);
void note_request(const char *key, size_t bytes);
int router_supports_extrainfo(const char *identity_digest, int is_authority);
diff --git a/src/or/test.c b/src/or/test.c
index 6d3eba196..33d1b5d43 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -2985,6 +2985,34 @@ test_dir_format(void)
tor_free(dir2); /* And more !*/
}
+static void
+test_dirutil(void)
+{
+ smartlist_t *sl = smartlist_create();
+ fp_pair_t *pair;
+
+ dir_split_resource_into_fingerprint_pairs(
+ /* Two pairs, out of order, with one duplicate. */
+ "73656372657420646174612E0000000000FFFFFF-"
+ "557365204145532d32353620696e73746561642e+"
+ "73656372657420646174612E0000000000FFFFFF-"
+ "557365204145532d32353620696e73746561642e+"
+ "48657861646563696d616c2069736e277420736f-"
+ "676f6f6420666f7220686964696e6720796f7572.z", sl);
+
+ test_eq(smartlist_len(sl), 2);
+ pair = smartlist_get(sl, 0);
+ test_memeq(pair->first, "Hexadecimal isn't so", DIGEST_LEN);
+ test_memeq(pair->second, "good for hiding your", DIGEST_LEN);
+ pair = smartlist_get(sl, 1);
+ test_memeq(pair->first, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN);
+ test_memeq(pair->second, "Use AES-256 instead.", DIGEST_LEN);
+
+ done:
+ SMARTLIST_FOREACH(sl, fp_pair_t *, pair, tor_free(pair));
+ smartlist_free(sl);
+}
+
extern const char AUTHORITY_CERT_1[];
extern const char AUTHORITY_SIGNKEY_1[];
extern const char AUTHORITY_CERT_2[];
@@ -4448,6 +4476,7 @@ static struct {
SUBENT(util, order_functions),
ENT(onion_handshake),
ENT(dir_format),
+ ENT(dirutil),
ENT(v3_networkstatus),
ENT(policies),
ENT(rend_fns),