airgap-it / airgap-vault

The AirGap Vault is installed on a spare smartphone that has no connection to any network, thus it is air gapped. This app handles the private key.
MIT License
386 stars 109 forks source link

Cannot reproduce v3.3.0 from Google Play #23

Closed Giszmo closed 4 years ago

Giszmo commented 4 years ago

I tried to reproduce the latest version from Google Play for WalletScrutiny but got a huge diff. I used the same test script as last time when it worked.

I'm pretty sure the build instructions should have changed as I see "1.0" as my build's version and that should be replaced by 3.3.0 I guess.

Files that differ:

Files /tmp/fromPlay_it.airgap.vault_20379/apktool.yml and /tmp/fromBuild_it.airgap.vault_20379/apktool.yml differ
Only in /tmp/fromPlay_it.airgap.vault_20379/assets/public: 38.cea6fa8b879cffca7fe3.js
Only in /tmp/fromBuild_it.airgap.vault_20379/assets/public: 38.e51e7d17dabdb5844377.js
Files /tmp/fromPlay_it.airgap.vault_20379/assets/public/index.html and /tmp/fromBuild_it.airgap.vault_20379/assets/public/index.html differ
Only in /tmp/fromPlay_it.airgap.vault_20379/assets/public: main.07c5ae921df3d9811219.js
Only in /tmp/fromBuild_it.airgap.vault_20379/assets/public: main.4ad3bdee2aeb1e78081d.js
Only in /tmp/fromPlay_it.airgap.vault_20379/assets/public: runtime.5f0fe13d41aff1159105.js
Only in /tmp/fromBuild_it.airgap.vault_20379/assets/public: runtime.8bf3e3c66d45f3bca379.js
Files /tmp/fromPlay_it.airgap.vault_20379/original/AndroidManifest.xml and /tmp/fromBuild_it.airgap.vault_20379/original/AndroidManifest.xml differ
Files /tmp/fromPlay_it.airgap.vault_20379/original/META-INF/MANIFEST.MF and /tmp/fromBuild_it.airgap.vault_20379/original/META-INF/MANIFEST.MF differ
Only in /tmp/fromPlay_it.airgap.vault_20379/original/META-INF: PAPERS.RSA
Only in /tmp/fromPlay_it.airgap.vault_20379/original/META-INF: PAPERS.SF
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/BuildConfig.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/BuildConfig.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/appinfo/AppInfo.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/appinfo/AppInfo.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$authenticate$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$authenticate$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$authenticate$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$authenticate$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$authenticate$3.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$authenticate$3.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$clearWindowSecureFlag$1$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$clearWindowSecureFlag$1$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$Companion.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$Companion.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$getItem$$inlined$with$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$getItem$$inlined$with$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$getItem$$inlined$with$lambda$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$getItem$$inlined$with$lambda$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$getItem$$inlined$with$lambda$3.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$getItem$$inlined$with$lambda$3.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$Key.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$Key.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$Param.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$Param.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$removeItem$$inlined$with$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$removeItem$$inlined$with$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$removeItem$$inlined$with$lambda$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$removeItem$$inlined$with$lambda$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setItem$$inlined$with$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setItem$$inlined$with$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setItem$$inlined$with$lambda$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setItem$$inlined$with$lambda$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setItem$$inlined$with$lambda$3.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setItem$$inlined$with$lambda$3.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupParanoiaPassword$$inlined$with$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupParanoiaPassword$$inlined$with$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupParanoiaPassword$$inlined$with$lambda$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupParanoiaPassword$$inlined$with$lambda$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupRecoveryPassword$$inlined$with$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupRecoveryPassword$$inlined$with$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupRecoveryPassword$$inlined$with$lambda$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupRecoveryPassword$$inlined$with$lambda$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupRecoveryPassword$$inlined$with$lambda$3.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setupRecoveryPassword$$inlined$with$lambda$3.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setWindowSecureFlag$1$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils$setWindowSecureFlag$1$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/SecurityUtils.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Errors.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Errors.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$afterTextChanged$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$afterTextChanged$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$Companion.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$Companion.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$generatePassword$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$generatePassword$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$generatePasswordKey$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$generatePasswordKey$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$readFromSecureStorage$1$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$readFromSecureStorage$1$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$readFromSecureStorage$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$readFromSecureStorage$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$1$1$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$1$1$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$1$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$1$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$error$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoverString$error$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoveryKeyCharacters$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$recoveryKeyCharacters$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordAlert$2$$special$$inlined$apply$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordAlert$2$$special$$inlined$apply$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordAlert$2$$special$$inlined$apply$lambda$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordAlert$2$$special$$inlined$apply$lambda$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordAlert$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordAlert$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2$$special$$inlined$apply$lambda$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2$$special$$inlined$apply$lambda$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showPasswordSetupAlert$2.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showRecoveryAlert$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$showRecoveryAlert$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$writeToSecureStorage$1$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$writeToSecureStorage$1$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$writeToSecureStorage$1.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage$writeToSecureStorage$1.smali differ
Files /tmp/fromPlay_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage.smali and /tmp/fromBuild_it.airgap.vault_20379/smali/it/airgap/vault/plugin/securityutils/storage/Storage.smali differ
AndreasGassmann commented 4 years ago

