LCOV - code coverage report
Current view: top level - feature/nodelist - authcert.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 126 474 26.6 %
Date: 2021-11-24 03:28:48 Functions: 16 36 44.4 %

          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 : }

Generated by: LCOV version 1.14