mba: normalize vendor_db in EV_EFI_VARIABLE_AUTHORITY events

tpm2_eventlog may provide the vendor_db data as either a signature list
or raw hex bytes, depending on the version used.

In this commit we add a enrich_vendor_db_authority_variable() function
to make sure we end up with a signature list independent on the format
of the data obtained by tpm2_eventlog.

Related: RHEL-108844

Signed-off-by: Sergio Correia <scorreia@redhat.com>
This commit is contained in:
Sergio Correia 2025-08-20 00:02:44 +00:00
parent 84e80090a9
commit d49b6792af
No known key found for this signature in database
GPG Key ID: D0D219ED1F7E762C
5 changed files with 536 additions and 2 deletions

View File

@ -0,0 +1,91 @@
From 39ea2efb72b383f729474a1583d4b8c097cf848a Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Thu, 6 Feb 2025 21:29:56 +0000
Subject: [PATCH 07/10] tests: change test_mba_parsing to not need keylime
installed
This test needs the verifier configuration file available, and on
systems that do not have keylime installed (hence, no config file),
it would fail.
This commit changes the test so that it creates a verifier conf file
in a temporary directory with default values, so that it can use it.
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
test/test_mba_parsing.py | 52 +++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 14 deletions(-)
diff --git a/test/test_mba_parsing.py b/test/test_mba_parsing.py
index 670a602..4ee4e3b 100644
--- a/test/test_mba_parsing.py
+++ b/test/test_mba_parsing.py
@@ -1,27 +1,51 @@
import os
+import tempfile
import unittest
+from configparser import RawConfigParser
+from keylime import config
+from keylime.cmd import convert_config
from keylime.common.algorithms import Hash
from keylime.mba import mba
+TEMPLATES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "templates"))
+
class TestMBAParsing(unittest.TestCase):
def test_parse_bootlog(self):
"""Test parsing binary measured boot event log"""
- mba.load_imports()
- # Use the file that triggered https://github.com/keylime/keylime/issues/1153
- mb_log_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "data/mb_log.b64"))
- with open(mb_log_path, encoding="utf-8") as f:
- # Read the base64 input and remove the newlines
- b64 = "".join(f.read().splitlines())
- pcr_hashes, boot_aggregates, measurement_data, failure = mba.bootlog_parse(b64, Hash.SHA256)
-
- self.assertFalse(
- failure, f"Parsing of measured boot log failed with: {list(map(lambda x: x.context, failure.events))}"
- )
- self.assertTrue(isinstance(pcr_hashes, dict))
- self.assertTrue(isinstance(boot_aggregates, dict))
- self.assertTrue(isinstance(measurement_data, dict))
+ # This test requires the verifier configuration file, so let's create
+ # one with the default values to use, so that we do not depend on the
+ # configuration files existing in the test system.
+ with tempfile.TemporaryDirectory() as config_dir:
+ # Let's write the config file for the verifier.
+ verifier_config = convert_config.process_versions(["verifier"], TEMPLATES_DIR, RawConfigParser(), True)
+ convert_config.output(["verifier"], verifier_config, TEMPLATES_DIR, config_dir)
+
+ # As we want to use a config file from a different location, the
+ # proper way would be to define an environment variable for the
+ # module of interest, e.g. in our case it would be the
+ # KEYLIME_VERIFIER_CONFIG variable. However, the config module
+ # reads such env vars at first load, and there is no clean way
+ # to have it re-read them, so for this test we will override it
+ # manually.
+ config.CONFIG_ENV["verifier"] = os.path.abspath(os.path.join(config_dir, "verifier.conf"))
+
+ mba.load_imports()
+ # Use the file that triggered https://github.com/keylime/keylime/issues/1153
+ mb_log_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "data/mb_log.b64"))
+ with open(mb_log_path, encoding="utf-8") as f:
+ # Read the base64 input and remove the newlines
+ b64 = "".join(f.read().splitlines())
+ pcr_hashes, boot_aggregates, measurement_data, failure = mba.bootlog_parse(b64, Hash.SHA256)
+
+ self.assertFalse(
+ failure,
+ f"Parsing of measured boot log failed with: {list(map(lambda x: x.context, failure.events))}",
+ )
+ self.assertTrue(isinstance(pcr_hashes, dict))
+ self.assertTrue(isinstance(boot_aggregates, dict))
+ self.assertTrue(isinstance(measurement_data, dict))
if __name__ == "__main__":
--
2.47.3

View File

@ -0,0 +1,53 @@
From 1496567e4b06f7a8eff9f758ea2e4e00ffa89f9b Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Wed, 4 Jun 2025 07:28:54 +0100
Subject: [PATCH 08/10] tests: skip measured-boot related tests for s390x and
ppc64le
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
test/test_create_mb_policy.py | 2 ++
test/test_mba_parsing.py | 2 ++
2 files changed, 4 insertions(+)
diff --git a/test/test_create_mb_policy.py b/test/test_create_mb_policy.py
index aa7a4b9..cd32bda 100644
--- a/test/test_create_mb_policy.py
+++ b/test/test_create_mb_policy.py
@@ -5,6 +5,7 @@ Copyright 2024 Red Hat, Inc.
import argparse
import os
+import platform
import unittest
from keylime.policy import create_mb_policy
@@ -12,6 +13,7 @@ from keylime.policy import create_mb_policy
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "data", "create-mb-policy"))
+@unittest.skipIf(platform.machine() in ["ppc64le", "s390x"], "ppc64le and s390x are not supported")
class CreateMeasuredBootPolicy_Test(unittest.TestCase):
def test_event_to_sha256(self):
test_cases = [
diff --git a/test/test_mba_parsing.py b/test/test_mba_parsing.py
index 4ee4e3b..82e6086 100644
--- a/test/test_mba_parsing.py
+++ b/test/test_mba_parsing.py
@@ -1,4 +1,5 @@
import os
+import platform
import tempfile
import unittest
from configparser import RawConfigParser
@@ -11,6 +12,7 @@ from keylime.mba import mba
TEMPLATES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "templates"))
+@unittest.skipIf(platform.machine() in ["ppc64le", "s390x"], "ppc64le and s390x are not supported")
class TestMBAParsing(unittest.TestCase):
def test_parse_bootlog(self):
"""Test parsing binary measured boot event log"""
--
2.47.3

View File

@ -0,0 +1,58 @@
From be968fd54198042d2014ad63368b78e9d4609169 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Thu, 22 May 2025 11:25:15 -0400
Subject: [PATCH 09/10] tests: fix rpm repo tests from create-runtime-policy
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
.../create-runtime-policy/setup-rpm-tests | 28 +++++++++++++------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/test/data/create-runtime-policy/setup-rpm-tests b/test/data/create-runtime-policy/setup-rpm-tests
index 708438c..b62729b 100755
--- a/test/data/create-runtime-policy/setup-rpm-tests
+++ b/test/data/create-runtime-policy/setup-rpm-tests
@@ -217,20 +217,32 @@ create_rpm() {
# https://github.com/rpm-software-management/rpm/commit/96467dce18f264b278e17ffe1859c88d9b5aa4b6
_pkgname="DUMMY-${_name}-${_version}-${_rel}.noarch.rpm"
- _expected_pkg="${RPMSDIR}/noarch/${_pkgname}"
- [ -e "${_expected_pkg}" ] && return 0
+ # For some reason, it may not store the built package within the
+ # noarch directory, but directly in RPMS, so let's check both
+ # locations.
+ _expected_pkg="${RPMSDIR}/noarch/${_pkgname} ${RPMSDIR}/${_pkgname}"
+ for _expected in ${_expected_pkg}; do
+ if [ -e "${_expected}" ]; then
+ echo "(create_rpm) CREATED RPM: ${_expected}" >&2
+ return 0
+ fi
+ done
# OK, the package was not built where it should. Let us see if
# it was built in ~/rpmbuild instead, and if that is the case,
# copy it to the expected location.
- _bad_location_pkg="${HOME}/rpmbuild/RPMS/noarch/${_pkgname}"
- if [ -e "${_bad_location_pkg}" ]; then
- echo "WARNING: the package ${_pkgname} was built into ~/rpmbuild despite rpmbuild being instructed to build it at a different location. Probably a fallout from https://github.com/rpm-software-management/rpm/commit/96467dce" >&2
- install -D -m644 "${_bad_location_pkg}" "${_expected_pkg}"
- return 0
- fi
+ _bad_location_pkg="${HOME}/rpmbuild/RPMS/noarch/${_pkgname} ${HOME}/rpmbuild/RPMS/${_pkgname}"
+ for _bad_l in ${_bad_location_pkg}; do
+ if [ -e "${_bad_l}" ]; then
+ echo "WARNING: the package ${_pkgname} was built into ~/rpmbuild despite rpmbuild being instructed to build it at a different location. Probably a fallout from https://github.com/rpm-software-management/rpm/commit/96467dce" >&2
+ install -D -m644 "${_bad_l}" "${RPMSDIR}/noarch/${_pkgname}"
+ echo "(create_rpm) CREATED RPM: ${RPMSDIR}/noarch/${_pkgname}" >&2
+ return 0
+ fi
+ done
# Should not be here.
+ echo "create_rpm() ended with error; probably an issue with the location where the RPMs were built" >&2
return 1
}
--
2.47.3

