瀏覽代碼

Massive refactoring of the various handshake types

The three handshake types are now accessed from a unified interface;
their state is abstracted from the rest of the cpath state, and so on.
Nick Mathewson 11 年之前
父節點
當前提交
f58d4dfcd6
共有 17 個文件被更改,包括 462 次插入135 次删除
  1. 68 54
      src/or/circuitbuild.c
  2. 2 1
      src/or/circuitbuild.h
  3. 4 3
      src/or/circuitlist.c
  4. 6 4
      src/or/command.c
  5. 21 19
      src/or/cpuworker.c
  6. 241 2
      src/or/onion.c
  7. 33 0
      src/or/onion.h
  8. 2 0
      src/or/onion_ntor.h
  9. 15 11
      src/or/onion_tap.c
  10. 8 3
      src/or/onion_tap.h
  11. 27 13
      src/or/or.h
  12. 7 7
      src/or/rendclient.c
  13. 4 4
      src/or/rendservice.c
  14. 7 0
      src/or/router.c
  15. 1 0
      src/or/router.h
  16. 9 7
      src/test/bench.c
  17. 7 7
      src/test/test.c

+ 68 - 54
src/or/circuitbuild.c

@@ -27,6 +27,7 @@
 #include "main.h"
 #include "networkstatus.h"
 #include "nodelist.h"
+#include "onion.h"
 #include "onion_tap.h"
 #include "onion_fast.h"
 #include "policies.h"
@@ -54,7 +55,9 @@ static channel_t * channel_connect_for_circuit(const tor_addr_t *addr,
                                                uint16_t port,
                                                const char *id_digest);
 static int circuit_deliver_create_cell(circuit_t *circ,
-                                       uint8_t cell_type, const char *payload);
+                                       uint8_t cell_type,
+                                       const uint8_t *payload,
+                                       size_t payload_len);
 static int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit);
 static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath);
 static int onion_extend_cpath(origin_circuit_t *circ);
@@ -474,7 +477,8 @@ circuit_n_chan_done(channel_t *chan, int status)
         /* pull the create cell out of circ->onionskin, and send it */
         tor_assert(circ->n_chan_onionskin);
         if (circuit_deliver_create_cell(circ,CELL_CREATE,
-                                        circ->n_chan_onionskin)<0) {
+                                        (const uint8_t*)circ->n_chan_onionskin,
+                                        circ->n_chan_onionskin_len)<0) {
           circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
           continue;
         }
@@ -491,12 +495,12 @@ circuit_n_chan_done(channel_t *chan, int status)
  * for the outgoing
  * circuit <b>circ</b>, and deliver a cell of type <b>cell_type</b>
  * (either CELL_CREATE or CELL_CREATE_FAST) with payload <b>payload</b>
- * to this circuit.
+ * to this circuit. DOCDOC payload_len
  * Return -1 if we failed to find a suitable circid, else return 0.
  */
 static int
 circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type,
-                            const char *payload)
+                            const uint8_t *payload, size_t payload_len)
 {
   cell_t cell;
   circid_t id;
@@ -518,7 +522,7 @@ circuit_deliver_create_cell(circuit_t *circ, uint8_t cell_type,
   cell.command = cell_type;
   cell.circ_id = circ->n_circ_id;
 
-  memcpy(cell.payload, payload, ONIONSKIN_CHALLENGE_LEN);
+  memcpy(cell.payload, payload, payload_len);
   append_cell_to_circuit_queue(circ, circ->n_chan, &cell,
                                CELL_DIRECTION_OUT, 0);
 
@@ -611,8 +615,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
 {
   crypt_path_t *hop;
   const node_t *node;
-  char payload[2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN];
-  char *onionskin;
+  uint8_t payload[2+4+DIGEST_LEN+MAX_ONIONSKIN_CHALLENGE_LEN];
+  uint8_t *onionskin;
+  uint16_t handshake_type;
+  int onionskin_len;
   size_t payload_len;
 
   tor_assert(circ);
@@ -633,30 +639,29 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
        * send an old slow create cell.
        */
       cell_type = CELL_CREATE;
-      if (onion_skin_create(circ->cpath->extend_info->onion_key,
-                            &(circ->cpath->dh_handshake_state),
-                            payload) < 0) {
-        log_warn(LD_CIRC,"onion_skin_create (first hop) failed.");
-        return - END_CIRC_REASON_INTERNAL;
-      }
+      handshake_type = ONION_HANDSHAKE_TYPE_TAP;
       note_request("cell: create", 1);
     } else {
       /* We are not an OR, and we're building the first hop of a circuit to a
        * new OR: we can be speedy and use CREATE_FAST to save an RSA operation
        * and a DH operation. */
       cell_type = CELL_CREATE_FAST;
-
-      memset(payload, 0, sizeof(payload));
-      if (fast_onionskin_create(&circ->cpath->fast_handshake_state,
-                                (uint8_t *)payload) < 0) {
-        log_warn(LD_CIRC,"onion_skin_create FAST (first hop) failed.");
-        return - END_CIRC_REASON_INTERNAL;
-      }
-
+      handshake_type = ONION_HANDSHAKE_TYPE_FAST;
       note_request("cell: create fast", 1);
     }
 
-    if (circuit_deliver_create_cell(TO_CIRCUIT(circ), cell_type, payload) < 0)
+    memset(payload, 0, sizeof(payload));
+    onionskin_len = onion_skin_create(handshake_type,
+                                      circ->cpath->extend_info,
+                                      &circ->cpath->handshake_state,
+                                      payload);
+    if (onionskin_len < 0) {
+      log_warn(LD_CIRC,"onion_skin_create (first hop) failed.");
+      return - END_CIRC_REASON_INTERNAL;
+    }
+
+    if (circuit_deliver_create_cell(TO_CIRCUIT(circ), cell_type, payload,
+                                    onionskin_len) < 0)
       return - END_CIRC_REASON_RESOURCELIMIT;
 
     circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
@@ -742,12 +747,16 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
     set_uint16(payload+4, htons(hop->extend_info->port));
 
     onionskin = payload+2+4;
-    memcpy(payload+2+4+ONIONSKIN_CHALLENGE_LEN,
+    memcpy(payload+2+4+TAP_ONIONSKIN_CHALLENGE_LEN,
            hop->extend_info->identity_digest, DIGEST_LEN);
-    payload_len = 2+4+ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN;
+    payload_len = 2+4+TAP_ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN;
+
+    handshake_type = ONION_HANDSHAKE_TYPE_TAP;
 
-    if (onion_skin_create(hop->extend_info->onion_key,
-                          &(hop->dh_handshake_state), onionskin) < 0) {
+    if (onion_skin_create(handshake_type,
+                          hop->extend_info,
+                          &hop->handshake_state,
+                          onionskin) < 0) {
       log_warn(LD_CIRC,"onion_skin_create failed.");
       return - END_CIRC_REASON_INTERNAL;
     }
@@ -758,7 +767,8 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
      * it to a create cell and then send to hop */
     if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
                                      RELAY_COMMAND_EXTEND,
-                                     payload, payload_len, hop->prev) < 0)
+                                     (char*)payload, payload_len,
+                                     hop->prev) < 0)
       return 0; /* circuit is closed */
 
     hop->state = CPATH_STATE_AWAITING_KEYS;
