secure-development-handbook/src/tapir.md

185 lines
7.6 KiB
Markdown
Raw Permalink Normal View History

2020-06-17 21:49:52 +00:00
# Tapir
2020-06-18 18:44:35 +00:00
Designed to replace the old protobuf-based ricochet channels, Tapir provides a
framework for building anonymous applications.
It is divided into a number of layers:
* Identity - An ed25519 keypair, required for established a Tor v3 onion service
and used to maintain a consistent cryptographic identity for a peer.
* Connections - The raw networking protocol that connects two peers. Connections
are so far only defined over Tor v3 Onion Services (see: [connectivity](./connectivity.md))
* Applications - The various logic that enables a particular information flow
over a connection. Examples include shared cryptographic transcripts
, authentication, spam guards and token based services. Applications provide
**Capabilities** which can be referenced by other applications to determine if
a given peer has the ability to use a given hosted application.
* Application Stacks - A mechanism for connecting more than one application
together, e.g. authentication depends on a shared cryptographic transcript
, and the main [cwtch](./cwtch.md) peer app is based on the authentication
application.
2020-07-02 21:24:11 +00:00
## Primitives
2020-07-03 18:20:37 +00:00
### Identity
An ed25519 keypair, required for established a Tor v3 onion service
and used to maintain a consistent cryptographic identity for a peer.
* InitializeIdentity - from a known, persistent keypair: \\(i,I\\)
* InitializeEphemeralIdentity - from a random keypair: \\(i_e, I_e\\)
2020-07-02 21:07:37 +00:00
## Applications
### Transcript App
**Dependencies:** None
Initializes a [Merlin](https://merlin.cool)-based cryptographic transcript that
can be used as the basis of higher level commitment-based protocols
Transcript app will panic if an app ever tries to overwrite an existing
transcript with a new one (enforcing the rule that a session is based on
one, and only one, transcript.)
### Authentication App
2020-07-03 18:20:37 +00:00
* **Dependencies**: Transcript App
* **Capabilities Granted**: *AuthenticationCapability*
* **Capabilities Required**: *None*
2020-07-02 21:07:37 +00:00
2020-11-27 22:03:30 +00:00
Engages in an [ephemeral triple-diffie-hellman handshake](./authentication_protocol.md) to derive a unique,
2020-07-02 21:07:37 +00:00
authenticated session key.
2020-07-03 18:20:37 +00:00
### transcript.Commit()
The merlin transcript derived challenge is based on all the messages sent in
the auth flow (and any that were sent prior to the Auth App)
// Derive a challenge from the transcript of the public parameters of this authentication protocol
transcript := ea.Transcript()
transcript.NewProtocol("auth-app")
transcript.AddToTranscript("outbound-hostname", []byte(outboundHostname))
transcript.AddToTranscript("inbound-hostname", []byte(inboundHostname))
transcript.AddToTranscript("outbound-challenge", outboundAuthMessage)
transcript.AddToTranscript("inbound-challenge", inboundAuthMessage)
challengeBytes := transcript.CommitToTranscript("3dh-auth-challenge")
2020-07-03 18:20:37 +00:00
#### Asymmetry
The client connection is guaranteed to possess the long term identity of the
server connection through the properties of the underlying tor v3 onion
2020-07-03 18:20:37 +00:00
connection.
As such if the server attempts to send a different long term identity to the
client we can detect it and terminate the authentication protocol early.
2020-07-02 21:07:37 +00:00
### Token App
**Dependencies:** Transcript App
2020-07-03 18:20:37 +00:00
* **Capabilities Granted**: *HasTokensCapability*
* **Capabilities Required**: *None* (implicitly guarded)
2020-07-02 21:07:37 +00:00
Allows the client to obtain signed, blinded tokens for use in another
application.
2020-07-02 21:22:20 +00:00
2020-07-03 18:20:37 +00:00
While this application has no explicit requirement for any given capability,
we expect it to be protected via a preceeding app in an `ApplicationChain` e.g.
powTokenApp := new(applications.ApplicationChain).
ChainApplication(new(applications.ProofOfWorkApplication), applications.SuccessfulProofOfWorkCapability).
ChainApplication(tokenApplication, applications.HasTokensCapability)
2020-07-02 21:22:20 +00:00
#### Notes
* No direct testing (tested via integration tests and unit tests)
2020-07-02 21:07:37 +00:00
2020-11-05 20:15:09 +00:00
### Ephemeral Connections
Occasionally it is desirable to have a peer conenct to another / a service
without using their long term identity (e.g. in the case of connecting to
a Cwtch Server).
In this case we want to enable a convenient way to allow connecting with an
ephemeral identity.
It turns out that doing this securely requires maintaining a completely separate
set of connections and applications in order to avoid side channel around avoid
duplicate connections (i.e. if we did mix them up then a service might be able
to exploit the fact that clients avid duplicate connections by attempting to
connect to known-online peers and observing if they reject the connection
because they already have an outbound ephemeral connection open.)
Because of this, we don't provide an explicit Ephemeral Connect api and instead
recommend that peers maintain one long term service and multiple ephemeral
services.
2020-06-18 18:44:35 +00:00
## Known Risks
### Impersonation of Peers
**Status: Mitigated**
By default, tor v3 onion services only provide one-way authentication, that
is the client can verify a metadata resistant connection to the server by the
server obtained no information about the client.
Tapir provides a peer-to-peer interface over this client-server structure
through the [Authentication application](https://git.openprivacy.ca/cwtch.im/tapir/src/branch/master/applications/auth.go).
The Authentication application implements a 3-way, ephemeral diffie-hellman
handshake to generate a shared session key. Once generated this session key is
used to encrypt *all* traffic between the two peers for the duration of the
session.
The session key is used to encrypt a challenge derived from the shared
cryptographic transcript (based on [merlin](https://merlin.cool))
Only if all the above checks pass is the connection maintained open - otherwise
the peer that detects a failure closes the connection.
### Double Connections
**Status: Mitigated**
Because of the one-way authentication provided by Tor onion services there is a
window between connection instantiation and the finalization of authentication
when two valid connections can occur between the same two peers.
While these vestigial connections are not harmful, they do have the potential to
confuse users and interfaces. To avoid ambiguity Tapir attempt to detect and
close duplicate connections through a number of rules:
1. If a connection open is attempted to a hostname that
already has an open connection the connection attempt is aborted.
2. After authentication the lookup happens again, and if another connection is
found the newest connection is closed.
There is a small chance both peers will close their initiated connections
if they also happen to start the connection attempt at exactly the sametime
. This should be exceedingly rare in practice, and is further mitigated by
an exponential backoff of connection retries by the [ui](./ui.md)
Finally, the Tapir interfaces `WaitForCapabilityOrClose` and `GetConnection` are
aware of the potential for duplicate connections and have logic that allows the
handling of such instances (such as returning an error when they are found
allowing a handling application to retry the request if a connection with a
given capability isn't returned)
## Testing Status
Tapir features a number of well-defined integration tests which exercise not
only the ideal case of two well-formed peers authenticating and messaging each
other, but also a malicious peer attempting to bypass authentication.
In addition, unit tests are defined for a number of the specified
applications (including Authentication) and many of the
cryptographic primitives.
All tests are also run with the `-race` flag which will cause them to fail if
race conditions are detected. Both integration tests and unit tests are run
automatically for every pull request and main branch merge.