[or-cvs] end-to-end integrity checking now works

Roger Dingledine arma at seul.org
Wed Dec 17 05:58:33 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	circuit.c cpuworker.c onion.c 
Log Message:
end-to-end integrity checking now works
initialize digests from shared secrets at handshake
make circuit_send_next_onion_skin use connection_edge_send_command


Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -d -r1.121 -r1.122
--- circuit.c	16 Dec 2003 22:56:49 -0000	1.121
+++ circuit.c	17 Dec 2003 05:58:30 -0000	1.122
@@ -83,6 +83,10 @@
     crypto_free_cipher_env(circ->n_crypto);
   if (circ->p_crypto)
     crypto_free_cipher_env(circ->p_crypto);
+  if (circ->n_digest)
+    crypto_free_digest_env(circ->n_digest);
+  if (circ->p_digest)
+    crypto_free_digest_env(circ->p_digest);
   if(circ->build_state)
     tor_free(circ->build_state->chosen_exit);
   tor_free(circ->build_state);
@@ -309,6 +313,7 @@
 
   crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
   crypto_digest_get_digest(digest, (char *)&integrity, 4);
+  log_fn(LOG_DEBUG,"Putting digest of %u into relay cell.",integrity);
   SET_CELL_RELAY_INTEGRITY(*cell, integrity);
 }
 
@@ -319,6 +324,7 @@
   uint32_t received_integrity, calculated_integrity;
 
   received_integrity = CELL_RELAY_INTEGRITY(*cell);
+  log_fn(LOG_DEBUG,"Reading digest of %u from relay cell.",received_integrity);
   SET_CELL_RELAY_INTEGRITY(*cell, 0);
 
   crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
@@ -854,6 +860,7 @@
   routerinfo_t *router;
   int r;
   int circ_id_type;
+  char payload[6+ONIONSKIN_CHALLENGE_LEN];
 
   assert(circ && circ->cpath);
 
@@ -899,27 +906,20 @@
     }
     hop = circ->cpath->prev;
 
-    memset(&cell, 0, sizeof(cell_t));
-    cell.command = CELL_RELAY; 
-    cell.circ_id = circ->n_circ_id;
-    SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_EXTEND);
-    SET_CELL_STREAM_ID(cell, ZERO_STREAM);
-    SET_CELL_RELAY_LENGTH(cell, 6+ONIONSKIN_CHALLENGE_LEN);
-
-    *(uint32_t*)(cell.payload+RELAY_HEADER_SIZE) = htonl(hop->addr);
-    *(uint16_t*)(cell.payload+RELAY_HEADER_SIZE+4) = htons(hop->port);
-    if(onion_skin_create(router->onion_pkey, &(hop->handshake_state),
-                         cell.payload+RELAY_HEADER_SIZE+6) < 0) {
+    *(uint32_t*)payload = htonl(hop->addr);
+    *(uint16_t*)(payload+4) = htons(hop->port);
+    if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), payload+6) < 0) {
       log_fn(LOG_WARN,"onion_skin_create failed.");
       return -1;
     }
 
     log_fn(LOG_DEBUG,"Sending extend relay cell.");
-    /* send it to hop->prev, because it will transfer it to a create cell and then send to hop */
-    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, hop->prev) < 0) {
-      log_fn(LOG_WARN,"failed to deliver extend cell. Closing.");
-      return -1;
-    }
+    /* send it to hop->prev, because it will transfer
+     * it to a create cell and then send to hop */
+    if(connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTEND,
+                               payload, sizeof(payload), hop->prev) < 0)
+      return -1; /* circuit is closed */
+
     hop->state = CPATH_STATE_AWAITING_KEYS;
   }
   return 0;
@@ -987,7 +987,7 @@
 
 int circuit_finish_handshake(circuit_t *circ, char *reply) {
   unsigned char iv[16];
-  unsigned char keys[32];
+  unsigned char keys[40+32];
   crypt_path_t *hop;
 
   memset(iv, 0, 16);
@@ -1006,7 +1006,7 @@
   }
   assert(hop->state == CPATH_STATE_AWAITING_KEYS);
 
-  if(onion_skin_client_handshake(hop->handshake_state, reply, keys, 32) < 0) {
+  if(onion_skin_client_handshake(hop->handshake_state, reply, keys, 40+32) < 0) {
     log_fn(LOG_WARN,"onion_skin_client_handshake failed.");
     return -1;
   }
@@ -1014,16 +1014,22 @@
   crypto_dh_free(hop->handshake_state); /* don't need it anymore */
   hop->handshake_state = NULL;
 
-  log_fn(LOG_DEBUG,"hop %d init cipher forward %u, backward %u.", 
-        (int)hop, (unsigned)*(uint32_t*)keys, (unsigned) *(uint32_t*)(keys+16));
+  log_fn(LOG_INFO,"hop %d init digest forward %u, backward %u.",
+         (int)hop, (unsigned)*(uint32_t*)keys, (unsigned)*(uint32_t*)(keys+20));
+  hop->f_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
+  crypto_digest_add_bytes(hop->f_digest, keys, 20);
+  hop->b_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
+  crypto_digest_add_bytes(hop->b_digest, keys+20, 20);
+
+  log_fn(LOG_DEBUG,"hop %d init cipher forward %u, backward %u.",
+        (int)hop, (unsigned)*(uint32_t*)(keys+40), (unsigned) *(uint32_t*)(keys+40+16));
   if (!(hop->f_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,keys,iv,1))) {
+        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40,iv,1))) {
     log(LOG_WARN,"forward cipher initialization failed.");
     return -1;
   }
-
   if (!(hop->b_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+16,iv,0))) {
+        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40+16,iv,0))) {
     log(LOG_WARN,"backward cipher initialization failed.");
     return -1;
   }
@@ -1135,9 +1141,13 @@
     if (c->cpath) {
       assert(!c->n_crypto);
       assert(!c->p_crypto);
+      assert(!c->n_digest);
+      assert(!c->p_digest);
     } else {
       assert(c->n_crypto);
       assert(c->p_crypto);
+      assert(c->n_digest);
+      assert(c->p_digest);
     }
   }
   if (c->cpath) {

Index: cpuworker.c
===================================================================
RCS file: /home/or/cvsroot/src/or/cpuworker.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cpuworker.c	16 Dec 2003 08:21:58 -0000	1.17
+++ cpuworker.c	17 Dec 2003 05:58:30 -0000	1.18
@@ -10,7 +10,7 @@
 
 #define TAG_LEN 8
 #define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN)
-#define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+32)
+#define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+40+32)
 
 int num_cpuworkers=0;
 int num_cpuworkers_busy=0;
@@ -119,7 +119,7 @@
   int fd;
 
   /* variables for onion processing */
-  unsigned char keys[32];
+  unsigned char keys[40+32];
   unsigned char reply_to_proxy[ONIONSKIN_REPLY_LEN];
   unsigned char buf[LEN_ONION_RESPONSE];
   char tag[TAG_LEN];
@@ -147,7 +147,7 @@
 
     if(question_type == CPUWORKER_TASK_ONION) {
       if(onion_skin_server_handshake(question, get_onion_key(),
-        reply_to_proxy, keys, 32) < 0) {
+        reply_to_proxy, keys, 40+32) < 0) {
         /* failure */
         log_fn(LOG_WARN,"onion_skin_server_handshake failed.");
         memset(buf,0,LEN_ONION_RESPONSE); /* send all zeros for failure */
@@ -157,7 +157,7 @@
         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,32);
+        memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,40+32);
       }
       if(write_all(fd, buf, LEN_ONION_RESPONSE) != LEN_ONION_RESPONSE) {
         log_fn(LOG_ERR,"writing response buf failed. Exiting.");

Index: onion.c
===================================================================
RCS file: /home/or/cvsroot/src/or/onion.c,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -d -r1.113 -r1.114
--- onion.c	16 Dec 2003 09:48:17 -0000	1.113
+++ onion.c	17 Dec 2003 05:58:30 -0000	1.114
@@ -131,16 +131,22 @@
 
   memcpy(cell.payload, payload, ONIONSKIN_REPLY_LEN);
 
-  log_fn(LOG_DEBUG,"init cipher forward %d, backward %d.", *(int*)keys, *(int*)(keys+16));
+  log_fn(LOG_INFO,"init digest forward %d, backward %d.",
+         *(uint32_t*)(keys), *(uint32_t*)(keys+20));
+  circ->n_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
+  crypto_digest_add_bytes(circ->n_digest, keys, 20);
+  circ->p_digest = crypto_new_digest_env(CRYPTO_SHA1_DIGEST);
+  crypto_digest_add_bytes(circ->p_digest, keys+20, 20);
 
+  log_fn(LOG_DEBUG,"init cipher forward %d, backward %d.",
+         *(uint32_t*)(keys+40), *(uint32_t*)(keys+40+16));
   if (!(circ->n_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,keys,iv,0))) {
+        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40,iv,0))) {
     log_fn(LOG_WARN,"Cipher initialization failed (n).");
     return -1;
   }
-
   if (!(circ->p_crypto =
-        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+16,iv,1))) {
+        crypto_create_init_cipher(CIRCUIT_CIPHER,keys+40+16,iv,1))) {
     log_fn(LOG_WARN,"Cipher initialization failed (p).");
     return -1;
   }



More information about the tor-commits mailing list