#!/bin/bash # SPDX-Version: 3.0 # SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; # SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.installer.git # SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency # SPDX-FileCopyrightText: 2024-2025; WEIDNER, Marc S.; # 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.installer # SPDX-Security-Contact: security@coresecret.eu set -Ceuo pipefail ####################################### # Backup Wrapper for all x509 Root CA Certs. # Globals: # ary_search_dir # var_backup_dir # Arguments: # None ####################################### create_backup() { printf "Backup Certificate: [%s] ... \n" "${var_backup_dir}" mkdir -p "${var_backup_dir}" declare dir="" for dir in "${ary_search_dir[@]}"; do if [[ -d "${dir}" ]] && compgen -G "${dir}"/* > /dev/null; then cp -r "${dir}"/* "${var_backup_dir}" fi done printf "Backup Certificate: [%s] done. \n" "${var_backup_dir}" } ####################################### # Check the validity of each certificate. # Globals: # ary_expd_certs # ary_search_dir # var_crrnt_date # Arguments: # None ####################################### check_certificates() { declare dir="" declare cert="" declare cert_date="" declare cert_date_seconds="" # shellcheck disable=SC2312 for dir in "${ary_search_dir[@]}"; do while IFS= read -r -d '' cert; do cert_date=$(openssl x509 -in "${cert}" -noout -enddate | sed 's/notAfter=//') cert_date_seconds=$(date -d "${cert_date}" +%s) if [[ ${cert_date_seconds} -lt ${var_crrnt_date} ]]; then declare -g ary_expd_certs+=("${cert}") fi done < <(find "${dir}" -type f \( -name "*.crt" -o -name "*.pem" \) -print0) done } ####################################### # Find and clean all ca-certificates.crt files in SEARCH_DIRS. # Globals: # CURRENT_DATE # SEARCH_DIRS # cert # line # Arguments: # None ####################################### delete_expired_from_all_bundles() { declare dir="" bundle="" for dir in "${ary_search_dir[@]}"; do bundle="${dir}/ca-certificates.crt" if [[ -f ${bundle} ]]; then printf "Checking Root-CA Bundle: [%s] ... \n" "${bundle}" # shellcheck disable=SC2155 declare tmp_bundle="$(mktemp "${bundle}.XXXXXXXX")" declare enddate="" cert_date_seconds="" line="" declare -a block=() declare -i expired=0 : >| "${tmp_bundle}" while IFS= read -r line; do block+=("${line}") if [[ ${line} == "-----END CERTIFICATE-----" ]]; then cert=$(printf "%s\n" "${block[@]}") enddate=$(echo "${cert}" | openssl x509 -noout -enddate 2> /dev/null | sed 's/notAfter=//') if [[ -n ${enddate} ]]; then declare cert_date_seconds="" cert_date_seconds=$(date -d "${enddate}" +%s) if [[ ${cert_date_seconds} -lt ${var_crrnt_date} ]]; then expired=1 else expired=0 fi else expired=0 fi if [[ ${expired} -eq 0 ]]; then printf "%s\n" "${block[@]}" >> "${tmp_bundle}" else printf "Certificate deleted: [%s] Expired: [%s] \n" "${bundle}" "${enddate}" fi block=() fi done < "${bundle}" mv -f "${tmp_bundle}" "${bundle}" printf "Checking Root-CA Bundle: [%s] done. \n" "${bundle}" fi done } ####################################### # Main() for deleting all expired x.509 Certificates in the chroot target system. # Globals: # ary_expd_certs # ary_search_dir # var_backup_dir # var_crrnt_date # Arguments: # 0 ####################################### main() { printf "Chroot hook: [%s] starting ... \n" "${0}" printf "Now checking and cleaning expired CA certificates in the target system. \n" printf "This may take up to a minute, depending on system size. \n" printf "All expired certificates will be safely removed. \n" declare -ag ary_search_dir=( "/etc/ssl/certs" "/usr/local/share/ca-certificates" "/usr/share/ca-certificates" "/etc/letsencrypt" ) declare -gx var_backup_dir="/root/.ciss/cdi/backup/certificates" declare -gx var_crrnt_date; var_crrnt_date=$(date +%s) declare -ag ary_expd_certs=() declare exp_cert="" basename="" mozilla_entry="" printf "Check certificates in: [%s] \n" "${ary_search_dir[*]}" create_backup delete_expired_from_all_bundles check_certificates if [[ ${#ary_expd_certs[@]} -eq 0 ]]; then printf "No expired certificates found. \n" sleep 1 else printf "Expired certificates found: \n" for exp_cert in "${ary_expd_certs[@]}"; do printf " [%s] \n" "${exp_cert}" done for exp_cert in "${ary_expd_certs[@]}"; do rm -f "${exp_cert}" printf "Certificate deleted: [%s] \n" "${exp_cert}" basename=$(basename "${exp_cert}") mozilla_entry="mozilla/${basename%.pem}.crt" mozilla_entry="${mozilla_entry%.crt}.crt" declare ca_conf="/etc/ca-certificates.conf" if grep -Fxq "${mozilla_entry}" "${ca_conf}"; then sed -i "s|^${mozilla_entry}$|#${mozilla_entry}|" "${ca_conf}" printf "Entry in [ca-certificates.conf] deselected: [#%s] \n" "${mozilla_entry}" fi done printf "Updating the certificate cache ... \n" if ! update-ca-certificates --fresh; then printf "[ERROR] Failed to update certificate cache. \n" >&2 exit 1 fi printf "Updating the certificate cache done. \n" fi printf "Chroot hook: [%s] applied successfully. \n" "${0}" exit 0 } main "$@" # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh