diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-08-26 15:34:53 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-08-26 15:34:53 +0000 |
commit | d54d7b7ec1321bd2f6e0779aa1080f49f4bea756 (patch) | |
tree | 41ea25df334bd5a108a8cdd3fa40cbf138764631 /src | |
parent | 893acb3acc8a340a7686eb09cb56bde7d75d6bd3 (diff) | |
download | tor-d54d7b7ec1321bd2f6e0779aa1080f49f4bea756.tar tor-d54d7b7ec1321bd2f6e0779aa1080f49f4bea756.tar.gz |
Add some documentation; move the signature generation logic into routerparse.c along with the hash generation logic; make router signing use it as well.
svn:r4840
Diffstat (limited to 'src')
-rw-r--r-- | src/or/dirserv.c | 72 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/router.c | 18 | ||||
-rw-r--r-- | src/or/routerparse.c | 38 | ||||
-rw-r--r-- | src/or/test.c | 1 |
5 files changed, 72 insertions, 59 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 9e7a679e9..f6d70b949 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -665,7 +665,10 @@ dirserv_remove_old_servers(int age) } } -/* DOCDOC */ +/* Given a (possibly empty) list of config_line_t, each line of which contains + * a list of comma-separated version numbers surrounded by optional space, + * allocate and return a new string containing the version numbers, in order, + * separated by commas. Used to generate Recommended(Client|Server)?Versions */ static char * format_versions_list(config_line_t *ln) { @@ -682,38 +685,6 @@ format_versions_list(config_line_t *ln) return result; } -/* DOCDOC */ -static int -append_signature(char *buf, size_t buf_len, const char *digest, - crypto_pk_env_t *private_key) -{ - char signature[PK_BYTES]; - int i; - - if (crypto_pk_private_sign(private_key, signature, digest, DIGEST_LEN) < 0) { - - log_fn(LOG_WARN,"Couldn't sign digest."); - return -1; - } - if (strlcat(buf, "-----BEGIN SIGNATURE-----\n", buf_len) >= buf_len) - goto truncated; - - i = strlen(buf); - if (base64_encode(buf+i, buf_len-i, signature, 128) < 0) { - log_fn(LOG_WARN,"couldn't base64-encode signature"); - tor_free(buf); - return -1; - } - - if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len) - goto truncated; - - return 0; - truncated: - log_fn(LOG_WARN,"tried to exceed string length."); - return -1; -} - /** Generate a new directory and write it into a newly allocated string. * Point *<b>dir_out</b> to the allocated string. Sign the * directory with <b>private_key</b>. Return 0 on success, -1 on @@ -796,7 +767,7 @@ dirserv_dump_directory_to_string(char **dir_out, tor_free(buf); return -1; } - if (append_signature(buf,buf_len,digest,private_key)<0) { + if (router_append_dirobj_signature(buf,buf_len,digest,private_key)<0) { tor_free(buf); return -1; } @@ -809,27 +780,32 @@ dirserv_dump_directory_to_string(char **dir_out, return -1; } -/** DOCDOC */ + +/** A cached_dir_t represents a cacheable directory object, along with its + * compressed form. */ typedef struct cached_dir_t { - char *dir; - char *dir_z; - size_t dir_len; - size_t dir_z_len; - time_t published; + char *dir; /**< Contents of this object */ + char *dir_z; /**< Compressed contents of this object. */ + size_t dir_len; /**< Length of <b>dir</b> */ + size_t dir_z_len; /**< Length of <b>dir_z</b> */ + time_t published; /**< When was this object published */ } cached_dir_t; /** Most recently generated encoded signed directory. (auth dirservers only.)*/ static cached_dir_t the_directory = { NULL, NULL, 0, 0, 0 }; -/* used only by non-auth dirservers */ +/* Used only by non-auth dirservers: The directory and runningrouters we'll +* serve when requested. */ static cached_dir_t cached_directory = { NULL, NULL, 0, 0, 0 }; static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0 }; -/* Used for other dirservers' network statuses. Map from hexdigest to +/* Used for other dirservers' v2 network statuses. Map from hexdigest to * cached_dir_t. */ static strmap_t *cached_v2_networkstatus = NULL; -/** DOCDOC */ +/** Possibly replace the contents of <b>d</b> with the value of + * <b>directory</b> published on <b>when</b>. (Do nothing if <b>when</b> is + * older than the last value, or too far in the future. */ static void set_cached_dir(cached_dir_t *d, const char *directory, time_t when) { @@ -853,6 +829,7 @@ set_cached_dir(cached_dir_t *d, const char *directory, time_t when) } } +/** Remove all storage held in <b>d</b>, but do not free <b>d</b> itself. */ static void clear_cached_dir(cached_dir_t *d) { @@ -861,6 +838,7 @@ clear_cached_dir(cached_dir_t *d) memset(d, 0, sizeof(cached_dir_t)); } +/** Free all storage held by the cached_dir_t in <b>d</b>. */ static void free_cached_dir(void *_d) { @@ -888,7 +866,7 @@ dirserv_set_cached_directory(const char *directory, time_t published, } } -/** DOCDOC */ +/** Called when we've just received a DOCDOC */ void dirserv_set_cached_networkstatus_v2(const char *directory, const char *fp, time_t published) @@ -1035,7 +1013,7 @@ generate_runningrouters(void) log_fn(LOG_WARN,"couldn't compute digest"); goto err; } - if (append_signature(s, len, digest, private_key)<0) + if (router_append_dirobj_signature(s, len, digest, private_key)<0) goto err; set_cached_dir(&the_runningrouters, s, time(NULL)); @@ -1231,7 +1209,7 @@ generate_v2_networkstatus(void) goto done; } - if (append_signature(outp,endp-outp,digest,private_key)<0) + if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) goto done; set_cached_dir(&the_v2_networkstatus, status, time(NULL)); @@ -1311,6 +1289,8 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key) smartlist_add(digests, d); }); smartlist_free(hexdigests); + /* XXXX should always return own descriptor. or special-case it. or + * something. */ SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, SMARTLIST_FOREACH(digests, const char *, d, if (!memcmp(d,ri->identity_digest,DIGEST_LEN)) { diff --git a/src/or/or.h b/src/or/or.h index b5c9f3bae..54d572cf3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2035,6 +2035,8 @@ int router_get_router_hash(const char *s, char *digest); int router_get_dir_hash(const char *s, char *digest); int router_get_runningrouters_hash(const char *s, char *digest); int router_get_networkstatus_v2_hash(const char *s, char *digest); +int router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest, + crypto_pk_env_t *private_key); int router_parse_list_from_string(const char **s, routerlist_t **dest, smartlist_t *good_nickname_list, diff --git a/src/or/router.c b/src/or/router.c index 44079db60..693f32bc8 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -857,9 +857,8 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, { char *onion_pkey; /* Onion key, PEM-encoded. */ char *identity_pkey; /* Identity key, PEM-encoded. */ - char digest[20]; - char signature[128]; - char published[32]; + char digest[DIGEST_LEN]; + char published[ISO_TIME_LEN+1]; char fingerprint[FINGERPRINT_LEN+1]; struct in_addr in; char addrbuf[INET_NTOA_BUF_LEN]; @@ -1017,18 +1016,11 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, if (router_get_router_hash(s, digest) < 0) return -1; - if (crypto_pk_private_sign(ident_key, signature, digest, 20) < 0) { - log_fn(LOG_WARN, "Error signing digest"); + if (router_append_dirobj_signature(s+written,maxlen-written, + digest,ident_key)<0) { + log_fn(LOG_WARN, "Couldn't sign router descriptor"); return -1; } - strlcat(s+written, "-----BEGIN SIGNATURE-----\n", maxlen-written); - written += strlen(s+written); - if (base64_encode(s+written, maxlen-written, signature, 128) < 0) { - log_fn(LOG_WARN, "Couldn't base64-encode signature"); - return -1; - } - written += strlen(s+written); - strlcat(s+written, "-----END SIGNATURE-----\n", maxlen-written); written += strlen(s+written); if (written+2 > maxlen) diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 6ebd5ff29..14d16f62f 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -187,6 +187,44 @@ router_get_networkstatus_v2_hash(const char *s, char *digest) "network-status-version","\ndirectory-signature"); } +/** Helper: used to generate signatures for routers, directories and + * network-status objects. Given a digest in <b>digest</b> and a secret + * <b>private_key</b>, generate an PKCS1-padded signature, BASE64-encode it, + * surround it with -----BEGIN/END----- pairs, and write it to the + * <b>buf_len</b>-byte buffer at <b>buf</b>. Return 0 on success, -1 on + * failure. + */ +int +router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest, + crypto_pk_env_t *private_key) +{ + char signature[PK_BYTES]; + int i; + + if (crypto_pk_private_sign(private_key, signature, digest, DIGEST_LEN) < 0) { + + log_fn(LOG_WARN,"Couldn't sign digest."); + return -1; + } + if (strlcat(buf, "-----BEGIN SIGNATURE-----\n", buf_len) >= buf_len) + goto truncated; + + i = strlen(buf); + if (base64_encode(buf+i, buf_len-i, signature, 128) < 0) { + log_fn(LOG_WARN,"couldn't base64-encode signature"); + tor_free(buf); + return -1; + } + + if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len) + goto truncated; + + return 0; + truncated: + log_fn(LOG_WARN,"tried to exceed string length."); + return -1; +} + /** * Find the first instance of "recommended-software ...\n" at the start of * a line; return a newly allocated string containing the "..." portion. diff --git a/src/or/test.c b/src/or/test.c index 604c68694..af976aa7b 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1529,6 +1529,7 @@ main(int c, char**v) options_init(options); options->DataDirectory = tor_strdup(temp_dir); set_options(options); + printf("a\n"); crypto_seed_rng(); |