This repository is part of the source code of Wire. You can find more information at wire.com or by contacting opensource@wire.com.
You can find the published source code at github.com/wireapp/wire.
For licensing information, see the attached LICENSE file and the list of third-party licenses at wire.com/legal/licenses/.
No license is granted to the Wire trademark and its associated logos, all of which will continue to be owned exclusively by Wire Swiss GmbH. Any use of the Wire trademark and/or its associated logos is expressly prohibited without the express prior written consent of Wire Swiss GmbH.
- Wire CoreCrypto
- rust: https://rustup.rs/
- GNU make: https://www.gnu.org/software/make/ (min version: 4.3)
- nextest: https://nexte.st/:
cargo install --locked cargo-nextest - Ensure your git is configured to sign commits
- Install the
pre-commitframework - Run
pre-commit installto initialize the pre-commit hooks
- Install SDKMAN!:
curl -s "https://get.sdkman.io" | bash - Install Java 17:
sdk install java 17.0.17-tem - Install Kotlin:
sdk install kotlin
make jvm # make the JVM target
make jvm-test # make and test the JVM targetInstall Android SDK and Build-Tools for API level 30+
Important
If you are building on macOS you'll need to setup $ANDROID_SDK_ROOT path variable manually:
export ANDROID_SDK_ROOT=~/Android/SdkInstall the Android NDK. Make sure to set the
ANDROID_NDK_HOME variable to point to the NDK installation.
Install android rust targets:
rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabiBuild:
make androidInstall Xcode & its command-line tools: https://developer.apple.com/xcode/.
Install iOS rust targets:
rustup target add aarch64-apple-ios aarch64-apple-ios-simBuild:
make ios
# Additionally, if you want to export a .XCFramework:
make ios-create-xcframeworkInstall macOS rust targets:
rustup target add aarch64-apple-darwinNote
If cross-compiling from macOS, you'll need to install https://github.com/messense/homebrew-macos-cross-toolchains.
Install Linux targets:
rustup target add x86_64-unknown-linux-gnuMake sure you have all prerequisites:
- Install wasm-pack:
cargo install --locked wasm-pack - Install the
wasm32-unknown-unknowntoolchain:rustup target add wasm32-unknown-unknown - Install node.js (recommended way is via Volta)
- Install Bun (follow the instructions on Bun's website)
- Install wasm-bindgen-cli:
cargo install wasm-bindgen-cli - Install chromedriver
bunx @puppeteer/browsers install --path ~/bin chrome-headless-shell bunx @puppeteer/browsers install --path ~/bin chromedriver
Build:
make ts # make the typescript target
make ts-test # make the typescript target and run testsBuild bindings for Android, JVM, iOS and WASM
# builds bindings and targets for the JVM (macOS / Linux)
make jvm
# builds bindings and targets for Android
make android
# builds iOS framework
make ios-create-xcframework
# builds wasm binary & TS bindings
make tscargo nextest runWarning
This takes quite a while.
cargo nextest run --features test-all-cipherSometimes for the Keystore it is valuable to run Rust unit/integration tests on the WASM target.
- Ensure you are set up to build wasm
Then, to run tests for a crate in the workspace do
wasm-pack test --headless --chrome ./keystoremake ts-testNote the CC_TEST_LOG_LEVEL environment variable. At 1 it emits browser console logs; at 2 it also emits CoreCrypto
logs.
make jvm-testmake android-testNo E2E testing is available as of now on Swift.
Some tests require a working container runtime, so make sure to prepare one before running all tests. Platform-specific instructions follow below.
Make sure to start the Docker service if it is not already running:
systemctl start docker.service# start socket activation, which will cause Podman to start once
# anything connects to the socket:
systemctl --user start podman.socket
# check that socket activation works
podman version
# if the above didn't work, depending on the distribution and installed packages,
# it may be necessary to configure the DOCKER_HOST variable to point to Podman's socket
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sockNote: Docker under macOS requires Docker Desktop, which must run as a GUI application.
# install docker and docker-desktop
brew install docker docker-desktop
# start the Docker daemon by launching docker-desktop as a GUI application
# check if everything went fine
docker version# install Podman
brew install podman
# install podman-mac-helper
sudo podman-mac-helper install
# create new VM based on machine-os:5.5; note that we're explicitly specifying
# an older image version because the newest one seems to be broken
podman machine init --image docker://quay.io/podman/machine-os:5.5
# start the machine
podman machine start
# if everything went well, this should print server version `5.5.x`
podman version
# symlink docker to podman (test scripts and code assume existence
# of the `docker` command)
ln -s /opt/homebrew/bin/podman /opt/homebrew/bin/dockerChoose the OIDC identity provider to use in tests by setting the TEST_IDP variable:
# use Keycloak
export TEST_IDP=keycloak
# or Authelia
export TEST_IDP=autheliaSimply execute the run-e2ei-tests.sh script:
bash scripts/run-e2ei-tests.shThe script will take care of cleaning up processes and containers that are started during tests.
run-e2ei-tests.sh forwards its arguments to cargo nextest, which can be used to run a specific test, or any subset
of tests, e.g.
bash scripts/run-e2ei-tests.sh alg::p256First, you need to start test-wire-server:
$ cargo run --locked --bin test-wire-server
[...]
127.0.0.1:20530Note the IP and port printed by test-wire-server and export that as TEST_WIRE_SERVER_ADDR:
export TEST_WIRE_SERVER_ADDR=127.0.0.1:20530Now that the environment is ready, you can run a specific test, or any subset of tests, e.g.
cargo nextest run --locked --ignore-default-filter -p wire-e2e-identity alg::p256Once you are done with testing, terminate the IdP container that has been started:
# if you're using Keycloak
docker kill keycloak && docker rm keycloak
# if you're using Authelia
docker kill authelia.local && docker rm authelia.localas well as the test-wire-server instance.
For all languages we provide make rules for formatting and checking.
make fmtmake rust-fmtmake swift-fmtmake kotlin-fmtmake ts-fmt
make checkmake rust-checkmake swift-checkmake kotlin-checkmake ts-check
We're using swift-format to format swift files and use swiftlint for linting.
We're using ktlint to format and lint kotlin files.
We're using mdformat for consistent formatting of our markdown files. Install it with the following extensions
mdformat-gfmmdformat-frontmattermdformat-footnotemdformat-gfm-alertsmdformat-toc
We're using taplo to format .toml files.
There are benches implemented in crypto/benches for several operations on mls groups with varying
sizes or proteus. Parameters like minimum or maximum group sizes and step sizes are defined in
crypto/benches/utils/mod.rs.
To execute the benches, e.g. for creating commits, run
cargo bench --bench=commit -- --quickwhere commit is the name of the bench specified in crypto/Cargo.toml, and the corresponding
file in crypto/benches. In case you're interested in higher accuracy, and willing to trade it for
execution speed, omit the --quick flag. If you need reporting plots, remove the .without_plots() call in
crypto/benches/utils/mod.rs. The reports generated by criterion will be located in
target/criterion.
- The
mainbranch is used as the everyday development branch. - No merge commits. Always rebase on top of
main. - Release branches are named
release/<series>, e.g.release/1.x,release/2.x. - Release branches contain fixes relevant to their specific release series and are never merged to
main. - Release branches always branch off their first major release tag. For example, the output of
git merge-base main release/2.xmust be a commit pointed to by tagv2.0.0. - Release branches are created lazily, that is, only when the first fix needs to be applied and released for a specific release series.
- Use conventional commits -- those are picked up by the changelog generator.
- If there is a JIRA ticket related to the change, you should mention it in either the PR title or the commit(s), with
the following format:
[TICKET_ID]. - Sign your commits and tags.
- Remove branches from the remote once you don't need them anymore.
The versioning scheme used is SemVer AKA Semantic Versioning.
- Make a branch based on
mainto prepare for release (git checkout -b prepare-release/X.Y.Z) - Run
sh scripts/update-versions.sh X.Y.Zto update the versions of- all workspace member crates
package.jsoncrypto-ffi/bindings/gradle.propertiesMake sure the result of the script run is correct.
- Generate the relevant changelog section:
and add it to the top of
git cliff --bump --unreleased
CHANGELOG.md. Make sure the version number generated bygit cliffmatches the release version. - If there are any release highlights, add them as the first subsection below release title:
## v1.0.2 - 2024-08-16 ### Highlights - foo - bar - baz
- In index.md, copy the commented-out table row from the bottom of the file to the appropriate place
in the table, ordering by version number, descending. Search and replace the first 5 occurrences of
x.x.xwithX.Y.Z. - Make sure the changes look reasonable and complete; you can use the previous release as a reference
- Push your
prepare-release/X.Y.Zbranch and create a PR for it - Get it reviewed, then merge it into
mainand remove theprepare-release/X.Y.Zbranch from the remote - Now, pull your local
main:git checkout main && git pull - Create the release tag:
git tag -s vX.Y.Z - Push the new tag:
git push origin tag vX.Y.Z - Create a new release on github, copying the relevant section from
CHANGELOG.md - Voilà!
- Isolate the changes to index.md and
CHANGELOG.mdfrom the release commit itself - After the release is finished, cherry-pick the changes to index.md and
CHANGELOG.mdand get them intomain - For release series
4.xand newer, docs upload happens automatically. If you released from the series3.xor older, you need to trigger docs upload manually:- On GitHub, go to the docs workflow
- Click the
Run workflowbutton - In the
Use workflow fromdropdown, chooserelease/5.x, inTag to checkoutprovide your release tag