[tor-commits] [tor/master] Add a master-key-ed25519 line for convenience

nickm at torproject.org nickm at torproject.org
Mon Jun 1 15:25:00 UTC 2015


commit 3d653dff5e891c1e547ef7eacbc991410a98c1cb
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Jun 1 11:24:55 2015 -0400

    Add a master-key-ed25519 line for convenience
---
 src/or/router.c      |   10 +++++++++-
 src/or/routerparse.c |   29 ++++++++++++++++++++++++++++-
 src/test/test_dir.c  |   12 ++++++++++--
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/or/router.c b/src/or/router.c
index 6868e7b..0903eb2 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -2406,6 +2406,7 @@ router_dump_router_to_string(routerinfo_t *router,
   if (emit_ed_sigs) {
     /* Encode ed25519 signing cert */
     char ed_cert_base64[256];
+    char ed_fp_base64[ED25519_BASE64_LEN+1];
     if (base64_encode(ed_cert_base64, sizeof(ed_cert_base64),
                       (const char*)router->signing_key_cert->encoded,
                       router->signing_key_cert->encoded_len,
@@ -2413,10 +2414,17 @@ router_dump_router_to_string(routerinfo_t *router,
       log_err(LD_BUG,"Couldn't base64-encode signing key certificate!");
       goto err;
     }
+    if (ed25519_public_to_base64(ed_fp_base64,
+                                 &router->signing_key_cert->signing_key)<0) {
+      log_err(LD_BUG,"Couldn't base64-encode identity key\n");
+      goto err;
+    }
     tor_asprintf(&ed_cert_line, "identity-ed25519\n"
                  "-----BEGIN ED25519 CERT-----\n"
                  "%s"
-                 "-----END ED25519 CERT-----\n", ed_cert_base64);
+                 "-----END ED25519 CERT-----\n"
+                 "master-key-ed25519 %s\n",
+                 ed_cert_base64, ed_fp_base64);
   }
 
   /* PEM-encode the onion key */
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 1413d40..ae50cda 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -89,6 +89,7 @@ typedef enum {
   K_IPV6_POLICY,
   K_ROUTER_SIG_ED25519,
   K_IDENTITY_ED25519,
+  K_MASTER_KEY_ED25519,
   K_ONION_KEY_CROSSCERT,
   K_NTOR_ONION_KEY_CROSSCERT,
 
@@ -302,6 +303,7 @@ static token_rule_t routerdesc_token_table[] = {
   T01("extra-info-digest",   K_EXTRA_INFO_DIGEST,   GE(1),   NO_OBJ ),
   T01("hidden-service-dir",  K_HIDDEN_SERVICE_DIR,  NO_ARGS, NO_OBJ ),
   T01("identity-ed25519",    K_IDENTITY_ED25519,    NO_ARGS, NEED_OBJ ),
+  T01("master-key-ed25519",  K_MASTER_KEY_ED25519,  GE(1),   NO_OBJ ),
   T01("router-sig-ed25519",  K_ROUTER_SIG_ED25519,  GE(1),   NO_OBJ ),
   T01("onion-key-crosscert", K_ONION_KEY_CROSSCERT, NO_ARGS, NEED_OBJ ),
   T01("ntor-onion-key-crosscert", K_NTOR_ONION_KEY_CROSSCERT,
@@ -1337,9 +1339,11 @@ router_parse_entry_from_string(const char *s, const char *end,
   }
 
   {
-    directory_token_t *ed_sig_tok, *ed_cert_tok, *cc_tap_tok, *cc_ntor_tok;
+    directory_token_t *ed_sig_tok, *ed_cert_tok, *cc_tap_tok, *cc_ntor_tok,
+      *master_key_tok;
     ed_sig_tok = find_opt_by_keyword(tokens, K_ROUTER_SIG_ED25519);
     ed_cert_tok = find_opt_by_keyword(tokens, K_IDENTITY_ED25519);
+    master_key_tok = find_opt_by_keyword(tokens, K_MASTER_KEY_ED25519);
     cc_tap_tok = find_opt_by_keyword(tokens, K_ONION_KEY_CROSSCERT);
     cc_ntor_tok = find_opt_by_keyword(tokens, K_NTOR_ONION_KEY_CROSSCERT);
     int n_ed_toks = !!ed_sig_tok + !!ed_cert_tok +
@@ -1350,6 +1354,11 @@ router_parse_entry_from_string(const char *s, const char *end,
                "cross-certification support");
       goto err;
     }
+    if (master_key_tok && !ed_sig_tok) {
+      log_warn(LD_DIR, "Router descriptor has ed25519 master key but no "
+               "certificate");
+      goto err;
+    }
     if (ed_sig_tok) {
       tor_assert(ed_cert_tok && cc_tap_tok && cc_ntor_tok);
       const int ed_cert_token_pos = smartlist_pos(tokens, ed_cert_tok);
@@ -1394,12 +1403,30 @@ router_parse_entry_from_string(const char *s, const char *end,
         goto err;
       }
       router->signing_key_cert = cert; /* makes sure it gets freed. */
+
       if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
           ! cert->signing_key_included) {
         log_warn(LD_DIR, "Invalid form for ed25519 cert");
         goto err;
       }
 
+      if (master_key_tok) {
+        /* This token is optional, but if it's present, it must match
+         * the signature in the signing cert, or supplant it. */
+        tor_assert(master_key_tok->n_args >= 1);
+        ed25519_public_key_t pkey;
+        if (ed25519_public_from_base64(&pkey, master_key_tok->args[0])<0) {
+          log_warn(LD_DIR, "Can't parse ed25519 master key");
+          goto err;
+        }
+
+        if (fast_memneq(&cert->signing_key.pubkey,
+                        pkey.pubkey, ED25519_PUBKEY_LEN)) {
+          log_warn(LD_DIR, "Ed25519 master key does not match "
+                   "key in certificate");
+          goto err;
+        }
+      }
       ntor_cc_cert = tor_cert_parse((const uint8_t*)cc_ntor_tok->object_body,
                                     cc_ntor_tok->object_size);
       if (!ntor_cc_cert) {
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 32ac8d4..35bd8ea 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -227,8 +227,16 @@ test_dir_formats(void *arg)
           "identity-ed25519\n"
           "-----BEGIN ED25519 CERT-----\n", sizeof(buf2));
   strlcat(buf2, cert_buf, sizeof(buf2));
-  strlcat(buf2, "-----END ED25519 CERT-----\n"
-          "platform Tor "VERSION" on ", sizeof(buf2));
+  strlcat(buf2, "-----END ED25519 CERT-----\n", sizeof(buf2));
+  strlcat(buf2, "master-key-ed25519 ", sizeof(buf2));
+  {
+    char k[ED25519_BASE64_LEN+1];
+    tt_assert(ed25519_public_to_base64(k, &r2->signing_key_cert->signing_key)
+              >= 0);
+    strlcat(buf2, k, sizeof(buf2));
+    strlcat(buf2, "\n", sizeof(buf2));
+  }
+  strlcat(buf2, "platform Tor "VERSION" on ", sizeof(buf2));
   strlcat(buf2, get_uname(), sizeof(buf2));
   strlcat(buf2, "\n"
           "protocols Link 1 2 Circuit 1\n"



More information about the tor-commits mailing list