@@ -826,7 +836,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
 
   relay_header_unpack(&rh, cell->payload);
 
-  if (rh.length < 4+2+ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN) {
+  if (rh.length < 4+2+TAP_ONIONSKIN_CHALLENGE_LEN+DIGEST_LEN) {
     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
            "Wrong length %d on extend cell. Closing circuit.",
            rh.length);
@@ -837,7 +847,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
   n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4));
   onionskin = (char*) cell->payload+RELAY_HEADER_SIZE+4+2;
   id_digest = (char*) cell->payload+RELAY_HEADER_SIZE+4+2+
-    ONIONSKIN_CHALLENGE_LEN;
+    TAP_ONIONSKIN_CHALLENGE_LEN;
   tor_addr_from_ipv4h(&n_addr, n_addr32);
 
   if (!n_port || !n_addr32) {
@@ -890,8 +900,10 @@ circuit_extend(cell_t *cell, circuit_t *circ)
                                     NULL /*onion_key*/,
                                     &n_addr, n_port);
 
-    circ->n_chan_onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN);
-    memcpy(circ->n_chan_onionskin, onionskin, ONIONSKIN_CHALLENGE_LEN);
+    circ->n_chan_onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN);
+    memcpy(circ->n_chan_onionskin, onionskin, TAP_ONIONSKIN_CHALLENGE_LEN);
+    circ->n_chan_onionskin_len = TAP_ONIONSKIN_CHALLENGE_LEN;
+
     circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT);
 
     if (should_launch) {
@@ -917,7 +929,8 @@ circuit_extend(cell_t *cell, circuit_t *circ)
             "n_chan is %s",
             channel_get_canonical_remote_descr(n_chan));
 
-  if (circuit_deliver_create_cell(circ, CELL_CREATE, onionskin) < 0)
+  if (circuit_deliver_create_cell(circ, CELL_CREATE, (uint8_t*)onionskin,
+                                  TAP_ONIONSKIN_CHALLENGE_LEN) < 0)
     return -1;
   return 0;
 }
@@ -1377,31 +1390,32 @@ circuit_finish_handshake(origin_circuit_t *circ, uint8_t reply_type,
   }
   tor_assert(hop->state == CPATH_STATE_AWAITING_KEYS);
 
-  if (reply_type == CELL_CREATED && hop->dh_handshake_state) {
-    if (onion_skin_client_handshake(hop->dh_handshake_state, (char*)reply,keys,
-                                    DIGEST_LEN*2+CIPHER_KEY_LEN*2) < 0) {
-      log_warn(LD_CIRC,"onion_skin_client_handshake failed.");
+  {
+    uint16_t handshake_type = 0xffff;
+    if (reply_type == CELL_CREATED)
+      handshake_type = ONION_HANDSHAKE_TYPE_TAP;
+    else if (reply_type == CELL_CREATED_FAST)
+      handshake_type = ONION_HANDSHAKE_TYPE_FAST;
+
+    if (handshake_type != hop->handshake_state.tag) {
+      log_warn(LD_PROTOCOL,"CREATED cell onionskin type (%u) did not "
+               "match CREATE cell onionskin type (%u).",
+               (unsigned)handshake_type,
+               (unsigned) hop->handshake_state.tag);
       return -END_CIRC_REASON_TORPROTOCOL;
     }
-    /* Remember hash of g^xy */
-    memcpy(hop->handshake_digest, reply+DH_KEY_LEN, DIGEST_LEN);
-  } else if (reply_type == CELL_CREATED_FAST && !hop->dh_handshake_state) {
-    if (fast_client_handshake(hop->fast_handshake_state, reply,
-                              (uint8_t*)keys,
-                              DIGEST_LEN*2+CIPHER_KEY_LEN*2) < 0) {
-      log_warn(LD_CIRC,"fast_client_handshake failed.");
+
+    if (onion_skin_client_handshake(handshake_type,
+                                    &hop->handshake_state,
+                                    reply,
+                                    (uint8_t*)keys, sizeof(keys),
+                                    (uint8_t*)hop->handshake_digest) < 0) {
+      log_warn(LD_CIRC,"onion_skin_client_handshake failed.");
       return -END_CIRC_REASON_TORPROTOCOL;
     }
-    memcpy(hop->handshake_digest, reply+DIGEST_LEN, DIGEST_LEN);
-  } else {
-    log_warn(LD_PROTOCOL,"CREATED cell type did not match CREATE cell type.");
-    return -END_CIRC_REASON_TORPROTOCOL;
   }
 
-  crypto_dh_free(hop->dh_handshake_state); /* don't need it anymore */
-  hop->dh_handshake_state = NULL;
-
-  memset(hop->fast_handshake_state, 0, sizeof(hop->fast_handshake_state));
+  onion_handshake_state_release(&hop->handshake_state);
 
   if (circuit_init_cpath_crypto(hop, keys, 0)<0) {
     return -END_CIRC_REASON_TORPROTOCOL;
@@ -1470,7 +1484,7 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason)
  */
 int
 onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
-                 const char *keys)
+                 size_t payload_len, const char *keys)
 {
   cell_t cell;
   crypt_path_t *tmp_cpath;
@@ -1484,8 +1498,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
 
   circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN);
 
-  memcpy(cell.payload, payload,
-         cell_type == CELL_CREATED ? ONIONSKIN_REPLY_LEN : DIGEST_LEN*2);
+  memcpy(cell.payload, payload, payload_len);
 
   log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.",
             (unsigned int)get_uint32(keys),
@@ -1502,6 +1515,7 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, const char *payload,
   tmp_cpath->magic = 0;
   tor_free(tmp_cpath);
 
+  /* XXXX Move responsibility for extracting this. */
   if (cell_type == CELL_CREATED)
     memcpy(circ->handshake_digest, cell.payload+DH_KEY_LEN, DIGEST_LEN);
   else

+ 2 - 1
src/or/circuitbuild.h

@@ -35,7 +35,8 @@ int circuit_finish_handshake(origin_circuit_t *circ, uint8_t cell_type,
 int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer,
                       int reason);
 int onionskin_answer(or_circuit_t *circ, uint8_t cell_type,
-                     const char *payload, const char *keys);
+                     const char *payload, size_t payload_len,
+                     const char *keys);
 int circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
                                         int *need_capacity);
 

