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 authcert.c
9 : * \brief Code to maintain directory authorities' certificates.
10 : *
11 : * Authority certificates are signed with authority identity keys; they
12 : * are used to authenticate shorter-term authority signing keys. We
13 : * fetch them when we find a consensus or a vote that has been signed
14 : * with a signing key we don't recognize. We cache them on disk and
15 : * load them on startup. Authority operators generate them with the
16 : * "tor-gencert" utility.
17 : */
18 :
19 : #include "core/or/or.h"
20 :
21 : #include "app/config/config.h"
22 : #include "core/mainloop/connection.h"
23 : #include "core/mainloop/mainloop.h"
24 : #include "core/or/policies.h"
25 : #include "feature/client/bridges.h"
26 : #include "feature/dirauth/authmode.h"
27 : #include "feature/dirclient/dirclient.h"
28 : #include "feature/dirclient/dlstatus.h"
29 : #include "feature/dircommon/directory.h"
30 : #include "feature/dircommon/fp_pair.h"
31 : #include "feature/dirparse/authcert_parse.h"
32 : #include "feature/nodelist/authcert.h"
33 : #include "feature/nodelist/dirlist.h"
34 : #include "feature/nodelist/networkstatus.h"
35 : #include "feature/nodelist/node_select.h"
36 : #include "feature/nodelist/nodelist.h"
37 : #include "feature/nodelist/routerlist.h"
38 : #include "feature/relay/routermode.h"
39 :
40 : #include "core/or/connection_st.h"
41 : #include "feature/dirclient/dir_server_st.h"
42 : #include "feature/dircommon/dir_connection_st.h"
43 : #include "feature/nodelist/authority_cert_st.h"
44 : #include "feature/nodelist/document_signature_st.h"
45 : #include "feature/nodelist/networkstatus_st.h"
46 : #include "feature/nodelist/networkstatus_voter_info_st.h"
47 : #include "feature/nodelist/node_st.h"
48 :
49 24 : DECLARE_TYPED_DIGESTMAP_FNS(dsmap, digest_ds_map_t, download_status_t)
50 : #define DSMAP_FOREACH(map, keyvar, valvar) \
51 : DIGESTMAP_FOREACH(dsmap_to_digestmap(map), keyvar, download_status_t *, \
52 : valvar)
53 : #define dsmap_free(map, fn) MAP_FREE_AND_NULL(dsmap, (map), (fn))
54 :
55 : /* Forward declaration for cert_list_t */
56 : typedef struct cert_list_t cert_list_t;
57 :
58 : static void download_status_reset_by_sk_in_cl(cert_list_t *cl,
59 : const char *digest);
60 : static int download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
61 : const char *digest,
62 : time_t now);
63 : static void list_pending_fpsk_downloads(fp_pair_map_t *result);
64 :
65 : /** List of certificates for a single authority, and download status for
66 : * latest certificate.
67 : */
68 : struct cert_list_t {
69 : /*
70 : * The keys of download status map are cert->signing_key_digest for pending
71 : * downloads by (identity digest/signing key digest) pair; functions such
72 : * as authority_cert_get_by_digest() already assume these are unique.
73 : */
74 : struct digest_ds_map_t *dl_status_map;
75 : /* There is also a dlstatus for the download by identity key only */
76 : download_status_t dl_status_by_id;
77 : smartlist_t *certs;
78 : };
79 : /** Map from v3 identity key digest to cert_list_t. */
80 : static digestmap_t *trusted_dir_certs = NULL;
81 :
82 : /** True iff any key certificate in at least one member of
83 : * <b>trusted_dir_certs</b> has changed since we last flushed the
84 : * certificates to disk. */
85 : static int trusted_dir_servers_certs_changed = 0;
86 :
87 : /** Initialise schedule, want_authority, and increment_on in the download
88 : * status dlstatus, then call download_status_reset() on it.
89 : * It is safe to call this function or download_status_reset() multiple times
90 : * on a new dlstatus. But it should *not* be called after a dlstatus has been
91 : * used to count download attempts or failures. */
92 : static void
93 12 : download_status_cert_init(download_status_t *dlstatus)
94 : {
95 12 : dlstatus->schedule = DL_SCHED_CONSENSUS;
96 12 : dlstatus->want_authority = DL_WANT_ANY_DIRSERVER;
97 12 : dlstatus->increment_on = DL_SCHED_INCREMENT_FAILURE;
98 12 : dlstatus->last_backoff_position = 0;
99 12 : dlstatus->last_delay_used = 0;
100 :
101 : /* Use the new schedule to set next_attempt_at */
102 12 : download_status_reset(dlstatus);
103 12 : }
104 :
105 : /** Reset the download status of a specified element in a dsmap */
106 : static void
107 0 : download_status_reset_by_sk_in_cl(cert_list_t *cl, const char *digest)
108 : {
109 0 : download_status_t *dlstatus = NULL;
110 :
111 0 : tor_assert(cl);
112 0 : tor_assert(digest);
113 :
114 : /* Make sure we have a dsmap */
115 0 : if (!(cl->dl_status_map)) {
116 0 : cl->dl_status_map = dsmap_new();
117 : }
118 : /* Look for a download_status_t in the map with this digest */
119 0 : dlstatus = dsmap_get(cl->dl_status_map, digest);
120 : /* Got one? */
121 0 : if (!dlstatus) {
122 : /* Insert before we reset */
123 0 : dlstatus = tor_malloc_zero(sizeof(*dlstatus));
124 0 : dsmap_set(cl->dl_status_map, digest, dlstatus);
125 0 : download_status_cert_init(dlstatus);
126 : }
127 0 : tor_assert(dlstatus);
128 : /* Go ahead and reset it */
129 0 : download_status_reset(dlstatus);
130 0 : }
131 :
132 : /**
133 : * Return true if the download for this signing key digest in cl is ready
134 : * to be re-attempted.
135 : */
136 : static int
137 0 : download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
138 : const char *digest,
139 : time_t now)
140 : {
141 0 : int rv = 0;
142 0 : download_status_t *dlstatus = NULL;
143 :
144 0 : tor_assert(cl);
145 0 : tor_assert(digest);
146 :
147 : /* Make sure we have a dsmap */
148 0 : if (!(cl->dl_status_map)) {
149 0 : cl->dl_status_map = dsmap_new();
150 : }
151 : /* Look for a download_status_t in the map with this digest */
152 0 : dlstatus = dsmap_get(cl->dl_status_map, digest);
153 : /* Got one? */
154 0 : if (dlstatus) {
155 : /* Use download_status_is_ready() */
156 0 : rv = download_status_is_ready(dlstatus, now);
157 : } else {
158 : /*
159 : * If we don't know anything about it, return 1, since we haven't
160 : * tried this one before. We need to create a new entry here,
161 : * too.
162 : */
163 0 : dlstatus = tor_malloc_zero(sizeof(*dlstatus));
164 0 : download_status_cert_init(dlstatus);
165 0 : dsmap_set(cl->dl_status_map, digest, dlstatus);
166 0 : rv = 1;
167 : }
168 :
169 0 : return rv;
170 : }
171 :
172 : /** Helper: Return the cert_list_t for an authority whose authority ID is
173 : * <b>id_digest</b>, allocating a new list if necessary. */
174 : static cert_list_t *
175 23 : get_cert_list(const char *id_digest)
176 : {
177 23 : cert_list_t *cl;
178 23 : if (!trusted_dir_certs)
179 12 : trusted_dir_certs = digestmap_new();
180 23 : cl = digestmap_get(trusted_dir_certs, id_digest);
181 23 : if (!cl) {
182 12 : cl = tor_malloc_zero(sizeof(cert_list_t));
183 12 : download_status_cert_init(&cl->dl_status_by_id);
184 12 : cl->certs = smartlist_new();
185 12 : cl->dl_status_map = dsmap_new();
186 12 : digestmap_set(trusted_dir_certs, id_digest, cl);
187 : }
188 23 : return cl;
189 : }
190 :
191 : /** Return a list of authority ID digests with potentially enumerable lists
192 : * of download_status_t objects; used by controller GETINFO queries.
193 : */
194 :
195 0 : MOCK_IMPL(smartlist_t *,
196 : list_authority_ids_with_downloads, (void))
197 : {
198 0 : smartlist_t *ids = smartlist_new();
199 0 : digestmap_iter_t *i;
200 0 : const char *digest;
201 0 : char *tmp;
202 0 : void *cl;
203 :
204 0 : if (trusted_dir_certs) {
205 0 : for (i = digestmap_iter_init(trusted_dir_certs);
206 0 : !(digestmap_iter_done(i));
207 0 : i = digestmap_iter_next(trusted_dir_certs, i)) {
208 : /*
209 : * We always have at least dl_status_by_id to query, so no need to
210 : * probe deeper than the existence of a cert_list_t.
211 : */
212 0 : digestmap_iter_get(i, &digest, &cl);
213 0 : tmp = tor_malloc(DIGEST_LEN);
214 0 : memcpy(tmp, digest, DIGEST_LEN);
215 0 : smartlist_add(ids, tmp);
216 : }
217 : }
218 : /* else definitely no downloads going since nothing even has a cert list */
219 :
220 0 : return ids;
221 : }
222 :
223 : /** Given an authority ID digest, return a pointer to the default download
224 : * status, or NULL if there is no such entry in trusted_dir_certs */
225 :
226 0 : MOCK_IMPL(download_status_t *,
227 : id_only_download_status_for_authority_id, (const char *digest))
228 : {
229 0 : download_status_t *dl = NULL;
230 0 : cert_list_t *cl;
231 :
232 0 : if (trusted_dir_certs) {
233 0 : cl = digestmap_get(trusted_dir_certs, digest);
234 0 : if (cl) {
235 0 : dl = &(cl->dl_status_by_id);
236 : }
237 : }
238 :
239 0 : return dl;
240 : }
241 :
242 : /** Given an authority ID digest, return a smartlist of signing key digests
243 : * for which download_status_t is potentially queryable, or NULL if no such
244 : * authority ID digest is known. */
245 :
246 0 : MOCK_IMPL(smartlist_t *,
247 : list_sk_digests_for_authority_id, (const char *digest))
248 : {
249 0 : smartlist_t *sks = NULL;
250 0 : cert_list_t *cl;
251 0 : dsmap_iter_t *i;
252 0 : const char *sk_digest;
253 0 : char *tmp;
254 0 : download_status_t *dl;
255 :
256 0 : if (trusted_dir_certs) {
257 0 : cl = digestmap_get(trusted_dir_certs, digest);
258 0 : if (cl) {
259 0 : sks = smartlist_new();
260 0 : if (cl->dl_status_map) {
261 0 : for (i = dsmap_iter_init(cl->dl_status_map);
262 0 : !(dsmap_iter_done(i));
263 0 : i = dsmap_iter_next(cl->dl_status_map, i)) {
264 : /* Pull the digest out and add it to the list */
265 0 : dsmap_iter_get(i, &sk_digest, &dl);
266 0 : tmp = tor_malloc(DIGEST_LEN);
267 0 : memcpy(tmp, sk_digest, DIGEST_LEN);
268 0 : smartlist_add(sks, tmp);
269 : }
270 : }
271 : }
272 : }
273 :
274 0 : return sks;
275 : }
276 :
277 : /** Given an authority ID digest and a signing key digest, return the
278 : * download_status_t or NULL if none exists. */
279 :
280 0 : MOCK_IMPL(download_status_t *,
281 : download_status_for_authority_id_and_sk,(const char *id_digest,
282 : const char *sk_digest))
283 : {
284 0 : download_status_t *dl = NULL;
285 0 : cert_list_t *cl = NULL;
286 :
287 0 : if (trusted_dir_certs) {
288 0 : cl = digestmap_get(trusted_dir_certs, id_digest);
289 0 : if (cl && cl->dl_status_map) {
290 0 : dl = dsmap_get(cl->dl_status_map, sk_digest);
291 : }
292 : }
293 :
294 0 : return dl;
295 : }
296 :
297 : #define cert_list_free(val) \
298 : FREE_AND_NULL(cert_list_t, cert_list_free_, (val))
299 :
300 : /** Release all space held by a cert_list_t */
301 : static void
302 12 : cert_list_free_(cert_list_t *cl)
303 : {
304 12 : if (!cl)
305 : return;
306 :
307 23 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
308 : authority_cert_free(cert));
309 12 : smartlist_free(cl->certs);
310 12 : dsmap_free(cl->dl_status_map, tor_free_);
311 12 : tor_free(cl);
312 : }
313 :
314 : /** Wrapper for cert_list_free so we can pass it to digestmap_free */
315 : static void
316 12 : cert_list_free_void(void *cl)
317 : {
318 12 : cert_list_free_(cl);
319 12 : }
320 :
321 : /** Reload the cached v3 key certificates from the cached-certs file in
322 : * the data directory. Return 0 on success, -1 on failure. */
323 : int
324 0 : trusted_dirs_reload_certs(void)
325 : {
326 0 : char *filename;
327 0 : char *contents;
328 0 : int r;
329 :
330 0 : filename = get_cachedir_fname("cached-certs");
331 0 : contents = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
332 0 : tor_free(filename);
333 0 : if (!contents)
334 : return 0;
335 0 : r = trusted_dirs_load_certs_from_string(
336 : contents,
337 : TRUSTED_DIRS_CERTS_SRC_FROM_STORE, 1, NULL);
338 0 : tor_free(contents);
339 0 : return r;
340 : }
341 :
342 : /** Helper: return true iff we already have loaded the exact cert
343 : * <b>cert</b>. */
344 : static inline int
345 12 : already_have_cert(authority_cert_t *cert)
346 : {
347 12 : cert_list_t *cl = get_cert_list(cert->cache_info.identity_digest);
348 :
349 12 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
350 : {
351 : if (tor_memeq(c->cache_info.signed_descriptor_digest,
352 : cert->cache_info.signed_descriptor_digest,
353 : DIGEST_LEN))
354 : return 1;
355 : });
356 : return 0;
357 : }
358 :
359 : /** Load a bunch of new key certificates from the string <b>contents</b>. If
360 : * <b>source</b> is TRUSTED_DIRS_CERTS_SRC_FROM_STORE, the certificates are
361 : * from the cache, and we don't need to flush them to disk. If we are a
362 : * dirauth loading our own cert, source is TRUSTED_DIRS_CERTS_SRC_SELF.
363 : * Otherwise, source is download type: TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST
364 : * or TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST. If <b>flush</b> is true, we
365 : * need to flush any changed certificates to disk now. Return 0 on success,
366 : * -1 if any certs fail to parse.
367 : *
368 : * If source_dir is non-NULL, it's the identity digest for a directory that
369 : * we've just successfully retrieved certificates from, so try it first to
370 : * fetch any missing certificates.
371 : */
372 : int
373 12 : trusted_dirs_load_certs_from_string(const char *contents, int source,
374 : int flush, const char *source_dir)
375 : {
376 12 : dir_server_t *ds;
377 12 : const char *s, *eos;
378 12 : int failure_code = 0;
379 12 : int from_store = (source == TRUSTED_DIRS_CERTS_SRC_FROM_STORE);
380 12 : int added_trusted_cert = 0;
381 :
382 24 : for (s = contents; *s; s = eos) {
383 12 : authority_cert_t *cert = authority_cert_parse_from_string(s, strlen(s),
384 : &eos);
385 12 : cert_list_t *cl;
386 12 : if (!cert) {
387 : failure_code = -1;
388 12 : break;
389 : }
390 24 : ds = trusteddirserver_get_by_v3_auth_digest(
391 12 : cert->cache_info.identity_digest);
392 12 : log_debug(LD_DIR, "Parsed certificate for %s",
393 : ds ? ds->nickname : "unknown authority");
394 :
395 12 : if (already_have_cert(cert)) {
396 : /* we already have this one. continue. */
397 0 : log_info(LD_DIR, "Skipping %s certificate for %s that we "
398 : "already have.",
399 : from_store ? "cached" : "downloaded",
400 : ds ? ds->nickname : "an old or new authority");
401 :
402 : /*
403 : * A duplicate on download should be treated as a failure, so we call
404 : * authority_cert_dl_failed() to reset the download status to make sure
405 : * we can't try again. Since we've implemented the fp-sk mechanism
406 : * to download certs by signing key, this should be much rarer than it
407 : * was and is perhaps cause for concern.
408 : */
409 0 : if (!from_store) {
410 0 : if (authdir_mode(get_options())) {
411 0 : log_warn(LD_DIR,
412 : "Got a certificate for %s, but we already have it. "
413 : "Maybe they haven't updated it. Waiting for a while.",
414 : ds ? ds->nickname : "an old or new authority");
415 : } else {
416 0 : log_info(LD_DIR,
417 : "Got a certificate for %s, but we already have it. "
418 : "Maybe they haven't updated it. Waiting for a while.",
419 : ds ? ds->nickname : "an old or new authority");
420 : }
421 :
422 : /*
423 : * This is where we care about the source; authority_cert_dl_failed()
424 : * needs to know whether the download was by fp or (fp,sk) pair to
425 : * twiddle the right bit in the download map.
426 : */
427 0 : if (source == TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST) {
428 0 : authority_cert_dl_failed(cert->cache_info.identity_digest,
429 : NULL, 404);
430 0 : } else if (source == TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST) {
431 0 : authority_cert_dl_failed(cert->cache_info.identity_digest,
432 0 : cert->signing_key_digest, 404);
433 : }
434 : }
435 :
436 0 : authority_cert_free(cert);
437 12 : continue;
438 : }
439 :
440 12 : if (ds) {
441 11 : added_trusted_cert = 1;
442 22 : log_info(LD_DIR, "Adding %s certificate for directory authority %s with "
443 : "signing key %s", from_store ? "cached" : "downloaded",
444 : ds->nickname, hex_str(cert->signing_key_digest,DIGEST_LEN));
445 : } else {
446 1 : int adding = we_want_to_fetch_unknown_auth_certs(get_options());
447 3 : log_info(LD_DIR, "%s %s certificate for unrecognized directory "
448 : "authority with signing key %s",
449 : adding ? "Adding" : "Not adding",
450 : from_store ? "cached" : "downloaded",
451 : hex_str(cert->signing_key_digest,DIGEST_LEN));
452 1 : if (!adding) {
453 1 : authority_cert_free(cert);
454 1 : continue;
455 : }
456 : }
457 :
458 11 : cl = get_cert_list(cert->cache_info.identity_digest);
459 11 : smartlist_add(cl->certs, cert);
460 11 : if (ds && cert->cache_info.published_on > ds->addr_current_at) {
461 : /* Check to see whether we should update our view of the authority's
462 : * address. */
463 11 : if (!tor_addr_is_null(&cert->ipv4_addr) && cert->ipv4_dirport &&
464 0 : (!tor_addr_eq(&ds->ipv4_addr, &cert->ipv4_addr) ||
465 0 : ds->ipv4_dirport != cert->ipv4_dirport)) {
466 0 : log_notice(LD_DIR, "Updating address for directory authority %s "
467 : "from %s:%"PRIu16" to %s:%"PRIu16" based on certificate.",
468 : ds->nickname, ds->address, ds->ipv4_dirport,
469 : fmt_addr(&cert->ipv4_addr), cert->ipv4_dirport);
470 0 : tor_addr_copy(&ds->ipv4_addr, &cert->ipv4_addr);
471 0 : ds->ipv4_dirport = cert->ipv4_dirport;
472 : }
473 11 : ds->addr_current_at = cert->cache_info.published_on;
474 : }
475 :
476 11 : if (!from_store)
477 11 : trusted_dir_servers_certs_changed = 1;
478 : }
479 :
480 12 : if (flush)
481 12 : trusted_dirs_flush_certs_to_disk();
482 :
483 : /* call this even if failure_code is <0, since some certs might have
484 : * succeeded, but only pass source_dir if there were no failures,
485 : * and at least one more authority certificate was added to the store.
486 : * This avoids retrying a directory that's serving bad or entirely duplicate
487 : * certificates. */
488 12 : if (failure_code == 0 && added_trusted_cert) {
489 11 : networkstatus_note_certs_arrived(source_dir);
490 : } else {
491 1 : networkstatus_note_certs_arrived(NULL);
492 : }
493 :
494 12 : return failure_code;
495 : }
496 :
497 : /** Save all v3 key certificates to the cached-certs file. */
498 : void
499 12 : trusted_dirs_flush_certs_to_disk(void)
500 : {
501 12 : char *filename;
502 12 : smartlist_t *chunks;
503 :
504 12 : if (!trusted_dir_servers_certs_changed || !trusted_dir_certs)
505 12 : return;
506 :
507 11 : chunks = smartlist_new();
508 22 : DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
509 22 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
510 : {
511 : sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
512 : c->bytes = cert->cache_info.signed_descriptor_body;
513 : c->len = cert->cache_info.signed_descriptor_len;
514 : smartlist_add(chunks, c);
515 : });
516 11 : } DIGESTMAP_FOREACH_END;
517 :
518 11 : filename = get_cachedir_fname("cached-certs");
519 11 : if (write_chunks_to_file(filename, chunks, 0, 0)) {
520 0 : log_warn(LD_FS, "Error writing certificates to disk.");
521 : }
522 11 : tor_free(filename);
523 22 : SMARTLIST_FOREACH(chunks, sized_chunk_t *, c, tor_free(c));
524 11 : smartlist_free(chunks);
525 :
526 11 : trusted_dir_servers_certs_changed = 0;
527 : }
528 :
529 : static int
530 0 : compare_certs_by_pubdates(const void **_a, const void **_b)
531 : {
532 0 : const authority_cert_t *cert1 = *_a, *cert2=*_b;
533 :
534 0 : if (cert1->cache_info.published_on < cert2->cache_info.published_on)
535 : return -1;
536 0 : else if (cert1->cache_info.published_on > cert2->cache_info.published_on)
537 : return 1;
538 : else
539 0 : return 0;
540 : }
541 :
542 : /** Remove all expired v3 authority certificates that have been superseded for
543 : * more than 48 hours or, if not expired, that were published more than 7 days
544 : * before being superseded. (If the most recent cert was published more than 48
545 : * hours ago, then we aren't going to get any consensuses signed with older
546 : * keys.) */
547 : void
548 0 : trusted_dirs_remove_old_certs(void)
549 : {
550 0 : time_t now = time(NULL);
551 : #define DEAD_CERT_LIFETIME (2*24*60*60)
552 : #define SUPERSEDED_CERT_LIFETIME (2*24*60*60)
553 0 : if (!trusted_dir_certs)
554 : return;
555 :
556 0 : DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
557 : /* Sort the list from first-published to last-published */
558 0 : smartlist_sort(cl->certs, compare_certs_by_pubdates);
559 :
560 0 : SMARTLIST_FOREACH_BEGIN(cl->certs, authority_cert_t *, cert) {
561 0 : if (cert_sl_idx == smartlist_len(cl->certs) - 1) {
562 : /* This is the most recently published cert. Keep it. */
563 0 : continue;
564 : }
565 0 : authority_cert_t *next_cert = smartlist_get(cl->certs, cert_sl_idx+1);
566 0 : const time_t next_cert_published = next_cert->cache_info.published_on;
567 0 : if (next_cert_published > now) {
568 : /* All later certs are published in the future. Keep everything
569 : * we didn't discard. */
570 : break;
571 : }
572 0 : int should_remove = 0;
573 0 : if (cert->expires + DEAD_CERT_LIFETIME < now) {
574 : /* Certificate has been expired for at least DEAD_CERT_LIFETIME.
575 : * Remove it. */
576 : should_remove = 1;
577 0 : } else if (next_cert_published + SUPERSEDED_CERT_LIFETIME < now) {
578 : /* Certificate has been superseded for OLD_CERT_LIFETIME.
579 : * Remove it.
580 : */
581 : should_remove = 1;
582 : }
583 : if (should_remove) {
584 0 : SMARTLIST_DEL_CURRENT_KEEPORDER(cl->certs, cert);
585 0 : authority_cert_free(cert);
586 0 : trusted_dir_servers_certs_changed = 1;
587 : }
588 0 : } SMARTLIST_FOREACH_END(cert);
589 :
590 0 : } DIGESTMAP_FOREACH_END;
591 : #undef DEAD_CERT_LIFETIME
592 : #undef OLD_CERT_LIFETIME
593 :
594 0 : trusted_dirs_flush_certs_to_disk();
595 : }
596 :
597 : /** Return the newest v3 authority certificate whose v3 authority identity key
598 : * has digest <b>id_digest</b>. Return NULL if no such authority is known,
599 : * or it has no certificate. */
600 : authority_cert_t *
601 2 : authority_cert_get_newest_by_id(const char *id_digest)
602 : {
603 2 : cert_list_t *cl;
604 2 : authority_cert_t *best = NULL;
605 2 : if (!trusted_dir_certs ||
606 2 : !(cl = digestmap_get(trusted_dir_certs, id_digest)))
607 0 : return NULL;
608 :
609 4 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
610 : {
611 : if (!best || cert->cache_info.published_on > best->cache_info.published_on)
612 : best = cert;
613 : });
614 : return best;
615 : }
616 :
617 : /** Return the newest v3 authority certificate whose directory signing key has
618 : * digest <b>sk_digest</b>. Return NULL if no such certificate is known.
619 : */
620 : authority_cert_t *
621 1 : authority_cert_get_by_sk_digest(const char *sk_digest)
622 : {
623 1 : authority_cert_t *c;
624 1 : if (!trusted_dir_certs)
625 : return NULL;
626 :
627 2 : if ((c = get_my_v3_authority_cert()) &&
628 1 : tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
629 : return c;
630 0 : if ((c = get_my_v3_legacy_cert()) &&
631 0 : tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
632 : return c;
633 :
634 0 : DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
635 0 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
636 : {
637 : if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
638 : return cert;
639 : });
640 : } DIGESTMAP_FOREACH_END;
641 : return NULL;
642 : }
643 :
644 : /** Return the v3 authority certificate with signing key matching
645 : * <b>sk_digest</b>, for the authority with identity digest <b>id_digest</b>.
646 : * Return NULL if no such authority is known. */
647 : authority_cert_t *
648 499 : authority_cert_get_by_digests(const char *id_digest,
649 : const char *sk_digest)
650 : {
651 499 : cert_list_t *cl;
652 499 : if (!trusted_dir_certs ||
653 54 : !(cl = digestmap_get(trusted_dir_certs, id_digest)))
654 445 : return NULL;
655 54 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
656 : if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
657 : return cert; );
658 :
659 : return NULL;
660 : }
661 :
662 : /** Add every known authority_cert_t to <b>certs_out</b>. */
663 : void
664 2 : authority_cert_get_all(smartlist_t *certs_out)
665 : {
666 2 : tor_assert(certs_out);
667 2 : if (!trusted_dir_certs)
668 : return;
669 :
670 2 : DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
671 2 : SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
672 : smartlist_add(certs_out, c));
673 2 : } DIGESTMAP_FOREACH_END;
674 : }
675 :
676 : /** Called when an attempt to download a certificate with the authority with
677 : * ID <b>id_digest</b> and, if not NULL, signed with key signing_key_digest
678 : * fails with HTTP response code <b>status</b>: remember the failure, so we
679 : * don't try again immediately. */
680 : void
681 0 : authority_cert_dl_failed(const char *id_digest,
682 : const char *signing_key_digest, int status)
683 : {
684 0 : cert_list_t *cl;
685 0 : download_status_t *dlstatus = NULL;
686 0 : char id_digest_str[2*DIGEST_LEN+1];
687 0 : char sk_digest_str[2*DIGEST_LEN+1];
688 :
689 0 : if (!trusted_dir_certs ||
690 0 : !(cl = digestmap_get(trusted_dir_certs, id_digest)))
691 0 : return;
692 :
693 : /*
694 : * Are we noting a failed download of the latest cert for the id digest,
695 : * or of a download by (id, signing key) digest pair?
696 : */
697 0 : if (!signing_key_digest) {
698 : /* Just by id digest */
699 0 : download_status_failed(&cl->dl_status_by_id, status);
700 : } else {
701 : /* Reset by (id, signing key) digest pair
702 : *
703 : * Look for a download_status_t in the map with this digest
704 : */
705 0 : dlstatus = dsmap_get(cl->dl_status_map, signing_key_digest);
706 : /* Got one? */
707 0 : if (dlstatus) {
708 0 : download_status_failed(dlstatus, status);
709 : } else {
710 : /*
711 : * Do this rather than hex_str(), since hex_str clobbers
712 : * old results and we call twice in the param list.
713 : */
714 0 : base16_encode(id_digest_str, sizeof(id_digest_str),
715 : id_digest, DIGEST_LEN);
716 0 : base16_encode(sk_digest_str, sizeof(sk_digest_str),
717 : signing_key_digest, DIGEST_LEN);
718 0 : log_warn(LD_BUG,
719 : "Got failure for cert fetch with (fp,sk) = (%s,%s), with "
720 : "status %d, but knew nothing about the download.",
721 : id_digest_str, sk_digest_str, status);
722 : }
723 : }
724 : }
725 :
726 : static const char *BAD_SIGNING_KEYS[] = {
727 : "09CD84F751FD6E955E0F8ADB497D5401470D697E", // Expires 2015-01-11 16:26:31
728 : "0E7E9C07F0969D0468AD741E172A6109DC289F3C", // Expires 2014-08-12 10:18:26
729 : "57B85409891D3FB32137F642FDEDF8B7F8CDFDCD", // Expires 2015-02-11 17:19:09
730 : "87326329007AF781F587AF5B594E540B2B6C7630", // Expires 2014-07-17 11:10:09
731 : "98CC82342DE8D298CF99D3F1A396475901E0D38E", // Expires 2014-11-10 13:18:56
732 : "9904B52336713A5ADCB13E4FB14DC919E0D45571", // Expires 2014-04-20 20:01:01
733 : "9DCD8E3F1DD1597E2AD476BBA28A1A89F3095227", // Expires 2015-01-16 03:52:30
734 : "A61682F34B9BB9694AC98491FE1ABBFE61923941", // Expires 2014-06-11 09:25:09
735 : "B59F6E99C575113650C99F1C425BA7B20A8C071D", // Expires 2014-07-31 13:22:10
736 : "D27178388FA75B96D37FA36E0B015227DDDBDA51", // Expires 2014-08-04 04:01:57
737 : NULL,
738 : };
739 :
740 : /** Return true iff <b>cert</b> authenticates some atuhority signing key
741 : * which, because of the old openssl heartbleed vulnerability, should
742 : * never be trusted. */
743 : int
744 329 : authority_cert_is_denylisted(const authority_cert_t *cert)
745 : {
746 329 : char hex_digest[HEX_DIGEST_LEN+1];
747 329 : int i;
748 329 : base16_encode(hex_digest, sizeof(hex_digest),
749 329 : cert->signing_key_digest, sizeof(cert->signing_key_digest));
750 :
751 3948 : for (i = 0; BAD_SIGNING_KEYS[i]; ++i) {
752 3290 : if (!strcasecmp(hex_digest, BAD_SIGNING_KEYS[i])) {
753 : return 1;
754 : }
755 : }
756 : return 0;
757 : }
758 :
759 : /** Return true iff when we've been getting enough failures when trying to
760 : * download the certificate with ID digest <b>id_digest</b> that we're willing
761 : * to start bugging the user about it. */
762 : int
763 0 : authority_cert_dl_looks_uncertain(const char *id_digest)
764 : {
765 : #define N_AUTH_CERT_DL_FAILURES_TO_BUG_USER 2
766 0 : cert_list_t *cl;
767 0 : int n_failures;
768 0 : if (!trusted_dir_certs ||
769 0 : !(cl = digestmap_get(trusted_dir_certs, id_digest)))
770 0 : return 0;
771 :
772 0 : n_failures = download_status_get_n_failures(&cl->dl_status_by_id);
773 0 : return n_failures >= N_AUTH_CERT_DL_FAILURES_TO_BUG_USER;
774 : }
775 :
776 : /* Fetch the authority certificates specified in resource.
777 : * If we are a bridge client, and node is a configured bridge, fetch from node
778 : * using dir_hint as the fingerprint. Otherwise, if rs is not NULL, fetch from
779 : * rs. Otherwise, fetch from a random directory mirror. */
780 : static void
781 0 : authority_certs_fetch_resource_impl(const char *resource,
782 : const char *dir_hint,
783 : const node_t *node,
784 : const routerstatus_t *rs)
785 : {
786 0 : const or_options_t *options = get_options();
787 0 : int get_via_tor = purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0,
788 : resource);
789 :
790 : /* Make sure bridge clients never connect to anything but a bridge */
791 0 : if (options->UseBridges) {
792 0 : if (node && !node_is_a_configured_bridge(node)) {
793 : /* If we're using bridges, and node is not a bridge, use a 3-hop path. */
794 : get_via_tor = 1;
795 0 : } else if (!node) {
796 : /* If we're using bridges, and there's no node, use a 3-hop path. */
797 0 : get_via_tor = 1;
798 : }
799 : }
800 :
801 0 : const dir_indirection_t indirection = get_via_tor ? DIRIND_ANONYMOUS
802 0 : : DIRIND_ONEHOP;
803 :
804 0 : directory_request_t *req = NULL;
805 : /* If we've just downloaded a consensus from a bridge, re-use that
806 : * bridge */
807 0 : if (options->UseBridges && node && node->ri && !get_via_tor) {
808 : /* clients always make OR connections to bridges */
809 0 : tor_addr_port_t or_ap;
810 : /* we are willing to use a non-preferred address if we need to */
811 0 : reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0,
812 : &or_ap);
813 :
814 0 : req = directory_request_new(DIR_PURPOSE_FETCH_CERTIFICATE);
815 0 : directory_request_set_or_addr_port(req, &or_ap);
816 0 : if (dir_hint)
817 0 : directory_request_set_directory_id_digest(req, dir_hint);
818 0 : } else if (rs) {
819 : /* And if we've just downloaded a consensus from a directory, re-use that
820 : * directory */
821 0 : req = directory_request_new(DIR_PURPOSE_FETCH_CERTIFICATE);
822 0 : directory_request_set_routerstatus(req, rs);
823 : }
824 :
825 0 : if (req) {
826 : /* We've set up a request object -- fill in the other request fields, and
827 : * send the request. */
828 0 : directory_request_set_indirection(req, indirection);
829 0 : directory_request_set_resource(req, resource);
830 0 : directory_initiate_request(req);
831 0 : directory_request_free(req);
832 0 : return;
833 : }
834 :
835 : /* Otherwise, we want certs from a random fallback or directory
836 : * mirror, because they will almost always succeed. */
837 0 : directory_get_from_dirserver(DIR_PURPOSE_FETCH_CERTIFICATE, 0,
838 : resource, PDS_RETRY_IF_NO_SERVERS,
839 : DL_WANT_ANY_DIRSERVER);
840 : }
841 :
842 : /** Try to download any v3 authority certificates that we may be missing. If
843 : * <b>status</b> is provided, try to get all the ones that were used to sign
844 : * <b>status</b>. Additionally, try to have a non-expired certificate for
845 : * every V3 authority in trusted_dir_servers. Don't fetch certificates we
846 : * already have.
847 : *
848 : * If dir_hint is non-NULL, it's the identity digest for a directory that
849 : * we've just successfully retrieved a consensus or certificates from, so try
850 : * it first to fetch any missing certificates.
851 : **/
852 : void
853 0 : authority_certs_fetch_missing(networkstatus_t *status, time_t now,
854 : const char *dir_hint)
855 : {
856 : /*
857 : * The pending_id digestmap tracks pending certificate downloads by
858 : * identity digest; the pending_cert digestmap tracks pending downloads
859 : * by (identity digest, signing key digest) pairs.
860 : */
861 0 : digestmap_t *pending_id;
862 0 : fp_pair_map_t *pending_cert;
863 : /*
864 : * The missing_id_digests smartlist will hold a list of id digests
865 : * we want to fetch the newest cert for; the missing_cert_digests
866 : * smartlist will hold a list of fp_pair_t with an identity and
867 : * signing key digest.
868 : */
869 0 : smartlist_t *missing_cert_digests, *missing_id_digests;
870 0 : char *resource = NULL;
871 0 : cert_list_t *cl;
872 0 : const or_options_t *options = get_options();
873 0 : const int keep_unknown = we_want_to_fetch_unknown_auth_certs(options);
874 0 : fp_pair_t *fp_tmp = NULL;
875 0 : char id_digest_str[2*DIGEST_LEN+1];
876 0 : char sk_digest_str[2*DIGEST_LEN+1];
877 :
878 0 : if (should_delay_dir_fetches(options, NULL))
879 0 : return;
880 :
881 0 : pending_cert = fp_pair_map_new();
882 0 : pending_id = digestmap_new();
883 0 : missing_cert_digests = smartlist_new();
884 0 : missing_id_digests = smartlist_new();
885 :
886 : /*
887 : * First, we get the lists of already pending downloads so we don't
888 : * duplicate effort.
889 : */
890 0 : list_pending_downloads(pending_id, NULL,
891 : DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
892 0 : list_pending_fpsk_downloads(pending_cert);
893 :
894 : /*
895 : * Now, we download any trusted authority certs we don't have by
896 : * identity digest only. This gets the latest cert for that authority.
897 : */
898 0 : SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
899 : dir_server_t *, ds) {
900 0 : int found = 0;
901 0 : if (!(ds->type & V3_DIRINFO))
902 0 : continue;
903 0 : if (smartlist_contains_digest(missing_id_digests,
904 0 : ds->v3_identity_digest))
905 0 : continue;
906 0 : cl = get_cert_list(ds->v3_identity_digest);
907 0 : SMARTLIST_FOREACH_BEGIN(cl->certs, authority_cert_t *, cert) {
908 0 : if (now < cert->expires) {
909 : /* It's not expired, and we weren't looking for something to
910 : * verify a consensus with. Call it done. */
911 0 : download_status_reset(&(cl->dl_status_by_id));
912 : /* No sense trying to download it specifically by signing key hash */
913 0 : download_status_reset_by_sk_in_cl(cl, cert->signing_key_digest);
914 0 : found = 1;
915 0 : break;
916 : }
917 0 : } SMARTLIST_FOREACH_END(cert);
918 0 : if (!found &&
919 0 : download_status_is_ready(&(cl->dl_status_by_id), now) &&
920 0 : !digestmap_get(pending_id, ds->v3_identity_digest)) {
921 0 : log_info(LD_DIR,
922 : "No current certificate known for authority %s "
923 : "(ID digest %s); launching request.",
924 : ds->nickname, hex_str(ds->v3_identity_digest, DIGEST_LEN));
925 0 : smartlist_add(missing_id_digests, ds->v3_identity_digest);
926 : }
927 0 : } SMARTLIST_FOREACH_END(ds);
928 :
929 : /*
930 : * Next, if we have a consensus, scan through it and look for anything
931 : * signed with a key from a cert we don't have. Those get downloaded
932 : * by (fp,sk) pair, but if we don't know any certs at all for the fp
933 : * (identity digest), and it's one of the trusted dir server certs
934 : * we started off above or a pending download in pending_id, don't
935 : * try to get it yet. Most likely, the one we'll get for that will
936 : * have the right signing key too, and we'd just be downloading
937 : * redundantly.
938 : */
939 0 : if (status) {
940 0 : SMARTLIST_FOREACH_BEGIN(status->voters, networkstatus_voter_info_t *,
941 : voter) {
942 0 : if (!smartlist_len(voter->sigs))
943 0 : continue; /* This authority never signed this consensus, so don't
944 : * go looking for a cert with key digest 0000000000. */
945 0 : if (!keep_unknown &&
946 0 : !trusteddirserver_get_by_v3_auth_digest(voter->identity_digest))
947 0 : continue; /* We don't want unknown certs, and we don't know this
948 : * authority.*/
949 :
950 : /*
951 : * If we don't know *any* cert for this authority, and a download by ID
952 : * is pending or we added it to missing_id_digests above, skip this
953 : * one for now to avoid duplicate downloads.
954 : */
955 0 : cl = get_cert_list(voter->identity_digest);
956 0 : if (smartlist_len(cl->certs) == 0) {
957 : /* We have no certs at all for this one */
958 :
959 : /* Do we have a download of one pending? */
960 0 : if (digestmap_get(pending_id, voter->identity_digest))
961 0 : continue;
962 :
963 : /*
964 : * Are we about to launch a download of one due to the trusted
965 : * dir server check above?
966 : */
967 0 : if (smartlist_contains_digest(missing_id_digests,
968 : voter->identity_digest))
969 0 : continue;
970 : }
971 :
972 0 : SMARTLIST_FOREACH_BEGIN(voter->sigs, document_signature_t *, sig) {
973 0 : authority_cert_t *cert =
974 0 : authority_cert_get_by_digests(voter->identity_digest,
975 0 : sig->signing_key_digest);
976 0 : if (cert) {
977 0 : if (now < cert->expires)
978 0 : download_status_reset_by_sk_in_cl(cl, sig->signing_key_digest);
979 0 : continue;
980 : }
981 0 : if (download_status_is_ready_by_sk_in_cl(
982 0 : cl, sig->signing_key_digest, now) &&
983 0 : !fp_pair_map_get_by_digests(pending_cert,
984 : voter->identity_digest,
985 : sig->signing_key_digest)) {
986 : /*
987 : * Do this rather than hex_str(), since hex_str clobbers
988 : * old results and we call twice in the param list.
989 : */
990 0 : base16_encode(id_digest_str, sizeof(id_digest_str),
991 : voter->identity_digest, DIGEST_LEN);
992 0 : base16_encode(sk_digest_str, sizeof(sk_digest_str),
993 : sig->signing_key_digest, DIGEST_LEN);
994 :
995 0 : if (voter->nickname) {
996 0 : log_info(LD_DIR,
997 : "We're missing a certificate from authority %s "
998 : "(ID digest %s) with signing key %s: "
999 : "launching request.",
1000 : voter->nickname, id_digest_str, sk_digest_str);
1001 : } else {
1002 0 : log_info(LD_DIR,
1003 : "We're missing a certificate from authority ID digest "
1004 : "%s with signing key %s: launching request.",
1005 : id_digest_str, sk_digest_str);
1006 : }
1007 :
1008 : /* Allocate a new fp_pair_t to append */
1009 0 : fp_tmp = tor_malloc(sizeof(*fp_tmp));
1010 0 : memcpy(fp_tmp->first, voter->identity_digest, sizeof(fp_tmp->first));
1011 0 : memcpy(fp_tmp->second, sig->signing_key_digest,
1012 : sizeof(fp_tmp->second));
1013 0 : smartlist_add(missing_cert_digests, fp_tmp);
1014 : }
1015 0 : } SMARTLIST_FOREACH_END(sig);
1016 0 : } SMARTLIST_FOREACH_END(voter);
1017 : }
1018 :
1019 : /* Bridge clients look up the node for the dir_hint */
1020 0 : const node_t *node = NULL;
1021 : /* All clients, including bridge clients, look up the routerstatus for the
1022 : * dir_hint */
1023 0 : const routerstatus_t *rs = NULL;
1024 :
1025 : /* If we still need certificates, try the directory that just successfully
1026 : * served us a consensus or certificates.
1027 : * As soon as the directory fails to provide additional certificates, we try
1028 : * another, randomly selected directory. This avoids continual retries.
1029 : * (We only ever have one outstanding request per certificate.)
1030 : */
1031 0 : if (dir_hint) {
1032 0 : if (options->UseBridges) {
1033 : /* Bridge clients try the nodelist. If the dir_hint is from an authority,
1034 : * or something else fetched over tor, we won't find the node here, but
1035 : * we will find the rs. */
1036 0 : node = node_get_by_id(dir_hint);
1037 : }
1038 :
1039 : /* All clients try the consensus routerstatus, then the fallback
1040 : * routerstatus */
1041 0 : rs = router_get_consensus_status_by_id(dir_hint);
1042 0 : if (!rs) {
1043 : /* This will also find authorities */
1044 0 : const dir_server_t *ds = router_get_fallback_dirserver_by_digest(
1045 : dir_hint);
1046 0 : if (ds) {
1047 0 : rs = &ds->fake_status;
1048 : }
1049 : }
1050 :
1051 0 : if (!node && !rs) {
1052 0 : log_warn(LD_BUG, "Directory %s delivered a consensus, but %s"
1053 : "no routerstatus could be found for it.",
1054 : options->UseBridges ? "no node and " : "",
1055 : hex_str(dir_hint, DIGEST_LEN));
1056 : }
1057 : }
1058 :
1059 : /* Do downloads by identity digest */
1060 0 : if (smartlist_len(missing_id_digests) > 0) {
1061 0 : int need_plus = 0;
1062 0 : smartlist_t *fps = smartlist_new();
1063 :
1064 0 : smartlist_add_strdup(fps, "fp/");
1065 :
1066 0 : SMARTLIST_FOREACH_BEGIN(missing_id_digests, const char *, d) {
1067 0 : char *fp = NULL;
1068 :
1069 0 : if (digestmap_get(pending_id, d))
1070 0 : continue;
1071 :
1072 0 : base16_encode(id_digest_str, sizeof(id_digest_str),
1073 : d, DIGEST_LEN);
1074 :
1075 0 : if (need_plus) {
1076 0 : tor_asprintf(&fp, "+%s", id_digest_str);
1077 : } else {
1078 : /* No need for tor_asprintf() in this case; first one gets no '+' */
1079 0 : fp = tor_strdup(id_digest_str);
1080 0 : need_plus = 1;
1081 : }
1082 :
1083 0 : smartlist_add(fps, fp);
1084 0 : } SMARTLIST_FOREACH_END(d);
1085 :
1086 0 : if (smartlist_len(fps) > 1) {
1087 0 : resource = smartlist_join_strings(fps, "", 0, NULL);
1088 : /* node and rs are directories that just gave us a consensus or
1089 : * certificates */
1090 0 : authority_certs_fetch_resource_impl(resource, dir_hint, node, rs);
1091 0 : tor_free(resource);
1092 : }
1093 : /* else we didn't add any: they were all pending */
1094 :
1095 0 : SMARTLIST_FOREACH(fps, char *, cp, tor_free(cp));
1096 0 : smartlist_free(fps);
1097 : }
1098 :
1099 : /* Do downloads by identity digest/signing key pair */
1100 0 : if (smartlist_len(missing_cert_digests) > 0) {
1101 0 : int need_plus = 0;
1102 0 : smartlist_t *fp_pairs = smartlist_new();
1103 :
1104 0 : smartlist_add_strdup(fp_pairs, "fp-sk/");
1105 :
1106 0 : SMARTLIST_FOREACH_BEGIN(missing_cert_digests, const fp_pair_t *, d) {
1107 0 : char *fp_pair = NULL;
1108 :
1109 0 : if (fp_pair_map_get(pending_cert, d))
1110 0 : continue;
1111 :
1112 : /* Construct string encodings of the digests */
1113 0 : base16_encode(id_digest_str, sizeof(id_digest_str),
1114 0 : d->first, DIGEST_LEN);
1115 0 : base16_encode(sk_digest_str, sizeof(sk_digest_str),
1116 0 : d->second, DIGEST_LEN);
1117 :
1118 : /* Now tor_asprintf() */
1119 0 : if (need_plus) {
1120 0 : tor_asprintf(&fp_pair, "+%s-%s", id_digest_str, sk_digest_str);
1121 : } else {
1122 : /* First one in the list doesn't get a '+' */
1123 0 : tor_asprintf(&fp_pair, "%s-%s", id_digest_str, sk_digest_str);
1124 0 : need_plus = 1;
1125 : }
1126 :
1127 : /* Add it to the list of pairs to request */
1128 0 : smartlist_add(fp_pairs, fp_pair);
1129 0 : } SMARTLIST_FOREACH_END(d);
1130 :
1131 0 : if (smartlist_len(fp_pairs) > 1) {
1132 0 : resource = smartlist_join_strings(fp_pairs, "", 0, NULL);
1133 : /* node and rs are directories that just gave us a consensus or
1134 : * certificates */
1135 0 : authority_certs_fetch_resource_impl(resource, dir_hint, node, rs);
1136 0 : tor_free(resource);
1137 : }
1138 : /* else they were all pending */
1139 :
1140 0 : SMARTLIST_FOREACH(fp_pairs, char *, p, tor_free(p));
1141 0 : smartlist_free(fp_pairs);
1142 : }
1143 :
1144 0 : smartlist_free(missing_id_digests);
1145 0 : SMARTLIST_FOREACH(missing_cert_digests, fp_pair_t *, p, tor_free(p));
1146 0 : smartlist_free(missing_cert_digests);
1147 0 : digestmap_free(pending_id, NULL);
1148 0 : fp_pair_map_free(pending_cert, NULL);
1149 : }
1150 :
1151 : void
1152 301 : authcert_free_all(void)
1153 : {
1154 301 : if (trusted_dir_certs) {
1155 12 : digestmap_free(trusted_dir_certs, cert_list_free_void);
1156 12 : trusted_dir_certs = NULL;
1157 : }
1158 301 : }
1159 :
1160 : /** Free storage held in <b>cert</b>. */
1161 : void
1162 2903 : authority_cert_free_(authority_cert_t *cert)
1163 : {
1164 2903 : if (!cert)
1165 : return;
1166 :
1167 482 : tor_free(cert->cache_info.signed_descriptor_body);
1168 482 : crypto_pk_free(cert->signing_key);
1169 482 : crypto_pk_free(cert->identity_key);
1170 :
1171 482 : tor_free(cert);
1172 : }
1173 :
1174 : /** For every certificate we are currently downloading by (identity digest,
1175 : * signing key digest) pair, set result[fp_pair] to (void *1).
1176 : */
1177 : static void
1178 0 : list_pending_fpsk_downloads(fp_pair_map_t *result)
1179 : {
1180 0 : const char *pfx = "fp-sk/";
1181 0 : smartlist_t *tmp;
1182 0 : smartlist_t *conns;
1183 0 : const char *resource;
1184 :
1185 0 : tor_assert(result);
1186 :
1187 0 : tmp = smartlist_new();
1188 0 : conns = get_connection_array();
1189 :
1190 0 : SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
1191 0 : if (conn->type == CONN_TYPE_DIR &&
1192 0 : conn->purpose == DIR_PURPOSE_FETCH_CERTIFICATE &&
1193 0 : !conn->marked_for_close) {
1194 0 : resource = TO_DIR_CONN(conn)->requested_resource;
1195 0 : if (!strcmpstart(resource, pfx))
1196 0 : dir_split_resource_into_fingerprint_pairs(resource + strlen(pfx),
1197 : tmp);
1198 : }
1199 0 : } SMARTLIST_FOREACH_END(conn);
1200 :
1201 0 : SMARTLIST_FOREACH_BEGIN(tmp, fp_pair_t *, fp) {
1202 0 : fp_pair_map_set(result, fp, (void*)1);
1203 0 : tor_free(fp);
1204 0 : } SMARTLIST_FOREACH_END(fp);
1205 :
1206 0 : smartlist_free(tmp);
1207 0 : }
|