diff options
author | Andrea Shepard <andrea@torproject.org> | 2013-05-09 04:56:54 -0700 |
---|---|---|
committer | Andrea Shepard <andrea@torproject.org> | 2013-05-09 10:55:01 -0700 |
commit | fddb814feaa3d0091df03b26fa709cfba55312ed (patch) | |
tree | a80560b8e77ab80ac5f88136521bd618253d00ff /src/or/directory.c | |
parent | d5bd4a4763dfa74572ce6ed0b565315c43ff9f87 (diff) | |
download | tor-fddb814feaa3d0091df03b26fa709cfba55312ed.tar.gz tor-fddb814feaa3d0091df03b26fa709cfba55312ed.zip |
When downloading certificates, distinguish requesting by identity digest from requesting by ID digest, signing key pair; fixes bug 5595
Diffstat (limited to 'src/or/directory.c')
-rw-r--r-- | src/or/directory.c | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index f235bf3b41..8dd5a7cdc8 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -809,13 +809,34 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) if (!conn->requested_resource) return; failed = smartlist_new(); - dir_split_resource_into_fingerprints(conn->requested_resource+3, - failed, NULL, DSR_HEX); - SMARTLIST_FOREACH(failed, char *, cp, - { - authority_cert_dl_failed(cp, status); - tor_free(cp); - }); + /* + * We have two cases download by fingerprint (resource starts + * with "fp/") or download by fingerprint/signing key pair + * (resource starts with "fp-sk/"). + */ + if (!strcmpstart(conn->requested_resource, "fp/")) { + /* Download by fingerprint case */ + dir_split_resource_into_fingerprints(conn->requested_resource + 3, + failed, NULL, DSR_HEX); + SMARTLIST_FOREACH_BEGIN(failed, char *, cp) { + /* Null signing key digest indicates download by fp only */ + authority_cert_dl_failed(cp, NULL, status); + tor_free(cp); + } SMARTLIST_FOREACH_END(cp); + } else if (!strcmpstart(conn->requested_resource, "fp-sk/")) { + /* Download by (fp,sk) pairs */ + dir_split_resource_into_fingerprint_pairs(conn->requested_resource + 5, + failed); + SMARTLIST_FOREACH_BEGIN(failed, fp_pair_t *, cp) { + authority_cert_dl_failed(cp->first, cp->second, status); + tor_free(cp); + } SMARTLIST_FOREACH_END(cp); + } else { + log_warn(LD_DIR, + "Don't know what to do with failure for cert fetch %s", + conn->requested_resource); + } + smartlist_free(failed); update_certificate_downloads(time(NULL)); @@ -1589,6 +1610,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) conn->_base.purpose == DIR_PURPOSE_FETCH_MICRODESC); int was_compressed=0; time_t now = time(NULL); + int src_code; switch (connection_fetch_from_buf_http(TO_CONN(conn), &headers, MAX_HEADERS_SIZE, @@ -1857,14 +1879,33 @@ connection_dir_client_reached_eof(dir_connection_t *conn) } log_info(LD_DIR,"Received authority certificates (size %d) from server " "'%s:%d'", (int)body_len, conn->_base.address, conn->_base.port); - if (trusted_dirs_load_certs_from_string(body, 0, 1)<0) { - log_warn(LD_DIR, "Unable to parse fetched certificates"); - /* if we fetched more than one and only some failed, the successful - * ones got flushed to disk so it's safe to call this on them */ - connection_dir_download_cert_failed(conn, status_code); + /* + * Tell trusted_dirs_load_certs_from_string() whether it was by fp + * or fp-sk pair. + */ + src_code = -1; + if (!strcmpstart(conn->requested_resource, "fp/")) { + src_code = TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST; + } else if (!strcmpstart(conn->requested_resource, "fp-sk/")) { + src_code = TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST; + } + + if (src_code != -1) { + if (trusted_dirs_load_certs_from_string(body, src_code, 1)<0) { + log_warn(LD_DIR, "Unable to parse fetched certificates"); + /* if we fetched more than one and only some failed, the successful + * ones got flushed to disk so it's safe to call this on them */ + connection_dir_download_cert_failed(conn, status_code); + } else { + directory_info_has_arrived(now, 0); + log_info(LD_DIR, "Successfully loaded certificates from fetch."); + } } else { - directory_info_has_arrived(now, 0); - log_info(LD_DIR, "Successfully loaded certificates from fetch."); + log_warn(LD_DIR, + "Couldn't figure out what to do with fetched certificates for " + "unknown resource %s", + conn->requested_resource); + connection_dir_download_cert_failed(conn, status_code); } } if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) { |