Loading doc/rend-spec.txt +2 −2 Changes for doc/rend-spec.txt: 2 added lines, 2 removed lines. Original line number Original line Diff line number Diff line Loading @@ -111,7 +111,7 @@ Tor Rendezvous Spec TS A timestamp [4 octets] TS A timestamp [4 octets] NI Number of introduction points [2 octets] NI Number of introduction points [2 octets] Ipt A list of NUL-terminated OR nicknames [variable] Ipt A list of NUL-terminated OR nicknames [variable] SIG Signature of above fields [KL octets] SIG Signature of above fields [variable] KL is the length of PK, in octets. (Currently, KL must be 128.) KL is the length of PK, in octets. (Currently, KL must be 128.) TS is the number of seconds elapsed since Jan 1, 1970. TS is the number of seconds elapsed since Jan 1, 1970. Loading @@ -131,7 +131,7 @@ Tor Rendezvous Spec KL Key length [2 octets] KL Key length [2 octets] PK Bob's public key [KL octets] PK Bob's public key [KL octets] HS Hash of session info [20 octets] HS Hash of session info [20 octets] SIG Signature of above information [KL octets] SIG Signature of above information [variable] To prevent replay attacks, the HS field contains a SHA-1 hash based on the To prevent replay attacks, the HS field contains a SHA-1 hash based on the shared secret KH between Bob's OP and the introduction point, as shared secret KH between Bob's OP and the introduction point, as Loading src/or/circuit.c +38 −6 Changes for src/or/circuit.c: 38 added lines, 6 removed lines. Original line number Original line Diff line number Diff line Loading @@ -88,7 +88,6 @@ void circuit_close_all_marked() } } } } circuit_t *circuit_new(uint16_t p_circ_id, connection_t *p_conn) { circuit_t *circuit_new(uint16_t p_circ_id, connection_t *p_conn) { circuit_t *circ; circuit_t *circ; Loading Loading @@ -307,14 +306,21 @@ circuit_t *circuit_get_newest(connection_t *conn, return NULL; return NULL; } } /* Return the first circuit in global_circuitlist whose rend_service /* Return the first circuit in global_circuitlist after 'start' whose * field is servid and whose purpose is purpose. Returns NULL if no circuit * rend_service field is servid and whose purpose is purpose. Returns * is found. * NULL if no circuit is found. If 'start' is null, begin at the start of * the list. */ */ circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose) circuit_t *circuit_get_next_by_service_and_purpose(circuit_t *start, const char *servid, int purpose) { { circuit_t *circ; circuit_t *circ; for(circ=global_circuitlist; circ; circ = circ->next) { if (start == NULL) circ = global_circuitlist; else circ = start->next; for( ; circ; circ = circ->next) { if (circ->marked_for_close) if (circ->marked_for_close) continue; continue; if (circ->purpose != purpose) if (circ->purpose != purpose) Loading @@ -325,6 +331,21 @@ circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose) return NULL; return NULL; } } /* Return the circuit waiting for a rendezvous with the provided cookie. * Return NULL if no such circuit is found. */ circuit_t *circuit_get_rendezvous(const char *cookie) { circuit_t *circ; for (circ = global_circuitlist; circ; circ = circ->next) { if (! circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_REND_POINT_WAITING && ! memcmp(circ->rend_cookie, cookie, REND_COOKIE_LEN) ) return circ; } return NULL; } #define MIN_SECONDS_BEFORE_EXPIRING_CIRC 10 #define MIN_SECONDS_BEFORE_EXPIRING_CIRC 10 /* circuits that were born at the end of their second might be expired /* circuits that were born at the end of their second might be expired * after 10.1 seconds; circuits born at the beginning might be expired * after 10.1 seconds; circuits born at the beginning might be expired Loading Loading @@ -516,6 +537,17 @@ int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, } } if(!conn) { if(!conn) { if (circ->rend_splice && cell_direction == CELL_DIRECTION_OUT) { assert(circ->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED); assert(circ->rend_splice->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED); cell->circ_id = circ->rend_splice->p_circ_id; if (circuit_receive_relay_cell(cell, circ->rend_splice, CELL_DIRECTION_IN)<0) { log_fn(LOG_WARN, "Error relaying cell across rendezvous; closing circuits"); circuit_mark_for_close(circ); /* XXXX Do this here, or just return -1? */ return -1; } return 0; } log_fn(LOG_WARN,"Didn't recognize cell, but circ stops here! Closing circ."); log_fn(LOG_WARN,"Didn't recognize cell, but circ stops here! Closing circ."); return -1; return -1; } } Loading src/or/or.h +4 −2 Changes for src/or/or.h: 4 added lines, 2 removed lines. Original line number Original line Diff line number Diff line Loading @@ -560,7 +560,7 @@ struct circuit_t { char rend_service[CRYPTO_SHA1_DIGEST_LEN]; char rend_service[CRYPTO_SHA1_DIGEST_LEN]; /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or * S_RENDEZVOUSING or C_ESTABLISH_REND. Filled with zeroes otherwise. * C_ESTABLISH_REND. Filled with zeroes otherwise. */ */ char rend_cookie[REND_COOKIE_LEN]; char rend_cookie[REND_COOKIE_LEN]; Loading Loading @@ -692,7 +692,9 @@ circuit_t *circuit_get_by_circ_id_conn(uint16_t circ_id, connection_t *conn); circuit_t *circuit_get_by_conn(connection_t *conn); circuit_t *circuit_get_by_conn(connection_t *conn); circuit_t *circuit_get_newest(connection_t *conn, circuit_t *circuit_get_newest(connection_t *conn, int must_be_open, int must_be_clean); int must_be_open, int must_be_clean); circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose); circuit_t *circuit_get_next_by_service_and_purpose(circuit_t *circuit, const char *servid, int purpose); circuit_t *circuit_get_rendezvous(const char *cookie); void circuit_expire_building(void); void circuit_expire_building(void); int circuit_count_building(void); int circuit_count_building(void); Loading src/or/rendmid.c +165 −0 Changes for src/or/rendmid.c: 165 added lines, 0 removed lines. Original line number Original line Diff line number Diff line Loading @@ -4,28 +4,193 @@ #include "or.h" #include "or.h" /* Respond to an ESTABLISH_INTRO cell by setting the circuit's purpose and * rendevous service. */ int int rend_mid_establish_intro(circuit_t *circ, char *request, int request_len) rend_mid_establish_intro(circuit_t *circ, char *request, int request_len) { { crypto_pk_env_t *pk = NULL; char buf[20+9]; char expected_digest[20]; char pk_digest[20]; int asn1len; circuit_t *c; if (circ->purpose != CIRCUIT_PURPOSE_INTERMEDIATE) { log_fn(LOG_WARN, "Rejecting ESTABLISH_INTRO on non-intermediate circuit"); goto err; } if (request_len < 22) goto truncated; /* First 2 bytes: length of asn1-encoded key. */ asn1len = get_uint16(request); /* Next asn1len bytes: asn1-encoded key. */ if (request_len < 22+asn1len) goto truncated; pk = crypto_pk_asn1_decode(request+2, asn1len); if (!pk) { log_fn(LOG_WARN, "Couldn't decode public key"); goto err; } /* Next 20 bytes: Hash of handshake_digest | "INTRODUCE" */ memcpy(buf, circ->handshake_digest, 20); memcpy(buf+20, "INTRODUCE", 9); if (crypto_SHA_digest(buf, 29, expected_digest)<0) { log_fn(LOG_WARN, "Error computing digest"); goto err; } if (memcmp(expected_digest, buf+2+asn1len, 20)) { log_fn(LOG_WARN, "Hash of session info was not as expected"); goto err; } /* Rest of body: signature of previous data */ if (crypto_pk_public_checksig_digest(pk, buf, 22+asn1len, buf+22+asn1len, request_len-(22+asn1len))<0) { log_fn(LOG_WARN, "Incorrect signature on ESTABLISH_INTRO cell; rejecting"); goto err; } /* The request is valid. First, compute the hash of Bob's PK.*/ if (crypto_pk_get_digest(pk, pk_digest)<0) { log_fn(LOG_WARN, "Couldn't hash public key."); goto err; } /* Close any other intro circuits with the same pk. */ c = NULL; while ((c = circuit_get_next_by_service_and_purpose( c,pk_digest,CIRCUIT_PURPOSE_INTRO_POINT))) { circuit_mark_for_close(c); } /* Now, set up this circuit. */ circ->purpose = CIRCUIT_PURPOSE_INTRO_POINT; memcpy(circ->rend_service, pk_digest, 20); return 0; return 0; truncated: log_fn(LOG_WARN, "Rejecting truncated ESTABLISH_INTRO cell"); err: if (pk) crypto_free_pk_env(pk); circuit_mark_for_close(circ); return -1; } } /* Process an INTRODUCE1 cell by finding the corresponding introduction * circuit, and relaying the body of the INTRODUCE1 cell inside an * INTRODUCE2 cell. */ int int rend_mid_introduce(circuit_t *circ, char *request, int request_len) rend_mid_introduce(circuit_t *circ, char *request, int request_len) { { circuit_t *intro_circ; if (request_len < 276) { log_fn(LOG_WARN, "Impossibly short INTRODUCE2 cell; dropping."); goto err; } /* The first 20 bytes are all we look at: they have a hash of Bob's PK. */ intro_circ = circuit_get_next_by_service_and_purpose( NULL, request, CIRCUIT_PURPOSE_INTRO_POINT); if (!intro_circ) { log_fn(LOG_WARN, "No introduction circuit matching INTRODUCE2 cell; dropping"); goto err; } /* Great. Now we just relay the cell down the circuit. */ if (connection_edge_send_command(NULL, intro_circ, RELAY_COMMAND_INTRODUCE2, request, request_len, NULL)) { log_fn(LOG_WARN, "Unable to send INTRODUCE2 cell to OP."); goto err; } return 0; return 0; err: circuit_mark_for_close(circ); /* Is this right? */ return -1; } } /* Process an ESTABLISH_RENDEZVOUS cell by settingthe circuit's purpose and * rendezvous cookie. */ int int rend_mid_establish_rendezvous(circuit_t *circ, char *request, int request_len) rend_mid_establish_rendezvous(circuit_t *circ, char *request, int request_len) { { if (circ->purpose != CIRCUIT_PURPOSE_INTERMEDIATE) { log_fn(LOG_WARN, "Tried to establish rendezvous on non-intermediate circuit"); goto err; } if (request_len != REND_COOKIE_LEN) { log_fn(LOG_WARN, "Invalid length on ESTABLISH_RENDEZVOUS"); goto err; } if (circuit_get_rendezvous(request)) { log_fn(LOG_WARN, "Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS"); goto err; } circ->purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING; memcpy(circ->rend_cookie, request, REND_COOKIE_LEN); return 0; return 0; err: circuit_mark_for_close(circ); return -1; } } /* Process a RENDEZVOUS1 cell by looking up the correct rendezvous circuit by its * relaying the cell's body in a RENDEZVOUS2 cell, and connecting the two circuits. */ int int rend_mid_rendezvous(circuit_t *circ, char *request, int request_len) rend_mid_rendezvous(circuit_t *circ, char *request, int request_len) { { circuit_t *rend_circ; if (circ->purpose != CIRCUIT_PURPOSE_INTERMEDIATE) { log_fn(LOG_WARN, "Tried to complete rendezvous on non-intermediate circuit"); goto err; } if (request_len < 20+128+20) { log_fn(LOG_WARN, "Rejecting impossibly short RENDEZVOUS1 cell"); goto err; } rend_circ = circuit_get_rendezvous(request); if (!rend_circ) { log_fn(LOG_WARN, "Rejecting RENDEZVOUS1 cell with unrecognized rendezvous cookie"); goto err; } /* Send the RENDEZVOUS2 cell to Alice. */ if (connection_edge_send_command(NULL, rend_circ, RELAY_COMMAND_RENDEZVOUS2, request+20, request_len-20, NULL)) { log_fn(LOG_WARN, "Unable to send RENDEZVOUS2 cell to OP."); goto err; } /* Join the circuits. */ circ->purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED; rend_circ->purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED; memset(circ->rend_cookie, 0, 20); rend_circ->rend_splice = circ; circ->rend_splice = rend_circ; return 0; return 0; err: circuit_mark_for_close(circ); return -1; } } /* /* Loading src/or/rendservice.c +1 −13 Changes for src/or/rendservice.c: 1 added line, 13 removed lines. Original line number Original line Diff line number Diff line Loading @@ -235,8 +235,7 @@ int rend_service_init_keys(void) return 0; return 0; } } /*DOCDOC*/ static rend_service_t * rend_service_t * rend_service_get_by_pk_digest(const char* digest) rend_service_get_by_pk_digest(const char* digest) { { int i; int i; Loading @@ -253,17 +252,6 @@ rend_service_get_by_pk_digest(const char* digest) * Handle cells * Handle cells ******/ ******/ typedef struct rend_introduction_t { /* Digest of the hidden service's PK. */ char key_digest[20]; /* Nickname of OR running rendezvous point. */ char *rendezvous_point; /* Cookie that we'll use to recognize the rendezvous point. */ char cookie[20]; /* g^xy */ char shared_secret[128]; } rend_introduction_t; /* Respond to an INTRODUCE2 cell by launching a circuit to the chosen /* Respond to an INTRODUCE2 cell by launching a circuit to the chosen * rendezvous points. * rendezvous points. */ */ Loading Loading
doc/rend-spec.txt +2 −2 Changes for doc/rend-spec.txt: 2 added lines, 2 removed lines. Original line number Original line Diff line number Diff line Loading @@ -111,7 +111,7 @@ Tor Rendezvous Spec TS A timestamp [4 octets] TS A timestamp [4 octets] NI Number of introduction points [2 octets] NI Number of introduction points [2 octets] Ipt A list of NUL-terminated OR nicknames [variable] Ipt A list of NUL-terminated OR nicknames [variable] SIG Signature of above fields [KL octets] SIG Signature of above fields [variable] KL is the length of PK, in octets. (Currently, KL must be 128.) KL is the length of PK, in octets. (Currently, KL must be 128.) TS is the number of seconds elapsed since Jan 1, 1970. TS is the number of seconds elapsed since Jan 1, 1970. Loading @@ -131,7 +131,7 @@ Tor Rendezvous Spec KL Key length [2 octets] KL Key length [2 octets] PK Bob's public key [KL octets] PK Bob's public key [KL octets] HS Hash of session info [20 octets] HS Hash of session info [20 octets] SIG Signature of above information [KL octets] SIG Signature of above information [variable] To prevent replay attacks, the HS field contains a SHA-1 hash based on the To prevent replay attacks, the HS field contains a SHA-1 hash based on the shared secret KH between Bob's OP and the introduction point, as shared secret KH between Bob's OP and the introduction point, as Loading
src/or/circuit.c +38 −6 Changes for src/or/circuit.c: 38 added lines, 6 removed lines. Original line number Original line Diff line number Diff line Loading @@ -88,7 +88,6 @@ void circuit_close_all_marked() } } } } circuit_t *circuit_new(uint16_t p_circ_id, connection_t *p_conn) { circuit_t *circuit_new(uint16_t p_circ_id, connection_t *p_conn) { circuit_t *circ; circuit_t *circ; Loading Loading @@ -307,14 +306,21 @@ circuit_t *circuit_get_newest(connection_t *conn, return NULL; return NULL; } } /* Return the first circuit in global_circuitlist whose rend_service /* Return the first circuit in global_circuitlist after 'start' whose * field is servid and whose purpose is purpose. Returns NULL if no circuit * rend_service field is servid and whose purpose is purpose. Returns * is found. * NULL if no circuit is found. If 'start' is null, begin at the start of * the list. */ */ circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose) circuit_t *circuit_get_next_by_service_and_purpose(circuit_t *start, const char *servid, int purpose) { { circuit_t *circ; circuit_t *circ; for(circ=global_circuitlist; circ; circ = circ->next) { if (start == NULL) circ = global_circuitlist; else circ = start->next; for( ; circ; circ = circ->next) { if (circ->marked_for_close) if (circ->marked_for_close) continue; continue; if (circ->purpose != purpose) if (circ->purpose != purpose) Loading @@ -325,6 +331,21 @@ circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose) return NULL; return NULL; } } /* Return the circuit waiting for a rendezvous with the provided cookie. * Return NULL if no such circuit is found. */ circuit_t *circuit_get_rendezvous(const char *cookie) { circuit_t *circ; for (circ = global_circuitlist; circ; circ = circ->next) { if (! circ->marked_for_close && circ->purpose == CIRCUIT_PURPOSE_REND_POINT_WAITING && ! memcmp(circ->rend_cookie, cookie, REND_COOKIE_LEN) ) return circ; } return NULL; } #define MIN_SECONDS_BEFORE_EXPIRING_CIRC 10 #define MIN_SECONDS_BEFORE_EXPIRING_CIRC 10 /* circuits that were born at the end of their second might be expired /* circuits that were born at the end of their second might be expired * after 10.1 seconds; circuits born at the beginning might be expired * after 10.1 seconds; circuits born at the beginning might be expired Loading Loading @@ -516,6 +537,17 @@ int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, } } if(!conn) { if(!conn) { if (circ->rend_splice && cell_direction == CELL_DIRECTION_OUT) { assert(circ->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED); assert(circ->rend_splice->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED); cell->circ_id = circ->rend_splice->p_circ_id; if (circuit_receive_relay_cell(cell, circ->rend_splice, CELL_DIRECTION_IN)<0) { log_fn(LOG_WARN, "Error relaying cell across rendezvous; closing circuits"); circuit_mark_for_close(circ); /* XXXX Do this here, or just return -1? */ return -1; } return 0; } log_fn(LOG_WARN,"Didn't recognize cell, but circ stops here! Closing circ."); log_fn(LOG_WARN,"Didn't recognize cell, but circ stops here! Closing circ."); return -1; return -1; } } Loading
src/or/or.h +4 −2 Changes for src/or/or.h: 4 added lines, 2 removed lines. Original line number Original line Diff line number Diff line Loading @@ -560,7 +560,7 @@ struct circuit_t { char rend_service[CRYPTO_SHA1_DIGEST_LEN]; char rend_service[CRYPTO_SHA1_DIGEST_LEN]; /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or * S_RENDEZVOUSING or C_ESTABLISH_REND. Filled with zeroes otherwise. * C_ESTABLISH_REND. Filled with zeroes otherwise. */ */ char rend_cookie[REND_COOKIE_LEN]; char rend_cookie[REND_COOKIE_LEN]; Loading Loading @@ -692,7 +692,9 @@ circuit_t *circuit_get_by_circ_id_conn(uint16_t circ_id, connection_t *conn); circuit_t *circuit_get_by_conn(connection_t *conn); circuit_t *circuit_get_by_conn(connection_t *conn); circuit_t *circuit_get_newest(connection_t *conn, circuit_t *circuit_get_newest(connection_t *conn, int must_be_open, int must_be_clean); int must_be_open, int must_be_clean); circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose); circuit_t *circuit_get_next_by_service_and_purpose(circuit_t *circuit, const char *servid, int purpose); circuit_t *circuit_get_rendezvous(const char *cookie); void circuit_expire_building(void); void circuit_expire_building(void); int circuit_count_building(void); int circuit_count_building(void); Loading
src/or/rendmid.c +165 −0 Changes for src/or/rendmid.c: 165 added lines, 0 removed lines. Original line number Original line Diff line number Diff line Loading @@ -4,28 +4,193 @@ #include "or.h" #include "or.h" /* Respond to an ESTABLISH_INTRO cell by setting the circuit's purpose and * rendevous service. */ int int rend_mid_establish_intro(circuit_t *circ, char *request, int request_len) rend_mid_establish_intro(circuit_t *circ, char *request, int request_len) { { crypto_pk_env_t *pk = NULL; char buf[20+9]; char expected_digest[20]; char pk_digest[20]; int asn1len; circuit_t *c; if (circ->purpose != CIRCUIT_PURPOSE_INTERMEDIATE) { log_fn(LOG_WARN, "Rejecting ESTABLISH_INTRO on non-intermediate circuit"); goto err; } if (request_len < 22) goto truncated; /* First 2 bytes: length of asn1-encoded key. */ asn1len = get_uint16(request); /* Next asn1len bytes: asn1-encoded key. */ if (request_len < 22+asn1len) goto truncated; pk = crypto_pk_asn1_decode(request+2, asn1len); if (!pk) { log_fn(LOG_WARN, "Couldn't decode public key"); goto err; } /* Next 20 bytes: Hash of handshake_digest | "INTRODUCE" */ memcpy(buf, circ->handshake_digest, 20); memcpy(buf+20, "INTRODUCE", 9); if (crypto_SHA_digest(buf, 29, expected_digest)<0) { log_fn(LOG_WARN, "Error computing digest"); goto err; } if (memcmp(expected_digest, buf+2+asn1len, 20)) { log_fn(LOG_WARN, "Hash of session info was not as expected"); goto err; } /* Rest of body: signature of previous data */ if (crypto_pk_public_checksig_digest(pk, buf, 22+asn1len, buf+22+asn1len, request_len-(22+asn1len))<0) { log_fn(LOG_WARN, "Incorrect signature on ESTABLISH_INTRO cell; rejecting"); goto err; } /* The request is valid. First, compute the hash of Bob's PK.*/ if (crypto_pk_get_digest(pk, pk_digest)<0) { log_fn(LOG_WARN, "Couldn't hash public key."); goto err; } /* Close any other intro circuits with the same pk. */ c = NULL; while ((c = circuit_get_next_by_service_and_purpose( c,pk_digest,CIRCUIT_PURPOSE_INTRO_POINT))) { circuit_mark_for_close(c); } /* Now, set up this circuit. */ circ->purpose = CIRCUIT_PURPOSE_INTRO_POINT; memcpy(circ->rend_service, pk_digest, 20); return 0; return 0; truncated: log_fn(LOG_WARN, "Rejecting truncated ESTABLISH_INTRO cell"); err: if (pk) crypto_free_pk_env(pk); circuit_mark_for_close(circ); return -1; } } /* Process an INTRODUCE1 cell by finding the corresponding introduction * circuit, and relaying the body of the INTRODUCE1 cell inside an * INTRODUCE2 cell. */ int int rend_mid_introduce(circuit_t *circ, char *request, int request_len) rend_mid_introduce(circuit_t *circ, char *request, int request_len) { { circuit_t *intro_circ; if (request_len < 276) { log_fn(LOG_WARN, "Impossibly short INTRODUCE2 cell; dropping."); goto err; } /* The first 20 bytes are all we look at: they have a hash of Bob's PK. */ intro_circ = circuit_get_next_by_service_and_purpose( NULL, request, CIRCUIT_PURPOSE_INTRO_POINT); if (!intro_circ) { log_fn(LOG_WARN, "No introduction circuit matching INTRODUCE2 cell; dropping"); goto err; } /* Great. Now we just relay the cell down the circuit. */ if (connection_edge_send_command(NULL, intro_circ, RELAY_COMMAND_INTRODUCE2, request, request_len, NULL)) { log_fn(LOG_WARN, "Unable to send INTRODUCE2 cell to OP."); goto err; } return 0; return 0; err: circuit_mark_for_close(circ); /* Is this right? */ return -1; } } /* Process an ESTABLISH_RENDEZVOUS cell by settingthe circuit's purpose and * rendezvous cookie. */ int int rend_mid_establish_rendezvous(circuit_t *circ, char *request, int request_len) rend_mid_establish_rendezvous(circuit_t *circ, char *request, int request_len) { { if (circ->purpose != CIRCUIT_PURPOSE_INTERMEDIATE) { log_fn(LOG_WARN, "Tried to establish rendezvous on non-intermediate circuit"); goto err; } if (request_len != REND_COOKIE_LEN) { log_fn(LOG_WARN, "Invalid length on ESTABLISH_RENDEZVOUS"); goto err; } if (circuit_get_rendezvous(request)) { log_fn(LOG_WARN, "Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS"); goto err; } circ->purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING; memcpy(circ->rend_cookie, request, REND_COOKIE_LEN); return 0; return 0; err: circuit_mark_for_close(circ); return -1; } } /* Process a RENDEZVOUS1 cell by looking up the correct rendezvous circuit by its * relaying the cell's body in a RENDEZVOUS2 cell, and connecting the two circuits. */ int int rend_mid_rendezvous(circuit_t *circ, char *request, int request_len) rend_mid_rendezvous(circuit_t *circ, char *request, int request_len) { { circuit_t *rend_circ; if (circ->purpose != CIRCUIT_PURPOSE_INTERMEDIATE) { log_fn(LOG_WARN, "Tried to complete rendezvous on non-intermediate circuit"); goto err; } if (request_len < 20+128+20) { log_fn(LOG_WARN, "Rejecting impossibly short RENDEZVOUS1 cell"); goto err; } rend_circ = circuit_get_rendezvous(request); if (!rend_circ) { log_fn(LOG_WARN, "Rejecting RENDEZVOUS1 cell with unrecognized rendezvous cookie"); goto err; } /* Send the RENDEZVOUS2 cell to Alice. */ if (connection_edge_send_command(NULL, rend_circ, RELAY_COMMAND_RENDEZVOUS2, request+20, request_len-20, NULL)) { log_fn(LOG_WARN, "Unable to send RENDEZVOUS2 cell to OP."); goto err; } /* Join the circuits. */ circ->purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED; rend_circ->purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED; memset(circ->rend_cookie, 0, 20); rend_circ->rend_splice = circ; circ->rend_splice = rend_circ; return 0; return 0; err: circuit_mark_for_close(circ); return -1; } } /* /* Loading
src/or/rendservice.c +1 −13 Changes for src/or/rendservice.c: 1 added line, 13 removed lines. Original line number Original line Diff line number Diff line Loading @@ -235,8 +235,7 @@ int rend_service_init_keys(void) return 0; return 0; } } /*DOCDOC*/ static rend_service_t * rend_service_t * rend_service_get_by_pk_digest(const char* digest) rend_service_get_by_pk_digest(const char* digest) { { int i; int i; Loading @@ -253,17 +252,6 @@ rend_service_get_by_pk_digest(const char* digest) * Handle cells * Handle cells ******/ ******/ typedef struct rend_introduction_t { /* Digest of the hidden service's PK. */ char key_digest[20]; /* Nickname of OR running rendezvous point. */ char *rendezvous_point; /* Cookie that we'll use to recognize the rendezvous point. */ char cookie[20]; /* g^xy */ char shared_secret[128]; } rend_introduction_t; /* Respond to an INTRODUCE2 cell by launching a circuit to the chosen /* Respond to an INTRODUCE2 cell by launching a circuit to the chosen * rendezvous points. * rendezvous points. */ */ Loading