[or-cvs] Implement response to RENDEZVOUS2 cell.

Nick Mathewson nickm at seul.org
Mon Apr 5 20:53:52 UTC 2004


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

Modified Files:
	or.h rendclient.c rendservice.c 
Log Message:
Implement response to RENDEZVOUS2 cell.

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.298
retrieving revision 1.299
diff -u -d -r1.298 -r1.299
--- or.h	5 Apr 2004 17:50:59 -0000	1.298
+++ or.h	5 Apr 2004 20:53:49 -0000	1.299
@@ -501,7 +501,7 @@
   int deliver_window;
 };
 
-#define DH_KEY_LEN CRYPTO_DH_SIZE
+#define DH_KEY_LEN DH_BYTES
 #define ONIONSKIN_CHALLENGE_LEN (16+DH_KEY_LEN)
 #define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+20)
 #define REND_COOKIE_LEN DIGEST_LEN
@@ -732,7 +732,7 @@
 int circuit_send_next_onion_skin(circuit_t *circ);
 int circuit_extend(cell_t *cell, circuit_t *circ);
 #define CPATH_KEY_MATERIAL_LEN (20*2+16*2)
-int circuit_init_cpath_crypto(crypt_path_t *cpath, char *key_data);
+int circuit_init_cpath_crypto(crypt_path_t *cpath, char *key_data,int reverse);
 int circuit_finish_handshake(circuit_t *circ, char *reply);
 int circuit_truncated(circuit_t *circ, crypt_path_t *layer);
 

Index: rendclient.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendclient.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- rendclient.c	5 Apr 2004 20:30:53 -0000	1.14
+++ rendclient.c	5 Apr 2004 20:53:50 -0000	1.15
@@ -160,6 +160,10 @@
 rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len)
 {
   connection_t *apconn;
+  crypt_path_t *hop;
+  char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN];
+  char buf[DIGEST_LEN+9];
+  char expected_digest[DIGEST_LEN];
 
   if(circ->purpose != CIRCUIT_PURPOSE_C_REND_READY ||
      !circ->build_state->pending_final_cpath) {
@@ -168,17 +172,49 @@
     return -1;
   }
 
-  /* XXX
-   * take 'request' and 'circ->build_state->pending_final_cpath'
-   * and do the right thing to circ
-   */
+  if (request_len != DH_KEY_LEN+DIGEST_LEN) {
+    log_fn(LOG_WARN,"Incorrect length (%d) on RENDEZVOUS2 cell.",request_len);
+    goto err;
+  }
+
+  /* first DH_KEY_LEN bytes are g^y from bob. Finish the dh handshake...*/
+  assert(circ->build_state && circ->build_state->pending_final_cpath);
+  hop = circ->build_state->pending_final_cpath;
+  assert(hop->handshake_state);
+  if (crypto_dh_compute_secret(hop->handshake_state, request, DH_KEY_LEN,
+                               keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
+    log_fn(LOG_WARN, "Couldn't complete DH handshake");
+    goto err;
+  }
+  /* ... and set up cpath. */
+  if (circuit_init_cpath_crypto(hop, keys+DIGEST_LEN, 0)<0)
+    goto err;
+
+  /* Check whether the digest is right... */
+  memcpy(buf, keys, DIGEST_LEN);
+  memcpy(buf+DIGEST_LEN, "INTRODUCE", 9);
+  if (crypto_digest(buf, DIGEST_LEN+9, expected_digest)) {
+    log_fn(LOG_WARN, "Error computing digest");
+    goto err;
+  }
+  if (memcmp(expected_digest, request+DH_KEY_LEN, DIGEST_LEN)) {
+    log_fn(LOG_WARN, "Incorrect digest of key material");
+    goto err;
+  }
 
+  /* All is well. Extend the circuit. */
   circ->purpose = CIRCUIT_PURPOSE_C_REND_JOINED;
+  onion_append_to_cpath(&circ->cpath, hop);
+  circ->build_state->pending_final_cpath = NULL; /* prevent double-free */
+
   for(apconn = circ->p_streams; apconn; apconn = apconn->next_stream) {
     if(connection_ap_handshake_send_begin(apconn, circ) < 0)
       return -1;
   }
   return 0;
+ err:
+  circuit_mark_for_close(circ);
+  return -1;
 }
 
 /* Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that

Index: rendservice.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendservice.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- rendservice.c	5 Apr 2004 20:34:58 -0000	1.25
+++ rendservice.c	5 Apr 2004 20:53:50 -0000	1.26
@@ -414,7 +414,7 @@
 
   cpath->handshake_state = dh;
   dh = NULL;
-  if (circuit_init_cpath_crypto(cpath,keys+20)<0)
+  if (circuit_init_cpath_crypto(cpath,keys+20,1)<0)
     goto err;
   memcpy(cpath->handshake_digest, keys, 20);
 



More information about the tor-commits mailing list