arti/crates/tor-proto
Nick Mathewson 2d4507ff35 Final (?) API revisions for tor-linkspec
With this change, each individual identity type becomes optional.
The functions that expose them unconditionally are now in a "legacy"
trait that only some downstream types are expected to implement.

There are new convenience APIs in HasRelayIds:
  * to return Option<&keytype>,
  * to see if one identity-set contains another.

This commit will break several downstream crates!  For the
reviewer's convenience, I will put the fixes for those crates into a
series of squash! commits on this one.

tor-netdir
----------

Revise tor-netdir to accept optional identities.  This required some
caveats and workarounds about the cases where we have to deal with a
key type that the tor-netdir code does not currently recognize at
all.  If we start to add more identity types in the future, we may
well want more internal indices in this code.

tor-proto
---------

In order to make tor-proto support optional identities, there were
fewer changes than I thought.  Some "check" functions needed to start
looking at "all the ids we want" rather than at "the two known IDs";
they also needed to accommodate that case where we don't have an ID
that we demand.

This change will also help with bridges, since we want to be able to
connect to a bridge without knowing all of its IDs up front.

The protocol currently _requires_ the two current ID types in some
places. To deal with that, I added a new `MissingId` error.

I also removed a couple of unconditional identity accessors for
chanmgr; code should use `target().identity(...)` instead.

tor-chanmgr
-----------

This is an incomplete conversion: it does not at all handle channel
targets without Ed25519 identities yet.  It still uses those
identities to index its internal map from identity to channel; but
it gives a new `MissingId` error type if it's given a channel target
that doesn't have one.

We'll want to revise the map type again down the road when we
implement bridges, but I'd rather not step on the channel-padding
work in progress right now.

tor-guardmgr
------------

This change is mostly a matter of constructing owned identity types
more sensibly, rather than unwrapping them directly.

There are some places marked with TODOs where we still depend on
particular identity types, because of how the directory protocol
works.  This will need revisiting when we add bridge support here.

tor-circmgr
-----------

These changes are just relatively simple API changes in the tests.
2022-08-10 10:39:37 -04:00
..
src Final (?) API revisions for tor-linkspec 2022-08-10 10:39:37 -04:00
testdata Move all crates into a `crates` subdirectory. 2021-08-27 09:53:09 -04:00
Cargo.toml Bump patch versions on crates that have new APIs. 2022-08-01 09:56:29 -04:00
README.md Use script to update README.md files. 2022-01-28 08:36:34 -05:00
semver.md Final (?) API revisions for tor-linkspec 2022-08-10 10:39:37 -04:00

README.md

tor-proto

Implementations for the core Tor protocol

Overview

The tor-proto crate lies at the core of Arti, a project to implement Tor in Rust. Most people shouldn't use this crate directly, since its APIs are needlessly low-level for most purposes, and it is easy to misuse them in an insecure or privacy-violating way.

Most people should use the [arti-client] crate instead. This crate is of interest mainly for those that want to access the Tor protocols at a low level.

Core concepts

At its essence, Tor makes connections called "channels" to other Tor instances. These channels are implemented using TLS. Each of these channels multiplexes a number of anonymized multihop "circuits" that act as reliable transports for "relay messages" that are sent between clients and the different relays on the circuits. Finally, each circuit multiplexes a number of "streams", each corresponding roughly to an application-level request.

This crate implements the logic, protocols, and cryptography that implement these [channel::Channel]s, [circuit::ClientCirc]s, and [stream::DataStream]s. It uses rust async code and future-related traits, and is intended to work with (nearly) any executor implementation that complies with the futures API. It should also work with nearly any TLS implementation that exposes AsyncRead and AsyncWrite traits.

Not in this crate

This crate does not implement higher level protocols, like onion services or the Tor directory protocol, that are based on the Tor protocol here. Nor does it decide when, how, or where to build channels and circuits: that's the role of higher-level crates.

This crate also has no support for timeouts, so every network operation here has the potential to block the current task indefinitely. Timeouts are another necessary piece that gets added at a higher level.

In order to create channels and circuits, you'll need to know about some Tor relays, and expose their information via [tor_linkspec::ChanTarget] and [tor_linkspec::CircTarget]. Currently, the [tor-netdir] crate is the easiest way to do so.

For an example of this crate in action, see the [arti-client] library, or the arti CLI.

Design notes

This crate's APIs are structured to explicitly avoid any usage of an asynchronous runtime: It doesn't launch tasks or include timeouts. Those are done at a higher level in Arti, via the [tor-rtcompat] crate.

To the extent possible, this crate avoids doing public-key cryptography in the same functions it uses for network activity. This makes it easier for higher-level code to parallelize or yield around public-key operations.

Limitations

This is all a work in progress, and will need severe refactoring before it's done.

This is a client-only implementation; there is no support the operations that Relays need.

There are too many missing features to list.

There isn't enough documentation or examples.

This crate was my first attempt to use async in rust, and is probably pretty kludgy.

I bet that there are deadlocks somewhere in this code. I fixed all the ones I could find or think of, but it would be great to find a good way to eliminate every lock that we have.

License: MIT OR Apache-2.0