Skip to content

Hack on Gosling! #rust #onion_services #network_protocols #testing

Organizational Details

  • Who is coordinating/leading this project: richard (aka pospeselr in various places)
  • Where to meet : #gosling-hackweek-2022 on OFTC IRC
  • Contact :

    OFTC IRC: richard

    email: richard@torproject.org

Team

  • Richard
  • nickm is psyched on a some-of-the-time basis
  • trinity-1686a (maybe, part-time)
  • meskio
  • Shelikhoo (Part-Time, also joined tangible) Sick Leave
  • Github : https://github.com/blueprint-freespeech/gosling
  • Gosling Protocol Spec : https://github.com/blueprint-freespeech/gosling/blob/main/docs/protocol.md

What is Gosling?

Gosling is an authentication protocol designed to make building anonymous+private peer-to-peer onion services easy. It is meant to solve the problem of authenticating onion services with each other for use in peer-to-peer communications.

Suppose Alice and Bob both have an identity associated with their own onion services (as is the case in Ricochet-Refresh). If Alice wants to connect to Bob, all she has to do is connect to Bob's public .onion. However, how can Bob be sure that the incoming connection actually is Alice (without rolling your own crypto thing)?

See the protocol documentation for more details+specifics: https://github.com/blueprint-freespeech/gosling/blob/main/docs/protocol.md

Code?

The code for Gosling is a work-in-progress and can be found here: https://github.com/blueprint-freespeech/gosling

I'm currently working on the final piece: actually implementing the Gosling protocol. Up to this point I've been working on the required building blocks. However, there should be at least an initial implementation by the time HackWeek happens (inshallah).

A short walkthrough:

-  source

- gosling : the Rust Gosling crate

- libgosling.hpp : a C++ header to make working with the exported C header easier for C++ consumers

- src

- ffi.rs : The C foriegn-function interface cbindgen uses to generate a C header

- honk_rpc.rs : The implementation of the underlying RPC protocol used by Gosling

- lib.rs : The crate root rs file

- object_registry.rs : Maps handles to Rust objects; said handles can be passed through the FFI to external callers

- test_utils.rs : some test-only helper objects

- tor_controller.rs : A tor controller, takes care of luanching tor daemon, ensuring a recent enough version, control port interface, and high-level TorManager for making and connecting to onion services

- tor_crypto.rs : ed25519, x25519 and other misc crypto primitives needed to work with tor and tor onion services

- work_manager.rs : A simple threaded worker pool for task-based concurrency

- test

- unit

- test.cpp : test for the cbindgen generated C FFI

Ideas for work to do: * Improve protocol! * Improve code! * Improve infrastructure!

Protocol concerns: * I think the best avenue for attacks against this protocol are attacks where I trick somebody into using one endpoint while thinking it's somebody else's endpoint. I'm not sure how to do that, but we should make sure that we're binding intro-point to end-point everwhere and every way we can.
* Attacker can probe to see if you're friends with X without being X.

Protocol suggestions: * add protocol-part and to initial version message. * Use bson for framing on proof object too -- or at least, introduce some kind of framing.

    * Also, only sign the proof, then send that signature. No need to hash.

* Make endpoints some with an expiration time, so that you know when you need to get a new one.  As part of endpoint handshake, give out the next endpoint (if you like the client).
* Cross-certify to prove ownership of endpoint keys: we don't want people giving out other people's endpoints.
* Instead of signing with ed25519 onion service "identity key", consider using shorter-term signing keys: these are certified by identity key. Doing this would let users keep identity key offline.
* Make sure no one can create a signature in a format recognised by this program unintentionally.
* Specify some invariant bson encoding, to avoid implementation fingerprinting.
* Use separate domain-separation for introduction and endpoint. (richard says this is done)
* Include the endpoint ID AND intro ID in the proof when available. (to avoid Jerk-in-the-middle)
* Consider what it would mean if a user had multiple introduction servers.
* Consider letting the protocol procede to the end of the protocol and _then_ rejecting.  (Otherwise you can probe as per above.)  Don't give out more than 1 bit of allowed/denied information, and only when you've authenticated.

Protocol document suggestions * The word "introduction" collides with rend-spec's "introduction point" language. * Instead of "string" or "document", specify a struct that gets encoded as bson, in every case.

Implementation suggestions: * Consider using serde instead of hand-parsing bson objects. * Add a layer that only does message-processing and the gosling protocol, with no knowledge of Tor or onion services. (perhaps this is already there?) * Focus on the protocol layer for now. * Consider extracting tor-controller into a new crate.

Next steps!

  • go through the code!
  • Find something that looks bad!
  • Fix it!