[or-cvs] Merge flagday into main branch.

Nick Mathewson nickm at seul.org
Sat Apr 24 22:17:54 UTC 2004


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv30999/src/or

Modified Files:
	config.c connection.c connection_or.c cpuworker.c dirserv.c 
	main.c onion.c or.h router.c routerlist.c test.c 
Log Message:
Merge flagday into main branch.

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.106
retrieving revision 1.107
diff -u -d -r1.106 -r1.107
--- config.c	5 Apr 2004 00:47:47 -0000	1.106
+++ config.c	24 Apr 2004 22:17:50 -0000	1.107
@@ -655,6 +655,10 @@
     log(LOG_WARN,"DirFetchPostPeriod option must be positive.");
     result = -1;
   }
+  if(options->DirFetchPostPeriod > MIN_ONION_KEY_LIFETIME/2) {
+    log(LOG_WARN,"DirFetchPostPeriod is too large; clipping.");
+    options->DirFetchPostPeriod = MIN_ONION_KEY_LIFETIME/2;
+  }
 
   if(options->KeepalivePeriod < 1) {
     log(LOG_WARN,"KeepalivePeriod option must be positive.");

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.195
retrieving revision 1.196
diff -u -d -r1.195 -r1.196
--- connection.c	8 Apr 2004 07:25:54 -0000	1.195
+++ connection.c	24 Apr 2004 22:17:50 -0000	1.196
@@ -116,8 +116,6 @@
 
   if (conn->onion_pkey)
     crypto_free_pk_env(conn->onion_pkey);
-  if (conn->link_pkey)
-    crypto_free_pk_env(conn->link_pkey);
   if (conn->identity_pkey)
     crypto_free_pk_env(conn->identity_pkey);
   tor_free(conn->nickname);

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -d -r1.94 -r1.95
--- connection_or.c	8 Apr 2004 19:49:55 -0000	1.94
+++ connection_or.c	24 Apr 2004 22:17:50 -0000	1.95
@@ -84,7 +84,6 @@
   conn->port = router->or_port;
   conn->receiver_bucket = conn->bandwidth = router->bandwidthburst;
   conn->onion_pkey = crypto_pk_dup_key(router->onion_pkey);
-  conn->link_pkey = crypto_pk_dup_key(router->link_pkey);
   conn->identity_pkey = crypto_pk_dup_key(router->identity_pkey);
   conn->nickname = tor_strdup(router->nickname);
   tor_free(conn->address);
@@ -178,7 +177,6 @@
 }
 
 static int connection_tls_finish_handshake(connection_t *conn) {
-  crypto_pk_env_t *pk;
   routerinfo_t *router;
   char nickname[MAX_NICKNAME_LEN+1];
   connection_t *c;
@@ -203,42 +201,34 @@
     return -1;
   }
   log_fn(LOG_DEBUG, "Other side claims to be '%s'", nickname);
