[tor-commits] [tor/master] Only load master ed25519 secret keys when we absolutely must.

nickm at torproject.org nickm at torproject.org
Thu May 28 15:06:55 UTC 2015


commit 64450c5f775c6453568c5ac218669ff0525dc232
Author: Nick Mathewson <nickm at torproject.org>
Date:   Sun Mar 1 14:05:00 2015 +0100

    Only load master ed25519 secret keys when we absolutely must.
---
 src/or/routerkeys.c |   88 +++++++++++++++++++++++++++++++++++++++------------
 src/or/routerkeys.h |    1 +
 2 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index 9ad5a89..ab12b90 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -34,6 +34,9 @@
  *
  * If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a
  * public key file but no secret key file, return successfully anyway.
+ *
+ * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not even try to
+ * load or return a secret key (but create and save on if needed).
  */
 ed25519_keypair_t *
 ed_key_init_from_file(const char *fname, uint32_t flags,
@@ -63,6 +66,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags,
 
   /* Try to read the secret key. */
   const int have_secret = try_to_load &&
+    !(flags & INIT_ED_KEY_OMIT_SECRET) &&
     ed25519_seckey_read_from_file(&keypair->seckey,
                                   &got_tag, secret_fname) == 0;
 
@@ -80,7 +84,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags,
 
   /* If it's absent and that's okay, try to read the pubkey. */
   int found_public = 0;
-  if (!have_secret && try_to_load && (flags & INIT_ED_KEY_MISSING_SECRET_OK)) {
+  if (!have_secret && try_to_load) {
     tor_free(got_tag);
     found_public = ed25519_pubkey_read_from_file(&keypair->pubkey,
                                                  &got_tag, public_fname) == 0;
@@ -90,6 +94,10 @@ ed_key_init_from_file(const char *fname, uint32_t flags,
     }
   }
 
+  /* If the secret key is absent and it's not allowed to be, fail. */
+  if (!have_secret && found_public && !(flags & INIT_ED_KEY_MISSING_SECRET_OK))
+    goto err;
+
   /* If it's absent, and we're not supposed to make a new keypair, fail. */
   if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE))
     goto err;
@@ -274,7 +282,9 @@ load_ed_keys(const or_options_t *options, time_t now)
   ed25519_keypair_t *sign = NULL;
   ed25519_keypair_t *link = NULL;
   ed25519_keypair_t *auth = NULL;
+  const ed25519_keypair_t *sign_signing_key_with_id = NULL;
   const ed25519_keypair_t *use_signing = NULL;
+  const tor_cert_t *check_signing_cert = NULL;
   tor_cert_t *sign_cert = NULL;
   tor_cert_t *link_cert = NULL;
   tor_cert_t *auth_cert = NULL;
@@ -299,40 +309,76 @@ load_ed_keys(const or_options_t *options, time_t now)
   /* XXXX use options. */
   (void) options;
 
-  id = ed_key_init_from_file(
+  /* First try to get the signing key to see how it is. */
+  if (master_signing_key) {
+    check_signing_cert = signing_key_cert;
+    use_signing = master_signing_key;
+  } else {
+    sign = ed_key_init_from_file(
+               options_get_datadir_fname2(options, "keys", "ed25519_signing"),
+               INIT_ED_KEY_NEEDCERT|
+               INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT,
+               LOG_INFO,
+               NULL, 0, 0, CERT_TYPE_ID_SIGNING, &sign_cert);
+    check_signing_cert = sign_cert;
+    use_signing = sign;
+  }
+
+  const int need_new_signing_key =
+    NULL == use_signing ||
+    EXPIRES_SOON(check_signing_cert, 0);
+  const int want_new_signing_key =
+    need_new_signing_key ||
+    EXPIRES_SOON(check_signing_cert, 86400/*???*/);
+
+  {
+    uint32_t flags =
+      (INIT_ED_KEY_CREATE|INIT_ED_KEY_SPLIT|
+       INIT_ED_KEY_EXTRA_STRONG);
+    if (! need_new_signing_key)
+      flags |= INIT_ED_KEY_MISSING_SECRET_OK;
+    if (! want_new_signing_key)
+      flags |= INIT_ED_KEY_OMIT_SECRET;
+
+    id = ed_key_init_from_file(
              options_get_datadir_fname2(options, "keys", "ed25519_master_id"),
-                             (INIT_ED_KEY_CREATE|INIT_ED_KEY_SPLIT|
-                              INIT_ED_KEY_MISSING_SECRET_OK|
-                              INIT_ED_KEY_EXTRA_STRONG),
-                             LOG_WARN, NULL, 0, 0, 0, NULL);
-  if (!id)
-    FAIL("Missing identity key");
-
-  if (!master_signing_key || EXPIRES_SOON(signing_key_cert, 86400/*???*/)) {
+             flags,
+             LOG_WARN, NULL, 0, 0, 0, NULL);
+    if (!id)
+      FAIL("Missing identity key");
+    if (tor_mem_is_zero((char*)id->seckey.seckey, sizeof(id->seckey)))
+      sign_signing_key_with_id = NULL;
+    else
+      sign_signing_key_with_id = id;
+  }
+
+  if (need_new_signing_key && NULL == sign_signing_key_with_id)
+    FAIL("Can't load master key make a new signing key.");
+
+  if (want_new_signing_key && sign_signing_key_with_id) {
     uint32_t flags = (INIT_ED_KEY_CREATE|
+                      INIT_ED_KEY_REPLACE|
                       INIT_ED_KEY_EXTRA_STRONG|
                       INIT_ED_KEY_NEEDCERT|
                       INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT);
-    const ed25519_keypair_t *sign_with_id = id;
-    if (master_signing_key) {
-      flags |= INIT_ED_KEY_REPLACE; /* it's expired, so force-replace it. */
-    }
-    if (tor_mem_is_zero((char*)id->seckey.seckey, sizeof(id->seckey))) {
-      sign_with_id = NULL;
-      flags &= ~INIT_ED_KEY_CREATE;
-    }
     sign = ed_key_init_from_file(
                options_get_datadir_fname2(options, "keys", "ed25519_signing"),
                                  flags, LOG_WARN,
-                                 sign_with_id, now, 30*86400/*XXX option*/,
+                                 sign_signing_key_with_id, now,
+                                 30*86400/*XXX option*/,
                                  CERT_TYPE_ID_SIGNING, &sign_cert);
     if (!sign)
       FAIL("Missing signing key");
     use_signing = sign;
-  } else {
-    use_signing = master_signing_key;
+  } else if (want_new_signing_key) {
+    static ratelim_t missing_master = RATELIM_INIT(3600);
+    log_fn_ratelim(&missing_master, LOG_WARN, LD_OR,
+                   "Signing key will expire soon, but I can't load the "
+                   "master key to sign a new one!");
   }
 
+  tor_assert(use_signing);
+
   /* At this point we no longer need our secret identity key.  So wipe
    * it, if we loaded it in the first place. */
   memwipe(id->seckey.seckey, 0, sizeof(id->seckey));
diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h
index 5e2ef45..6c188b7 100644
--- a/src/or/routerkeys.h
+++ b/src/or/routerkeys.h
@@ -13,6 +13,7 @@
 #define INIT_ED_KEY_NEEDCERT                    (1u<<4)
 #define INIT_ED_KEY_EXTRA_STRONG                (1u<<5)
 #define INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT (1u<<6)
+#define INIT_ED_KEY_OMIT_SECRET                 (1u<<7)
 
 struct tor_cert_st;
 ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags,





More information about the tor-commits mailing list