summaryrefslogtreecommitdiff
path: root/src/or/routerparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r--src/or/routerparse.c260
1 files changed, 164 insertions, 96 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 8c4f582c07..781c57897d 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -64,13 +64,13 @@ typedef enum {
K_DIR_OPTIONS,
K_CLIENT_VERSIONS,
K_SERVER_VERSIONS,
+ K_OR_ADDRESS,
K_P,
K_R,
K_S,
K_V,
K_W,
K_M,
- K_EVENTDNS,
K_EXTRA_INFO,
K_EXTRA_INFO_DIGEST,
K_CACHES_EXTRA_INFO,
@@ -178,7 +178,7 @@ typedef struct directory_token_t {
size_t object_size; /**< Bytes in object_body */
char *object_body; /**< Contents of object, base64-decoded. */
- crypto_pk_env_t *key; /**< For public keys only. Heap-allocated. */
+ crypto_pk_t *key; /**< For public keys only. Heap-allocated. */
char *error; /**< For _ERR tokens only. */
} directory_token_t;
@@ -287,7 +287,7 @@ static token_rule_t routerdesc_token_table[] = {
T01("family", K_FAMILY, ARGS, NO_OBJ ),
T01("caches-extra-info", K_CACHES_EXTRA_INFO, NO_ARGS, NO_OBJ ),
- T01("eventdns", K_EVENTDNS, ARGS, NO_OBJ ),
+ T0N("or-address", K_OR_ADDRESS, GE(1), NO_OBJ ),
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
T1( "bandwidth", K_BANDWIDTH, GE(3), NO_OBJ ),
@@ -543,6 +543,7 @@ static int router_get_hashes_impl(const char *s, size_t s_len,
const char *start_str, const char *end_str,
char end_char);
static void token_clear(directory_token_t *tok);
+static smartlist_t *find_all_by_keyword(smartlist_t *s, directory_keyword k);
static smartlist_t *find_all_exitpolicy(smartlist_t *s);
static directory_token_t *_find_by_keyword(smartlist_t *s,
directory_keyword keyword,
@@ -568,10 +569,10 @@ static directory_token_t *get_next_token(memarea_t *area,
static int check_signature_token(const char *digest,
ssize_t digest_len,
directory_token_t *tok,
- crypto_pk_env_t *pkey,
+ crypto_pk_t *pkey,
int flags,
const char *doctype);
-static crypto_pk_env_t *find_dir_signing_key(const char *str, const char *eos);
+static crypto_pk_t *find_dir_signing_key(const char *str, const char *eos);
#undef DEBUG_AREA_ALLOC
@@ -681,12 +682,12 @@ router_get_networkstatus_v3_hash(const char *s, char *digest,
' ', alg);
}
-/** Set <b>digest</b> to the SHA-1 digest of the hash of the extrainfo
- * string in <b>s</b>. Return 0 on success, -1 on failure. */
+/** Set <b>digest</b> to the SHA-1 digest of the hash of the <b>s_len</b>-byte
+ * extrainfo string at <b>s</b>. Return 0 on success, -1 on failure. */
int
-router_get_extrainfo_hash(const char *s, char *digest)
+router_get_extrainfo_hash(const char *s, size_t s_len, char *digest)
{
- return router_get_hash_impl(s, strlen(s), digest, "extra-info",
+ return router_get_hash_impl(s, s_len, digest, "extra-info",
"\nrouter-signature",'\n', DIGEST_SHA1);
}
@@ -699,7 +700,7 @@ router_get_extrainfo_hash(const char *s, char *digest)
*/
int
router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest,
- size_t digest_len, crypto_pk_env_t *private_key)
+ size_t digest_len, crypto_pk_t *private_key)
{
char *signature;
size_t i, keysize;
@@ -765,7 +766,7 @@ tor_version_is_obsolete(const char *myversion, const char *versionlist)
log_err(LD_BUG,"I couldn't parse my own version (%s)", myversion);
tor_assert(0);
}
- version_sl = smartlist_create();
+ version_sl = smartlist_new();
smartlist_split_string(version_sl, versionlist, ",", SPLIT_SKIP_SPACE, 0);
if (!strlen(versionlist)) { /* no authorities cared or agreed */
@@ -826,7 +827,7 @@ router_parse_directory(const char *str)
int r;
const char *end, *cp, *str_dup = str;
smartlist_t *tokens = NULL;
- crypto_pk_env_t *declared_key = NULL;
+ crypto_pk_t *declared_key = NULL;
memarea_t *area = memarea_new();
/* XXXX This could be simplified a lot, but it will all go away
@@ -847,7 +848,7 @@ router_parse_directory(const char *str)
log_warn(LD_DIR, "No signature found on directory."); goto err;
}
++cp;
- tokens = smartlist_create();
+ tokens = smartlist_new();
if (tokenize_string(area,cp,strchr(cp,'\0'),tokens,dir_token_table,0)) {
log_warn(LD_DIR, "Error tokenizing directory signature"); goto err;
}
@@ -900,7 +901,7 @@ router_parse_directory(const char *str)
dump_desc(str_dup, "v1 directory");
r = -1;
done:
- if (declared_key) crypto_free_pk_env(declared_key);
+ if (declared_key) crypto_pk_free(declared_key);
if (tokens) {
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
@@ -922,7 +923,7 @@ router_parse_runningrouters(const char *str)
directory_token_t *tok;
time_t published_on;
int r = -1;
- crypto_pk_env_t *declared_key = NULL;
+ crypto_pk_t *declared_key = NULL;
smartlist_t *tokens = NULL;
const char *eos = str + strlen(str), *str_dup = str;
memarea_t *area = NULL;
@@ -932,7 +933,7 @@ router_parse_runningrouters(const char *str)
goto err;
}
area = memarea_new();
- tokens = smartlist_create();
+ tokens = smartlist_new();
if (tokenize_string(area,str,eos,tokens,dir_token_table,0)) {
log_warn(LD_DIR, "Error tokenizing running-routers"); goto err;
}
@@ -966,7 +967,7 @@ router_parse_runningrouters(const char *str)
r = 0;
err:
dump_desc(str_dup, "v1 running-routers");
- if (declared_key) crypto_free_pk_env(declared_key);
+ if (declared_key) crypto_pk_free(declared_key);
if (tokens) {
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
@@ -981,12 +982,12 @@ router_parse_runningrouters(const char *str)
/** Given a directory or running-routers string in <b>str</b>, try to
* find the its dir-signing-key token (if any). If this token is
* present, extract and return the key. Return NULL on failure. */
-static crypto_pk_env_t *
+static crypto_pk_t *
find_dir_signing_key(const char *str, const char *eos)
{
const char *cp;
directory_token_t *tok;
- crypto_pk_env_t *key = NULL;
+ crypto_pk_t *key = NULL;
memarea_t *area = NULL;
tor_assert(str);
tor_assert(eos);
@@ -1029,7 +1030,7 @@ find_dir_signing_key(const char *str, const char *eos)
/** Return true iff <b>key</b> is allowed to sign directories.
*/
static int
-dir_signing_key_is_trusted(crypto_pk_env_t *key)
+dir_signing_key_is_trusted(crypto_pk_t *key)
{
char digest[DIGEST_LEN];
if (!key) return 0;
@@ -1056,7 +1057,7 @@ static int
check_signature_token(const char *digest,
ssize_t digest_len,
directory_token_t *tok,
- crypto_pk_env_t *pkey,
+ crypto_pk_t *pkey,
int flags,
const char *doctype)
{
@@ -1261,7 +1262,7 @@ dump_distinct_digest_count(int severity)
* s through end into the signed_descriptor_body of the resulting
* routerinfo_t.
*
- * If <b>end</b> is NULL, <b>s</b> must be properly NULL-terminated.
+ * If <b>end</b> is NULL, <b>s</b> must be properly NUL-terminated.
*
* If <b>allow_annotations</b>, it's okay to encounter annotations in <b>s</b>
* before the router; if it's false, reject the router if it's annotated. If
@@ -1297,7 +1298,7 @@ router_parse_entry_from_string(const char *s, const char *end,
--end;
area = memarea_new();
- tokens = smartlist_create();
+ tokens = smartlist_new();
if (prepend_annotations) {
if (tokenize_string(area,prepend_annotations,NULL,tokens,
routerdesc_token_table,TS_NOCHECK)) {
@@ -1357,7 +1358,6 @@ router_parse_entry_from_string(const char *s, const char *end,
tor_assert(tok->n_args >= 5);
router = tor_malloc_zero(sizeof(routerinfo_t));
- router->country = -1;
router->cache_info.routerlist_index = -1;
router->cache_info.annotations_len = s-start_of_annotations + prepend_len;
router->cache_info.signed_descriptor_len = end-s;
@@ -1503,19 +1503,33 @@ router_parse_entry_from_string(const char *s, const char *end,
router->contact_info = tor_strdup(tok->args[0]);
}
- if ((tok = find_opt_by_keyword(tokens, K_EVENTDNS))) {
- router->has_old_dnsworkers = tok->n_args && !strcmp(tok->args[0], "0");
- } else if (router->platform) {
- if (! tor_version_as_new_as(router->platform, "0.1.2.2-alpha"))
- router->has_old_dnsworkers = 1;
- }
-
if (find_opt_by_keyword(tokens, K_REJECT6) ||
find_opt_by_keyword(tokens, K_ACCEPT6)) {
log_warn(LD_DIR, "Rejecting router with reject6/accept6 line: they crash "
"older Tors.");
goto err;
}
+ {
+ smartlist_t *or_addresses = find_all_by_keyword(tokens, K_OR_ADDRESS);
+ if (or_addresses) {
+ SMARTLIST_FOREACH_BEGIN(or_addresses, directory_token_t *, t) {
+ tor_addr_t a;
+ maskbits_t bits;
+ uint16_t port_min, port_max;
+ /* XXXX Prop186 the full spec allows much more than this. */
+ if (tor_addr_parse_mask_ports(t->args[0], &a, &bits, &port_min,
+ &port_max) == AF_INET6 &&
+ bits == 128 &&
+ port_min == port_max) {
+ /* Okay, this is one we can understand. */
+ tor_addr_copy(&router->ipv6_addr, &a);
+ router->ipv6_orport = port_min;
+ break;
+ }
+ } SMARTLIST_FOREACH_END(t);
+ smartlist_free(or_addresses);
+ }
+ }
exit_policy_tokens = find_all_exitpolicy(tokens);
if (!smartlist_len(exit_policy_tokens)) {
log_warn(LD_DIR, "No exit policy tokens in descriptor.");
@@ -1532,7 +1546,7 @@ router_parse_entry_from_string(const char *s, const char *end,
if ((tok = find_opt_by_keyword(tokens, K_FAMILY)) && tok->n_args) {
int i;
- router->declared_family = smartlist_create();
+ router->declared_family = smartlist_new();
for (i=0;i<tok->n_args;++i) {
if (!is_legal_nickname_or_hexdigest(tok->args[i])) {
log_warn(LD_DIR, "Illegal nickname %s in family line",
@@ -1574,8 +1588,6 @@ router_parse_entry_from_string(const char *s, const char *end,
"router descriptor") < 0)
goto err;
- routerinfo_set_country(router);
-
if (!router->or_port) {
log_warn(LD_DIR,"or_port unreadable or 0. Failing.");
goto err;
@@ -1618,7 +1630,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
char digest[128];
smartlist_t *tokens = NULL;
directory_token_t *tok;
- crypto_pk_env_t *key = NULL;
+ crypto_pk_t *key = NULL;
routerinfo_t *router = NULL;
memarea_t *area = NULL;
const char *s_dup = s;
@@ -1631,11 +1643,11 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
while (end > s+2 && *(end-1) == '\n' && *(end-2) == '\n')
--end;
- if (router_get_extrainfo_hash(s, digest) < 0) {
+ if (router_get_extrainfo_hash(s, end-s, digest) < 0) {
log_warn(LD_DIR, "Couldn't compute router hash.");
goto err;
}
- tokens = smartlist_create();
+ tokens = smartlist_new();
area = memarea_new();
if (tokenize_string(area,s,end,tokens,extrainfo_token_table,0)) {
log_warn(LD_DIR, "Error tokenizing extra-info document.");
@@ -1768,7 +1780,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
return NULL;
}
- tokens = smartlist_create();
+ tokens = smartlist_new();
area = memarea_new();
if (tokenize_string(area,s, eos, tokens, dir_key_certificate_table, 0) < 0) {
log_warn(LD_DIR, "Error tokenizing key certificate");
@@ -1823,9 +1835,9 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
struct in_addr in;
char *address = NULL;
tor_assert(tok->n_args);
- /* XXX023 use tor_addr_port_parse() below instead. -RD */
- if (parse_addr_port(LOG_WARN, tok->args[0], &address, NULL,
- &cert->dir_port)<0 ||
+ /* XXX023 use some tor_addr parse function below instead. -RD */
+ if (tor_addr_port_split(LOG_WARN, tok->args[0], &address,
+ &cert->dir_port) < 0 ||
tor_inet_aton(address, &in) == 0) {
log_warn(LD_DIR, "Couldn't parse dir-address in certificate");
tor_free(address);
@@ -1975,6 +1987,7 @@ routerstatus_parse_entry_from_string(memarea_t *area,
if (!consensus_method)
flav = FLAV_NS;
+ tor_assert(flav == FLAV_NS || flav == FLAV_MICRODESC);
eos = find_start_of_next_routerstatus(*s);
@@ -1987,15 +2000,16 @@ routerstatus_parse_entry_from_string(memarea_t *area,
goto err;
}
tok = find_by_keyword(tokens, K_R);
- tor_assert(tok->n_args >= 7);
+ tor_assert(tok->n_args >= 7); /* guaranteed by GE(7) in K_R setup */
if (flav == FLAV_NS) {
if (tok->n_args < 8) {
log_warn(LD_DIR, "Too few arguments to r");
goto err;
}
- } else {
- offset = -1;
+ } else if (flav == FLAV_MICRODESC) {
+ offset = -1; /* There is no identity digest */
}
+
if (vote_rs) {
rs = &vote_rs->status;
} else {
@@ -2069,7 +2083,7 @@ routerstatus_parse_entry_from_string(memarea_t *area,
else if (!strcmp(tok->args[i], "Fast"))
rs->is_fast = 1;
else if (!strcmp(tok->args[i], "Running"))
- rs->is_running = 1;
+ rs->is_flagged_running = 1;
else if (!strcmp(tok->args[i], "Named"))
rs->is_named = 1;
else if (!strcmp(tok->args[i], "Valid"))
@@ -2100,6 +2114,8 @@ routerstatus_parse_entry_from_string(memarea_t *area,
rs->version_supports_begindir = 1;
rs->version_supports_extrainfo_upload = 1;
rs->version_supports_conditional_consensus = 1;
+ rs->version_supports_microdesc_cache = 1;
+ rs->version_supports_optimistic_data = 1;
} else {
rs->version_supports_begindir =
tor_version_as_new_as(tok->args[0], "0.2.0.1-alpha");
@@ -2109,6 +2125,10 @@ routerstatus_parse_entry_from_string(memarea_t *area,
tor_version_as_new_as(tok->args[0], "0.2.0.8-alpha");
rs->version_supports_conditional_consensus =
tor_version_as_new_as(tok->args[0], "0.2.1.1-alpha");
+ rs->version_supports_microdesc_cache =
+ tor_version_supports_microdescriptors(tok->args[0]);
+ rs->version_supports_optimistic_data =
+ tor_version_as_new_as(tok->args[0], "0.2.3.1-alpha");
}
if (vote_rs) {
vote_rs->version = tor_strdup(tok->args[0]);
@@ -2171,6 +2191,16 @@ routerstatus_parse_entry_from_string(memarea_t *area,
vote_rs->microdesc = line;
}
} SMARTLIST_FOREACH_END(t);
+ } else if (flav == FLAV_MICRODESC) {
+ tok = find_opt_by_keyword(tokens, K_M);
+ if (tok) {
+ tor_assert(tok->n_args);
+ if (digest256_from_base64(rs->descriptor_digest, tok->args[0])) {
+ log_warn(LD_DIR, "Error decoding microdescriptor digest %s",
+ escaped(tok->args[0]));
+ goto err;
+ }
+ }
}
if (!strcasecmp(rs->nickname, UNNAMED_ROUTER_NICKNAME))
@@ -2221,8 +2251,8 @@ networkstatus_v2_t *
networkstatus_v2_parse_from_string(const char *s)
{
const char *eos, *s_dup = s;
- smartlist_t *tokens = smartlist_create();
- smartlist_t *footer_tokens = smartlist_create();
+ smartlist_t *tokens = smartlist_new();
+ smartlist_t *footer_tokens = smartlist_new();
networkstatus_v2_t *ns = NULL;
char ns_digest[DIGEST_LEN];
char tmp_digest[DIGEST_LEN];
@@ -2332,7 +2362,7 @@ networkstatus_v2_parse_from_string(const char *s)
goto err;
}
- ns->entries = smartlist_create();
+ ns->entries = smartlist_new();
s = eos;
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
@@ -2779,7 +2809,7 @@ networkstatus_t *
networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
networkstatus_type_t ns_type)
{
- smartlist_t *tokens = smartlist_create();
+ smartlist_t *tokens = smartlist_new();
smartlist_t *rs_tokens = NULL, *footer_tokens = NULL;
networkstatus_voter_info_t *voter = NULL;
networkstatus_t *ns = NULL;
@@ -2791,6 +2821,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
int i, inorder, n_signatures = 0;
memarea_t *area = NULL, *rs_area = NULL;
consensus_flavor_t flav = FLAV_NS;
+ char *last_kwd=NULL;
tor_assert(s);
@@ -2864,7 +2895,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
if (parse_iso_time(tok->args[0], &ns->published))
goto err;
- ns->supported_methods = smartlist_create();
+ ns->supported_methods = smartlist_new();
tok = find_opt_by_keyword(tokens, K_CONSENSUS_METHODS);
if (tok) {
for (i=0; i < tok->n_args; ++i)
@@ -2931,7 +2962,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
}
tok = find_by_keyword(tokens, K_KNOWN_FLAGS);
- ns->known_flags = smartlist_create();
+ ns->known_flags = smartlist_new();
inorder = 1;
for (i = 0; i < tok->n_args; ++i) {
smartlist_add(ns->known_flags, tor_strdup(tok->args[i]));
@@ -2947,15 +2978,18 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
tok = find_opt_by_keyword(tokens, K_PARAMS);
if (tok) {
+ int any_dups = 0;
inorder = 1;
- ns->net_params = smartlist_create();
+ ns->net_params = smartlist_new();
for (i = 0; i < tok->n_args; ++i) {
int ok=0;
char *eq = strchr(tok->args[i], '=');
+ size_t eq_pos;
if (!eq) {
log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
goto err;
}
+ eq_pos = eq-tok->args[i];
tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
if (!ok) {
log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
@@ -2965,15 +2999,27 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
log_warn(LD_DIR, "%s >= %s", tok->args[i-1], tok->args[i]);
inorder = 0;
}
+ if (last_kwd && eq_pos == strlen(last_kwd) &&
+ fast_memeq(last_kwd, tok->args[i], eq_pos)) {
+ log_warn(LD_DIR, "Duplicate value for %s parameter",
+ escaped(tok->args[i]));
+ any_dups = 1;
+ }
+ tor_free(last_kwd);
+ last_kwd = tor_strndup(tok->args[i], eq_pos);
smartlist_add(ns->net_params, tor_strdup(tok->args[i]));
}
if (!inorder) {
log_warn(LD_DIR, "params not in order");
goto err;
}
+ if (any_dups) {
+ log_warn(LD_DIR, "Duplicate in parameters");
+ goto err;
+ }
}
- ns->voters = smartlist_create();
+ ns->voters = smartlist_new();
SMARTLIST_FOREACH_BEGIN(tokens, directory_token_t *, _tok) {
tok = _tok;
@@ -2983,7 +3029,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
if (voter)
smartlist_add(ns->voters, voter);
voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
- voter->sigs = smartlist_create();
+ voter->sigs = smartlist_new();
if (ns->type != NS_TYPE_CONSENSUS)
memcpy(voter->vote_digest, ns_digests.d[DIGEST_SHA1], DIGEST_LEN);
@@ -3068,10 +3114,10 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
}
/* Parse routerstatus lines. */
- rs_tokens = smartlist_create();
+ rs_tokens = smartlist_new();
rs_area = memarea_new();
s = end_of_header;
- ns->routerstatus_list = smartlist_create();
+ ns->routerstatus_list = smartlist_new();
while (!strcmpstart(s, "r ")) {
if (ns->type != NS_TYPE_CONSENSUS) {
@@ -3111,7 +3157,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
}
/* Parse footer; check signature. */
- footer_tokens = smartlist_create();
+ footer_tokens = smartlist_new();
if ((end_of_footer = strstr(s, "\nnetwork-status-version ")))
++end_of_footer;
else
@@ -3144,7 +3190,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
tok = find_opt_by_keyword(footer_tokens, K_BW_WEIGHTS);
if (tok) {
- ns->weight_params = smartlist_create();
+ ns->weight_params = smartlist_new();
for (i = 0; i < tok->n_args; ++i) {
int ok=0;
char *eq = strchr(tok->args[i], '=');
@@ -3309,6 +3355,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
}
if (rs_area)
memarea_drop_all(rs_area);
+ tor_free(last_kwd);
return ns;
}
@@ -3336,7 +3383,7 @@ detached_get_signatures(ns_detached_signatures_t *sigs,
{
smartlist_t *sl = strmap_get(sigs->signatures, flavor_name);
if (!sl) {
- sl = smartlist_create();
+ sl = smartlist_new();
strmap_set(sigs->signatures, flavor_name, sl);
}
return sl;
@@ -3353,7 +3400,7 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
memarea_t *area = NULL;
digests_t *digests;
- smartlist_t *tokens = smartlist_create();
+ smartlist_t *tokens = smartlist_new();
ns_detached_signatures_t *sigs =
tor_malloc_zero(sizeof(ns_detached_signatures_t));
sigs->digests = strmap_new();
@@ -3502,10 +3549,10 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
siglist = detached_get_signatures(sigs, flavor);
is_duplicate = 0;
- SMARTLIST_FOREACH(siglist, document_signature_t *, s, {
- if (s->alg == alg &&
- tor_memeq(id_digest, s->identity_digest, DIGEST_LEN) &&
- tor_memeq(sk_digest, s->signing_key_digest, DIGEST_LEN)) {
+ SMARTLIST_FOREACH(siglist, document_signature_t *, dsig, {
+ if (dsig->alg == alg &&
+ tor_memeq(id_digest, dsig->identity_digest, DIGEST_LEN) &&
+ tor_memeq(sk_digest, dsig->signing_key_digest, DIGEST_LEN)) {
is_duplicate = 1;
}
});
@@ -3608,7 +3655,7 @@ router_add_exit_policy(routerinfo_t *router, directory_token_t *tok)
if (!newe)
return -1;
if (! router->exit_policy)
- router->exit_policy = smartlist_create();
+ router->exit_policy = smartlist_new();
if (((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
tor_addr_family(&newe->addr) == AF_INET)
@@ -3716,7 +3763,7 @@ static void
token_clear(directory_token_t *tok)
{
if (tok->key)
- crypto_free_pk_env(tok->key);
+ crypto_pk_free(tok->key);
}
#define ALLOC_ZERO(sz) memarea_alloc_zero(area,sz)
@@ -3962,11 +4009,11 @@ get_next_token(memarea_t *area,
RET_ERR("Couldn't parse object: missing footer or object much too big.");
if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */
- tok->key = crypto_new_pk_env();
+ tok->key = crypto_pk_new();
if (crypto_pk_read_public_key_from_string(tok->key, obstart, eol-obstart))
RET_ERR("Couldn't parse public key.");
} else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */
- tok->key = crypto_new_pk_env();
+ tok->key = crypto_pk_new();
if (crypto_pk_read_private_key_from_string(tok->key, obstart, eol-obstart))
RET_ERR("Couldn't parse private key.");
} else { /* If it's something else, try to base64-decode it */
@@ -4122,13 +4169,27 @@ _find_by_keyword(smartlist_t *s, directory_keyword keyword,
return tok;
}
+/** DOCDOC */
+static smartlist_t *
+find_all_by_keyword(smartlist_t *s, directory_keyword k)
+{
+ smartlist_t *out = NULL;
+ SMARTLIST_FOREACH(s, directory_token_t *, t,
+ if (t->tp == k) {
+ if (!out)
+ out = smartlist_new();
+ smartlist_add(out, t);
+ });
+ return out;
+}
+
/** Return a newly allocated smartlist of all accept or reject tokens in
* <b>s</b>.
*/
static smartlist_t *
find_all_exitpolicy(smartlist_t *s)
{
- smartlist_t *out = smartlist_create();
+ smartlist_t *out = smartlist_new();
SMARTLIST_FOREACH(s, directory_token_t *, t,
if (t->tp == K_ACCEPT || t->tp == K_ACCEPT6 ||
t->tp == K_REJECT || t->tp == K_REJECT6)
@@ -4300,8 +4361,8 @@ microdescs_parse_from_string(const char *s, const char *eos,
s = eat_whitespace_eos(s, eos);
area = memarea_new();
- result = smartlist_create();
- tokens = smartlist_create();
+ result = smartlist_new();
+ tokens = smartlist_new();
while (s < eos) {
start_of_next_microdesc = find_start_of_next_microdesc(s, eos);
@@ -4346,7 +4407,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
if ((tok = find_opt_by_keyword(tokens, K_FAMILY))) {
int i;
- md->family = smartlist_create();
+ md->family = smartlist_new();
for (i=0;i<tok->n_args;++i) {
if (!is_legal_nickname_or_hexdigest(tok->args[i])) {
log_warn(LD_DIR, "Illegal nickname %s in family line",
@@ -4358,7 +4419,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
}
if ((tok = find_opt_by_keyword(tokens, K_P))) {
- md->exitsummary = tor_strdup(tok->args[0]);
+ md->exit_policy = parse_short_policy(tok->args[0]);
}
crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256);
@@ -4381,6 +4442,14 @@ microdescs_parse_from_string(const char *s, const char *eos,
return result;
}
+/** Return true iff this Tor version can answer directory questions
+ * about microdescriptors. */
+int
+tor_version_supports_microdescriptors(const char *platform)
+{
+ return tor_version_as_new_as(platform, "0.2.3.1-alpha");
+}
+
/** Parse the Tor version of the platform string <b>platform</b>,
* and compare it to the version in <b>cutoff</b>. Return 1 if
* the router is at least as new as the cutoff, else return 0.
@@ -4621,7 +4690,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
tor_malloc_zero(sizeof(rend_service_descriptor_t));
char desc_hash[DIGEST_LEN];
const char *eos;
- smartlist_t *tokens = smartlist_create();
+ smartlist_t *tokens = smartlist_new();
directory_token_t *tok;
char secret_id_part[DIGEST_LEN];
int i, version, num_ok=1;
@@ -4730,7 +4799,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
/* Parse protocol versions. */
tok = find_by_keyword(tokens, R_PROTOCOL_VERSIONS);
tor_assert(tok->n_args == 1);
- versions = smartlist_create();
+ versions = smartlist_new();
smartlist_split_string(versions, tok->args[0], ",",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
for (i = 0; i < smartlist_len(versions); i++) {
@@ -4813,8 +4882,8 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
session_key[CIPHER_KEY_LEN], *dec;
int declen, client_blocks;
size_t pos = 0, len, client_entries_len;
- crypto_digest_env_t *digest;
- crypto_cipher_env_t *cipher;
+ crypto_digest_t *digest;
+ crypto_cipher_t *cipher;
client_blocks = (int) ipos_encrypted[1];
client_entries_len = client_blocks * REND_BASIC_AUTH_CLIENT_MULTIPLE *
REND_BASIC_AUTH_CLIENT_ENTRY_LEN;
@@ -4824,33 +4893,33 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
return -1;
}
memcpy(iv, ipos_encrypted + 2 + client_entries_len, CIPHER_IV_LEN);
- digest = crypto_new_digest_env();
+ digest = crypto_digest_new();
crypto_digest_add_bytes(digest, descriptor_cookie, REND_DESC_COOKIE_LEN);
crypto_digest_add_bytes(digest, iv, CIPHER_IV_LEN);
crypto_digest_get_digest(digest, client_id,
REND_BASIC_AUTH_CLIENT_ID_LEN);
- crypto_free_digest_env(digest);
+ crypto_digest_free(digest);
for (pos = 2; pos < 2 + client_entries_len;
pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN) {
if (tor_memeq(ipos_encrypted + pos, client_id,
REND_BASIC_AUTH_CLIENT_ID_LEN)) {
/* Attempt to decrypt introduction points. */
- cipher = crypto_create_init_cipher(descriptor_cookie, 0);
+ cipher = crypto_cipher_new(descriptor_cookie);
if (crypto_cipher_decrypt(cipher, session_key, ipos_encrypted
+ pos + REND_BASIC_AUTH_CLIENT_ID_LEN,
CIPHER_KEY_LEN) < 0) {
log_warn(LD_REND, "Could not decrypt session key for client.");
- crypto_free_cipher_env(cipher);
+ crypto_cipher_free(cipher);
return -1;
}
- crypto_free_cipher_env(cipher);
- cipher = crypto_create_init_cipher(session_key, 0);
+ crypto_cipher_free(cipher);
+
len = ipos_encrypted_size - 2 - client_entries_len - CIPHER_IV_LEN;
dec = tor_malloc(len);
- declen = crypto_cipher_decrypt_with_iv(cipher, dec, len,
+ declen = crypto_cipher_decrypt_with_iv(session_key, dec, len,
ipos_encrypted + 2 + client_entries_len,
ipos_encrypted_size - 2 - client_entries_len);
- crypto_free_cipher_env(cipher);
+
if (declen < 0) {
log_warn(LD_REND, "Could not decrypt introduction point string.");
tor_free(dec);
@@ -4871,7 +4940,6 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
"check your authorization for this service!");
return -1;
} else if (ipos_encrypted[0] == (int)REND_STEALTH_AUTH) {
- crypto_cipher_env_t *cipher;
char *dec;
int declen;
if (ipos_encrypted_size < CIPHER_IV_LEN + 2) {
@@ -4880,13 +4948,13 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
return -1;
}
dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1);
- cipher = crypto_create_init_cipher(descriptor_cookie, 0);
- declen = crypto_cipher_decrypt_with_iv(cipher, dec,
+
+ declen = crypto_cipher_decrypt_with_iv(descriptor_cookie, dec,
ipos_encrypted_size -
CIPHER_IV_LEN - 1,
ipos_encrypted + 1,
ipos_encrypted_size - 1);
- crypto_free_cipher_env(cipher);
+
if (declen < 0) {
log_warn(LD_REND, "Decrypting introduction points failed!");
tor_free(dec);
@@ -4926,8 +4994,8 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
/* Consider one intro point after the other. */
current_ipo = intro_points_encoded;
end_of_intro_points = intro_points_encoded + intro_points_encoded_size;
- tokens = smartlist_create();
- parsed->intro_nodes = smartlist_create();
+ tokens = smartlist_new();
+ parsed->intro_nodes = smartlist_new();
area = memarea_new();
while (!fast_memcmpstart(current_ipo, end_of_intro_points-current_ipo,
@@ -4974,7 +5042,7 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
info->identity_digest, DIGEST_LEN);
/* Parse IP address. */
tok = find_by_keyword(tokens, R_IPO_IP_ADDRESS);
- if (tor_addr_from_str(&info->addr, tok->args[0])<0) {
+ if (tor_addr_parse(&info->addr, tok->args[0])<0) {
log_warn(LD_REND, "Could not parse introduction point address.");
rend_intro_point_free(intro);
goto err;
@@ -5048,7 +5116,7 @@ rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr)
memarea_t *area = NULL;
if (!ckstr || strlen(ckstr) == 0)
return -1;
- tokens = smartlist_create();
+ tokens = smartlist_new();
/* Begin parsing with first entry, skipping comments or whitespace at the
* beginning. */
area = memarea_new();
@@ -5120,9 +5188,9 @@ rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr)
/* The size of descriptor_cookie_tmp needs to be REND_DESC_COOKIE_LEN+2,
* because a base64 encoding of length 24 does not fit into 16 bytes in all
* cases. */
- if ((base64_decode(descriptor_cookie_tmp, REND_DESC_COOKIE_LEN+2,
- tok->args[0], REND_DESC_COOKIE_LEN_BASE64+2+1)
- != REND_DESC_COOKIE_LEN)) {
+ if (base64_decode(descriptor_cookie_tmp, sizeof(descriptor_cookie_tmp),
+ tok->args[0], strlen(tok->args[0]))
+ != REND_DESC_COOKIE_LEN) {
log_warn(LD_REND, "Descriptor cookie contains illegal characters: "
"%s", escaped(tok->args[0]));
goto err;