-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
Reproducible Builds
You can just use these instructions from the official announcement at Open Whisper System's blog:
# Clone the Signal Android source repository
$ git clone https://github.com/WhisperSystems/Signal-Android.git && cd Signal-Android
# Check out the release tag for the version you'd like to compare
$ git checkout v[the version number]
# Build using the Docker environment
$ docker run --rm -v $(pwd):/project -w /project whispersystems/signal-android:0.2 ./gradlew clean assembleRelease
# Verify the APKs
$ apkdiff/apkdiff.py build/output/apks/project-release-unsigned.apk path/to/SignalFromPlay.apk
Since version 3.15.0 Signal for Android has supported reproducible builds. This is achieved by replicating the build environment as a Docker container. You'll need to build and run the container, compile Signal inside the container and then compare the resulted APK to the APK that is distributed in the Google Play Store.
The command line parts in this guide are written for Linux but with some little modifications you can adapt them to OS X and Windows. In the following sections we will use 3.15.2
as an example Signal version. You'll just need to replace all occurrences of 3.15.2
with the version number you are about to verify.
First make sure that the Signal version you want to verify is installed on your Android device. You'll need adb
for this part.
Plug your device to your computer and run:
user@host:$ adb shell pm path org.thoughtcrime.securesms
package:/data/app/org.thoughtcrime.securesms-1/base.apk
The output will tell you where the Signal APK is located in your device. (In this example the path is /data/app/org.thoughtcrime.securesms-1/base.apk
)
Now using this information, pull the APK from your device to your computer's home directory (~
):
user@host:$ adb pull /data/app/org.thoughtcrime.securesms-1/base.apk ~/Signal-3.15.2-from-Google-Play.apk
We will use this APK in the final part when we compare it with the self-built APK from GitHub.
Install Docker by following the instructions for your platform at https://docs.docker.com/engine/installation/
Your platform might also have its own preferred way of installing Docker. E.g. Ubuntu has its own Docker package (docker.io
) if you do not want to follow Docker's instructions.
In the following sections we will assume that your Docker installation works without issues. So after installing, please make sure that everything is running smoothly before continuing.
First you will need the Dockerfile
for Signal Android. It comes bundled with Signal's source code. The Dockerfile
contains instructions on how to automatically build a container for Signal. You just need to run it and it builds itself.
To keep things simple, we will grab Signal's source as a zip file from https://github.com/WhisperSystems/Signal-Android/releases, unzip it to your home folder (~
) and use the Dockerfile
from the source directory.
user@host:$ cd ~
user@host:$ wget https://github.com/WhisperSystems/Signal-Android/archive/v3.15.2.zip
user@host:$ unzip v3.15.2.zip
In your home folder (~
), create a new directory called signal-build-context
and copy the Dockerfile
there:
user@host:$ mkdir ~/signal-build-context
user@host:$ cd ~/signal-build-context
user@host:$ cp ~/Signal-Android-3.15.2/Dockerfile .
While still inside the signal-build-context
directory, build the container image based on the Dockerfile
:
user@host:$ docker build --file Dockerfile --tag signal-android .
Wait a few years for the build to finish... 👷
(Depending on your computer and network connection, this may take several minutes.)
📆 😴
After the build has finished, you may wish to list your containers to see that it's really there:
user@host:$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
signal-android latest c6b84450b896 46 seconds ago 2.94 GB
ubuntu 14.04.3 8693db7e8a00 9 weeks ago 187.9 MB
Next we will run the container, grab Signal's source code and compile Signal.
Run your newly built Signal container and get a terminal session inside it:
user@host:$ docker run --name signal --interactive --tty signal-android
Now you are inside the container.
Grab Signal Android source code from GitHub and go to the repository directory:
root@container:# cd ~
root@container:# git clone https://github.com/WhisperSystems/Signal-Android.git
root@container:# cd Signal-Android
Before you can compile, you must ensure that you are at the right commit. In other words you must checkout to the version you wish to verify (here we are verifying 3.15.2):
root@container:# git checkout --quiet v3.15.2
Now you may compile the release APK by running:
root@container:# ./gradlew assembleRelease
This will take a few minutes 😴
After the build has completed successfully we can compare if the APKs match. You can do this either inside the Signal container or in your host OS. In this guide we will do the comparison inside the container because the comparison tool requires Python and your host OS might not have it installed.
For the comparison we need of course the Google Play Store version of Signal APK which you copied to your home directory in the beginning of this guide. So while keeping your Signal container running, open a terminal in your host system and run:
user@host:$ docker cp ~/Signal-3.15.2-from-Google-Play.apk signal:/root/
(Note that copying files from your host system to a Docker container only works with Docker versions >=1.8. If you are running an older version of Docker, you have to do it the other way around.)
Finally, using the apkdiff.py
tool compare the two APKs:
root@container:# ~/Signal-Android-3.15.2/apkdiff/apkdiff.py ~/Signal-3.15.2-from-Google-Play.apk ~/Signal-Android-3.15.2/build/outputs/apk/Signal-Android-release-unsigned.apk
APKs match!
If you get APKs match!
, you have successfully verified that the Google Play release matches with your own self-built version of Signal. Congratulations! ✨
If you get APKs don't match!
, you did something wrong in the previous steps.
- you built the container with an older version of
Dockerfile
- you didn't checkout to the correct version tag with Git before compiling
- this guide is outdated
- you are in a dream
You don't need to build the container every time you want to verify a new APK. You can reuse the old container provided that the build environment (Dockerfile
) has not changed.
In short, it looks something like this
user@host:$ docker start signal
user@host:$ docker attach signal
root@container:# cd ~/Signal-Android
root@container:# git pull origin master
root@container:# git checkout v3.141.592 # or whatever the new version number is
root@container:# ./gradlew clean assembleRelease
And then compare with apkdiff.py
as you did previously.
If you cannot get things to work, please do not open an issue or comment on an existing issue at GitHub. Instead, ask for help at https://whispersystems.discoursehosting.net/c/development