Hi, thanks for reaching out. That shouldn't be the case.

I'll investigate ASAP and get back to you.

Giszmo commented 4 years ago

It's 2am here. Sorry I probably will not update the site without sleeping a bit first. Also sorry for publishing such alerts without checking back with you but it's kind of a race if the new release was bad, which I assume it is not but just in principle. I worded the tweet carefully.

I hope we get to a point where new releases can get checked for rebuildability earlier. I'm still figuring out how that could best be done. I guess ideally projects would add the build with or without signature to their repo or another place where a script can easily find it. Then hopefully rebuild issues would get sorted out before Google approves the release.

AndreasGassmann commented 4 years ago

No worries. It is unfortunate this happened, but alerting users to hold off with updating in such a case is exactly what your project should be doing.

I agree, there should have an automated way to make sure the APK is verifiable before we submit it to the playstore. Let's have a chat about that in your repository.

AndreasGassmann commented 4 years ago

So I finally had time to look at this and I found 2 issues:

  1. We recently changed from using cordova to capacitor. While the main build still happens in the docker and doesn't have to be changed in your script, the replacement of the version number is now in a different place. I fixed that in this PR: https://gitlab.com/walletscrutiny/walletScrutinyCom/-/merge_requests/63

  2. Regarding the reproducibility of the latest version: It looks like the reason for this was a simple commit hash mixup. We created the tag for 3.3.0 a week ago when we submitted the APK to the playstore, but we then found an issue with that release and created an updated version, which we released to the play store last friday. I did not remember that we had already released the 3.3.0 tag, so that tag was referencing an old commit hash. I re-created the tag to point to the correct commit.

We'll try to improve the handling of tags/releases in the future, also regarding signing tags: https://github.com/airgap-it/airgap-vault/issues/20

I hope that fixes the issue and you can update our status to reproducible again. :)

Giszmo commented 4 years ago

Thanks for the MR. It worked. Website is updated.

Please consider commenting on this issue in order to prevent such down-times. I get stressed when I have to warn of rebuild issues as they usually are not actually big issues. And some wallets react less relaxed than you guys, too, adding to the stress. I'd hope to get to a point where each wallet does the necessary changes to the test script before I or any rebuilder might get to deal with the new release and ideally I would get the apk stripped of its signature as soon as it's built. This would be for later when failed rebuilds trigger actual warnings to users that care. Now, nobody cares yet.

AndreasGassmann commented 4 years ago

Thanks for updating the website and we will comment on your issue.

EDIT: Maybe just to add to your comment. We are planning to integrate some kind of automatic step to make sure the build is reproducible. But I would consider it our responsibility to make sure our builds are verifiable in any case, so if they are not because of a build script change or a tag issue (like it was in our case), it shouldn't add to your stress levels, at least not from our side.

Giszmo commented 4 years ago

it shouldn't add to your stress levels

I agree and I appreciate you see it like that but others don't and with 165 wallet apps out there and none getting shunned over any such issue leaves less committed players attack me on Twitter without problem. Look how Samourai have tons of fan-boys despite them being hostile to any form of scrutiny and openly reject rebuildability.

I want to establish something with patience and therefore the top category is green despite there not being any wallet that has

I don't know how smaller and not-for-profit open source projects could live up to such standards but without scrutiny, nobody should trust any wallet. I have some ideas how to raise the bar further but for now I hope to see more apps to join the ranks of reproducible wallets.

AndreasGassmann commented 4 years ago

I would definitely like to see how we can raise the bar even further. But you're probably right, first the wallets in the non-reproducible list should be convinced to make the effort to become reproducible.

One last thing, could you maybe send out another tweet saying that 3.3.0 is now reproducible?

Giszmo commented 4 years ago

One last thing, could you maybe send out another tweet saying that 3.3.0 is now reproducible?

Yes, sorry, wanted to do that anyway. Multitasking ...