From 103b8ead40102dd3f50db4f6b8b3353c783b6541 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 1 Apr 2004 20:05:57 +0000 Subject: [PATCH] Finish implementing what-bob-does-on-INTRODUCE2 svn:r1432 --- src/or/circuit.c | 5 ++++- src/or/or.h | 15 +++++++++------ src/or/rendservice.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/or/circuit.c b/src/or/circuit.c index b0ca853a13..584005e016 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 8c343c9d3e..4256296952 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 d0656a2e36..31f0d2600f 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; } /******