#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-10-11; 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: EUPL-1.2 OR LicenseRef-CCLA-1.0
# 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

printf "\e[95m++++ ++++ ++++ ++++ ++++ ++++ ++ 🧪 '%s' starting ... \e[0m\n" "${0}"

target="/usr/lib/live/boot/0030-verify-checksums"
src="$(mktemp)"

if [[ ! -d /usr/lib/live/boot ]]; then
  mkdir -p /usr/lib/live/boot
fi

cat << 'EOF' >| "${src}"
#!/bin/sh
# bashsupport disable=BP5007
# shellcheck shell=sh

# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-10-28; 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-verify-checksums'
### In case of successful verification of the offered checksum, proceed with booting; otherwise panic.

#######################################
# Modified checksum-integrity and authenticity-verification-script for continuing the boot process.
# Globals:
#   LIVE_BOOT_CMDLINE
#   _TTY
# Arguments:
#   1: _MOUNTPOINT
# Returns:
#   0 : Successful verification
#######################################
Verify_checksums() {
  _MOUNTPOINT="${1}"

  _TTY="/dev/tty8"

  LIVE_VERIFY_CHECKSUMS_DIGESTS="${LIVE_VERIFY_CHECKSUMS_DIGESTS:-sha512 sha384 sha256}"

  LIVE_VERIFY_CHECKSUMS_SIGNATURES="false"

  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

  case "${LIVE_VERIFY_CHECKSUMS}" in

    true)
      :
      ;;

    *)
      return 0
      ;;

  esac

  # 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-verify-checksums' ..."
    printf "\n"

    CDLB_SCRIPT="$(basename "${0}")"
    CDLB_SHA="sha512"
    CDLB_CMD="" CDLB_COMPUTED="" CDLB_EXPECTED="" CDLB_HASHFILE="" CDLB_ITEM="" CDLB_SIG_FILE=""

    for CDLB_ITEM in ${CDLB_SHA}; do

      CDLB_HASHFILE="${CDLB_SCRIPT}.${CDLB_ITEM}"
      CDLB_SIG_FILE="${CDLB_HASHFILE}.sig"
      CDLB_CMD="${CDLB_ITEM}sum"

      printf "Verifying signature of: [%s]\n" "${CDLB_HASHFILE}"

      if ! gpgv --keyring 0030-verify-checksums_public.gpg "${CDLB_SIG_FILE}" "${CDLB_HASHFILE}"; then

        printf "Signature verification failed for: [%s]\n" "${CDLB_HASHFILE}"
        sleep 8
        # TODO: Remove debug mode
        # return 0

      else

        printf "Signature verification successful for: [%s]\n" "${CDLB_HASHFILE}"

      fi

      printf "Recomputing hash for: [%s]\n" "${CDLB_ITEM}"

      CDLB_COMPUTED=$("${CDLB_CMD}" "${CDLB_SCRIPT}" | { read -r first rest || exit 1; printf '%s\n' "${first}"; })
      read -r CDLB_EXPECTED < "${CDLB_HASHFILE}"

      if [ "${CDLB_COMPUTED}" != "${CDLB_EXPECTED}" ]; then

        printf "Recomputed hash mismatch for: [%s]\n" "${CDLB_ITEM}"
        sleep 8
        # TODO: Remove debug mode
        # return 0

      fi

      printf "Hash verification successful for: [%s]\n" "${CDLB_ITEM}"

    done

    printf "Verifying integrity of '0030-verify-checksums' successfully completed. Proceeding."

    log_end_msg
    printf "\n"

  fi

  ### Checksum and checksum signature verification -----------------------------------------------------------------------------
  log_begin_msg "Verifying checksums"
  printf "\n"

  # 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

        printf "Found [%s] ...\n" "${_CHECKSUM}"

        if [ -e "/bin/${_DIGEST}sum" ]; then

          if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then

            printf "Checking Signature of [%s] ...\n" "${_CHECKSUM}"
            _CHECKSUM_SIGNATURE="${_CHECKSUM}.sig"
            gpgv --keyring 0030-verify-checksums_public.gpg "${_CHECKSUM_SIGNATURE}" "${_CHECKSUM}"
            _RETURN_PGP="${?}"

          else

            _RETURN_PGP="na"

          fi

          printf "Checking Hashes of [%s] ...\n" "${_CHECKSUM}"

          # shellcheck disable=SC2312
          grep -v '^#' "${_CHECKSUM}" | /bin/"${_DIGEST}"sum -c > "${_TTY}"
          _RETURN_SHA="${?}"

          # Stop after the first verification.
          break 2

        else

          printf "Not found [%s] ...\n" "/bin/${_DIGEST}sum"

        fi

      fi

    done

  done

  log_end_msg

  case "${_RETURN_PGP},${_RETURN_SHA}" in

    0,0)
      log_success_msg "Verification of signature AND checksum file successful; continuing booting in 8 seconds."
      sleep 8
      return 0
      ;;

    na,0)
      log_success_msg "Verification of checksum file successful; continuing booting in 8 seconds."
      sleep 8
      return 0
      ;;

    *,0)
      panic "Verification of signature file failed while verification of checksum file successful."
      ;;

    na,*)
      panic "Verification of checksum file failed."
      ;;

  esac
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
EOF

# Copy and make executable
install -m 0755 "${src}" "${target}"

rm -f "${src}"

unset target src

printf "\e[92m++++ ++++ ++++ ++++ ++++ ++++ ++ ✅ '%s' applied successfully. \e[0m\n" "${0}"

exit 0
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
