Skip to content

Sign every update; launch-test the Windows and Linux builds - #25

Merged
burhankhanzada merged 1 commit into
mainfrom
feat/signed-updates
Oct 3, 2026
Merged

burhankhanzada merged 1 commit into
mainfrom
feat/signed-updates

Conversation

@burhankhanzada

Copy link
Copy Markdown
Member

The app's updater accepted anything its appcast pointed to: no SUPublicEDKey on macOS, no DSAPub on Windows, and no signatures in the releases.

  • macOS: Info.plist carries SUPublicEDKey (Ed25519), so Sparkle installs an update only with a valid signature.
  • Windows: Runner.rc carries a DSAPub resource. The WinSparkle 0.8 that auto_updater bundles verifies DSA (over SHA-1), not EdDSA.
  • release.yml signs the .dmg and the installer with the private halves (secrets SPARKLE_ED_PRIVATE_KEY, WINSPARKLE_DSA_PRIVATE_KEY, already set), verifies each signature against the key the app embeds, and fails if either secret is missing. release_metadata.dart now writes sparkle:dsaSignature too, with tests.
  • OpenSSL's Ed25519 signatures are byte-identical to Sparkle's own sign_update's for the same key (checked locally), so Sparkle accepts them. Locally the whole sign-and-verify step works, and a tampered file is rejected.
  • Launch tests: Windows is installed silently, launched, checked to still be running after 15 s, then uninstalled and checked to be gone. Linux is unpacked from the tarball and launched under Xvfb. Until now only macOS was ever started in CI.

This PR runs the release workflow as a trial (it touches release.yml, Info.plist and Runner.rc), so all of that runs here.

⚠️ The private keys are backed up only in ~/.pinbench-keys on the machine that made them. Copy them somewhere safe: an installed app accepts only updates signed with the key it shipped with.

🤖 Generated with Claude Code

The app's updater accepted anything its appcast pointed to: the macOS
build had no SUPublicEDKey and the Windows build no DSAPub, and releases
carried no signatures.

- macOS: Info.plist carries SUPublicEDKey, an Ed25519 key, so Sparkle
  installs an update only with a valid signature from it.
- Windows: Runner.rc carries a DSAPub resource, since the WinSparkle 0.8
  that auto_updater bundles verifies DSA (over SHA-1), not EdDSA.
- release.yml signs the .dmg and the installer with the private halves
  (the SPARKLE_ED_PRIVATE_KEY and WINSPARKLE_DSA_PRIVATE_KEY secrets),
  verifies each signature against the key the app embeds, and fails if
  either secret is missing. tools/release_metadata.dart writes
  sparkle:dsaSignature as well as sparkle:edSignature; tested.
- The Ed25519 signatures OpenSSL makes are byte-identical to Sparkle's
  own sign_update's for the same key, so Sparkle accepts them.
- The Windows build is installed silently, launched, checked to still be
  running after 15 s, and uninstalled; the Linux tarball is unpacked and
  launched under Xvfb. Until now only the macOS build was ever started.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@burhankhanzada
burhankhanzada merged commit f320972 into main Oct 3, 2026
14 checks passed
@burhankhanzada
burhankhanzada deleted the feat/signed-updates branch October 3, 2026 07:25
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant