diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/channel.c | 67 | ||||
-rw-r--r-- | src/or/channel.h | 21 | ||||
-rw-r--r-- | src/or/channeltls.c | 1 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 21 | ||||
-rw-r--r-- | src/or/connection_or.c | 4 |
5 files changed, 83 insertions, 31 deletions
diff --git a/src/or/channel.c b/src/or/channel.c index af5810788c..d484e71259 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -733,27 +733,62 @@ channel_find_by_global_id(uint64_t global_identifier) return rv; } +/** Return true iff <b>chan</b> matches <b>rsa_id_digest</b> and <b>ed_id</b>. + * as its identity keys. If either is NULL, do not check for a match. */ +static int +channel_remote_identity_matches(const channel_t *chan, + const char *rsa_id_digest, + const ed25519_public_key_t *ed_id) +{ + if (BUG(!chan)) + return 0; + if (rsa_id_digest) { + if (tor_memneq(rsa_id_digest, chan->identity_digest, DIGEST_LEN)) + return 0; + } + if (ed_id) { + if (tor_memneq(ed_id->pubkey, chan->ed25519_identity.pubkey, + ED25519_PUBKEY_LEN)) + return 0; + } + return 1; +} + /** - * Find channel by digest of the remote endpoint + * Find channel by RSA/Ed25519 identity of of the remote endpoint * - * This function looks up a channel by the digest of its remote endpoint in - * the channel digest map. It's possible that more than one channel to a - * given endpoint exists. Use channel_next_with_digest() to walk the list. + * This function looks up a channel by the digest of its remote endpoint's RSA + * identity key. If <b>ed_id</b> is provided and nonzero, only a channel + * matching the <b>ed_id</b> will be returned. + * + * It's possible that more than one channel to a given endpoint exists. Use + * channel_next_with_rsa_identity() to walk the list of channels; make sure + * to test for Ed25519 identity match too (as appropriate) */ - channel_t * -channel_find_by_remote_digest(const char *identity_digest) +channel_find_by_remote_identity(const char *rsa_id_digest, + const ed25519_public_key_t *ed_id) { channel_t *rv = NULL; channel_idmap_entry_t *ent, search; - tor_assert(identity_digest); + tor_assert(rsa_id_digest); /* For now, we require that every channel have + * an RSA identity, and that every lookup + * contain an RSA identity */ + if (ed_id && ed25519_public_key_is_zero(ed_id)) { + /* Treat zero as meaning "We don't care about the presence or absence of + * an Ed key", not "There must be no Ed key". */ + ed_id = NULL; + } - memcpy(search.digest, identity_digest, DIGEST_LEN); + memcpy(search.digest, rsa_id_digest, DIGEST_LEN); ent = HT_FIND(channel_idmap, &channel_identity_map, &search); if (ent) { rv = TOR_LIST_FIRST(&ent->channel_list); } + while (rv && ! channel_remote_identity_matches(rv, rsa_id_digest, ed_id)) { + rv = channel_next_with_rsa_identity(rv); + } return rv; } @@ -766,7 +801,7 @@ channel_find_by_remote_digest(const char *identity_digest) */ channel_t * -channel_next_with_digest(channel_t *chan) +channel_next_with_rsa_identity(channel_t *chan) { tor_assert(chan); @@ -3296,7 +3331,8 @@ channel_is_better(time_t now, channel_t *a, channel_t *b, */ channel_t * -channel_get_for_extend(const char *digest, +channel_get_for_extend(const char *rsa_id_digest, + const ed25519_public_key_t *ed_id, const tor_addr_t *target_addr, const char **msg_out, int *launch_out) @@ -3309,14 +3345,14 @@ channel_get_for_extend(const char *digest, tor_assert(msg_out); tor_assert(launch_out); - chan = channel_find_by_remote_digest(digest); + chan = channel_find_by_remote_identity(rsa_id_digest, ed_id); /* Walk the list, unrefing the old one and refing the new at each * iteration. */ - for (; chan; chan = channel_next_with_digest(chan)) { + for (; chan; chan = channel_next_with_rsa_identity(chan)) { tor_assert(tor_memeq(chan->identity_digest, - digest, DIGEST_LEN)); + rsa_id_digest, DIGEST_LEN)); if (CHANNEL_CONDEMNED(chan)) continue; @@ -3327,6 +3363,11 @@ channel_get_for_extend(const char *digest, continue; } + /* The Ed25519 key has to match too */ + if (!channel_remote_identity_matches(chan, rsa_id_digest, ed_id)) { + continue; + } + /* Never return a non-open connection. */ if (!CHANNEL_IS_OPEN(chan)) { /* If the address matches, don't launch a new connection for this diff --git a/src/or/channel.h b/src/or/channel.h index 7e7b2ec899..2747e52140 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -153,10 +153,16 @@ struct channel_s { int (*write_var_cell)(channel_t *, var_cell_t *); /** - * Hash of the public RSA key for the other side's identity key, or - * zeroes if the other side hasn't shown us a valid identity key. + * Hash of the public RSA key for the other side's RSA identity key, or + * zeroes if the other side hasn't shown us a valid RSA identity key. */ char identity_digest[DIGEST_LEN]; + /** + * The Ed25519 public identity key for the other side, or zeros if the other + * size hasn't shown us a valid Ed25519 identity key + */ + ed25519_public_key_t ed25519_identity; + /** Nickname of the OR on the other side, or NULL if none. */ char *nickname; @@ -489,10 +495,11 @@ int channel_send_destroy(circid_t circ_id, channel_t *chan, */ channel_t * channel_connect(const tor_addr_t *addr, uint16_t port, - const char *id_digest, + const char *rsa_id_digest, const ed25519_public_key_t *ed_id); -channel_t * channel_get_for_extend(const char *digest, +channel_t * channel_get_for_extend(const char *rsa_id_digest, + const ed25519_public_key_t *ed_id, const tor_addr_t *target_addr, const char **msg_out, int *launch_out); @@ -506,11 +513,13 @@ int channel_is_better(time_t now, */ channel_t * channel_find_by_global_id(uint64_t global_identifier); -channel_t * channel_find_by_remote_digest(const char *identity_digest); +channel_t * channel_find_by_remote_identity(const char *rsa_id_digest, + const ed25519_public_key_t *ed_id); /** For things returned by channel_find_by_remote_digest(), walk the list. + * The RSA key will match for all returned elements; the Ed25519 key might not. */ -channel_t * channel_next_with_digest(channel_t *chan); +channel_t * channel_next_with_rsa_identity(channel_t *chan); /* * Helper macros to lookup state of given channel. diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 9fb309d0fd..8384576e68 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -174,7 +174,6 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id) { - (void) ed_id; // XXXX not fully used yet channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan)); channel_t *chan = &(tlschan->base_); diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index e578a94019..9a3af4091e 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -63,8 +63,9 @@ #include "transports.h" static channel_t * channel_connect_for_circuit(const tor_addr_t *addr, - uint16_t port, - const char *id_digest); + uint16_t port, + const char *id_digest, + const ed25519_public_key_t *ed_id); static int circuit_deliver_create_cell(circuit_t *circ, const create_cell_t *create_cell, int relayed); @@ -80,13 +81,12 @@ static int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice); */ static channel_t * channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port, - const char *id_digest) + const char *id_digest, + const ed25519_public_key_t *ed_id) { channel_t *chan; - chan = channel_connect(addr, port, id_digest, - NULL // XXXX Ed25519 id. - ); + chan = channel_connect(addr, port, id_digest, ed_id); if (chan) command_setup_channel(chan); return chan; @@ -556,6 +556,7 @@ circuit_handle_first_hop(origin_circuit_t *circ) firsthop->extend_info->port)); n_chan = channel_get_for_extend(firsthop->extend_info->identity_digest, + &firsthop->extend_info->ed_identity, &firsthop->extend_info->addr, &msg, &should_launch); @@ -573,7 +574,8 @@ circuit_handle_first_hop(origin_circuit_t *circ) n_chan = channel_connect_for_circuit( &firsthop->extend_info->addr, firsthop->extend_info->port, - firsthop->extend_info->identity_digest); + firsthop->extend_info->identity_digest, + &firsthop->extend_info->ed_identity); if (!n_chan) { /* connect failed, forget the whole thing */ log_info(LD_CIRC,"connect to firsthop failed. Closing."); return -END_CIRC_REASON_CONNECTFAILED; @@ -1185,7 +1187,7 @@ circuit_extend(cell_t *cell, circuit_t *circ) } n_chan = channel_get_for_extend((const char*)ec.node_id, - /*&ec.ed25519_id 15056 */ + &ec.ed_pubkey, &ec.orport_ipv4.addr, &msg, &should_launch); @@ -1212,7 +1214,8 @@ circuit_extend(cell_t *cell, circuit_t *circ) /* we should try to open a connection */ n_chan = channel_connect_for_circuit(&ec.orport_ipv4.addr, ec.orport_ipv4.port, - (const char*)ec.node_id); + (const char*)ec.node_id, + &ec.ed_pubkey); if (!n_chan) { log_info(LD_CIRC,"Launching n_chan failed. Closing circuit."); circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index eb67f0653f..e83dca2be4 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -149,7 +149,7 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *rsa_digest, const ed25519_public_key_t *ed_id) { - (void) ed_id; // DOCDOC // XXXX not implemented yet. + (void) ed_id; // DOCDOC // XXXX not implemented yet. 15056 or_connection_t *tmp; tor_assert(conn); tor_assert(rsa_digest); @@ -1182,7 +1182,7 @@ connection_or_connect, (const tor_addr_t *_addr, uint16_t port, const ed25519_public_key_t *ed_id, channel_tls_t *chan)) { - (void) ed_id; // XXXX not fully used yet. + (void) ed_id; // XXXX not fully used yet. 15056 or_connection_t *conn; const or_options_t *options = get_options(); int socket_error = 0; |