[tor-commits] [tor/master] Add periodic timer for expiring old onion keys.

nickm at torproject.org nickm at torproject.org
Fri Mar 17 15:18:17 UTC 2017


commit 853b54dea4c56ea2913caf58ad6d337502b18b91
Author: Alexander Færøy <ahf at torproject.org>
Date:   Fri Mar 10 13:00:20 2017 +0100

    Add periodic timer for expiring old onion keys.
    
    This patch adds a new timer that is executed when it is time to expire
    our current set of old onion keys. Because of proposal #274 this can no
    longer be assumed to be at the same time we rotate our onion keys since
    they will be updated less frequently.
    
    See: https://bugs.torproject.org/21641
---
 changes/bug21641 |  5 +++++
 src/or/main.c    | 29 +++++++++++++++++++++++++++++
 src/or/router.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
 src/or/router.h  |  1 +
 4 files changed, 80 insertions(+)

diff --git a/changes/bug21641 b/changes/bug21641
new file mode 100644
index 0000000..96fdf5f
--- /dev/null
+++ b/changes/bug21641
@@ -0,0 +1,5 @@
+  o Minor feature (defaults, directory):
+    - Onion key rotation and expiry intervals are now defined as a network
+      consensus parameter as per proposal #274. The default lifetime of an
+      onion key is bumped from 7 to 28 days. Old onion keys will expire after 7
+      days by default. Fixes bug #21641.
diff --git a/src/or/main.c b/src/or/main.c
index 107a484..d24c674 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1161,6 +1161,7 @@ static int periodic_events_initialized = 0;
 #define CALLBACK(name) \
   static int name ## _callback(time_t, const or_options_t *)
 CALLBACK(rotate_onion_key);
+CALLBACK(check_onion_keys_expiry_time);
 CALLBACK(check_ed_keys);
 CALLBACK(launch_descriptor_fetches);
 CALLBACK(rotate_x509_certificate);
@@ -1192,6 +1193,7 @@ CALLBACK(heartbeat);
 
 static periodic_event_item_t periodic_events[] = {
   CALLBACK(rotate_onion_key),
+  CALLBACK(check_onion_keys_expiry_time),
   CALLBACK(check_ed_keys),
   CALLBACK(launch_descriptor_fetches),
   CALLBACK(rotate_x509_certificate),
@@ -1499,6 +1501,33 @@ rotate_onion_key_callback(time_t now, const or_options_t *options)
   return PERIODIC_EVENT_NO_UPDATE;
 }
 
+/* Period callback: Check if our old onion keys are still valid after the
+ * period of time defined by the consensus parameter
+ * "onion-key-grace-period-days", otherwise expire them by setting them to
+ * NULL.
+ */
+static int
+check_onion_keys_expiry_time_callback(time_t now, const or_options_t *options)
+{
+  if (server_mode(options)) {
+    int onion_key_grace_period = get_onion_key_grace_period();
+    time_t expiry_time = get_onion_key_set_at()+onion_key_grace_period;
+
+    if (expiry_time > now) {
+      return safe_timer_diff(now, expiry_time);
+    }
+
+    log_info(LD_GENERAL, "Expiring old onion keys.");
+
+    expire_old_onion_keys();
+    cpuworkers_rotate_keyinfo();
+
+    return onion_key_grace_period;
+  }
+
+  return PERIODIC_EVENT_NO_UPDATE;
+}
+
 /* Periodic callback: Every 30 seconds, check whether it's time to make new
  * Ed25519 subkeys.
  */
diff --git a/src/or/router.c b/src/or/router.c
index 2985753..dd869d2 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -148,6 +148,51 @@ dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last)
   tor_mutex_release(key_lock);
 }
 
+/** Expire our old set of onion keys. This is done by setting
+ * last_curve25519_onion_key and lastonionkey to all zero's and NULL
+ * respectively.
+ *
+ * This function does not perform any grace period checks for the old onion
+ * keys.
+ */
+void
+expire_old_onion_keys(void)
+{
+  char *fname = NULL;
+
+  tor_mutex_acquire(key_lock);
+
+  /* Free lastonionkey and set it to NULL. */
+  if (lastonionkey) {
+    crypto_pk_free(lastonionkey);
+    lastonionkey = NULL;
+  }
+
+  /* We zero out the keypair. See the tor_mem_is_zero() check made in
+   * construct_ntor_key_map() below. */
+  memset(&last_curve25519_onion_key, 0, sizeof(last_curve25519_onion_key));
+
+  tor_mutex_release(key_lock);
+
+  fname = get_datadir_fname2("keys", "secret_onion_key.old");
+  if (file_status(fname) == FN_FILE) {
+    if (tor_unlink(fname) != 0) {
+      log_warn(LD_FS, "Couldn't unlink old onion key file %s: %s",
+               fname, strerror(errno));
+    }
+  }
+  tor_free(fname);
+
+  fname = get_datadir_fname2("keys", "secret_onion_key_ntor.old");
+  if (file_status(fname) == FN_FILE) {
+    if (tor_unlink(fname) != 0) {
+      log_warn(LD_FS, "Couldn't unlink old ntor onion key file %s: %s",
+               fname, strerror(errno));
+    }
+  }
+  tor_free(fname);
+}
+
 /** Return the current secret onion key for the ntor handshake. Must only
  * be called from the main thread. */
 static const curve25519_keypair_t *
diff --git a/src/or/router.h b/src/or/router.h
index 55a3927..a02488f 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -27,6 +27,7 @@ crypto_pk_t *get_my_v3_authority_signing_key(void);
 authority_cert_t *get_my_v3_legacy_cert(void);
 crypto_pk_t *get_my_v3_legacy_signing_key(void);
 void dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last);
+void expire_old_onion_keys(void);
 void rotate_onion_key(void);
 crypto_pk_t *init_key_from_file(const char *fname, int generate,
                                     int severity, int log_greeting);





More information about the tor-commits mailing list