"Fossies" - the Fresh Open Source Software Archive

Member "tor-0.4.1.6/src/feature/nodelist/authcert.c" (10 Jun 2019, 42000 Bytes) of package /linux/misc/tor-0.4.1.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "authcert.c" see the Fossies "Dox" file reference documentation.

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