-  pk = tor_tls_verify(conn->tls);
-  if(!pk) {
-    log_fn(LOG_WARN,"Other side '%s' (%s:%d) has a cert but it's invalid. Closing.",
-           nickname, conn->address, conn->port);
+  router = router_get_by_nickname(nickname);
+  if (!router) {
+    log_fn(LOG_INFO, "Unrecognized router with nickname '%s'", nickname);
     return -1;
   }
-  router = router_get_by_link_pk(pk);
-  if (!router) {
-    log_fn(LOG_INFO,"Unrecognized public key from peer '%s' (%s:%d). Closing.",
+  if(tor_tls_verify(conn->tls, router->identity_pkey)<0) {
+    log_fn(LOG_WARN,"Other side '%s' (%s:%d) has a cert but it's invalid. Closing.",
            nickname, conn->address, conn->port);
-    crypto_free_pk_env(pk);
     return -1;
   }
-  if(conn->link_pkey) { /* I initiated this connection. */
-    if(crypto_pk_cmp_keys(conn->link_pkey, pk)) {
-      log_fn(LOG_WARN,"We connected to '%s' (%s:%d) but he gave us a different key. Closing.",
-             nickname, conn->address, conn->port);
-      crypto_free_pk_env(pk);
+  log_fn(LOG_DEBUG,"The router's cert is valid.");
+
+  if (conn->nickname) {
+    /* I initiated this connection. */
+    if (strcmp(conn->nickname, nickname)) {
+      log_fn(options.DirPort ? LOG_WARN : LOG_INFO,
+             "Other side is '%s', but we tried to connect to '%s'",
+             nickname, conn->nickname);
       return -1;
     }
-    log_fn(LOG_DEBUG,"The router's pk matches the one we meant to connect to. Good.");
   } else {
     if((c=connection_exact_get_by_addr_port(router->addr,router->or_port))) {
       log_fn(LOG_INFO,"Router %s is already connected on fd %d. Dropping fd %d.", router->nickname, c->s, conn->s);
-      crypto_free_pk_env(pk);
       return -1;
     }
-    connection_or_init_conn_from_router(conn, router);
-  }
-  crypto_free_pk_env(pk);
-  if (strcmp(conn->nickname, nickname)) {
-    log_fn(options.DirPort ? LOG_WARN : LOG_INFO,
-           "Other side claims to be '%s', but we expected '%s'",
-           nickname, conn->nickname);
-    return -1;
+    connection_or_init_conn_from_router(conn,router);
   }
+
   if (!options.ORPort) { /* If I'm an OP... */
     conn->receiver_bucket = conn->bandwidth = DEFAULT_BANDWIDTH_OP;
   }

Index: cpuworker.c
===================================================================
RCS file: /home/or/cvsroot/src/or/cpuworker.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- cpuworker.c	20 Mar 2004 09:30:30 -0000	1.28
+++ cpuworker.c	24 Apr 2004 22:17:50 -0000	1.29
@@ -12,8 +12,9 @@
 #define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN)
 #define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+40+32)
 
-int num_cpuworkers=0;
-int num_cpuworkers_busy=0;
+static int num_cpuworkers=0;
+static int num_cpuworkers_busy=0;
+static time_t last_rotation_time=0;
 
 int cpuworker_main(void *data);
 static int spawn_cpuworker(void);
@@ -21,6 +22,7 @@
 static void process_pending_task(connection_t *cpuworker);
 
 void cpu_init(void) {
+  last_rotation_time=time(NULL);
   spawn_enough_cpuworkers();
 }
 
@@ -47,6 +49,18 @@
   log_fn(LOG_DEBUG,"onion was from %s:%d, circ_id %d.", inet_ntoa(in), *port, *circ_id);
 }
 
+void cpuworkers_rotate(void)
+{
+  connection_t *cpuworker;
+  while ((cpuworker = connection_get_by_type_state(CONN_TYPE_CPUWORKER,
+                                                   CPUWORKER_STATE_IDLE))) {
+    connection_mark_for_close(cpuworker,0);
+    --num_cpuworkers;
+  }
+  last_rotation_time = time(NULL);
+  spawn_enough_cpuworkers();
+}
+
 int connection_cpu_process_inbuf(connection_t *conn) {
   char success;
   unsigned char buf[LEN_ONION_RESPONSE];
@@ -111,7 +125,13 @@
 done_processing:
   conn->state = CPUWORKER_STATE_IDLE;
   num_cpuworkers_busy--;
-  process_pending_task(conn);
+  if (conn->timestamp_created < last_rotation_time) {
+    connection_mark_for_close(conn,0);
+    num_cpuworkers--;
+    spawn_enough_cpuworkers();
+  } else {
+    process_pending_task(conn);
+  }
   return 0;
 }
 
@@ -126,6 +146,7 @@
   unsigned char reply_to_proxy[ONIONSKIN_REPLY_LEN];
   unsigned char buf[LEN_ONION_RESPONSE];
   char tag[TAG_LEN];
+  crypto_pk_env_t *onion_key = NULL, *last_onion_key = NULL;
 
   close(fdarray[0]); /* this is the side of the socketpair the parent uses */
   fd = fdarray[1]; /* this side is ours */
@@ -133,27 +154,32 @@
   connection_free_all(); /* so the child doesn't hold the parent's fd's open */
 #endif
 
+  /* XXXX WINDOWS lock here. */
+  onion_key = crypto_pk_dup_key(get_onion_key());
+  if (get_previous_onion_key())
+    last_onion_key = crypto_pk_dup_key(get_previous_onion_key());
+
   for(;;) {
 
     if(recv(fd, &question_type, 1, 0) != 1) {
 //      log_fn(LOG_ERR,"read type failed. Exiting.");
       log_fn(LOG_INFO,"cpuworker exiting because tor process died.");
-      spawn_exit();
+      goto end;
     }
     assert(question_type == CPUWORKER_TASK_ONION);
 
     if(read_all(fd, tag, TAG_LEN, 1) != TAG_LEN) {
       log_fn(LOG_ERR,"read tag failed. Exiting.");
-      spawn_exit();
+      goto end;
     }
 
     if(read_all(fd, question, ONIONSKIN_CHALLENGE_LEN, 1) != ONIONSKIN_CHALLENGE_LEN) {
       log_fn(LOG_ERR,"read question failed. Exiting.");
-      spawn_exit();
+      goto end;
     }
 
     if(question_type == CPUWORKER_TASK_ONION) {
-      if(onion_skin_server_handshake(question, get_onion_key(),
+      if(onion_skin_server_handshake(question, onion_key, last_onion_key,
         reply_to_proxy, keys, 40+32) < 0) {
         /* failure */
         log_fn(LOG_WARN,"onion_skin_server_handshake failed.");
@@ -173,6 +199,12 @@
       log_fn(LOG_DEBUG,"finished writing response.");
     }
   }
+ end:
+  if (onion_key)
+    crypto_free_pk_env(onion_key);
+  if (last_onion_key)
+    crypto_free_pk_env(last_onion_key);
+  spawn_exit();
   return 0; /* windows wants this function to return an int */
 }
 
@@ -263,7 +295,7 @@
       return 0;
     }
 
-    if(!cpuworker)
+    if (!cpuworker)
       cpuworker = connection_get_by_type_state(CONN_TYPE_CPUWORKER, CPUWORKER_STATE_IDLE);
 
     assert(cpuworker);

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dirserv.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- dirserv.c	13 Apr 2004 20:06:08 -0000	1.37
+++ dirserv.c	24 Apr 2004 22:17:50 -0000	1.38
@@ -437,8 +437,13 @@
   /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
      signature.
   */
-  if (strlcat(s, "directory-signature\n", maxlen) >= maxlen)
+  if (strlcat(s, "directory-signature ", maxlen) >= maxlen)
+    goto truncated;
+  if (strlcat(s, options.Nickname, maxlen) >= maxlen)
     goto truncated;
+  if (strlcat(s, "\n", maxlen) >= maxlen)
+    goto truncated;
+
 
   if (router_get_dir_hash(s,digest)) {
     log_fn(LOG_WARN,"couldn't compute digest");

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.246
retrieving revision 1.247
diff -u -d -r1.246 -r1.247
--- main.c	20 Apr 2004 17:27:54 -0000	1.246
+++ main.c	24 Apr 2004 22:17:50 -0000	1.247
@@ -53,6 +53,7 @@
 ****************************************************************************/
 
 int connection_add(connection_t *conn) {
+  assert(conn);
 
   if(nfds >= options.MaxConn-1) {
     log_fn(LOG_WARN,"failing because nfds is too high.");
@@ -345,9 +346,38 @@
 static void run_scheduled_events(time_t now) {
   static long time_to_fetch_directory = 0;
   static time_t last_uploaded_services = 0;
+  static time_t last_rotated_certificate = 0;
   int i;
 
-  /* 1. Every DirFetchPostPeriod seconds, we get a new directory and upload
+
+  /* 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
+   *  shut down and restart all cpuworkers, and update the directory if
+   *  necessary.
+   */
+  if (options.ORPort && get_onion_key_set_at()+MIN_ONION_KEY_LIFETIME < now) {
+    rotate_onion_key();
+    cpuworkers_rotate();
+    if (router_rebuild_descriptor()<0) {
+      log_fn(LOG_WARN, "Couldn't rebuild router descriptor");
+    }
+    router_rebuild_descriptor();
+    router_upload_dir_desc_to_dirservers();
+  }
+
+  /* 1b. Every MAX_LINK_KEY_LIFETIME seconds, we change our TLS context. */
+  if (!last_rotated_certificate)
+    last_rotated_certificate = now;
+  if (options.ORPort && last_rotated_certificate+MAX_SSL_KEY_LIFETIME < now) {
+    if (tor_tls_context_new(get_identity_key(), 1, options.Nickname,
+                            MAX_SSL_KEY_LIFETIME) < 0) {
+      log_fn(LOG_WARN, "Error reinitializing TLS context");
+    }
+    last_rotated_certificate = now;
+    /* XXXX We should rotate TLS connections as well; this code doesn't change
+     * XXXX them at all. */
+  }
+
+  /* 1c. Every DirFetchPostPeriod seconds, we get a new directory and upload
    *    our descriptor (if any). */
   if(time_to_fetch_directory < now) {
     /* it's time to fetch a new directory and/or post our descriptor */
@@ -371,6 +401,7 @@
     time_to_fetch_directory = now + options.DirFetchPostPeriod;
   }
 
+
   /* 2. Every second, we examine pending circuits and prune the
    *    ones which have been pending for more than a few seconds.
    *    We do this before step 3, so it can try building more if

Index: onion.c
===================================================================
RCS file: /home/or/cvsroot/src/or/onion.c,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -d -r1.155 -r1.156
--- onion.c	17 Apr 2004 06:34:20 -0000	1.155
+++ onion.c	24 Apr 2004 22:17:50 -0000	1.156
@@ -576,9 +576,6 @@
 [16 bytes] Symmetric key for encrypting blob past RSA
 [112 bytes] g^x part 1 (inside the RSA)
 [16 bytes] g^x part 2 (symmetrically encrypted)
-[ 6 bytes] Meeting point (IP/port)
-[ 8 bytes] Meeting cookie
-[16 bytes] End-to-end authentication [optional]
 
  * Stores the DH private key into handshake_state_out for later completion
  * of the handshake.
@@ -604,7 +601,7 @@
   pkbytes = crypto_pk_keysize(dest_router_key);
   assert(dhbytes == 128);
   assert(pkbytes == 128);
-  challenge = tor_malloc_zero(ONIONSKIN_CHALLENGE_LEN-CIPHER_KEY_LEN);
+  challenge = tor_malloc_zero(DH_KEY_LEN);
 
   if (crypto_dh_get_public(dh, challenge, dhbytes))
     goto err;
@@ -626,8 +623,8 @@
 
   /* set meeting point, meeting cookie, etc here. Leave zero for now. */
   if (crypto_pk_public_hybrid_encrypt(dest_router_key, challenge,
-                                      ONIONSKIN_CHALLENGE_LEN-CIPHER_KEY_LEN,
-                                      onion_skin_out, PK_NO_PADDING, 1)<0)
+                                      DH_KEY_LEN,
+                                  onion_skin_out, PK_PKCS1_OAEP_PADDING, 1)<0)
     goto err;
 
   tor_free(challenge);
@@ -648,6 +645,7 @@
 int
 onion_skin_server_handshake(char *onion_skin, /* ONIONSKIN_CHALLENGE_LEN bytes */
                             crypto_pk_env_t *private_key,
+                            crypto_pk_env_t *prev_private_key,
                             char *handshake_reply_out, /* ONIONSKIN_REPLY_LEN bytes */
                             char *key_out,
                             int key_out_len)
@@ -656,11 +654,28 @@
   crypto_dh_env_t *dh = NULL;
   int len;
   char *key_material=NULL;
+  int i;
+  crypto_pk_env_t *k;
 
-  if (crypto_pk_private_hybrid_decrypt(private_key,
-                                       onion_skin, ONIONSKIN_CHALLENGE_LEN,
-                                       challenge, PK_NO_PADDING)<0)
+  len = -1;
+  for (i=0;i<2;++i) {
+    k = i==0?private_key:prev_private_key;
+    if (!k)
+      break;
+    len = crypto_pk_private_hybrid_decrypt(k,
+                                           onion_skin, ONIONSKIN_CHALLENGE_LEN,
+                                           challenge, PK_PKCS1_OAEP_PADDING);
+    if (len>0)
+      break;
+  }
+  if (len<0) {
+    log_fn(LOG_WARN, "Couldn't decrypt onionskin");
+    goto err;
+  } else if (len != DH_KEY_LEN) {
+    log_fn(LOG_WARN, "Unexpected onionskin length after decryption: %d",
+           len);
     goto err;
+  }
 
   dh = crypto_dh_new();
   if (crypto_dh_get_public(dh, handshake_reply_out, DH_KEY_LEN))

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.322
retrieving revision 1.323
diff -u -d -r1.322 -r1.323
--- or.h	18 Apr 2004 08:38:40 -0000	1.322
+++ or.h	24 Apr 2004 22:17:50 -0000	1.323
@@ -112,6 +112,9 @@
 #define MAX_DNS_ENTRY_AGE (15*60)
 #endif
 
+#define MIN_ONION_KEY_LIFETIME (120*60)
+#define MAX_SSL_KEY_LIFETIME (120*60)
+
 #define CIRC_ID_TYPE_LOWER 0
 #define CIRC_ID_TYPE_HIGHER 1
 
@@ -381,7 +384,6 @@
                   * strdup into this, because free_connection frees it
                   */
   crypto_pk_env_t *onion_pkey; /* public RSA key for the other side's onions */
-  crypto_pk_env_t *link_pkey; /* public RSA key for the other side's TLS */
   crypto_pk_env_t *identity_pkey; /* public RSA key for the other side's signing */
   char *nickname;
 
@@ -445,7 +447,6 @@
   time_t published_on;
 
   crypto_pk_env_t *onion_pkey; /* public RSA key for onions */
-  crypto_pk_env_t *link_pkey;  /* public RSA key for TLS */
   crypto_pk_env_t *identity_pkey;  /* public RSA key for signing */
 
   int is_running;
@@ -492,8 +493,10 @@
 };
 
 #define DH_KEY_LEN DH_BYTES
-#define ONIONSKIN_CHALLENGE_LEN (16+DH_KEY_LEN)
-#define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+20)
+#define ONIONSKIN_CHALLENGE_LEN (PKCS1_OAEP_PADDING_OVERHEAD+\
+                                 CIPHER_KEY_LEN+\
+                                 DH_KEY_LEN)
+#define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+DIGEST_LEN)
 #define REND_COOKIE_LEN DIGEST_LEN
 
 typedef struct crypt_path_t crypt_path_t;
@@ -882,6 +885,7 @@
 /********************************* cpuworker.c *****************************/
 
 void cpu_init(void);
+void cpuworkers_rotate(void);
 int connection_cpu_finished_flushing(connection_t *conn);
 int connection_cpu_process_inbuf(connection_t *conn);
 int cpuworker_main(void *data);
@@ -948,6 +952,7 @@
 
 int onion_skin_server_handshake(char *onion_skin,
                                 crypto_pk_env_t *private_key,
+                                crypto_pk_env_t *prev_private_key,
                                 char *handshake_reply_out,
                                 char *key_out,
                                 int key_out_len);
@@ -964,11 +969,13 @@
 
 void set_onion_key(crypto_pk_env_t *k);
 crypto_pk_env_t *get_onion_key(void);
+crypto_pk_env_t *get_previous_onion_key(void);
+time_t get_onion_key_set_at(void);
 void set_identity_key(crypto_pk_env_t *k);
 crypto_pk_env_t *get_identity_key(void);
-crypto_pk_env_t *get_link_key(void);
 int init_keys(void);
 crypto_pk_env_t *init_key_from_file(const char *fname);
+void rotate_onion_key(void);
 
 void router_retry_connections(void);
 void router_upload_dir_desc_to_dirservers(void);
@@ -989,7 +996,6 @@
                                         char *preferred, char *excluded,
                                         struct smartlist_t *excludedsmartlist);
 routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port);
-routerinfo_t *router_get_by_link_pk(crypto_pk_env_t *pk);
 routerinfo_t *router_get_by_nickname(char *nickname);
 void router_get_routerlist(routerlist_t **prouterlist);
 void routerinfo_free(routerinfo_t *router);

Index: router.c
===================================================================
RCS file: /home/or/cvsroot/src/or/router.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- router.c	8 Apr 2004 20:22:01 -0000	1.26
+++ router.c	24 Apr 2004 22:17:50 -0000	1.27
@@ -11,12 +11,14 @@
 /************************************************************/
 
 /* private keys */
+static time_t onionkey_set_at=0;
 static crypto_pk_env_t *onionkey=NULL;
-static crypto_pk_env_t *linkkey=NULL;
+static crypto_pk_env_t *lastonionkey=NULL;
 static crypto_pk_env_t *identitykey=NULL;
 
 void set_onion_key(crypto_pk_env_t *k) {
   onionkey = k;
+  onionkey_set_at = time(NULL);
 }
 
 crypto_pk_env_t *get_onion_key(void) {
@@ -24,15 +26,12 @@
   return onionkey;
 }
 
-void set_link_key(crypto_pk_env_t *k)
-{
-  linkkey = k;
+crypto_pk_env_t *get_previous_onion_key(void) {
+  return lastonionkey;
 }
 
-crypto_pk_env_t *get_link_key(void)
-{
-  assert(linkkey);
-  return linkkey;
+time_t get_onion_key_set_at(void) {
+  return onionkey_set_at;
 }
 
 void set_identity_key(crypto_pk_env_t *k) {
@@ -46,6 +45,46 @@
 
 /************************************************************/
 
+/* Replace the previous onion key with the current onion key, and generate
+ * a new previous onion key.  Immediately after calling this function,
+ * the OR should:
+ *     a) shedule all previous cpuworker to shut down _after_ processing
+ *        pending work.  (This will cause fresh cpuworkers to be generated.)
+ *     b) generate and upload a fresh routerinfo.
+ */
+void rotate_onion_key(void)
+{
+  char fname[512];
+  crypto_pk_env_t *prkey;
+  sprintf(fname,"%s/keys/onion.key",options.DataDirectory);
+  if (!(prkey = crypto_new_pk_env())) {
+    log(LOG_ERR, "Error creating crypto environment.");
+    goto error;
+  }
+  if (crypto_pk_generate_key(onionkey)) {
+    log(LOG_ERR, "Error generating key: %s", crypto_perror());
+    goto error;
+  }
+  if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
+    log(LOG_ERR, "Couldn't write generated key to %s.", fname);
+    goto error;
+  }
+  if (lastonionkey)
+    crypto_free_pk_env(lastonionkey);
+  /* XXXX WINDOWS on windows, we need to protect this next bit with a lock.
+   */
+  lastonionkey = onionkey;
+  set_onion_key(prkey);
+  if (router_rebuild_descriptor() <0) {
+    goto error;
+  }
+  router_upload_dir_desc_to_dirservers();
+  /* Mark all CPU workers to close. */
+  return;
+ error:
+  log_fn(LOG_WARN, "Couldn't rotate onion key.");
+}
+
 /* Try to read an RSA key from 'fname'.  If 'fname' doesn't exist, create a new
  * RSA key and save it in 'fname'.  Return the read/created key, or NULL on
  * error.
@@ -112,7 +151,7 @@
   /* OP's don't need keys.  Just initialize the TLS context.*/
   if (!options.ORPort) {
     assert(!options.DirPort);
-    if (tor_tls_context_new(NULL, 0, NULL)<0) {
+    if (tor_tls_context_new(NULL, 0, NULL, 0)<0) {
       log_fn(LOG_ERR, "Error creating TLS context for OP.");
       return -1;
     }
@@ -146,12 +185,10 @@
   set_onion_key(prkey);
 
   /* 3. Initialize link key and TLS context. */
-  strcpy(cp, "/link.key");
-  log_fn(LOG_INFO,"Reading/making link key %s...",keydir);
-  prkey = init_key_from_file(keydir);
-  if (!prkey) return -1;
-  set_link_key(prkey);
-  if (tor_tls_context_new(prkey, 1, options.Nickname) < 0) {
+  /* XXXX use actual rotation interval as cert lifetime, once we do
+   *  connection rotation. */
+  if (tor_tls_context_new(get_identity_key(), 1, options.Nickname,
+                          MAX_SSL_KEY_LIFETIME) < 0) {
     log_fn(LOG_ERR, "Error initializing TLS context");
     return -1;
   }
@@ -370,7 +407,6 @@
   ri->dir_port = options.DirPort;
   ri->published_on = time(NULL);
   ri->onion_pkey = crypto_pk_dup_key(get_onion_key());
-  ri->link_pkey = crypto_pk_dup_key(get_link_key());
   ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
   get_platform_str(platform, sizeof(platform));
   ri->platform = tor_strdup(platform);
@@ -403,13 +439,12 @@
 int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
                                  crypto_pk_env_t *ident_key) {
   char *onion_pkey;
-  char *link_pkey;
   char *identity_pkey;
   struct in_addr in;
   char digest[20];
   char signature[128];
   char published[32];
-  int onion_pkeylen, link_pkeylen, identity_pkeylen;
+  int onion_pkeylen, identity_pkeylen;
   int written;
   int result=0;
   struct exit_policy_t *tmpe;
@@ -436,33 +471,28 @@
     return -1;
   }
 
-  if(crypto_pk_write_public_key_to_string(router->link_pkey,
-                                          &link_pkey,&link_pkeylen)<0) {
-    log_fn(LOG_WARN,"write link_pkey to string failed!");
-    return -1;
-  }
   strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router->published_on));
 
+  /* XXXX eventually, don't include link key */
   result = snprintf(s, maxlen,
-                    "router %s %s %d %d %d %d\n"
+                    "router %s %s %d %d %d\n"
                     "platform %s\n"
                     "published %s\n"
+                    "bandwidth %d %d\n"
                     "onion-key\n%s"
-                    "link-key\n%s"
                     "signing-key\n%s",
     router->nickname,
     router->address,
     router->or_port,
     router->socks_port,
     router->dir_port,
-    (int) router->bandwidthrate,
-/* XXXBC also write bandwidthburst */
     router->platform,
     published,
-    onion_pkey, link_pkey, identity_pkey);
+    (int) router->bandwidthrate,
+    (int) router->bandwidthburst,
+    onion_pkey, identity_pkey);
 
   free(onion_pkey);
-  free(link_pkey);
   free(identity_pkey);
 
   if(result < 0 || result >= maxlen) {

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routerlist.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- routerlist.c	8 Apr 2004 03:21:15 -0000	1.60
+++ routerlist.c	24 Apr 2004 22:17:50 -0000	1.61
@@ -30,7 +30,7 @@
   K_SIGNED_DIRECTORY,
   K_SIGNING_KEY,
   K_ONION_KEY,
-  K_LINK_KEY,
+  K_LINK_KEY, /* XXXX obsolete */
   K_ROUTER_SIGNATURE,
   K_PUBLISHED,
   K_RUNNING_ROUTERS,
@@ -83,7 +83,7 @@
   char *t; int v; arg_syntax s; obj_syntax os; where_syntax ws;
 } token_table[] = {
   { "accept", K_ACCEPT, ARGS, NO_OBJ, RTR_ONLY },
-  { "directory-signature", K_DIRECTORY_SIGNATURE, NO_ARGS, NEED_OBJ, DIR_ONLY},
+  { "directory-signature", K_DIRECTORY_SIGNATURE, ARGS, NEED_OBJ, DIR_ONLY},
   { "reject", K_REJECT, ARGS, NO_OBJ, RTR_ONLY },
   { "router", K_ROUTER, ARGS, NO_OBJ, RTR_ONLY },
   { "recommended-software", K_RECOMMENDED_SOFTWARE, ARGS, NO_OBJ, DIR_ONLY },
@@ -305,21 +305,6 @@
   return NULL;
 }
 
-routerinfo_t *router_get_by_link_pk(crypto_pk_env_t *pk)
-{
-  int i;
-  routerinfo_t *router;
-
-  assert(routerlist);
-
-  for(i=0;i<smartlist_len(routerlist->routers);i++) {
-    router = smartlist_get(routerlist->routers, i);
-    if (0 == crypto_pk_cmp_keys(router->link_pkey, pk))
-      return router;
-  }
-  return NULL;
-}
-
 routerinfo_t *router_get_by_nickname(char *nickname)
 {
   int i;
@@ -354,8 +339,6 @@
   tor_free(router->platform);
   if (router->onion_pkey)
     crypto_free_pk_env(router->onion_pkey);
-  if (router->link_pkey)
-    crypto_free_pk_env(router->link_pkey);
   if (router->identity_pkey)
     crypto_free_pk_env(router->identity_pkey);
   while (router->exit_policy) {
@@ -380,8 +363,6 @@
   r->platform = tor_strdup(r->platform);
   if (r->onion_pkey)
     r->onion_pkey = crypto_pk_dup_key(r->onion_pkey);
-  if (r->link_pkey)
-    r->link_pkey = crypto_pk_dup_key(r->link_pkey);
   if (r->identity_pkey)
     r->identity_pkey = crypto_pk_dup_key(r->identity_pkey);
   e = &r->exit_policy;
@@ -949,10 +930,10 @@
   }
 
   router = tor_malloc_zero(sizeof(routerinfo_t));
-  router->onion_pkey = router->identity_pkey = router->link_pkey = NULL;
+  router->onion_pkey = router->identity_pkey = NULL;
   ports_set = bw_set = 0;
 
-  if (tok->n_args == 2 || tok->n_args == 6) {
+  if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
     router->nickname = tor_strdup(tok->args[0]);
     if (strlen(router->nickname) > MAX_NICKNAME_LEN) {
       log_fn(LOG_WARN,"Router nickname too long.");
@@ -966,15 +947,20 @@
     router->address = tor_strdup(tok->args[1]);
     router->addr = 0;
 
-    if (tok->n_args == 6) {
+    if (tok->n_args >= 5) {
       router->or_port = atoi(tok->args[2]);
       router->socks_port = atoi(tok->args[3]);
       router->dir_port = atoi(tok->args[4]);
-      router->bandwidthrate = atoi(tok->args[5]);
-      ports_set = bw_set = 1;
+      ports_set = 1;
+      /* XXXX Remove this after everyone has moved to 0.0.6 */
+      if (tok->n_args == 6) {
+        router->bandwidthrate = atoi(tok->args[5]);
+        router->bandwidthburst = router->bandwidthrate * 10;
+        bw_set = 1;
+      }
     }
   } else {
-    log_fn(LOG_WARN,"Wrong # of arguments to \"router\"");
+    log_fn(LOG_WARN,"Wrong # of arguments to \"router\" (%d)",tok->n_args);
     goto err;
   }
 
@@ -998,11 +984,12 @@
     log_fn(LOG_WARN,"Redundant bandwidth line");
     goto err;
   } else if (tok) {
-    if (tok->n_args < 1) {
+    if (tok->n_args < 2) {
       log_fn(LOG_WARN,"Not enough arguments to \"bandwidth\"");
       goto err;
     }
     router->bandwidthrate = atoi(tok->args[0]);
+    router->bandwidthburst = atoi(tok->args[1]);
     bw_set = 1;
   }
 
@@ -1020,12 +1007,9 @@
   router->onion_pkey = tok->key;
   tok->key = NULL; /* Prevent free */
 
-  if (!(tok = find_first_by_keyword(tokens, K_LINK_KEY))) {
-    log_fn(LOG_WARN, "Missing onion key"); goto err;
+  if ((tok = find_first_by_keyword(tokens, K_LINK_KEY))) {
+    log_fn(LOG_INFO, "Skipping obsolete link-key"); goto err;
   }
-  /* XXX Check key length */
-  router->link_pkey = tok->key;
-  tok->key = NULL; /* Prevent free */
 
   if (!(tok = find_first_by_keyword(tokens, K_SIGNING_KEY))) {
     log_fn(LOG_WARN, "Missing onion key"); goto err;
@@ -1077,16 +1061,6 @@
     router->platform = tor_strdup("<unknown>");
   }
 
-#if XXXBC
-  router->bandwidthburst = atoi(ARGS[6]);
-  if (!router->bandwidthburst) {
-    log_fn(LOG_WARN,"bandwidthburst unreadable or 0. Failing.");
-    goto err;
-  }
-#else
-  router->bandwidthburst = 10*router->bandwidthrate;
-#endif
-
   log_fn(LOG_DEBUG,"or_port %d, socks_port %d, dir_port %d, bandwidthrate %u, bandwidthburst %u.",
     router->or_port, router->socks_port, router->dir_port,
     (unsigned) router->bandwidthrate, (unsigned) router->bandwidthburst);

Index: test.c
===================================================================
RCS file: /home/or/cvsroot/src/or/test.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -d -r1.81 -r1.82
--- test.c	14 Apr 2004 19:51:57 -0000	1.81
+++ test.c	24 Apr 2004 22:17:50 -0000	1.82
@@ -650,7 +650,7 @@
   /* server handshake */
   memset(s_buf, 0, ONIONSKIN_REPLY_LEN);
   memset(s_keys, 0, 40);
-  test_assert(! onion_skin_server_handshake(c_buf, pk, s_buf, s_keys, 40));
+  test_assert(! onion_skin_server_handshake(c_buf, pk, NULL, s_buf, s_keys, 40));
 
   /* client handshake 2 */
   memset(c_keys, 0, 40);
@@ -701,8 +701,8 @@
   r1.dir_port = 9003;
   r1.onion_pkey = pk1;
   r1.identity_pkey = pk2;
-  r1.link_pkey = pk3;
-  r1.bandwidthrate = r1.bandwidthburst = 1000;
+  r1.bandwidthrate = 1000;
+  r1.bandwidthburst = 5000;
   r1.exit_policy = NULL;
   r1.nickname = "Magri";
   r1.platform = tor_strdup(platform);
@@ -727,7 +727,6 @@
   r2.dir_port = 0;
   r2.onion_pkey = pk2;
   r2.identity_pkey = pk1;
-  r2.link_pkey = pk2;
   r2.bandwidthrate = r2.bandwidthburst = 3000;
   r2.exit_policy = &ex1;
   r2.nickname = "Fred";
@@ -742,15 +741,14 @@
   memset(buf, 0, 2048);
   test_assert(router_dump_router_to_string(buf, 2048, &r1, pk2)>0);
 
-  strcpy(buf2, "router Magri testaddr1.foo.bar 9000 9002 9003 1000\n"
+  strcpy(buf2, "router Magri testaddr1.foo.bar 9000 9002 9003\n"
          "platform Tor "VERSION" on ");
   strcat(buf2, get_uname());
   strcat(buf2, "\n"
          "published 1970-01-01 00:00:00\n"
+         "bandwidth 1000 5000\n"
          "onion-key\n");
   strcat(buf2, pk1_str);
-  strcat(buf2, "link-key\n");
-  strcat(buf2, pk3_str);
   strcat(buf2, "signing-key\n");
   strcat(buf2, pk2_str);
   strcat(buf2, "router-signature\n");
@@ -767,9 +765,8 @@
   test_eq(rp1->socks_port, r1.socks_port);
   test_eq(rp1->dir_port, r1.dir_port);
   test_eq(rp1->bandwidthrate, r1.bandwidthrate);
-//  test_eq(rp1->bandwidthburst, r1.bandwidthburst);
+  test_eq(rp1->bandwidthburst, r1.bandwidthburst);
   test_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0);
-  test_assert(crypto_pk_cmp_keys(rp1->link_pkey, pk3) == 0);
   test_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0);
   test_assert(rp1->exit_policy == NULL);
 
@@ -908,7 +905,7 @@
   test_onion();
   test_onion_handshake();
   puts("\n========================= Directory Formats ===============");
-//  add_stream_log(LOG_DEBUG, NULL, stdout);
+  /* add_stream_log(LOG_DEBUG, NULL, stdout); */
   test_dir_format();
   puts("\n========================= Rendezvous functionality ========");
   test_rend_fns();



More information about the tor-commits mailing list