earthstar-project / earthstar

Storage for private, distributed, offline-first applications.
https://earthstar-project.org
GNU Lesser General Public License v3.0
637 stars 20 forks source link

Cinn25519, Auth, Cap, Peer, Syncer, Blake3 #330

Closed sgwilym closed 4 months ago

sgwilym commented 4 months ago

This PR adds several new Willow-powered features as well as refactoring some others.

Paths are incorrectly implemented as only allowing alphanumeric characters in this branch. This will be addressed later with a PR for a more powerful Path class.

Blake3

Earthstar now uses BLAKE3 digests. The Blake3 export provides an interface for producing BLAKE3 digests using different implementations for different runtimes.

Cinn25519

This is an implementation of the new Cinn25519 spec, and unifies the code which was previously spread around the EsCrypto class and several other places.

This implementation adds the concept of tags, string representations of Cinn25519 public keys, e.g. @suzy.b724w6da6euw2ip7szpxopq2uodagdyswovh4pqd6ptnanz2u362a or +gardening.bhynoq5vqfpysmi2i7zilhdnynfsuq5wddus5sfgce24z53a2f6da. We used to call these addresses, but someone pointed out they weren't actually addresses. These tags also provide the interface for users to specify public keys in different APIs.

Auth

Meadowcap grants read and write access to namespaces (Earthstar's shares) via capabilities, which are unforgeable tokens proving this access was bestowed to the possessor(s) of a specific keypair. Prior to this, Earthstar only managed access via a namespace public key and secret which would grant unlimited access to the entire share.

With Earthstar now needing to manage keypairs and capabilities, offloading this responsibility to users (e.g. asking them to put them all in a password manager) is a offputting amount of busywork.

Additionally, given Earthstar's usage within browsers it becomes important for malevolent applications running on the same origin to be prevented from accessing users' keypairs or capabilities.

The new Auth class stores identity keypairs, share keypairs, and capabilities in a secure encrypted storage, in addition to providing APIs for generating new keypairs and capabilities, and delegations thereof..

The user provides a plaintext password during the instantiation of Auth. This password is used to derive a PBKDF2 key, which is then used to derive a AES-GCM key used for encrypting and decrypting values in the underlying key value store.

The resulting encryption key is used to attempt the decryption of a static challenge created by a previous instantiation. If this fails, the constructor throws. This is to ensure that Auth only stores values encrypted using the same key. If the password is lost, the only thing to do is to call Auth.reset, deleting all values and the password challenge.

The keys for stored values only indicate what kind of value it contains, but nothing indicating what it might be (e.g. an encoded digest). This is so an attacker with access to the store could learn what it contains if they have a list of existing keypair / capability digests.

This also means that the performance of querying Auth has an upper bound, as all items of that type must be iterated through to exhaust all possible matches.

A capability can only be added to Auth if the keypair for that capability's receiver is already in storage.

Auth uses pluggable storage, using Willow's KvDriver interface. This means that users can store items in-memory, with Deno.KV, or IndexedDB.

Auth is meant as a low-level API to be used by other Earthstar APIs, rather than directly by users themselves.

Cap

Cap provides a friendly interface for dealing with Meadowcap's capabilities. Rather than a plain object containing data from which semantic information can be derived, Cap directly exposes that semantic information, as well as providing methods for created a newly delegated Cap, or exporting it (returning a byte encoded format) for transmission to another user.

Peer

There are a whole lot of things going on now: identities, shares, capabilities, the Store class which provides the actual interface for reading and writing data, and syncing. The Peer class unites all these APIs in order to minimise the overhead of coordinating all these features.

A Peer has its own Auth instance which it uses to securely store credentials such as keypairs and capabilities, as well as produce new identities, shares, and capabilities.

A Peer is able to use these stored credentials to then determine which Stores it can provide, or which shares and areas of interest should be synced.

When peers can be provided with drivers upon instantiation which determine how Store and Auth data is persisted.

Syncer

Syncer is an instance of Willow's WgpsMessenger configured with all of Earthstar's parameters. It can automatically derive areas of interest for syncing from all read capabilities in an Auth instance, or explicit interests can be manually specified using a an array of CapSelector.