Implement response to RENDEZVOUS2 cell.

svn:r1490
This commit is contained in:
Nick Mathewson 2004-04-05 20:53:50 +00:00
parent b1a8b208ca
commit 04e8dc9026
3 changed files with 43 additions and 7 deletions

View File

@ -501,7 +501,7 @@ struct crypt_path_t {
int deliver_window; 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_CHALLENGE_LEN (16+DH_KEY_LEN)
#define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+20) #define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+20)
#define REND_COOKIE_LEN DIGEST_LEN #define REND_COOKIE_LEN DIGEST_LEN
@ -732,7 +732,7 @@ void circuit_n_conn_open(connection_t *or_conn);
int circuit_send_next_onion_skin(circuit_t *circ); int circuit_send_next_onion_skin(circuit_t *circ);
int circuit_extend(cell_t *cell, circuit_t *circ); int circuit_extend(cell_t *cell, circuit_t *circ);
#define CPATH_KEY_MATERIAL_LEN (20*2+16*2) #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_finish_handshake(circuit_t *circ, char *reply);
int circuit_truncated(circuit_t *circ, crypt_path_t *layer); int circuit_truncated(circuit_t *circ, crypt_path_t *layer);

View File

@ -160,6 +160,10 @@ int
rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len) rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len)
{ {
connection_t *apconn; 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 || if(circ->purpose != CIRCUIT_PURPOSE_C_REND_READY ||
!circ->build_state->pending_final_cpath) { !circ->build_state->pending_final_cpath) {
@ -168,17 +172,49 @@ rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request
return -1; return -1;
} }
/* XXX if (request_len != DH_KEY_LEN+DIGEST_LEN) {
* take 'request' and 'circ->build_state->pending_final_cpath' log_fn(LOG_WARN,"Incorrect length (%d) on RENDEZVOUS2 cell.",request_len);
* and do the right thing to circ 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; 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) { for(apconn = circ->p_streams; apconn; apconn = apconn->next_stream) {
if(connection_ap_handshake_send_begin(apconn, circ) < 0) if(connection_ap_handshake_send_begin(apconn, circ) < 0)
return -1; return -1;
} }
return 0; return 0;
err:
circuit_mark_for_close(circ);
return -1;
} }
/* Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that /* Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that

View File

@ -414,7 +414,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len)
cpath->handshake_state = dh; cpath->handshake_state = dh;
dh = NULL; dh = NULL;
if (circuit_init_cpath_crypto(cpath,keys+20)<0) if (circuit_init_cpath_crypto(cpath,keys+20,1)<0)
goto err; goto err;
memcpy(cpath->handshake_digest, keys, 20); memcpy(cpath->handshake_digest, keys, 20);