This library provides an API to facilitate secure end-to-end encrypted messaging on Android devices, backed by a fork of libsignal and communicating via a tassis messaging server.
messaging-android is currently used in Lantern but is intended to be usable by other parties in their own clients. tassis will eventually support federation, such that 3rd parties can host their own back end and interoperate with other messaging clients.
- Run all tests in
androidTest
with./gradlew connectedDebugAndroidTest
- Those require a running emulator
- Run a specific test with
./gradlew -P android.testInstrumentationRunnerArguments.class=com.your.test.package#testWhatever connectedAndroidTest
- e.g.,
./gradlew -P android.testInstrumentationRunnerArguments.class=io.lantern.messaging.MessagingTest#testRecovery connectedAndroidTest
to runtestRecovery
- e.g.,
messaging-android communicates with Tassis and internally stores data using protocol buffers. Messages exchanged with tassis are defined in Messages.proto, which is just a copy of the protocol buffers defined in tassis.
The messaging-android data model is defined in Model.proto.
messaging-android stores data in an encrypted key-value store using keys that follow the below convention.
The recovery key from which all other keys are derived.
The contact entry for the user themselves.
A direct contact, identified by their public IdentityKey
A group contact, identified by its group id
An index of Contacts by most recent activity. A given Contact will appear only once in this index.
The full content of all Messages are stored here, including both sent and received messages. The messageId is an id that's unique for messages sent from the given senderIdentityKey (in practice it's a type 4 UUID).
An index of all messages for a given Contact, by the sent timestamp of the message.
An index of all messages that are supposed to auto disappear by some time (in unix milliseconds)
A queue of outbound messages that are pending send. If sending to some recipients fails, messages will be re-queued here for a limited period of time until they either send successfully or time runs out.
A queue of inbound attachments that are pending download. If downloading fails, downloads will be re-queued here for a limited period of time until they either send successfully or time runs out.
An index of Introduction messages keyed to the contact who introduced us and then the contact to whom we're being introduced.
An index of Introduction messages keyed to the contact to whom we're being introduced and then the contact who introduced us.
An index to the "best" introduction message for a given contact to which we're being introduced. "Best" means most trusted (highest verification level).
The included Signal code (like AttachmentCipherInputStream) comes from https://github.com/signalapp/Signal-Android, not from https://github.com/signalapp/libsignal-service-java
This project is formatted and linted with ktlint using the ktlint-gradle plugin.
You can install the ktlint Intellij plugin for some support for linting within Android Studio.
./gradlew addKtlintCheckGitPreCommitHook
This adds a pre commit hook that lints all staged files upon commit.
./gradlew ktlintFormat
This auto-formats all Kotlin files in the project.
./gradlew ktlintCheck
This manually runs the linter against all Kotlin files in the project.
This library uses a lot of cryptography routines, which uses up available entropy on systems. If you're frequently running the tests on emulators or devices which you don't actually use, the system may run out of entropy and the tests will slow down and eventually even stop working.
The solution is to run the tests on a device or emulator on which you also use the UI, which helps regenerate entropy.