+ 4 - 3
src/or/circuitlist.c

@@ -744,8 +744,8 @@ circuit_free_cpath_node(crypt_path_t *victim)
   crypto_cipher_free(victim->b_crypto);
   crypto_digest_free(victim->f_digest);
   crypto_digest_free(victim->b_digest);
-  crypto_dh_free(victim->dh_handshake_state);
-  fast_handshake_state_free(victim->fast_handshake_state);
+  onion_handshake_state_release(&victim->handshake_state);
+  crypto_dh_free(victim->rend_dh_handshake_state);
   extend_info_free(victim->extend_info);
 
   memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
@@ -1494,7 +1494,8 @@ assert_cpath_layer_ok(const crypt_path_t *cp)
       tor_assert(cp->b_crypto);
       /* fall through */
     case CPATH_STATE_CLOSED:
-      tor_assert(!cp->dh_handshake_state);
+      /*XXXX Assert that there's no handshake_state either. */
+      tor_assert(!cp->rend_dh_handshake_state);
       break;
     case CPATH_STATE_AWAITING_KEYS:
       /* tor_assert(cp->dh_handshake_state); */

+ 6 - 4
src/or/command.c

@@ -30,6 +30,7 @@
 #include "hibernate.h"
 #include "nodelist.h"
 //#include "onion.h"
+#include "onion_tap.h"
 #include "onion_fast.h"
 #include "relay.h"
 #include "router.h"
@@ -254,8 +255,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
   circ->base_.purpose = CIRCUIT_PURPOSE_OR;
   circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);
   if (cell->command == CELL_CREATE) {
-    char *onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN);
-    memcpy(onionskin, cell->payload, ONIONSKIN_CHALLENGE_LEN);
+    char *onionskin = tor_malloc(TAP_ONIONSKIN_CHALLENGE_LEN);
+    memcpy(onionskin, cell->payload, TAP_ONIONSKIN_CHALLENGE_LEN);
 
     /* hand it off to the cpuworkers, and then return. */
     if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) {
@@ -282,7 +283,8 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
       circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
       return;
     }
-    if (onionskin_answer(circ, CELL_CREATED_FAST, reply, keys)<0) {
+    if (onionskin_answer(circ, CELL_CREATED_FAST, reply, sizeof(reply),
+                         keys)<0) {
       log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing.");
       circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
       return;
@@ -340,7 +342,7 @@ command_process_created_cell(cell_t *cell, channel_t *chan)
     log_debug(LD_OR,
               "Converting created cell to extended relay cell, sending.");
     relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED,
-                                 (char*)cell->payload, ONIONSKIN_REPLY_LEN,
+                                 (char*)cell->payload, TAP_ONIONSKIN_REPLY_LEN,
                                  NULL);
   }
 }

+ 21 - 19
src/or/cpuworker.c

@@ -35,7 +35,7 @@
 #define TAG_LEN 10
 /** How many bytes are sent from the cpuworker back to tor? */
 #define LEN_ONION_RESPONSE \
-  (1+TAG_LEN+ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN)
+  (1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN+CPATH_KEY_MATERIAL_LEN)
 
 /** How many cpuworkers we have running right now. */
 static int num_cpuworkers=0;
@@ -185,7 +185,8 @@ connection_cpu_process_inbuf(connection_t *conn)
     }
     tor_assert(! CIRCUIT_IS_ORIGIN(circ));
     if (onionskin_answer(TO_OR_CIRCUIT(circ), CELL_CREATED, buf+TAG_LEN,
-                         buf+TAG_LEN+ONIONSKIN_REPLY_LEN) < 0) {
+                         TAP_ONIONSKIN_REPLY_LEN,
+                         buf+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN) < 0) {
       log_warn(LD_OR,"onionskin_answer failed. Closing.");
       circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL);
       goto done_processing;
@@ -214,11 +215,11 @@ connection_cpu_process_inbuf(connection_t *conn)
  *   Request format:
  *          Task type           [1 byte, always CPUWORKER_TASK_ONION]
  *          Opaque tag          TAG_LEN
- *          Onionskin challenge ONIONSKIN_CHALLENGE_LEN
+ *          Onionskin challenge TAP_ONIONSKIN_CHALLENGE_LEN
  *   Response format:
  *          Success/failure     [1 byte, boolean.]
  *          Opaque tag          TAG_LEN
