veilor-os/scripts/gen-mok-key.sh
veilor-org 2782b72ead sre: release pipeline w/ ISO split, GPG sig, MOK signing scaffold
- build-iso.yml: on tag push (v*.*.*), split ISO into 1.9G parts, GPG-sign
  the sha256 with GPG_PRIVATE_KEY secret, and auto-create release with
  softprops/action-gh-release@v2 attaching part files + sig + reassembly
  instructions. Falls back to legacy release.published path.
- build-iso.yml: optional EFI Secure Boot signing step. If MOK_PRIVATE_KEY
  + MOK_CERT secrets are present, sbsign each .efi inside the ISO and
  repack with xorriso; otherwise warn and ship unsigned. Refresh sha256.
- release-checksums.yml: new PR-time gate. Validates source + generated
  CI kickstart, shellchecks scripts, parses every workflow YAML, and
  asserts the split size stays under GitHub'''s 2 GiB asset cap.
- scripts/gen-mok-key.sh: idempotent MOK keypair generator (RSA-4096,
  10y), outputs to gitignored build/keys/. Header documents mokutil
  enrollment and gh secret upload. exec bit set in index.
- .gitignore: add build/keys/, *.priv, *.der.

User must add GitHub secrets before the next tagged release:
  GPG_PRIVATE_KEY  — armored private key for sha256 signing
  MOK_PRIVATE_KEY  — sbsign EFI signing key (PEM)
  MOK_CERT         — public cert (DER) for sbsign + mokutil enrollment
2026-05-01 23:39:19 +01:00

94 lines
3.5 KiB
Bash
Executable file

#!/usr/bin/env bash
# gen-mok-key.sh — Generate a Machine Owner Key (MOK) pair for Secure Boot
#
# Purpose:
# Produces an RSA-4096 key pair used to sign EFI binaries (BOOTX64.EFI,
# shim, grub) and out-of-tree kernel modules so they pass UEFI Secure Boot
# verification once the public cert is enrolled in the firmware.
#
# Output (gitignored):
# build/keys/MOK.priv — PEM private key (sbsign / sign-file input)
# build/keys/MOK.der — DER public certificate (mokutil enrollment input)
# build/keys/MOK.pem — PEM public certificate (sbsign --cert input)
#
# Idempotent: if MOK.priv already exists, exits 0 without regenerating.
# Re-running with existing keys is safe — won't clobber a key already used
# to sign released ISOs.
#
# ─── User enrollment workflow (post-install) ─────────────────────────────
# 1. Copy build/keys/MOK.der to the installed system (USB / scp / etc.)
# 2. On the booted veilor-os system, as root:
# mokutil --import /path/to/MOK.der
# Set a one-time password when prompted.
# 3. Reboot. The shim's MokManager will appear on next boot — choose
# "Enroll MOK", confirm with the password from step 2, then continue
# boot. The cert is now in the kernel's .platform keyring.
# 4. Verify enrollment:
# mokutil --list-enrolled | grep -A2 'veilor'
#
# ─── Uploading to GitHub Actions secrets ─────────────────────────────────
# After running this script, populate the CI signing secrets with:
# gh secret set MOK_PRIVATE_KEY < build/keys/MOK.priv
# gh secret set MOK_CERT < build/keys/MOK.der
#
# Keep build/keys/ off-disk-backup-medium-of-record offline. Anyone with
# MOK.priv can sign code that boots on enrolled machines.
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
KEY_DIR="$REPO_ROOT/build/keys"
PRIV_KEY="$KEY_DIR/MOK.priv"
DER_CERT="$KEY_DIR/MOK.der"
PEM_CERT="$KEY_DIR/MOK.pem"
# Subject for the X.509 cert. Tweak CN if you fork the project.
SUBJ="/CN=veilor-os Machine Owner Key/O=veilor-org/OU=secure-boot/"
# Cert validity — 10 years. Long enough that we don't churn re-enrollment;
# short enough that a leaked key has a hard expiry.
DAYS=3650
if [[ -f "$PRIV_KEY" ]]; then
echo "[INFO] $PRIV_KEY already exists — skipping (idempotent)."
echo "[INFO] To regenerate, delete $KEY_DIR/ first."
exit 0
fi
mkdir -p "$KEY_DIR"
chmod 700 "$KEY_DIR"
echo "[*] Generating RSA-4096 MOK keypair → $KEY_DIR/"
# Single openssl invocation produces PEM private key + DER public cert.
# -nodes = no passphrase on the key (CI must use it non-interactively).
# Protect the resulting MOK.priv with filesystem perms only.
openssl req \
-new \
-x509 \
-newkey rsa:4096 \
-nodes \
-sha256 \
-days "$DAYS" \
-subj "$SUBJ" \
-keyout "$PRIV_KEY" \
-outform DER \
-out "$DER_CERT"
# Also emit a PEM-encoded copy of the cert — sbsign accepts PEM more
# reliably than DER in some distros' build of the tool.
openssl x509 -inform DER -in "$DER_CERT" -outform PEM -out "$PEM_CERT"
chmod 600 "$PRIV_KEY"
chmod 644 "$DER_CERT" "$PEM_CERT"
echo "[OK] MOK keypair written:"
echo " private : $PRIV_KEY (mode 600)"
echo " cert DER: $DER_CERT (enroll via mokutil --import)"
echo " cert PEM: $PEM_CERT (sbsign --cert input)"
echo ""
echo "[next] Upload to CI:"
echo " gh secret set MOK_PRIVATE_KEY < $PRIV_KEY"
echo " gh secret set MOK_CERT < $DER_CERT"