summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-06 02:17:30 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-06 02:17:30 +0000
commit35db127c4920388f07b1c109a88e6845d80ec827 (patch)
treea0f1670b1f0d4b49baf63986bc4968f33cfc6250
parent192f645be293b6bad64875fb1cfb872b027d99be (diff)
automatic import of keylimeopeneuler24.03_LTS
-rw-r--r--.gitignore2
-rw-r--r--0001-Remove-usage-of-Required-NotRequired-typing_ext.patch104
-rw-r--r--0002-Allow-keylime_server_t-tcp-connect-to-several-domain.patch27
-rw-r--r--0003-Use-version-2.0-as-the-minimum-for-the-configuration.patch51
-rw-r--r--0004-Duplicate-str_to_version-for-the-upgrade-tool.patch88
-rw-r--r--0005-elchecking-example-add-ignores-for-EV_PLATFORM_CONFI.patch50
-rw-r--r--0006-Revert-mapping-changes.patch43
-rw-r--r--0007-Handle-session-close-using-a-session-manager.patch90
-rw-r--r--0008-verifier-should-read-parameters-from-verifier.conf-o.patch31
-rw-r--r--0009-CVE-2023-38201.patch48
-rw-r--r--0010-CVE-2023-38200.patch69
-rw-r--r--0011-Automatically-update-agent-API-version.patch244
-rw-r--r--keylime.spec464
-rw-r--r--keylime.sysusers2
-rw-r--r--sources2
15 files changed, 1315 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..5a66786 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/keylime-selinux-1.2.0.tar.gz
+/v7.3.0.tar.gz
diff --git a/0001-Remove-usage-of-Required-NotRequired-typing_ext.patch b/0001-Remove-usage-of-Required-NotRequired-typing_ext.patch
new file mode 100644
index 0000000..5782252
--- /dev/null
+++ b/0001-Remove-usage-of-Required-NotRequired-typing_ext.patch
@@ -0,0 +1,104 @@
+Subject: [PATCH] Remove usage of Required/NotRequired typing_ext
+
+Since we do not yet have typing_extensions packaged, let us not
+use its functionality yet.
+---
+ keylime/ima/types.py | 33 ++++++++++++++-------------------
+ keylime/registrar_client.py | 8 +-------
+ 2 files changed, 15 insertions(+), 26 deletions(-)
+
+diff --git a/keylime/ima/types.py b/keylime/ima/types.py
+index 99f0aa7..a0fffdf 100644
+--- a/keylime/ima/types.py
++++ b/keylime/ima/types.py
+@@ -6,11 +6,6 @@ if sys.version_info >= (3, 8):
+ else:
+ from typing_extensions import Literal, TypedDict
+
+-if sys.version_info >= (3, 11):
+- from typing import NotRequired, Required
+-else:
+- from typing_extensions import NotRequired, Required
+-
+ ### Types for tpm_dm.py
+
+ RuleAttributeType = Optional[Union[int, str, bool]]
+@@ -51,7 +46,7 @@ class Rule(TypedDict):
+
+
+ class Policies(TypedDict):
+- version: Required[int]
++ version: int
+ match_on: MatchKeyType
+ rules: Dict[str, Rule]
+
+@@ -60,27 +55,27 @@ class Policies(TypedDict):
+
+
+ class RPMetaType(TypedDict):
+- version: Required[int]
+- generator: NotRequired[int]
+- timestamp: NotRequired[str]
++ version: int
++ generator: int
++ timestamp: str
+
+
+ class RPImaType(TypedDict):
+- ignored_keyrings: Required[List[str]]
+- log_hash_alg: Required[Literal["sha1", "sha256", "sha384", "sha512"]]
++ ignored_keyrings: List[str]
++ log_hash_alg: Literal["sha1", "sha256", "sha384", "sha512"]
+ dm_policy: Optional[Policies]
+
+
+ RuntimePolicyType = TypedDict(
+ "RuntimePolicyType",
+ {
+- "meta": Required[RPMetaType],
+- "release": NotRequired[int],
+- "digests": Required[Dict[str, List[str]]],
+- "excludes": Required[List[str]],
+- "keyrings": Required[Dict[str, List[str]]],
+- "ima": Required[RPImaType],
+- "ima-buf": Required[Dict[str, List[str]]],
+- "verification-keys": Required[str],
++ "meta": RPMetaType,
++ "release": int,
++ "digests": Dict[str, List[str]],
++ "excludes": List[str],
++ "keyrings": Dict[str, List[str]],
++ "ima": RPImaType,
++ "ima-buf": Dict[str, List[str]],
++ "verification-keys": str,
+ },
+ )
+diff --git a/keylime/registrar_client.py b/keylime/registrar_client.py
+index ab28977..ea5341b 100644
+--- a/keylime/registrar_client.py
++++ b/keylime/registrar_client.py
+@@ -13,12 +13,6 @@ if sys.version_info >= (3, 8):
+ else:
+ from typing_extensions import TypedDict
+
+-if sys.version_info >= (3, 11):
+- from typing import NotRequired
+-else:
+- from typing_extensions import NotRequired
+-
+-
+ class RegistrarData(TypedDict):
+ ip: Optional[str]
+ port: Optional[str]
+@@ -27,7 +21,7 @@ class RegistrarData(TypedDict):
+ aik_tpm: str
+ ek_tpm: str
+ ekcert: Optional[str]
+- provider_keys: NotRequired[Dict[str, str]]
++ provider_keys: Dict[str, str]
+
+
+ logger = keylime_logging.init_logging("registrar_client")
+--
+2.41.0
+
diff --git a/0002-Allow-keylime_server_t-tcp-connect-to-several-domain.patch b/0002-Allow-keylime_server_t-tcp-connect-to-several-domain.patch
new file mode 100644
index 0000000..c54b161
--- /dev/null
+++ b/0002-Allow-keylime_server_t-tcp-connect-to-several-domain.patch
@@ -0,0 +1,27 @@
+From e8a1fa55ff0892ee2380e832ac94abc629b401d6 Mon Sep 17 00:00:00 2001
+From: Patrik Koncity <pkoncity@redhat.com>
+Date: Thu, 10 Aug 2023 07:47:04 -0400
+Subject: [PATCH 2/2] Allow keylime_server_t tcp connect to several domains
+
+---
+ keylime-selinux-1.2.0/keylime.te | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/keylime-selinux-1.2.0/keylime.te b/keylime-selinux-1.2.0/keylime.te
+index 8d47d26..8e6487b 100644
+--- a/keylime-selinux-1.2.0/keylime.te
++++ b/keylime-selinux-1.2.0/keylime.te
+@@ -83,6 +83,10 @@ allow keylime_server_t self:udp_socket create_stream_socket_perms;
+ manage_dirs_pattern(keylime_server_t, keylime_log_t, keylime_log_t)
+ manage_files_pattern(keylime_server_t, keylime_log_t, keylime_log_t)
+
++corenet_tcp_connect_http_cache_port(keylime_server_t)
++corenet_tcp_connect_mysqld_port(keylime_server_t)
++corenet_tcp_connect_postgresql_port(keylime_server_t)
++
+ fs_getattr_all_fs(keylime_server_t)
+ fs_rw_inherited_tmpfs_files(keylime_server_t)
+
+--
+2.39.3
+
diff --git a/0003-Use-version-2.0-as-the-minimum-for-the-configuration.patch b/0003-Use-version-2.0-as-the-minimum-for-the-configuration.patch
new file mode 100644
index 0000000..4ecd144
--- /dev/null
+++ b/0003-Use-version-2.0-as-the-minimum-for-the-configuration.patch
@@ -0,0 +1,51 @@
+From b8e26ca5e98e1b842db2fc21411962d40f27c557 Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Tue, 15 Aug 2023 07:19:28 -0400
+Subject: [PATCH 3/4] Use version 2.0 as the minimum for the configuration
+
+---
+ keylime/cmd/convert_config.py | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/keylime/cmd/convert_config.py b/keylime/cmd/convert_config.py
+index ac28151..1d71b99 100755
+--- a/keylime/cmd/convert_config.py
++++ b/keylime/cmd/convert_config.py
+@@ -191,7 +191,13 @@ def output(components: List[str], config: RawConfigParser, templates: str, outdi
+
+ # Check that there are templates for all components
+ for component in components:
+- version = config[component]["version"].strip('" ')
++ # Minimum version.
++ version = '2.0'
++ if "version" in config[component]:
++ version = config[component]["version"].strip('" ')
++ else:
++ config[component]["version"] = version
++
+ version_dir = os.path.join(templates, version)
+ if not os.path.isdir(version_dir):
+ raise Exception(f"Could not find directory {version_dir}")
+@@ -292,15 +298,15 @@ def process_mapping(
+ raise Exception("Invalid version number found in old configuration")
+
+ except (configparser.NoOptionError, configparser.NoSectionError):
+- print(f"No version found in old configuration for {component}, using '1.0'")
+- old_version = (1, 0)
++ print(f"No version found in old configuration for {component}, using '2.0'")
++ old_version = (2, 0)
+ else:
+ # If the old_version does not contain the component from the
+ # mapping, use the minimum version to use defaults
+- old_version = (1, 0)
++ old_version = (2, 0)
+
+ # Skip versions lower than the current version
+- if old_version >= new_version:
++ if old_version >= new_version and component in old_config:
+ new[component] = old_config[component]
+ continue
+
+--
+2.39.3
+
diff --git a/0004-Duplicate-str_to_version-for-the-upgrade-tool.patch b/0004-Duplicate-str_to_version-for-the-upgrade-tool.patch
new file mode 100644
index 0000000..66cb11b
--- /dev/null
+++ b/0004-Duplicate-str_to_version-for-the-upgrade-tool.patch
@@ -0,0 +1,88 @@
+From dbd521e8e8f0ffd9ace79c7b9b888f4cb89488f9 Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Tue, 15 Aug 2023 06:09:37 -0400
+Subject: [PATCH 4/4] Duplicate str_to_version for the upgrade tool
+
+So it does not depend on python-keylime
+---
+ keylime/cmd/convert_config.py | 24 ++++++++++++++++++++++--
+ templates/2.0/adjust.py | 22 ++++++++++++++++++++--
+ 2 files changed, 42 insertions(+), 4 deletions(-)
+
+diff --git a/keylime/cmd/convert_config.py b/keylime/cmd/convert_config.py
+index c1c6180..cad5e31 100755
+--- a/keylime/cmd/convert_config.py
++++ b/keylime/cmd/convert_config.py
+@@ -84,13 +84,33 @@ import importlib.util
+ import itertools
+ import json
+ import os
++import re
+ import shutil
+ from configparser import RawConfigParser
+-from typing import List, Optional, Tuple
++from typing import List, Optional, Tuple, Union
+
+ from jinja2 import Template
+
+-from keylime.common.version import str_to_version
++
++def str_to_version(v_str: str) -> Union[Tuple[int, int], None]:
++ """
++ Validates the string format and converts the provided string to a tuple of
++ ints which can be sorted and compared.
++
++ :returns: Tuple with version number parts converted to int. In case of
++ invalid version string, returns None
++ """
++
++ # Strip to remove eventual quotes and spaces
++ v_str = v_str.strip('" ')
++
++ m = re.match(r"^(\d+)\.(\d+)$", v_str)
++
++ if not m:
++ return None
++
++ return (int(m.group(1)), int(m.group(2)))
++
+
+ COMPONENTS = ["agent", "verifier", "tenant", "registrar", "ca", "logging"]
+
+diff --git a/templates/2.0/adjust.py b/templates/2.0/adjust.py
+index 312b790..c1e582a 100644
+--- a/templates/2.0/adjust.py
++++ b/templates/2.0/adjust.py
+@@ -2,9 +2,27 @@ import ast
+ import configparser
+ import re
+ from configparser import RawConfigParser
+-from typing import Dict, List, Optional, Tuple
++from typing import Dict, List, Optional, Tuple, Union
+
+-from keylime.common.version import str_to_version
++
++def str_to_version(v_str: str) -> Union[Tuple[int, int], None]:
++ """
++ Validates the string format and converts the provided string to a tuple of
++ ints which can be sorted and compared.
++
++ :returns: Tuple with version number parts converted to int. In case of
++ invalid version string, returns None
++ """
++
++ # Strip to remove eventual quotes and spaces
++ v_str = v_str.strip('" ')
++
++ m = re.match(r"^(\d+)\.(\d+)$", v_str)
++
++ if not m:
++ return None
++
++ return (int(m.group(1)), int(m.group(2)))
+
+
+ def adjust(config: RawConfigParser, mapping: Dict) -> None: # pylint: disable=unused-argument
+--
+2.39.3
+
diff --git a/0005-elchecking-example-add-ignores-for-EV_PLATFORM_CONFI.patch b/0005-elchecking-example-add-ignores-for-EV_PLATFORM_CONFI.patch
new file mode 100644
index 0000000..18a242d
--- /dev/null
+++ b/0005-elchecking-example-add-ignores-for-EV_PLATFORM_CONFI.patch
@@ -0,0 +1,50 @@
+From f2432efbeb7b6305067111bb3a77ef5d7da4eb5b Mon Sep 17 00:00:00 2001
+From: Thore Sommer <mail@thson.de>
+Date: Thu, 10 Aug 2023 16:15:57 +0300
+Subject: [PATCH 5/6] elchecking/example: add ignores for
+ EV_PLATFORM_CONFIG_FLAGS
+
+These are generated by edk2 when used with QEMU, but we do not have a
+reference for them.
+
+Signed-off-by: Thore Sommer <mail@thson.de>
+---
+ keylime/mba/elchecking/example.py | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/keylime/mba/elchecking/example.py b/keylime/mba/elchecking/example.py
+index 8885227..921db4e 100644
+--- a/keylime/mba/elchecking/example.py
++++ b/keylime/mba/elchecking/example.py
+@@ -75,7 +75,6 @@ shim_authcode_sha256_no_secureboot = tests.obj_test(
+ kernel_cmdline=tests.type_test(str),
+ )
+
+-
+ allowed_kernel_list_test_no_secureboot = tests.list_test(shim_authcode_sha256_no_secureboot)
+
+
+@@ -303,6 +302,20 @@ class Example(policies.Policy):
+ ),
+ ),
+ )
++ # edk2 measures up to 4 of those events, where we do not have a good way to get a reference
++ # See:
++ # - https://github.com/keylime/keylime/issues/1393
++ # - https://github.com/tianocore/edk2/commit/935343cf1639a28530904a1e8d73d6517a07cbff
++ dispatcher.set(
++ (1, "EV_PLATFORM_CONFIG_FLAGS"),
++ tests.Or(
++ tests.OnceTest(tests.AcceptAll()),
++ tests.OnceTest(tests.AcceptAll()),
++ tests.OnceTest(tests.AcceptAll()),
++ tests.OnceTest(tests.AcceptAll()),
++ ),
++ )
++
+ dispatcher.set((4, "EV_EFI_ACTION"), tests.EvEfiActionTest(4))
+ for pcr in range(8):
+ dispatcher.set((pcr, "EV_SEPARATOR"), tests.EvSeperatorTest())
+--
+2.39.3
+
diff --git a/0006-Revert-mapping-changes.patch b/0006-Revert-mapping-changes.patch
new file mode 100644
index 0000000..e06a1c0
--- /dev/null
+++ b/0006-Revert-mapping-changes.patch
@@ -0,0 +1,43 @@
+From ed213b9533535ceae5026b2fab274f80bcc58cb8 Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Tue, 15 Aug 2023 09:18:32 -0400
+Subject: [PATCH 6/6] Revert mapping changes
+
+---
+ templates/2.0/mapping.json | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/templates/2.0/mapping.json b/templates/2.0/mapping.json
+index 66addbc..0036b63 100644
+--- a/templates/2.0/mapping.json
++++ b/templates/2.0/mapping.json
+@@ -207,7 +207,7 @@
+ "registrar_port": {
+ "section": "cloud_verifier",
+ "option": "registrar_port",
+- "default": "8881"
++ "default": "8891"
+ },
+ "tls_dir": {
+ "section": "cloud_verifier",
+@@ -232,7 +232,7 @@
+ "server_key_password": {
+ "section": "cloud_verifier",
+ "option": "private_key_pw",
+- "default": ""
++ "default": "default"
+ },
+ "enable_agent_mtls": {
+ "section": "cloud_verifier",
+@@ -558,7 +558,7 @@
+ "server_key_password": {
+ "section": "registrar",
+ "option": "private_key_pw",
+- "default": ""
++ "default": "default"
+ },
+ "server_cert": {
+ "section": "registrar",
+--
+2.39.3
+
diff --git a/0007-Handle-session-close-using-a-session-manager.patch b/0007-Handle-session-close-using-a-session-manager.patch
new file mode 100644
index 0000000..ead77ea
--- /dev/null
+++ b/0007-Handle-session-close-using-a-session-manager.patch
@@ -0,0 +1,90 @@
+From 3dc40e8b1878d84045ee80cb6d216348713c048a Mon Sep 17 00:00:00 2001
+From: Karel Srot <ksrot@redhat.com>
+Date: Tue, 15 Aug 2023 10:00:50 +0200
+Subject: [PATCH 7/7] Handle session close using a session manager
+
+Resolves https://github.com/keylime/keylime/issues/1455
+
+Signed-off-by: Karel Srot <ksrot@redhat.com>
+---
+ keylime/revocation_notifier.py | 50 +++++++++++++++++-----------------
+ packit-ci.fmf | 1 +
+ 2 files changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/keylime/revocation_notifier.py b/keylime/revocation_notifier.py
+index 31a3095..5cc8b1a 100644
+--- a/keylime/revocation_notifier.py
++++ b/keylime/revocation_notifier.py
+@@ -132,32 +132,32 @@ def notify_webhook(tosend: Dict[str, Any]) -> None:
+ def worker_webhook(tosend: Dict[str, Any], url: str) -> None:
+ interval = config.getfloat("verifier", "retry_interval")
+ exponential_backoff = config.getboolean("verifier", "exponential_backoff")
+- session = requests.session()
+- logger.info("Sending revocation event via webhook...")
+- for i in range(config.getint("verifier", "max_retries")):
+- next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
+- try:
+- response = session.post(url, json=tosend, timeout=5)
+- if response.status_code in [200, 202]:
+- break
+-
+- logger.debug(
+- "Unable to publish revocation message %d times via webhook, "
+- "trying again in %d seconds. "
+- "Server returned status code: %s",
+- i,
+- next_retry,
+- response.status_code,
+- )
+- except requests.exceptions.RequestException as e:
+- logger.debug(
+- "Unable to publish revocation message %d times via webhook, trying again in %d seconds: %s",
+- i,
+- next_retry,
+- e,
+- )
++ with requests.Session() as session:
++ logger.info("Sending revocation event via webhook...")
++ for i in range(config.getint("verifier", "max_retries")):
++ next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
++ try:
++ response = session.post(url, json=tosend, timeout=5)
++ if response.status_code in [200, 202]:
++ break
++
++ logger.debug(
++ "Unable to publish revocation message %d times via webhook, "
++ "trying again in %d seconds. "
++ "Server returned status code: %s",
++ i,
++ next_retry,
++ response.status_code,
++ )
++ except requests.exceptions.RequestException as e:
++ logger.debug(
++ "Unable to publish revocation message %d times via webhook, trying again in %d seconds: %s",
++ i,
++ next_retry,
++ e,
++ )
+
+- time.sleep(next_retry)
++ time.sleep(next_retry)
+
+ w = functools.partial(worker_webhook, tosend, url)
+ t = threading.Thread(target=w, daemon=True)
+diff --git a/packit-ci.fmf b/packit-ci.fmf
+index f4d2dae..7abe313 100644
+--- a/packit-ci.fmf
++++ b/packit-ci.fmf
+@@ -108,6 +108,7 @@ adjust:
+ - /setup/configure_tpm_emulator
+ - /setup/install_upstream_keylime
+ - /setup/install_rust_keylime_from_copr
++ - /setup/configure_kernel_ima_module/ima_policy_simple
+ - /functional/basic-attestation-on-localhost
+ - /functional/basic-attestation-with-custom-certificates
+ - /functional/basic-attestation-without-mtls
+--
+2.41.0
+
diff --git a/0008-verifier-should-read-parameters-from-verifier.conf-o.patch b/0008-verifier-should-read-parameters-from-verifier.conf-o.patch
new file mode 100644
index 0000000..efb3a2c
--- /dev/null
+++ b/0008-verifier-should-read-parameters-from-verifier.conf-o.patch
@@ -0,0 +1,31 @@
+From aa891f456d5cf0fc23e16d87fb28efc79a0d8073 Mon Sep 17 00:00:00 2001
+From: Marcio Silva <marcio.a.silva@ibm.com>
+Date: Wed, 23 Aug 2023 11:24:59 -0300
+Subject: [PATCH 8/8] verifier: should read parameters from verifier.conf only
+
+Single-line fix for #1446
+
+The verifier should read "durable attestation" backend imports from
+verifier.conf (and NOT from registrar.conf)
+
+Signed-off-by: Marcio Silva <marcio.a.silva@ibm.com>
+---
+ keylime/cloud_verifier_tornado.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/keylime/cloud_verifier_tornado.py b/keylime/cloud_verifier_tornado.py
+index d65cb63..261022a 100644
+--- a/keylime/cloud_verifier_tornado.py
++++ b/keylime/cloud_verifier_tornado.py
+@@ -51,7 +51,7 @@ except SQLAlchemyError as err:
+ sys.exit(1)
+
+ try:
+- rmc = record.get_record_mgt_class(config.get("registrar", "durable_attestation_import", fallback=""))
++ rmc = record.get_record_mgt_class(config.get("verifier", "durable_attestation_import", fallback=""))
+ if rmc:
+ rmc = rmc("verifier")
+ except record.RecordManagementException as rme:
+--
+2.41.0
+
diff --git a/0009-CVE-2023-38201.patch b/0009-CVE-2023-38201.patch
new file mode 100644
index 0000000..cd1847d
--- /dev/null
+++ b/0009-CVE-2023-38201.patch
@@ -0,0 +1,48 @@
+From 9e5ac9f25cd400b16d5969f531cee28290543f2a Mon Sep 17 00:00:00 2001
+From: Marcio Silva <marcio.a.silva@ibm.com>
+Date: Wed, 12 Jul 2023 12:05:47 -0300
+Subject: [PATCH] Fix for CVE-2023-38201 (Security Advisory
+ GHSA-f4r5-q63f-gcww)
+
+In addition to remove the offending message, this patch also ensures
+deletion of an agent's record from the database in case of failure after
+a single attempt.
+
+Signed-off-by: Marcio Silva <marcio.a.silva@ibm.com>
+---
+ keylime/registrar_common.py | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/keylime/registrar_common.py b/keylime/registrar_common.py
+index 1fd97cd0c..7f15ae430 100644
+--- a/keylime/registrar_common.py
++++ b/keylime/registrar_common.py
+@@ -250,7 +250,9 @@ def get_network_params(
+ try:
+ port = int(port)
+ if port < 1 or port > 65535:
+- logger.warning("Contact port for agent %s is not a number between 1 and got: %s.", agent_id, port)
++ logger.warning(
++ "Contact port for agent %s is not a number between 1 and 65535 got: %s.", agent_id, port
++ )
+ port = None
+ except ValueError:
+ logger.warning("Contact port for agent %s is not a valid number got: %s.", agent_id, port)
+@@ -447,7 +449,16 @@ def do_PUT(self) -> None:
+ logger.error("SQLAlchemy Error: %s", e)
+ raise
+ else:
+- raise Exception(f"Auth tag {auth_tag} does not match expected value {ex_mac}")
++ if agent_id and session.query(RegistrarMain).filter_by(agent_id=agent_id).delete():
++ try:
++ session.commit()
++ except SQLAlchemyError as e:
++ logger.error("SQLAlchemy Error: %s", e)
++ raise
++
++ raise Exception(
++ f"Auth tag {auth_tag} for agent {agent_id} does not match expected value. The agent has been deleted from database, and a restart of it will be required"
++ )
+
+ web_util.echo_json_response(self, 200, "Success")
+ logger.info("PUT activated: %s", agent_id)
diff --git a/0010-CVE-2023-38200.patch b/0010-CVE-2023-38200.patch
new file mode 100644
index 0000000..7c06151
--- /dev/null
+++ b/0010-CVE-2023-38200.patch
@@ -0,0 +1,69 @@
+From e17d5a6a47c1405a799a06754d3e905856e3035d Mon Sep 17 00:00:00 2001
+From: florian <264356+flozilla@users.noreply.github.com>
+Date: Tue, 11 Jul 2023 21:31:27 +0200
+Subject: [PATCH 10/10] CVE-2023-38200
+
+Extend Registrar SSL socket to be non-blocking
+
+Fixes: CVE-2023-38200
+
+Upstream:
+ - https://github.com/keylime/keylime/commit/c68d8f0b7
+ - https://github.com/keylime/keylime/commit/27d515f4b
+---
+ keylime/registrar_common.py | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/keylime/registrar_common.py b/keylime/registrar_common.py
+index d1d20dd..6441e3b 100644
+--- a/keylime/registrar_common.py
++++ b/keylime/registrar_common.py
+@@ -2,8 +2,10 @@ import base64
+ import http.server
+ import ipaddress
+ import os
++import select
+ import signal
+ import socket
++import ssl
+ import sys
+ import threading
+ from http.server import BaseHTTPRequestHandler, HTTPServer
+@@ -77,6 +79,25 @@ class BaseHandler(BaseHTTPRequestHandler, SessionManager):
+
+
+ class ProtectedHandler(BaseHandler):
++ def handle(self) -> None:
++ """Need to perform SSL handshake here, as
++ do_handshake_on_connect=False for non-blocking SSL socket"""
++ while True:
++ try:
++ self.request.do_handshake()
++ break
++ except ssl.SSLWantReadError:
++ select.select([self.request], [], [])
++ except ssl.SSLWantWriteError:
++ select.select([], [self.request], [])
++ except ssl.SSLError as e:
++ logger.error("SSL connection error: %s", e)
++ return
++ except Exception as e:
++ logger.error("General communication failure: %s", e)
++ return
++ BaseHTTPRequestHandler.handle(self)
++
+ def do_HEAD(self) -> None:
+ """HEAD not supported"""
+ web_util.echo_json_response(self, 405, "HEAD not supported")
+@@ -494,7 +515,7 @@ def start(host: str, tlsport: int, port: int) -> None:
+ protected_server = RegistrarServer((host, tlsport), ProtectedHandler)
+ context = web_util.init_mtls("registrar", logger=logger)
+ if context is not None:
+- protected_server.socket = context.wrap_socket(protected_server.socket, server_side=True)
++ protected_server.socket = context.wrap_socket(protected_server.socket, server_side=True, do_handshake_on_connect=False)
+ thread_protected_server = threading.Thread(target=protected_server.serve_forever)
+
+ # Set up the unprotected registrar server
+--
+2.41.0
+
diff --git a/0011-Automatically-update-agent-API-version.patch b/0011-Automatically-update-agent-API-version.patch
new file mode 100644
index 0000000..c87b309
--- /dev/null
+++ b/0011-Automatically-update-agent-API-version.patch
@@ -0,0 +1,244 @@
+From b0cf69c9db20eb319ea2e90c22f500e09b704224 Mon Sep 17 00:00:00 2001
+From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+Date: Wed, 23 Aug 2023 16:24:15 +0200
+Subject: [PATCH] Implement automatic agent API version bump
+
+Automatically update the agent supported API version in the database if
+the agent is updated and its API version is bumped.
+
+Previously, if an agent was added to a verifier while it used an old API
+version, and then it is updated with an API version bump, the
+attestation would fail as the verifier would try to reach the agent
+using the old API version.
+
+Fixes #1457
+
+Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+---
+ keylime/cloud_verifier_tornado.py | 185 +++++++++++++++++++++++++++---
+ 1 file changed, 167 insertions(+), 18 deletions(-)
+
+diff --git a/keylime/cloud_verifier_tornado.py b/keylime/cloud_verifier_tornado.py
+index 261022ac6..31e6f7159 100644
+--- a/keylime/cloud_verifier_tornado.py
++++ b/keylime/cloud_verifier_tornado.py
+@@ -32,6 +32,7 @@
+ )
+ from keylime.agentstates import AgentAttestState, AgentAttestStates
+ from keylime.common import retry, states, validators
++from keylime.common.version import str_to_version
+ from keylime.da import record
+ from keylime.db.keylime_db import DBEngineManager, SessionManager
+ from keylime.db.verifier_db import VerfierMain, VerifierAllowlist
+@@ -998,6 +999,80 @@ def data_received(self, chunk: Any) -> None:
+ raise NotImplementedError()
+
+
++async def update_agent_api_version(agent: Dict[str, Any], timeout: float = 60.0) -> Union[Dict[str, Any], None]:
++ agent_id = agent["agent_id"]
++
++ logger.info("Agent %s API version bump detected, trying to update stored API version", agent_id)
++ kwargs = {}
++ if agent["ssl_context"]:
++ kwargs["context"] = agent["ssl_context"]
++
++ res = tornado_requests.request(
++ "GET",
++ f"http://{agent['ip']}:{agent['port']}/version",
++ **kwargs,
++ timeout=timeout,
++ )
++ response = await res
++
++ if response.status_code != 200:
++ logger.warning(
++ "Could not get agent %s supported API version, Error: %s",
++ agent["agent_id"],
++ response.status_code,
++ )
++ return None
++
++ try:
++ json_response = json.loads(response.body)
++ new_version = json_response["results"]["supported_version"]
++ old_version = agent["supported_version"]
++
++ # Only update the API version to use if it is supported by the verifier
++ if new_version in keylime_api_version.all_versions():
++ new_version_tuple = str_to_version(new_version)
++ old_version_tuple = str_to_version(old_version)
++
++ assert new_version_tuple, f"Agent {agent_id} version {new_version} is invalid"
++ assert old_version_tuple, f"Agent {agent_id} version {old_version} is invalid"
++
++ # Check that the new version is greater than current version
++ if new_version_tuple <= old_version_tuple:
++ logger.warning(
++ "Agent %s API version %s is lower or equal to previous version %s",
++ agent_id,
++ new_version,
++ old_version,
++ )
++ return None
++
++ logger.info("Agent %s new API version %s is supported", agent_id, new_version)
++ session = get_session()
++ agent["supported_version"] = new_version
++
++ # Remove keys that should not go to the DB
++ agent_db = dict(agent)
++ for key in exclude_db:
++ if key in agent_db:
++ del agent_db[key]
++
++ session.query(VerfierMain).filter_by(agent_id=agent_id).update(agent_db) # pyright: ignore
++ session.commit()
++ else:
++ logger.warning("Agent %s new API version %s is not supported", agent_id, new_version)
++ return None
++
++ except SQLAlchemyError as e:
++ logger.error("SQLAlchemy Error updating API version for agent %s: %s", agent_id, e)
++ return None
++ except Exception as e:
++ logger.exception(e)
++ return None
++
++ logger.info("Agent %s API version updated to %s", agent["agent_id"], agent["supported_version"])
++ return agent
++
++
+ async def invoke_get_quote(
+ agent: Dict[str, Any], runtime_policy: str, need_pubkey: bool, timeout: float = 60.0
+ ) -> None:
+@@ -1028,15 +1103,43 @@ async def invoke_get_quote(
+ # this is a connection error, retry get quote
+ if response.status_code in [408, 500, 599]:
+ asyncio.ensure_future(process_agent(agent, states.GET_QUOTE_RETRY))
+- else:
+- # catastrophic error, do not continue
+- logger.critical(
+- "Unexpected Get Quote response error for cloud agent %s, Error: %s",
+- agent["agent_id"],
+- response.status_code,
+- )
+- failure.add_event("no_quote", "Unexpected Get Quote reponse from agent", False)
+- asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
++ return
++
++ if response.status_code == 400:
++ try:
++ json_response = json.loads(response.body)
++ if "API version not supported" in json_response["status"]:
++ update = update_agent_api_version(agent)
++ updated = await update
++
++ if updated:
++ asyncio.ensure_future(process_agent(updated, states.GET_QUOTE_RETRY))
++ else:
++ logger.warning("Could not update stored agent %s API version", agent["agent_id"])
++ failure.add_event(
++ "version_not_supported",
++ {"context": "Agent API version not supported", "data": json_response},
++ False,
++ )
++ asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
++ return
++
++ except Exception as e:
++ logger.exception(e)
++ failure.add_event(
++ "exception", {"context": "Agent caused the verifier to throw an exception", "data": str(e)}, False
++ )
++ asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
++ return
++
++ # catastrophic error, do not continue
++ logger.critical(
++ "Unexpected Get Quote response error for cloud agent %s, Error: %s",
++ agent["agent_id"],
++ response.status_code,
++ )
++ failure.add_event("no_quote", "Unexpected Get Quote reponse from agent", False)
++ asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
+ else:
+ try:
+ json_response = json.loads(response.body)
+@@ -1100,15 +1203,43 @@ async def invoke_provide_v(agent: Dict[str, Any], timeout: float = 60.0) -> None
+ if response.status_code != 200:
+ if response.status_code in [408, 500, 599]:
+ asyncio.ensure_future(process_agent(agent, states.PROVIDE_V_RETRY))
+- else:
+- # catastrophic error, do not continue
+- logger.critical(
+- "Unexpected Provide V response error for cloud agent %s, Error: %s",
+- agent["agent_id"],
+- response.status_code,
+- )
+- failure.add_event("no_v", {"message": "Unexpected provide V response", "data": response.status_code}, False)
+- asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
++ return
++
++ if response.status_code == 400:
++ try:
++ json_response = json.loads(response.body)
++ if "API version not supported" in json_response["status"]:
++ update = update_agent_api_version(agent)
++ updated = await update
++
++ if updated:
++ asyncio.ensure_future(process_agent(updated, states.PROVIDE_V_RETRY))
++ else:
++ logger.warning("Could not update stored agent %s API version", agent["agent_id"])
++ failure.add_event(
++ "version_not_supported",
++ {"context": "Agent API version not supported", "data": json_response},
++ False,
++ )
++ asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
++ return
++
++ except Exception as e:
++ logger.exception(e)
++ failure.add_event(
++ "exception", {"context": "Agent caused the verifier to throw an exception", "data": str(e)}, False
++ )
++ asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
++ return
++
++ # catastrophic error, do not continue
++ logger.critical(
++ "Unexpected Provide V response error for cloud agent %s, Error: %s",
++ agent["agent_id"],
++ response.status_code,
++ )
++ failure.add_event("no_v", {"message": "Unexpected provide V response", "data": response.status_code}, False)
++ asyncio.ensure_future(process_agent(agent, states.FAILED, failure))
+ else:
+ asyncio.ensure_future(process_agent(agent, states.GET_QUOTE))
+
+@@ -1134,6 +1265,24 @@ async def invoke_notify_error(agent: Dict[str, Any], tosend: Dict[str, Any], tim
+ agent["agent_id"],
+ )
+ elif response.status_code != 200:
++ if response.status_code == 400:
++ try:
++ json_response = json.loads(response.body)
++ if "API version not supported" in json_response["status"]:
++ update = update_agent_api_version(agent)
++ updated = await update
++
++ if updated:
++ asyncio.ensure_future(invoke_notify_error(updated, tosend))
++ else:
++ logger.warning("Could not update stored agent %s API version", agent["agent_id"])
++
++ return
++
++ except Exception as e:
++ logger.exception(e)
++ return
++
+ logger.warning(
+ "Unexpected Notify Revocation response error for cloud agent %s, Error: %s",
+ agent["agent_id"],
diff --git a/keylime.spec b/keylime.spec
new file mode 100644
index 0000000..f106cb3
--- /dev/null
+++ b/keylime.spec
@@ -0,0 +1,464 @@
+%global srcname keylime
+%global policy_version 1.2.0
+%global with_selinux 1
+%global selinuxtype targeted
+
+# Package is actually noarch, but it has an optional dependency that is
+# arch-specific.
+%global debug_package %{nil}
+
+Name: keylime
+Version: 7.3.0
+Release: 9%{?dist}
+Summary: Open source TPM software for Bootstrapping and Maintaining Trust
+
+URL: https://github.com/keylime/keylime
+Source0: https://github.com/keylime/keylime/archive/refs/tags/v%{version}.tar.gz
+Source1: %{srcname}.sysusers
+Source2: https://github.com/RedHat-SP-Security/%{name}-selinux/archive/v%{policy_version}/keylime-selinux-%{policy_version}.tar.gz
+
+Patch: 0001-Remove-usage-of-Required-NotRequired-typing_ext.patch
+Patch: 0002-Allow-keylime_server_t-tcp-connect-to-several-domain.patch
+Patch: 0003-Use-version-2.0-as-the-minimum-for-the-configuration.patch
+Patch: 0004-Duplicate-str_to_version-for-the-upgrade-tool.patch
+Patch: 0005-elchecking-example-add-ignores-for-EV_PLATFORM_CONFI.patch
+Patch: 0006-Revert-mapping-changes.patch
+Patch: 0007-Handle-session-close-using-a-session-manager.patch
+Patch: 0008-verifier-should-read-parameters-from-verifier.conf-o.patch
+Patch: 0009-CVE-2023-38201.patch
+Patch: 0010-CVE-2023-38200.patch
+Patch: 0011-Automatically-update-agent-API-version.patch
+
+License: ASL 2.0 and MIT
+
+BuildRequires: git-core
+BuildRequires: swig
+BuildRequires: openssl-devel
+BuildRequires: python3-devel
+BuildRequires: python3-dbus
+BuildRequires: python3-jinja2
+BuildRequires: python3-setuptools
+BuildRequires: systemd-rpm-macros
+BuildRequires: tpm2-abrmd-selinux
+
+Requires: python3-%{srcname} = %{version}-%{release}
+Requires: %{srcname}-base = %{version}-%{release}
+Requires: %{srcname}-verifier = %{version}-%{release}
+Requires: %{srcname}-registrar = %{version}-%{release}
+Requires: %{srcname}-tenant = %{version}-%{release}
+
+# Agent.
+Requires: keylime-agent
+Suggests: keylime-agent-rust
+
+%{?python_enable_dependency_generator}
+%description
+Keylime is a TPM based highly scalable remote boot attestation
+and runtime integrity measurement solution.
+
+%package base
+Summary: The base package contains the default configuration
+License: MIT
+
+
+Requires(pre): python3-jinja2
+Requires(pre): shadow-utils
+Requires(pre): util-linux
+Requires: procps-ng
+Requires: tpm2-tss
+
+%if 0%{?with_selinux}
+# This ensures that the *-selinux package and all it’s dependencies are not pulled
+# into containers and other systems that do not use SELinux
+Recommends: (%{srcname}-selinux if selinux-policy-%{selinuxtype})
+%endif
+
+%ifarch %efi
+Requires: efivar-libs
+%endif
+
+
+%description base
+The base package contains the Keylime default configuration
+
+%package -n python3-%{srcname}
+Summary: The Python Keylime module
+License: MIT
+
+Requires: %{srcname}-base = %{version}-%{release}
+%{?python_provide:%python_provide python3-%{srcname}}
+
+Requires: python3-tornado
+Requires: python3-sqlalchemy
+Requires: python3-alembic
+Requires: python3-cryptography
+Requires: python3-pyyaml
+Requires: python3-packaging
+Requires: python3-requests
+Requires: python3-gpg
+Requires: python3-lark-parser
+Requires: python3-pyasn1
+Requires: python3-pyasn1-modules
+Requires: python3-jsonschema
+Requires: tpm2-tools
+Requires: openssl
+
+%description -n python3-%{srcname}
+The python3-keylime module implements the functionality used
+by Keylime components.
+
+%package verifier
+Summary: The Python Keylime Verifier component
+License: MIT
+
+Requires: %{srcname}-base = %{version}-%{release}
+Requires: python3-%{srcname} = %{version}-%{release}
+
+%description verifier
+The Keylime Verifier continuously verifies the integrity state
+of the machine that the agent is running on.
+
+%package registrar
+Summary: The Keylime Registrar component
+License: MIT
+
+Requires: %{srcname}-base = %{version}-%{release}
+Requires: python3-%{srcname} = %{version}-%{release}
+
+%description registrar
+The Keylime Registrar is a database of all agents registered
+with Keylime and hosts the public keys of the TPM vendors.
+
+%if 0%{?with_selinux}
+# SELinux subpackage
+%package selinux
+Summary: keylime SELinux policy
+BuildArch: noarch
+Requires: selinux-policy-%{selinuxtype}
+Requires(post): selinux-policy-%{selinuxtype}
+BuildRequires: selinux-policy-devel
+%{?selinux_requires}
+
+%description selinux
+Custom SELinux policy module
+%endif
+
+%package tenant
+Summary: The Python Keylime Tenant
+License: MIT
+
+Requires: %{srcname}-base = %{version}-%{release}
+Requires: python3-%{srcname} = %{version}-%{release}
+
+
+%description tenant
+The Keylime Tenant can be used to provision a Keylime Agent.
+
+%prep
+%autosetup -S git -n %{srcname}-%{version} -a2
+
+%if 0%{?with_selinux}
+# SELinux policy (originally from selinux-policy-contrib)
+# this policy module will override the production module
+mkdir selinux
+
+make -f %{_datadir}/selinux/devel/Makefile %{srcname}.pp
+bzip2 -9 %{srcname}.pp
+%endif
+
+%build
+%py3_build
+
+%install
+%py3_install
+mkdir -p %{buildroot}/%{_sharedstatedir}/%{srcname}
+mkdir -p --mode=0700 %{buildroot}/%{_rundir}/%{srcname}
+mkdir -p --mode=0700 %{buildroot}/%{_localstatedir}/log/%{srcname}
+
+mkdir -p --mode=0700 %{buildroot}/%{_sysconfdir}/%{srcname}/
+for comp in "verifier" "tenant" "registrar" "ca" "logging"; do
+ mkdir -p --mode=0700 %{buildroot}/%{_sysconfdir}/%{srcname}/${comp}.conf.d
+ install -Dpm 400 config/${comp}.conf %{buildroot}/%{_sysconfdir}/%{srcname}
+done
+
+# Ship some scripts.
+mkdir -p %{buildroot}/%{_datadir}/%{srcname}/scripts
+for s in create_runtime_policy.sh \
+ create_mb_refstate \
+ ek-openssl-verify; do
+ install -Dpm 755 scripts/${s} \
+ %{buildroot}/%{_datadir}/%{srcname}/scripts/${s}
+done
+
+# Ship configuration templates.
+cp -r ./templates %{buildroot}%{_datadir}/%{srcname}/templates/
+
+mkdir -p --mode=0755 %{buildroot}/%{_bindir}
+install -Dpm 755 ./keylime/cmd/convert_config.py %{buildroot}/%{_bindir}/keylime_upgrade_config
+
+%if 0%{?with_selinux}
+install -D -m 0644 %{srcname}.pp.bz2 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{srcname}.pp.bz2
+install -D -p -m 0644 keylime-selinux-%{policy_version}/%{srcname}.if %{buildroot}%{_datadir}/selinux/devel/include/distributed/%{srcname}.if
+%endif
+
+install -Dpm 644 ./services/%{srcname}_verifier.service \
+ %{buildroot}%{_unitdir}/%{srcname}_verifier.service
+
+install -Dpm 644 ./services/%{srcname}_registrar.service \
+ %{buildroot}%{_unitdir}/%{srcname}_registrar.service
+
+cp -r ./tpm_cert_store %{buildroot}%{_sharedstatedir}/%{srcname}/
+chmod 400 %{buildroot}%{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem
+
+install -p -d %{buildroot}/%{_tmpfilesdir}
+cat > %{buildroot}/%{_tmpfilesdir}/%{srcname}.conf << EOF
+d %{_rundir}/%{srcname} 0700 %{srcname} %{srcname} -
+EOF
+
+install -p -D -m 0644 %{SOURCE1} %{buildroot}%{_sysusersdir}/%{srcname}.conf
+
+%pre base
+%sysusers_create_compat %{SOURCE1}
+exit 0
+
+%post base
+/usr/bin/keylime_upgrade_config --component ca --component logging >/dev/null
+exit 0
+
+%posttrans base
+if [ -d %{_sysconfdir}/%{srcname} ]; then
+ chmod 500 %{_sysconfdir}/%{srcname}
+ chown -R %{srcname}:%{srcname} %{_sysconfdir}/%{srcname}
+
+ for comp in "verifier" "tenant" "registrar" "ca" "logging"; do
+ [ -d %{_sysconfdir}/%{srcname}/${comp}.conf.d ] && \
+ chmod 500 %{_sysconfdir}/%{srcname}/${comp}.conf.d
+ done
+fi
+
+[ -d %{_sharedstatedir}/%{srcname} ] && \
+ chown -R %{srcname} %{_sharedstatedir}/%{srcname}/
+
+[ -d %{_sharedstatedir}/%{srcname}/tpm_cert_store ] && \
+ chmod 400 %{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem && \
+ chmod 500 %{_sharedstatedir}/%{srcname}/tpm_cert_store/
+
+[ -d %{_localstatedir}/log/%{srcname} ] && \
+ chown -R %{srcname} %{_localstatedir}/log/%{srcname}/
+exit 0
+
+%post verifier
+/usr/bin/keylime_upgrade_config --component verifier >/dev/null
+%systemd_post %{srcname}_verifier.service
+exit 0
+
+%post registrar
+/usr/bin/keylime_upgrade_config --component registrar >/dev/null
+%systemd_post %{srcname}_registrar.service
+exit 0
+
+%post tenant
+/usr/bin/keylime_upgrade_config --component tenant >/dev/null
+exit 0
+
+%preun verifier
+%systemd_preun %{srcname}_verifier.service
+
+%preun registrar
+%systemd_preun %{srcname}_registrar.service
+
+%postun verifier
+%systemd_postun_with_restart %{srcname}_verifier.service
+
+%postun registrar
+%systemd_postun_with_restart %{srcname}_registrar.service
+
+%if 0%{?with_selinux}
+# SELinux contexts are saved so that only affected files can be
+# relabeled after the policy module installation
+%pre selinux
+%selinux_relabel_pre -s %{selinuxtype}
+
+%post selinux
+%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{srcname}.pp.bz2
+%selinux_relabel_post -s %{selinuxtype}
+
+if [ "$1" -le "1" ]; then # First install
+ # The services need to be restarted for the custom label to be
+ # applied in case they where already present in the system,
+ # restart fails silently in case they where not.
+ for svc in agent registrar verifier; do
+ [ -f "%{_unitdir}/%{srcname}_${svc}".service ] && \
+ %systemd_postun_with_restart "%{srcname}_${svc}".service
+ done
+fi
+exit 0
+
+%postun selinux
+if [ $1 -eq 0 ]; then
+ %selinux_modules_uninstall -s %{selinuxtype} %{srcname}
+ %selinux_relabel_post -s %{selinuxtype}
+fi
+%endif
+
+%files verifier
+%license LICENSE
+%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/verifier.conf.d
+%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/verifier.conf
+%{_bindir}/%{srcname}_verifier
+%{_bindir}/%{srcname}_ca
+%{_unitdir}/keylime_verifier.service
+
+%files registrar
+%license LICENSE
+%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/registrar.conf.d
+%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/registrar.conf
+%{_bindir}/%{srcname}_registrar
+%{_unitdir}/keylime_registrar.service
+
+%if 0%{?with_selinux}
+%files selinux
+%{_datadir}/selinux/packages/%{selinuxtype}/%{srcname}.pp.*
+%{_datadir}/selinux/devel/include/distributed/%{srcname}.if
+%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{srcname}
+%endif
+
+%files tenant
+%license LICENSE
+%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/tenant.conf.d
+%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/tenant.conf
+%{_bindir}/%{srcname}_tenant
+
+%files -n python3-%{srcname}
+%license LICENSE
+%{python3_sitelib}/%{srcname}-*.egg-info/
+%{python3_sitelib}/%{srcname}
+%{_datadir}/%{srcname}/scripts/create_mb_refstate
+%{_bindir}/keylime_attest
+%{_bindir}/keylime_convert_runtime_policy
+%{_bindir}/keylime_create_policy
+%{_bindir}/keylime_sign_runtime_policy
+%{_bindir}/keylime_userdata_encrypt
+
+%files base
+%license LICENSE
+%doc README.md
+%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/{ca,logging}.conf.d
+%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/ca.conf
+%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/logging.conf
+%attr(700,%{srcname},%{srcname}) %dir %{_rundir}/%{srcname}
+%attr(700,%{srcname},%{srcname}) %dir %{_localstatedir}/log/%{srcname}
+%attr(700,%{srcname},%{srcname}) %dir %{_sharedstatedir}/%{srcname}
+%attr(500,%{srcname},%{srcname}) %dir %{_sharedstatedir}/%{srcname}/tpm_cert_store
+%attr(400,%{srcname},%{srcname}) %{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem
+%{_tmpfilesdir}/%{srcname}.conf
+%{_sysusersdir}/%{srcname}.conf
+%{_datadir}/%{srcname}/scripts/create_runtime_policy.sh
+%{_datadir}/%{srcname}/scripts/ek-openssl-verify
+%{_datadir}/%{srcname}/templates
+%{_bindir}/keylime_upgrade_config
+
+%files
+%license LICENSE
+
+%changelog
+* Wed Sep 06 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-9
+- Rebuild for properly tagging the resulting build
+ Resolves: RHEL-1898
+
+* Fri Sep 01 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-8
+- Add missing dependencies python3-jinja2 and util-linux
+ Resolves: RHEL-1898
+
+* Mon Aug 28 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-7
+- Automatically update agent API version
+ Resolves: RHEL-1518
+
+* Mon Aug 28 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-6
+- Fix registrar is subject to a DoS against SSL (CVE-2023-38200)
+ Resolves: rhbz#2222694
+
+* Fri Aug 25 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-5
+- Fix challenge-protocol bypass during agent registration (CVE-2023-38201)
+ Resolves: rhbz#2222695
+
+* Tue Aug 22 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-4
+- Update spec file to use %verify(not md5 size mode mtime) for files updated in %post scriptlets
+ Resolves: RHEL-475
+
+* Tue Aug 15 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-3
+- Fix Keylime configuration upgrades issues introduced in last rebase
+ Resolves: RHEL-475
+- Handle session close using a session manager
+ Resolves: RHEL-1252
+- Add ignores for EV_PLATFORM_CONFIG_FLAGS
+ Resolves: RHEL-947
+
+* Tue Aug 8 2023 Patrik Koncity <pkoncity@redhat.com> - 7.3.0-2
+- Keylime SELinux policy provides more restricted ports.
+- New SELinux label for ports used by keylime.
+- Adding tabrmd interfaces allow unix stream socket communication and dbus communication.
+- Allow the keylime_server_t domain to get the attributes of all filesystems.
+ Resolves: RHEL-595
+ Resolves: RHEL-390
+ Resolves: RHEL-948
+
+* Wed Jul 19 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-1
+- Update to 7.3.0
+ Resolves: RHEL-475
+
+* Fri Jan 13 2023 Sergio Correia <scorreia@redhat.com> - 6.5.2-4
+- Backport upstream PR#1240 - logging: remove option to log into separate file
+ Resolves: rhbz#2154584 - keylime verifier is not logging to /var/log/keylime
+
+* Thu Dec 1 2022 Sergio Correia <scorreia@redhat.com> - 6.5.2-3
+- Remove leftover policy file
+ Related: rhbz#2152135
+
+* Thu Dec 1 2022 Patrik Koncity <pkoncity@redhat.com> - 6.5.2-2
+- Use keylime selinux policy from upstream.
+ Resolves: rhbz#2152135
+
+* Mon Nov 14 2022 Sergio Correia <scorreia@redhat.com> - 6.5.2-1
+- Update to 6.5.2
+ Resolves: CVE-2022-3500
+ Resolves: rhbz#2138167 - agent fails IMA attestation when one scripts is executed quickly after the other
+ Resolves: rhbz#2140670 - Segmentation fault in /usr/share/keylime/create_mb_refstate script
+ Resolves: rhbz#142009 - Registrar may crash during EK validation when require_ek_cert is enabled
+
+* Tue Sep 13 2022 Sergio Correia <scorreia@redhat.com> - 6.5.0-1
+- Update to 6.5.0
+ Resolves: rhbz#2120686 - Keylime configuration is too complex
+
+* Fri Aug 26 2022 Sergio Correia <scorreia@redhat.com> - 6.4.3-1
+- Update to 6.4.3
+ Resolves: rhbz#2121044 - Error parsing EK ASN.1 certificate of Nuvoton HW TPM
+
+* Fri Aug 26 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-6
+- Update keylime SELinux policy
+- Resolves: rhbz#2121058
+
+* Fri Aug 26 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-5
+- Update keylime SELinux policy and removed duplicate rules
+- Resolves: rhbz#2121058
+
+* Fri Aug 26 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-4
+- Update keylime SELinux policy
+- Resolves: rhbz#2121058
+
+* Wed Aug 17 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-3
+- Add keylime-selinux policy as subpackage
+- See https://fedoraproject.org/wiki/SELinux/IndependentPolicy
+- Resolves: rhbz#2121058
+
+* Mon Jul 11 2022 Sergio Correia <scorreia@redhat.com> - 6.4.2-2
+- Fix efivar-libs dependency
+ Related: rhbz#2082989
+
+* Thu Jul 07 2022 Sergio Correia <scorreia@redhat.com> - 6.4.2-1
+- Update to 6.4.2
+ Related: rhbz#2082989
+
+* Tue Jun 21 2022 Sergio Correia <scorreia@redhat.com> - 6.4.1-1
+- Add keylime to RHEL-9
+ Resolves: rhbz#2082989
diff --git a/keylime.sysusers b/keylime.sysusers
new file mode 100644
index 0000000..4979d46
--- /dev/null
+++ b/keylime.sysusers
@@ -0,0 +1,2 @@
+u keylime - "Keylime unprivileged user" /var/lib/keylime /usr/sbin/nologin
+m keylime tss
diff --git a/sources b/sources
new file mode 100644
index 0000000..d2f0188
--- /dev/null
+++ b/sources
@@ -0,0 +1,2 @@
+97676e6eae08a1e3be7b83fc6e7c61f1 keylime-selinux-1.2.0.tar.gz
+fb1e9a6d90674c1d21dd68a6974db3ed v7.3.0.tar.gz