50#define DSMAP_FOREACH(map, keyvar, valvar) \
51 DIGESTMAP_FOREACH(dsmap_to_digestmap(map), keyvar, download_status_t *, \
53#define dsmap_free(map, fn) MAP_FREE_AND_NULL(dsmap, (map), (fn))
74 struct digest_ds_map_t *dl_status_map;
95 dlstatus->
schedule = DL_SCHED_CONSENSUS;
115 if (!(cl->dl_status_map)) {
116 cl->dl_status_map = dsmap_new();
119 dlstatus = dsmap_get(cl->dl_status_map, digest);
123 dlstatus = tor_malloc_zero(
sizeof(*dlstatus));
124 dsmap_set(cl->dl_status_map, digest, dlstatus);
148 if (!(cl->dl_status_map)) {
149 cl->dl_status_map = dsmap_new();
152 dlstatus = dsmap_get(cl->dl_status_map, digest);
163 dlstatus = tor_malloc_zero(
sizeof(*dlstatus));
165 dsmap_set(cl->dl_status_map, digest, dlstatus);
185 cl->dl_status_map = dsmap_new();
206 !(digestmap_iter_done(i));
212 digestmap_iter_get(i, &digest, &cl);
235 dl = &(cl->dl_status_by_id);
252 const char *sk_digest;
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)) {
265 dsmap_iter_get(i, &sk_digest, &dl);
282 const char *sk_digest))
289 if (cl && cl->dl_status_map) {
290 dl = dsmap_get(cl->dl_status_map, sk_digest);
297#define cert_list_free(val) \
298 FREE_AND_NULL(cert_list_t, cert_list_free_, (val))
308 authority_cert_free(cert));
309 smartlist_free(cl->certs);
310 dsmap_free(cl->dl_status_map,
tor_free_);
330 filename = get_cachedir_fname(
"cached-certs");
337 TRUSTED_DIRS_CERTS_SRC_FROM_STORE, 1, NULL);
351 if (tor_memeq(c->cache_info.signed_descriptor_digest,
352 cert->cache_info.signed_descriptor_digest,
374 int flush,
const char *source_dir)
378 int failure_code = 0;
379 int from_store = (source == TRUSTED_DIRS_CERTS_SRC_FROM_STORE);
380 int added_trusted_cert = 0;
382 for (s = contents; *s; s = eos) {
392 log_debug(
LD_DIR,
"Parsed certificate for %s",
393 ds ? ds->nickname :
"unknown authority");
397 log_info(
LD_DIR,
"Skipping %s certificate for %s that we "
399 from_store ?
"cached" :
"downloaded",
400 ds ? ds->nickname :
"an old or new authority");
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");
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");
427 if (source == TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST) {
430 }
else if (source == TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST) {
436 authority_cert_free(cert);
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",
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",
453 authority_cert_free(cert);
466 log_notice(
LD_DIR,
"Updating address for directory authority %s "
467 "from %s:%"PRIu16
" to %s:%"PRIu16
" based on certificate.",
488 if (failure_code == 0 && added_trusted_cert) {
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);
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.");
524 smartlist_free(chunks);
530compare_certs_by_pubdates(
const void **_a,
const void **_b)
550 time_t now = time(NULL);
551#define DEAD_CERT_LIFETIME (2*24*60*60)
552#define SUPERSEDED_CERT_LIFETIME (2*24*60*60)
561 if (cert_sl_idx == smartlist_len(cl->certs) - 1) {
567 if (next_cert_published > now) {
572 int should_remove = 0;
573 if (cert->expires + DEAD_CERT_LIFETIME < now) {
577 }
else if (next_cert_published + SUPERSEDED_CERT_LIFETIME < now) {
585 authority_cert_free(cert);
588 } SMARTLIST_FOREACH_END(cert);
591#undef DEAD_CERT_LIFETIME
592#undef OLD_CERT_LIFETIME
611 if (!best || cert->cache_info.published_on > best->cache_info.published_on)
637 if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
649 const char *sk_digest)
682 const char *signing_key_digest,
int status)
697 if (!signing_key_digest) {
705 dlstatus = dsmap_get(cl->dl_status_map, signing_key_digest);
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);
726static const char *BAD_SIGNING_KEYS[] = {
727 "09CD84F751FD6E955E0F8ADB497D5401470D697E",
728 "0E7E9C07F0969D0468AD741E172A6109DC289F3C",
729 "57B85409891D3FB32137F642FDEDF8B7F8CDFDCD",
730 "87326329007AF781F587AF5B594E540B2B6C7630",
731 "98CC82342DE8D298CF99D3F1A396475901E0D38E",
732 "9904B52336713A5ADCB13E4FB14DC919E0D45571",
733 "9DCD8E3F1DD1597E2AD476BBA28A1A89F3095227",
734 "A61682F34B9BB9694AC98491FE1ABBFE61923941",
735 "B59F6E99C575113650C99F1C425BA7B20A8C071D",
736 "D27178388FA75B96D37FA36E0B015227DDDBDA51",
751 for (i = 0; BAD_SIGNING_KEYS[i]; ++i) {
752 if (!strcasecmp(hex_digest, BAD_SIGNING_KEYS[i])) {
765#define N_AUTH_CERT_DL_FAILURES_TO_BUG_USER 2
773 return n_failures >= N_AUTH_CERT_DL_FAILURES_TO_BUG_USER;
781authority_certs_fetch_resource_impl(
const char *resource,
782 const char *dir_hint,
807 if (options->
UseBridges && node && node->ri && !get_via_tor) {
831 directory_request_free(req);
839 DL_WANT_ANY_DIRSERVER);
854 const char *dir_hint)
861 digestmap_t *pending_id;
869 smartlist_t *missing_cert_digests, *missing_id_digests;
870 char *resource = NULL;
882 pending_id = digestmap_new();
904 ds->v3_identity_digest))
908 if (now < cert->expires) {
917 } SMARTLIST_FOREACH_END(cert);
920 !digestmap_get(pending_id, ds->v3_identity_digest)) {
922 "No current certificate known for authority %s "
923 "(ID digest %s); launching request.",
927 } SMARTLIST_FOREACH_END(ds);
942 if (!smartlist_len(voter->sigs))
956 if (smartlist_len(cl->certs) == 0) {
960 if (digestmap_get(pending_id, voter->identity_digest))
968 voter->identity_digest))
975 sig->signing_key_digest);
977 if (now < cert->expires)
982 cl, sig->signing_key_digest, now) &&
984 voter->identity_digest,
985 sig->signing_key_digest)) {
995 if (voter->nickname) {
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);
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);
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));
1015 } SMARTLIST_FOREACH_END(sig);
1016 } SMARTLIST_FOREACH_END(voter);
1020 const node_t *node = NULL;
1052 log_warn(
LD_BUG,
"Directory %s delivered a consensus, but %s"
1053 "no routerstatus could be found for it.",
1060 if (smartlist_len(missing_id_digests) > 0) {
1069 if (digestmap_get(pending_id, d))
1079 fp = tor_strdup(id_digest_str);
1084 } SMARTLIST_FOREACH_END(d);
1086 if (smartlist_len(fps) > 1) {
1090 authority_certs_fetch_resource_impl(resource, dir_hint, node, rs);
1096 smartlist_free(fps);
1100 if (smartlist_len(missing_cert_digests) > 0) {
1107 char *fp_pair = NULL;
1120 tor_asprintf(&fp_pair,
"+%s-%s", id_digest_str, sk_digest_str);
1123 tor_asprintf(&fp_pair,
"%s-%s", id_digest_str, sk_digest_str);
1129 } SMARTLIST_FOREACH_END(d);
1131 if (smartlist_len(fp_pairs) > 1) {
1135 authority_certs_fetch_resource_impl(resource, dir_hint, node, rs);
1141 smartlist_free(fp_pairs);
1144 smartlist_free(missing_id_digests);
1146 smartlist_free(missing_cert_digests);
1147 digestmap_free(pending_id, NULL);
1148 fp_pair_map_free(pending_cert, NULL);
1152authcert_free_all(
void)
1180 const char *pfx =
"fp-sk/";
1183 const char *resource;
1193 !conn->marked_for_close) {
1199 } SMARTLIST_FOREACH_END(conn);
1204 } SMARTLIST_FOREACH_END(fp);
1206 smartlist_free(tmp);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
int tor_addr_is_null(const tor_addr_t *addr)
#define tor_addr_eq(a, b)
static int already_have_cert(authority_cert_t *cert)
void authority_cert_dl_failed(const char *id_digest, const char *signing_key_digest, int status)
int trusted_dirs_load_certs_from_string(const char *contents, int source, int flush, const char *source_dir)
smartlist_t * list_authority_ids_with_downloads(void)
void trusted_dirs_remove_old_certs(void)
static int trusted_dir_servers_certs_changed
static void list_pending_fpsk_downloads(fp_pair_map_t *result)
static digestmap_t * trusted_dir_certs
void authority_cert_get_all(smartlist_t *certs_out)
static void download_status_cert_init(download_status_t *dlstatus)
static int download_status_is_ready_by_sk_in_cl(cert_list_t *cl, const char *digest, time_t now)
static void download_status_reset_by_sk_in_cl(cert_list_t *cl, const char *digest)
int trusted_dirs_reload_certs(void)
void authority_certs_fetch_missing(networkstatus_t *status, time_t now, const char *dir_hint)
static cert_list_t * get_cert_list(const char *id_digest)
authority_cert_t * authority_cert_get_newest_by_id(const char *id_digest)
download_status_t * download_status_for_authority_id_and_sk(const char *id_digest, const char *sk_digest)
static void cert_list_free_void(void *cl)
download_status_t * id_only_download_status_for_authority_id(const char *digest)
int authority_cert_is_denylisted(const authority_cert_t *cert)
void trusted_dirs_flush_certs_to_disk(void)
authority_cert_t * authority_cert_get_by_sk_digest(const char *sk_digest)
static void cert_list_free_(cert_list_t *cl)
smartlist_t * list_sk_digests_for_authority_id(const char *digest)
void authority_cert_free_(authority_cert_t *cert)
int authority_cert_dl_looks_uncertain(const char *id_digest)
authority_cert_t * authority_cert_get_by_digests(const char *id_digest, const char *sk_digest)
Header file for authcert.c.
authority_cert_t * authority_cert_parse_from_string(const char *s, size_t maxlen, const char **end_of_string)
Header file for authcert_parse.c.
int authdir_mode(const or_options_t *options)
Header file for directory authority mode.
Authority certificate structure.
const char * hex_str(const char *from, size_t fromlen)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
int node_is_a_configured_bridge(const node_t *node)
Header file for circuitbuild.c.
const or_options_t * get_options(void)
Header file for config.c.
Header file for connection.c.
Base connection structure.
int tor_memeq(const void *a, const void *b, size_t sz)
Client/server directory connection structure.
Trusted/fallback directory server structure.
void directory_request_set_resource(directory_request_t *req, const char *resource)
void directory_request_set_or_addr_port(directory_request_t *req, const tor_addr_port_t *p)
void directory_request_set_indirection(directory_request_t *req, dir_indirection_t indirection)
void directory_request_set_routerstatus(directory_request_t *req, const routerstatus_t *status)
void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, const char *resource, int pds_flags, download_want_authority_t want_authority)
void directory_request_set_directory_id_digest(directory_request_t *req, const char *digest)
void directory_initiate_request(directory_request_t *request)
directory_request_t * directory_request_new(uint8_t dir_purpose)
Header file for dirclient.c.
struct directory_request_t directory_request_t
int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose, const char *resource)
int dir_split_resource_into_fingerprint_pairs(const char *res, smartlist_t *pairs_out)
dir_connection_t * TO_DIR_CONN(connection_t *c)
Header file for directory.c.
#define DIR_PURPOSE_FETCH_CERTIFICATE
dir_server_t * trusteddirserver_get_by_v3_auth_digest(const char *digest)
dir_server_t * router_get_fallback_dirserver_by_digest(const char *digest)
Header file for dirlist.c.
int download_status_is_ready(download_status_t *dls, time_t now)
int download_status_get_n_failures(const download_status_t *dls)
void download_status_reset(download_status_t *dls)
Header file for dlstatus.c.
#define download_status_failed(dls, sc)
Authority signature structure.
#define RFTS_IGNORE_MISSING
void * fp_pair_map_get(const fp_pair_map_t *map, const fp_pair_t *key)
void * fp_pair_map_get_by_digests(const fp_pair_map_t *map, const char *first, const char *second)
void * fp_pair_map_set(fp_pair_map_t *map, const fp_pair_t *key, void *val)
fp_pair_map_t * fp_pair_map_new(void)
Header file for fp_pair.c.
smartlist_t * get_connection_array(void)
Header file for mainloop.c.
void tor_free_(void *mem)
#define DIGESTMAP_FOREACH_END
#define DIGESTMAP_FOREACH(map, keyvar, valtype, valvar)
void networkstatus_note_certs_arrived(const char *source_dir)
int should_delay_dir_fetches(const or_options_t *options, const char **msg_out)
const routerstatus_t * router_get_consensus_status_by_id(const char *digest)
int we_want_to_fetch_unknown_auth_certs(const or_options_t *options)
Header file for networkstatus.c.
Networkstatus consensus/vote structure.
Single consensus voter structure.
Header file for node_select.c.
#define PDS_RETRY_IF_NO_SERVERS
Node information structure.
const node_t * node_get_by_id(const char *identity_digest)
Header file for nodelist.c.
Master header file for Tor-specific functionality.
void reachable_addr_choose_from_node(const node_t *node, firewall_connection_t fw_connection, int pref_only, tor_addr_port_t *ap)
Header file for policies.c.
int tor_asprintf(char **strp, const char *fmt,...)
authority_cert_t * get_my_v3_authority_cert(void)
authority_cert_t * get_my_v3_legacy_cert(void)
void list_pending_downloads(digestmap_t *result, digest256map_t *result256, int purpose, const char *prefix)
Header file for routerlist.c.
Header file for routermode.c.
int smartlist_contains_digest(const smartlist_t *sl, const char *element)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
void smartlist_add_strdup(struct smartlist_t *sl, const char *string)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define SMARTLIST_DEL_CURRENT_KEEPORDER(sl, var)
crypto_pk_t * identity_key
crypto_pk_t * signing_key
char signing_key_digest[DIGEST_LEN]
signed_descriptor_t cache_info
char * requested_resource
routerstatus_t fake_status
download_want_authority_bitfield_t want_authority
download_schedule_increment_bitfield_t increment_on
uint8_t last_backoff_position
download_schedule_bitfield_t schedule
char identity_digest[DIGEST_LEN]
char * signed_descriptor_body
#define MOCK_IMPL(rv, funcname, arglist)
int strcmpstart(const char *s1, const char *s2)