Skip to content

reproducible build process #141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 9, 2014

Conversation

eighthave
Copy link
Collaborator

These commits, in conjuction with the utility faketime, make for a reproducible, deterministic build process so that others can exactly reproduce the official release builds. It includes extra metadata in the jar file about which Java, SDK, and NDK were used to make the given build. This makes it easy to verify that the release build came only from the source in the git repo, and nothing was injected in during the build process.

You can get faketime from various package systems:

 apt-get install faketime
 brew install libfaketime
 fink install libfaketime
 port install libfaketime

This moves jar creation to `ant release`.

To provide build security, it should be possible for anyone to run the
build process and end up with the same result as Zetetic.  To aid that
process, this adds metadata to the release jar that specifies which
versions of Java, Android SDK, and Android NDK were used to build the
official release.
@developernotes
Copy link
Member

Hi @eighthave

This looks pretty slick, thanks! In testing it locally, I found I needed to adjust the UTC specifier when running on OS X:

ifeq ($(shell uname),Darwin)
    UTC_FLAG := -u
else
    UTC_FLAG := --utc
endif
  TIMESTAMP := $(shell faketime "`git log -n1 --format=format:%ai`" \
                   date $(UTC_FLAG) '+%Y-%m-%d %H:%M:%S')

However it is currently failing in the ant release portion of the build. Relevant output below:

-code-gen:
[mergemanifest] No changes in the AndroidManifest files.
     [echo] Handling aidl files...
     [aidl] Found 1 AIDL files.
     [aidl] Compiling 1 AIDL files.
     [aidl] dyld: could not load inserted library '/usr/local/Cellar/libfaketime/0.9.5/lib/faketime/libfaketime.1.dylib' because no suitable image found.  Did find:
     [aidl]     /usr/local/Cellar/libfaketime/0.9.5/lib/faketime/libfaketime.1.dylib: mach-o, but wrong architecture
     [aidl]

BUILD FAILED
/Users/nparker/bin/android-sdk/tools/ant/build.xml:653: The following error occurred while executing this line:
/Users/nparker/bin/android-sdk/tools/ant/build.xml:659: null returned: 133

We currently build our release binary packages on OS X, so we will need to investigate this a bit further.

…mmit

If the `faketime` utility is available, use it to fix the time of the build
based on the time of the current git commit.  This makes the build process
reproducible since anyone who builds it from git will end up with a build
that has the same exact timestamps.

You can get faketime from various package systems:
 apt-get install faketime
 brew install faketime
 port install libfaketime
@eighthave
Copy link
Collaborator Author

Turns out date -u works on Debian, so I just updated the patch to use that.
This is the heart of your issue:

[aidl] dyld: could not load inserted library '/usr/local/Cellar/libfaketime/0.9.5/lib/faketime/libfaketime.1.dylib' because no suitable image found. Did find:
[aidl] /usr/local/Cellar/libfaketime/0.9.5/lib/faketime/libfaketime.1.dylib: mach-o, but wrong architecture

My guess is that it is caused by you using a 32-bit SDK on a 64-bit Mac? Or
maybe a 32-bit Java on a 64-bit Mac? Or a 32-bit libfaketime? You should get
a better idea of which binary has which architecture by doing this:

/usr/bin/file /usr/local/Cellar/libfaketime/0.9.5/lib/faketime/libfaketime.1.dylib
/usr/bin/file $ANDROID_HOME/build-tools/20.0.0/aidl

@eighthave
Copy link
Collaborator Author

Also, I should mention, faketime is not required. The Makefile should work fine if faketime is not installed. But it probably won't create a reproducible build since there might be different timestamps in the build.

@developernotes
Copy link
Member

If it is present, I would prefer it to work if there isn't too much involved to get it working. ☺

That said, you were correct about the architecture differences between aidl and libfaketime.1.dylib. I will see if I can build libfaketime to build to i386.

@brody4hire
Copy link

It would be really cool if we could (also) use a MD5 sum to verify the reproducible build..

@eighthave
Copy link
Collaborator Author

We can do one better: once this process is fully nailed down, then you can use
Zetetic's GPG signature to verify your own build. And of course, the MD5
would also match.

@developernotes
Copy link
Member

Hi @brodybits

You can currently verify the binary package that is distributed against our signing key. We have more info about that here.

sqlipher --> sqlcipher

`git describe` will give only the name of the tag if the current commit
is tagged.  Otherwise, it will get the most recent tag, how many commits
since that tag, and the commit hash id.   This marks non-release builds
clearly and enforces that the release must be made from the proper tagged
git commit.
This script unpacks the zip and jars into a temp folders, then compares
@eighthave
Copy link
Collaborator Author

I got it quite close to having the release zipball generate the exact same hash, but not quite. I think there are 4 bytes that are different in the jar wrapping of sqlcipher.jar, and about 20 bytes in sqlcipher-javadoc.jar. I don't know what is causing that difference. Everything else is an exact match when running the build on Debian/wheezy/amd64 and Ubuntu/precise/amd64. I threw in a script for comparing builds.

@developernotes developernotes merged commit b97c9dd into sqlcipher:master Oct 9, 2014
@eighthave eighthave deleted the reproducible-build branch October 9, 2014 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants