diff options
author | Nick Mathewson <nickm@torproject.org> | 2020-11-09 16:17:50 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2020-11-09 16:17:50 -0500 |
commit | 62ca07b1fd8d9e3dacf6d82610e6318f4705a820 (patch) | |
tree | eb784304d225fe29e5a0d5081a0f73d3fcd79634 | |
parent | adf81fb757853b0185873e251b8620d05f15cee1 (diff) | |
parent | ec0f000445fdc3fd7809032c763b67880a6391c4 (diff) | |
download | tor-62ca07b1fd8d9e3dacf6d82610e6318f4705a820.tar.gz tor-62ca07b1fd8d9e3dacf6d82610e6318f4705a820.zip |
Merge branch 'maint-0.4.4' into release-0.4.4
-rw-r--r-- | changes/bug40080 | 6 | ||||
-rw-r--r-- | src/core/or/channel.c | 2 | ||||
-rw-r--r-- | src/core/or/channel.h | 3 | ||||
-rw-r--r-- | src/core/or/circuitbuild.c | 24 |
4 files changed, 30 insertions, 5 deletions
diff --git a/changes/bug40080 b/changes/bug40080 new file mode 100644 index 0000000000..8162466354 --- /dev/null +++ b/changes/bug40080 @@ -0,0 +1,6 @@ + o Minor bugfixes (security): + - When completing a channel, relays now check more thoroughly to make + sure that it matches any pending circuits before attaching those + circuits. Previously, address correctness and Ed25519 identities were not + checked in this case, but only when extending circuits on an existing + channel. Fixes bug 40080; bugfix on 0.2.7.2-alpha. diff --git a/src/core/or/channel.c b/src/core/or/channel.c index 5ed6bb9272..9194718e3d 100644 --- a/src/core/or/channel.c +++ b/src/core/or/channel.c @@ -670,7 +670,7 @@ channel_find_by_global_id(uint64_t global_identifier) /** 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 +int channel_remote_identity_matches(const channel_t *chan, const char *rsa_id_digest, const ed25519_public_key_t *ed_id) diff --git a/src/core/or/channel.h b/src/core/or/channel.h index 82d89471b4..fa4ce4f703 100644 --- a/src/core/or/channel.h +++ b/src/core/or/channel.h @@ -735,6 +735,9 @@ int channel_is_outgoing(channel_t *chan); void channel_mark_client(channel_t *chan); void channel_clear_client(channel_t *chan); int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info); +int channel_remote_identity_matches(const channel_t *chan, + const char *rsa_id_digest, + const ed25519_public_key_t *ed_id); unsigned int channel_num_circuits(channel_t *chan); MOCK_DECL(void,channel_set_circid_type,(channel_t *chan, crypto_pk_t *identity_rcvd, diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index a1b8ba78ab..ec61b4a455 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -643,21 +643,37 @@ circuit_n_chan_done(channel_t *chan, int status, int close_origin_circuits) circ->state != CIRCUIT_STATE_CHAN_WAIT) continue; - if (tor_digest_is_zero(circ->n_hop->identity_digest)) { + const char *rsa_ident = NULL; + const ed25519_public_key_t *ed_ident = NULL; + if (! tor_digest_is_zero(circ->n_hop->identity_digest)) { + rsa_ident = circ->n_hop->identity_digest; + } + if (! ed25519_public_key_is_zero(&circ->n_hop->ed_identity)) { + ed_ident = &circ->n_hop->ed_identity; + } + + if (rsa_ident == NULL && ed_ident == NULL) { /* Look at addr/port. This is an unkeyed connection. */ if (!channel_matches_extend_info(chan, circ->n_hop)) continue; } else { - /* We expected a key. See if it's the right one. */ - if (tor_memneq(chan->identity_digest, - circ->n_hop->identity_digest, DIGEST_LEN)) + /* We expected a key or keys. See if they matched. */ + if (!channel_remote_identity_matches(chan, rsa_ident, ed_ident)) continue; + + /* If the channel is canonical, great. If not, it needs to match + * the requested address exactly. */ + if (! chan->is_canonical && + ! channel_matches_extend_info(chan, circ->n_hop)) { + continue; + } } if (!status) { /* chan failed; close circ */ log_info(LD_CIRC,"Channel failed; closing circ."); circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED); continue; } + if (close_origin_circuits && CIRCUIT_IS_ORIGIN(circ)) { log_info(LD_CIRC,"Channel deprecated for origin circs; closing circ."); circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED); |