- scripts/secureboot/gen-keys.sh: generates a Machine Owner Key pair (MOK.priv / MOK.pem / MOK.der) for self-signing the boot chain. - scripts/secureboot/sign-image.sh: signs kernels and EFI binaries (already-signed files skipped) with sbsign. - arcline-mok-enroll.service (+ script): one-time MOK enrollment at first boot via mokutil; no-ops when no key was shipped. - build-iso.sh: ARCLINE_SIGN=1 signs the live boot chain and ships the public MOK in the image. Smoke test now asserts the enroll unit exists.
52 lines
2.4 KiB
Bash
Executable File
52 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Arcline OS — secure boot: sign an image with the MOK
|
|
#
|
|
# scripts/secureboot/sign-image.sh <rootfs-or-isofiles-dir> [--keydir build/keys]
|
|
#
|
|
# Signs every PE binary in the boot chain with the MOK:
|
|
# - kernels (vmlinuz*) in /boot and /live
|
|
# - EFI binaries (*.efi) in /boot (grubx64, shimx64, mmx64, ...)
|
|
#
|
|
# sbsign replaces files in place (already-signed files are skipped). GRUB
|
|
# .mod modules are not PE and are out of scope here — see docs/secureboot.md.
|
|
#
|
|
# Requires sbsigntool. Keypair from scripts/secureboot/gen-keys.sh.
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
set -euo pipefail
|
|
source "$(dirname "${BASH_SOURCE[0]}")/../../scripts/common.sh"
|
|
|
|
TARGET="${1:?usage: sign-image.sh <rootfs-or-isofiles-dir> [--keydir <dir>]}"
|
|
KEYDIR="$BUILD_DIR/keys"
|
|
[[ "${2:-}" == "--keydir" ]] && KEYDIR="${3:?usage: sign-image.sh <dir> [--keydir <dir>]}"
|
|
|
|
[[ -d "$TARGET" ]] || die "target '$TARGET' does not exist"
|
|
[[ -f "$KEYDIR/MOK.priv" && -f "$KEYDIR/MOK.pem" ]] || die "MOK keypair not found in $KEYDIR (run: scripts/secureboot/gen-keys.sh)"
|
|
command -v sbsign >/dev/null || die "sbsign not found (package: sbsigntool)"
|
|
command -v sbverify >/dev/null || die "sbverify not found (package: sbsigntool)"
|
|
|
|
signed=0; skipped=0
|
|
sign_file() {
|
|
local f="$1"
|
|
if sbverify --cert "$KEYDIR/MOK.pem" "$f" >/dev/null 2>&1; then
|
|
skipped=$((skipped+1))
|
|
return
|
|
fi
|
|
local tmp="$f.arcline-signed"
|
|
if sbsign --key "$KEYDIR/MOK.priv" --cert "$KEYDIR/MOK.pem" --output "$tmp" "$f" >/dev/null 2>&1; then
|
|
mv "$tmp" "$f"
|
|
log "signed: $f"
|
|
signed=$((signed+1))
|
|
else
|
|
warn "could not sign: $f"
|
|
rm -f "$tmp"
|
|
fi
|
|
}
|
|
|
|
log "signing boot chain in $TARGET"
|
|
while IFS= read -r -d '' f; do sign_file "$f"; done < <(find "$TARGET" -type f \( -name 'vmlinuz*' -o -name '*.efi' \) -print0)
|
|
# also sign any live-boot kernel staged by the ISO build
|
|
while IFS= read -r -d '' f; do sign_file "$f"; done < <(find "$TARGET/live" -maxdepth 1 -type f -name 'vmlinuz*' -print0 2>/dev/null)
|
|
|
|
log "secure boot signing done: $signed signed, $skipped already signed"
|