Loading ChangeLog +4 −0 Original line number Diff line number Diff line Changes in version 0.2.0.19-alpha - 2008-0?-?? o Minor bugfixes: - Directory caches now fetch certificates from all authorities listed in a networkstatus consensus, even when they do not recognize them. Fixes bug 571. Bugfix on 0.2.0.x. Changes in version 0.2.0.18-alpha - 2008-01-25 Loading src/or/directory.c +2 −11 Original line number Diff line number Diff line Loading @@ -601,9 +601,7 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) failed, NULL, 1, 0); SMARTLIST_FOREACH(failed, char *, cp, { trusted_dir_server_t *dir = trusteddirserver_get_by_v3_auth_digest(cp); if (dir) download_status_failed(&dir->cert_dl_status, status); authority_cert_dl_failed(cp, status); tor_free(cp); }); smartlist_free(failed); Loading Loading @@ -2494,14 +2492,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, smartlist_t *certs = smartlist_create(); ssize_t len = -1; if (!strcmp(url, "/tor/keys/all")) { SMARTLIST_FOREACH(router_get_trusted_dir_servers(), trusted_dir_server_t *, ds, { if (!ds->v3_certs) continue; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, smartlist_add(certs, cert)); }); authority_cert_get_all(certs); } else if (!strcmp(url, "/tor/keys/authority")) { authority_cert_t *cert = get_my_v3_authority_cert(); if (cert) Loading src/or/or.h +8 −0 Original line number Diff line number Diff line Loading @@ -3030,6 +3030,10 @@ int dir_split_resource_into_fingerprints(const char *resource, char *directory_dump_request_log(void); int router_supports_extrainfo(const char *identity_digest, int is_authority); void directory_post_to_hs_dir(smartlist_t *descs, const char *service_id, int seconds_valid); int directory_get_from_hs_dir(const char *desc_id, const char *query); time_t download_status_increment_failure(download_status_t *dls, int status_code, const char *item, int server, time_t now); Loading Loading @@ -3813,9 +3817,11 @@ typedef struct trusted_dir_server_t { /** What kind of authority is this? (Bitfield.) */ authority_type_t type; #if 0 smartlist_t *v3_certs; /**< V3 key certificates for this authority */ download_status_t cert_dl_status; /**< Status of downloading this server's * latest certificate. */ #endif download_status_t v2_ns_dl_status; /**< Status of downloading this server's * v2 network status. */ time_t addr_current_at; /**< When was the document that we derived the Loading @@ -3840,6 +3846,8 @@ authority_cert_t *authority_cert_get_newest_by_id(const char *id_digest); authority_cert_t *authority_cert_get_by_sk_digest(const char *sk_digest); authority_cert_t *authority_cert_get_by_digests(const char *id_digest, const char *sk_digest); void authority_cert_get_all(smartlist_t *certs_out); void authority_cert_dl_failed(const char *id_digest, int status); void authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now); int router_reload_router_list(void); smartlist_t *router_get_trusted_dir_servers(void); Loading src/or/routerlist.c +114 −67 Original line number Diff line number Diff line Loading @@ -47,8 +47,16 @@ DECLARE_TYPED_DIGESTMAP_FNS(eimap_, digest_ei_map_t, extrainfo_t) /** Global list of a trusted_dir_server_t object for each trusted directory * server. */ static smartlist_t *trusted_dir_servers = NULL; /** True iff the key certificate in at least one member of * <b>trusted_dir_server_t</b> has changed since we last flushed the /** DOCDOC */ typedef struct cert_list_t { download_status_t dl_status; smartlist_t *certs; } cert_list_t; /** Map from v3 identity key digest to cert_list_t. */ static digestmap_t *trusted_dir_certs = NULL; /** True iff any key certificate in at least one member of * <b>trusted_dir_certs</b> has changed since we last flushed the * certificates to disk. */ static int trusted_dir_servers_certs_changed = 0; Loading Loading @@ -80,6 +88,22 @@ get_n_authorities(authority_type_t type) #define get_n_v2_authorities() get_n_authorities(V2_AUTHORITY) /** DOCDOC */ static cert_list_t * get_cert_list(const char *id_digest) { cert_list_t *cl; if (!trusted_dir_certs) trusted_dir_certs = digestmap_new(); cl = digestmap_get(trusted_dir_certs, id_digest); if (!cl) { cl = tor_malloc_zero(sizeof(cert_list_t)); cl->certs = smartlist_create(); digestmap_set(trusted_dir_certs, id_digest, cl); } return cl; } /** Reload the cached v3 key certificates from the cached-certs file in * the data directory. Return 0 on success, -1 on failure. */ int Loading Loading @@ -108,6 +132,7 @@ int trusted_dirs_load_certs_from_string(const char *contents, int from_store) { trusted_dir_server_t *ds; cert_list_t *cl; const char *s, *eos; for (s = contents; *s; s = eos) { Loading @@ -117,17 +142,20 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store) break; ds = trusteddirserver_get_by_v3_auth_digest( cert->cache_info.identity_digest); if (!ds) { #if 0 if (drop_unknown && !ds) { log_info(LD_DIR, "Found %s certificate whose key didn't match " "any v3 authority we recognized; skipping.", from_store ? "cached" : "downloaded"); authority_cert_free(cert); continue; } if (!ds->v3_certs) ds->v3_certs = smartlist_create(); } #endif cl = get_cert_list(cert->cache_info.identity_digest); SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c, { if (!memcmp(c->cache_info.signed_descriptor_digest, cert->cache_info.signed_descriptor_digest, Loading @@ -145,12 +173,19 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store) if (found) continue; if (ds) { log_info(LD_DIR, "Adding %s certificate for directory authority %s with " "signing key %s", from_store ? "cached" : "downloaded", ds->nickname, hex_str(cert->signing_key_digest,DIGEST_LEN)); } else { log_info(LD_DIR, "Adding %s certificate for unrecognized directory " "authority with signing key %s", from_store ? "cached" : "downloaded", hex_str(cert->signing_key_digest,DIGEST_LEN)); } smartlist_add(ds->v3_certs, cert); if (cert->cache_info.published_on > ds->addr_current_at) { smartlist_add(cl->certs, cert); if (ds && cert->cache_info.published_on > ds->addr_current_at) { /* Check to see whether we should update our view of the authority's * address. */ if (cert->addr && cert->dir_port && Loading Loading @@ -185,23 +220,20 @@ trusted_dirs_flush_certs_to_disk(void) char *filename; smartlist_t *chunks; if (!trusted_dir_servers_certs_changed) if (!trusted_dir_servers_certs_changed || !trusted_dir_certs) return; chunks = smartlist_create(); SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { if (ds->v3_certs) { SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t)); c->bytes = cert->cache_info.signed_descriptor_body; c->len = cert->cache_info.signed_descriptor_len; smartlist_add(chunks, c); }); } }); } DIGESTMAP_FOREACH_END filename = get_datadir_fname("cached-certs"); if (write_chunks_to_file(filename, chunks, 0)) { log_warn(LD_FS, "Error writing certificates to disk."); Loading @@ -221,23 +253,23 @@ static void trusted_dirs_remove_old_certs(void) { #define OLD_CERT_LIFETIME (48*60*60) SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { if (!trusted_dir_certs) return; DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { authority_cert_t *newest = NULL; if (!ds->v3_certs) continue; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, if (!newest || (cert->cache_info.published_on > newest->cache_info.published_on)) newest = cert); SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, if (newest && (newest->cache_info.published_on > cert->cache_info.published_on + OLD_CERT_LIFETIME)) { SMARTLIST_DEL_CURRENT(ds->v3_certs, cert); SMARTLIST_DEL_CURRENT(cl->certs, cert); authority_cert_free(cert); trusted_dir_servers_certs_changed = 1; }); }); } DIGESTMAP_FOREACH_END #undef OLD_CERT_LIFETIME trusted_dirs_flush_certs_to_disk(); Loading @@ -249,11 +281,11 @@ trusted_dirs_remove_old_certs(void) authority_cert_t * authority_cert_get_newest_by_id(const char *id_digest) { trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest); cert_list_t *cl; authority_cert_t *best = NULL; if (!ds || !ds->v3_certs) if (!trusted_dir_certs || !(cl = digestmap_get(trusted_dir_certs, id_digest))) return NULL; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { if (!best || cert->cache_info.published_on > best->cache_info.published_on) best = cert; Loading @@ -267,18 +299,16 @@ authority_cert_get_newest_by_id(const char *id_digest) authority_cert_t * authority_cert_get_by_sk_digest(const char *sk_digest) { if (!trusted_dir_servers) if (!trusted_dir_certs) return NULL; SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { if (!ds->v3_certs) continue; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN)) return cert; }); }); } DIGESTMAP_FOREACH_END return NULL; } Loading @@ -289,17 +319,40 @@ authority_cert_t * authority_cert_get_by_digests(const char *id_digest, const char *sk_digest) { trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest); if (!ds || !ds->v3_certs) cert_list_t *cl; if (!trusted_dir_certs || !(cl = digestmap_get(trusted_dir_certs, id_digest))) return NULL; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN)) return cert; ); return NULL; } /** DOCDOC */ void authority_cert_get_all(smartlist_t *certs_out) { if (!trusted_dir_certs) return; DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c, smartlist_add(certs_out, c)); } DIGESTMAP_FOREACH_END } /** DOCDOC */ void authority_cert_dl_failed(const char *id_digest, int status) { cert_list_t *cl; if (!trusted_dir_certs || !(cl = digestmap_get(trusted_dir_certs, id_digest))) return; download_status_failed(&cl->dl_status, status); } /** How many times will we try to fetch a certificate before giving up? */ #define MAX_CERT_DL_FAILURES 8 Loading @@ -315,6 +368,8 @@ authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now) digestmap_t *pending; smartlist_t *missing_digests; char *resource = NULL; cert_list_t *cl; const int cache = directory_caches_dir_info(get_options()); if (should_delay_dir_fetches(get_options())) return; Loading @@ -326,24 +381,22 @@ authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now) if (status) { SMARTLIST_FOREACH(status->voters, networkstatus_voter_info_t *, voter, { trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest); if (!ds) /* XXXX020 This is wrong!! If we're a cache, we should * download unrecognized signing keys so we can serve * them. */ continue; if (tor_digest_is_zero(voter->signing_key_digest)) continue; /* This authority never signed this consensus, so don't * go looking for a cert with key digest 0000000000. */ if (!cache && !trusteddirserver_get_by_v3_auth_digest(voter->identity_digest)) continue; /* We are not a cache, and we don't know this authority.*/ cl = get_cert_list(voter->identity_digest); if (authority_cert_get_by_digests(voter->identity_digest, voter->signing_key_digest)) { download_status_reset(&ds->cert_dl_status); download_status_reset(&cl->dl_status); continue; } if (download_status_is_ready(&ds->cert_dl_status, now, if (download_status_is_ready(&cl->dl_status, now, MAX_CERT_DL_FAILURES)) { log_notice(LD_DIR, "We're missing a certificate from authority %s " "with signing key %s: launching request.", ds->nickname, log_notice(LD_DIR, "We're missing a certificate from authority " "with signing key %s: launching request.", hex_str(voter->signing_key_digest, DIGEST_LEN)); smartlist_add(missing_digests, voter->identity_digest); } Loading @@ -356,19 +409,18 @@ authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now) continue; if (smartlist_digest_isin(missing_digests, ds->v3_identity_digest)) continue; if (!ds->v3_certs) ds->v3_certs = smartlist_create(); SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, cl = get_cert_list(ds->v3_identity_digest); SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { if (!ftime_definitely_after(now, cert->expires)) { /* It's not expired, and we weren't looking for something to * verify a consensus with. Call it done. */ download_status_reset(&ds->cert_dl_status); download_status_reset(&cl->dl_status); found = 1; break; } }); if (!found && download_status_is_ready(&ds->cert_dl_status, now, if (!found && download_status_is_ready(&cl->dl_status, now, MAX_CERT_DL_FAILURES)) { log_notice(LD_DIR, "No current certificate known for authority %s; " "launching request.", ds->nickname); Loading Loading @@ -3403,11 +3455,6 @@ authority_cert_free(authority_cert_t *cert) static void trusted_dir_server_free(trusted_dir_server_t *ds) { if (ds->v3_certs) { SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, authority_cert_free(cert)); smartlist_free(ds->v3_certs); } tor_free(ds->nickname); tor_free(ds->description); tor_free(ds->address); Loading src/or/routerparse.c +13 −17 Original line number Diff line number Diff line Loading @@ -1433,14 +1433,13 @@ extrainfo_parse_entry_from_string(const char *s, const char *end, authority_cert_t * authority_cert_parse_from_string(const char *s, const char **end_of_string) { authority_cert_t *cert = NULL; authority_cert_t *cert = NULL, *old_cert; smartlist_t *tokens = NULL; char digest[DIGEST_LEN]; directory_token_t *tok; char fp_declared[DIGEST_LEN]; char *eos; size_t len; trusted_dir_server_t *ds; int found; s = eat_whitespace(s); Loading Loading @@ -1531,22 +1530,19 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string) } /* If we already have this cert, don't bother checking the signature. */ ds = trusteddirserver_get_by_v3_auth_digest( cert->cache_info.identity_digest); old_cert = authority_cert_get_by_digests( cert->cache_info.identity_digest, cert->signing_key_digest); found = 0; if (ds && ds->v3_certs) { SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c, { if (old_cert) { /* XXXX020 can we just compare signed_descriptor_digest ? */ if (c->cache_info.signed_descriptor_len == len && c->cache_info.signed_descriptor_body && !memcmp(s, c->cache_info.signed_descriptor_body, len)) { if (old_cert->cache_info.signed_descriptor_len == len && old_cert->cache_info.signed_descriptor_body && !memcmp(s, old_cert->cache_info.signed_descriptor_body, len)) { log_debug(LD_DIR, "We already checked the signature on this " "certificate; no need to do so again."); found = 1; break; } }); } if (!found) { if (check_signature_token(digest, tok, cert->identity_key, 0, Loading Loading
ChangeLog +4 −0 Original line number Diff line number Diff line Changes in version 0.2.0.19-alpha - 2008-0?-?? o Minor bugfixes: - Directory caches now fetch certificates from all authorities listed in a networkstatus consensus, even when they do not recognize them. Fixes bug 571. Bugfix on 0.2.0.x. Changes in version 0.2.0.18-alpha - 2008-01-25 Loading
src/or/directory.c +2 −11 Original line number Diff line number Diff line Loading @@ -601,9 +601,7 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) failed, NULL, 1, 0); SMARTLIST_FOREACH(failed, char *, cp, { trusted_dir_server_t *dir = trusteddirserver_get_by_v3_auth_digest(cp); if (dir) download_status_failed(&dir->cert_dl_status, status); authority_cert_dl_failed(cp, status); tor_free(cp); }); smartlist_free(failed); Loading Loading @@ -2494,14 +2492,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, smartlist_t *certs = smartlist_create(); ssize_t len = -1; if (!strcmp(url, "/tor/keys/all")) { SMARTLIST_FOREACH(router_get_trusted_dir_servers(), trusted_dir_server_t *, ds, { if (!ds->v3_certs) continue; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, smartlist_add(certs, cert)); }); authority_cert_get_all(certs); } else if (!strcmp(url, "/tor/keys/authority")) { authority_cert_t *cert = get_my_v3_authority_cert(); if (cert) Loading
src/or/or.h +8 −0 Original line number Diff line number Diff line Loading @@ -3030,6 +3030,10 @@ int dir_split_resource_into_fingerprints(const char *resource, char *directory_dump_request_log(void); int router_supports_extrainfo(const char *identity_digest, int is_authority); void directory_post_to_hs_dir(smartlist_t *descs, const char *service_id, int seconds_valid); int directory_get_from_hs_dir(const char *desc_id, const char *query); time_t download_status_increment_failure(download_status_t *dls, int status_code, const char *item, int server, time_t now); Loading Loading @@ -3813,9 +3817,11 @@ typedef struct trusted_dir_server_t { /** What kind of authority is this? (Bitfield.) */ authority_type_t type; #if 0 smartlist_t *v3_certs; /**< V3 key certificates for this authority */ download_status_t cert_dl_status; /**< Status of downloading this server's * latest certificate. */ #endif download_status_t v2_ns_dl_status; /**< Status of downloading this server's * v2 network status. */ time_t addr_current_at; /**< When was the document that we derived the Loading @@ -3840,6 +3846,8 @@ authority_cert_t *authority_cert_get_newest_by_id(const char *id_digest); authority_cert_t *authority_cert_get_by_sk_digest(const char *sk_digest); authority_cert_t *authority_cert_get_by_digests(const char *id_digest, const char *sk_digest); void authority_cert_get_all(smartlist_t *certs_out); void authority_cert_dl_failed(const char *id_digest, int status); void authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now); int router_reload_router_list(void); smartlist_t *router_get_trusted_dir_servers(void); Loading
src/or/routerlist.c +114 −67 Original line number Diff line number Diff line Loading @@ -47,8 +47,16 @@ DECLARE_TYPED_DIGESTMAP_FNS(eimap_, digest_ei_map_t, extrainfo_t) /** Global list of a trusted_dir_server_t object for each trusted directory * server. */ static smartlist_t *trusted_dir_servers = NULL; /** True iff the key certificate in at least one member of * <b>trusted_dir_server_t</b> has changed since we last flushed the /** DOCDOC */ typedef struct cert_list_t { download_status_t dl_status; smartlist_t *certs; } cert_list_t; /** Map from v3 identity key digest to cert_list_t. */ static digestmap_t *trusted_dir_certs = NULL; /** True iff any key certificate in at least one member of * <b>trusted_dir_certs</b> has changed since we last flushed the * certificates to disk. */ static int trusted_dir_servers_certs_changed = 0; Loading Loading @@ -80,6 +88,22 @@ get_n_authorities(authority_type_t type) #define get_n_v2_authorities() get_n_authorities(V2_AUTHORITY) /** DOCDOC */ static cert_list_t * get_cert_list(const char *id_digest) { cert_list_t *cl; if (!trusted_dir_certs) trusted_dir_certs = digestmap_new(); cl = digestmap_get(trusted_dir_certs, id_digest); if (!cl) { cl = tor_malloc_zero(sizeof(cert_list_t)); cl->certs = smartlist_create(); digestmap_set(trusted_dir_certs, id_digest, cl); } return cl; } /** Reload the cached v3 key certificates from the cached-certs file in * the data directory. Return 0 on success, -1 on failure. */ int Loading Loading @@ -108,6 +132,7 @@ int trusted_dirs_load_certs_from_string(const char *contents, int from_store) { trusted_dir_server_t *ds; cert_list_t *cl; const char *s, *eos; for (s = contents; *s; s = eos) { Loading @@ -117,17 +142,20 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store) break; ds = trusteddirserver_get_by_v3_auth_digest( cert->cache_info.identity_digest); if (!ds) { #if 0 if (drop_unknown && !ds) { log_info(LD_DIR, "Found %s certificate whose key didn't match " "any v3 authority we recognized; skipping.", from_store ? "cached" : "downloaded"); authority_cert_free(cert); continue; } if (!ds->v3_certs) ds->v3_certs = smartlist_create(); } #endif cl = get_cert_list(cert->cache_info.identity_digest); SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c, { if (!memcmp(c->cache_info.signed_descriptor_digest, cert->cache_info.signed_descriptor_digest, Loading @@ -145,12 +173,19 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store) if (found) continue; if (ds) { log_info(LD_DIR, "Adding %s certificate for directory authority %s with " "signing key %s", from_store ? "cached" : "downloaded", ds->nickname, hex_str(cert->signing_key_digest,DIGEST_LEN)); } else { log_info(LD_DIR, "Adding %s certificate for unrecognized directory " "authority with signing key %s", from_store ? "cached" : "downloaded", hex_str(cert->signing_key_digest,DIGEST_LEN)); } smartlist_add(ds->v3_certs, cert); if (cert->cache_info.published_on > ds->addr_current_at) { smartlist_add(cl->certs, cert); if (ds && cert->cache_info.published_on > ds->addr_current_at) { /* Check to see whether we should update our view of the authority's * address. */ if (cert->addr && cert->dir_port && Loading Loading @@ -185,23 +220,20 @@ trusted_dirs_flush_certs_to_disk(void) char *filename; smartlist_t *chunks; if (!trusted_dir_servers_certs_changed) if (!trusted_dir_servers_certs_changed || !trusted_dir_certs) return; chunks = smartlist_create(); SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { if (ds->v3_certs) { SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t)); c->bytes = cert->cache_info.signed_descriptor_body; c->len = cert->cache_info.signed_descriptor_len; smartlist_add(chunks, c); }); } }); } DIGESTMAP_FOREACH_END filename = get_datadir_fname("cached-certs"); if (write_chunks_to_file(filename, chunks, 0)) { log_warn(LD_FS, "Error writing certificates to disk."); Loading @@ -221,23 +253,23 @@ static void trusted_dirs_remove_old_certs(void) { #define OLD_CERT_LIFETIME (48*60*60) SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { if (!trusted_dir_certs) return; DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { authority_cert_t *newest = NULL; if (!ds->v3_certs) continue; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, if (!newest || (cert->cache_info.published_on > newest->cache_info.published_on)) newest = cert); SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, if (newest && (newest->cache_info.published_on > cert->cache_info.published_on + OLD_CERT_LIFETIME)) { SMARTLIST_DEL_CURRENT(ds->v3_certs, cert); SMARTLIST_DEL_CURRENT(cl->certs, cert); authority_cert_free(cert); trusted_dir_servers_certs_changed = 1; }); }); } DIGESTMAP_FOREACH_END #undef OLD_CERT_LIFETIME trusted_dirs_flush_certs_to_disk(); Loading @@ -249,11 +281,11 @@ trusted_dirs_remove_old_certs(void) authority_cert_t * authority_cert_get_newest_by_id(const char *id_digest) { trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest); cert_list_t *cl; authority_cert_t *best = NULL; if (!ds || !ds->v3_certs) if (!trusted_dir_certs || !(cl = digestmap_get(trusted_dir_certs, id_digest))) return NULL; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { if (!best || cert->cache_info.published_on > best->cache_info.published_on) best = cert; Loading @@ -267,18 +299,16 @@ authority_cert_get_newest_by_id(const char *id_digest) authority_cert_t * authority_cert_get_by_sk_digest(const char *sk_digest) { if (!trusted_dir_servers) if (!trusted_dir_certs) return NULL; SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { if (!ds->v3_certs) continue; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN)) return cert; }); }); } DIGESTMAP_FOREACH_END return NULL; } Loading @@ -289,17 +319,40 @@ authority_cert_t * authority_cert_get_by_digests(const char *id_digest, const char *sk_digest) { trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest); if (!ds || !ds->v3_certs) cert_list_t *cl; if (!trusted_dir_certs || !(cl = digestmap_get(trusted_dir_certs, id_digest))) return NULL; SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN)) return cert; ); return NULL; } /** DOCDOC */ void authority_cert_get_all(smartlist_t *certs_out) { if (!trusted_dir_certs) return; DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) { SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c, smartlist_add(certs_out, c)); } DIGESTMAP_FOREACH_END } /** DOCDOC */ void authority_cert_dl_failed(const char *id_digest, int status) { cert_list_t *cl; if (!trusted_dir_certs || !(cl = digestmap_get(trusted_dir_certs, id_digest))) return; download_status_failed(&cl->dl_status, status); } /** How many times will we try to fetch a certificate before giving up? */ #define MAX_CERT_DL_FAILURES 8 Loading @@ -315,6 +368,8 @@ authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now) digestmap_t *pending; smartlist_t *missing_digests; char *resource = NULL; cert_list_t *cl; const int cache = directory_caches_dir_info(get_options()); if (should_delay_dir_fetches(get_options())) return; Loading @@ -326,24 +381,22 @@ authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now) if (status) { SMARTLIST_FOREACH(status->voters, networkstatus_voter_info_t *, voter, { trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest); if (!ds) /* XXXX020 This is wrong!! If we're a cache, we should * download unrecognized signing keys so we can serve * them. */ continue; if (tor_digest_is_zero(voter->signing_key_digest)) continue; /* This authority never signed this consensus, so don't * go looking for a cert with key digest 0000000000. */ if (!cache && !trusteddirserver_get_by_v3_auth_digest(voter->identity_digest)) continue; /* We are not a cache, and we don't know this authority.*/ cl = get_cert_list(voter->identity_digest); if (authority_cert_get_by_digests(voter->identity_digest, voter->signing_key_digest)) { download_status_reset(&ds->cert_dl_status); download_status_reset(&cl->dl_status); continue; } if (download_status_is_ready(&ds->cert_dl_status, now, if (download_status_is_ready(&cl->dl_status, now, MAX_CERT_DL_FAILURES)) { log_notice(LD_DIR, "We're missing a certificate from authority %s " "with signing key %s: launching request.", ds->nickname, log_notice(LD_DIR, "We're missing a certificate from authority " "with signing key %s: launching request.", hex_str(voter->signing_key_digest, DIGEST_LEN)); smartlist_add(missing_digests, voter->identity_digest); } Loading @@ -356,19 +409,18 @@ authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now) continue; if (smartlist_digest_isin(missing_digests, ds->v3_identity_digest)) continue; if (!ds->v3_certs) ds->v3_certs = smartlist_create(); SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, cl = get_cert_list(ds->v3_identity_digest); SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, { if (!ftime_definitely_after(now, cert->expires)) { /* It's not expired, and we weren't looking for something to * verify a consensus with. Call it done. */ download_status_reset(&ds->cert_dl_status); download_status_reset(&cl->dl_status); found = 1; break; } }); if (!found && download_status_is_ready(&ds->cert_dl_status, now, if (!found && download_status_is_ready(&cl->dl_status, now, MAX_CERT_DL_FAILURES)) { log_notice(LD_DIR, "No current certificate known for authority %s; " "launching request.", ds->nickname); Loading Loading @@ -3403,11 +3455,6 @@ authority_cert_free(authority_cert_t *cert) static void trusted_dir_server_free(trusted_dir_server_t *ds) { if (ds->v3_certs) { SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert, authority_cert_free(cert)); smartlist_free(ds->v3_certs); } tor_free(ds->nickname); tor_free(ds->description); tor_free(ds->address); Loading
src/or/routerparse.c +13 −17 Original line number Diff line number Diff line Loading @@ -1433,14 +1433,13 @@ extrainfo_parse_entry_from_string(const char *s, const char *end, authority_cert_t * authority_cert_parse_from_string(const char *s, const char **end_of_string) { authority_cert_t *cert = NULL; authority_cert_t *cert = NULL, *old_cert; smartlist_t *tokens = NULL; char digest[DIGEST_LEN]; directory_token_t *tok; char fp_declared[DIGEST_LEN]; char *eos; size_t len; trusted_dir_server_t *ds; int found; s = eat_whitespace(s); Loading Loading @@ -1531,22 +1530,19 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string) } /* If we already have this cert, don't bother checking the signature. */ ds = trusteddirserver_get_by_v3_auth_digest( cert->cache_info.identity_digest); old_cert = authority_cert_get_by_digests( cert->cache_info.identity_digest, cert->signing_key_digest); found = 0; if (ds && ds->v3_certs) { SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c, { if (old_cert) { /* XXXX020 can we just compare signed_descriptor_digest ? */ if (c->cache_info.signed_descriptor_len == len && c->cache_info.signed_descriptor_body && !memcmp(s, c->cache_info.signed_descriptor_body, len)) { if (old_cert->cache_info.signed_descriptor_len == len && old_cert->cache_info.signed_descriptor_body && !memcmp(s, old_cert->cache_info.signed_descriptor_body, len)) { log_debug(LD_DIR, "We already checked the signature on this " "certificate; no need to do so again."); found = 1; break; } }); } if (!found) { if (check_signature_token(digest, tok, cert->identity_key, 0, Loading