node authentication and a hardening round
the client now checks node keys against a ca anchor, and relays refuse replayed setup cells, keep cell counters strictly in turn and bound what one address can take.
four changes reached the main branch since the last note. they tighten what a client and a relay accept. the numbers on the research page are the same preliminary series as before.
node keys are checked against an anchor
the client takes node keys only from a signed bundle: a certificate from the certificate authority and a descriptor signed by the node’s own signing key. it checks every node of the chain against a trust anchor, the public key of the authority, and refuses to build the circuit on any error. there is no fallback to unverified keys.
certificates are issued by jimichi enroll outside the cluster. the ca key is created for one
issuance and released at once. a relay creates its signing key in memory at start, the key never
leaves the process, and a certificate is installed once per relay process.
why it matters: this is the countermeasure against node keys being substituted when the client fetches them.
a setup cell opens once
a relay remembers a tag of every circuit setup cell it opened for as long as its key lives, and drops a copy, including after the original circuit has closed. the number of tags is bounded, and a full relay refuses new circuits rather than forget a tag.
why it matters: a copy would otherwise create the hop key again, and the counters would restart from zero under the same key.
counters strictly in turn, different on every link
the cell counter takes a value of its own on every link of a circuit. a relay accepts a cell only if its counter is one above the last one it accepted: a copy, a gap or a reorder closes the circuit and the cell goes no further.
why it matters: a counter of its own on every link is part of the countermeasure against linking a flow by cell headers, and forwarding a replay would hand an active observer a free timing mark.
limits on a node
handshakes, setups and writes have deadlines, and a circuit is torn down after an idle timeout and at the end of its lifetime. a connection is admitted or refused when it is accepted, before any key agreement, and one address gets at most its share of links, handshakes and setups. on the testbed a network policy lets each cell port take connections only from the hop before it.
why it matters: a silent peer holds a slot only until its deadline runs out, and one address cannot take every slot.
what this does not fix
- circuit layers still have no forward secrecy against a neighbour.
- a node cannot tell a relay from a client until links between nodes are authenticated.
- there is no node directory, and no revocation beyond a certificate’s expiry and a node restart.
- denial of service beyond the node limits is neither prevented nor measured.
the full list is on the limits page and in limitations. formats and the order of checks are in architecture, the threats and countermeasures in the threat model. published advisories are on the repository’s security advisories page.