More Overview and Android Writeup

This commit is contained in:
Sarah Jamie Lewis 2021-08-26 12:18:18 -07:00
parent 3f2328622c
commit 937755e58f
5 changed files with 66 additions and 11 deletions

View File

@ -7,4 +7,4 @@ title = "Cwtch Secure Development Handbook"
[output.html]
mathjax-support = true
default-theme = "navy"
default-theme = "ayu"

View File

@ -1,8 +1,8 @@
# Summary
- [Problem Overview](./overview.md)
- [Overview and History](./overview.md)
- [Risk Model](./risk.md)
- [Cwtch Overview](./cwtch-overview.md)
- [Cwtch Technical Basics](./cwtch-overview.md)
- [Open Questions](./open-questions.md)
- [Cwtch Library](./cwtch.md)
- [Message Formats](./message_formats.md)

View File

@ -1,3 +1,28 @@
# Android Service
(Currently under active development, will be documented here once it has been merged into trunk)
[Adapted from: Discreet Log #11: Integrating FFI processes with Android services](https://openprivacy.ca/discreet-log/11-android-ffi-service-integration/)
In addition to needing to make plain ol method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isnt really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service.
The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, its not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service.
If youd like to follow along, our WorkManager specifications are created in the handleCwtch() method of [MainActivity.kt](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt), and the workers themselves are defined in [FlwtchWorker.kt](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt).
Our plain ol method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback.
One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, its easy for it to yield and resume as necessary while waiting for events to be generated. Cwtchs goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately.
FlwtchWorkers eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isnt running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontends Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary.
Messages and other permanent state are stored on disk by the service, so the frontend doesnt need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state.
Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isnt the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:
private fun getNativeLibDir(): String {
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
"im.cwtch.flwtch", // Must be app name
PackageManager.GET_SHARED_LIBRARY_FILES)
return ainfo.nativeLibraryDir
}
…then, whenever the app is launched, we cancel any jobs that arent tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker.

View File

@ -1,7 +1,6 @@
# Cwtch Overview
This page presents a brief technical overview of the Cwtch system.
# Cwtch Technical Basics
This page presents a brief technical overview of the Cwtch protocol.
## A Cwtch Profile
@ -9,8 +8,7 @@ Users can create one of more Cwtch Profiles. Each profile generates a random ed2
Tor.
In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys +
associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in
addition to other associated data like the group nickname and historical messages).
associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages).
## 2-party conversions: Peer to Peer
@ -31,14 +29,32 @@ fact - it is impossible to definitely prove that the exchange happened at all.
After, the authentication protocol the two parties may exchange messages with each other freely.
## Multi-party conversations: Peer to Server
## Multi-party conversations: Groups and Peer to Server Communication
**Note: Metadata Resistant Group Communication is still an active research area and what is documented here
will likely change in the future.**
When a person wants to start a group conversation they first randomly generate a secret `Group Key`. All group communication will be encrypted using this key.
Along with the `Group Key`, the group creator also decides on a **Cwtch Server** to use as the host of the group.
For more information on how Servers authenticate themselves see [key bundles](./key_bundles.md).
A `Group Identifier` is generated using the group key and the group server and these three elements are packaged up
into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections).
To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts
their message using the `Group Key` and generates a cryptographic signature over the `Group Id`, `Group Server`
and the decrypted message (see: [wire formats](./message_formats.md) for more information).
To receive message from the group, a profile connected to the server hosting the group and downloads *all* messages (since
their previous connection). Profiles then attempt to decrypt each message using the `Group Key` and if successful attempt
to verify the signature (see [Cwtch Servers](./server.md) [Cwtch Groups](./groups.md) for an overview of attacks and mitigations).
### Servers are Peers
In many respects communication with a server is identical to communication with a regular Cwtch peer,
all the same steps above are taken however the server always acts as the inbound peer, and the outbound
peer always uses newly generated keypair as their "longterm identity".
peer always uses newly generated **ephemeral keypair** as their "longterm identity".
As such peer-server conversations only differ in the *kinds* of messages that are sent between the two parties,
with the server relaying all messages that it receives and also allowing any client to query for older messages.

View File

@ -9,6 +9,20 @@ processes.
![](https://docs.openprivacy.ca/cwtch-security-handbook/2.png)
## What is Cwtch?
Cwtch (/kʊtʃ/ - a Welsh word roughly translating to “a hug that creates a safe place”) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications.
* **Decentralized and Open**: There is no “Cwtch service” or “Cwtch network”. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch.
* **Privacy Preserving**: All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services.
* **Metadata Resistant**: Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.
### A Video Explainer
<video width="99%" controls>
<source src="https://cwtch.im/cwtch-explainer.mp4" type="video/mp4">
</video>
## A (Brief) History of Metadata Resistant Chat
In recent years, public awareness of the need and benefits of end-to-end