-
Notifications
You must be signed in to change notification settings - Fork 211
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
Building CakeWallet Android App 4.4.0 failed with haven_wallet errors, Missing cw_haven realted build instructions? #337
Comments
How is progress on this? How can we compile this app? |
Why was this issue closed without any investigation or explanation? I'm concerned that the APK was demonstrably NOT reproducible. |
Hi, was a mistake to close this issue without a resolution.... as this issue was from 2 years ago, the build guide has been updated since then and I believe this is what you need:
Please have a look the current build guide and try building the latest main or version tag: https://github.com/cake-tech/cake_wallet/blob/main/howto-build-android.md For discussion on 1 to 1 binary reproduceability, #112 and #338 will still be open. Let us know if you have any other build questions 😃 |
Cool. In relation to current attempts by WalletScrutiny to re-verify apps, I'm opening an issue for walletscrutiny.com again. Hopefully, this app can be verified. |
The issue is here: https://gitlab.com/walletscrutiny/walletScrutinyCom/-/issues/537 We have our plates full though - so if anybody would like to boost the spirit of Open Source, you are most welcome to build this app. |
Hi, I tried to build the latest version,
This is the dockerfile i created. this follows the build instructions provided in the
It is in my understanding a dependency conflict, which arises due to flutter_localizations requiring intl version 0.19.0, while cake_wallet depends on intl version ^0.18.0. This version conflict causes the resolution process to fail. I tried to fix this by manually finding and fixing the file:
but sadly that didn't work. I also tried deleting the pubspec.lock so it can be generated later, but that also didn't work. Any idea or suggestion on what to do next on this? |
Hello, I wrote a new working docker as of last commit b8ffd47 compiling a working APK I believe v4.20.1 is building and working fine, Building logs here, Dockerfile here Commented lines for easy env fill
|
hey, keraliss from walletscrutiny here!! I was able to build the apks using the dockerfile provided by @Justxd22 .
there were also 700+ lines of diff for xml and png files. would be great if you guys can look into it! |
@sethforprivacy what do you think of this! |
I'll look into this over the next week. At the moment Cake isn't reproducible regardless of these random xml and png files (not sure why) because of the API key secrets that are added during build time that aren't in the repository. |
This might be standard if they have flutter_icons installed and the versions have been upgraded and those extra images type could be rendered legitimately from a source image (sorry I should check pubspec on phone and in rush). Or if you want to lay as the sceptic you could say.. So making changes, cause that could be potentially malicious, or potentially good.. They should be check for basic steganography, pull a dictionary on Linux, and see if there are any hex code to ascii which match’s to anything in the dictionary where the word is at least 3 characters long (we’re looking for encoded human readable or suspicious looking strings that wouldn’t otherwise be in an image. You might have to look at every image to find anything unless there is a valid justification for this change I personally would avoid compiling and running it myself, and I use DispableVMs in Qubes-Whonix, it’s also with checking the mimetype is definitely and image/ which are basically just file types, I don’t think there is any excuse for there to be anything that sys the word application, binary. (edited) I can be normal for exception less images to be referenced that’s how Java/Android like to do things, you could try building an alternate platform. See if the same kind of things happen. Checking the hex’s too etc. There is a useful Snap on Snapcraft to check hex (i known some people hate snap, but it’s not that bad anymore) heehe Also. I figured cw_monero was the proprietary part, no? I mean that’s where all the value is really. |
@KewbitXMR no, cw_monero is not proprietary.. it is in main directory of the project... |
Hey everyone, danny here from @WalletScrutiny, I'm picking up here where I left of with v4.23.0. Attempt 1: Previous attempts primarily centered on generating single-apks. I would document my attempts here. 2025-02-08WS primary methodology for verifying split apks, revolves around the testAAB.sh script Here the version number is determined, the app hashes reported, and passed on to the more flexible script and dockerfile: Encountered an error:
Build 1 - fail Error:
|
Hey @xrviv, thanks so much for taking a look at this! I'm working right now to update our build docs + Dockerize the build process, will report back when that's done and we can get down to details of what is/isn't the same between release APKs and those built from source. |
@xrviv please follow up in this thread https://forum.cakewallet.com/t/wallet-scrutiny-review-process/59 the error you posted related to mwebd should be fixed using the dockerfile i posted line 83 https://github.com/Justxd22/Cake_wallet_DOCKER_xD/blob/main/cakeRELEASE.Dockerfile#L83 |
Thank you, There are currently 3 venues for the build, so to comply with both WalletScrutiny.com's requirements and yours, I will mirror my attempts: cakewallet forum and here
I encountered an error:
I am modifying the dockerfile slightly. continuing. With Build 008 I was able to get past that error and reach the build process stage, by modifying the Dockerfile like so:
This is the latest error:
Explanation for the error:
Some Progress 2025-02-10 18:35Build 009 - Success! But need to target more specific to arch of builder's phone - Dockerfile |
I'm not sure that simply downloading the necessary libraries properly fits the goal of reproducibility here, even if it does greatly simplify builds. I've opened a draft PR with my docs and Dockerfile changes, feel free to peruse those to see if anything is useful in your quest to reproduce Cake Wallet: |
I made it optional to use pre-built for faster build time vs build the binaries https://github.com/Justxd22/Cake_wallet_DOCKER_xD?tab=readme-ov-file#how-to-build |
Thank you. I will test the dockerfile. |
Seth's Dockerfile
|
@xrviv second link is broken |
fixed, thanks. this one: ✅ Builds Monero dependencies from source. It's taking quite some time though. So no results yet
I will try again tomorrow. |
I'ved pushed an updated Dockerfile, with a revised way to build out of it. With the new Dockerfile in the PR, you can build for Android like this: docker build -t cake-builder:latest .
docker run -v$(pwd):$(pwd) -w $(pwd) -i --rm cake-builder:latest bash -x << EOF
pushd scripts/android
source ./app_env.sh cakewallet
./app_config.sh
./build_monero_all.sh
./build_mwebd.sh --dont-install
popd
pushd android/app
[[ -f key.jks ]] || keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass hunter1 -keypass hunter1
popd
./model_generator.sh
dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=hunter1 keyPassword=hunter1
dart run tool/generate_localization.dart
dart run tool/generate_new_secrets.dart
flutter build apk --release --split-per-abi
EOF
Note that I am still testing this build process myself, so might be worth waiting a bit. Just didn't want you working on the old Dockerfile for longer than necessary. |
For the sake of argument I'll invest few minutes of my time into this issue, and I'll drop you a couple links and insights in regards to the reproducible build. First APKs are not reproducible. They just aren't. It is simply because of the apk signature, with V1 it was quite simple, you just exclude couple of META-INF/* files, v2 and v3 live at the end of zip's cdr, but still - not a single person in this thread attempted to strip the signature. Doing so is explained nicely by fdroid Now that we know that simple What is a reproducible build? Part oneThis one is easy. It's a build that you can reproduce locally. Actually. No. Let's start from the beginning: What is a non-reproducible build?Essentially this.
We have an input that is open source, it lives entirely under this repository, and we have different outputs when we build it. Why? For the most part because of metadata. Let's take a look at monero_c, I know that it will diff from the outcome of your build, so let's skip straight to the differences. $ wget https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.3.4-RC10/wownero_aarch64-linux-gnu_libwallet2_api_c.so.xz -O - | unxz > monero_libwallet2_api_c.so
$ strings monero_libwallet2_api_c.so | grep /__w
<around 759 entries like this one>
/__w/monero_c/monero_c/wownero/src/wallet/wallet2.cpp:16168 Okay, for those who don't know, GitHub Actions mount docker containers in a directory called
instead of this:
(AI generated crash, no software was harmed during writing of this comment). Sure, we can derive where the crash is happening but it is convenient for us to just Ctrl(or ⌘ for apple users) + mouse click in terminal to open the crashing file+line. Okay, this was the easy part. It is possible to build monero reproducibly (it's just monero_c that doesn't really prioritize that), we also learned that the environment in which software is being built, and that environment affects build outcome. That's why monero is moving towards the use of Guix in order to achieve reproducible builds (previously Monero used gitian). What is a reproducible build? Part two
In this case no matter how many times and on what machine you rebuild the software you will end up with the same output binary. This is what everyone in here tries to achieve. I think. Everyone in here is using Docker to achieve reproducible builds, some even relying on 3rd party images to reduce the lines of Dockerfile you have to write. In most of the attempts you didn't even specify the source code hash, which... Do I really need to? Yes? Okay, running a build once and then again later, after changes were made to the source code will result in different output binary... obviously. So first of all - pin the hash of source code. Then you can start to consider working on a reproducible build. I lied. What is a bootstrapable build?Okay. So having said all that, let's try to make a reproducible toolchain that will output reproducible cake wallet .apk. I have decided to use Go since package main
import (
"embed"
"io"
"log"
"os"
"path/filepath"
)
//go:embed Cake_Wallet_v4.23.0_246.apk
var embeddedFile embed.FS
func main() {
log.Println("Starting extraction...")
targetDir := "build"
targetFile := filepath.Join(targetDir, "Cake_Wallet_v4.23.0_246.apk")
if err := os.MkdirAll(targetDir, 0755); err != nil {
log.Fatalf("Failed to create directory %s: %v", targetDir, err)
}
log.Println("Created build directory")
inputFile, err := embeddedFile.Open("Cake_Wallet_v4.23.0_246.apk")
if err != nil {
log.Fatalf("Failed to open embedded file: %v", err)
}
defer inputFile.Close()
log.Println("Opened embedded APK")
outputFile, err := os.Create(targetFile)
if err != nil {
log.Fatalf("Failed to create output file: %v", err)
}
defer outputFile.Close()
log.Println("Created output file")
if _, err := io.Copy(outputFile, inputFile); err != nil {
log.Fatalf("Failed to write file: %v", err)
}
log.Println("Extraction complete: ", targetFile)
} It takes less than a second to reproducibly produce current release of cake wallet. $ time ./cake_builder
2025/02/10 31:75:07 Starting extraction...
2025/02/10 31:75:07 Created build directory
2025/02/10 31:75:07 Opened embedded APK
2025/02/10 31:75:07 Created output file
2025/02/10 31:75:07 Extraction complete: build/Cake_Wallet_v4.23.0_246.apk
./cake_builder 0.01s user 0.06s system 90% cpu 0.085 total The apk will be exactly the same no matter where you run the code. Obviously. There is actually a shorter version of that command. You can just As a bonus point this method required ~300MiB of space, since I see that in the table above running Okay, this joke is too long and not funny. But I had to make a point. All of you would agree that this is not really a favorable way of getting reproducible .apk right? Despite the fact that it will always output the same .apk file you probably don't feel confident. I got slightly triggered by:
No. That's not the point. That's opposite of the point. But back on track.
Would you call the Go code I made trusted? No. At least you shouldn't; if you do, then... seek help. So what is a Trusted Bootstrap Binary? For our case it is the enormous 20GiB+ Dockerfile with all dependencies, including things such as:
Now without looking it up, can you name a single proprietary component in that list? No? It's cmdline-tools. But I'm getting sidetracked again. If you want your build to result in a reproducible .apk you need to:
There is a fun story that you may want to take a look at: The point I'm trying to make here is: as long as there is any binary code that is not trusted the output cannot be trusted. Final thoughtsI wrote this post not as someone who is employed by Cake but by someone who doesn't like AI generated content and bounties (and this discussion appears to be both at the same time). If you want cake wallet to be reproducible, please start with dependencies. I welcome you to start your journey with making sure that monero_c is reproducible, as it is a project that is used by Cake Wallet, and is currently not reproducible - so you need to do it anyway in order to achieve reproducible Cake Wallet builds. And it may be relatively easy because the biggest dependency (monero, wownero and zano) have reproducible builds available. I would personally use Guix or Nix to achieve it, but I'll leave that up to you. I and everyone else would love to see reproducible cake wallet, but it is not an easy task. It's much more than going to this repo and creating a Dockerfile that builds the apk, and as far as you can probably tell there are a couple of open PR that need merging, some issues that need fixing and making builds fully reproducible is not our highest priority. That being said we are making small steps to achieve it. |
Adding to what MrCyjaneK said, we should start using pre-built bins from https://github.com/MrCyjaneK/monero_c for the sake of keeping things simple and start verifying if these bins are reproducible first, get hashes, Then we can continue the build process |
@Justxd22 Whatever you guys prefer, however it makes little to no sense to verify hashes if you know they are not going to match. However to encourage you to do that properly, there is a bounty on making reproducible builds of monero_c MrCyjaneK/monero_c#113 |
@MrCyjaneK yes, we could do better but we don't use the hashes of APKs for reproducibility testing neither. We document the hashes of signed APKs to recognize them when we see them again. Instead of reproducing an APK with zeroed signature, we currently treat the APK as a zip file, trust that zip works in converting folder to file and back and compare the content of signed APKs with the content of built APKs. Higher signature schemes conveniently do not show up when unzipping but you are right it's not perfect to just ignore what we don't see. We are open for suggestions on how to improve that but I sort of trust the engineers at Google to not run binaries outside the Manifest so apart from some serious bugs it's a valid approach. Furthermore your "build script" that only takes the built apk and calls it a build is a concern but at WalletScrutiny our stance is that this might happen with any binary blob well hidden in the build process. We merely attest to reproducibility and consider the detection of backdoors in plain sight or binary blobs a responsibility of code reviewers. Whenever we detect binary dependencies especially under the control of the wallet provider or other crypto adjacent libraries we require these to be reproducible, too. In Cake's case the Monero binary for example. If we fail with our approach to reproduce products, we consider it a red flag. If we manage to reproduce then we consider the project worthy of code reviews as surely absent of reproducibility, findings during a code review might not relate to what people run on their devices. |
Hey guys, as we've resolved the build issues that this original issue is related to, do you mind if we close out this issue? Would be best to move the discussion either into the forum post below, or into a new issue that could be more centered on reproducibility if possible. https://forum.cakewallet.com/t/wallet-scrutiny-review-process/59/4 |
I thank you for the time spent crafting this response and I am glad for the opportunity to learn something new.
If I got that correctly, well, yes. After doing this for so many apps, we do actually notice the differences. Strict reproducibility is not possible that's why the endeavor is to show which files in a build do differ. In that light, we are coming up with a list of acceptable diffs as we accumulate experience across different projects: We would like to invite you for your valuable input on the matter. I first noticed these file exclusions on bitkey, then later on bitbanana, and then finally nunchuk. |
It seems like we are in agreement to move this conversation to the forum or a new issue, so I'll let y'all choose which of those you'd like. |
New issue it is! |
Build 4.4.0 failed with errors:
Running:
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. ;
as it's looks like errors cause such command is missing in build instructions, maybe loop over array instead that contain the
cw_strings
values instead, as it run the same commands just in different directory.Return:
Above warning which cause error in this case happened in previous compiling steps, issue opened for it is: #335
Containerfile to reproduce:
Build container with command
podman build --pull --rm -t cakewallet_build_apk -f ContainerFile
Run container with command
podman run --rm --name cakewallet_build_apk -ti cakewallet_build_apk
In container run commands:
The text was updated successfully, but these errors were encountered: