Line data Source code
1 : /* Copyright (c) 2001 Matej Pfajfar.
2 : * Copyright (c) 2001-2004, Roger Dingledine.
3 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 : /* See LICENSE for licensing information */
6 :
7 : /**
8 : * \file routerparse.c
9 : * \brief Code to parse and validate router descriptors, consenus directories,
10 : * and similar objects.
11 : *
12 : * The objects parsed by this module use a common text-based metaformat,
13 : * documented in dir-spec.txt in torspec.git. This module is itself divided
14 : * into two major kinds of function: code to handle the metaformat, and code
15 : * to convert from particular instances of the metaformat into the
16 : * objects that Tor uses.
17 : *
18 : * The generic parsing code works by calling a table-based tokenizer on the
19 : * input string. Each token corresponds to a single line with a token, plus
20 : * optional arguments on that line, plus an optional base-64 encoded object
21 : * after that line. Each token has a definition in a table of token_rule_t
22 : * entries that describes how many arguments it can take, whether it takes an
23 : * object, how many times it may appear, whether it must appear first, and so
24 : * on.
25 : *
26 : * The tokenizer function tokenize_string() converts its string input into a
27 : * smartlist full of instances of directory_token_t, according to a provided
28 : * table of token_rule_t.
29 : *
30 : * The generic parts of this module additionally include functions for
31 : * finding the start and end of signed information inside a signed object, and
32 : * computing the digest that will be signed.
33 : *
34 : * There are also functions for saving objects to disk that have caused
35 : * parsing to fail.
36 : *
37 : * The specific parts of this module describe conversions between
38 : * particular lists of directory_token_t and particular objects. The
39 : * kinds of objects that can be parsed here are:
40 : * <ul>
41 : * <li>router descriptors (managed from routerlist.c)
42 : * <li>extra-info documents (managed from routerlist.c)
43 : * <li>microdescriptors (managed from microdesc.c)
44 : * <li>vote and consensus networkstatus documents, and the routerstatus_t
45 : * objects that they comprise (managed from networkstatus.c)
46 : * <li>detached-signature objects used by authorities for gathering
47 : * signatures on the networkstatus consensus (managed from dirvote.c)
48 : * <li>authority key certificates (managed from routerlist.c)
49 : * <li>hidden service descriptors (managed from rendcommon.c and rendcache.c)
50 : * </ul>
51 : **/
52 :
53 : #define ROUTERDESC_TOKEN_TABLE_PRIVATE
54 :
55 : #include "core/or/or.h"
56 : #include "app/config/config.h"
57 : #include "core/or/policies.h"
58 : #include "core/or/versions.h"
59 : #include "feature/dirparse/parsecommon.h"
60 : #include "feature/dirparse/policy_parse.h"
61 : #include "feature/dirparse/routerparse.h"
62 : #include "feature/dirparse/sigcommon.h"
63 : #include "feature/dirparse/unparseable.h"
64 : #include "feature/nodelist/describe.h"
65 : #include "feature/nodelist/nickname.h"
66 : #include "feature/nodelist/routerinfo.h"
67 : #include "feature/nodelist/routerlist.h"
68 : #include "feature/nodelist/torcert.h"
69 : #include "feature/relay/router.h"
70 : #include "lib/crypt_ops/crypto_curve25519.h"
71 : #include "lib/crypt_ops/crypto_ed25519.h"
72 : #include "lib/crypt_ops/crypto_format.h"
73 : #include "lib/memarea/memarea.h"
74 : #include "lib/sandbox/sandbox.h"
75 :
76 : #include "core/or/addr_policy_st.h"
77 : #include "feature/nodelist/extrainfo_st.h"
78 : #include "feature/nodelist/routerinfo_st.h"
79 : #include "feature/nodelist/routerlist_st.h"
80 :
81 : /****************************************************************************/
82 :
83 : /** List of tokens recognized in router descriptors */
84 : // clang-format off
85 : const token_rule_t routerdesc_token_table[] = {
86 : T0N("reject", K_REJECT, ARGS, NO_OBJ ),
87 : T0N("accept", K_ACCEPT, ARGS, NO_OBJ ),
88 : T0N("reject6", K_REJECT6, ARGS, NO_OBJ ),
89 : T0N("accept6", K_ACCEPT6, ARGS, NO_OBJ ),
90 : T1_START( "router", K_ROUTER, GE(5), NO_OBJ ),
91 : T01("ipv6-policy", K_IPV6_POLICY, CONCAT_ARGS, NO_OBJ),
92 : T1( "signing-key", K_SIGNING_KEY, NO_ARGS, NEED_KEY_1024 ),
93 : T1( "onion-key", K_ONION_KEY, NO_ARGS, NEED_KEY_1024 ),
94 : T1("ntor-onion-key", K_ONION_KEY_NTOR, GE(1), NO_OBJ ),
95 : T1_END( "router-signature", K_ROUTER_SIGNATURE, NO_ARGS, NEED_OBJ ),
96 : T1( "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ ),
97 : T01("uptime", K_UPTIME, GE(1), NO_OBJ ),
98 : T01("fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ),
99 : T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ ),
100 : T01("platform", K_PLATFORM, CONCAT_ARGS, NO_OBJ ),
101 : T1("proto", K_PROTO, CONCAT_ARGS, NO_OBJ ),
102 : T01("contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ),
103 : T01("read-history", K_READ_HISTORY, ARGS, NO_OBJ ),
104 : T01("write-history", K_WRITE_HISTORY, ARGS, NO_OBJ ),
105 : T01("extra-info-digest", K_EXTRA_INFO_DIGEST, GE(1), NO_OBJ ),
106 : T01("hidden-service-dir", K_HIDDEN_SERVICE_DIR, NO_ARGS, NO_OBJ ),
107 : T1("identity-ed25519", K_IDENTITY_ED25519, NO_ARGS, NEED_OBJ ),
108 : T1("master-key-ed25519", K_MASTER_KEY_ED25519, GE(1), NO_OBJ ),
109 : T1("router-sig-ed25519", K_ROUTER_SIG_ED25519, GE(1), NO_OBJ ),
110 : T1("onion-key-crosscert", K_ONION_KEY_CROSSCERT, NO_ARGS, NEED_OBJ ),
111 : T1("ntor-onion-key-crosscert", K_NTOR_ONION_KEY_CROSSCERT,
112 : EQ(1), NEED_OBJ ),
113 :
114 : T01("allow-single-hop-exits",K_ALLOW_SINGLE_HOP_EXITS, NO_ARGS, NO_OBJ ),
115 :
116 : T01("family", K_FAMILY, ARGS, NO_OBJ ),
117 : T01("caches-extra-info", K_CACHES_EXTRA_INFO, NO_ARGS, NO_OBJ ),
118 : T0N("or-address", K_OR_ADDRESS, GE(1), NO_OBJ ),
119 :
120 : T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
121 : T1( "bandwidth", K_BANDWIDTH, GE(3), NO_OBJ ),
122 : A01("@purpose", A_PURPOSE, GE(1), NO_OBJ ),
123 : T01("tunnelled-dir-server",K_DIR_TUNNELLED, NO_ARGS, NO_OBJ ),
124 :
125 : END_OF_TABLE
126 : };
127 : // clang-format on
128 :
129 : /** List of tokens recognized in extra-info documents. */
130 : // clang-format off
131 : static token_rule_t extrainfo_token_table[] = {
132 : T1_END( "router-signature", K_ROUTER_SIGNATURE, NO_ARGS, NEED_OBJ ),
133 : T1( "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ ),
134 : T1("identity-ed25519", K_IDENTITY_ED25519, NO_ARGS, NEED_OBJ ),
135 : T1("router-sig-ed25519", K_ROUTER_SIG_ED25519, GE(1), NO_OBJ ),
136 : T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
137 : T01("read-history", K_READ_HISTORY, ARGS, NO_OBJ ),
138 : T01("write-history", K_WRITE_HISTORY, ARGS, NO_OBJ ),
139 : T01("dirreq-stats-end", K_DIRREQ_END, ARGS, NO_OBJ ),
140 : T01("dirreq-v2-ips", K_DIRREQ_V2_IPS, ARGS, NO_OBJ ),
141 : T01("dirreq-v3-ips", K_DIRREQ_V3_IPS, ARGS, NO_OBJ ),
142 : T01("dirreq-v2-reqs", K_DIRREQ_V2_REQS, ARGS, NO_OBJ ),
143 : T01("dirreq-v3-reqs", K_DIRREQ_V3_REQS, ARGS, NO_OBJ ),
144 : T01("dirreq-v2-share", K_DIRREQ_V2_SHARE, ARGS, NO_OBJ ),
145 : T01("dirreq-v3-share", K_DIRREQ_V3_SHARE, ARGS, NO_OBJ ),
146 : T01("dirreq-v2-resp", K_DIRREQ_V2_RESP, ARGS, NO_OBJ ),
147 : T01("dirreq-v3-resp", K_DIRREQ_V3_RESP, ARGS, NO_OBJ ),
148 : T01("dirreq-v2-direct-dl", K_DIRREQ_V2_DIR, ARGS, NO_OBJ ),
149 : T01("dirreq-v3-direct-dl", K_DIRREQ_V3_DIR, ARGS, NO_OBJ ),
150 : T01("dirreq-v2-tunneled-dl", K_DIRREQ_V2_TUN, ARGS, NO_OBJ ),
151 : T01("dirreq-v3-tunneled-dl", K_DIRREQ_V3_TUN, ARGS, NO_OBJ ),
152 : T01("entry-stats-end", K_ENTRY_END, ARGS, NO_OBJ ),
153 : T01("entry-ips", K_ENTRY_IPS, ARGS, NO_OBJ ),
154 : T01("cell-stats-end", K_CELL_END, ARGS, NO_OBJ ),
155 : T01("cell-processed-cells", K_CELL_PROCESSED, ARGS, NO_OBJ ),
156 : T01("cell-queued-cells", K_CELL_QUEUED, ARGS, NO_OBJ ),
157 : T01("cell-time-in-queue", K_CELL_TIME, ARGS, NO_OBJ ),
158 : T01("cell-circuits-per-decile", K_CELL_CIRCS, ARGS, NO_OBJ ),
159 : T01("exit-stats-end", K_EXIT_END, ARGS, NO_OBJ ),
160 : T01("exit-kibibytes-written", K_EXIT_WRITTEN, ARGS, NO_OBJ ),
161 : T01("exit-kibibytes-read", K_EXIT_READ, ARGS, NO_OBJ ),
162 : T01("exit-streams-opened", K_EXIT_OPENED, ARGS, NO_OBJ ),
163 :
164 : T1_START( "extra-info", K_EXTRA_INFO, GE(2), NO_OBJ ),
165 :
166 : END_OF_TABLE
167 : };
168 : // clang-format on
169 :
170 : #undef T
171 :
172 : /* static function prototypes */
173 : static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
174 : static smartlist_t *find_all_exitpolicy(smartlist_t *s);
175 :
176 : /** Set <b>digest</b> to the SHA-1 digest of the hash of the first router in
177 : * <b>s</b>. Return 0 on success, -1 on failure.
178 : */
179 : int
180 309 : router_get_router_hash(const char *s, size_t s_len, char *digest)
181 : {
182 309 : return router_get_hash_impl(s, s_len, digest,
183 : "router ","\nrouter-signature", '\n',
184 : DIGEST_SHA1);
185 : }
186 :
187 : /** Set <b>digest</b> to the SHA-1 digest of the hash of the <b>s_len</b>-byte
188 : * extrainfo string at <b>s</b>. Return 0 on success, -1 on failure. */
189 : int
190 174 : router_get_extrainfo_hash(const char *s, size_t s_len, char *digest)
191 : {
192 174 : return router_get_hash_impl(s, s_len, digest, "extra-info",
193 : "\nrouter-signature",'\n', DIGEST_SHA1);
194 : }
195 :
196 : /** Helper: move *<b>s_ptr</b> ahead to the next router, the next extra-info,
197 : * or to the first of the annotations proceeding the next router or
198 : * extra-info---whichever comes first. Set <b>is_extrainfo_out</b> to true if
199 : * we found an extrainfo, or false if found a router. Do not scan beyond
200 : * <b>eos</b>. Return -1 if we found nothing; 0 if we found something. */
201 : static int
202 62 : find_start_of_next_router_or_extrainfo(const char **s_ptr,
203 : const char *eos,
204 : int *is_extrainfo_out)
205 : {
206 62 : const char *annotations = NULL;
207 62 : const char *s = *s_ptr;
208 :
209 62 : s = eat_whitespace_eos(s, eos);
210 :
211 110 : while (s < eos-32) { /* 32 gives enough room for a the first keyword. */
212 : /* We're at the start of a line. */
213 103 : tor_assert(*s != '\n');
214 :
215 103 : if (*s == '@' && !annotations) {
216 : annotations = s;
217 79 : } else if (*s == 'r' && !strcmpstart(s, "router ")) {
218 40 : *s_ptr = annotations ? annotations : s;
219 40 : *is_extrainfo_out = 0;
220 40 : return 0;
221 39 : } else if (*s == 'e' && !strcmpstart(s, "extra-info ")) {
222 15 : *s_ptr = annotations ? annotations : s;
223 15 : *is_extrainfo_out = 1;
224 15 : return 0;
225 : }
226 :
227 48 : if (!(s = memchr(s+1, '\n', eos-(s+1))))
228 : break;
229 48 : s = eat_whitespace_eos(s, eos);
230 : }
231 : return -1;
232 : }
233 :
234 : /** Given a string *<b>s</b> containing a concatenated sequence of router
235 : * descriptors (or extra-info documents if <b>want_extrainfo</b> is set),
236 : * parses them and stores the result in <b>dest</b>. All routers are marked
237 : * running and valid. Advances *s to a point immediately following the last
238 : * router entry. Ignore any trailing router entries that are not complete.
239 : *
240 : * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
241 : * descriptor in the signed_descriptor_body field of each routerinfo_t. If it
242 : * isn't SAVED_NOWHERE, remember the offset of each descriptor.
243 : *
244 : * Returns 0 on success and -1 on failure. Adds a digest to
245 : * <b>invalid_digests_out</b> for every entry that was unparseable or
246 : * invalid. (This may cause duplicate entries.)
247 : */
248 : int
249 7 : router_parse_list_from_string(const char **s, const char *eos,
250 : smartlist_t *dest,
251 : saved_location_t saved_location,
252 : int want_extrainfo,
253 : int allow_annotations,
254 : const char *prepend_annotations,
255 : smartlist_t *invalid_digests_out)
256 : {
257 7 : routerinfo_t *router;
258 7 : extrainfo_t *extrainfo;
259 7 : signed_descriptor_t *signed_desc = NULL;
260 7 : void *elt;
261 7 : const char *end, *start;
262 7 : int have_extrainfo;
263 :
264 7 : tor_assert(s);
265 7 : tor_assert(*s);
266 7 : tor_assert(dest);
267 :
268 7 : start = *s;
269 7 : if (!eos)
270 7 : eos = *s + strlen(*s);
271 :
272 7 : tor_assert(eos >= *s);
273 :
274 62 : while (1) {
275 62 : char raw_digest[DIGEST_LEN];
276 62 : int have_raw_digest = 0;
277 62 : int dl_again = 0;
278 62 : if (find_start_of_next_router_or_extrainfo(s, eos, &have_extrainfo) < 0)
279 : break;
280 :
281 55 : end = tor_memstr(*s, eos-*s, "\nrouter-signature");
282 55 : if (end)
283 55 : end = tor_memstr(end, eos-end, "\n-----END SIGNATURE-----\n");
284 55 : if (end)
285 55 : end += strlen("\n-----END SIGNATURE-----\n");
286 :
287 55 : if (!end)
288 : break;
289 :
290 55 : elt = NULL;
291 :
292 55 : if (have_extrainfo && want_extrainfo) {
293 10 : routerlist_t *rl = router_get_routerlist();
294 10 : have_raw_digest = router_get_extrainfo_hash(*s, end-*s, raw_digest) == 0;
295 10 : extrainfo = extrainfo_parse_entry_from_string(*s, end,
296 : saved_location != SAVED_IN_CACHE,
297 : rl->identity_map, &dl_again);
298 10 : if (extrainfo) {
299 4 : signed_desc = &extrainfo->cache_info;
300 4 : elt = extrainfo;
301 : }
302 45 : } else if (!have_extrainfo && !want_extrainfo) {
303 35 : have_raw_digest = router_get_router_hash(*s, end-*s, raw_digest) == 0;
304 35 : router = router_parse_entry_from_string(*s, end,
305 : saved_location != SAVED_IN_CACHE,
306 : allow_annotations,
307 : prepend_annotations, &dl_again);
308 35 : if (router) {
309 28 : log_debug(LD_DIR, "Read router '%s', purpose '%s'",
310 : router_describe(router),
311 : router_purpose_to_string(router->purpose));
312 28 : signed_desc = &router->cache_info;
313 28 : elt = router;
314 : }
315 : }
316 55 : if (! elt && ! dl_again && have_raw_digest && invalid_digests_out) {
317 11 : smartlist_add(invalid_digests_out, tor_memdup(raw_digest, DIGEST_LEN));
318 : }
319 55 : if (!elt) {
320 23 : *s = end;
321 23 : continue;
322 : }
323 32 : if (saved_location != SAVED_NOWHERE) {
324 28 : tor_assert(signed_desc);
325 28 : signed_desc->saved_location = saved_location;
326 28 : signed_desc->saved_offset = *s - start;
327 : }
328 32 : *s = end;
329 32 : smartlist_add(dest, elt);
330 : }
331 :
332 7 : return 0;
333 : }
334 :
335 : /** Try to find an IPv6 OR port in <b>list</b> of directory_token_t's
336 : * with at least one argument (use GE(1) in setup). If found, store
337 : * address and port number to <b>addr_out</b> and
338 : * <b>port_out</b>. Return number of OR ports found. */
339 : int
340 174 : find_single_ipv6_orport(const smartlist_t *list,
341 : tor_addr_t *addr_out,
342 : uint16_t *port_out)
343 : {
344 174 : int ret = 0;
345 174 : tor_assert(list != NULL);
346 174 : tor_assert(addr_out != NULL);
347 174 : tor_assert(port_out != NULL);
348 :
349 181 : SMARTLIST_FOREACH_BEGIN(list, directory_token_t *, t) {
350 174 : tor_addr_t a;
351 174 : maskbits_t bits;
352 174 : uint16_t port_min, port_max;
353 174 : tor_assert(t->n_args >= 1);
354 : /* XXXX Prop186 the full spec allows much more than this. */
355 174 : if (tor_addr_parse_mask_ports(t->args[0], 0,
356 : &a, &bits, &port_min,
357 167 : &port_max) == AF_INET6 &&
358 167 : bits == 128 &&
359 167 : port_min == port_max) {
360 : /* Okay, this is one we can understand. Use it and ignore
361 : any potential more addresses in list. */
362 167 : tor_addr_copy(addr_out, &a);
363 167 : *port_out = port_min;
364 167 : ret = 1;
365 167 : break;
366 : }
367 7 : } SMARTLIST_FOREACH_END(t);
368 :
369 174 : return ret;
370 : }
371 :
372 : /** Helper function: reads a single router entry from *<b>s</b> ...
373 : * *<b>end</b>. Mallocs a new router and returns it if all goes well, else
374 : * returns NULL. If <b>cache_copy</b> is true, duplicate the contents of
375 : * s through end into the signed_descriptor_body of the resulting
376 : * routerinfo_t.
377 : *
378 : * If <b>end</b> is NULL, <b>s</b> must be properly NUL-terminated.
379 : *
380 : * If <b>allow_annotations</b>, it's okay to encounter annotations in <b>s</b>
381 : * before the router; if it's false, reject the router if it's annotated. If
382 : * <b>prepend_annotations</b> is set, it should contain some annotations:
383 : * append them to the front of the router before parsing it, and keep them
384 : * around when caching the router.
385 : *
386 : * Only one of allow_annotations and prepend_annotations may be set.
387 : *
388 : * If <b>can_dl_again_out</b> is provided, set *<b>can_dl_again_out</b> to 1
389 : * if it's okay to try to download a descriptor with this same digest again,
390 : * and 0 if it isn't. (It might not be okay to download it again if part of
391 : * the part covered by the digest is invalid.)
392 : */
393 : routerinfo_t *
394 1292 : router_parse_entry_from_string(const char *s, const char *end,
395 : int cache_copy, int allow_annotations,
396 : const char *prepend_annotations,
397 : int *can_dl_again_out)
398 : {
399 1292 : routerinfo_t *router = NULL;
400 1292 : char digest[128];
401 1292 : smartlist_t *tokens = NULL, *exit_policy_tokens = NULL;
402 1292 : directory_token_t *tok;
403 1292 : struct in_addr in;
404 1292 : const char *start_of_annotations, *cp, *s_dup = s;
405 1292 : size_t prepend_len = prepend_annotations ? strlen(prepend_annotations) : 0;
406 1292 : int ok = 1;
407 1292 : memarea_t *area = NULL;
408 1292 : tor_cert_t *ntor_cc_cert = NULL;
409 : /* Do not set this to '1' until we have parsed everything that we intend to
410 : * parse that's covered by the hash. */
411 1292 : int can_dl_again = 0;
412 1292 : crypto_pk_t *rsa_pubkey = NULL;
413 :
414 1292 : tor_assert(!allow_annotations || !prepend_annotations);
415 :
416 1292 : if (!end) {
417 72 : end = s + strlen(s);
418 : }
419 :
420 : /* point 'end' to a point immediately after the final newline. */
421 1716 : while (end > s+2 && *(end-1) == '\n' && *(end-2) == '\n')
422 424 : --end;
423 :
424 1292 : area = memarea_new();
425 1292 : tokens = smartlist_new();
426 1292 : if (prepend_annotations) {
427 2 : if (tokenize_string(area,prepend_annotations,NULL,tokens,
428 : routerdesc_token_table,TS_NOCHECK)) {
429 1 : log_warn(LD_DIR, "Error tokenizing router descriptor (annotations).");
430 1 : goto err;
431 : }
432 : }
433 :
434 1291 : start_of_annotations = s;
435 1291 : cp = tor_memstr(s, end-s, "\nrouter ");
436 1291 : if (!cp) {
437 1263 : if (end-s < 7 || strcmpstart(s, "router ")) {
438 8 : log_warn(LD_DIR, "No router keyword found.");
439 8 : goto err;
440 : }
441 : } else {
442 28 : s = cp+1;
443 : }
444 :
445 1283 : if (start_of_annotations != s) { /* We have annotations */
446 28 : if (allow_annotations) {
447 25 : if (tokenize_string(area,start_of_annotations,s,tokens,
448 : routerdesc_token_table,TS_NOCHECK)) {
449 1 : log_warn(LD_DIR, "Error tokenizing router descriptor (annotations).");
450 1 : goto err;
451 : }
452 : } else {
453 3 : log_warn(LD_DIR, "Found unexpected annotations on router descriptor not "
454 : "loaded from disk. Dropping it.");
455 3 : goto err;
456 : }
457 : }
458 :
459 1279 : if (!tor_memstr(s, end-s, "\nproto ")) {
460 1021 : log_debug(LD_DIR, "Found an obsolete router descriptor. "
461 : "Rejecting quietly.");
462 1021 : goto err;
463 : }
464 :
465 258 : if (router_get_router_hash(s, end - s, digest) < 0) {
466 0 : log_warn(LD_DIR, "Couldn't compute router hash.");
467 0 : goto err;
468 : }
469 : {
470 258 : int flags = 0;
471 258 : if (allow_annotations)
472 30 : flags |= TS_ANNOTATIONS_OK;
473 258 : if (prepend_annotations)
474 1 : flags |= TS_ANNOTATIONS_OK|TS_NO_NEW_ANNOTATIONS;
475 :
476 258 : if (tokenize_string(area,s,end,tokens,routerdesc_token_table, flags)) {
477 134 : log_warn(LD_DIR, "Error tokenizing router descriptor.");
478 134 : goto err;
479 : }
480 : }
481 :
482 124 : if (smartlist_len(tokens) < 2) {
483 0 : log_warn(LD_DIR, "Impossibly short router descriptor.");
484 0 : goto err;
485 : }
486 :
487 124 : tok = find_by_keyword(tokens, K_ROUTER);
488 124 : const int router_token_pos = smartlist_pos(tokens, tok);
489 124 : tor_assert(tok->n_args >= 5);
490 :
491 124 : router = tor_malloc_zero(sizeof(routerinfo_t));
492 124 : router->cert_expiration_time = TIME_MAX;
493 124 : router->cache_info.routerlist_index = -1;
494 124 : router->cache_info.annotations_len = s-start_of_annotations + prepend_len;
495 124 : router->cache_info.signed_descriptor_len = end-s;
496 124 : if (cache_copy) {
497 65 : size_t len = router->cache_info.signed_descriptor_len +
498 : router->cache_info.annotations_len;
499 130 : char *signed_body =
500 65 : router->cache_info.signed_descriptor_body = tor_malloc(len+1);
501 65 : if (prepend_annotations) {
502 0 : memcpy(signed_body, prepend_annotations, prepend_len);
503 0 : signed_body += prepend_len;
504 : }
505 : /* This assertion will always succeed.
506 : * len == signed_desc_len + annotations_len
507 : * == end-s + s-start_of_annotations + prepend_len
508 : * == end-start_of_annotations + prepend_len
509 : * We already wrote prepend_len bytes into the buffer; now we're
510 : * writing end-start_of_annotations -NM. */
511 65 : tor_assert(signed_body+(end-start_of_annotations) ==
512 : router->cache_info.signed_descriptor_body+len);
513 65 : memcpy(signed_body, start_of_annotations, end-start_of_annotations);
514 65 : router->cache_info.signed_descriptor_body[len] = '\0';
515 65 : tor_assert(strlen(router->cache_info.signed_descriptor_body) == len);
516 : }
517 124 : memcpy(router->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
518 :
519 124 : router->nickname = tor_strdup(tok->args[0]);
520 124 : if (!is_legal_nickname(router->nickname)) {
521 2 : log_warn(LD_DIR,"Router nickname is invalid");
522 2 : goto err;
523 : }
524 122 : if (!tor_inet_aton(tok->args[1], &in)) {
525 2 : log_warn(LD_DIR,"Router address is not an IP address.");
526 2 : goto err;
527 : }
528 120 : tor_addr_from_in(&router->ipv4_addr, &in);
529 :
530 240 : router->ipv4_orport =
531 120 : (uint16_t) tor_parse_long(tok->args[2],10,0,65535,&ok,NULL);
532 120 : if (!ok) {
533 3 : log_warn(LD_DIR,"Invalid OR port %s", escaped(tok->args[2]));
534 3 : goto err;
535 : }
536 234 : router->ipv4_dirport =
537 117 : (uint16_t) tor_parse_long(tok->args[4],10,0,65535,&ok,NULL);
538 117 : if (!ok) {
539 1 : log_warn(LD_DIR,"Invalid dir port %s", escaped(tok->args[4]));
540 1 : goto err;
541 : }
542 :
543 116 : tok = find_by_keyword(tokens, K_BANDWIDTH);
544 116 : tor_assert(tok->n_args >= 3);
545 232 : router->bandwidthrate = (int)
546 116 : tor_parse_long(tok->args[0],10,1,INT_MAX,&ok,NULL);
547 :
548 116 : if (!ok) {
549 1 : log_warn(LD_DIR, "bandwidthrate %s unreadable or 0. Failing.",
550 : escaped(tok->args[0]));
551 1 : goto err;
552 : }
553 230 : router->bandwidthburst =
554 115 : (int) tor_parse_long(tok->args[1],10,0,INT_MAX,&ok,NULL);
555 115 : if (!ok) {
556 4 : log_warn(LD_DIR, "Invalid bandwidthburst %s", escaped(tok->args[1]));
557 4 : goto err;
558 : }
559 222 : router->bandwidthcapacity = (int)
560 111 : tor_parse_long(tok->args[2],10,0,INT_MAX,&ok,NULL);
561 111 : if (!ok) {
562 0 : log_warn(LD_DIR, "Invalid bandwidthcapacity %s", escaped(tok->args[1]));
563 0 : goto err;
564 : }
565 :
566 111 : if ((tok = find_opt_by_keyword(tokens, A_PURPOSE))) {
567 1 : tor_assert(tok->n_args);
568 1 : router->purpose = router_purpose_from_string(tok->args[0]);
569 1 : if (router->purpose == ROUTER_PURPOSE_UNKNOWN) {
570 0 : goto err;
571 : }
572 : } else {
573 110 : router->purpose = ROUTER_PURPOSE_GENERAL;
574 : }
575 111 : router->cache_info.send_unencrypted =
576 111 : (router->purpose == ROUTER_PURPOSE_GENERAL) ? 1 : 0;
577 :
578 111 : if ((tok = find_opt_by_keyword(tokens, K_UPTIME))) {
579 83 : tor_assert(tok->n_args >= 1);
580 83 : router->uptime = tor_parse_long(tok->args[0],10,0,LONG_MAX,&ok,NULL);
581 83 : if (!ok) {
582 1 : log_warn(LD_DIR, "Invalid uptime %s", escaped(tok->args[0]));
583 1 : goto err;
584 : }
585 : }
586 :
587 110 : if ((tok = find_opt_by_keyword(tokens, K_HIBERNATING))) {
588 26 : tor_assert(tok->n_args >= 1);
589 26 : router->is_hibernating
590 26 : = (tor_parse_long(tok->args[0],10,0,LONG_MAX,NULL,NULL) != 0);
591 : }
592 :
593 110 : tok = find_by_keyword(tokens, K_PUBLISHED);
594 110 : tor_assert(tok->n_args == 1);
595 110 : if (parse_iso_time(tok->args[0], &router->cache_info.published_on) < 0)
596 2 : goto err;
597 :
598 108 : tok = find_by_keyword(tokens, K_ONION_KEY);
599 108 : if (!crypto_pk_public_exponent_ok(tok->key)) {
600 1 : log_warn(LD_DIR,
601 : "Relay's onion key had invalid exponent.");
602 1 : goto err;
603 : }
604 107 : router->onion_pkey = tor_memdup(tok->object_body, tok->object_size);
605 107 : router->onion_pkey_len = tok->object_size;
606 107 : crypto_pk_free(tok->key);
607 :
608 107 : if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
609 107 : curve25519_public_key_t k;
610 107 : tor_assert(tok->n_args >= 1);
611 107 : if (curve25519_public_from_base64(&k, tok->args[0]) < 0) {
612 1 : log_warn(LD_DIR, "Bogus ntor-onion-key in routerinfo");
613 1 : goto err;
614 : }
615 106 : router->onion_curve25519_pkey =
616 106 : tor_memdup(&k, sizeof(curve25519_public_key_t));
617 : }
618 :
619 106 : tok = find_by_keyword(tokens, K_SIGNING_KEY);
620 106 : router->identity_pkey = tok->key;
621 106 : tok->key = NULL; /* Prevent free */
622 106 : if (crypto_pk_get_digest(router->identity_pkey,
623 106 : router->cache_info.identity_digest)) {
624 0 : log_warn(LD_DIR, "Couldn't calculate key digest"); goto err;
625 : }
626 :
627 : {
628 106 : directory_token_t *ed_sig_tok, *ed_cert_tok, *cc_tap_tok, *cc_ntor_tok,
629 : *master_key_tok;
630 106 : ed_sig_tok = find_opt_by_keyword(tokens, K_ROUTER_SIG_ED25519);
631 106 : ed_cert_tok = find_opt_by_keyword(tokens, K_IDENTITY_ED25519);
632 106 : master_key_tok = find_opt_by_keyword(tokens, K_MASTER_KEY_ED25519);
633 106 : cc_tap_tok = find_opt_by_keyword(tokens, K_ONION_KEY_CROSSCERT);
634 106 : cc_ntor_tok = find_opt_by_keyword(tokens, K_NTOR_ONION_KEY_CROSSCERT);
635 106 : int n_ed_toks = !!ed_sig_tok + !!ed_cert_tok +
636 106 : !!cc_tap_tok + !!cc_ntor_tok;
637 106 : if ((n_ed_toks != 0 && n_ed_toks != 4) ||
638 106 : (n_ed_toks == 4 && !router->onion_curve25519_pkey)) {
639 0 : log_warn(LD_DIR, "Router descriptor with only partial ed25519/"
640 : "cross-certification support");
641 0 : goto err;
642 : }
643 106 : if (master_key_tok && !ed_sig_tok) {
644 0 : log_warn(LD_DIR, "Router descriptor has ed25519 master key but no "
645 : "certificate");
646 0 : goto err;
647 : }
648 106 : if (ed_sig_tok) {
649 106 : tor_assert(ed_cert_tok && cc_tap_tok && cc_ntor_tok);
650 106 : const int ed_cert_token_pos = smartlist_pos(tokens, ed_cert_tok);
651 106 : if (ed_cert_token_pos == -1 || router_token_pos == -1 ||
652 106 : (ed_cert_token_pos != router_token_pos + 1 &&
653 1 : ed_cert_token_pos != router_token_pos - 1)) {
654 1 : log_warn(LD_DIR, "Ed25519 certificate in wrong position");
655 9 : goto err;
656 : }
657 105 : if (ed_sig_tok != smartlist_get(tokens, smartlist_len(tokens)-2)) {
658 1 : log_warn(LD_DIR, "Ed25519 signature in wrong position");
659 1 : goto err;
660 : }
661 104 : if (strcmp(ed_cert_tok->object_type, "ED25519 CERT")) {
662 0 : log_warn(LD_DIR, "Wrong object type on identity-ed25519 "
663 : "in descriptor");
664 0 : goto err;
665 : }
666 104 : if (strcmp(cc_ntor_tok->object_type, "ED25519 CERT")) {
667 0 : log_warn(LD_DIR, "Wrong object type on ntor-onion-key-crosscert "
668 : "in descriptor");
669 0 : goto err;
670 : }
671 104 : if (strcmp(cc_tap_tok->object_type, "CROSSCERT")) {
672 0 : log_warn(LD_DIR, "Wrong object type on onion-key-crosscert "
673 : "in descriptor");
674 0 : goto err;
675 : }
676 104 : if (strcmp(cc_ntor_tok->args[0], "0") &&
677 48 : strcmp(cc_ntor_tok->args[0], "1")) {
678 0 : log_warn(LD_DIR, "Bad sign bit on ntor-onion-key-crosscert");
679 0 : goto err;
680 : }
681 104 : int ntor_cc_sign_bit = !strcmp(cc_ntor_tok->args[0], "1");
682 :
683 104 : uint8_t d256[DIGEST256_LEN];
684 104 : const char *signed_start, *signed_end;
685 208 : tor_cert_t *cert = tor_cert_parse(
686 104 : (const uint8_t*)ed_cert_tok->object_body,
687 : ed_cert_tok->object_size);
688 104 : if (! cert) {
689 1 : log_warn(LD_DIR, "Couldn't parse ed25519 cert");
690 1 : goto err;
691 : }
692 : /* makes sure it gets freed. */
693 103 : router->cache_info.signing_key_cert = cert;
694 :
695 103 : if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
696 : ! cert->signing_key_included) {
697 1 : log_warn(LD_DIR, "Invalid form for ed25519 cert");
698 1 : goto err;
699 : }
700 :
701 102 : if (master_key_tok) {
702 : /* This token is optional, but if it's present, it must match
703 : * the signature in the signing cert, or supplant it. */
704 102 : tor_assert(master_key_tok->n_args >= 1);
705 102 : ed25519_public_key_t pkey;
706 102 : if (ed25519_public_from_base64(&pkey, master_key_tok->args[0])<0) {
707 0 : log_warn(LD_DIR, "Can't parse ed25519 master key");
708 0 : goto err;
709 : }
710 :
711 102 : if (fast_memneq(&cert->signing_key.pubkey,
712 : pkey.pubkey, ED25519_PUBKEY_LEN)) {
713 0 : log_warn(LD_DIR, "Ed25519 master key does not match "
714 : "key in certificate");
715 0 : goto err;
716 : }
717 : }
718 102 : ntor_cc_cert = tor_cert_parse((const uint8_t*)cc_ntor_tok->object_body,
719 : cc_ntor_tok->object_size);
720 102 : if (!ntor_cc_cert) {
721 0 : log_warn(LD_DIR, "Couldn't parse ntor-onion-key-crosscert cert");
722 0 : goto err;
723 : }
724 204 : if (ntor_cc_cert->cert_type != CERT_TYPE_ONION_ID ||
725 102 : ! ed25519_pubkey_eq(&ntor_cc_cert->signed_key, &cert->signing_key)) {
726 1 : log_warn(LD_DIR, "Invalid contents for ntor-onion-key-crosscert cert");
727 1 : goto err;
728 : }
729 :
730 101 : ed25519_public_key_t ntor_cc_pk;
731 101 : if (ed25519_public_key_from_curve25519_public_key(&ntor_cc_pk,
732 101 : router->onion_curve25519_pkey,
733 : ntor_cc_sign_bit)<0) {
734 0 : log_warn(LD_DIR, "Error converting onion key to ed25519");
735 0 : goto err;
736 : }
737 :
738 101 : if (router_get_hash_impl_helper(s, end-s, "router ",
739 : "\nrouter-sig-ed25519",
740 : ' ', LOG_WARN,
741 : &signed_start, &signed_end) < 0) {
742 0 : log_warn(LD_DIR, "Can't find ed25519-signed portion of descriptor");
743 0 : goto err;
744 : }
745 101 : crypto_digest_t *d = crypto_digest256_new(DIGEST_SHA256);
746 101 : crypto_digest_add_bytes(d, ED_DESC_SIGNATURE_PREFIX,
747 : strlen(ED_DESC_SIGNATURE_PREFIX));
748 101 : crypto_digest_add_bytes(d, signed_start, signed_end-signed_start);
749 101 : crypto_digest_get_digest(d, (char*)d256, sizeof(d256));
750 101 : crypto_digest_free(d);
751 :
752 101 : ed25519_checkable_t check[3];
753 101 : int check_ok[3];
754 101 : time_t expires = TIME_MAX;
755 101 : if (tor_cert_get_checkable_sig(&check[0], cert, NULL, &expires) < 0) {
756 0 : log_err(LD_BUG, "Couldn't create 'checkable' for cert.");
757 0 : goto err;
758 : }
759 101 : if (tor_cert_get_checkable_sig(&check[1],
760 : ntor_cc_cert, &ntor_cc_pk, &expires) < 0) {
761 0 : log_err(LD_BUG, "Couldn't create 'checkable' for ntor_cc_cert.");
762 0 : goto err;
763 : }
764 :
765 101 : if (ed25519_signature_from_base64(&check[2].signature,
766 101 : ed_sig_tok->args[0])<0) {
767 3 : log_warn(LD_DIR, "Couldn't decode ed25519 signature");
768 3 : goto err;
769 : }
770 98 : check[2].pubkey = &cert->signed_key;
771 98 : check[2].msg = d256;
772 98 : check[2].len = DIGEST256_LEN;
773 :
774 98 : if (ed25519_checksig_batch(check_ok, check, 3) < 0) {
775 1 : log_warn(LD_DIR, "Incorrect ed25519 signature(s)");
776 1 : goto err;
777 : }
778 :
779 97 : rsa_pubkey = router_get_rsa_onion_pkey(router->onion_pkey,
780 : router->onion_pkey_len);
781 97 : if (check_tap_onion_key_crosscert(
782 97 : (const uint8_t*)cc_tap_tok->object_body,
783 97 : (int)cc_tap_tok->object_size,
784 : rsa_pubkey,
785 : &cert->signing_key,
786 : (const uint8_t*)router->cache_info.identity_digest)<0) {
787 0 : log_warn(LD_DIR, "Incorrect TAP cross-verification");
788 0 : goto err;
789 : }
790 :
791 : /* We check this before adding it to the routerlist. */
792 97 : router->cert_expiration_time = expires;
793 : }
794 : }
795 :
796 97 : if ((tok = find_opt_by_keyword(tokens, K_FINGERPRINT))) {
797 : /* If there's a fingerprint line, it must match the identity digest. */
798 83 : char d[DIGEST_LEN];
799 83 : tor_assert(tok->n_args == 1);
800 83 : tor_strstrip(tok->args[0], " ");
801 83 : if (base16_decode(d, DIGEST_LEN,
802 83 : tok->args[0], strlen(tok->args[0])) != DIGEST_LEN) {
803 6 : log_warn(LD_DIR, "Couldn't decode router fingerprint %s",
804 : escaped(tok->args[0]));
805 7 : goto err;
806 : }
807 77 : if (tor_memneq(d,router->cache_info.identity_digest, DIGEST_LEN)) {
808 1 : log_warn(LD_DIR, "Fingerprint '%s' does not match identity digest.",
809 : tok->args[0]);
810 1 : goto err;
811 : }
812 : }
813 :
814 : {
815 90 : const char *version = NULL, *protocols = NULL;
816 90 : if ((tok = find_opt_by_keyword(tokens, K_PLATFORM))) {
817 76 : router->platform = tor_strdup(tok->args[0]);
818 76 : version = tok->args[0];
819 : }
820 :
821 90 : if ((tok = find_opt_by_keyword(tokens, K_PROTO))) {
822 90 : router->protocol_list = tor_strdup(tok->args[0]);
823 90 : protocols = tok->args[0];
824 : }
825 :
826 90 : summarize_protover_flags(&router->pv, protocols, version);
827 : }
828 :
829 90 : if ((tok = find_opt_by_keyword(tokens, K_CONTACT))) {
830 30 : router->contact_info = tor_strdup(tok->args[0]);
831 : }
832 :
833 168 : if (find_opt_by_keyword(tokens, K_REJECT6) ||
834 78 : find_opt_by_keyword(tokens, K_ACCEPT6)) {
835 12 : log_warn(LD_DIR, "Rejecting router with reject6/accept6 line: they crash "
836 : "older Tors.");
837 12 : goto err;
838 : }
839 : {
840 78 : smartlist_t *or_addresses = find_all_by_keyword(tokens, K_OR_ADDRESS);
841 78 : if (or_addresses) {
842 34 : find_single_ipv6_orport(or_addresses, &router->ipv6_addr,
843 : &router->ipv6_orport);
844 34 : smartlist_free(or_addresses);
845 : }
846 : }
847 78 : exit_policy_tokens = find_all_exitpolicy(tokens);
848 78 : if (!smartlist_len(exit_policy_tokens)) {
849 1 : log_warn(LD_DIR, "No exit policy tokens in descriptor.");
850 1 : goto err;
851 : }
852 374 : SMARTLIST_FOREACH(exit_policy_tokens, directory_token_t *, t,
853 : if (router_add_exit_policy(router,t)<0) {
854 : log_warn(LD_DIR,"Error in exit policy");
855 : goto err;
856 : });
857 73 : policy_expand_private(&router->exit_policy);
858 :
859 73 : if ((tok = find_opt_by_keyword(tokens, K_IPV6_POLICY)) && tok->n_args) {
860 5 : router->ipv6_exit_policy = parse_short_policy(tok->args[0]);
861 5 : if (! router->ipv6_exit_policy) {
862 1 : log_warn(LD_DIR , "Error in ipv6-policy %s", escaped(tok->args[0]));
863 1 : goto err;
864 : }
865 : }
866 :
867 72 : if (policy_is_reject_star(router->exit_policy, AF_INET, 1) &&
868 21 : (!router->ipv6_exit_policy ||
869 0 : short_policy_is_reject_star(router->ipv6_exit_policy)))
870 21 : router->policy_is_reject_star = 1;
871 :
872 72 : if ((tok = find_opt_by_keyword(tokens, K_FAMILY)) && tok->n_args) {
873 7 : int i;
874 7 : router->declared_family = smartlist_new();
875 25 : for (i=0;i<tok->n_args;++i) {
876 20 : if (!is_legal_nickname_or_hexdigest(tok->args[i])) {
877 2 : log_warn(LD_DIR, "Illegal nickname %s in family line",
878 : escaped(tok->args[i]));
879 2 : goto err;
880 : }
881 18 : smartlist_add_strdup(router->declared_family, tok->args[i]);
882 : }
883 : }
884 :
885 70 : if (find_opt_by_keyword(tokens, K_CACHES_EXTRA_INFO))
886 13 : router->caches_extra_info = 1;
887 :
888 70 : if (find_opt_by_keyword(tokens, K_ALLOW_SINGLE_HOP_EXITS))
889 4 : router->allow_single_hop_exits = 1;
890 :
891 70 : if ((tok = find_opt_by_keyword(tokens, K_EXTRA_INFO_DIGEST))) {
892 43 : tor_assert(tok->n_args >= 1);
893 43 : if (strlen(tok->args[0]) == HEX_DIGEST_LEN) {
894 42 : if (base16_decode(router->cache_info.extra_info_digest, DIGEST_LEN,
895 : tok->args[0], HEX_DIGEST_LEN) != DIGEST_LEN) {
896 0 : log_warn(LD_DIR,"Invalid extra info digest");
897 : }
898 : } else {
899 1 : log_warn(LD_DIR, "Invalid extra info digest %s", escaped(tok->args[0]));
900 : }
901 :
902 43 : if (tok->n_args >= 2) {
903 39 : if (digest256_from_base64(router->cache_info.extra_info_digest256,
904 39 : tok->args[1]) < 0) {
905 0 : log_warn(LD_DIR, "Invalid extra info digest256 %s",
906 : escaped(tok->args[1]));
907 : }
908 : }
909 : }
910 :
911 70 : if (find_opt_by_keyword(tokens, K_HIDDEN_SERVICE_DIR)) {
912 62 : router->wants_to_be_hs_dir = 1;
913 : }
914 :
915 : /* This router accepts tunnelled directory requests via begindir if it has
916 : * an open dirport or it included "tunnelled-dir-server". */
917 70 : if (find_opt_by_keyword(tokens, K_DIR_TUNNELLED) ||
918 12 : router->ipv4_dirport > 0) {
919 69 : router->supports_tunnelled_dir_requests = 1;
920 : }
921 :
922 70 : tok = find_by_keyword(tokens, K_ROUTER_SIGNATURE);
923 :
924 70 : if (!router->ipv4_orport) {
925 1 : log_warn(LD_DIR,"or_port unreadable or 0. Failing.");
926 1 : goto err;
927 : }
928 :
929 : /* We've checked everything that's covered by the hash. */
930 69 : can_dl_again = 1;
931 69 : if (check_signature_token(digest, DIGEST_LEN, tok, router->identity_pkey, 0,
932 : "router descriptor") < 0)
933 3 : goto err;
934 :
935 66 : if (!router->platform) {
936 4 : router->platform = tor_strdup("<unknown>");
937 : }
938 66 : goto done;
939 :
940 1226 : err:
941 1226 : dump_desc(s_dup, "router descriptor");
942 1226 : routerinfo_free(router);
943 1226 : router = NULL;
944 1292 : done:
945 1292 : crypto_pk_free(rsa_pubkey);
946 1292 : tor_cert_free(ntor_cc_cert);
947 1292 : if (tokens) {
948 5322 : SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
949 1292 : smartlist_free(tokens);
950 : }
951 1292 : smartlist_free(exit_policy_tokens);
952 1292 : if (area) {
953 1292 : DUMP_AREA(area, "routerinfo");
954 1292 : memarea_drop_all(area);
955 : }
956 1292 : if (can_dl_again_out)
957 67 : *can_dl_again_out = can_dl_again;
958 1292 : return router;
959 : }
960 :
961 : /** Parse a single extrainfo entry from the string <b>s</b>, ending at
962 : * <b>end</b>. (If <b>end</b> is NULL, parse up to the end of <b>s</b>.) If
963 : * <b>cache_copy</b> is true, make a copy of the extra-info document in the
964 : * cache_info fields of the result. If <b>routermap</b> is provided, use it
965 : * as a map from router identity to routerinfo_t when looking up signing keys.
966 : *
967 : * If <b>can_dl_again_out</b> is provided, set *<b>can_dl_again_out</b> to 1
968 : * if it's okay to try to download an extrainfo with this same digest again,
969 : * and 0 if it isn't. (It might not be okay to download it again if part of
970 : * the part covered by the digest is invalid.)
971 : */
972 : extrainfo_t *
973 479 : extrainfo_parse_entry_from_string(const char *s, const char *end,
974 : int cache_copy, struct digest_ri_map_t *routermap,
975 : int *can_dl_again_out)
976 : {
977 479 : extrainfo_t *extrainfo = NULL;
978 479 : char digest[128];
979 479 : smartlist_t *tokens = NULL;
980 479 : directory_token_t *tok;
981 479 : crypto_pk_t *key = NULL;
982 479 : routerinfo_t *router = NULL;
983 479 : memarea_t *area = NULL;
984 479 : const char *s_dup = s;
985 : /* Do not set this to '1' until we have parsed everything that we intend to
986 : * parse that's covered by the hash. */
987 479 : int can_dl_again = 0;
988 :
989 479 : if (BUG(s == NULL))
990 0 : return NULL;
991 :
992 479 : if (!end) {
993 28 : end = s + strlen(s);
994 : }
995 :
996 : /* point 'end' to a point immediately after the final newline. */
997 766 : while (end > s+2 && *(end-1) == '\n' && *(end-2) == '\n')
998 287 : --end;
999 :
1000 479 : if (!tor_memstr(s, end-s, "\nidentity-ed25519")) {
1001 349 : log_debug(LD_DIR, "Found an obsolete extrainfo. Rejecting quietly.");
1002 349 : goto err;
1003 : }
1004 :
1005 130 : if (router_get_extrainfo_hash(s, end-s, digest) < 0) {
1006 1 : log_warn(LD_DIR, "Couldn't compute router hash.");
1007 1 : goto err;
1008 : }
1009 129 : tokens = smartlist_new();
1010 129 : area = memarea_new();
1011 129 : if (tokenize_string(area,s,end,tokens,extrainfo_token_table,0)) {
1012 13 : log_warn(LD_DIR, "Error tokenizing extra-info document.");
1013 13 : goto err;
1014 : }
1015 :
1016 116 : if (smartlist_len(tokens) < 2) {
1017 0 : log_warn(LD_DIR, "Impossibly short extra-info document.");
1018 0 : goto err;
1019 : }
1020 :
1021 : /* XXXX Accept this in position 1 too, and ed identity in position 0. */
1022 116 : tok = smartlist_get(tokens,0);
1023 116 : if (tok->tp != K_EXTRA_INFO) {
1024 0 : log_warn(LD_DIR,"Entry does not start with \"extra-info\"");
1025 0 : goto err;
1026 : }
1027 :
1028 116 : extrainfo = tor_malloc_zero(sizeof(extrainfo_t));
1029 116 : extrainfo->cache_info.is_extrainfo = 1;
1030 116 : if (cache_copy)
1031 21 : extrainfo->cache_info.signed_descriptor_body = tor_memdup_nulterm(s,end-s);
1032 116 : extrainfo->cache_info.signed_descriptor_len = end-s;
1033 116 : memcpy(extrainfo->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
1034 116 : crypto_digest256((char*)extrainfo->digest256, s, end-s, DIGEST_SHA256);
1035 :
1036 116 : tor_assert(tok->n_args >= 2);
1037 116 : if (!is_legal_nickname(tok->args[0])) {
1038 4 : log_warn(LD_DIR,"Bad nickname %s on \"extra-info\"",escaped(tok->args[0]));
1039 4 : goto err;
1040 : }
1041 112 : strlcpy(extrainfo->nickname, tok->args[0], sizeof(extrainfo->nickname));
1042 223 : if (strlen(tok->args[1]) != HEX_DIGEST_LEN ||
1043 111 : base16_decode(extrainfo->cache_info.identity_digest, DIGEST_LEN,
1044 : tok->args[1], HEX_DIGEST_LEN) != DIGEST_LEN) {
1045 3 : log_warn(LD_DIR,"Invalid fingerprint %s on \"extra-info\"",
1046 : escaped(tok->args[1]));
1047 3 : goto err;
1048 : }
1049 :
1050 109 : tok = find_by_keyword(tokens, K_PUBLISHED);
1051 109 : if (parse_iso_time(tok->args[0], &extrainfo->cache_info.published_on)) {
1052 9 : log_warn(LD_DIR,"Invalid published time %s on \"extra-info\"",
1053 : escaped(tok->args[0]));
1054 9 : goto err;
1055 : }
1056 :
1057 : {
1058 100 : directory_token_t *ed_sig_tok, *ed_cert_tok;
1059 100 : ed_sig_tok = find_opt_by_keyword(tokens, K_ROUTER_SIG_ED25519);
1060 100 : ed_cert_tok = find_opt_by_keyword(tokens, K_IDENTITY_ED25519);
1061 100 : int n_ed_toks = !!ed_sig_tok + !!ed_cert_tok;
1062 100 : if (n_ed_toks != 0 && n_ed_toks != 2) {
1063 0 : log_warn(LD_DIR, "Router descriptor with only partial ed25519/"
1064 : "cross-certification support");
1065 0 : goto err;
1066 : }
1067 100 : if (ed_sig_tok) {
1068 100 : tor_assert(ed_cert_tok);
1069 100 : const int ed_cert_token_pos = smartlist_pos(tokens, ed_cert_tok);
1070 100 : if (ed_cert_token_pos != 1) {
1071 : /* Accept this in position 0 XXXX */
1072 10 : log_warn(LD_DIR, "Ed25519 certificate in wrong position");
1073 74 : goto err;
1074 : }
1075 90 : if (ed_sig_tok != smartlist_get(tokens, smartlist_len(tokens)-2)) {
1076 3 : log_warn(LD_DIR, "Ed25519 signature in wrong position");
1077 3 : goto err;
1078 : }
1079 87 : if (strcmp(ed_cert_tok->object_type, "ED25519 CERT")) {
1080 3 : log_warn(LD_DIR, "Wrong object type on identity-ed25519 "
1081 : "in descriptor");
1082 3 : goto err;
1083 : }
1084 :
1085 84 : uint8_t d256[DIGEST256_LEN];
1086 84 : const char *signed_start, *signed_end;
1087 168 : tor_cert_t *cert = tor_cert_parse(
1088 84 : (const uint8_t*)ed_cert_tok->object_body,
1089 : ed_cert_tok->object_size);
1090 84 : if (! cert) {
1091 40 : log_warn(LD_DIR, "Couldn't parse ed25519 cert");
1092 40 : goto err;
1093 : }
1094 : /* makes sure it gets freed. */
1095 44 : extrainfo->cache_info.signing_key_cert = cert;
1096 :
1097 44 : if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
1098 : ! cert->signing_key_included) {
1099 11 : log_warn(LD_DIR, "Invalid form for ed25519 cert");
1100 11 : goto err;
1101 : }
1102 :
1103 33 : if (router_get_hash_impl_helper(s, end-s, "extra-info ",
1104 : "\nrouter-sig-ed25519",
1105 : ' ', LOG_WARN,
1106 : &signed_start, &signed_end) < 0) {
1107 2 : log_warn(LD_DIR, "Can't find ed25519-signed portion of extrainfo");
1108 2 : goto err;
1109 : }
1110 31 : crypto_digest_t *d = crypto_digest256_new(DIGEST_SHA256);
1111 31 : crypto_digest_add_bytes(d, ED_DESC_SIGNATURE_PREFIX,
1112 : strlen(ED_DESC_SIGNATURE_PREFIX));
1113 31 : crypto_digest_add_bytes(d, signed_start, signed_end-signed_start);
1114 31 : crypto_digest_get_digest(d, (char*)d256, sizeof(d256));
1115 31 : crypto_digest_free(d);
1116 :
1117 31 : ed25519_checkable_t check[2];
1118 31 : int check_ok[2];
1119 31 : if (tor_cert_get_checkable_sig(&check[0], cert, NULL, NULL) < 0) {
1120 0 : log_err(LD_BUG, "Couldn't create 'checkable' for cert.");
1121 0 : goto err;
1122 : }
1123 :
1124 31 : if (ed25519_signature_from_base64(&check[1].signature,
1125 31 : ed_sig_tok->args[0])<0) {
1126 5 : log_warn(LD_DIR, "Couldn't decode ed25519 signature");
1127 5 : goto err;
1128 : }
1129 26 : check[1].pubkey = &cert->signed_key;
1130 26 : check[1].msg = d256;
1131 26 : check[1].len = DIGEST256_LEN;
1132 :
1133 26 : if (ed25519_checksig_batch(check_ok, check, 2) < 0) {
1134 0 : log_warn(LD_DIR, "Incorrect ed25519 signature(s)");
1135 0 : goto err;
1136 : }
1137 : /* We don't check the certificate expiration time: checking that it
1138 : * matches the cert in the router descriptor is adequate. */
1139 : }
1140 : }
1141 :
1142 : /* We've checked everything that's covered by the hash. */
1143 26 : can_dl_again = 1;
1144 :
1145 26 : if (routermap &&
1146 7 : (router = digestmap_get((digestmap_t*)routermap,
1147 : extrainfo->cache_info.identity_digest))) {
1148 4 : key = router->identity_pkey;
1149 : }
1150 :
1151 26 : tok = find_by_keyword(tokens, K_ROUTER_SIGNATURE);
1152 26 : if (strcmp(tok->object_type, "SIGNATURE") ||
1153 26 : tok->object_size < 128 || tok->object_size > 512) {
1154 1 : log_warn(LD_DIR, "Bad object type or length on extra-info signature");
1155 1 : goto err;
1156 : }
1157 :
1158 25 : if (key) {
1159 4 : if (check_signature_token(digest, DIGEST_LEN, tok, key, 0,
1160 : "extra-info") < 0)
1161 0 : goto err;
1162 :
1163 4 : if (router)
1164 4 : extrainfo->cache_info.send_unencrypted =
1165 4 : router->cache_info.send_unencrypted;
1166 : } else {
1167 21 : extrainfo->pending_sig = tor_memdup(tok->object_body,
1168 : tok->object_size);
1169 21 : extrainfo->pending_sig_len = tok->object_size;
1170 : }
1171 :
1172 25 : goto done;
1173 454 : err:
1174 454 : dump_desc(s_dup, "extra-info descriptor");
1175 454 : extrainfo_free(extrainfo);
1176 454 : extrainfo = NULL;
1177 479 : done:
1178 479 : if (tokens) {
1179 12258 : SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
1180 129 : smartlist_free(tokens);
1181 : }
1182 479 : if (area) {
1183 129 : DUMP_AREA(area, "extrainfo");
1184 129 : memarea_drop_all(area);
1185 : }
1186 479 : if (can_dl_again_out)
1187 463 : *can_dl_again_out = can_dl_again;
1188 : return extrainfo;
1189 : }
1190 :
1191 : /** Add an exit policy stored in the token <b>tok</b> to the router info in
1192 : * <b>router</b>. Return 0 on success, -1 on failure. */
1193 : static int
1194 301 : router_add_exit_policy(routerinfo_t *router, directory_token_t *tok)
1195 : {
1196 301 : addr_policy_t *newe;
1197 : /* Use the standard interpretation of accept/reject *, an IPv4 wildcard. */
1198 301 : newe = router_parse_addr_policy(tok, 0);
1199 301 : if (!newe)
1200 : return -1;
1201 297 : if (! router->exit_policy)
1202 77 : router->exit_policy = smartlist_new();
1203 :
1204 : /* Ensure that in descriptors, accept/reject fields are followed by
1205 : * IPv4 addresses, and accept6/reject6 fields are followed by
1206 : * IPv6 addresses. Unlike torrcs, descriptor exit policies do not permit
1207 : * accept/reject followed by IPv6. */
1208 297 : if (((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
1209 0 : tor_addr_family(&newe->addr) == AF_INET)
1210 297 : ||
1211 297 : ((tok->tp == K_ACCEPT || tok->tp == K_REJECT) &&
1212 297 : tor_addr_family(&newe->addr) == AF_INET6)) {
1213 : /* There's nothing the user can do about other relays' descriptors,
1214 : * so we don't provide usage advice here. */
1215 0 : log_warn(LD_DIR, "Mismatch between field type and address type in exit "
1216 : "policy '%s'. Discarding entire router descriptor.",
1217 : tok->n_args == 1 ? tok->args[0] : "");
1218 0 : addr_policy_free(newe);
1219 0 : return -1;
1220 : }
1221 :
1222 297 : smartlist_add(router->exit_policy, newe);
1223 :
1224 297 : return 0;
1225 : }
1226 :
1227 : /** Return a newly allocated smartlist of all accept or reject tokens in
1228 : * <b>s</b>.
1229 : */
1230 : static smartlist_t *
1231 78 : find_all_exitpolicy(smartlist_t *s)
1232 : {
1233 78 : smartlist_t *out = smartlist_new();
1234 1961 : SMARTLIST_FOREACH(s, directory_token_t *, t,
1235 : if (t->tp == K_ACCEPT || t->tp == K_ACCEPT6 ||
1236 : t->tp == K_REJECT || t->tp == K_REJECT6)
1237 : smartlist_add(out,t));
1238 78 : return out;
1239 : }
1240 :
1241 : /** Called on startup; right now we just handle scanning the unparseable
1242 : * descriptor dumps, but hang anything else we might need to do in the
1243 : * future here as well.
1244 : */
1245 : void
1246 194 : routerparse_init(void)
1247 : {
1248 : /*
1249 : * Check both if the sandbox is active and whether it's configured; no
1250 : * point in loading all that if we won't be able to use it after the
1251 : * sandbox becomes active.
1252 : */
1253 194 : if (!(sandbox_is_active() || get_options()->Sandbox)) {
1254 194 : dump_desc_init();
1255 : }
1256 194 : }
1257 :
1258 : /** Clean up all data structures used by routerparse.c at exit */
1259 : void
1260 235 : routerparse_free_all(void)
1261 : {
1262 235 : dump_desc_fifo_cleanup();
1263 235 : }
|