From 44fbf6895bd3acd11f552514e746a2e3876cad2d Mon Sep 17 00:00:00 2001 From: Nsable-sh Date: Thu, 13 Aug 2026 14:29:14 -0300 Subject: release: package Windows builds with managed Tor --- docs/release-verification.md | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/release-verification.md') diff --git a/docs/release-verification.md b/docs/release-verification.md index 408bab9..04d18a3 100644 --- a/docs/release-verification.md +++ b/docs/release-verification.md @@ -81,6 +81,12 @@ Publish, alongside the assets, `SHA256SUMS` and `SHA256SUMS.asc`, and update is ever rotated, announce the new fingerprint clearly and update the embedded key in `verify-release.sh`. +For Windows releases with managed Tor built in, run `make windows-tor`. It +creates `Bitflash-*-windows-with-tor.zip` by downloading the Tor Expert Bundle, +checking the pinned SHA256 in `scripts/package-windows-tor.sh`, and placing +`tor/tor.exe` next to `Bitflash.exe`. Include that zip in `SHA256SUMS` like any +other release asset. + ## Why this matters `SHA256SUMS` alone protects against a broken download, but not against someone -- cgit v1.2.3 From 03e583395c42124521d09287bef29bf1d1bbe59b Mon Sep 17 00:00:00 2001 From: Nsable-sh Date: Thu, 13 Aug 2026 14:35:49 -0300 Subject: release: verify bundled Tor signatures --- README.md | 6 ++-- docs/release-verification.md | 8 +++-- docs/tor.md | 9 ++++-- scripts/package-windows-tor.sh | 71 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 78 insertions(+), 16 deletions(-) (limited to 'docs/release-verification.md') diff --git a/README.md b/README.md index c30f171..bb6a4d4 100644 --- a/README.md +++ b/README.md @@ -462,8 +462,10 @@ make windows-tor That produces `Bitflash-*-windows-with-tor.zip`. The release script downloads the Tor Expert Bundle from the official Tor archive, verifies its pinned SHA256, -and places `tor/tor.exe` beside `Bitflash.exe` so `-managedtor` works without a -separate Tor install. +optionally verifies the Tor Project GPG signature when `gpg` is available, and +places `tor/tor.exe` beside `Bitflash.exe` so `-managedtor` works without a +separate Tor install. For release builds, use `TOR_VERIFY_GPG=required make +windows-tor` to require the extra signature check. --- diff --git a/docs/release-verification.md b/docs/release-verification.md index 04d18a3..b8eaf5e 100644 --- a/docs/release-verification.md +++ b/docs/release-verification.md @@ -83,9 +83,11 @@ key in `verify-release.sh`. For Windows releases with managed Tor built in, run `make windows-tor`. It creates `Bitflash-*-windows-with-tor.zip` by downloading the Tor Expert Bundle, -checking the pinned SHA256 in `scripts/package-windows-tor.sh`, and placing -`tor/tor.exe` next to `Bitflash.exe`. Include that zip in `SHA256SUMS` like any -other release asset. +checking the pinned SHA256 in `scripts/package-windows-tor.sh`, optionally +verifying the Tor Project `.asc` signature, and placing `tor/tor.exe` next to +`Bitflash.exe`. For release builds, run `TOR_VERIFY_GPG=required make +windows-tor` so the signature check is mandatory. Include that zip in +`SHA256SUMS` like any other release asset. ## Why this matters diff --git a/docs/tor.md b/docs/tor.md index be6a145..a408704 100644 --- a/docs/tor.md +++ b/docs/tor.md @@ -65,9 +65,12 @@ make windows-tor ``` The packaging script verifies a pinned SHA256 for the downloaded Tor Expert -Bundle before copying it into the release directory. The Tor binary is bundled; -the runtime data directory, hidden-service key, and control cookie are still -created under the user's Bitflash data directory. +Bundle before copying it into the release directory. When `gpg` is available it +also verifies the matching `.asc` signature against the pinned Tor Browser +Developers signing-key fingerprint. Release builds should use +`TOR_VERIFY_GPG=required make windows-tor` to make that second check mandatory. +The Tor binary is bundled; the runtime data directory, hidden-service key, and +control cookie are still created under the user's Bitflash data directory. To point at a specific Tor executable: diff --git a/scripts/package-windows-tor.sh b/scripts/package-windows-tor.sh index 084fd1a..c8cca3b 100755 --- a/scripts/package-windows-tor.sh +++ b/scripts/package-windows-tor.sh @@ -8,11 +8,15 @@ TOR_VERSION="${TOR_VERSION:-15.0.19}" TOR_ARCHIVE_NAME="tor-expert-bundle-windows-x86_64-${TOR_VERSION}.tar.gz" TOR_URL="${TOR_URL:-https://archive.torproject.org/tor-package-archive/torbrowser/${TOR_VERSION}/${TOR_ARCHIVE_NAME}}" TOR_SHA256="${TOR_SHA256:-6AC067402C7B4A3DC37887ED3754B3914B67FDC220C966190683E9CCF91ABF0F}" +TOR_ASC_URL="${TOR_ASC_URL:-${TOR_URL}.asc}" +TOR_SIGNING_KEY_FINGERPRINT="${TOR_SIGNING_KEY_FINGERPRINT:-EF6E286DDA85EA2A4BA7DE684E2C6E8793298290}" +TOR_VERIFY_GPG="${TOR_VERIFY_GPG:-auto}" BUNDLE_DIR="${BUNDLE_DIR:-$ROOT/Bitflash-${VERSION}-windows}" OUT_ZIP="${OUT_ZIP:-$ROOT/Bitflash-${VERSION}-windows-with-tor.zip}" CACHE_DIR="${CACHE_DIR:-$ROOT/.cache}" ARCHIVE="${TOR_ARCHIVE:-$CACHE_DIR/$TOR_ARCHIVE_NAME}" +ASC_FILE="${TOR_ASC:-$ARCHIVE.asc}" usage() { cat </dev/null 2>&1; then + curl -L --fail --output "$out" "$url" + elif command -v wget >/dev/null 2>&1; then + wget -O "$out" "$url" + else + echo "missing required command: curl or wget" >&2 + exit 1 + fi +} + if [ ! -d "$BUNDLE_DIR" ]; then echo "missing Windows release directory: $BUNDLE_DIR" >&2 echo "run 'make windows' first, or set BUNDLE_DIR" >&2 @@ -65,14 +85,7 @@ OUT_ZIP_ABS="$OUT_PARENT/$OUT_NAME" mkdir -p "$CACHE_DIR" if [ ! -f "$ARCHIVE" ]; then - if command -v curl >/dev/null 2>&1; then - curl -L --fail --output "$ARCHIVE" "$TOR_URL" - elif command -v wget >/dev/null 2>&1; then - wget -O "$ARCHIVE" "$TOR_URL" - else - echo "missing required command: curl or wget" >&2 - exit 1 - fi + download "$TOR_URL" "$ARCHIVE" fi got="$(sha256sum "$ARCHIVE" | awk '{print tolower($1)}')" @@ -87,6 +100,48 @@ fi tmp="$(mktemp -d "${TMPDIR:-/tmp}/bitflash-tor-package.XXXXXX")" trap 'rm -rf "$tmp"' EXIT +case "$TOR_VERIFY_GPG" in + auto|required|off) ;; + *) echo "TOR_VERIFY_GPG must be auto, required, or off" >&2; exit 2 ;; +esac + +if [ "$TOR_VERIFY_GPG" != "off" ]; then + if command -v gpg >/dev/null 2>&1; then + if [ ! -f "$ASC_FILE" ]; then + download "$TOR_ASC_URL" "$ASC_FILE" + fi + gnupg_home="$tmp/gnupg" + mkdir -p "$gnupg_home" + chmod 0700 "$gnupg_home" + gpg --homedir "$gnupg_home" --batch --auto-key-locate nodefault,wkd,keyserver \ + --locate-keys torbrowser@torproject.org >/dev/null 2>&1 || { + if [ "$TOR_VERIFY_GPG" = "required" ]; then + echo "could not import Tor Browser Developers signing key" >&2 + exit 1 + fi + echo "WARNING: skipped Tor GPG signature verification; signing key import failed" >&2 + } + if gpg --homedir "$gnupg_home" --batch --with-colons --fingerprint "$TOR_SIGNING_KEY_FINGERPRINT" \ + 2>/dev/null | grep -q "^fpr:::::::::${TOR_SIGNING_KEY_FINGERPRINT}:"; then + gpg --homedir "$gnupg_home" --batch --verify "$ASC_FILE" "$ARCHIVE" >/dev/null 2>&1 || { + echo "Tor archive GPG signature verification failed" >&2 + exit 1 + } + echo "Tor archive GPG signature verified against ${TOR_SIGNING_KEY_FINGERPRINT}" + elif [ "$TOR_VERIFY_GPG" = "required" ]; then + echo "Tor signing key fingerprint mismatch" >&2 + exit 1 + else + echo "WARNING: skipped Tor GPG signature verification; signing key fingerprint was not available" >&2 + fi + elif [ "$TOR_VERIFY_GPG" = "required" ]; then + echo "missing required command for TOR_VERIFY_GPG=required: gpg" >&2 + exit 1 + else + echo "WARNING: gpg not found; relying on pinned SHA256 only" >&2 + fi +fi + mkdir -p "$tmp/extract" tar -xzf "$ARCHIVE" -C "$tmp/extract" -- cgit v1.2.3