tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

authcert.c (42067B)


      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 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 (!tor_addr_is_null(&cert->ipv4_addr) && cert->ipv4_dirport &&
    464          (!tor_addr_eq(&ds->ipv4_addr, &cert->ipv4_addr) ||
    465           ds->ipv4_dirport != cert->ipv4_dirport)) {
    466        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        tor_addr_copy(&ds->ipv4_addr, &cert->ipv4_addr);
    471        ds->ipv4_dirport = cert->ipv4_dirport;
    472      }
    473      ds->addr_current_at = cert->cache_info.published_on;
    474    }
    475 
    476    if (!from_store)
    477      trusted_dir_servers_certs_changed = 1;
    478  }
    479 
    480  if (flush)
    481    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  if (failure_code == 0 && added_trusted_cert) {
    489    networkstatus_note_certs_arrived(source_dir);
    490  } else {
    491    networkstatus_note_certs_arrived(NULL);
    492  }
    493 
    494  return failure_code;
    495 }
    496 
    497 /** Save all v3 key certificates to the cached-certs file. */
    498 void
    499 trusted_dirs_flush_certs_to_disk(void)
    500 {
    501  char *filename;
    502  smartlist_t *chunks;
    503 
    504  if (!trusted_dir_servers_certs_changed || !trusted_dir_certs)
    505    return;
    506 
    507  chunks = smartlist_new();
    508  DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
    509    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  } DIGESTMAP_FOREACH_END;
    517 
    518  filename = get_cachedir_fname("cached-certs");
    519  if (write_chunks_to_file(filename, chunks, 0, 0)) {
    520    log_warn(LD_FS, "Error writing certificates to disk.");
    521  }
    522  tor_free(filename);
    523  SMARTLIST_FOREACH(chunks, sized_chunk_t *, c, tor_free(c));
    524  smartlist_free(chunks);
    525 
    526  trusted_dir_servers_certs_changed = 0;
    527 }
    528 
    529 static int
    530 compare_certs_by_pubdates(const void **_a, const void **_b)
    531 {
    532  const authority_cert_t *cert1 = *_a, *cert2=*_b;
    533 
    534  if (cert1->cache_info.published_on < cert2->cache_info.published_on)
    535    return -1;
    536  else if (cert1->cache_info.published_on >  cert2->cache_info.published_on)
    537    return 1;
    538  else
    539    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 trusted_dirs_remove_old_certs(void)
    549 {
    550  time_t now = time(NULL);
    551 #define DEAD_CERT_LIFETIME (2*24*60*60)
    552 #define SUPERSEDED_CERT_LIFETIME (2*24*60*60)
    553  if (!trusted_dir_certs)
    554    return;
    555 
    556  DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
    557    /* Sort the list from first-published to last-published */
    558    smartlist_sort(cl->certs, compare_certs_by_pubdates);
    559 
    560    SMARTLIST_FOREACH_BEGIN(cl->certs, authority_cert_t *, cert) {
    561      if (cert_sl_idx == smartlist_len(cl->certs) - 1) {
    562        /* This is the most recently published cert.  Keep it. */
    563        continue;
    564      }
    565      authority_cert_t *next_cert = smartlist_get(cl->certs, cert_sl_idx+1);
    566      const time_t next_cert_published = next_cert->cache_info.published_on;
    567      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      int should_remove = 0;
    573      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      } 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        SMARTLIST_DEL_CURRENT_KEEPORDER(cl->certs, cert);
    585        authority_cert_free(cert);
    586        trusted_dir_servers_certs_changed = 1;
    587      }
    588    } SMARTLIST_FOREACH_END(cert);
    589 
    590  } DIGESTMAP_FOREACH_END;
    591 #undef DEAD_CERT_LIFETIME
    592 #undef OLD_CERT_LIFETIME
    593 
    594  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 authority_cert_get_newest_by_id(const char *id_digest)
    602 {
    603  cert_list_t *cl;
    604  authority_cert_t *best = NULL;
    605  if (!trusted_dir_certs ||
    606      !(cl = digestmap_get(trusted_dir_certs, id_digest)))
    607    return NULL;
    608 
    609  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 authority_cert_get_by_sk_digest(const char *sk_digest)
    622 {
    623  authority_cert_t *c;
    624  if (!trusted_dir_certs)
    625    return NULL;
    626 
    627  if ((c = get_my_v3_authority_cert()) &&
    628      tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
    629    return c;
    630  if ((c = get_my_v3_legacy_cert()) &&
    631      tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
    632    return c;
    633 
    634  DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
    635    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 authority_cert_get_by_digests(const char *id_digest,
    649                              const char *sk_digest)
    650 {
    651  cert_list_t *cl;
    652  if (!trusted_dir_certs ||
    653      !(cl = digestmap_get(trusted_dir_certs, id_digest)))
    654    return NULL;
    655  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 authority_cert_get_all(smartlist_t *certs_out)
    665 {
    666  tor_assert(certs_out);
    667  if (!trusted_dir_certs)
    668    return;
    669 
    670  DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
    671    SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
    672                      smartlist_add(certs_out, c));
    673  } 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 authority_cert_dl_failed(const char *id_digest,
    682                         const char *signing_key_digest, int status)
    683 {
    684  cert_list_t *cl;
    685  download_status_t *dlstatus = NULL;
    686  char id_digest_str[2*DIGEST_LEN+1];
    687  char sk_digest_str[2*DIGEST_LEN+1];
    688 
    689  if (!trusted_dir_certs ||
    690      !(cl = digestmap_get(trusted_dir_certs, id_digest)))
    691    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  if (!signing_key_digest) {
    698    /* Just by id digest */
    699    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    dlstatus = dsmap_get(cl->dl_status_map, signing_key_digest);
    706    /* Got one? */
    707    if (dlstatus) {
    708      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      base16_encode(id_digest_str, sizeof(id_digest_str),
    715                    id_digest, DIGEST_LEN);
    716      base16_encode(sk_digest_str, sizeof(sk_digest_str),
    717                    signing_key_digest, DIGEST_LEN);
    718      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 authority_cert_is_denylisted(const authority_cert_t *cert)
    745 {
    746  char hex_digest[HEX_DIGEST_LEN+1];
    747  int i;
    748  base16_encode(hex_digest, sizeof(hex_digest),
    749                cert->signing_key_digest, sizeof(cert->signing_key_digest));
    750 
    751  for (i = 0; BAD_SIGNING_KEYS[i]; ++i) {
    752    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 authority_cert_dl_looks_uncertain(const char *id_digest)
    764 {
    765 #define N_AUTH_CERT_DL_FAILURES_TO_BUG_USER 2
    766  cert_list_t *cl;
    767  int n_failures;
    768  if (!trusted_dir_certs ||
    769      !(cl = digestmap_get(trusted_dir_certs, id_digest)))
    770    return 0;
    771 
    772  n_failures = download_status_get_n_failures(&cl->dl_status_by_id);
    773  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 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  const or_options_t *options = get_options();
    787  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  if (options->UseBridges) {
    792    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    } else if (!node) {
    796      /* If we're using bridges, and there's no node, use a 3-hop path. */
    797      get_via_tor = 1;
    798    }
    799  }
    800 
    801  const dir_indirection_t indirection = get_via_tor ? DIRIND_ANONYMOUS
    802                                                    : DIRIND_ONEHOP;
    803 
    804  directory_request_t *req = NULL;
    805  /* If we've just downloaded a consensus from a bridge, re-use that
    806   * bridge */
    807  if (options->UseBridges && node && node->ri && !get_via_tor) {
    808    /* clients always make OR connections to bridges */
    809    tor_addr_port_t or_ap;
    810    /* we are willing to use a non-preferred address if we need to */
    811    reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0,
    812                                         &or_ap);
    813 
    814    req = directory_request_new(DIR_PURPOSE_FETCH_CERTIFICATE);
    815    directory_request_set_or_addr_port(req, &or_ap);
    816    if (dir_hint)
    817      directory_request_set_directory_id_digest(req, dir_hint);
    818  } else if (rs) {
    819    /* And if we've just downloaded a consensus from a directory, re-use that
    820     * directory */
    821    req = directory_request_new(DIR_PURPOSE_FETCH_CERTIFICATE);
    822    directory_request_set_routerstatus(req, rs);
    823  }
    824 
    825  if (req) {
    826    /* We've set up a request object -- fill in the other request fields, and
    827     * send the request.  */
    828    directory_request_set_indirection(req, indirection);
    829    directory_request_set_resource(req, resource);
    830    directory_initiate_request(req);
    831    directory_request_free(req);
    832    return;
    833  }
    834 
    835  /* Otherwise, we want certs from a random fallback or directory
    836   * mirror, because they will almost always succeed. */
    837  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 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  digestmap_t *pending_id;
    862  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  smartlist_t *missing_cert_digests, *missing_id_digests;
    870  char *resource = NULL;
    871  cert_list_t *cl;
    872  const or_options_t *options = get_options();
    873  const int keep_unknown = we_want_to_fetch_unknown_auth_certs(options);
    874  fp_pair_t *fp_tmp = NULL;
    875  char id_digest_str[2*DIGEST_LEN+1];
    876  char sk_digest_str[2*DIGEST_LEN+1];
    877 
    878  if (should_delay_dir_fetches(options, NULL))
    879    return;
    880 
    881  pending_cert = fp_pair_map_new();
    882  pending_id = digestmap_new();
    883  missing_cert_digests = smartlist_new();
    884  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  list_pending_downloads(pending_id, NULL,
    891                         DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
    892  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  SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
    899                          dir_server_t *, ds) {
    900    int found = 0;
    901    if (!(ds->type & V3_DIRINFO))
    902      continue;
    903    if (smartlist_contains_digest(missing_id_digests,
    904                                  ds->v3_identity_digest))
    905      continue;
    906    cl = get_cert_list(ds->v3_identity_digest);
    907    SMARTLIST_FOREACH_BEGIN(cl->certs, authority_cert_t *, cert) {
    908      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        download_status_reset(&(cl->dl_status_by_id));
    912        /* No sense trying to download it specifically by signing key hash */
    913        download_status_reset_by_sk_in_cl(cl, cert->signing_key_digest);
    914        found = 1;
    915        break;
    916      }
    917    } SMARTLIST_FOREACH_END(cert);
    918    if (!found &&
    919        download_status_is_ready(&(cl->dl_status_by_id), now) &&
    920        !digestmap_get(pending_id, ds->v3_identity_digest)) {
    921      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      smartlist_add(missing_id_digests, ds->v3_identity_digest);
    926    }
    927  } 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  if (status) {
    940    SMARTLIST_FOREACH_BEGIN(status->voters, networkstatus_voter_info_t *,
    941                            voter) {
    942      if (!smartlist_len(voter->sigs))
    943        continue; /* This authority never signed this consensus, so don't
    944                   * go looking for a cert with key digest 0000000000. */
    945      if (!keep_unknown &&
    946          !trusteddirserver_get_by_v3_auth_digest(voter->identity_digest))
    947        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      cl = get_cert_list(voter->identity_digest);
    956      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        if (digestmap_get(pending_id, voter->identity_digest))
    961          continue;
    962 
    963        /*
    964         * Are we about to launch a download of one due to the trusted
    965         * dir server check above?
    966         */
    967        if (smartlist_contains_digest(missing_id_digests,
    968                                      voter->identity_digest))
    969          continue;
    970      }
    971 
    972      SMARTLIST_FOREACH_BEGIN(voter->sigs, document_signature_t *, sig) {
    973        authority_cert_t *cert =
    974          authority_cert_get_by_digests(voter->identity_digest,
    975                                        sig->signing_key_digest);
    976        if (cert) {
    977          if (now < cert->expires)
    978            download_status_reset_by_sk_in_cl(cl, sig->signing_key_digest);
    979          continue;
    980        }
    981        if (download_status_is_ready_by_sk_in_cl(
    982              cl, sig->signing_key_digest, now) &&
    983            !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          base16_encode(id_digest_str, sizeof(id_digest_str),
    991                        voter->identity_digest, DIGEST_LEN);
    992          base16_encode(sk_digest_str, sizeof(sk_digest_str),
    993                        sig->signing_key_digest, DIGEST_LEN);
    994 
    995          if (voter->nickname) {
    996            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            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          fp_tmp = tor_malloc(sizeof(*fp_tmp));
   1010          memcpy(fp_tmp->first, voter->identity_digest, sizeof(fp_tmp->first));
   1011          memcpy(fp_tmp->second, sig->signing_key_digest,
   1012                 sizeof(fp_tmp->second));
   1013          smartlist_add(missing_cert_digests, fp_tmp);
   1014        }
   1015      } SMARTLIST_FOREACH_END(sig);
   1016    } SMARTLIST_FOREACH_END(voter);
   1017  }
   1018 
   1019  /* Bridge clients look up the node for the dir_hint */
   1020  const node_t *node = NULL;
   1021  /* All clients, including bridge clients, look up the routerstatus for the
   1022   * dir_hint */
   1023  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  if (dir_hint) {
   1032    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      node = node_get_by_id(dir_hint);
   1037    }
   1038 
   1039    /* All clients try the consensus routerstatus, then the fallback
   1040     * routerstatus */
   1041    rs = router_get_consensus_status_by_id(dir_hint);
   1042    if (!rs) {
   1043      /* This will also find authorities */
   1044      const dir_server_t *ds = router_get_fallback_dirserver_by_digest(
   1045                                                                    dir_hint);
   1046      if (ds) {
   1047        rs = &ds->fake_status;
   1048      }
   1049    }
   1050 
   1051    if (!node && !rs) {
   1052      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  if (smartlist_len(missing_id_digests) > 0) {
   1061    int need_plus = 0;
   1062    smartlist_t *fps = smartlist_new();
   1063 
   1064    smartlist_add_strdup(fps, "fp/");
   1065 
   1066    SMARTLIST_FOREACH_BEGIN(missing_id_digests, const char *, d) {
   1067      char *fp = NULL;
   1068 
   1069      if (digestmap_get(pending_id, d))
   1070        continue;
   1071 
   1072      base16_encode(id_digest_str, sizeof(id_digest_str),
   1073                    d, DIGEST_LEN);
   1074 
   1075      if (need_plus) {
   1076        tor_asprintf(&fp, "+%s", id_digest_str);
   1077      } else {
   1078        /* No need for tor_asprintf() in this case; first one gets no '+' */
   1079        fp = tor_strdup(id_digest_str);
   1080        need_plus = 1;
   1081      }
   1082 
   1083      smartlist_add(fps, fp);
   1084    } SMARTLIST_FOREACH_END(d);
   1085 
   1086    if (smartlist_len(fps) > 1) {
   1087      resource = smartlist_join_strings(fps, "", 0, NULL);
   1088      /* node and rs are directories that just gave us a consensus or
   1089       * certificates */
   1090      authority_certs_fetch_resource_impl(resource, dir_hint, node, rs);
   1091      tor_free(resource);
   1092    }
   1093    /* else we didn't add any: they were all pending */
   1094 
   1095    SMARTLIST_FOREACH(fps, char *, cp, tor_free(cp));
   1096    smartlist_free(fps);
   1097  }
   1098 
   1099  /* Do downloads by identity digest/signing key pair */
   1100  if (smartlist_len(missing_cert_digests) > 0) {
   1101    int need_plus = 0;
   1102    smartlist_t *fp_pairs = smartlist_new();
   1103 
   1104    smartlist_add_strdup(fp_pairs, "fp-sk/");
   1105 
   1106    SMARTLIST_FOREACH_BEGIN(missing_cert_digests, const fp_pair_t *, d) {
   1107      char *fp_pair = NULL;
   1108 
   1109      if (fp_pair_map_get(pending_cert, d))
   1110        continue;
   1111 
   1112      /* Construct string encodings of the digests */
   1113      base16_encode(id_digest_str, sizeof(id_digest_str),
   1114                    d->first, DIGEST_LEN);
   1115      base16_encode(sk_digest_str, sizeof(sk_digest_str),
   1116                    d->second, DIGEST_LEN);
   1117 
   1118      /* Now tor_asprintf() */
   1119      if (need_plus) {
   1120        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        tor_asprintf(&fp_pair, "%s-%s", id_digest_str, sk_digest_str);
   1124        need_plus = 1;
   1125      }
   1126 
   1127      /* Add it to the list of pairs to request */
   1128      smartlist_add(fp_pairs, fp_pair);
   1129    } SMARTLIST_FOREACH_END(d);
   1130 
   1131    if (smartlist_len(fp_pairs) > 1) {
   1132      resource = smartlist_join_strings(fp_pairs, "", 0, NULL);
   1133      /* node and rs are directories that just gave us a consensus or
   1134       * certificates */
   1135      authority_certs_fetch_resource_impl(resource, dir_hint, node, rs);
   1136      tor_free(resource);
   1137    }
   1138    /* else they were all pending */
   1139 
   1140    SMARTLIST_FOREACH(fp_pairs, char *, p, tor_free(p));
   1141    smartlist_free(fp_pairs);
   1142  }
   1143 
   1144  smartlist_free(missing_id_digests);
   1145  SMARTLIST_FOREACH(missing_cert_digests, fp_pair_t *, p, tor_free(p));
   1146  smartlist_free(missing_cert_digests);
   1147  digestmap_free(pending_id, NULL);
   1148  fp_pair_map_free(pending_cert, NULL);
   1149 }
   1150 
   1151 void
   1152 authcert_free_all(void)
   1153 {
   1154  if (trusted_dir_certs) {
   1155    digestmap_free(trusted_dir_certs, cert_list_free_void);
   1156    trusted_dir_certs = NULL;
   1157  }
   1158 }
   1159 
   1160 /** Free storage held in <b>cert</b>. */
   1161 void
   1162 authority_cert_free_(authority_cert_t *cert)
   1163 {
   1164  if (!cert)
   1165    return;
   1166 
   1167  tor_free(cert->cache_info.signed_descriptor_body);
   1168  crypto_pk_free(cert->signing_key);
   1169  crypto_pk_free(cert->identity_key);
   1170 
   1171  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 list_pending_fpsk_downloads(fp_pair_map_t *result)
   1179 {
   1180  const char *pfx = "fp-sk/";
   1181  smartlist_t *tmp;
   1182  smartlist_t *conns;
   1183  const char *resource;
   1184 
   1185  tor_assert(result);
   1186 
   1187  tmp = smartlist_new();
   1188  conns = get_connection_array();
   1189 
   1190  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
   1191    if (conn->type == CONN_TYPE_DIR &&
   1192        conn->purpose == DIR_PURPOSE_FETCH_CERTIFICATE &&
   1193        !conn->marked_for_close) {
   1194      resource = TO_DIR_CONN(conn)->requested_resource;
   1195      if (!strcmpstart(resource, pfx))
   1196        dir_split_resource_into_fingerprint_pairs(resource + strlen(pfx),
   1197                                                  tmp);
   1198    }
   1199  } SMARTLIST_FOREACH_END(conn);
   1200 
   1201  SMARTLIST_FOREACH_BEGIN(tmp, fp_pair_t *, fp) {
   1202    fp_pair_map_set(result, fp, (void*)1);
   1203    tor_free(fp);
   1204  } SMARTLIST_FOREACH_END(fp);
   1205 
   1206  smartlist_free(tmp);
   1207 }