- *          Onionskin challenge ONIONSKIN_REPLY_LEN
+ *          Onionskin challenge TAP_ONIONSKIN_REPLY_LEN
  *          Negotiated keys     KEY_LEN*2+DIGEST_LEN*2
  *
  *  (Note: this _should_ be by addr/port, since we're concerned with specific
@@ -227,17 +228,17 @@ connection_cpu_process_inbuf(connection_t *conn)
 static void
 cpuworker_main(void *data)
 {
-  char question[ONIONSKIN_CHALLENGE_LEN];
+  char question[TAP_ONIONSKIN_CHALLENGE_LEN];
   uint8_t question_type;
   tor_socket_t *fdarray = data;
   tor_socket_t fd;
 
   /* variables for onion processing */
   char keys[CPATH_KEY_MATERIAL_LEN];
-  char reply_to_proxy[ONIONSKIN_REPLY_LEN];
+  char reply_to_proxy[MAX_ONIONSKIN_REPLY_LEN];
   char buf[LEN_ONION_RESPONSE];
   char tag[TAG_LEN];
-  crypto_pk_t *onion_key = NULL, *last_onion_key = NULL;
+  server_onion_keys_t onion_keys;
 
   fd = fdarray[1]; /* this side is ours */
 #ifndef TOR_IS_MULTITHREADED
@@ -248,7 +249,7 @@ cpuworker_main(void *data)
 #endif
   tor_free(data);
 
-  dup_onion_keys(&onion_key, &last_onion_key);
+  setup_server_onion_keys(&onion_keys);
 
   for (;;) {
     ssize_t r;
@@ -275,15 +276,18 @@ cpuworker_main(void *data)
       goto end;
     }
 
-    if (read_all(fd, question, ONIONSKIN_CHALLENGE_LEN, 1) !=
-        ONIONSKIN_CHALLENGE_LEN) {
+    if (read_all(fd, question, TAP_ONIONSKIN_CHALLENGE_LEN, 1) !=
+        TAP_ONIONSKIN_CHALLENGE_LEN) {
       log_err(LD_BUG,"read question failed. Exiting.");
       goto end;
     }
 
     if (question_type == CPUWORKER_TASK_ONION) {
-      if (onion_skin_server_handshake(question, onion_key, last_onion_key,
-          reply_to_proxy, keys, CPATH_KEY_MATERIAL_LEN) < 0) {
+      if (onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_TAP,
+                         (const uint8_t*)question,
+                         &onion_keys,
+                         (uint8_t*)reply_to_proxy,
+                         (uint8_t*)keys, CPATH_KEY_MATERIAL_LEN) < 0) {
         /* failure */
         log_debug(LD_OR,"onion_skin_server_handshake failed.");
         *buf = 0; /* indicate failure in first byte */
@@ -295,8 +299,9 @@ cpuworker_main(void *data)
         log_debug(LD_OR,"onion_skin_server_handshake succeeded.");
         buf[0] = 1; /* 1 means success */
         memcpy(buf+1,tag,TAG_LEN);
-        memcpy(buf+1+TAG_LEN,reply_to_proxy,ONIONSKIN_REPLY_LEN);
-        memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,CPATH_KEY_MATERIAL_LEN);
+        memcpy(buf+1+TAG_LEN,reply_to_proxy,TAP_ONIONSKIN_REPLY_LEN);
+        memcpy(buf+1+TAG_LEN+TAP_ONIONSKIN_REPLY_LEN,keys,
+               CPATH_KEY_MATERIAL_LEN);
       }
       if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) {
         log_err(LD_BUG,"writing response buf failed. Exiting.");
@@ -306,10 +311,7 @@ cpuworker_main(void *data)
     }
   }
  end:
-  if (onion_key)
-    crypto_pk_free(onion_key);
-  if (last_onion_key)
-    crypto_pk_free(last_onion_key);
+  release_server_onion_keys(&onion_keys);
   tor_close_socket(fd);
   crypto_thread_cleanup();
   spawn_exit();
@@ -497,7 +499,7 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
     qbuf[0] = CPUWORKER_TASK_ONION;
     connection_write_to_buf(qbuf, 1, cpuworker);
     connection_write_to_buf(tag, sizeof(tag), cpuworker);
-    connection_write_to_buf(onionskin, ONIONSKIN_CHALLENGE_LEN, cpuworker);
+    connection_write_to_buf(onionskin, TAP_ONIONSKIN_CHALLENGE_LEN, cpuworker);
     tor_free(onionskin);
   }
   return 0;

+ 241 - 2
src/or/onion.c

@@ -6,15 +6,19 @@
 
 /**
  * \file onion.c
- * \brief Functions to queue create cells, and handle onionskin
- * parsing and creation.
+ * \brief Functions to queue create cells, handle onionskin
+ * parsing and creation, and wrap the various onionskin types.
  **/
 
 #include "or.h"
 #include "circuitlist.h"
 #include "config.h"
 #include "onion.h"
+#include "onion_fast.h"
+#include "onion_ntor.h"
+#include "onion_tap.h"
 #include "rephist.h"
+#include "router.h"
 
 /** Type for a linked list of circuits that are waiting for a free CPU worker
  * to process a waiting onion handshake. */
@@ -37,6 +41,8 @@ static onion_queue_t *ol_tail=NULL;
 /** Length of ol_list */
 static int ol_length=0;
 
+/* XXXX Check lengths vs MAX_ONIONSKIN_{CHALLENGE,REPLY}_LEN */
+
 /** Add <b>circ</b> to the end of ol_list and return 0, except
  * if ol_list is too long, in which case do nothing and return -1.
  */
@@ -171,3 +177,236 @@ clear_pending_onions(void)
   ol_length = 0;
 }
 
+/* ============================================================ */
+
+/** Fill in a server_onion_keys_t object at <b>keys</b> with all of the keys
+ * and other info we might need to do onion handshakes.  (We make a copy of
+ * our keys for each cpuworker to avoid race conditions with the main thread,
+ * and to avoid locking) */
+void
+setup_server_onion_keys(server_onion_keys_t *keys)
+{
+  memset(keys, 0, sizeof(server_onion_keys_t));
+  memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN);
+  dup_onion_keys(&keys->onion_key, &keys->last_onion_key);
+#ifdef CURVE25519_ENABLED
+  keys->curve25519_key_map = construct_ntor_key_map();
+#endif
+}
+
+/** Release all storage held in <b>keys</b>, but do not free <b>keys</b>
+ * itself (as it's likely to be stack-allocated.) */
+void
+release_server_onion_keys(server_onion_keys_t *keys)
+{
+  if (! keys)
+    return;
+
+  crypto_pk_free(keys->onion_key);
+  crypto_pk_free(keys->last_onion_key);
+#ifdef CURVE25519_ENABLED
+  ntor_key_map_free(keys->curve25519_key_map);
+#endif
+  memset(keys, 0, sizeof(server_onion_keys_t));
+}
+
+/** Release whatever storage is held in <b>state</b>, depending on its
+ * type, and clear its pointer. */
+void
+onion_handshake_state_release(onion_handshake_state_t *state)
+{
+  switch (state->tag) {
+  case ONION_HANDSHAKE_TYPE_TAP:
+    crypto_dh_free(state->u.tap);
+    state->u.tap = NULL;
+    break;
+  case ONION_HANDSHAKE_TYPE_FAST:
+    fast_handshake_state_free(state->u.fast);
+    state->u.fast = NULL;
+    break;
+#ifdef CURVE25519_ENABLED
+  case ONION_HANDSHAKE_TYPE_NTOR:
+    ntor_handshake_state_free(state->u.ntor);
+    state->u.ntor = NULL;
+    break;
+#endif
+  default:
+    log_warn(LD_BUG, "called with unknown handshake state type %d",
+             (int)state->tag);
+    tor_fragile_assert();
+  }
+}
+
+/** Perform the first step of a circuit-creation handshake of type <b>type</b>
+ * (one of ONION_HANDSHAKE_TYPE_*): generate the initial "onion skin" in
+ * <b>onion_skin_out</b>, and store any state information in <b>state_out</b>.
+ * Return -1 on failure, and the length of the onionskin on acceptance.
+ */
+int
+onion_skin_create(int type,
+                  const extend_info_t *node,
+                  onion_handshake_state_t *state_out,
+                  uint8_t *onion_skin_out)
+{
+  int r = -1;
+
+  switch (type) {
+  case ONION_HANDSHAKE_TYPE_TAP:
+    if (!node->onion_key)
+      return -1;
+
+    if (onion_skin_TAP_create(node->onion_key,
+                              &state_out->u.tap,
+                              (char*)onion_skin_out) < 0)
+      return -1;
+
+    r = TAP_ONIONSKIN_CHALLENGE_LEN;
+    break;
+  case ONION_HANDSHAKE_TYPE_FAST:
+    if (fast_onionskin_create(&state_out->u.fast, onion_skin_out) < 0)
+      return -1;
+
+    r = CREATE_FAST_LEN;
+    break;
+  case ONION_HANDSHAKE_TYPE_NTOR:
+#ifdef CURVE25519_ENABLED
+    if (tor_mem_is_zero((const char*)node->curve25519_onion_key.public_key,
+                        CURVE25519_PUBKEY_LEN))
+      return -1;
+    if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
+                               &node->curve25519_onion_key,
+                               &state_out->u.ntor,
+                               onion_skin_out) < 0)
+      return -1;
+
+    r = NTOR_ONIONSKIN_LEN;
+#else
+    return -1;
+#endif
+    break;
+  default:
+    log_warn(LD_BUG, "called with unknown handshake state type %d", type);
+    tor_fragile_assert();
+    r = -1;
+  }
+
+  if (r > 0)
+    state_out->tag = (uint16_t) type;
+
+  return r;
+}
+
+/** Perform the second (server-side) step of a circuit-creation handshake of
+ * type <b>type</b>, responding to the client request in <b>onion_skin</b>
+ * using the keys in <b>keys</b>.  On success, write our response into
+ * <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
+ * in <b>keys_out_len</b>, and return the length of the reply. On failure,
+ * return -1.  */
+int
+onion_skin_server_handshake(int type,
+                      const uint8_t *onion_skin,
+                      const server_onion_keys_t *keys,
+                      uint8_t *reply_out,
+                      uint8_t *keys_out, size_t keys_out_len)
+{
+  int r = -1;
+
+  switch (type) {
+  case ONION_HANDSHAKE_TYPE_TAP:
+    if (onion_skin_TAP_server_handshake((const char*)onion_skin,
+                                        keys->onion_key, keys->last_onion_key,
+                                        (char*)reply_out,
+                                        (char*)keys_out, keys_out_len)<0)
+      return -1;
+    r = TAP_ONIONSKIN_REPLY_LEN;
+    break;
+  case ONION_HANDSHAKE_TYPE_FAST:
+    if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
+      return -1;
+    r = CREATED_FAST_LEN;
+    break;
+  case ONION_HANDSHAKE_TYPE_NTOR:
+#ifdef CURVE25519_ENABLED
+    if (onion_skin_ntor_server_handshake(onion_skin, keys->curve25519_key_map,
+                                         keys->my_identity,
+                                         reply_out, keys_out, keys_out_len)<0)
+      return -1;
+    r = NTOR_REPLY_LEN;
+#else
+    return -1;
+#endif
+    break;
+  default:
+    log_warn(LD_BUG, "called with unknown handshake state type %d", type);
+    tor_fragile_assert();
+    return -1;
+  }
+
+  /* XXXX we should generate the rendezvous nonce stuff too.  Some notes
+   * below */
+    // memcpy(hop->handshake_digest, reply+DH_KEY_LEN, DIGEST_LEN);
+
+    //memcpy(hop->handshake_digest, reply+DIGEST_LEN, DIGEST_LEN);
+
+  return r;
+}
+
+/** Perform the final (client-side) step of a circuit-creation handshake of
+ * type <b>type</b>, using our state in <b>handshake_state</b> and the
+ * server's response in <b>reply</b> On success, generate <b>keys_out_len</b>
+ * bytes worth of key material in <b>keys_out_len</b>, set
+ * <b>rend_authenticator_out</b> to the "KH" field that can be used to
+ * establish introduction points at this hop, and return 0.  On failure,
+ * return -1. */
+int
+onion_skin_client_handshake(int type,
+                      const onion_handshake_state_t *handshake_state,
+                      const uint8_t *reply,
+                      uint8_t *keys_out, size_t keys_out_len,
+                      uint8_t *rend_authenticator_out)
+{
+  if (handshake_state->tag != type)
+    return -1;
+
+  switch (type) {
+  case ONION_HANDSHAKE_TYPE_TAP:
+    if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
+                                        (const char*)reply,
+                                        (char *)keys_out, keys_out_len) < 0)
+      return -1;
+
+    memcpy(rend_authenticator_out, reply+DH_KEY_LEN, DIGEST_LEN);
+
+    return 0;
+  case ONION_HANDSHAKE_TYPE_FAST:
+    if (fast_client_handshake(handshake_state->u.fast, reply,
+                              keys_out, keys_out_len) < 0)
+      return -1;
+
+    memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN);
+    return 0;
+#ifdef CURVE25519_ENABLED
+  case ONION_HANDSHAKE_TYPE_NTOR:
+    {
+      size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
+      uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
+      if (onion_skin_ntor_client_handshake(handshake_state->u.ntor,
+                                           reply,
+                                           keys_tmp, keys_tmp_len) < 0) {
+        tor_free(keys_tmp);
+        return -1;
+      }
+      memcpy(keys_out, keys_tmp, keys_out_len);
+      memcpy(rend_authenticator_out, keys_tmp + keys_out_len, DIGEST_LEN);
+      memwipe(keys_tmp, 0, keys_tmp_len);
+      tor_free(keys_tmp);
+    }
+    return 0;
+#endif
+  default:
+    log_warn(LD_BUG, "called with unknown handshake state type %d", type);
+    tor_fragile_assert();
+    return -1;
+  }
+}
+

+ 33 - 0
src/or/onion.h

@@ -17,5 +17,38 @@ or_circuit_t *onion_next_task(char **onionskin_out);
 void onion_pending_remove(or_circuit_t *circ);
 void clear_pending_onions(void);
 
+typedef struct server_onion_keys_t {
+  uint8_t my_identity[DIGEST_LEN];
+  crypto_pk_t *onion_key;
+  crypto_pk_t *last_onion_key;
+#ifdef CURVE25519_ENABLED
+  di_digest256_map_t *curve25519_key_map;
+#endif
+} server_onion_keys_t;
+
+#define MAX_ONIONSKIN_CHALLENGE_LEN 255
+#define MAX_ONIONSKIN_REPLY_LEN 255
+
+void setup_server_onion_keys(server_onion_keys_t *keys);
+void release_server_onion_keys(server_onion_keys_t *keys);
+
+void onion_handshake_state_release(onion_handshake_state_t *state);
+
+int onion_skin_create(int type,
+                      const extend_info_t *node,
+                      onion_handshake_state_t *state_out,
+                      uint8_t *onion_skin_out);
+int onion_skin_server_handshake(int type,
+                      const uint8_t *onion_skin,
+                      const server_onion_keys_t *keys,
+                      uint8_t *reply_out,
+                      uint8_t *keys_out, size_t key_out_len);
+//                      uint8_t *rend_authenticator_out);
+int onion_skin_client_handshake(int type,
+                      const onion_handshake_state_t *handshake_state,
+                      const uint8_t *reply,
+                      uint8_t *keys_out, size_t key_out_len,
+                      uint8_t *rend_authenticator_out);
+
 #endif
 

+ 2 - 0
src/or/onion_ntor.h

@@ -17,6 +17,7 @@ typedef struct ntor_handshake_state_t ntor_handshake_state_t;
 /** Length of an ntor reply, as sent from server to client. */
 #define NTOR_REPLY_LEN 64
 
