Browse Source

r11588@Kushana: nickm | 2006-12-15 02:04:32 -0500
Add a LastRotatedOnionKey variable to the state file, so we can rotate onion keys a week after they change even if we never stay up for a whole week at a time. Should fix bug 368.


svn:r9120

Nick Mathewson 19 years ago
parent
commit
38bd6837db
4 changed files with 25 additions and 3 deletions
  1. 3 0
      ChangeLog
  2. 1 0
      src/or/config.c
  3. 3 1
      src/or/or.h
  4. 18 2
      src/or/router.c

+ 3 - 0
ChangeLog

@@ -43,6 +43,9 @@ Changes in version 0.1.2.5-xxxx - 200?-??-??
       safe.)
       safe.)
     - When generating bandwidth history, round down to the nearest
     - When generating bandwidth history, round down to the nearest
       1k. When storing accounting data, round up to the nearest 1k.
       1k. When storing accounting data, round up to the nearest 1k.
+    - When we're running as a server, remember when we last rotated onion
+      keys, so that we will rotate keys once they're a week old even if we
+      never stay up for a week ourselves.  (Bug 368.)
 
 
   o Controller features:
   o Controller features:
     - Have GETINFO dir/status/* work on hosts with DirPort disabled.
     - Have GETINFO dir/status/* work on hosts with DirPort disabled.

+ 1 - 0
src/or/config.c

@@ -283,6 +283,7 @@ static config_var_t _state_vars[] = {
 
 
   VAR("TorVersion",              STRING,      TorVersion,             NULL),
   VAR("TorVersion",              STRING,      TorVersion,             NULL),
 
 
+  VAR("LastRotatedOnionKey",     ISOTIME,     LastRotatedOnionKey,    NULL),
   VAR("LastWritten",             ISOTIME,     LastWritten,            NULL),
   VAR("LastWritten",             ISOTIME,     LastWritten,            NULL),
 
 
   { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
   { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }

+ 3 - 1
src/or/or.h

@@ -1698,6 +1698,9 @@ typedef struct {
   /** Holds any unrecognized values we found in the state file, in the order
   /** Holds any unrecognized values we found in the state file, in the order
    * in which we found them. */
    * in which we found them. */
   config_line_t *ExtraLines;
   config_line_t *ExtraLines;
+
+  /** When did we last rotate our onion key?  "0" for 'no idea'. */
+  time_t LastRotatedOnionKey;
 } or_state_t;
 } or_state_t;
 
 
 /** Change the next_write time of <b>state</b> to <b>when</b>, unless the
 /** Change the next_write time of <b>state</b> to <b>when</b>, unless the
@@ -2602,7 +2605,6 @@ int rend_mid_rendezvous(or_circuit_t *circ, const char *request,
 
 
 /********************************* router.c ***************************/
 /********************************* router.c ***************************/
 
 
-void set_onion_key(crypto_pk_env_t *k);
 crypto_pk_env_t *get_onion_key(void);
 crypto_pk_env_t *get_onion_key(void);
 time_t get_onion_key_set_at(void);
 time_t get_onion_key_set_at(void);
 void set_identity_key(crypto_pk_env_t *k);
 void set_identity_key(crypto_pk_env_t *k);

+ 18 - 2
src/or/router.c

@@ -35,7 +35,7 @@ static crypto_pk_env_t *identitykey=NULL;
 /** Replace the current onion key with <b>k</b>.  Does not affect lastonionkey;
 /** Replace the current onion key with <b>k</b>.  Does not affect lastonionkey;
  * to update onionkey correctly, call rotate_onion_key().
  * to update onionkey correctly, call rotate_onion_key().
  */
  */
-void
+static void
 set_onion_key(crypto_pk_env_t *k)
 set_onion_key(crypto_pk_env_t *k)
 {
 {
   tor_mutex_acquire(key_lock);
   tor_mutex_acquire(key_lock);
@@ -122,6 +122,8 @@ rotate_onion_key(void)
   char fname[512];
   char fname[512];
   char fname_prev[512];
   char fname_prev[512];
   crypto_pk_env_t *prkey;
   crypto_pk_env_t *prkey;
+  or_state_t *state = get_or_state();
+  time_t now;
   tor_snprintf(fname,sizeof(fname),
   tor_snprintf(fname,sizeof(fname),
            "%s/keys/secret_onion_key",get_options()->DataDirectory);
            "%s/keys/secret_onion_key",get_options()->DataDirectory);
   tor_snprintf(fname_prev,sizeof(fname_prev),
   tor_snprintf(fname_prev,sizeof(fname_prev),
@@ -148,9 +150,11 @@ rotate_onion_key(void)
     crypto_free_pk_env(lastonionkey);
     crypto_free_pk_env(lastonionkey);
   lastonionkey = onionkey;
   lastonionkey = onionkey;
   onionkey = prkey;
   onionkey = prkey;
-  onionkey_set_at = time(NULL);
+  now = time(NULL);
+  state->LastRotatedOnionKey = onionkey_set_at = now;
   tor_mutex_release(key_lock);
   tor_mutex_release(key_lock);
   mark_my_descriptor_dirty();
   mark_my_descriptor_dirty();
+  or_state_mark_dirty(state, now+600);
   return;
   return;
  error:
  error:
   log_warn(LD_GENERAL, "Couldn't rotate onion key.");
   log_warn(LD_GENERAL, "Couldn't rotate onion key.");
@@ -247,6 +251,7 @@ init_keys(void)
   crypto_pk_env_t *prkey;
   crypto_pk_env_t *prkey;
   char digest[20];
   char digest[20];
   or_options_t *options = get_options();
   or_options_t *options = get_options();
+  or_state_t *state = get_or_state();
 
 
   if (!key_lock)
   if (!key_lock)
     key_lock = tor_mutex_new();
     key_lock = tor_mutex_new();
@@ -293,6 +298,17 @@ init_keys(void)
   prkey = init_key_from_file_name_changed(keydir,keydir2);
   prkey = init_key_from_file_name_changed(keydir,keydir2);
   if (!prkey) return -1;
   if (!prkey) return -1;
   set_onion_key(prkey);
   set_onion_key(prkey);
+  if (state->LastRotatedOnionKey > 100) { /* allow for some parsing slop. */
+    onionkey_set_at = state->LastRotatedOnionKey;
+  } else {
+    /* We have no LastRotatedOnionKey set; either we just created the key
+     * or it's a holdover from 0.1.2.4-alpha-dev or earlier.  In either case,
+     * start the clock ticking now so that we will eventually rotate it even
+     * if we don't stay up for a full MIN_ONION_KEY_LIFETIME. */
+    state->LastRotatedOnionKey = time(NULL);
+    or_state_mark_dirty(state, time(NULL)+600);
+  }
+
   tor_snprintf(keydir,sizeof(keydir),"%s/keys/secret_onion_key.old",datadir);
   tor_snprintf(keydir,sizeof(keydir),"%s/keys/secret_onion_key.old",datadir);
   if (file_status(keydir) == FN_FILE) {
   if (file_status(keydir) == FN_FILE) {
     prkey = init_key_from_file(keydir);
     prkey = init_key_from_file(keydir);