V9.14.016.2026.06.06
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2026-06-06 14:39:12 +01:00
parent 83f6f8488c
commit e42fdff89b
77 changed files with 410 additions and 230 deletions
+103 -34
View File
@@ -9,34 +9,41 @@
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
# shellcheck disable=SC2312
set -Ceuo pipefail
# Final live-build binary hook for the CISS UKI build. When the ciss-uki Secure Boot profile is active, this hook selects the
# complete kernel/initrd pair, reads the live kernel command line, optionally embeds separate early microcode, creates unsigned
# and signed Unified Kernel Images with ukify, verifies the signed UKI with 'sbverify', writes a manifest, and refuses private
# Secure Boot key material in build artifact paths.
#######################################
# Prints failure message.
# Prints a fatal error message and terminates the hook.
# Globals:
# None
# Arguments:
# 1: Message to print
# 1: Error message
# Returns:
# 42: on failure
# 42: always exits with failure
#######################################
die() {
declare message="$1"
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ ❌ %s \e[0m\n" "${message}" >&2
declare message="${1}"
printf "\e[91m❌ %s \e[0m\n" "${message}" >&2
exit 42
}
#######################################
# Checking command to execute for existence.
# Checks whether a required command exists.
# Globals:
# None
# Arguments:
# 1: Command
# 1: Command name
# Returns:
# 0: on success
# 42: if the command is missing
#######################################
require_command() {
declare command_name="$1"
declare command_name="${1}"
command -v "${command_name}" >/dev/null 2>&1 || die "Required command not found: '${command_name}'."
@@ -44,18 +51,19 @@ require_command() {
}
#######################################
# Checking file for existence.
# Checks whether a required file exists.
# Globals:
# None
# Arguments:
# 1: /PATH/TO/FILE
# 2: Description
# 1: File path
# 2: Human-readable file description
# Returns:
# 0: on success
# 42: if the file is missing
#######################################
require_file() {
declare file_path="$1"
declare description="$2"
declare file_path="${1}"
declare description="${2}"
[[ -f "${file_path}" ]] || die "Missing ${description}: '${file_path}'."
@@ -63,18 +71,19 @@ require_file() {
}
#######################################
# Checking file for existence.
# Reads the single LB_BOOTAPPEND_LIVE value from a live-build binary configuration file.
# Globals:
# None
# Arguments:
# 1: /PATH/TO/FILE
# 2: Description
# 1: live-build binary configuration file
# 2: Output variable name for the kernel command line
# Returns:
# 0: on success
# 42: if the file is missing, the entry is ambiguous, or the value is empty
#######################################
read_bootappend_live() {
declare config_file="$1"
declare output_var="$2"
declare config_file="${1}"
declare output_var="${2}"
declare -a matches=()
declare value=""
@@ -99,10 +108,22 @@ read_bootappend_live() {
return 0
}
#######################################
# Collects kernel and initrd candidates from one artifact directory.
# Globals:
# None
# Arguments:
# 1: Artifact directory
# 2: Output variable name for the selected kernel path
# 3: Output variable name for the selected initrd path
# Returns:
# 0: on success, including when the directory does not exist
# 42: if more than one kernel or initrd candidate exists
#######################################
collect_artifacts_from_dir() {
declare artifact_dir="$1"
declare kernel_output_var="$2"
declare initrd_output_var="$3"
declare artifact_dir="${1}"
declare kernel_output_var="${2}"
declare initrd_output_var="${3}"
declare -a kernels=()
declare -a initrds=()
@@ -129,6 +150,17 @@ collect_artifacts_from_dir() {
return 0
}
#######################################
# Selects the kernel/initrd pair used to build the UKI.
# Globals:
# None
# Arguments:
# 1: Output variable name for the selected kernel path
# 2: Output variable name for the selected initrd path
# Returns:
# 0: on success
# 42: if no complete pair exists, the final pair is incomplete, or candidates are ambiguous
#######################################
select_kernel_initrd_pair() {
declare kernel_output_var="$1"
declare initrd_output_var="$2"
@@ -140,7 +172,7 @@ select_kernel_initrd_pair() {
collect_artifacts_from_dir "binary/live" binary_kernel binary_initrd
if [[ -n "${binary_kernel}" && -n "${binary_initrd}" ]]; then
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Using final binary/live kernel and initrd artifacts. \e[0m\n"
printf "\e[92m Using final binary/live kernel and initrd artifacts. \e[0m\n"
printf -v "${kernel_output_var}" "%s" "${binary_kernel}"
printf -v "${initrd_output_var}" "%s" "${binary_initrd}"
return 0
@@ -150,11 +182,11 @@ select_kernel_initrd_pair() {
die "Incomplete binary/live kernel/initrd pair. Refusing to mix final and fallback artifacts."
fi
printf "\e[93m++++ ++++ ++++ ++++ ++++ ++++ ++ [WARN] No complete binary/live kernel/initrd pair found; checking chroot/boot fallback. \e[0m\n"
printf "\e[93m No complete binary/live kernel/initrd pair found; checking chroot/boot fallback. \e[0m\n"
collect_artifacts_from_dir "chroot/boot" fallback_kernel fallback_initrd
if [[ -n "${fallback_kernel}" && -n "${fallback_initrd}" ]]; then
printf "\e[93m++++ ++++ ++++ ++++ ++++ ++++ ++ [WARN] Using chroot/boot fallback artifacts because binary/live has no complete pair. \e[0m\n"
printf "\e[93m Using chroot/boot fallback artifacts because binary/live has no complete pair. \e[0m\n"
printf -v "${kernel_output_var}" "%s" "${fallback_kernel}"
printf -v "${initrd_output_var}" "%s" "${fallback_initrd}"
return 0
@@ -163,9 +195,20 @@ select_kernel_initrd_pair() {
die "No complete kernel/initrd pair found in binary/live or chroot/boot."
}
#######################################
# Finds an optional separate early microcode cpio next to the selected initrd.
# Globals:
# None
# Arguments:
# 1: Artifact directory
# 2: Output variable name for the selected microcode cpio path
# Returns:
# 0: on success, including when no separate microcode cpio exists
# 42: if more than one separate microcode cpio candidate exists
#######################################
collect_optional_microcode() {
declare artifact_dir="$1"
declare output_var="$2"
declare artifact_dir="${1}"
declare output_var="${2}"
declare -a microcode_candidates=()
mapfile -d '' -t microcode_candidates < <(
@@ -181,6 +224,16 @@ collect_optional_microcode() {
return 0
}
#######################################
# Refuses private Secure Boot key material in generated artifact paths.
# Globals:
# None
# Arguments:
# None
# Returns:
# 0: on success
# 42: if a private Secure Boot key is found below a guarded path
#######################################
guard_private_key_leaks() {
declare -a guard_roots=(binary chroot config/includes.binary config/includes.chroot config/includes.installer)
declare guard_root=""
@@ -201,6 +254,22 @@ guard_private_key_leaks() {
return 0
}
#######################################
# Builds unsigned and signed CISS UKIs for the ciss-uki Secure Boot profile.
# Globals:
# PWD
# VAR_CISS_SECUREBOOT_DIR
# VAR_CISS_SECUREBOOT_EFI_CERT
# VAR_CISS_SECUREBOOT_EFI_KEY
# VAR_CISS_SECUREBOOT_PROFILE
# VAR_HANDLER_BUILD_DIR
# VAR_WORKDIR
# Arguments:
# None
# Returns:
# 0: on success or when the active Secure Boot profile does not require a CISS UKI
# 42: on validation, artifact selection, UKI build, signing, or verification failure
#######################################
main() {
declare profile="${VAR_CISS_SECUREBOOT_PROFILE:-debian-shim}"
declare build_dir="${VAR_HANDLER_BUILD_DIR:-${PWD}}"
@@ -226,11 +295,11 @@ main() {
declare -a ukify_args=()
if [[ "${profile}" != "ciss-uki" ]]; then
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Secure Boot profile '%s'; skipping CISS UKI build. \e[0m\n" "${profile}"
printf "\e[92m Secure Boot profile '%s'; skipping CISS UKI build. \e[0m\n" "${profile}"
return 0
fi
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Building CISS Secure Boot UKI ... \e[0m\n"
printf "\e[95m🧪 Building CISS Secure Boot UKI ... \e[0m\n"
cd "${build_dir}"
@@ -280,18 +349,18 @@ main() {
)
if [[ -n "${microcode_initrd}" ]]; then
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Embedding separate early microcode cpio before normal initrd: '%s'. \e[0m\n" "${microcode_initrd}"
printf "\e[92m Embedding separate early microcode cpio before normal initrd: '%s'. \e[0m\n" "${microcode_initrd}"
ukify_args+=(--initrd="${microcode_initrd}")
else
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] No separate early microcode cpio found; using normal initrd only. \e[0m\n"
printf "\e[92m No separate early microcode cpio found; using normal initrd only. \e[0m\n"
fi
ukify_args+=(--initrd="${initrd_path}")
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Creating unsigned UKI: '%s'. \e[0m\n" "${unsigned_uki}"
printf "\e[95m🧪 Creating unsigned UKI: '%s'. \e[0m\n" "${unsigned_uki}"
ukify "${ukify_args[@]}" --output="${unsigned_uki}"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Creating signed UKI: '%s'. \e[0m\n" "${signed_uki}"
printf "\e[95m🧪 Creating signed UKI: '%s'. \e[0m\n" "${signed_uki}"
ukify "${ukify_args[@]}" \
--secureboot-private-key="${secureboot_key}" \
--secureboot-certificate="${secureboot_cert}" \
@@ -316,8 +385,8 @@ main() {
sbverify --cert "${secureboot_cert}" "${signed_uki}"
} >| "${manifest}" 2>&1
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] UKI inspection and signature verification written to '%s'. \e[0m\n" "${manifest}"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] CISS Secure Boot UKI build completed. \e[0m\n"
printf "\e[92m UKI inspection and signature verification written to '%s'. \e[0m\n" "${manifest}"
printf "\e[92m CISS Secure Boot UKI build completed. \e[0m\n"
return 0
}