From 6c9de115e9c9ae6b0c9fb608b8c6650bf4b2ba1d Mon Sep 17 00:00:00 2001 From: vjrj Date: Wed, 22 Jul 2026 20:37:38 +0200 Subject: [PATCH] ci(release): sign fdroid references v2/v3 only (no v1) for reproducibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reproducible-build verify failed even after the /home/vagrant path fix made every file identical: our reference APK carried a v1 (JAR) signature, which adds META-INF/{MANIFEST.MF,*.SF,*.RSA} as three extra ZIP ENTRIES. F-Droid's apksigcopier transplants only the v2/v3 signing block onto its rebuild, so those 3 v1 entries make the reference's signed content differ from F-Droid's build — apksigner then reports a v3 CHUNKED_SHA512 digest mismatch though 'diff -r' shows no file differences. Proven by zipinfo: our ref had 486 entries vs F-Droid's 483, the delta being exactly the v1 files; the shared 483 are byte-identical. minSdk is 24 so v1 is never needed. Sign v2/v3 only so the reference byte-matches F-Droid's rebuild. --- .forgejo/workflows/release.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 44575f8..405bda4 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -239,8 +239,16 @@ jobs: fi echo "$TANE_KEYSTORE_BASE64" | base64 -d > /tmp/ks.jks out="/tmp/app-${ABI}-release.apk" + # v2/v3 only — NO v1 (JAR) signature. minSdk is 24, so v1 is never + # needed, and v1 adds META-INF/*.SF/*.RSA/MANIFEST.MF as zip ENTRIES + # that F-Droid's rebuild doesn't have. F-Droid's apksigcopier transplants + # only the v2/v3 signing block, so those extra v1 entries make the + # reference's signed content differ from F-Droid's rebuild (CHUNKED_SHA512 + # mismatch) even when every file is identical. Dropping v1 makes the + # reference byte-match F-Droid's build so the signature copy verifies. "$apksigner" sign --ks /tmp/ks.jks --ks-key-alias "$TANE_KEY_ALIAS" \ --ks-pass "pass:$TANE_KEYSTORE_PASSWORD" --key-pass "pass:$TANE_KEY_PASSWORD" \ + --v1-signing-enabled false --v2-signing-enabled true --v3-signing-enabled true \ --out "$out" "$f" # Prove the signer cert matches AllowedAPKSigningKeys. "$apksigner" verify --print-certs "$out" | grep -i 'SHA-256' || true @@ -357,8 +365,16 @@ jobs: fi echo "$TANE_KEYSTORE_BASE64" | base64 -d > /tmp/ks.jks out="/tmp/app-${ABI}-release.apk" + # v2/v3 only — NO v1 (JAR) signature. minSdk is 24, so v1 is never + # needed, and v1 adds META-INF/*.SF/*.RSA/MANIFEST.MF as zip ENTRIES + # that F-Droid's rebuild doesn't have. F-Droid's apksigcopier transplants + # only the v2/v3 signing block, so those extra v1 entries make the + # reference's signed content differ from F-Droid's rebuild (CHUNKED_SHA512 + # mismatch) even when every file is identical. Dropping v1 makes the + # reference byte-match F-Droid's build so the signature copy verifies. "$apksigner" sign --ks /tmp/ks.jks --ks-key-alias "$TANE_KEY_ALIAS" \ --ks-pass "pass:$TANE_KEYSTORE_PASSWORD" --key-pass "pass:$TANE_KEY_PASSWORD" \ + --v1-signing-enabled false --v2-signing-enabled true --v3-signing-enabled true \ --out "$out" "$f" "$apksigner" verify --print-certs "$out" | grep -i 'SHA-256' || true rm -f /tmp/ks.jks @@ -473,8 +489,16 @@ jobs: fi echo "$TANE_KEYSTORE_BASE64" | base64 -d > /tmp/ks.jks out="/tmp/app-${ABI}-release.apk" + # v2/v3 only — NO v1 (JAR) signature. minSdk is 24, so v1 is never + # needed, and v1 adds META-INF/*.SF/*.RSA/MANIFEST.MF as zip ENTRIES + # that F-Droid's rebuild doesn't have. F-Droid's apksigcopier transplants + # only the v2/v3 signing block, so those extra v1 entries make the + # reference's signed content differ from F-Droid's rebuild (CHUNKED_SHA512 + # mismatch) even when every file is identical. Dropping v1 makes the + # reference byte-match F-Droid's build so the signature copy verifies. "$apksigner" sign --ks /tmp/ks.jks --ks-key-alias "$TANE_KEY_ALIAS" \ --ks-pass "pass:$TANE_KEYSTORE_PASSWORD" --key-pass "pass:$TANE_KEY_PASSWORD" \ + --v1-signing-enabled false --v2-signing-enabled true --v3-signing-enabled true \ --out "$out" "$f" "$apksigner" verify --print-certs "$out" | grep -i 'SHA-256' || true rm -f /tmp/ks.jks