Commit afb6ff17 authored by Nick Mathewson's avatar Nick Mathewson 🌻
Browse files

Validate ed25519 keys and canonicity from circuit_n_conn_done()

Fixes bug 40080. Bugfix on
parent c4742b89
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
......@@ -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
channel_remote_identity_matches(const channel_t *chan,
const char *rsa_id_digest,
const ed25519_public_key_t *ed_id)
......@@ -741,6 +741,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);
int channel_matches_target_addr_for_extend(channel_t *chan,
const tor_addr_t *target);
unsigned int channel_num_circuits(channel_t *chan);
......@@ -623,21 +623,37 @@ circuit_n_chan_done(channel_t *chan, int status, int close_origin_circuits)
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))
} 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))
/* 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)) {
if (!status) { /* chan failed; close circ */
log_info(LD_CIRC,"Channel failed; closing circ.");
circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
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);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment