All checks were successful
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Successful in 1m4s
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
336 lines
9.9 KiB
Bash
336 lines
9.9 KiB
Bash
#!/bin/sh
|
|
# bashsupport disable=BP5007
|
|
# shellcheck disable=SC2249
|
|
# shellcheck shell=sh
|
|
|
|
# SPDX-Version: 3.0
|
|
# SPDX-CreationInfo: 2025-11-12; 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-2025; WEIDNER, Marc S.; <msw@coresecret.dev>
|
|
# SPDX-FileType: SOURCE
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# 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
|
|
|
|
### Modified Version of the original file:
|
|
### https://salsa.debian.org/live-team/live-boot 'components/0030-ciss-verify-checksums'
|
|
### If the offered checksum is successfully verified, proceed with booting. Otherwise, panic.
|
|
|
|
#######################################
|
|
# Modified checksum-integrity and authenticity-verification-script depending on pinned GPG FPR for boot process verification.
|
|
# Globals:
|
|
# LIVE_BOOT_CMDLINE
|
|
# _TTY
|
|
# Arguments:
|
|
# 1: _MOUNTPOINT
|
|
# Returns:
|
|
# 0 : Successful verification
|
|
#######################################
|
|
Verify_checksums() {
|
|
printf "\e[95m[INFO] Starting : [/usr/lib/live/boot/0030-ciss-verify-checksums] \n\e[0m"
|
|
|
|
### Declare variables --------------------------------------------------------------------------------------------------------
|
|
|
|
### Will be replaced at build time:
|
|
export CDLB_EXP_FPR="@EXP_FPR@"
|
|
export CDLB_EXP_CA_FPR="@EXP_CA_FPR@"
|
|
|
|
### Declare functions --------------------------------------------------------------------------------------------------------
|
|
|
|
#######################################
|
|
# Helper for colored text output on stdout.
|
|
# Globals:
|
|
# None
|
|
# Arguments:
|
|
# *: String to print
|
|
#######################################
|
|
log_in() { printf '\e[95m[INFO] %s \n\e[0m' "$*"; }
|
|
|
|
|
|
#######################################
|
|
# Helper for colored text output on stdout.
|
|
# Globals:
|
|
# None
|
|
# Arguments:
|
|
# *: String to print
|
|
#######################################
|
|
log_ok() { printf '\e[92m[INFO] %s \n\e[0m' "$*"; }
|
|
|
|
#######################################
|
|
# Helper for colored text output on stdout.
|
|
# Globals:
|
|
# None
|
|
# Arguments:
|
|
# *: String to print
|
|
#######################################
|
|
log_er() { printf '\e[91m[FATAL] %s \n\e[0m' "$*"; }
|
|
|
|
_MOUNTPOINT="${1}"
|
|
|
|
_PARAMETER=""
|
|
|
|
_TTY="/dev/tty8"
|
|
|
|
LIVE_VERIFY_CHECKSUMS_DIGESTS="${LIVE_VERIFY_CHECKSUMS_DIGESTS:-sha512 sha384 sha256}"
|
|
|
|
LIVE_VERIFY_CHECKSUMS_SIGNATURES="false"
|
|
|
|
_KEYFILE=""
|
|
|
|
_MP=""
|
|
|
|
### Parse commandline arguments ----------------------------------------------------------------------------------------------
|
|
for _PARAMETER in ${LIVE_BOOT_CMDLINE}; do
|
|
|
|
case "${_PARAMETER}" in
|
|
|
|
live-boot.verify-checksums=* | verify-checksums=*)
|
|
|
|
LIVE_VERIFY_CHECKSUMS="true"
|
|
LIVE_VERIFY_CHECKSUMS_DIGESTS="${_PARAMETER#*verify-checksums=}"
|
|
;;
|
|
|
|
live-boot.verify-checksums | verify-checksums)
|
|
|
|
LIVE_VERIFY_CHECKSUMS="true"
|
|
;;
|
|
|
|
live-boot.verify-checksums-signatures | verify-checksums-signatures)
|
|
|
|
LIVE_VERIFY_CHECKSUMS_SIGNATURES="true"
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
### Check if the function should be skipped ----------------------------------------------------------------------------------
|
|
case "${LIVE_VERIFY_CHECKSUMS}" in
|
|
|
|
true)
|
|
:
|
|
;;
|
|
|
|
*)
|
|
return 0
|
|
;;
|
|
|
|
esac
|
|
|
|
### Check GPG pubkey file correct path ---------------------------------------------------------------------------------------
|
|
for _MP in /lib/live/mount/medium /run/live/medium /cdrom /; do
|
|
|
|
if [ -e "${_MP}/${CDLB_EXP_FPR}.gpg" ]; then
|
|
|
|
_KEYFILE="${_MP}/${CDLB_EXP_FPR}.gpg"
|
|
|
|
if [ -e "${_MP}/${CDLB_EXP_CA_FPR}.gpg" ]; then
|
|
|
|
_CA_KEYFILE="${_MP}/${CDLB_EXP_CA_FPR}.gpg"
|
|
|
|
fi
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
# shellcheck disable=SC2164
|
|
cd "${_MOUNTPOINT}"
|
|
|
|
|
|
### CDLB verification of script integrity itself -----------------------------------------------------------------------------
|
|
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then
|
|
|
|
log_begin_msg "Verifying integrity of: [0030-ciss-verify-checksums]"
|
|
printf "\n"
|
|
|
|
_CAND=""
|
|
CDLB_SCRIPT_SELF="" CDLB_CMD="" CDLB_COMPUTED="" CDLB_EXPECTED="" CDLB_HASHFILE="" CDLB_SIG_FILE=""
|
|
|
|
CDLB_CMD="/usr/bin/sha512sum"
|
|
CDLB_SHA="sha512"
|
|
|
|
for _CAND in /scripts/live-bottom/0030-ciss-verify-checksums /usr/lib/live/boot/0030-ciss-verify-checksums ; do
|
|
|
|
[ -e "${_CAND}" ] && { CDLB_SCRIPT_SELF="${_CAND}"; break; }
|
|
|
|
done
|
|
|
|
CDLB_SCRIPT_FILE="${CDLB_SCRIPT_SELF##*/}"
|
|
CDLB_SCRIPT_PATH="${CDLB_SCRIPT_SELF%/*}"
|
|
CDLB_SCRIPT_FULL="${CDLB_SCRIPT_PATH%/}/${CDLB_SCRIPT_FILE}"
|
|
CDLB_HASHFILE="/etc/ciss/hashes/${CDLB_SCRIPT_FILE}.${CDLB_SHA}sum.txt"
|
|
CDLB_SIG_FILE="/etc/ciss/signatures/${CDLB_SCRIPT_FILE}.${CDLB_SHA}sum.txt.sig"
|
|
|
|
_STATUS="$(/usr/bin/gpgv --keyring "${_KEYFILE}" --status-fd 1 "${CDLB_SIG_FILE}" "${CDLB_HASHFILE}")"
|
|
|
|
_CDLB_SIG_FILE_FPR="$(printf '%s\n' "${_STATUS}" | awk '/^\[GNUPG:\] VALIDSIG /{print $3; exit}')"
|
|
|
|
### Compare against pinned and expected fingerprint.
|
|
if [ "${_CDLB_SIG_FILE_FPR}" = "${CDLB_EXP_FPR}" ]; then
|
|
|
|
log_ok "Signature FPR valid: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]"
|
|
|
|
else
|
|
|
|
log_er "Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]"
|
|
sleep 8
|
|
panic "[FATAL] Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]."
|
|
|
|
fi
|
|
|
|
### Script self-integrity and authenticity checks --------------------------------------------------------------------------
|
|
### Assumption: initramfs itself is not altered.
|
|
log_in "Verifying signature of: [${CDLB_SIG_FILE}] ..."
|
|
|
|
if ! /usr/bin/gpgv --keyring "${_KEYFILE}" --status-fd 1 "${CDLB_SIG_FILE}" "${CDLB_HASHFILE}"; then
|
|
|
|
log_er "Verifying signature of: [${CDLB_SIG_FILE}] failed."
|
|
sleep 8
|
|
panic "[FATAL] Verifying signature of: [${CDLB_SIG_FILE}] failed."
|
|
|
|
else
|
|
|
|
log_ok "Verifying signature of: [${CDLB_SIG_FILE}] successful."
|
|
|
|
fi
|
|
|
|
log_in "Recomputing hash for: [${CDLB_SHA}] ..."
|
|
|
|
CDLB_COMPUTED=$("${CDLB_CMD}" "${CDLB_SCRIPT_FULL}" | { read -r first _ || exit 1; printf '%s\n' "${first}"; })
|
|
IFS=' ' read -r CDLB_EXPECTED _ < "${CDLB_HASHFILE}"
|
|
|
|
if [ "${CDLB_COMPUTED}" != "${CDLB_EXPECTED}" ]; then
|
|
|
|
log_er "Recomputing hash for: [${CDLB_SHA}] failed."
|
|
sleep 8
|
|
panic "[FATAL] Recomputing hash for: [${CDLB_SHA}] failed."
|
|
|
|
fi
|
|
|
|
log_ok "Recomputing hash for: [${CDLB_SHA}] successful."
|
|
log_ok "Verification of authenticity and integrity of [${CDLB_SCRIPT_FULL}] successfully completed."
|
|
log_end_msg
|
|
printf "\n"
|
|
|
|
fi
|
|
|
|
### Checksum and checksum signature verification -----------------------------------------------------------------------------
|
|
log_begin_msg "Verifying checksums"
|
|
printf "\n"
|
|
log_in "Verifying checksums ..."
|
|
|
|
# shellcheck disable=SC2001
|
|
for _DIGEST in $(echo "${LIVE_VERIFY_CHECKSUMS_DIGESTS}" | sed -e 's|,| |g'); do
|
|
|
|
# shellcheck disable=SC2060
|
|
_CHECKSUMS="$(echo "${_DIGEST}" | tr [a-z] [A-Z])SUMS ${_DIGEST}sum.txt"
|
|
|
|
for _CHECKSUM in ${_CHECKSUMS}; do
|
|
|
|
if [ -e "${_CHECKSUM}" ]; then
|
|
|
|
log_in "Found: [${_CHECKSUM}] ..."
|
|
|
|
if [ -e "/usr/bin/${_DIGEST}sum" ]; then
|
|
|
|
log_in "Found: [/usr/bin/${_DIGEST}sum] ..."
|
|
|
|
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then
|
|
|
|
log_in "Checking signature of: [${_CHECKSUM}] ..."
|
|
|
|
_CHECKSUM_SIGNATURE="${_CHECKSUM}.sig"
|
|
|
|
if /usr/bin/gpgv --keyring "${_KEYFILE}" --status-fd 1 "${_CHECKSUM_SIGNATURE}" "${_CHECKSUM}"; then
|
|
|
|
_RETURN_PGP="${?}"
|
|
log_in "Checking signature of: [${_CHECKSUM}] successful."
|
|
|
|
else
|
|
|
|
_RETURN_PGP="${?}"
|
|
log_er "Checking signature of: [${_CHECKSUM}] failed."
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
_RETURN_PGP="na"
|
|
|
|
fi
|
|
|
|
# shellcheck disable=SC2312
|
|
if grep -v '^#' "${_CHECKSUM}" | /usr/bin/"${_DIGEST}"sum -c > "${_TTY}"; then
|
|
|
|
_RETURN_SHA="${?}"
|
|
log_ok "Found: [/usr/bin/${_DIGEST}sum] successful verified: [${_CHECKSUM}]"
|
|
|
|
else
|
|
|
|
_RETURN_SHA="${?}"
|
|
log_er "Found: [/usr/bin/${_DIGEST}sum] unsuccessful verified: [${_CHECKSUM}]"
|
|
|
|
fi
|
|
|
|
# Stop after the first verification.
|
|
break 2
|
|
|
|
else
|
|
|
|
_RETURN_SHA="255"
|
|
log_er "NOT Found [/usr/bin/${_DIGEST}sum]."
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
|
|
|
log_end_msg
|
|
printf "\n"
|
|
|
|
case "${_RETURN_PGP},${_RETURN_SHA}" in
|
|
|
|
"0,0")
|
|
log_ok "Verification of [GPG signature] and [sha checksum] file successful; continuing booting in 8 seconds."
|
|
log_success_msg "Verification of [GPG signature] and [sha checksum] file successful; continuing booting in 8 seconds."
|
|
sleep 8
|
|
return 0
|
|
;;
|
|
|
|
"na,0")
|
|
log_ok "Verification of [sha checksum] file successful; continuing booting in 8 seconds."
|
|
log_success_msg "Verification of [sha checksum] file successful; continuing booting in 8 seconds."
|
|
sleep 8
|
|
return 0
|
|
;;
|
|
|
|
"0,"*)
|
|
log_er "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
|
|
sleep 8
|
|
panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
|
|
;;
|
|
|
|
*",0")
|
|
log_er "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
|
|
sleep 8
|
|
panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
|
|
;;
|
|
|
|
"na,"*)
|
|
log_er "Verification of [sha checksum] file failed."
|
|
sleep 8
|
|
panic "Verification of [sha checksum] file failed."
|
|
;;
|
|
|
|
esac
|
|
}
|
|
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
|