aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-04-01 20:05:57 +0000
committerNick Mathewson <nickm@torproject.org>2004-04-01 20:05:57 +0000
commit103b8ead40102dd3f50db4f6b8b3353c783b6541 (patch)
treeec142c8e2a2050be3f10c6ae4c90cf9eaed3c51c /src
parent56b3d67149a96ad6d766be19a014d620b99dc34a (diff)
downloadtor-103b8ead40102dd3f50db4f6b8b3353c783b6541.tar
tor-103b8ead40102dd3f50db4f6b8b3353c783b6541.tar.gz
Finish implementing what-bob-does-on-INTRODUCE2
svn:r1432
Diffstat (limited to 'src')
-rw-r--r--src/or/circuit.c5
-rw-r--r--src/or/or.h15
-rw-r--r--src/or/rendservice.c40
3 files changed, 48 insertions, 12 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index b0ca853a1..584005e01 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -127,8 +127,11 @@ void circuit_free(circuit_t *circ) {
crypto_free_digest_env(circ->n_digest);
if (circ->p_digest)
crypto_free_digest_env(circ->p_digest);
- if(circ->build_state)
+ if(circ->build_state) {
tor_free(circ->build_state->chosen_exit);
+ if (circ->build_state->rend_handshake_state)
+ crypto_dh_free(circ->build_state->rend_handshake_state);
+ }
tor_free(circ->build_state);
circuit_free_cpath(circ->cpath);
if (circ->rend_splice) {
diff --git a/src/or/or.h b/src/or/or.h
index 8c343c9d3..425629695 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -491,6 +491,8 @@ typedef struct crypt_path_t crypt_path_t;
typedef struct {
int desired_path_len;
char *chosen_exit; /* nickname of planned exit node */
+ crypto_dh_env_t *rend_handshake_state; /*XXXXDOCDOC*/
+ unsigned char rend_key_material[52]; /*XXXXDOCDOC*/
} cpath_build_state_t;
/* struct for a path (circuit) through the network */
@@ -531,14 +533,15 @@ struct circuit_t {
uint8_t state;
uint8_t purpose;
- /*
- * holds hash of location-hidden service's PK if purpose is INTRO_POINT
- * or S_ESTABLISH_INTRO or S_RENDEZVOUSING;
- * holds y portion of y.onion (zero-padded) if purpose is C_INTRODUCING or
- * C_ESTABLISH_REND, or is a C_GENERAL for a hidden service.
- * filled with zeroes otherwise.
+ /* The field rend_sevice:
+ * holds hash of location-hidden service's PK if purpose is INTRO_POINT
+ * or S_ESTABLISH_INTRO or S_RENDEZVOUSING;
+ * holds y portion of y.onion (zero-padded) if purpose is C_INTRODUCING or
+ * C_ESTABLISH_REND, or is a C_GENERAL for a hidden service.
+ * is filled with zeroes otherwise.
*/
char rend_service[CRYPTO_SHA1_DIGEST_LEN];
+
/* Holds rendezvous cookie if purpose is REND_POINT_WAITING or
* S_RENDEZVOUSING. Filled with zeroes otherwise.
*/
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index d0656a2e3..31f0d2600 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -268,9 +268,12 @@ int
rend_service_introduce(circuit_t *circuit, char *request, int request_len)
{
char *ptr, *rp_nickname, *r_cookie;
- char buf[1024];
+ char buf[RELAY_PAYLOAD_SIZE];
+ char secret[20+2*16]; /* Holds KH, Kf, Kb */
rend_service_t *service;
int len, keylen;
+ crypto_dh_env_t *dh = NULL;
+ circuit_t *launched = NULL;
if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
log_fn(LOG_WARN, "Got an INTRODUCE2 over a non-introduction circuit.");
@@ -315,6 +318,7 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
log_fn(LOG_WARN, "Nickname in INTRODUCE2 cell contains illegal character.");
return -1;
}
+ /* Okay, now we know that the nickname is at the start of the buffer. */
rp_nickname = buf;
++ptr;
len -= (ptr-buf);
@@ -322,14 +326,40 @@ rend_service_introduce(circuit_t *circuit, char *request, int request_len)
log_fn(LOG_WARN, "Bad length for INTRODUCE2 cell.");
return -1;
}
+ r_cookie = ptr;
- /* XXXX 1. Do the DH jumping-jacks, and put our key "someplace".
- * XXXX 2. Store the cell that we will send once we're connected "someplace".
- * XXXX 3. Launch a circuit to rp_nickname.
- * XXXX 4. Once we've build the circuit, send the cell.
+ /* Try DH handshake... */
+ dh = crypto_dh_new();
+ if (!dh || crypto_dh_generate_public(dh)<0) {
+ log_fn(LOG_WARN, "Couldn't build DH state or generate public key");
+ goto err;
+ }
+ if (crypto_dh_compute_secret(dh, ptr+20, 128, secret, 20+16*2)<0) {
+ log_fn(LOG_WARN, "Couldn't complete DH handshake");
+ goto err;
+ }
+
+ /* Launch a circuit to alice's chosen rendezvous point.
*/
+ launched = circuit_launch_new(CIRCUIT_PURPOSE_S_RENDEZVOUSING, rp_nickname);
+ if (!launched) {
+ log_fn(LOG_WARN, "Can't launch circuit to rendezvous point '%s'",
+ rp_nickname);
+ return -1;
+ }
+ assert(launched->build_state);
+ /* Fill in the circuit's state. */
+ memcpy(launched->rend_service, circuit->rend_service,CRYPTO_SHA1_DIGEST_LEN);
+ memcpy(launched->rend_cookie, r_cookie, REND_COOKIE_LEN);
+ memcpy(launched->build_state->rend_key_material, secret, 20+16*2);
+ launched->build_state->rend_handshake_state = dh;
+ dh = NULL;
return 0;
+ err:
+ if (dh) crypto_dh_free(dh);
+ if (launched) circuit_mark_for_close(launched);
+ return -1;
}
/******