Przeglądaj źródła

r15956@catbus: nickm | 2007-10-19 11:18:14 -0400
Encode address in certificates. Also, make it possible to create certs reusing an old key.


svn:r12046

Nick Mathewson 17 lat temu
rodzic
commit
106e01db3d
6 zmienionych plików z 75 dodań i 10 usunięć
  1. 5 0
      ChangeLog
  2. 1 1
      doc/TODO
  3. 1 1
      doc/spec/dir-spec.txt
  4. 2 0
      src/or/or.h
  5. 15 3
      src/or/routerparse.c
  6. 51 5
      src/tools/tor-gencert.c

+ 5 - 0
ChangeLog

@@ -17,6 +17,11 @@ Changes in version 0.2.0.9-alpha - 2007-10-??
       clear all the flags for routers that fall out of the networkstatus
       clear all the flags for routers that fall out of the networkstatus
       consensus. Fixes bug 529.
       consensus. Fixes bug 529.
 
 
+  o Minor features (v3 directory protocol):
+    - Allow tor-gencert to generate a new certificate without replacing the
+      signing key.
+    - Allow certificates to include an address.
+
   o Minor features (router descriptor cache):
   o Minor features (router descriptor cache):
     - If we find a cached-routers file that's been sitting around for more
     - If we find a cached-routers file that's been sitting around for more
       than 28 days unmodified, then most likely it's a leftover from when we
       than 28 days unmodified, then most likely it's a leftover from when we

+ 1 - 1
doc/TODO

@@ -56,7 +56,7 @@ Things we'd like to do in 0.2.0.x:
     - Make new download types comply with should_delay_dir_fetches()
     - Make new download types comply with should_delay_dir_fetches()
     - When DownloadExtraInfo is turned on for the first time, don't flip
     - When DownloadExtraInfo is turned on for the first time, don't flip
       out and download the ancient history of the universe.
       out and download the ancient history of the universe.
-    - List IP addresses in certificates?
+    o List IP addresses in certificates?
     - Make the address in votes be an actual IP address.
     - Make the address in votes be an actual IP address.
 
 
   - Proposals:
   - Proposals:

+ 1 - 1
doc/spec/dir-spec.txt

@@ -655,7 +655,7 @@ $Id$
         the protocol described in this document.  Implementations MUST
         the protocol described in this document.  Implementations MUST
         reject formats they don't understand.
         reject formats they don't understand.
 
 
-    "address" IP NL
+    "dir-address" IP NL
         [Once or more]
         [Once or more]
 
 
         An IP:Port for this authority's directory port.
         An IP:Port for this authority's directory port.

+ 2 - 0
src/or/or.h

@@ -1475,6 +1475,8 @@ typedef struct authority_cert_t {
   crypto_pk_env_t *signing_key;
   crypto_pk_env_t *signing_key;
   char signing_key_digest[DIGEST_LEN];
   char signing_key_digest[DIGEST_LEN];
   time_t expires;
   time_t expires;
+  uint32_t addr;
+  uint16_t dir_port;
 } authority_cert_t;
 } authority_cert_t;
 
 
 /** Bitfield enum type listing types of directory authority/directory
 /** Bitfield enum type listing types of directory authority/directory

+ 15 - 3
src/or/routerparse.c

@@ -63,6 +63,7 @@ typedef enum {
   K_DIR_KEY_PUBLISHED,
   K_DIR_KEY_PUBLISHED,
   K_DIR_KEY_EXPIRES,
   K_DIR_KEY_EXPIRES,
   K_DIR_KEY_CERTIFICATION,
   K_DIR_KEY_CERTIFICATION,
+  K_DIR_ADDRESS,
 
 
   K_VOTE_STATUS,
   K_VOTE_STATUS,
   K_VALID_AFTER,
   K_VALID_AFTER,
@@ -280,8 +281,6 @@ static token_rule_t dir_token_table[] = {
   END_OF_TABLE
   END_OF_TABLE
 };
 };
 
 
-/** List of tokens allowable in the footer of v1/v2 directory/networkstatus
- * footers. */
 #define CERTIFICATE_MEMBERS                                                  \
 #define CERTIFICATE_MEMBERS                                                  \
   T1("dir-key-certificate-version", K_DIR_KEY_CERTIFICATE_VERSION,           \
   T1("dir-key-certificate-version", K_DIR_KEY_CERTIFICATE_VERSION,           \
                                                      GE(1),       NO_OBJ ),  \
                                                      GE(1),       NO_OBJ ),  \
@@ -290,7 +289,8 @@ static token_rule_t dir_token_table[] = {
   T1("dir-key-expires",  K_DIR_KEY_EXPIRES,          CONCAT_ARGS, NO_OBJ),   \
   T1("dir-key-expires",  K_DIR_KEY_EXPIRES,          CONCAT_ARGS, NO_OBJ),   \
   T1("dir-signing-key",  K_DIR_SIGNING_KEY,          NO_ARGS,     NEED_KEY ),\
   T1("dir-signing-key",  K_DIR_SIGNING_KEY,          NO_ARGS,     NEED_KEY ),\
   T1("dir-key-certification", K_DIR_KEY_CERTIFICATION,                       \
   T1("dir-key-certification", K_DIR_KEY_CERTIFICATION,                       \
-                                                     NO_ARGS,     NEED_OBJ),
+                                                     NO_ARGS,     NEED_OBJ), \
+  T01("dir-address",     K_DIR_ADDRESS,              GE(1),       NO_OBJ),
 
 
 static token_rule_t dir_key_certificate_table[] = {
 static token_rule_t dir_key_certificate_table[] = {
   CERTIFICATE_MEMBERS
   CERTIFICATE_MEMBERS
@@ -346,6 +346,8 @@ static token_rule_t networkstatus_consensus_token_table[] = {
   END_OF_TABLE
   END_OF_TABLE
 };
 };
 
 
+/** List of tokens allowable in the footer of v1/v2 directory/networkstatus
+ * footers. */
 static token_rule_t networkstatus_vote_footer_token_table[] = {
 static token_rule_t networkstatus_vote_footer_token_table[] = {
   T(  "directory-signature", K_DIRECTORY_SIGNATURE, GE(2),   NEED_OBJ ),
   T(  "directory-signature", K_DIRECTORY_SIGNATURE, GE(2),   NEED_OBJ ),
   END_OF_TABLE
   END_OF_TABLE
@@ -1438,6 +1440,16 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
     goto err;
     goto err;
   }
   }
 
 
+  tok = find_first_by_keyword(tokens, K_DIR_ADDRESS);
+  if (tok) {
+    tor_assert(tok->n_args);
+    if (parse_addr_port(LOG_WARN, tok->args[0], NULL, &cert->addr,
+                        &cert->dir_port)<0) {
+      log_warn(LD_DIR, "Couldn't parse dir-address in certificate");
+      goto err;
+    }
+  }
+
   tok = find_first_by_keyword(tokens, K_DIR_KEY_PUBLISHED);
   tok = find_first_by_keyword(tokens, K_DIR_KEY_PUBLISHED);
   tor_assert(tok);
   tor_assert(tok);
   if (parse_iso_time(tok->args[0], &cert->cache_info.published_on) < 0) {
   if (parse_iso_time(tok->args[0], &cert->cache_info.published_on) < 0) {

+ 51 - 5
src/tools/tor-gencert.c

@@ -39,9 +39,11 @@
 char *identity_key_file = NULL;
 char *identity_key_file = NULL;
 char *signing_key_file = NULL;
 char *signing_key_file = NULL;
 char *certificate_file = NULL;
 char *certificate_file = NULL;
+int reuse_signing_key = 0;
 int verbose = 0;
 int verbose = 0;
 int make_new_id = 0;
 int make_new_id = 0;
 int months_lifetime = DEFAULT_LIFETIME;
 int months_lifetime = DEFAULT_LIFETIME;
+char *address = NULL;
 
 
 EVP_PKEY *identity_key = NULL;
 EVP_PKEY *identity_key = NULL;
 EVP_PKEY *signing_key = NULL;
 EVP_PKEY *signing_key = NULL;
@@ -53,7 +55,8 @@ show_help(void)
   fprintf(stderr, "Syntax:\n"
   fprintf(stderr, "Syntax:\n"
           "tor-gencert [-h|--help] [-v] [--create-identity-key] "
           "tor-gencert [-h|--help] [-v] [--create-identity-key] "
           "[-i identity_key_file]\n"
           "[-i identity_key_file]\n"
-          "            [-s signing_key_file] [-c certificate_file]\n");
+          "            [-s signing_key_file] [-c certificate_file] "
+          "[--reuse-signing-key]\n");
 }
 }
 
 
 /* XXXX copied from crypto.c */
 /* XXXX copied from crypto.c */
@@ -109,8 +112,25 @@ parse_commandline(int argc, char **argv)
         fprintf(stderr, "Lifetime (in months) was out of range.");
         fprintf(stderr, "Lifetime (in months) was out of range.");
         return 1;
         return 1;
       }
       }
