Open Giszmo opened 3 years ago
it's INCORRECT to compare apk generated from ./gradlew assembleRelease
to apk downloaded from google-play if appbundle is used, in such case a apk generated with bundletool
from the aab file generated by ./gradlew bundleRelease
need to be done.
steps are (all commands to run in the Containerfile I written in: https://gitlab.com/walletscrutiny/walletScrutinyCom/-/issues/208):
download bundletool latest release (currently it's 1.6.0):
cd /home/appuser/app/sdk/; \
wget https://github.com/google/bundletool/releases/download/1.6.0/bundletool-all-1.6.0.jar; \
echo "fdabaa9137dd9d346a3571d010ee4404a4bae3f1641ebe2236ed4b74ee73bf6f bundletool-all-1.6.0.jar" | sha256sum -c;
Build universal apk (this is done to compare against published apks which built this way, some providers do for apk uploaded to github, which is aked in issue #8)
cd /home/appuser/app/bitcoinorg; \
java -jar /home/appuser/app/sdk/bundletool-all-1.6.0.jar build-apks --bundle=/home/appuser/app/bitcoinorg/BitcoinWalletMobile/android/app/build/outputs/bundle/release/app-release.aab --mode=universal --output=/home/appuser/app/bitcoinorg/bitcoinorg-universal.apks; \
unzip /home/appuser/app/bitcoinorg/bitcoinorg-universal.apks
The universal apk will be located at: /home/appuser/app/bitcoinorg/universal.apk
Build matched apk to compare against apk downloaded from google-play
cd /home/appuser/app/bitcoinorg;
java -jar /home/appuser/app/sdk/bundletool-all-1.6.0.jar build-apks --bundle=/home/appuser/app/bitcoinorg/BitcoinWalletMobile/android/app/build/outputs/bundle/release/app-release.aab --output=/home/appuser/app/bitcoinorg/bitcoinorg-all.apks; \
Which will generate bitcoinorg-all.apks
file, using it in below command bundletool extract-apks
with matched --device-spec
argument to the device used to download apk from google-play is needed.
For example, Create file /home/appuser/app/sdk/pixel2.json
with content:
{
"supportedAbis": ["arm64-v8a", "armeabi-v7a", "armeabi"],
"supportedLocales": ["en-US"],
"screenDensity": 560,
"sdkVersion": 30
}
Then run:
java -jar /home/appuser/app/sdk/bundletool-all-1.6.0.jar extract-apks --apks=/home/appuser/app/bitcoinorg/bitcoinorg-all.apks --output-dir=/home/appuser/app/bitcoinorg/bitcoinorg-pixel2-apks --device-spec=/home/appuser/app/sdk/pixel2.json
which will generate apks in directory /home/appuser/app/bitcoinorg/bitcoinorg-pixel2-apks
that should be compared to what downloaded from google-play.
This are the steps to create apk that is matched to what downloaded from google-play when appbundles are used, unfortunately while writing this the google-play url return "We're sorry, the requested URL was not found on this server.", opened issue about it in: #9
if you have apk downloaded from google-play, create the apk from appbundle as described above (The json file need to match the spec used to download app from google-play) and publish the results.
Thanks for looking at the wallet. Please keep in mind for now that the only reason the wallet was on the app store was to monitor and test live usage patterns. It's not actually fully "released" as I'm not 100% confident about pushing users towards it.
@emanuelb: Good catch on figuring out how to get a reproducible build. I'm going to use your response as a template for general build instructions on how to reproduce.
@emanuelb what's it with the "INCORRECT"? Absent build instructions, it's as correct as any other attempt at building this app, so please don't shout at me.
Reproducible builds make little sense when there is a custom build for every user or even only a huge combinatory variety of possible builds. The approach can't be to build them all. At WalletScrutiny we attest that app X with version Y and hash Z is indeed built from the source but that's really only helpful for users of the app with hash Z. All the others might have a rogue app.
@Cobra-Bitcoin please provide build instructions for reproducibility. Given an apk, how can I reproduce it from the code here?
@emanuelb in other words, if somebody shares his apk with me, I cannot reproduce the apk without knowing how he got it from Google Play? That's pretty sick. (I'll further investigate this part, too.)
That's how appbundle works, not sure there is a way for provider to turn them off when it's was enabled on google-play, also google is pushing hard for appbundles (might be mandatory for new apps), appbundle & splitting is fine (except the part where signing keys are uploaded to google, this part is very bad... shame on google for adding this additonal not-needed evil requirement...)
My intent is not to shout, I wrote in related gitlab issue that the missing step for verification is appbundle compare, probably wasn't clear enough about it... was planning to test it myself after they fixed the other issues I reported (or some of them) and publish newer version, anyway the instructions are in my previous comment here...
reproducible-builds makes lots of sense for appbundle as well, they just require different verification routine:
if the app on google-play use appbundles, using bundletool
to create the apk with device-spec that match what was used to download the apk is needed... that's how it's work... comparing it to universal apk (created from appbundle or by assembleRelease) is incorrect and will show diffs in XML files & missing files, etc... it's wrong comparison...
When appbundle is enabled on google-play, different devices will receive different APK depending on several factors like screen size, the arch of the device, etc...
Even if app don't use appbundles, the fact that you verified 1 apk doesn't mean another user will receive it, vendor can send another apk on google-play for other android versions, or for users in other countries etc... so enumeration is still needed for coverage, for full coverage "binary transparency" is needed.
The first step in verification is to ensure reproducible-builds is possible for 1 tested apk, increasing coverage is other issue (will require downloading more apks...)
I would have showed end-to-end diff/diffoscope for this app, but I can't download it as google-play return 404 (was removed temporary) The bitcoin paper-wallet is using appbundle: https://github.com/ValleZ/Paper-Wallet/ will test it later & publish the results in the related issue in the repo...
That's how appbundle works, not sure there is a way for provider to turn them off when it's was enabled on google-play,
It's impossible to opt out after opting in.
also google is pushing hard for appbundles (might be mandatory for new apps),
Not yet but I agree it's likely to happen.
The rest of your comment is more for the WalletScrutiny issue tracker than for here. We knew AAB is coming. You consider it to be on us to figure out. I consider it on the provider to figure it out as he can't really make any guarantees about an app if he can't reproduce stuff neither but the provider probably has access to the app bundle which the end user almost certainly does not.
The provider can upload .aab file in github releases, some of them do, I consider it useless as it's not helpful for users (as .aab installation not possible on device directly) and require first to extract apk from it using bundletool build-apks
or installing with bundletool install-apks
commands.
for reproducible-builds downloading .aab file it's not needed either, as published universal-apk built from it is useful to users and can be verified by creating it the same way (aab -> bundletool --mode=universal
-> unzip > verify "universal.apk")
for testing apk downloaded from google-play, same device-spec should be used (for downloading, and in bundletool)
so I see no reason to publish .aab in github releases, publishing .ipa is useful as it's like .apk & the apple server-side mechanism which is like bundletool is not open-source and even available... so knowing what's the provider uploaded is useful to compare against.
It make sense and should be done for the provider to reproduce .aab on different environments before uploading it to google-play
I tried to reproduce the app I got from Google Play to make sure it matches the published source code but failed. My findings will be public on WalletScrutiny. The short version of the analysis is:
After running
The diff with what I get from Google Play is huge:
The diff ignoring what was only in my build and not in the Google version and the META-INF lines is still huge, with
index.android.bundle
being obfuscated (minified) code.