diff --git a/scripts/build_android_apk.sh b/scripts/build_android_apk.sh index 39c5119..1fc83ed 100755 --- a/scripts/build_android_apk.sh +++ b/scripts/build_android_apk.sh @@ -213,15 +213,35 @@ KEY_PASS="${KEY_PASS:-$KEYSTORE_PASS}" mkdir -p "$(dirname "$APK_OUT")" echo ">>> apksigner sign -> $APK_OUT" +# Sign the schemes explicitly instead of relying on apksigner's auto behaviour. +# Left to "auto", this pipeline produced an APK carrying invalid v1 (JAR) +# signature files (META-INF/*.SF/.RSA present but failing v1 verification). +# Android installs it fine via v2/v3, but Obtainium parses the APK's legacy v1 +# certificate at install time, gets an empty cert list, and crashes with +# "RangeError (length): Invalid value: valid value range is empty: 0". +# minSdk is 26 (solitaire_app/android/AndroidManifest.xml), so v1/JAR signing is +# not needed at all — disable it and ship a clean v2+v3 signature, matching what +# modern Android tooling produces for minSdk >= 24. "$BT/apksigner" sign \ --ks "$KEYSTORE" \ --ks-pass "pass:$KEYSTORE_PASS" \ --ks-key-alias "$KEY_ALIAS" \ --key-pass "pass:$KEY_PASS" \ + --min-sdk-version 26 \ + --v1-signing-enabled false \ + --v2-signing-enabled true \ + --v3-signing-enabled true \ --out "$APK_OUT" \ "$STAGING/app-aligned.apk" echo ">>> verify" -"$BT/apksigner" verify --verbose "$APK_OUT" +"$BT/apksigner" verify --min-sdk-version 26 --verbose "$APK_OUT" + +# Guard: no leftover v1/JAR signature files may remain — their presence (valid or +# not) is what tripped Obtainium. Fail the build if any slipped through. +if unzip -l "$APK_OUT" 2>/dev/null | grep -qiE 'META-INF/.*\.(SF|RSA|DSA|EC)$'; then + echo "ERROR: APK still contains v1/JAR signature files; expected v2+v3 only" >&2 + exit 1 +fi echo ">>> done: $APK_OUT"