mirror of
https://github.com/zen-browser/desktop
synced 2026-04-25 17:15:00 +02:00
Merge commit from fork
* security: enable MAR signature verification for updates Remove `--enable-unverified-updates` from the common mozconfig. This flag was disabling all MAR (Mozilla ARchive) signature verification in the updater binary, meaning update packages were applied without any cryptographic authenticity check. With this flag removed, the Mozilla build system will: - Link NSS and signmar into the updater binary - Enable SecVerifyTransformCreate-based signature verification on macOS - Require MAR files to contain valid signatures before applying REQUIRED FOLLOW-UP (maintainer action): 1. Generate a Zen-specific MAR signing keypair (RSA-PKCS1-SHA384) See: https://firefox-source-docs.mozilla.org/build/buildsystem/mar.html 2. Place the public key DER file(s) in the source tree at toolkit/mozapps/update/updater/release_primary.der 3. Sign MAR files during the release build with the private key 4. Set ACCEPTED_MAR_CHANNEL_IDS in update-settings.ini to restrict which update channels the updater will accept Ref: GHSA-qpj9-m8jc-mw6q * no-bug: Added signature steps * no-bug: Export browser/installer/package-manifest.in --------- Co-authored-by: Maliq Barnard <maliqbarnard@Maliqs-MacBook-Air.local> Co-authored-by: Mr. M <mr.m@tuta.com>
This commit is contained in:
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@@ -505,6 +505,20 @@ jobs:
|
||||
run: |
|
||||
git clone https://github.com/zen-browser/windows-binaries.git .github/workflows/object --depth 1
|
||||
|
||||
- name: Download signmar-linux-x86_64 from artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: signmar-linux-x86_64
|
||||
|
||||
- name: Sign MAR files
|
||||
env:
|
||||
SIGNMAR: ${{ github.workspace }}/signmar-linux-x86_64
|
||||
ZEN_MAR_SIGNING_PASSWORD: ${{ secrets.ZEN_MAR_SIGNING_PASSWORD }}
|
||||
ZEN_SIGNING_CERT_PEM_BASE64: ${{ secrets.ZEN_SIGNING_CERT_PEM_BASE64 }}
|
||||
ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64: ${{ secrets.ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 }}
|
||||
run: |
|
||||
bash scripts/mar_sign.sh -s
|
||||
|
||||
- name: Copy update manifests
|
||||
env:
|
||||
RELEASE_BRANCH: ${{ inputs.update_branch }}
|
||||
|
||||
8
.github/workflows/linux-release-build.yml
vendored
8
.github/workflows/linux-release-build.yml
vendored
@@ -173,3 +173,11 @@ jobs:
|
||||
retention-days: 5
|
||||
name: linux_update_manifest_${{ matrix.arch }}
|
||||
path: ./dist/update
|
||||
|
||||
- name: Upload signmar
|
||||
if: ${{ matrix.arch == 'x86_64' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
retention-days: 2
|
||||
name: signmar-linux-x86_64
|
||||
path: engine/obj-x86_64-pc-linux-gnu/dist/bin/signmar
|
||||
|
||||
2
.github/workflows/src/release-build.sh
vendored
2
.github/workflows/src/release-build.sh
vendored
@@ -10,6 +10,8 @@ fi
|
||||
|
||||
. $HOME/.cargo/env
|
||||
|
||||
sh ./scripts/mar_sign.sh -i
|
||||
|
||||
ulimit -n 4096
|
||||
|
||||
if command -v Xvfb &> /dev/null; then
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -27,3 +27,10 @@ locales/firefox-l10n/
|
||||
.DS_Store
|
||||
|
||||
mozconfig
|
||||
|
||||
build/signing/env/
|
||||
build/signing/nss_config/
|
||||
build/signing/cert.pem
|
||||
build/signing/private_key.pem
|
||||
build/signing/private_key.p12
|
||||
|
||||
|
||||
BIN
build/signing/public_key.der
Normal file
BIN
build/signing/public_key.der
Normal file
Binary file not shown.
@@ -48,6 +48,8 @@ if test "$ZEN_RELEASE"; then
|
||||
|
||||
ac_add_options --enable-optimize
|
||||
|
||||
ac_add_options --enable-verify-mar
|
||||
|
||||
ac_add_options --enable-release
|
||||
ac_add_options --disable-debug
|
||||
ac_add_options --disable-debug-symbols
|
||||
@@ -89,8 +91,6 @@ if test "$ZEN_RELEASE"; then
|
||||
ac_add_options --enable-replace-malloc
|
||||
fi
|
||||
|
||||
ac_add_options --enable-unverified-updates
|
||||
|
||||
ac_add_options --enable-jxl
|
||||
|
||||
ac_add_options --with-unsigned-addon-scopes=app,system
|
||||
|
||||
165
scripts/mar_sign.sh
Normal file
165
scripts/mar_sign.sh
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env bash
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
set -e
|
||||
|
||||
CERT_PATH_DIR=build/signing
|
||||
UPDATER_CERT_DIR="engine/toolkit/mozapps/update/updater"
|
||||
NSS_CONFIG_DIR="$CERT_PATH_DIR/nss_config"
|
||||
|
||||
generate_certs() {
|
||||
mkdir temp
|
||||
cd temp
|
||||
|
||||
# 1. Generate private key
|
||||
openssl genrsa -out private_key.pem 4096
|
||||
|
||||
# 2. Generate self-signed certificate (required for PKCS#12 bundling)
|
||||
openssl req -new -x509 \
|
||||
-key private_key.pem \
|
||||
-out cert.pem \
|
||||
-subj "/CN=MAR Signing"
|
||||
|
||||
# 3. Export public key as SPKI DER (for embedding in updater)
|
||||
openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
|
||||
|
||||
cd ..
|
||||
mkdir -p "$CERT_PATH_DIR"
|
||||
mv temp/private_key.pem "$CERT_PATH_DIR"/private_key.pem
|
||||
mv temp/cert.pem "$CERT_PATH_DIR"/cert.pem
|
||||
mv temp/public_key.der "$CERT_PATH_DIR"/public_key.der
|
||||
|
||||
mkdir -p "$CERT_PATH_DIR/env"
|
||||
base64 -w 0 "$CERT_PATH_DIR"/cert.pem > "$CERT_PATH_DIR"/env/ZEN_SIGNING_CERT_PEM_BASE64
|
||||
base64 -w 0 "$CERT_PATH_DIR"/private_key.pem > "$CERT_PATH_DIR"/env/ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64
|
||||
|
||||
# Verify public key
|
||||
openssl rsa -in "$CERT_PATH_DIR"/public_key.der \
|
||||
-pubin -inform DER -text -noout
|
||||
|
||||
rm -rf temp
|
||||
}
|
||||
|
||||
import_cert() {
|
||||
if [ ! -f "$CERT_PATH_DIR/public_key.der" ]; then
|
||||
echo "Error: public_key.der not found. Run with -g first." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Importing certificate into $UPDATER_CERT_DIR/release_primary.der"
|
||||
cp "$CERT_PATH_DIR/public_key.der" "$UPDATER_CERT_DIR/release_primary.der"
|
||||
echo "Importing certificate into $UPDATER_CERT_DIR/release_secondary.der"
|
||||
cp "$CERT_PATH_DIR/public_key.der" "$UPDATER_CERT_DIR/release_secondary.der"
|
||||
echo "Done. Rebuild the updater to embed the new certificate."
|
||||
}
|
||||
|
||||
create_nss_config_dir() {
|
||||
rm -rf "$NSS_CONFIG_DIR"
|
||||
mkdir "$NSS_CONFIG_DIR"
|
||||
|
||||
if [ -z "$ZEN_MAR_SIGNING_PASSWORD" ]; then
|
||||
echo "Warning: ZEN_MAR_SIGNING_PASSWORD environment variable not set. Using empty password." >&2
|
||||
ZEN_MAR_SIGNING_PASSWORD=""
|
||||
fi
|
||||
|
||||
password_file="$NSS_CONFIG_DIR/password.txt"
|
||||
echo "$ZEN_MAR_SIGNING_PASSWORD" > "$password_file"
|
||||
|
||||
if [ "$ZEN_SIGNING_CERT_PEM_BASE64" ]; then
|
||||
echo "Decoding signing certificate from ZEN_SIGNING_CERT_PEM_BASE64 environment variable..."
|
||||
echo "$ZEN_SIGNING_CERT_PEM_BASE64" | base64 -d > "$CERT_PATH_DIR/cert.pem"
|
||||
fi
|
||||
|
||||
if [ "$ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64" ]; then
|
||||
echo "Decoding signing private key from ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 environment variable..."
|
||||
echo "$ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64" | base64 -d > "$CERT_PATH_DIR/private_key.pem"
|
||||
fi
|
||||
|
||||
echo "Generating NSS config directory at $NSS_CONFIG_DIR"
|
||||
certutil -N -d "$NSS_CONFIG_DIR" -f "$password_file"
|
||||
|
||||
echo "Wrapping private key into PKCS#12..."
|
||||
echo "Wrapping key + cert into PKCS#12..."
|
||||
openssl pkcs12 -export \
|
||||
-inkey "$CERT_PATH_DIR/private_key.pem" \
|
||||
-in "$CERT_PATH_DIR/cert.pem" \
|
||||
-name "private_key" \
|
||||
-passout pass:"$ZEN_MAR_SIGNING_PASSWORD" \
|
||||
-out "$CERT_PATH_DIR/private_key.p12"
|
||||
|
||||
echo "Importing PKCS#12 into NSS database..."
|
||||
pk12util \
|
||||
-i "$CERT_PATH_DIR/private_key.p12" \
|
||||
-d "$NSS_CONFIG_DIR" \
|
||||
-W "$ZEN_MAR_SIGNING_PASSWORD" \
|
||||
-K "$ZEN_MAR_SIGNING_PASSWORD"
|
||||
}
|
||||
|
||||
cleanup_certs() {
|
||||
rm -rf "$NSS_CONFIG_DIR"
|
||||
rm -rf "$CERT_PATH_DIR/env"
|
||||
|
||||
rm -f "$CERT_PATH_DIR/private_key.p12"
|
||||
rm -f "$CERT_PATH_DIR/private_key.pem"
|
||||
rm -f "$CERT_PATH_DIR/cert.pem"
|
||||
}
|
||||
|
||||
sign_mars() {
|
||||
if [ ! -f "$SIGNMAR" ]; then
|
||||
echo "Error: signmar not found at $SIGNMAR. Build the engine first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_nss_config_dir
|
||||
|
||||
folders=(
|
||||
linux.mar
|
||||
linux-aarch64.mar
|
||||
windows.mar
|
||||
windows-arm64
|
||||
macos.mar
|
||||
)
|
||||
# each folder will contain the .mar files for that platform, and the signature will be written in-place
|
||||
for folder in "${folders[@]}"; do
|
||||
if [ -d "$folder" ]; then
|
||||
for mar_file in "$folder"/*.mar; do
|
||||
if [ -f "$mar_file" ]; then
|
||||
echo ""
|
||||
echo "Signing $mar_file..."
|
||||
# mar [-C workingDir] -d NSSConfigDir -n certname -s archive.mar out_signed_archive.mar
|
||||
"$SIGNMAR" -d "$NSS_CONFIG_DIR" -n "private_key" -s "$mar_file" "$mar_file".signed
|
||||
echo "Signed $mar_file. Verifying signature..."
|
||||
"$SIGNMAR" -d "$NSS_CONFIG_DIR" -n "private_key" -v "$mar_file".signed
|
||||
mv "$mar_file".signed "$mar_file"
|
||||
echo "Successfully signed $mar_file"
|
||||
else
|
||||
echo "No .mar files found in $folder, skipping."
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Directory $folder not found, skipping."
|
||||
fi
|
||||
done
|
||||
|
||||
cleanup_certs
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
-g)
|
||||
generate_certs
|
||||
;;
|
||||
-i)
|
||||
import_cert
|
||||
;;
|
||||
-s)
|
||||
sign_mars
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [-g] [-i] [-s]" >&2
|
||||
echo " -g Generate MAR signing certificates" >&2
|
||||
echo " -i Import the certificate into the updater (release_primary.der)" >&2
|
||||
echo " -s Sign *.mar files in the current directory in-place" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,18 +1,8 @@
|
||||
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
|
||||
index 36eafe35063f02fe3d4acaab24a08dc1b7b0ae24..951889b156498f66118d67d4245aca649e27a3a2 100644
|
||||
index 36eafe35063f02fe3d4acaab24a08dc1b7b0ae24..b6bf327bf286de5246e5c50d89519d16d5771caf 100644
|
||||
--- a/browser/installer/package-manifest.in
|
||||
+++ b/browser/installer/package-manifest.in
|
||||
@@ -378,17 +378,17 @@ bin/libfreebl_64int_3.so
|
||||
; [MaintenanceService]
|
||||
;
|
||||
#ifdef MOZ_MAINTENANCE_SERVICE
|
||||
-@BINPATH@/maintenanceservice.exe
|
||||
-@BINPATH@/maintenanceservice_installer.exe
|
||||
+;@BINPATH@/maintenanceservice.exe
|
||||
+;@BINPATH@/maintenanceservice_installer.exe
|
||||
#endif
|
||||
|
||||
; [Crash Reporter]
|
||||
@@ -386,9 +386,9 @@ bin/libfreebl_64int_3.so
|
||||
;
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#ifdef XP_MACOSX
|
||||
|
||||
@@ -7,7 +7,7 @@ index 57ea0415653678bb300e277e66c97e332e756cc7..5f757e68a685948c83fee8f963c49bee
|
||||
"signmar",
|
||||
]
|
||||
+ if CONFIG["OS_ARCH"] == "Linux":
|
||||
+ # Zen: --enable-unverified-updates is enabled, the RPATH is not added
|
||||
+ # Zen: ensure RPATH is set so NSS/signmar libs are found at runtime
|
||||
+ OS_LIBS += [
|
||||
+ "-Wl,-rpath=\\$$ORIGIN",
|
||||
+ ]
|
||||
|
||||
Reference in New Issue
Block a user