V9.14.008.2026.06.04
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2026-06-04 20:14:02 +01:00
parent ec3aca7fc8
commit 83f6f8488c
8 changed files with 775 additions and 2 deletions
+1
View File
@@ -0,0 +1 @@
+26
View File
@@ -0,0 +1,26 @@
---
gitea: none
include_toc: true
---
# 1. CISS.debian.live.builder
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br>
**Build**: V9.14.008.2026.06.04<br>
# 2. CISS Secure Boot Private Material
This directory is intentionally ignored except for this README.
On the air-gapped build host, place the private EFI image signing key here:
* `ciss-efi-image.key`
Do not commit private keys. The custom UKI hooks fail if this key is copied into `binary/`, `chroot/`, or
`config/includes.*`.
---
**[no tracking | no logging | no advertising | no profiling | no bullshit](https://coresecret.eu/)**
<!-- vim: set number et ts=2 sw=2 sts=2 ai tw=128 ft=markdown -->
+26
View File
@@ -0,0 +1,26 @@
---
gitea: none
include_toc: true
---
# 1. CISS.debian.live.builder
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br>
**Build**: V9.14.008.2026.06.04<br>
# 2. CISS Secure Boot Public Material
Place public CISS Secure Boot certificates here on the air-gapped build host.
Expected file for the `ciss-uki` build profile:
* `ciss-efi-image.crt`
Public CA and module-signing certificates may also live here, for example `ciss-secureboot-ca.crt` and
`ciss-module-signing.crt`, but they are not copied into the ISO by the current UKI hooks.
---
**[no tracking | no logging | no advertising | no profiling | no bullshit](https://coresecret.eu/)**
<!-- vim: set number et ts=2 sw=2 sts=2 ai tw=128 ft=markdown -->
+1
View File
@@ -0,0 +1 @@
@@ -0,0 +1,327 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2026-06-04; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# 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
set -Ceuo pipefail
#######################################
# Prints failure message.
# Globals:
# None
# Arguments:
# 1: Message to print
# Returns:
# 42: on failure
#######################################
die() {
declare message="$1"
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ ❌ %s \e[0m\n" "${message}" >&2
exit 42
}
#######################################
# Checking command to execute for existence.
# Globals:
# None
# Arguments:
# 1: Command
# Returns:
# 0: on success
#######################################
require_command() {
declare command_name="$1"
command -v "${command_name}" >/dev/null 2>&1 || die "Required command not found: '${command_name}'."
return 0
}
#######################################
# Checking file for existence.
# Globals:
# None
# Arguments:
# 1: /PATH/TO/FILE
# 2: Description
# Returns:
# 0: on success
#######################################
require_file() {
declare file_path="$1"
declare description="$2"
[[ -f "${file_path}" ]] || die "Missing ${description}: '${file_path}'."
return 0
}
#######################################
# Checking file for existence.
# Globals:
# None
# Arguments:
# 1: /PATH/TO/FILE
# 2: Description
# Returns:
# 0: on success
#######################################
read_bootappend_live() {
declare config_file="$1"
declare output_var="$2"
declare -a matches=()
declare value=""
require_file "${config_file}" "live-build binary configuration"
mapfile -t matches < <(grep -E '^LB_BOOTAPPEND_LIVE=' "${config_file}" || true)
if (( ${#matches[@]} != 1 )); then
die "Expected exactly one LB_BOOTAPPEND_LIVE entry in '${config_file}', found '${#matches[@]}'."
fi
value="${matches[0]#LB_BOOTAPPEND_LIVE=}"
if [[ "${value}" == \"*\" ]]; then
value="${value#\"}"
value="${value%\"}"
fi
[[ -n "${value}" ]] || die "LB_BOOTAPPEND_LIVE in '${config_file}' is empty."
printf -v "${output_var}" "%s" "${value}"
return 0
}
collect_artifacts_from_dir() {
declare artifact_dir="$1"
declare kernel_output_var="$2"
declare initrd_output_var="$3"
declare -a kernels=()
declare -a initrds=()
if [[ ! -d "${artifact_dir}" ]]; then
printf -v "${kernel_output_var}" "%s" ""
printf -v "${initrd_output_var}" "%s" ""
return 0
fi
mapfile -d '' -t kernels < <(find "${artifact_dir}" -maxdepth 1 -type f -name "vmlinuz-*" -print0 | LC_ALL=C sort -z)
mapfile -d '' -t initrds < <(find "${artifact_dir}" -maxdepth 1 -type f -name "initrd.img-*" -print0 | LC_ALL=C sort -z)
if (( ${#kernels[@]} > 1 )); then
die "Ambiguous kernel candidates in '${artifact_dir}'. Refusing to select automatically."
fi
if (( ${#initrds[@]} > 1 )); then
die "Ambiguous initrd candidates in '${artifact_dir}'. Refusing to select automatically."
fi
printf -v "${kernel_output_var}" "%s" "${kernels[0]:-}"
printf -v "${initrd_output_var}" "%s" "${initrds[0]:-}"
return 0
}
select_kernel_initrd_pair() {
declare kernel_output_var="$1"
declare initrd_output_var="$2"
declare binary_kernel=""
declare binary_initrd=""
declare fallback_kernel=""
declare fallback_initrd=""
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 -v "${kernel_output_var}" "%s" "${binary_kernel}"
printf -v "${initrd_output_var}" "%s" "${binary_initrd}"
return 0
fi
if [[ -n "${binary_kernel}" || -n "${binary_initrd}" ]]; then
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"
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 -v "${kernel_output_var}" "%s" "${fallback_kernel}"
printf -v "${initrd_output_var}" "%s" "${fallback_initrd}"
return 0
fi
die "No complete kernel/initrd pair found in binary/live or chroot/boot."
}
collect_optional_microcode() {
declare artifact_dir="$1"
declare output_var="$2"
declare -a microcode_candidates=()
mapfile -d '' -t microcode_candidates < <(
find "${artifact_dir}" -maxdepth 1 -type f \( -name "*microcode*.cpio" -o -name "*ucode*.cpio" \) -print0 | LC_ALL=C sort -z
)
if (( ${#microcode_candidates[@]} > 1 )); then
die "Ambiguous separate early microcode cpio candidates in '${artifact_dir}'. Refusing to select automatically."
fi
printf -v "${output_var}" "%s" "${microcode_candidates[0]:-}"
return 0
}
guard_private_key_leaks() {
declare -a guard_roots=(binary chroot config/includes.binary config/includes.chroot config/includes.installer)
declare guard_root=""
declare private_file=""
for guard_root in "${guard_roots[@]}"; do
if [[ ! -d "${guard_root}" ]]; then
continue
fi
while IFS= read -r -d '' private_file; do
die "Refusing private Secure Boot key inside build artifact path: '${private_file}'."
done < <(find "${guard_root}" -xdev -type f \( -name "ciss-efi-image.key" -o -name "ciss-module-signing.key" \) -print0)
done
return 0
}
main() {
declare profile="${VAR_CISS_SECUREBOOT_PROFILE:-debian-shim}"
declare build_dir="${VAR_HANDLER_BUILD_DIR:-${PWD}}"
declare secureboot_dir="${VAR_CISS_SECUREBOOT_DIR:-${VAR_WORKDIR:-${build_dir}}/ciss.secureboot}"
declare secureboot_key="${VAR_CISS_SECUREBOOT_EFI_KEY:-${secureboot_dir}/private/ciss-efi-image.key}"
declare secureboot_cert="${VAR_CISS_SECUREBOOT_EFI_CERT:-${secureboot_dir}/public/ciss-efi-image.crt}"
declare stub="/usr/lib/systemd/boot/efi/linuxx64.efi.stub"
declare os_release="chroot/usr/lib/os-release"
declare kernel_path=""
declare initrd_path=""
declare kernel_base=""
declare initrd_base=""
declare kernel_version=""
declare initrd_version=""
declare cmdline=""
declare microcode_initrd=""
declare output_root=""
declare uki_dir=""
declare manifest_dir=""
declare unsigned_uki=""
declare signed_uki=""
declare manifest=""
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}"
return 0
fi
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Building CISS Secure Boot UKI ... \e[0m\n"
cd "${build_dir}"
require_command ukify
require_command sbverify
require_command sha512sum
require_file "${stub}" "systemd EFI stub"
require_file "${secureboot_key}" "CISS EFI image signing key"
require_file "${secureboot_cert}" "CISS EFI image signing certificate"
require_file "${os_release}" "target os-release metadata"
guard_private_key_leaks
select_kernel_initrd_pair kernel_path initrd_path
kernel_base="${kernel_path##*/}"
initrd_base="${initrd_path##*/}"
kernel_version="${kernel_base#vmlinuz-}"
initrd_version="${initrd_base#initrd.img-}"
[[ -n "${kernel_version}" && "${kernel_base}" != "${kernel_version}" ]] || die "Kernel artifact name does not match vmlinuz-<version>: '${kernel_path}'."
[[ -n "${initrd_version}" && "${initrd_base}" != "${initrd_version}" ]] || die "Initrd artifact name does not match initrd.img-<version>: '${initrd_path}'."
if [[ "${kernel_version}" != "${initrd_version}" ]]; then
die "Kernel/initrd version mismatch: kernel='${kernel_version}', initrd='${initrd_version}'."
fi
read_bootappend_live "config/binary" cmdline
collect_optional_microcode "${initrd_path%/*}" microcode_initrd
output_root="${build_dir}/ciss.secureboot"
uki_dir="${output_root}/uki"
manifest_dir="${output_root}/manifests"
unsigned_uki="${uki_dir}/CISS-LIVE-${kernel_version}.unsigned.efi"
signed_uki="${uki_dir}/CISS-LIVE-${kernel_version}.signed.efi"
manifest="${manifest_dir}/CISS-LIVE-${kernel_version}.uki-build.txt"
install -d -m 0755 "${uki_dir}" "${manifest_dir}"
rm -f -- "${unsigned_uki}" "${signed_uki}" "${manifest}"
ukify_args=(
build
--stub="${stub}"
--linux="${kernel_path}"
--cmdline="${cmdline}"
--os-release="@${os_release}"
--uname="${kernel_version}"
)
if [[ -n "${microcode_initrd}" ]]; then
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] 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"
fi
ukify_args+=(--initrd="${initrd_path}")
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] 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}"
ukify "${ukify_args[@]}" \
--secureboot-private-key="${secureboot_key}" \
--secureboot-certificate="${secureboot_cert}" \
--output="${signed_uki}"
require_file "${unsigned_uki}" "unsigned CISS UKI"
require_file "${signed_uki}" "signed CISS UKI"
{
printf "CISS Secure Boot UKI build manifest\n"
printf "Kernel: %s\n" "${kernel_path}"
printf "Initrd: %s\n" "${initrd_path}"
printf "Microcode initrd: %s\n" "${microcode_initrd:-none}"
printf "Uname: %s\n" "${kernel_version}"
printf "OS release: %s\n" "${os_release}"
printf "Command line: %s\n" "${cmdline}"
printf "\nSHA512:\n"
sha512sum "${unsigned_uki}" "${signed_uki}"
printf "\nukify inspect:\n"
ukify inspect "${signed_uki}"
printf "\nsbverify:\n"
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"
return 0
}
main "$@"
exit 0
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
@@ -0,0 +1,248 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2026-06-04; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# 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
set -Ceuo pipefail
declare TMP_DIR=""
cleanup() {
declare build_dir="${VAR_HANDLER_BUILD_DIR:-${PWD}}"
if [[ -n "${TMP_DIR}" && -d "${TMP_DIR}" ]]; then
case "${TMP_DIR}" in
"${build_dir}/ciss.secureboot/"*)
rm -rf -- "${TMP_DIR}"
;;
*)
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ [FATAL] Refusing to clean unexpected temporary path: '%s'. \e[0m\n" "${TMP_DIR}" >&2
return 42
;;
esac
fi
return 0
}
trap cleanup EXIT
die() {
declare message="$1"
printf "\e[91m++++ ++++ ++++ ++++ ++++ ++++ ++ [FATAL] %s \e[0m\n" "${message}" >&2
exit 42
}
require_command() {
declare command_name="$1"
command -v "${command_name}" >/dev/null 2>&1 || die "Required command not found: '${command_name}'."
return 0
}
require_file() {
declare file_path="$1"
declare description="$2"
[[ -f "${file_path}" ]] || die "Missing ${description}: '${file_path}'."
return 0
}
select_signed_uki() {
declare uki_dir="$1"
declare output_var="$2"
declare -a signed_ukis=()
[[ -d "${uki_dir}" ]] || die "Missing CISS UKI output directory: '${uki_dir}'."
mapfile -d '' -t signed_ukis < <(find "${uki_dir}" -maxdepth 1 -type f -name "CISS-LIVE-*.signed.efi" -print0 | LC_ALL=C sort -z)
if (( ${#signed_ukis[@]} != 1 )); then
die "Expected exactly one signed CISS UKI in '${uki_dir}', found '${#signed_ukis[@]}'."
fi
printf -v "${output_var}" "%s" "${signed_ukis[0]}"
return 0
}
guard_private_key_leaks() {
declare -a guard_roots=(binary chroot config/includes.binary config/includes.chroot config/includes.installer)
declare guard_root=""
declare private_file=""
for guard_root in "${guard_roots[@]}"; do
if [[ ! -d "${guard_root}" ]]; then
continue
fi
while IFS= read -r -d '' private_file; do
die "Refusing private Secure Boot key inside build artifact path: '${private_file}'."
done < <(find "${guard_root}" -xdev -type f \( -name "ciss-efi-image.key" -o -name "ciss-module-signing.key" \) -print0)
done
return 0
}
install_iso_tree_bootx64() {
declare signed_uki="$1"
declare output_var="$2"
declare iso_tree_bootx64=""
if [[ -d "binary/EFI/boot" ]]; then
iso_tree_bootx64="binary/EFI/boot/bootx64.efi"
elif [[ -d "binary/EFI/BOOT" ]]; then
iso_tree_bootx64="binary/EFI/BOOT/BOOTX64.EFI"
elif [[ -d "binary/EFI" ]]; then
install -d -m 0755 "binary/EFI/BOOT"
iso_tree_bootx64="binary/EFI/BOOT/BOOTX64.EFI"
fi
if [[ -n "${iso_tree_bootx64}" ]]; then
install -m 0644 "${signed_uki}" "${iso_tree_bootx64}"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Mirrored signed UKI into ISO EFI tree: '%s'. \e[0m\n" "${iso_tree_bootx64}"
else
printf "\e[93m++++ ++++ ++++ ++++ ++++ ++++ ++ [WARN] No binary/EFI tree found; only EFI boot image was updated. \e[0m\n"
fi
printf -v "${output_var}" "%s" "${iso_tree_bootx64}"
return 0
}
main() {
declare profile="${VAR_CISS_SECUREBOOT_PROFILE:-debian-shim}"
declare build_dir="${VAR_HANDLER_BUILD_DIR:-${PWD}}"
declare secureboot_dir="${VAR_CISS_SECUREBOOT_DIR:-${VAR_WORKDIR:-${build_dir}}/ciss.secureboot}"
declare secureboot_cert="${VAR_CISS_SECUREBOOT_EFI_CERT:-${secureboot_dir}/public/ciss-efi-image.crt}"
declare output_root=""
declare uki_dir=""
declare manifest_dir=""
declare signed_uki=""
declare efi_img="binary/boot/grub/efi.img"
declare uki_name=""
declare kernel_version=""
declare manifest=""
declare tmp_img=""
declare extracted_uki=""
declare iso_tree_bootx64=""
declare uki_size=""
declare -i uki_kib=0
declare -i blocks=0
declare source_epoch="${SOURCE_DATE_EPOCH:-0}"
declare volid=""
if [[ "${profile}" != "ciss-uki" ]]; then
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Secure Boot profile '%s'; skipping CISS UKI EFI installation. \e[0m\n" "${profile}"
return 0
fi
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Installing CISS signed UKI into EFI boot image ... \e[0m\n"
cd "${build_dir}"
require_command cmp
require_command mcopy
require_command mdir
require_command mkfs.msdos
require_command sbverify
require_command sha512sum
require_command stat
require_command ukify
require_file "${secureboot_cert}" "CISS EFI image signing certificate"
require_file "${efi_img}" "live-build EFI boot image"
guard_private_key_leaks
output_root="${build_dir}/ciss.secureboot"
uki_dir="${output_root}/uki"
manifest_dir="${output_root}/manifests"
select_signed_uki "${uki_dir}" signed_uki
uki_name="${signed_uki##*/}"
kernel_version="${uki_name#CISS-LIVE-}"
kernel_version="${kernel_version%.signed.efi}"
[[ -n "${kernel_version}" && "${kernel_version}" != "${uki_name}" ]] || die "Signed UKI name does not match CISS-LIVE-<version>.signed.efi: '${signed_uki}'."
install -d -m 0755 "${manifest_dir}"
TMP_DIR="$(mktemp -d -p "${output_root}" "efi-img.XXXXXXXX")"
tmp_img="${TMP_DIR}/efi.img"
extracted_uki="${TMP_DIR}/BOOTX64.EFI"
manifest="${manifest_dir}/CISS-LIVE-${kernel_version}.efi-install.txt"
rm -f -- "${manifest}"
uki_size="$(stat -c %s -- "${signed_uki}")"
uki_kib=$(( (uki_size + 1023) / 1024 ))
blocks=$(( (uki_kib + 8192 + 31) / 32 * 32 ))
if (( blocks < 32768 )); then
blocks=32768
fi
if [[ ! "${source_epoch}" =~ ^[0-9]+$ ]]; then
source_epoch="0"
fi
printf -v volid "%08x" "$((source_epoch % 4294967296))"
printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] Rebuilding EFI boot image with signed UKI as EFI/BOOT/BOOTX64.EFI. \e[0m\n"
mkfs.msdos -C "${tmp_img}" "${blocks}" -i "${volid}" >/dev/null
mmd -i "${tmp_img}" "::EFI"
mmd -i "${tmp_img}" "::EFI/BOOT"
mcopy -m -o -i "${tmp_img}" "${signed_uki}" "::EFI/BOOT/BOOTX64.EFI"
mcopy -o -i "${tmp_img}" "::EFI/BOOT/BOOTX64.EFI" "${extracted_uki}"
cmp -s "${signed_uki}" "${extracted_uki}" || die "Extracted BOOTX64.EFI differs from signed UKI before EFI image installation."
sbverify --cert "${secureboot_cert}" "${extracted_uki}" >/dev/null
install -m 0644 "${tmp_img}" "${efi_img}"
rm -f -- "${extracted_uki}"
mcopy -o -i "${efi_img}" "::EFI/BOOT/BOOTX64.EFI" "${extracted_uki}"
cmp -s "${signed_uki}" "${extracted_uki}" || die "Installed EFI/BOOT/BOOTX64.EFI differs from signed UKI."
sbverify --cert "${secureboot_cert}" "${extracted_uki}" >/dev/null
install_iso_tree_bootx64 "${signed_uki}" iso_tree_bootx64
if [[ -n "${iso_tree_bootx64}" ]]; then
cmp -s "${signed_uki}" "${iso_tree_bootx64}" || die "ISO EFI tree BOOTX64.EFI differs from signed UKI."
sbverify --cert "${secureboot_cert}" "${iso_tree_bootx64}" >/dev/null
fi
guard_private_key_leaks
{
printf "CISS Secure Boot EFI image installation manifest\n"
printf "EFI image: %s\n" "${efi_img}"
printf "Installed path: EFI/BOOT/BOOTX64.EFI\n"
printf "ISO EFI tree mirror: %s\n" "${iso_tree_bootx64:-none}"
printf "Signed UKI: %s\n" "${signed_uki}"
printf "FAT image blocks KiB: %s\n" "${blocks}"
printf "FAT volume id: %s\n" "${volid}"
printf "\nSHA512:\n"
sha512sum "${efi_img}" "${signed_uki}" "${extracted_uki}"
if [[ -n "${iso_tree_bootx64}" ]]; then
sha512sum "${iso_tree_bootx64}"
fi
printf "\nEFI directory:\n"
mdir -i "${efi_img}" "::EFI/BOOT"
printf "\nukify inspect installed BOOTX64.EFI:\n"
ukify inspect "${extracted_uki}"
printf "\nsbverify installed BOOTX64.EFI:\n"
sbverify --cert "${secureboot_cert}" "${extracted_uki}"
} >| "${manifest}" 2>&1
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] EFI image installation verification written to '%s'. \e[0m\n" "${manifest}"
printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ [INFO] CISS signed UKI installed as EFI/BOOT/BOOTX64.EFI. \e[0m\n"
return 0
}
main "$@"
exit 0
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
+2 -2
View File
@@ -26,8 +26,8 @@ $(echo -e "\e[97m###############################################################
$(echo -e "\e[92m CISS.debian.live.builder from https://git.coresecret.dev/msw \e[0m") $(echo -e "\e[92m CISS.debian.live.builder from https://git.coresecret.dev/msw \e[0m")
$(echo -e "\e[92m A lightweight Shell Wrapper for building a hardened Debian Live ISO Image. \e[0m") $(echo -e "\e[92m A lightweight Shell Wrapper for building a hardened Debian Live ISO Image. \e[0m")
$(echo -e "\e[97m (c) Marc S. Weidner, 2018 - 2025 \e[0m") $(echo -e "\e[97m (c) Marc S. Weidner, 2018 - 2026 \e[0m")
$(echo -e "\e[97m (p) Centurion Press, 2024 - 2025 \e[0m") $(echo -e "\e[97m (p) Centurion Press, 2024 - 2026 \e[0m")
$(echo -e "\e[95m 💬 Contact: \e[0m") $(echo -e "\e[95m 💬 Contact: \e[0m")
$(echo -e "\e[95m 🌐 https://coresecret.eu/ \e[0m") $(echo -e "\e[95m 🌐 https://coresecret.eu/ \e[0m")
+144
View File
@@ -0,0 +1,144 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2026-06-04; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# 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=SC2154,SC2312
guard_sourcing || return "${ERR_GUARD_SRCE}"
#######################################
# Guard against accidental inclusion of CISS Secure Boot private keys.
# Globals:
# ERR_UNCRITICAL
# VAR_HANDLER_BUILD_DIR
# Arguments:
# None
# Returns:
# 0: on success
# ERR_UNCRITICAL: on failure
#######################################
secureboot_profile_guard_private_keys() {
declare -a guard_roots=(
"${VAR_HANDLER_BUILD_DIR}/binary"
"${VAR_HANDLER_BUILD_DIR}/chroot"
"${VAR_HANDLER_BUILD_DIR}/config/includes.binary"
"${VAR_HANDLER_BUILD_DIR}/config/includes.chroot"
"${VAR_HANDLER_BUILD_DIR}/config/includes.installer"
)
declare guard_root=""
declare private_file=""
for guard_root in "${guard_roots[@]}"; do
if [[ ! -d "${guard_root}" ]]; then
continue
fi
while IFS= read -r -d '' private_file; do
printf "\e[91m❌ Refusing private Secure Boot key inside build artifact path: '%s'. \e[0m\n" "${private_file}" >&2
return "${ERR_UNCRITICAL}"
done < <(find "${guard_root}" -xdev -type f \( -name "ciss-efi-image.key" -o -name "ciss-module-signing.key" \) -print0)
done
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f secureboot_profile_guard_private_keys
#######################################
# Apply the selected Secure Boot profile after repository files were copied into the live-build config.
# Globals:
# BASH_SOURCE
# ERR_ARG_MSMTCH
# ERR_UNCRITICAL
# VAR_ARCHITECTURE
# VAR_CISS_SECUREBOOT_PROFILE
# VAR_HANDLER_BUILD_DIR
# VAR_WORKDIR
# Arguments:
# None
# Returns:
# 0: on success
#######################################
secureboot_profile_apply() {
declare profile="${VAR_CISS_SECUREBOOT_PROFILE,,}"
declare hooks_dir="${VAR_HANDLER_BUILD_DIR}/config/hooks/live"
declare build_uki_hook="${hooks_dir}/zzzz_ciss_build_uki.hook.binary"
declare install_uki_hook="${hooks_dir}/9910-ciss-install-uki-into-efi-img.hook.binary"
declare secureboot_dir="${VAR_WORKDIR}/ciss.secureboot"
declare secureboot_key="${secureboot_dir}/private/ciss-efi-image.key"
declare secureboot_cert="${secureboot_dir}/public/ciss-efi-image.crt"
printf "\e[95m🧪 %s starting ... \e[0m\n" "${BASH_SOURCE[0]}"
case "${profile}" in
debian-shim | ciss-uki)
;;
*)
printf "\e[91m❌ Unsupported Secure Boot profile: '%s'. \e[0m\n" "${profile}" >&2
return "${ERR_ARG_MSMTCH}"
;;
esac
declare -gx VAR_CISS_SECUREBOOT_PROFILE="${profile}"
declare -gx VAR_CISS_SECUREBOOT_DIR="${secureboot_dir}"
declare -gx VAR_CISS_SECUREBOOT_EFI_KEY="${secureboot_key}"
declare -gx VAR_CISS_SECUREBOOT_EFI_CERT="${secureboot_cert}"
if [[ "${profile}" == "debian-shim" ]]; then
rm -f -- "${build_uki_hook}" "${install_uki_hook}"
printf "\e[92m✅ Secure Boot profile: debian-shim. Custom CISS UKI hooks disabled. \e[0m\n"
printf "\e[92m✅ %s successfully applied. \e[0m\n" "${BASH_SOURCE[0]}"
return 0
fi
if [[ "${VAR_ARCHITECTURE,,}" != "amd64" ]]; then
printf "\e[91m❌ Secure Boot profile 'ciss-uki' currently targets amd64/BOOTX64.EFI only. Got: '%s'. \e[0m\n" "${VAR_ARCHITECTURE}" >&2
return "${ERR_ARG_MSMTCH}"
fi
install -d -m 0755 "${secureboot_dir}/public" "${secureboot_dir}/manifests" "${secureboot_dir}/uki"
install -d -m 0700 "${secureboot_dir}/private"
if [[ ! -f "${secureboot_key}" ]]; then
printf "\e[91m❌ Missing CISS Secure Boot EFI signing key: '%s'. \e[0m\n" "${secureboot_key}" >&2
return "${ERR_UNCRITICAL}"
fi
if [[ ! -f "${secureboot_cert}" ]]; then
printf "\e[91m❌ Missing CISS Secure Boot EFI signing certificate: '%s'. \e[0m\n" "${secureboot_cert}" >&2
return "${ERR_UNCRITICAL}"
fi
secureboot_profile_guard_private_keys
chmod 0755 "${build_uki_hook}" "${install_uki_hook}"
printf "\e[92m❌ Secure Boot profile: ciss-uki. Custom UKI hooks enabled. \e[0m\n"
printf "\e[92m❌ %s successfully applied. \e[0m\n" "${BASH_SOURCE[0]}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f secureboot_profile_apply
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh