Skip to content
Snippets Groups Projects
Commit 91173d85 authored by Torsten Grote's avatar Torsten Grote
Browse files

Merge branch 'reproduce-briar-headless-jar' into 'master'

Reproduce briar-headless.jar

See merge request briar-reproducer!4
parents 1dc7fe8a bf1579c8
No related branches found
No related tags found
No related merge requests found
.idea .idea
*.apk *.apk
*.jar
briar/
...@@ -30,7 +30,7 @@ test_success: ...@@ -30,7 +30,7 @@ test_success:
script: script:
# Consider adding the cap and the device directly to the CI config # Consider adding the cap and the device directly to the CI config
# https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-docker-section # https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-docker-section
- docker run --cap-add SYS_ADMIN --device /dev/fuse ${TEST_IMAGE} ./reproduce.py release-1.1.7 - docker run --cap-add SYS_ADMIN --device /dev/fuse ${TEST_IMAGE} ./reproduce.py release-1.2.10
except: except:
- triggers - triggers
......
...@@ -9,8 +9,7 @@ WORKDIR /opt/briar-reproducer ...@@ -9,8 +9,7 @@ WORKDIR /opt/briar-reproducer
# add required files to WORKDIR # add required files to WORKDIR
ADD install*.sh ./ ADD install*.sh ./
ADD verify-apk.py ./ ADD *.py ./
ADD reproduce.py ./
RUN ./install.sh RUN ./install.sh
......
#!/usr/bin/env python3 #!/usr/bin/env python3
import atexit
import os import os
import sys import sys
from subprocess import call, check_call, check_output from subprocess import call, check_call, check_output
from verify_apk import verify_apk
from verify_jar import verify_jar
from utils import fail
REPO_DIR = "briar" REPO_DIR = "briar"
REFERENCE_URL = 'https://briarproject.org/apk/briar-%s.apk' REFERENCE_APK_URL = 'https://briarproject.org/apk/briar-%s.apk'
GRADLE_TASK = "briar-android:assembleRelease" REFERENCE_JAR_URL = 'https://briarproject.org/jar/briar-headless-%s.jar'
GRADLE_APK_TASK = "briar-android:assembleRelease"
GRADLE_JAR_TASK = "briar-headless:assemble"
APK_PATH = "briar-android/build/outputs/apk/official/release/" + \ APK_PATH = "briar-android/build/outputs/apk/official/release/" + \
"briar-android-official-release-unsigned.apk" "briar-android-official-release-unsigned.apk"
OLD_APK_PATH = "briar-android/build/outputs/apk/release/briar-android-release-unsigned.apk" OLD_APK_PATH = "briar-android/build/outputs/apk/release/briar-android-release-unsigned.apk"
JAR_PATH= "briar-headless/build/libs/briar-headless.jar"
BUILD_DIR = "briar-build" BUILD_DIR = "briar-build"
...@@ -21,28 +28,39 @@ def main(): ...@@ -21,28 +28,39 @@ def main():
# clone/reset repo and checkout tag # clone/reset repo and checkout tag
tag = prepare_repo(tag) tag = prepare_repo(tag)
# download reference binary (before building to detect missing file early on) # download reference binaries (before building to detect missing file early on)
version = tag.split('-')[1] version = tag.split('-')[1]
url = REFERENCE_URL % version apk_url = REFERENCE_APK_URL % version
reference_apk = "briar-%s.apk" % version reference_apk = "briar-%s.apk" % version
check_call(['wget', '--no-verbose', url, '-O', reference_apk]) check_call(['wget', '--no-verbose', apk_url, '-O', reference_apk])
jar_url = REFERENCE_JAR_URL % version
reference_jar = "briar-headless-%s.jar" % version
if version >= "1.2.10":
check_call(['wget', '--no-verbose', jar_url, '-O', reference_jar])
# use non-deterministic file system for building the app to detect issues # use non-deterministic file system for building the app to detect issues
if not os.path.exists(BUILD_DIR): if not os.path.exists(BUILD_DIR):
os.makedirs(BUILD_DIR) os.makedirs(BUILD_DIR)
check_call(['disorderfs', '--shuffle-dirents=yes', REPO_DIR, BUILD_DIR]) check_call(['disorderfs', '--shuffle-dirents=yes', REPO_DIR, BUILD_DIR])
atexit.register(unmount)
# build the app # build the app
check_call(["./gradlew", "--no-daemon", GRADLE_TASK], cwd=BUILD_DIR) check_call(["./gradlew", "--no-daemon", GRADLE_APK_TASK, GRADLE_JAR_TASK], cwd=BUILD_DIR)
# check if both APKs match # check if both APKs match
apk = os.path.join(BUILD_DIR, APK_PATH if version >= "1.1.0" else OLD_APK_PATH) apk = os.path.join(BUILD_DIR, APK_PATH if version >= "1.1.0" else OLD_APK_PATH)
if call(['./verify-apk.py', reference_apk, apk]) == 0: if not verify_apk(reference_apk, apk):
print("Version '%s' was built reproducible! :)" % tag)
sys.exit(0)
else:
sys.exit(1) sys.exit(1)
# check if both jars match
if version >= "1.2.10":
jar = os.path.join(BUILD_DIR, JAR_PATH)
if not verify_jar(reference_jar, jar):
sys.exit(1)
print("Version '%s' was built reproducible! :)" % tag)
def prepare_repo(tag): def prepare_repo(tag):
if os.path.isdir(REPO_DIR): if os.path.isdir(REPO_DIR):
...@@ -76,9 +94,8 @@ def repo_call(command): ...@@ -76,9 +94,8 @@ def repo_call(command):
check_call(command, cwd=REPO_DIR) check_call(command, cwd=REPO_DIR)
def fail(msg=""): def unmount():
sys.stderr.write(msg + "\n") call(['fusermount', '-u', BUILD_DIR])
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
......
utils.py 0 → 100755
#!/usr/bin/env python3
import hashlib
import sys
def calc_hash(filename, block_size=65536):
sha512 = hashlib.sha512()
with open(filename, 'rb') as f:
for block in iter(lambda: f.read(block_size), b''):
sha512.update(block)
return sha512.hexdigest()
def fail(msg=""):
sys.stderr.write(msg + "\n")
sys.exit(1)
#!/usr/bin/env python3 #!/usr/bin/env python3
import hashlib
import os import os
import re import re
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
import zipfile import zipfile
from utils import calc_hash, fail
APK_SIG_FILE = re.compile(r'META-INF/[0-9A-Za-z_\-]+\.(SF|RSA|DSA|EC|MF)') APK_SIG_FILE = re.compile(r'META-INF/[0-9A-Za-z_\-]+\.(SF|RSA|DSA|EC|MF)')
...@@ -14,15 +14,17 @@ APK_SIG_FILE = re.compile(r'META-INF/[0-9A-Za-z_\-]+\.(SF|RSA|DSA|EC|MF)') ...@@ -14,15 +14,17 @@ APK_SIG_FILE = re.compile(r'META-INF/[0-9A-Za-z_\-]+\.(SF|RSA|DSA|EC|MF)')
def main(): def main():
if len(sys.argv) != 3: if len(sys.argv) != 3:
fail("Usage: %s referenceAPK builtAPK" % sys.argv[0]) fail("Usage: %s referenceAPK builtAPK" % sys.argv[0])
verify(sys.argv[1], sys.argv[2]) if not verify_apk(sys.argv[1], sys.argv[2]): sys.exit(1)
def verify(reference_apk, built_apk): def verify_apk(reference_apk, built_apk):
if not os.path.isfile(reference_apk): if not os.path.isfile(reference_apk):
fail("Can not verify: Reference APK '%s' does not exists" % reference_apk) sys.stderr.write("Cannot verify: Reference APK '%s' does not exist" % reference_apk)
return False
if not os.path.isfile(built_apk): if not os.path.isfile(built_apk):
fail("Can not verify: Built APK '%s' does not exists" % built_apk) sys.stderr.write("Cannot verify: Built APK '%s' does not exist" % built_apk)
return False
with tempfile.TemporaryDirectory() as tmp_dir: with tempfile.TemporaryDirectory() as tmp_dir:
# repack reference APK # repack reference APK
...@@ -37,10 +39,11 @@ def verify(reference_apk, built_apk): ...@@ -37,10 +39,11 @@ def verify(reference_apk, built_apk):
if calc_hash(reference_tmp) != calc_hash(built_tmp): if calc_hash(reference_tmp) != calc_hash(built_tmp):
sys.stderr.write("Mismatch detected. Trying to find reason...\n") sys.stderr.write("Mismatch detected. Trying to find reason...\n")
subprocess.call(['diffoscope', reference_tmp, built_tmp]) subprocess.call(['diffoscope', reference_tmp, built_tmp])
fail("Files do NOT match! :(") sys.stderr.write("Files do NOT match! :(")
return False
else: else:
print("Files match! :)") print("Files match! :)")
sys.exit(0) return True
def repack_apk(zip_file, new_zip_file): def repack_apk(zip_file, new_zip_file):
...@@ -60,18 +63,5 @@ def repack_apk(zip_file, new_zip_file): ...@@ -60,18 +63,5 @@ def repack_apk(zip_file, new_zip_file):
tmp.writestr(info, f.read(info.filename)) tmp.writestr(info, f.read(info.filename))
def calc_hash(filename, block_size=65536):
sha512 = hashlib.sha512()
with open(filename, 'rb') as f:
for block in iter(lambda: f.read(block_size), b''):
sha512.update(block)
return sha512.hexdigest()
def fail(msg=""):
sys.stderr.write(msg + "\n")
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
#!/usr/bin/env python3
import os
import subprocess
import sys
from utils import calc_hash, fail
def main():
if len(sys.argv) != 3:
fail("Usage: %s reference_jar built_jar" % sys.argv[0])
if not verify_jar(sys.argv[1], sys.argv[2]): sys.exit(1)
def verify_jar(reference_jar, built_jar):
if not os.path.isfile(reference_jar):
sys.stderr.write("Cannot verify: Reference jar '%s' does not exist" % reference_jar)
return False
if not os.path.isfile(built_jar):
sys.stderr.write("Cannot verify: Built jar '%s' does not exist" % built_jar)
return False
if calc_hash(reference_jar) != calc_hash(built_jar):
sys.stderr.write("Mismatch detected. Trying to find reason...\n")
subprocess.call(['diffoscope', reference_jar, built_jar])
sys.stderr.write("Files do NOT match! :(")
return False
else:
print("Files match! :)")
return True
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment