Commit a9e09a75 authored by Torsten Grote's avatar Torsten Grote

Initial commit

parents
Pipeline #1600 passed with stages
in 26 minutes and 48 seconds
/.idea
/__pycache__
/android-ndk
/tor-android
/android-ndk.zip
image: docker:git
services:
- docker:dind
stages:
- build
- test
- release
variables:
TEST_IMAGE: briar/tor-reproducer:${CI_BUILD_REF_NAME}
RELEASE_IMAGE: briar/tor-reproducer:latest
before_script:
- echo ${DOCKER_HUB_PASS} | docker login -u ${DOCKER_HUB_USER} --password-stdin
build:
stage: build
script:
- docker build -t ${TEST_IMAGE} .
- docker push $TEST_IMAGE
test:
stage: test
script:
- docker run ${TEST_IMAGE} ./build-tor.py
release:
stage: release
script:
- docker pull $TEST_IMAGE
- docker tag $TEST_IMAGE $RELEASE_IMAGE
- docker push $RELEASE_IMAGE
only:
- master
FROM debian:stretch
ENV LANG=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /opt/tor-reproducer
ADD build-tor.py ./
ADD install*.sh ./
ADD tor-versions.json ./
ADD utils.py ./
RUN ./install.sh
CMD ./build-tor.py
# Tor Reproducer
This is a tool you can use to verify that the version of Tor
used by [Briar](https://briar.app) was built exactly from the public source code
and no modifications (such as backdoors) were made.
More information about these so called reproducible builds is available at
[reproducible-builds.org](https://reproducible-builds.org/).
The source code for this tool is available at
https://code.briarproject.org/briar/tor-reproducer
## How to use
Make sure the version of Tor you want to verify is included in `tor-versions.json`.
Verify that you have `docker` installed:
docker --version
If this command does not work,
please [install Docker](https://docs.docker.com/install/)
and continue once it is installed.
### Using our pre-built image
If you trust that our pre-built Docker image was build exactly from *its* source,
you can use it for faster verification.
If not, you can read the next section to learn how to build the image yourself.
Then you are only trusting the official `debian:stable` which is out of our control.
Otherwise, you can skip the next section and move directly to *Run the verification*.
### Building your own image
Check out the source repository:
git clone https://code.briarproject.org/briar/tor-reproducer.git
Build our Docker image:
docker build -t briar/tor-reproducer tor-reproducer
### Run the verification
To verify a specific version of Briar, run
docker run briar/tor-reproducer:latest ./build-tor.py [tag]
Where `[tag]` is the git tag (source code snapshot) that identifies the version
of Tor you want to test, for example `tor-0.3.3.6`.
You can find a list of tags in Tor's
[source code repository](https://gitweb.torproject.org/tor.git/refs/).
#!/usr/bin/env python3
import json
import os
import sys
from collections import OrderedDict
from shutil import move, copy, rmtree
from subprocess import check_call
from utils import get_sha256, fail
NDK_DIR = 'android-ndk'
REPO_DIR = 'tor-android'
def main():
if len(sys.argv) > 2:
fail("Usage: %s [Tor version tag]" % sys.argv[0])
tag = sys.argv[1] if len(sys.argv) > 1 else None
# get Tor version and versions of its dependencies
versions = get_build_versions(tag)
# setup Android NDK
setup_android_ndk(versions)
# clone and checkout tor-android repo based on tor-versions.json
prepare_tor_android_repo(versions)
# build Tor for various architectures
build_architectures()
# zip geoip database
geoip_path = os.path.join(REPO_DIR, 'external', 'tor', 'src', 'config', 'geoip')
check_call(['zip', '-X', os.path.join(REPO_DIR, 'geoip.zip'), geoip_path])
# zip everything together
file_list = ['tor_arm_pie.zip', 'tor_arm.zip', 'tor_x86_pie.zip', 'tor_x86.zip', 'geoip.zip']
zip_name = 'tor-android-%s.zip' % versions['tor'].split('-')[1]
check_call(['zip', '-X', zip_name] + file_list, cwd=REPO_DIR)
# print hashes for debug purposes
for file in file_list + [zip_name]:
sha256hash = get_sha256(os.path.join(REPO_DIR, file))
print("%s: %s" % (file, sha256hash))
def get_build_versions(tag):
# load Tor versions and their dependencies
with open('tor-versions.json', 'r') as f:
versions = json.load(f, object_pairs_hook=OrderedDict)
if tag is None:
# take top-most Tor version
tag = next(iter(versions))
print("Building Tor %s" % versions[tag]['tor'])
return versions[tag]
def setup_android_ndk(versions):
if os.path.isdir(NDK_DIR):
# check that we are using the correct NDK
from configparser import ConfigParser
config = ConfigParser()
with open(os.path.join(NDK_DIR, 'source.properties'), 'r') as f:
config.read_string('[default]\n' + f.read())
revision = config.get('default', 'Pkg.Revision')
if revision != versions['ndk']['revision']:
print("Existing Android NDK has unexpected revision. Deleting...")
rmtree(NDK_DIR)
if not os.path.isdir(NDK_DIR):
# download Android NDK
print("Downloading Android NDK...")
check_call(['wget', '-c', '--no-verbose', versions['ndk']['url'], '-O', 'android-ndk.zip'])
# check sha256 hash on downloaded file
if get_sha256('android-ndk.zip') != versions['ndk']['sha256']:
fail("Android NDK checksum does not match")
# install the NDK
print("Unpacking Android NDK...")
ndk_dir_tmp = NDK_DIR + '-tmp'
check_call(['unzip', '-q', 'android-ndk.zip', '-d', ndk_dir_tmp])
content = os.listdir(ndk_dir_tmp)
if len(content) == 1 and content[0].startswith('android-ndk-r'):
move(os.path.join(ndk_dir_tmp, content[0]), NDK_DIR)
os.rmdir(ndk_dir_tmp)
else:
fail("Could not extract NDK: %s" % str(content))
os.putenv('ANDROID_NDK_HOME', os.path.abspath(NDK_DIR))
def prepare_tor_android_repo(versions):
if os.path.isdir(REPO_DIR):
# get latest commits and tags from remote
check_call(['git', 'fetch', 'origin'], cwd=REPO_DIR)
else:
# clone repo
url = versions['tor_android_repo_url']
check_call(['git', 'clone', '--recurse-submodules', url, REPO_DIR])
# checkout tor-android version
check_call(['git', 'checkout', '-f', versions['tor-android']], cwd=REPO_DIR)
# undo all changes
check_call(['git', 'reset', '--hard'], cwd=REPO_DIR)
check_call(['git', 'submodule', 'foreach', 'git', 'reset', '--hard'], cwd=REPO_DIR)
# clean all untracked files and directories (-d) from repo
check_call(['git', 'clean', '-dffx'], cwd=REPO_DIR)
check_call(['git', 'submodule', 'foreach', 'git', 'clean', '-dffx'], cwd=REPO_DIR)
# check out versions of external dependencies
checkout('tor', versions['tor'], 'external/tor')
checkout('libevent', versions['libevent'], 'external/libevent')
checkout('openssl', versions['openssl'], 'external/openssl')
checkout('xz', versions['xz'], 'external/xz')
checkout('zstd', versions['zstd'], 'external/zstd')
def checkout(name, tag, path):
print("Checking out %s: %s" % (name, tag))
repo_path = os.path.join(REPO_DIR, path)
check_call(['git', 'checkout', '-f', tag], cwd=repo_path)
def build_architectures():
# build arm pie
os.unsetenv('APP_ABI')
os.unsetenv('NDK_PLATFORM_LEVEL')
os.unsetenv('PIEFLAGS')
build_arch('tor_arm_pie.zip')
# build arm
os.putenv('NDK_PLATFORM_LEVEL', '14')
os.putenv('PIEFLAGS', '')
build_arch('tor_arm.zip')
# build x86 pie
os.putenv('APP_ABI', 'x86')
os.unsetenv('NDK_PLATFORM_LEVEL')
os.unsetenv('PIEFLAGS')
build_arch('tor_x86_pie.zip')
# build x86
os.putenv('NDK_PLATFORM_LEVEL', '14')
os.putenv('PIEFLAGS', '')
build_arch('tor_x86.zip')
def build_arch(name):
check_call(['make', '-C', 'external', 'clean', 'tor'], cwd=REPO_DIR)
copy(os.path.join(REPO_DIR, 'external', 'bin', 'tor'), os.path.join(REPO_DIR, 'tor'))
check_call(['strip', '-D', 'tor'], cwd=REPO_DIR)
check_call(['zip', name, 'tor'], cwd=REPO_DIR)
if __name__ == "__main__":
main()
#!/usr/bin/env bash
set -e
set -x
apt-get install -y --no-install-recommends \
python3-pip python3-setuptools python3-wheel \
python3-libarchive-c \
libmagic1
# Install latest diffoscope (version in Debian stable is outdated)
pip3 install diffoscope
\ No newline at end of file
#!/usr/bin/env bash
set -e
set -x
apt-get install -y --no-install-recommends \
git \
zip \
unzip \
wget \
make \
patch \
autopoint \
libtool \
automake \
binutils-multiarch
#!/usr/bin/env bash
set -e
set -x
# update package sources
apt-get update
apt-get -y upgrade
# do not install documentation to keep image small
echo "path-exclude=/usr/share/locale/*" >> /etc/dpkg/dpkg.cfg.d/01_nodoc
echo "path-exclude=/usr/share/man/*" >> /etc/dpkg/dpkg.cfg.d/01_nodoc
echo "path-exclude=/usr/share/doc/*" >> /etc/dpkg/dpkg.cfg.d/01_nodoc
# install dependencies
./install-dependencies.sh
./install-dependencies-verification.sh
# clean up for smaller image size
apt-get -y autoremove --purge
apt-get clean
rm -rf /var/lib/apt/lists/*
{
"0.3.3.6": {
"tor": "tor-0.3.3.6",
"libevent": "release-2.0.22-stable",
"openssl": "OpenSSL_1_0_2o",
"xz": "v5.2.3",
"zstd": "v1.3.2",
"tor-android": "tor-android-binary-0.3.3.5-rc-3",
"tor_android_repo_url": "https://github.com/n8fr8/tor-android",
"ndk": {
"url": "https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip",
"revision": "15.2.4203891",
"sha256": "f01788946733bf6294a36727b99366a18369904eb068a599dde8cca2c1d2ba3c"
}
},
"0.2.9.15": {
"tor": "tor-0.2.9.15",
"libevent": "release-2.0.22-stable",
"openssl": "OpenSSL_1_0_2o",
"xz": "v5.2.3",
"zstd": "v1.3.2",
"tor-android": "tor-android-binary-0.3.3.5-rc-3",
"tor_android_repo_url": "https://github.com/n8fr8/tor-android",
"ndk": {
"url": "https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip",
"revision": "15.2.4203891",
"sha256": "f01788946733bf6294a36727b99366a18369904eb068a599dde8cca2c1d2ba3c"
}
}
}
\ No newline at end of file
#!/usr/bin/env python3
import hashlib
import sys
def fail(msg=""):
sys.stderr.write("Error: %s\n" % msg)
sys.exit(1)
def get_sha256(filename, block_size=65536):
sha256 = hashlib.sha256()
with open(filename, 'rb') as f:
for block in iter(lambda: f.read(block_size), b''):
sha256.update(block)
return sha256.hexdigest()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment