From 659eef6750efed5e3b10fc8f6b60138c63e58407 Mon Sep 17 00:00:00 2001 From: Peter Kindler Date: Wed, 17 Apr 2024 11:43:32 +0200 Subject: [PATCH] feat(swupdate): add multicert functionality for signed firmware when factory partition is present --- .../swupdate/25-sw-collections-config.sh | 74 ++++++++++--------- .../swupdate/swupdate/26-multicert-config.sh | 39 ++++++++++ .../swupdate/swupdate_%.bbappend | 7 +- 3 files changed, 83 insertions(+), 37 deletions(-) create mode 100644 layers/meta-belden-coreos/recipes-support/swupdate/swupdate/26-multicert-config.sh diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh index 9b2ec54..0957ae1 100644 --- a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh +++ b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh @@ -2,41 +2,43 @@ # ============================================================================== ROOT_PART=$(swupdate -g) -echo "Root partition is ${ROOT_PART}" - -# Get the partition label of the root partition -# ============================================================================== - -DISK_DEVICE_NAME=$(lsblk -ndo pkname "${ROOT_PART}") -DISK_PARTITION_TYPE=$(lsblk -dno PTTYPE "/dev/${DISK_DEVICE_NAME}") - -echo "Root partition is on device ${DISK_DEVICE_NAME} - type ${DISK_PARTITION_TYPE}" - -# Use partlabel for GPT disk, as it's more reliable than the filesystem label -# Fallback to label for legacy DOS/MBR disk -if [ "${DISK_PARTITION_TYPE}" == "gpt" ]; then - ROOT_PARTLABEL=$(lsblk -dno PARTLABEL "${ROOT_PART}") +if [ "${ROOT_PART}" == "" ]; then + # In case we are running on a installer image + SWUPDATE_ARGS="${SWUPDATE_ARGS} -e stable,copy0" else - echo "Using MBR is not supported" - exit 1 + echo "Root partition is ${ROOT_PART}" + + # Get the partition label of the root partition + # ============================================================================== + + DISK_DEVICE_NAME=$(lsblk -ndo pkname "${ROOT_PART}") + DISK_PARTITION_TYPE=$(lsblk -dno PTTYPE "/dev/${DISK_DEVICE_NAME}") + + echo "Root partition is on device ${DISK_DEVICE_NAME} - type ${DISK_PARTITION_TYPE}" + + # Use partlabel for GPT disk, as it's more reliable than the filesystem label + # Fallback to label for legacy DOS/MBR disk + if [ "${DISK_PARTITION_TYPE}" == "gpt" ]; then + ROOT_PARTLABEL=$(lsblk -dno PARTLABEL "${ROOT_PART}") + else + echo "Using MBR is not supported" + exit 1 + fi + + echo "Root partition label is ${ROOT_PARTLABEL}" + + case $ROOT_PARTLABEL in + rootfs0 ) + echo "We are running copy0 -> Use copy1 in the SWU file" + SWUPDATE_ARGS="${SWUPDATE_ARGS} -q stable,copy1" + ;; + rootfs1 ) + echo "We are running copy1 -> Use copy0 in the SWU file" + SWUPDATE_ARGS="${SWUPDATE_ARGS} -q stable,copy0" + ;; + * ) + >&2 echo "Root partition label ${ROOT_PARTLABEL} is invalid" + exit 1 + ;; + esac fi - -echo "Root partition label is ${ROOT_PARTLABEL}" - -case $ROOT_PARTLABEL in - rootfs0 ) - echo "We are running copy0 -> Use copy1 in the SWU file" - SWUPDATE_ARGS="${SWUPDATE_ARGS} -e stable,copy1" - ;; - rootfs1 ) - echo "We are running copy1 -> Use copy0 in the SWU file" - SWUPDATE_ARGS="${SWUPDATE_ARGS} -e stable,copy0" - ;; - * ) - >&2 echo "Root partition label ${ROOT_PARTLABEL} is invalid" - exit 1 - ;; -esac - -echo "Public key used to verify software image is /usr/lib/swupdate/swupdate.crt" -SWUPDATE_ARGS="${SWUPDATE_ARGS} -k /usr/lib/swupdate/swupdate.crt" diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/26-multicert-config.sh b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/26-multicert-config.sh new file mode 100644 index 0000000..f312da1 --- /dev/null +++ b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/26-multicert-config.sh @@ -0,0 +1,39 @@ + +touch /tmp/combinedcert.pem +chmod 600 /tmp/combinedcert.pem + +# If we are running on a released device with a factory partition, add the five certs from PKI +if [ -f /etc/certificates.sha256sum ] && [ -d /mnt/factory/ ]; then + if ! mountpoint -q /mnt/factory; then + fct_part_was_mounted=0 + mount -o ro,noload /dev/disk/by-partlabel/factory /mnt/factory + else + fct_part_was_mounted=1 + fi + + if mountpoint -q /mnt/factory; then + numcerts_found=$(find /mnt/factory/certificates/*.pem -type f | wc -l) + numcerts_expected=$(wc -l < /etc/certificates.sha256sum) + if [ "$numcerts_found" -eq "$numcerts_expected" ]; then + + numfails=$(sha256sum -c /etc/certificates.sha256sum | grep -c 'FAILED') + if [ "$numfails" -eq 0 ]; then + + # in sha256sum file there are two spaces between hash and filename. Hence, the filename is the third word. + cut -f 3 -d " " < /etc/certificates.sha256sum | xargs cat > /tmp/combinedcert.pem + fi + fi + fi + + if [ $fct_part_was_mounted -eq 0 ]; then + umount /mnt/factory + fi +fi + +# If there is a developer or CI certificate, append it +if [ -f /usr/lib/swupdate/swupdate.crt ]; then + echo "The developer public key used to verify software image is /usr/lib/swupdate/swupdate.crt" + cat /usr/lib/swupdate/swupdate.crt >> /tmp/combinedcert.pem +fi + +SWUPDATE_ARGS="${SWUPDATE_ARGS} -k /tmp/combinedcert.pem" diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend index ea9d91b..ac61b5e 100644 --- a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend +++ b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend @@ -10,6 +10,7 @@ DEPENDS += "cos-certificates-and-keys-native" SRC_URI += "\ file://50-webserver-config.sh \ file://25-sw-collections-config.sh \ + file://26-multicert-config.sh \ " PACKAGES =+ "${PN}-coreos-config ${PN}-coreos-installer-config" @@ -24,7 +25,10 @@ FILES:${PN} += "${sysconfdir}/hwrevision" # If we install the webserver package, it should be started automatically FILES:${PN}-www += "${libdir}/swupdate/conf.d/50-webserver-config.sh" -FILES:${PN}-coreos-config += "${libdir}/swupdate/conf.d/25-sw-collections-config.sh" +FILES:${PN}-coreos-config += "\ + ${libdir}/swupdate/conf.d/25-sw-collections-config.sh \ + ${libdir}/swupdate/conf.d/26-multicert-config.sh \ +" RDEPENDS:${PN}:append = " efibootguard" @@ -45,6 +49,7 @@ do_install:append() { # Probably replace revision with the value of the device tree install -m 755 ${WORKDIR}/50-webserver-config.sh ${D}${libdir}/swupdate/conf.d/ install -m 755 ${WORKDIR}/25-sw-collections-config.sh ${D}${libdir}/swupdate/conf.d/ + install -m 755 ${WORKDIR}/26-multicert-config.sh ${D}${libdir}/swupdate/conf.d/ install -m 755 ${COREOS_EFI_SECUREBOOT_KEYDIR}/swupdate.crt ${D}${libdir}/swupdate/ echo "${MACHINE} 1.0" > ${D}${sysconfdir}/hwrevision }