|
@@ -132,6 +132,23 @@ trusted_dirs_reload_certs(void)
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
+/** Helper: return true iff we already have loaded the exact cert
|
|
|
+ * <b>cert</b>. */
|
|
|
+static INLINE int
|
|
|
+already_have_cert(authority_cert_t *cert)
|
|
|
+{
|
|
|
+ cert_list_t *cl = get_cert_list(cert->cache_info.identity_digest);
|
|
|
+
|
|
|
+ SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
|
|
|
+ {
|
|
|
+ if (!memcmp(c->cache_info.signed_descriptor_digest,
|
|
|
+ cert->cache_info.signed_descriptor_digest,
|
|
|
+ DIGEST_LEN))
|
|
|
+ return 1;
|
|
|
+ });
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/** Load a bunch of new key certificates from the string <b>contents</b>. If
|
|
|
* <b>from_store</b> is true, the certificates are from the cache, and we
|
|
|
* don't need to flush them to disk. If <b>from_store</b> is false, we need
|
|
@@ -141,12 +158,11 @@ 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) {
|
|
|
authority_cert_t *cert = authority_cert_parse_from_string(s, &eos);
|
|
|
- int found = 0;
|
|
|
+ cert_list_t *cl;
|
|
|
if (!cert)
|
|
|
break;
|
|
|
ds = trusteddirserver_get_by_v3_auth_digest(
|
|
@@ -154,25 +170,15 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store)
|
|
|
log_debug(LD_DIR, "Parsed certificate for %s",
|
|
|
ds ? ds->nickname : "unknown authority");
|
|
|
|
|
|
- cl = get_cert_list(cert->cache_info.identity_digest);
|
|
|
-
|
|
|
- SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
|
|
|
- {
|
|
|
- if (!memcmp(c->cache_info.signed_descriptor_digest,
|
|
|
- cert->cache_info.signed_descriptor_digest,
|
|
|
- DIGEST_LEN)) {
|
|
|
- /* we already have this one. continue. */
|
|
|
- log_info(LD_DIR, "Skipping %s certificate for %s that we "
|
|
|
- "already have.",
|
|
|
- from_store ? "cached" : "downloaded",
|
|
|
- ds ? ds->nickname : "??");
|
|
|
- authority_cert_free(cert);
|
|
|
- found = 1;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (found)
|
|
|
+ if (already_have_cert(cert)) {
|
|
|
+ /* we already have this one. continue. */
|
|
|
+ log_info(LD_DIR, "Skipping %s certificate for %s that we "
|
|
|
+ "already have.",
|
|
|
+ from_store ? "cached" : "downloaded",
|
|
|
+ ds ? ds->nickname : "??");
|
|
|
+ authority_cert_free(cert);
|
|
|
continue;
|
|
|
+ }
|
|
|
|
|
|
if (ds) {
|
|
|
log_info(LD_DIR, "Adding %s certificate for directory authority %s with "
|
|
@@ -185,6 +191,7 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store)
|
|
|
hex_str(cert->signing_key_digest,DIGEST_LEN));
|
|
|
}
|
|
|
|
|
|
+ cl = get_cert_list(cert->cache_info.identity_digest);
|
|
|
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
|