Merge branch 'bug40080_035'

This commit is contained in:
Nick Mathewson 2020-10-30 10:51:20 -04:00
commit 148b5b03a3
4 changed files with 30 additions and 5 deletions

6
changes/bug40080 Normal file
View File

@ -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.

View File

@ -663,7 +663,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)

View File

@ -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,

View File

@ -654,21 +654,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);