mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Implement response to RENDEZVOUS2 cell.
svn:r1490
This commit is contained in:
parent
b1a8b208ca
commit
04e8dc9026
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user