r14028@Kushana: nickm | 2007-08-14 17:07:51 -0400

Implement cert-retrieval URLs. (Also, update TODO)


svn:r11112
This commit is contained in:
Nick Mathewson 2007-08-14 21:09:30 +00:00
parent 9a30f8ba0e
commit 484a580698
5 changed files with 129 additions and 5 deletions

View File

@ -55,7 +55,7 @@ Things we'd like to do in 0.2.0.x:
unreachable is bunk -- it's leftover from the time when all
servers ran 24/7. now it triggers every time a server goes
away and then returns before the old descriptor has expired.
- Update dir-spec with decisions made on these issues:
o Update dir-spec with decisions made on these issues:
o clients don't log as loudly when they receive them
o they don't count toward the 3-strikes rule
D But eventually, we give up after getting a lot of 503s.
@ -67,8 +67,8 @@ Things we'd like to do in 0.2.0.x:
D They can 503 client descriptor requests when they feel like it.
How can they distinguish? Not implemented for now, maybe
should abandon.
- describe our 302 not modified behaviors.
- and document a bit more -- e.g. it looks like we return an empty
o describe our 302 not modified behaviors.
o and document a bit more -- e.g. it looks like we return an empty
200 OK when somebody asks us for a networkstatus and we don't
have it?
@ -84,7 +84,7 @@ Things we'd like to do in 0.2.0.x:
- Get authorities voting
. Code to manage key certificates
- Download as needed.
- Serve list as needed.
o Serve list as needed.
o Avoid double-checking signatures every time we get a vote.
- Warn about expired stuff.
- Fix all XXXX020s in vote code

View File

@ -1242,6 +1242,14 @@ $Id$
available at:
http://<hostname>/tor/keys/authority.z
The key certificate for an authority whose authority identity fingerprint
is <F> should be available at:
http://<hostname>/tor/keys/fp/<F>.z
The key certificate whose signing key is <F> should be available at:
http://<hostname>/tor/keys/fp/<F>.z
[XXX020 cross-certify?]
The most recent descriptor for a server whose identity key has a
fingerprint of <F> should be available at:
http://<hostname>/tor/server/fp/<F>.z

View File

@ -1737,7 +1737,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
const char *body, size_t body_len)
{
size_t dlen;
char *url = NULL;
char *url = NULL; /* XXX020 every exit point needs to free url. this
* function should use 'goto done' for that. */
or_options_t *options = get_options();
time_t if_modified_since = 0;
char *header;
@ -2007,6 +2008,84 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
return 0;
}
if (!strcmpstart(url,"/tor/keys/")) {
smartlist_t *certs = smartlist_create();
int compressed;
ssize_t len = -1;
url += strlen("/tor/keys/");
compressed = !strcmpend(url, ".z");
if (compressed)
url[strlen(url)-2] = '\0';
if (!strcmp(url, "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,
if (cert->cache_info.published_on >= if_modified_since)
smartlist_add(certs, cert));
});
} else if (!strcmp(url, "authority")) {
authority_cert_t *cert = get_my_v3_authority_cert();
if (cert)
smartlist_add(certs, cert);
} else if (!strcmpstart(url, "fp/")) {
smartlist_t *fps = smartlist_create();
dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
SMARTLIST_FOREACH(fps, char *, d, {
authority_cert_t *c = authority_cert_get_newest_by_id(d);
if (c) smartlist_add(certs, c);
tor_free(d);
});
smartlist_free(fps);
} else if (!strcmpstart(url, "sk/")) {
smartlist_t *fps = smartlist_create();
dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
SMARTLIST_FOREACH(fps, char *, d, {
authority_cert_t *c = authority_cert_get_by_sk_digest(d);
if (c) smartlist_add(certs, c);
tor_free(d);
});
smartlist_free(fps);
} else {
write_http_status_line(conn, 400, "Bad request");
tor_free(url);
smartlist_free(certs);
return 0;
}
if (!smartlist_len(certs)) {
write_http_status_line(conn, 404, "Not found");
tor_free(url);
smartlist_free(certs);
return 0;
}
if (!compressed) {
len = 0;
SMARTLIST_FOREACH(certs, authority_cert_t *, c,
len += c->cache_info.signed_descriptor_len);
}
write_http_response_header(conn, len,
compressed?"application/octet-stream":"text/plain",
compressed?"deflate":"identity",
60*60);
if (compressed) {
conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
SMARTLIST_FOREACH(certs, authority_cert_t *, c,
connection_write_to_buf_zlib(c->cache_info.signed_descriptor_body,
c->cache_info.signed_descriptor_len,
conn, 0));
connection_write_to_buf_zlib("", 0, conn, 1);
} else {
SMARTLIST_FOREACH(certs, authority_cert_t *, c,
connection_write_to_buf(c->cache_info.signed_descriptor_body,
c->cache_info.signed_descriptor_len,
TO_CONN(conn)));
}
smartlist_free(certs);
tor_free(url);
}
if (options->HSAuthoritativeDir &&
(!strcmpstart(url,"/tor/rendezvous/") ||
!strcmpstart(url,"/tor/rendezvous1/"))) {

View File

@ -3355,6 +3355,8 @@ trusted_dir_server_t *router_get_trusteddirserver_by_digest(
const char *digest);
trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(
const char *digest);
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 routerlist_add_family(smartlist_t *sl, routerinfo_t *router);

View File

@ -337,6 +337,41 @@ trusted_dirs_remove_old_certs(void)
trusted_dirs_flush_certs_to_disk();
}
/** DOCDOC */
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);
authority_cert_t *best = NULL;
if (!ds || !ds->v3_certs)
return NULL;
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
{
if (!best || cert->cache_info.published_on > best->cache_info.published_on)
best = cert;
});
return best;
}
/** DOCDOC */
authority_cert_t *
authority_cert_get_by_sk_digest(const char *sk_digest)
{
if (!trusted_dir_servers)
return NULL;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
if (!ds->v3_certs)
return NULL;
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
{
if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN))
return cert;
});
});
return NULL;
}
/** Return the v3 authority certificate with signing key matching
* <b>sk_digest</b>, for the authority with identity digest <b>id_digest</b>.
* Return NULL if no such authority is known. */