I like to make the build of FairEmail reproducible (with developer’s signature, mine).
There is some documentation about reproducible builds here:
but it is not completely clear what should actually be done to get a reproducible build.
For example, it is unclear which NDK version F-Droid uses.
Preferably the documentation should be updated with steps to accomplish this.
Which one you want: https://f-droid.org/en/docs/Build_Metadata_Reference/#Build
Version of the NDK to use in this build. Defaults to the latest NDK release that included legacy toolchains (12b), so as to not break builds that require toolchains no longer included in current versions of the NDK.
The buildserver supports
r9b with its legacy toolchains, r10e, r11c r12b them all, and the latest release as of writing this document, r21. You may add support for more versions by adding them to ’ndk_paths’ in your config file.
@Licaon_Kter can you please add
This should also be added or linked from in the reproducible build documentation.
What else should be done?
Fixed now, yes: https://gitlab.com/fdroid/fdroid-website/-/merge_requests/501
Umm what exactly? The metadata syntax in general?
Since the NDK version is important for a reproducible build, the documentation should tell that the NDK version should be specified and link to the available NDK versions.
It is important to all apps wanting a reproducible build using native code.
I am using NDK r21, so the .yml file of FairEmail should be updated.
If I understand things correctly a ‘Binaries’ line needs to be added to the .yml file too.
Yes, after we build the unsigned APK is compared to yours (signed with v1 only for the moment) that you/Github hosts.
@Bubu can add more info
The place to start is following the rebuilds on our rebuilder. You can
see some eu.faircode APKs have been reproducible, though not FailEmail:
You can see all the build/repro attempts here:
Then try rebuilding the APK on your machine, using
fdroid build and
then use diffoscope to compare it to the F-Droid APK. Then fix the
differences. Once the APK is reliably reproducible, then you can
consider also using the upstream developer signature, which requires
Then try rebuilding the APK on your machine
Or post here and I run test builds… so you don’t waste time setting up
@hans can you please take a look at:
and maybe tell what is causing the differences?
that one looks like a diffoscope misconfiguration, since it is showing a
diff of binary data
Can this misconfiguration be fixed?
I have made the following changes:
Explicitly specify NDK:
Signature V1 for GitHub/F-Droid build:
@Licaon_Kter both changes likely require changes in the .yml file
@Licaon_Kter based on what I know so far, a reproducible build should be possible with version 1.992
I imagine so. Someone needs to dig into it to figure it out. That can
happen anywhere. My guess is that diffoscope is mislabeling one of the
APKs as somethung else, like a plain JAR or plain ZIP, then doing a
binary comparison. APKs are both valid JARs and valid ZIPs.
BUILD SUCCESSFUL in 37s
52 actionable tasks: 51 executed, 1 up-to-date
INFO: Successfully built version 1.992 of eu.faircode.email
DEBUG: Using androguard from "/usr/lib/python3/dist-packages/androguard/__init__.py"
DEBUG: Checking build/eu.faircode.email/app/build/outputs/apk/full/release/FairEmail-v1.992-full-release-unsigned.apk
INFO: ...retrieving https://github.com/M66B/FairEmail/releases/download/1.992/FairEmail-v1.992-full-github.apk
DEBUG: Starting new HTTPS connection (1): github.com
DEBUG: https://github.com:443 "GET /M66B/FairEmail/releases/download/1.992/FairEmail-v1.992-full-github.apk HTTP/1.1" 302 638
DEBUG: Starting new HTTPS connection (1): github-production-release-asset-2e65be.s3.amazonaws.com
DEBUG: https://github-production-release-asset-2e65be.s3.amazonaws.com:443 "GET /143298715/d8194c80-596f-11ea-803c-7e7046b0d821?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20200227%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20200227T143504Z&X-Amz-Expires=300&X-Amz-Signature=7d46a678f70be8fa38631003323cbf396d3babfa33fd0776fc927ffc49070582&X-Amz-SignedHeaders=host&actor_id=0&response-content-disposition=attachment%3B%20filename%3DFairEmail-v1.992-full-github.apk&response-content-type=application%2Fvnd.android.package-archive HTTP/1.1" 200 12174168
WARNING: Ignoring META-INF/MANIFEST.MF from unsigned/eu.faircode.email_992.apk
DOES NOT VERIFY
ERROR: SHA-256 digest of AndroidManifest.xml does not match the digest specified in META-INF/MANIFEST.MF. Expected: <oTOZfOh8OUkJZrrW3ByzKfy/zl1Rb2Ywg4l3PYpHrwQ=>, actual: <kSPZ+GnUbxRRZw0EvDerKqqEx9jebp9GJ8MVQ/jBjDA=>
ERROR: SHA-256 digest of classes.dex does not match the digest specified in META-INF/MANIFEST.MF. Expected: <IypiPzw/bBi5loZvI01Po2n++AYrLWfo5FSMz7knjWM=>, actual: <asXmVEQg4NzX6H/YLniWSTUgARHS5FRjGP3OrwUiX64=>
ERROR: SHA-256 digest of classes2.dex does not match the digest specified in META-INF/MANIFEST.MF. Expected: <VP6C33A0DM40xWvoMP/5VuN5l2xJuS9gnu//uhzzpQA=>, actual: <B/3V7v91IF5/q0+a+ighqdP8PIbx/U9EdwLgCJKN7Ts=>
INFO: ...NOT verified - /tmp/tmp_s1n3aci/sigcp_eu.faircode.email_992.apk
DEBUG: > diff -r /tmp/tmp_s1n3aci/unsigned_binaries_eu.faircode.email_992.binary /tmp/tmp_s1n3aci/_tmp_tmp_s1n3aci_sigcp_eu.faircode.email_992
DEBUG: removing unsigned/eu.faircode.email_992.apk
DEBUG: removing unsigned/binaries/eu.faircode.email_992.binary.apk
ERROR: Could not build app eu.faircode.email: compared built binary to supplied reference binary but failed
==== detail begin ====
Unexpected diff output:
Binary files /tmp/tmp_s1n3aci/unsigned_binaries_eu.faircode.email_992.binary/content/AndroidManifest.xml and /tmp/tmp_s1n3aci/_tmp_tmp_s1n3aci_sigcp_eu.faircode.email_992/content/AndroidManifest.xml differ
Binary files /tmp/tmp_s1n3aci/unsigned_binaries_eu.faircode.email_992.binary/content/classes2.dex and /tmp/tmp_s1n3aci/_tmp_tmp_s1n3aci_sigcp_eu.faircode.email_992/content/classes2.dex differ
Binary files /tmp/tmp_s1n3aci/unsigned_binaries_eu.faircode.email_992.binary/content/classes.dex and /tmp/tmp_s1n3aci/_tmp_tmp_s1n3aci_sigcp_eu.faircode.email_992/content/classes.dex differ
==== detail end ====
INFO: 1 build failed
I’m comparing with the Github published one, that’s what you want @M66B right?
AuthorName: Marcel Bokhorst (M66B)
- versionName: '1.992'
prebuild: sed -i -e '/keystoreProperties/d' build.gradle
AutoUpdateMode: Version %v
Oh maybe disorderfs needs to be added…brb
Yes, that is what version 1.992 was released for.
Since the manifest and classes differ, I am wondering if the same source code is being used. In any case the are no native libraries different, which is good.