aboutsummaryrefslogtreecommitdiff
path: root/src/or/rendclient.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-04-05 20:53:50 +0000
committerNick Mathewson <nickm@torproject.org>2004-04-05 20:53:50 +0000
commit04e8dc90262d9ccc5ef6932cfe86feac24fde997 (patch)
tree7f40aa771e57b35abfb4d9e6745cb18c34846899 /src/or/rendclient.c
parentb1a8b208ca9a3fe4c1de1e5e53c32b147937b8f7 (diff)
downloadtor-04e8dc90262d9ccc5ef6932cfe86feac24fde997.tar
tor-04e8dc90262d9ccc5ef6932cfe86feac24fde997.tar.gz
Implement response to RENDEZVOUS2 cell.
svn:r1490
Diffstat (limited to 'src/or/rendclient.c')
-rw-r--r--src/or/rendclient.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index d02e7521f..f7b89ca13 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -160,6 +160,10 @@ int
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 @@ rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request
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