File diff suppressed because one or more lines are too long

View File

@ -28,23 +28,46 @@ Patch: 0002-mb-support-EV_EFI_HANDOFF_TABLES-events-on-PCR1.patch
Patch: 0003-mb-support-vendor_db-as-logged-by-newer-shim-version.patch
# Backported from https://github.com/keylime/keylime/pull/1784
# and https://github.com/keylime/keylime/pull/1785.
# and https://github.com/keylime/keylime/pull/1785
Patch: 0004-verifier-Gracefully-shutdown-on-signal.patch
Patch: 0005-revocations-Try-to-send-notifications-on-shutdown.patch
Patch: 0006-requests_client-close-the-session-at-the-end-of-the-.patch
# Backported from https://github.com/keylime/keylime/pull/1736,
# https://github.com/keylime/keylime/commit/11c6b7f and
# https://github.com/keylime/keylime/commit/dd63459
Patch: 0007-tests-change-test_mba_parsing-to-not-need-keylime-in.patch
Patch: 0008-tests-skip-measured-boot-related-tests-for-s390x-and.patch
Patch: 0009-tests-fix-rpm-repo-tests-from-create-runtime-policy.patch
# Backported from https://github.com/keylime/keylime/pull/1793
Patch: 0010-mba-normalize-vendor_db-in-EV_EFI_VARIABLE_AUTHORITY.patch
# Main program: Apache-2.0
# Icons: MIT
License: Apache-2.0 AND MIT
BuildRequires: git-core
BuildRequires: swig
BuildRequires: openssl
BuildRequires: openssl-devel
BuildRequires: python3-devel
BuildRequires: python3-dbus
BuildRequires: python3-jinja2
BuildRequires: python3-cryptography
BuildRequires: python3-gpg
BuildRequires: python3-pyasn1
BuildRequires: python3-pyasn1-modules
BuildRequires: python3-tornado
BuildRequires: python3-sqlalchemy
BuildRequires: python3-lark
BuildRequires: python3-psutil
BuildRequires: python3-pyyaml
BuildRequires: python3-jsonschema
BuildRequires: python3-setuptools
BuildRequires: systemd-rpm-macros
BuildRequires: rpm-sign
BuildRequires: createrepo_c
BuildRequires: tpm2-tools
Requires: python3-%{srcname} = %{version}-%{release}
Requires: %{srcname}-base = %{version}-%{release}
@ -91,6 +114,7 @@ Recommends: (%{srcname}-selinux if selinux-policy-%{selinuxtype})
%endif
%ifarch %efi
BuildRequires: efivar-libs
Requires: efivar-libs
%endif
@ -264,6 +288,33 @@ done
install -p -D -m 0644 %{SOURCE2} %{buildroot}/%{_sysusersdir}/%{srcname}.conf
install -p -D -m 0644 %{SOURCE3} %{buildroot}/%{_tmpfilesdir}/%{name}.conf
%check
# Create the default configuration files to be used by the tests.
# Also set the associated environment variables so that the tests
# will actually use them.
CONF_TEMP_DIR="$(mktemp -d)"
%{python3} -m keylime.cmd.convert_config --out "${CONF_TEMP_DIR}" --templates templates/
export KEYLIME_VERIFIER_CONFIG="${CONF_TEMP_DIR}/verifier.conf"
export KEYLIME_TENANT_CONFIG="${CONF_TEMP_DIR}/tenant.conf"
export KEYLIME_REGISTRAR_CONFIG="${CONF_TEMP_DIR}/registrar.conf"
export KEYLIME_CA_CONFIG="${CONF_TEMP_DIR}/ca.conf"
export KEYLIME_LOGGING_CONFIG="${CONF_TEMP_DIR}/logging.conf"
# Run the tests.
%{python3} -m unittest
# Cleanup.
[ "${CONF_TEMP_DIR}" ] && rm -rf "${CONF_TEMP_DIR}"
for e in KEYLIME_VERIFIER_CONFIG \
KEYLIME_TENANT_CONFIG \
KEYLIME_REGISTRAR_CONFIG \
KEYLIME_CA_CONFIG \
KEYLIME_LOGGING_CONFIG; do
unset "${e}"
done
exit 0
%pre base
%sysusers_create_compat %{SOURCE2}
exit 0