+    } else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--reuse")) {
+      reuse_signing_key = 1;
     } else if (!strcmp(argv[i], "-v")) {
     } else if (!strcmp(argv[i], "-v")) {
       verbose = 1;
       verbose = 1;
+    } else if (!strcmp(argv[i], "-a")) {
+      uint32_t addr;
+      uint16_t port;
+      char b[INET_NTOA_BUF_LEN];
+      struct in_addr in;
+      if (i+1>=argc) {
+        fprintf(stderr, "No argument to -a\n");
+        return 1;
+      }
+      if (parse_addr_port(LOG_ERR, argv[++i], NULL, &addr, &port)<0)
+        return 1;
+      in.s_addr = htonl(addr);
+      tor_inet_ntoa(&in, b, sizeof(b));
+      address = tor_malloc(INET_NTOA_BUF_LEN+32);
+      tor_snprintf(address, INET_NTOA_BUF_LEN+32, "%s:%d", b, (int)port);
     } else if (!strcmp(argv[i], "--create-identity-key")) {
     } else if (!strcmp(argv[i], "--create-identity-key")) {
       make_new_id = 1;
       make_new_id = 1;
     } else {
     } else {
@@ -213,6 +233,24 @@ load_identity_key(void)
   return 0;
   return 0;
 }
 }
 
 
+/** DOCDOC */
+static int
+load_signing_key(void)
+{
+  FILE *f;
+  if (!(f = fopen(signing_key_file, "r"))) {
+    log_err(LD_GENERAL, "Couldn't open %s for reading: %s",
+            signing_key_file, strerror(errno));
+    return 1;
+  }
+  if (!(signing_key = PEM_read_PrivateKey(f, NULL, NULL, NULL))) {
+    log_err(LD_GENERAL, "Couldn't read siging key from %s", signing_key_file);
+    return 1;
+  }
+  fclose(f);
+  return 0;
+}
+
 /** DOCDOC */
 /** DOCDOC */
 static int
 static int
 generate_signing_key(void)
 generate_signing_key(void)
@@ -315,13 +353,15 @@ generate_certificate(void)
   format_iso_time(expires, mktime(&tm));
   format_iso_time(expires, mktime(&tm));
 
 
   tor_snprintf(buf, sizeof(buf),
   tor_snprintf(buf, sizeof(buf),
-               "dir-key-certificate-version 3\n"
+               "dir-key-certificate-version 3"
-               "fingerprint %s\n"
+               "%s%s"
+               "\nfingerprint %s\n"
                "dir-key-published %s\n"
                "dir-key-published %s\n"
                "dir-key-expires %s\n"
                "dir-key-expires %s\n"
                "dir-identity-key\n%s"
                "dir-identity-key\n%s"
                "dir-signing-key\n%s"
                "dir-signing-key\n%s"
                "dir-key-certification\n",
                "dir-key-certification\n",
+               address?"\ndir-address ":"", address?address:"",
                fingerprint, published, expires, ident, signing);
                fingerprint, published, expires, ident, signing);
   signed_len = strlen(buf);
   signed_len = strlen(buf);
   SHA1((const unsigned char*)buf,signed_len,(unsigned char*)digest);
   SHA1((const unsigned char*)buf,signed_len,(unsigned char*)digest);
@@ -368,8 +408,13 @@ main(int argc, char **argv)
     goto done;
     goto done;
   if (load_identity_key())
   if (load_identity_key())
     goto done;
     goto done;
-  if (generate_signing_key())
+  if (reuse_signing_key) {
-    goto done;
+    if (load_signing_key())
+      goto done;
+  } else {
+    if (generate_signing_key())
+      goto done;
+  }
   if (generate_certificate())
   if (generate_certificate())
     goto done;
     goto done;
 
 
@@ -379,6 +424,7 @@ main(int argc, char **argv)
     EVP_PKEY_free(identity_key);
     EVP_PKEY_free(identity_key);
   if (signing_key)
   if (signing_key)
     EVP_PKEY_free(signing_key);
     EVP_PKEY_free(signing_key);
+  tor_free(address);
 
 
   crypto_global_cleanup();
   crypto_global_cleanup();
   return r;
   return r;