+#ifdef CURVE25519_ENABLED
 void ntor_handshake_state_free(ntor_handshake_state_t *state);
 
 int onion_skin_ntor_create(const uint8_t *router_id,
@@ -36,6 +37,7 @@ int onion_skin_ntor_client_handshake(
                              const uint8_t *handshake_reply,
                              uint8_t *key_out,
                              size_t key_out_len);
+#endif
 
 #endif
 

+ 15 - 11
src/or/onion_tap.c

@@ -35,9 +35,9 @@
  * The meeting point/cookies and auth are zeroed out for now.
  */
 int
-onion_skin_create(crypto_pk_t *dest_router_key,
+onion_skin_TAP_create(crypto_pk_t *dest_router_key,
                   crypto_dh_t **handshake_state_out,
-                  char *onion_skin_out) /* ONIONSKIN_CHALLENGE_LEN bytes */
+                  char *onion_skin_out) /* TAP_ONIONSKIN_CHALLENGE_LEN bytes */
 {
   char challenge[DH_KEY_LEN];
   crypto_dh_t *dh = NULL;
@@ -47,7 +47,7 @@ onion_skin_create(crypto_pk_t *dest_router_key,
   tor_assert(handshake_state_out);
   tor_assert(onion_skin_out);
   *handshake_state_out = NULL;
-  memset(onion_skin_out, 0, ONIONSKIN_CHALLENGE_LEN);
+  memset(onion_skin_out, 0, TAP_ONIONSKIN_CHALLENGE_LEN);
 
   if (!(dh = crypto_dh_new(DH_TYPE_CIRCUIT)))
     goto err;
@@ -64,7 +64,7 @@ onion_skin_create(crypto_pk_t *dest_router_key,
 
   /* set meeting point, meeting cookie, etc here. Leave zero for now. */
   if (crypto_pk_public_hybrid_encrypt(dest_router_key, onion_skin_out,
-                                      ONIONSKIN_CHALLENGE_LEN,
+                                      TAP_ONIONSKIN_CHALLENGE_LEN,
                                       challenge, DH_KEY_LEN,
                                       PK_PKCS1_OAEP_PADDING, 1)<0)
     goto err;
@@ -85,14 +85,17 @@ onion_skin_create(crypto_pk_t *dest_router_key,
  * next key_out_len bytes of key material in key_out.
  */
 int
-onion_skin_server_handshake(const char *onion_skin, /*ONIONSKIN_CHALLENGE_LEN*/
+onion_skin_TAP_server_handshake(
+                            /*TAP_ONIONSKIN_CHALLENGE_LEN*/
+                            const char *onion_skin,
                             crypto_pk_t *private_key,
                             crypto_pk_t *prev_private_key,
-                            char *handshake_reply_out, /*ONIONSKIN_REPLY_LEN*/
+                            /*TAP_ONIONSKIN_REPLY_LEN*/
+                            char *handshake_reply_out,
                             char *key_out,
                             size_t key_out_len)
 {
-  char challenge[ONIONSKIN_CHALLENGE_LEN];
+  char challenge[TAP_ONIONSKIN_CHALLENGE_LEN];
   crypto_dh_t *dh = NULL;
   ssize_t len;
   char *key_material=NULL;
@@ -107,8 +110,9 @@ onion_skin_server_handshake(const char *onion_skin, /*ONIONSKIN_CHALLENGE_LEN*/
       break;
     note_crypto_pk_op(DEC_ONIONSKIN);
     len = crypto_pk_private_hybrid_decrypt(k, challenge,
-                                           ONIONSKIN_CHALLENGE_LEN,
-                                           onion_skin, ONIONSKIN_CHALLENGE_LEN,
+                                           TAP_ONIONSKIN_CHALLENGE_LEN,
+                                           onion_skin,
+                                           TAP_ONIONSKIN_CHALLENGE_LEN,
                                            PK_PKCS1_OAEP_PADDING,0);
     if (len>0)
       break;
@@ -175,8 +179,8 @@ onion_skin_server_handshake(const char *onion_skin, /*ONIONSKIN_CHALLENGE_LEN*/
  * After the invocation, call crypto_dh_free on handshake_state.
  */
 int
-onion_skin_client_handshake(crypto_dh_t *handshake_state,
-            const char *handshake_reply, /* ONIONSKIN_REPLY_LEN bytes */
+onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
+            const char *handshake_reply, /* TAP_ONIONSKIN_REPLY_LEN bytes */
             char *key_out,
             size_t key_out_len)
 {

+ 8 - 3
src/or/onion_tap.h

@@ -12,18 +12,23 @@
 #ifndef TOR_ONION_TAP_H
 #define TOR_ONION_TAP_H
 
-int onion_skin_create(crypto_pk_t *router_key,
+#define TAP_ONIONSKIN_CHALLENGE_LEN (PKCS1_OAEP_PADDING_OVERHEAD+\
+                                 CIPHER_KEY_LEN+\
+                                 DH_KEY_LEN)
+#define TAP_ONIONSKIN_REPLY_LEN (DH_KEY_LEN+DIGEST_LEN)
+
+int onion_skin_TAP_create(crypto_pk_t *router_key,
                       crypto_dh_t **handshake_state_out,
                       char *onion_skin_out);
 
-int onion_skin_server_handshake(const char *onion_skin,
+int onion_skin_TAP_server_handshake(const char *onion_skin,
                                 crypto_pk_t *private_key,
                                 crypto_pk_t *prev_private_key,
                                 char *handshake_reply_out,
                                 char *key_out,
                                 size_t key_out_len);
 
-int onion_skin_client_handshake(crypto_dh_t *handshake_state,
+int onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
                                 const char *handshake_reply,
                                 char *key_out,
                                 size_t key_out_len);

+ 27 - 13
src/or/or.h

@@ -1381,6 +1381,7 @@ typedef struct or_connection_t {
 
   or_handshake_state_t *handshake_state; /**< If we are setting this connection
                                           * up, state information to do so. */
+
   time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/
   time_t timestamp_last_added_nonpadding; /** When did we last add a
                                            * non-padding cell to the outbuf? */
@@ -2470,6 +2471,9 @@ typedef struct extend_info_t {
   uint16_t port; /**< OR port. */
   tor_addr_t addr; /**< IP address. */
   crypto_pk_t *onion_key; /**< Current onionskin key. */
+#ifdef CURVE25519_ENABLED
+  curve25519_public_key_t curve25519_onion_key;
+#endif
 } extend_info_t;
 
 /** Certificate for v3 directory protocol: binds long-term authority identity
@@ -2525,6 +2529,19 @@ typedef enum {
 #define CRYPT_PATH_MAGIC 0x70127012u
 
 struct fast_handshake_state_t;
+struct ntor_handshake_state_t;
+#define ONION_HANDSHAKE_TYPE_TAP 0x0000
+#define ONION_HANDSHAKE_TYPE_FAST 0x0001
+#define ONION_HANDSHAKE_TYPE_NTOR 0x0002
+typedef struct {
+  uint16_t tag;
+  union {
+    struct fast_handshake_state_t *fast;
+    crypto_dh_t *tap;
+    struct ntor_handshake_state_t *ntor;
+  } u;
+} onion_handshake_state_t;
+
 /** Holds accounting information for a single step in the layered encryption
  * performed by a circuit.  Used only at the client edge of a circuit. */
 typedef struct crypt_path_t {
@@ -2543,16 +2560,15 @@ typedef struct crypt_path_t {
   /** Digest state for cells heading away from the OR at this step. */
   crypto_digest_t *b_digest;
 
-  /** Current state of Diffie-Hellman key negotiation with the OR at this
+  /** Current state of the handshake as performed with the OR at this
    * step. */
-  crypto_dh_t *dh_handshake_state;
-  /** Current state of 'fast' (non-PK) key negotiation with the OR at this
-   * step. Used to save CPU when TLS is already providing all the
-   * authentication, secrecy, and integrity we need, and we're already
-   * distinguishable from an OR.
-   */
-  struct fast_handshake_state_t *fast_handshake_state;
+  onion_handshake_state_t handshake_state;
+  /** Diffie-hellman handshake state for performing an introduction
+   * operations */
+  crypto_dh_t *rend_dh_handshake_state;
+
   /** Negotiated key material shared with the OR at this step. */
+  /* XXXX RENAME */
   char handshake_digest[DIGEST_LEN];/* KH in tor-spec.txt */
 
   /** Information to extend to the OR at this step. */
@@ -2594,10 +2610,6 @@ typedef struct {
 #define CPATH_KEY_MATERIAL_LEN (20*2+16*2)
 
 #define DH_KEY_LEN DH_BYTES
-#define ONIONSKIN_CHALLENGE_LEN (PKCS1_OAEP_PADDING_OVERHEAD+\
-                                 CIPHER_KEY_LEN+\
-                                 DH_KEY_LEN)
-#define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+DIGEST_LEN)
 
 /** Information used to build a circuit. */
 typedef struct {
@@ -2703,9 +2715,10 @@ typedef struct circuit_t {
    * more. */
   int deliver_window;
 
+  uint8_t n_chan_onionskin_len; /* XXXX MAKE THIS GET USED. */
   /** For storage while n_chan is pending
     * (state CIRCUIT_STATE_CHAN_WAIT). When defined, it is always
-    * length ONIONSKIN_CHALLENGE_LEN. */
+    * length n_chan_onionskin_len */
   char *n_chan_onionskin;
 
   /** When was this circuit created?  We keep this timestamp with a higher
@@ -2965,6 +2978,7 @@ typedef struct or_circuit_t {
   char rend_token[REND_TOKEN_LEN];
 
   /* ???? move to a subtype or adjunct structure? Wastes 20 bytes -NM */
+  /* XXXX rename this. */
   char handshake_digest[DIGEST_LEN]; /**< Stores KH for the handshake. */
 
   /** How many more relay_early cells can we send on this circuit, according

+ 7 - 7
src/or/rendclient.c

@@ -206,12 +206,12 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
     cpath = rendcirc->build_state->pending_final_cpath =
       tor_malloc_zero(sizeof(crypt_path_t));
     cpath->magic = CRYPT_PATH_MAGIC;
-    if (!(cpath->dh_handshake_state = crypto_dh_new(DH_TYPE_REND))) {
+    if (!(cpath->rend_dh_handshake_state = crypto_dh_new(DH_TYPE_REND))) {
       log_warn(LD_BUG, "Internal error: couldn't allocate DH.");
       status = -2;
       goto perm_err;
     }
-    if (crypto_dh_generate_public(cpath->dh_handshake_state)<0) {
+    if (crypto_dh_generate_public(cpath->rend_dh_handshake_state)<0) {
       log_warn(LD_BUG, "Internal error: couldn't generate g^x.");
       status = -2;
       goto perm_err;
@@ -261,7 +261,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
     dh_offset = MAX_NICKNAME_LEN+1+REND_COOKIE_LEN;
   }
 
-  if (crypto_dh_get_public(cpath->dh_handshake_state, tmp+dh_offset,
+  if (crypto_dh_get_public(cpath->rend_dh_handshake_state, tmp+dh_offset,
                            DH_KEY_LEN)<0) {
     log_warn(LD_BUG, "Internal error: couldn't extract g^x.");
     status = -2;
@@ -896,9 +896,9 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
   tor_assert(circ->build_state);
   tor_assert(circ->build_state->pending_final_cpath);
   hop = circ->build_state->pending_final_cpath;
-  tor_assert(hop->dh_handshake_state);
+  tor_assert(hop->rend_dh_handshake_state);
   if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN,
-                               hop->dh_handshake_state, (char*)request,
+                               hop->rend_dh_handshake_state, (char*)request,
                                DH_KEY_LEN,
                                keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
     log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
@@ -914,8 +914,8 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
     goto err;
   }
 
-  crypto_dh_free(hop->dh_handshake_state);
-  hop->dh_handshake_state = NULL;
+  crypto_dh_free(hop->rend_dh_handshake_state);
+  hop->rend_dh_handshake_state = NULL;
 
   /* All is well. Extend the circuit. */
   circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_REND_JOINED);

+ 4 - 4
src/or/rendservice.c

@@ -1378,7 +1378,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
   cpath->magic = CRYPT_PATH_MAGIC;
   launched->build_state->expiry_time = now + MAX_REND_TIMEOUT;
 
-  cpath->dh_handshake_state = dh;
+  cpath->rend_dh_handshake_state = dh;
   dh = NULL;
   if (circuit_init_cpath_crypto(cpath,keys+DIGEST_LEN,1)<0)
     goto err;
@@ -2624,7 +2624,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
 
   /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */
   memcpy(buf, circuit->rend_data->rend_cookie, REND_COOKIE_LEN);
-  if (crypto_dh_get_public(hop->dh_handshake_state,
+  if (crypto_dh_get_public(hop->rend_dh_handshake_state,
                            buf+REND_COOKIE_LEN, DH_KEY_LEN)<0) {
     log_warn(LD_GENERAL,"Couldn't get DH public key.");
     reason = END_CIRC_REASON_INTERNAL;
@@ -2643,8 +2643,8 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
     goto err;
   }
 
-  crypto_dh_free(hop->dh_handshake_state);
-  hop->dh_handshake_state = NULL;
+  crypto_dh_free(hop->rend_dh_handshake_state);
+  hop->rend_dh_handshake_state = NULL;
 
   /* Append the cpath entry. */
   hop->state = CPATH_STATE_OPEN;

+ 7 - 0
src/or/router.c

@@ -1598,6 +1598,13 @@ router_digest_is_me(const char *digest)
           tor_memeq(server_identitykey_digest, digest, DIGEST_LEN));
 }
 
+/** DOCDOC */
+const uint8_t *
+router_get_my_id_digest(void)
+{
+  return (const uint8_t *)server_identitykey_digest;
+}
+
 /** Return true iff I'm a server and <b>digest</b> is equal to
  * my identity digest. */
 int

+ 1 - 0
src/or/router.h

@@ -84,6 +84,7 @@ extrainfo_t *router_get_my_extrainfo(void);
 const char *router_get_my_descriptor(void);
 const char *router_get_descriptor_gen_reason(void);
 int router_digest_is_me(const char *digest);
+const uint8_t *router_get_my_id_digest(void);
 int router_extrainfo_digest_is_me(const char *digest);
 int router_is_me(const routerinfo_t *router);
 int router_fingerprint_is_me(const char *fp);

+ 9 - 7
src/test/bench.c

@@ -110,8 +110,8 @@ bench_onion_TAP(void)
   int i;
   crypto_pk_t *key, *key2;
   uint64_t start, end;
-  char os[ONIONSKIN_CHALLENGE_LEN];
-  char or[ONIONSKIN_REPLY_LEN];
+  char os[TAP_ONIONSKIN_CHALLENGE_LEN];
+  char or[TAP_ONIONSKIN_REPLY_LEN];
   crypto_dh_t *dh_out;
 
   key = crypto_pk_new();
@@ -122,17 +122,18 @@ bench_onion_TAP(void)
   reset_perftime();
   start = perftime();
   for (i = 0; i < iters; ++i) {
-    onion_skin_create(key, &dh_out, os);
+    onion_skin_TAP_create(key, &dh_out, os);
     crypto_dh_free(dh_out);
   }
   end = perftime();
   printf("Client-side, part 1: %f usec.\n", NANOCOUNT(start, end, iters)/1e3);
 
-  onion_skin_create(key, &dh_out, os);
+  onion_skin_TAP_create(key, &dh_out, os);
   start = perftime();
   for (i = 0; i < iters; ++i) {
     char key_out[CPATH_KEY_MATERIAL_LEN];
-    onion_skin_server_handshake(os, key, NULL, or, key_out, sizeof(key_out));
+    onion_skin_TAP_server_handshake(os, key, NULL, or,
+                                    key_out, sizeof(key_out));
   }
   end = perftime();
   printf("Server-side, key guessed right: %f usec\n",
@@ -141,7 +142,8 @@ bench_onion_TAP(void)
   start = perftime();
   for (i = 0; i < iters; ++i) {
     char key_out[CPATH_KEY_MATERIAL_LEN];
-    onion_skin_server_handshake(os, key2, key, or, key_out, sizeof(key_out));
+    onion_skin_TAP_server_handshake(os, key2, key, or,
+                                    key_out, sizeof(key_out));
   }
   end = perftime();
   printf("Server-side, key guessed wrong: %f usec.\n",
@@ -153,7 +155,7 @@ bench_onion_TAP(void)
     char key_out[CPATH_KEY_MATERIAL_LEN];
     int s;
     dh = crypto_dh_dup(dh_out);
-    s = onion_skin_client_handshake(dh, or, key_out, sizeof(key_out));
+    s = onion_skin_TAP_client_handshake(dh, or, key_out, sizeof(key_out));
     tor_assert(s == 0);
   }
   end = perftime();

+ 7 - 7
src/test/test.c

@@ -819,11 +819,11 @@ test_onion_handshake(void)
 {
   /* client-side */
   crypto_dh_t *c_dh = NULL;
-  char c_buf[ONIONSKIN_CHALLENGE_LEN];
+  char c_buf[TAP_ONIONSKIN_CHALLENGE_LEN];
   char c_keys[40];
 
   /* server-side */
-  char s_buf[ONIONSKIN_REPLY_LEN];
+  char s_buf[TAP_ONIONSKIN_REPLY_LEN];
   char s_keys[40];
 
   /* shared */
@@ -832,18 +832,18 @@ test_onion_handshake(void)
   pk = pk_generate(0);
 
   /* client handshake 1. */
-  memset(c_buf, 0, ONIONSKIN_CHALLENGE_LEN);
-  test_assert(! onion_skin_create(pk, &c_dh, c_buf));
+  memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN);
+  test_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
 
   /* server handshake */
-  memset(s_buf, 0, ONIONSKIN_REPLY_LEN);
+  memset(s_buf, 0, TAP_ONIONSKIN_REPLY_LEN);
   memset(s_keys, 0, 40);
-  test_assert(! onion_skin_server_handshake(c_buf, pk, NULL,
+  test_assert(! onion_skin_TAP_server_handshake(c_buf, pk, NULL,
                                             s_buf, s_keys, 40));
 
   /* client handshake 2 */
   memset(c_keys, 0, 40);
-  test_assert(! onion_skin_client_handshake(c_dh, s_buf, c_keys, 40));
+  test_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
 
   if (memcmp(c_keys, s_keys, 40)) {
     puts("Aiiiie");