[or-cvs] r11112: Implement cert-retrieval URLs. (Also, update TODO) (in tor/trunk: . doc doc/spec src/or)

nickm at seul.org nickm at seul.org
Tue Aug 14 21:09:30 UTC 2007


Author: nickm
Date: 2007-08-14 17:09:30 -0400 (Tue, 14 Aug 2007)
New Revision: 11112

Modified:
   tor/trunk/
   tor/trunk/doc/TODO
   tor/trunk/doc/spec/dir-spec.txt
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
Log:
 r14028 at Kushana:  nickm | 2007-08-14 17:07:51 -0400
 Implement cert-retrieval URLs. (Also, update TODO)



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r14028] on c95137ef-5f19-0410-b913-86e773d04f59

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-08-14 20:20:06 UTC (rev 11111)
+++ tor/trunk/doc/TODO	2007-08-14 21:09:30 UTC (rev 11112)
@@ -55,7 +55,7 @@
           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 @@
         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 @@
       - 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

Modified: tor/trunk/doc/spec/dir-spec.txt
===================================================================
--- tor/trunk/doc/spec/dir-spec.txt	2007-08-14 20:20:06 UTC (rev 11111)
+++ tor/trunk/doc/spec/dir-spec.txt	2007-08-14 21:09:30 UTC (rev 11112)
@@ -1242,6 +1242,14 @@
    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

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2007-08-14 20:20:06 UTC (rev 11111)
+++ tor/trunk/src/or/directory.c	2007-08-14 21:09:30 UTC (rev 11112)
@@ -1737,7 +1737,8 @@
                              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 @@
     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/"))) {

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-08-14 20:20:06 UTC (rev 11111)
+++ tor/trunk/src/or/or.h	2007-08-14 21:09:30 UTC (rev 11112)
@@ -3355,6 +3355,8 @@
      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);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-08-14 20:20:06 UTC (rev 11111)
+++ tor/trunk/src/or/routerlist.c	2007-08-14 21:09:30 UTC (rev 11112)
@@ -337,6 +337,41 @@
   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. */



More information about the tor-commits mailing list