import CS keylime-7.3.0-12.el9_3

This commit is contained in:
eabdullin 2023-11-07 13:14:19 +00:00
parent 39cf484682
commit 779adab425
19 changed files with 1068 additions and 367 deletions

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/keylime-selinux-1.0.0.tar.gz
SOURCES/v6.5.2.tar.gz
SOURCES/keylime-selinux-1.2.0.tar.gz
SOURCES/v7.3.0.tar.gz

View File

@ -1,2 +1,2 @@
a1154fc19d2ae6f52b6b77a39e62d2420c0f4c5e SOURCES/keylime-selinux-1.0.0.tar.gz
1c311bc1d3ab6c8050fd819410c593392187c2fa SOURCES/v6.5.2.tar.gz
9130beade415b8e3b02aac8d06678f2c45b939fe SOURCES/keylime-selinux-1.2.0.tar.gz
400e2b019060b8a6cc255dbfc14c582121acbee1 SOURCES/v7.3.0.tar.gz

View File

@ -1,130 +0,0 @@
From d6dd71e3a3fe8e822fbcaa0d88f19a0c3332cacd Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Tue, 15 Nov 2022 07:09:13 -0300
Subject: [PATCH] Do not use default values that need reading the config in
methods
Following up from the recent refactoring that moved the EK validation
to cert_utils, in a few places were added default method values that
were reading the configuration files directly.
It was not such a great idea becasue it then made those config files as
required to even import the modules.
Example "from keylime import cert_utils" now also requires that the
tenant configuration be available for getting the path for the TPM
cert store.
Let's stop doing that.
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
keylime/cert_utils.py | 5 +++--
keylime/tenant.py | 2 +-
keylime/tpm/tpm_abstract.py | 2 +-
keylime/tpm/tpm_main.py | 4 ++--
keylime/tpm_ek_ca.py | 6 +++---
5 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/keylime/cert_utils.py b/keylime/cert_utils.py
index d2fc54d..3576c64 100644
--- a/keylime/cert_utils.py
+++ b/keylime/cert_utils.py
@@ -12,7 +12,7 @@ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
from pyasn1.codec.der import decoder, encoder
from pyasn1_modules import pem, rfc2459
-from keylime import config, keylime_logging, tpm_ek_ca
+from keylime import keylime_logging, tpm_ek_ca
# Issue #944 -- python-cryptography won't parse malformed certs,
# such as some Nuvoton ones we have encountered in the field.
@@ -56,9 +56,10 @@ def x509_pem_cert(pem_cert_data: str):
return x509.load_der_x509_certificate(data=encoder.encode(pyasn1_cert), backend=default_backend())
-def verify_ek(ekcert, tpm_cert_store=config.get("tenant", "tpm_cert_store")):
+def verify_ek(ekcert: bytes, tpm_cert_store: str) -> bool:
"""Verify that the provided EK certificate is signed by a trusted root
:param ekcert: The Endorsement Key certificate in DER format
+ :param tpm_cert_store: The path for the TPM certificate store
:returns: True if the certificate can be verified, False otherwise
"""
try:
diff --git a/keylime/tenant.py b/keylime/tenant.py
index b574d04..076b849 100644
--- a/keylime/tenant.py
+++ b/keylime/tenant.py
@@ -430,7 +430,7 @@ class Tenant:
elif ekcert is None:
logger.warning("No EK cert provided, require_ek_cert option in config set to True")
return False
- elif not self.tpm_instance.verify_ek(base64.b64decode(ekcert)):
+ elif not self.tpm_instance.verify_ek(base64.b64decode(ekcert), config.get("tenant", "tpm_cert_store")):
logger.warning("Invalid EK certificate")
return False
diff --git a/keylime/tpm/tpm_abstract.py b/keylime/tpm/tpm_abstract.py
index ff41837..df6222c 100644
--- a/keylime/tpm/tpm_abstract.py
+++ b/keylime/tpm/tpm_abstract.py
@@ -97,7 +97,7 @@ class AbstractTPM(metaclass=ABCMeta):
pass
@abstractmethod
- def verify_ek(self, ekcert):
+ def verify_ek(self, ekcert, tpm_cert_store):
pass
@abstractmethod
diff --git a/keylime/tpm/tpm_main.py b/keylime/tpm/tpm_main.py
index e1d1cf8..e244dfa 100644
--- a/keylime/tpm/tpm_main.py
+++ b/keylime/tpm/tpm_main.py
@@ -776,12 +776,12 @@ class tpm(tpm_abstract.AbstractTPM):
os.remove(sesspath)
return key
- def verify_ek(self, ekcert):
+ def verify_ek(self, ekcert, tpm_cert_store):
"""Verify that the provided EK certificate is signed by a trusted root
:param ekcert: The Endorsement Key certificate in DER format
:returns: True if the certificate can be verified, false otherwise
"""
- return cert_utils.verify_ek(ekcert)
+ return cert_utils.verify_ek(ekcert, tpm_cert_store)
def get_tpm_manufacturer(self, output=None):
vendorStr = None
diff --git a/keylime/tpm_ek_ca.py b/keylime/tpm_ek_ca.py
index fb66c07..bc84571 100644
--- a/keylime/tpm_ek_ca.py
+++ b/keylime/tpm_ek_ca.py
@@ -1,13 +1,13 @@
import glob
import os
-from keylime import config, keylime_logging
+from keylime import keylime_logging
logger = keylime_logging.init_logging("tpm_ek_ca")
trusted_certs = {}
-def check_tpm_cert_store(tpm_cert_store=config.get("tenant", "tpm_cert_store")):
+def check_tpm_cert_store(tpm_cert_store):
if not os.path.isdir(tpm_cert_store):
logger.error("The directory %s does not exist.", tpm_cert_store)
raise Exception(f"The directory {tpm_cert_store} does not exist.")
@@ -20,7 +20,7 @@ def check_tpm_cert_store(tpm_cert_store=config.get("tenant", "tpm_cert_store")):
raise Exception(f"The directory {tpm_cert_store} does not contain " f"any .pem files")
-def cert_loader(tpm_cert_store=config.get("tenant", "tpm_cert_store")):
+def cert_loader(tpm_cert_store):
file_list = glob.glob(os.path.join(tpm_cert_store, "*.pem"))
my_trusted_certs = {}
for file_path in file_list:
--
2.38.1

View File

@ -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

View File

@ -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

View File

@ -1,67 +0,0 @@
From 1f9ee7437f5b712a892c6d13ac8d75e128c1a16f Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.ibm.com>
Date: Tue, 22 Nov 2022 10:56:43 -0500
Subject: [PATCH] tests: Switch to sha256 hashes for signatures
Resolves: https://github.com/keylime/keylime/issues/1202
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
test/test_ima_ast.py | 4 ++--
test/test_ima_verification.py | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/test/test_ima_ast.py b/test/test_ima_ast.py
index cd54f95f9..e7d3841a7 100644
--- a/test/test_ima_ast.py
+++ b/test/test_ima_ast.py
@@ -14,11 +14,11 @@
VALID_ENTRIES = {
"ima-sig-rsa": (
ast.ImaSig,
- "10 50873c47693cf9458e87eb4a02dd4f594f7a0c0f ima-sig sha1:1350320e5f7f51553bac8aa403489a1b135bc101 /usr/bin/dd 030202f3452d23010084c2a6cf7de1aeefa119220df0da265a7c44d34380f0d97002e7c778d09cfcf88c018e6595df3ee70eda926851f159332f852e7981a8fca1bc5e959958d06d234a0896861f13cc60da825905c8ed234df26c1deecfa816d5aa9bfb11b905e2814084a86b588be60423afada8dd0dd5a143774c6d890b64195ac42fb47ef5a9a00f0d6c80711d8e0c2b843ec38c02f60fd46bc46c7b4c329ad2dbb1b7625293703f9c739dc4c2bf0769126a2f3cb2cd031d1881cd0af64bf20fd474a993b48620f103a5c14999a2f17d60721bcc019a896b4138a688a59f50cb6cd94a4cfe3b8052e82dec025fef4feabb08c7ce412e3de850f903797e293ec27c329f57fd84e0",
+ "10 1e70a3e1af66f42826ad63b761b4cb9c4df195e1 ima-sig sha256:d33d5d13792292e202dbf69a6f1b07bc8a02f01424db8489ba7bb7d43c0290ef /usr/bin/dd 030204f3452d2301009dd340c852f37e35748363586939d4199b6684be27e7c1236ca1528f708372ed9cd52a0d991f66448790f5616ed5bd7f9bbd22193b1e3e54f6bf29a1497945a34d1b418b24f4cbeaef897bf3cebca27065ebb8761b46bc2662fe76f141245b9186a5ac8493c7f4976cf0d6dfc085c3e503e3f771bc3ccb121230db76fd8aba4f45f060ad64ab3afd99b4e52824b9eba12e93e46f9dcb2fa01d9cef89f298a0da02a82a4fb56924afd3e3c277a1302d99f770d488449df2d43eb5b174a0a528827e6877b965c2f0b7c89cf1aa26a7417a892df4c2294e2872d62748b72ea04ecb0689b5d792e615a9bf9d56f6e0f298560bf9441df0a22729c5f23389f028c25f",
),
"ima-sig-ec": (
ast.ImaSig,
- "10 06e804489a77ddab51b9ef27e17053c0e5d503bd ima-sig sha1:1cb84b12db45d7da8de58ba6744187db84082f0e /usr/bin/zmore 030202531f402500483046022100bff9c02dc7b270c83cc94bfec10eecd42831de2cdcb04f024369a14623bc3a91022100cc4d015ae932fb98d6846645ed7d1bb1afd4621ec9089bc087126f191886dd31",
+ "10 5d4d5141ccd5066d50dc3f21d79ba02fedc24256 ima-sig sha256:b8ae0b8dd04a5935cd8165aa2260cd11b658bd71629bdb52256a675a1f73907b /usr/bin/zmore 030204531f402500483046022100fe24678d21083ead47660e1a2d553a592d777c478d1b0466de6ed484b54956b3022100cad3adb37f277bbb03544d6107751b4cd4f2289d8353fa36257400a99334d5c3",
),
"ima-sig-missing": (
ast.ImaSig,
diff --git a/test/test_ima_verification.py b/test/test_ima_verification.py
index bdb929c9c..d2fc9ef16 100644
--- a/test/test_ima_verification.py
+++ b/test/test_ima_verification.py
@@ -27,8 +27,8 @@
"/lib/modules/5.4.48-openpower1/kernel/drivers/gpu/drm/drm_panel_orientation_quirks.ko": [
"cd026b58efdf66658685430ff526490d54a430a3f0066a35ac26a8acab66c55d"
],
- "/usr/bin/dd": ["1350320e5f7f51553bac8aa403489a1b135bc101"],
- "/usr/bin/zmore": ["1cb84b12db45d7da8de58ba6744187db84082f0e"],
+ "/usr/bin/dd": ["d33d5d13792292e202dbf69a6f1b07bc8a02f01424db8489ba7bb7d43c0290ef"],
+ "/usr/bin/zmore": ["b8ae0b8dd04a5935cd8165aa2260cd11b658bd71629bdb52256a675a1f73907b"],
"/usr/bin/zless": ["233ad3a8e77c63a7d9a56063ec2cad1eafa58850"],
},
"keyrings": {
@@ -50,8 +50,8 @@
"version": 1,
},
"hashes": {
- "/usr/bin/dd": ["1350320e5f7f51553bac8aa403489a1b135bc102"],
- "/usr/bin/zmore": ["1cb84b12db45d7da8de58ba6744187db84082f01"],
+ "/usr/bin/dd": ["bad05d13792292e202dbf69a6f1b07bc8a02f01424db8489ba7bb7d43c0290ef"],
+ "/usr/bin/zmore": ["bad00b8dd04a5935cd8165aa2260cd11b658bd71629bdb52256a675a1f73907b"],
},
}
@@ -73,8 +73,8 @@
# 1st signature: RSA
# 2nd signature: EC
SIGNATURES = (
- "10 50873c47693cf9458e87eb4a02dd4f594f7a0c0f ima-sig sha1:1350320e5f7f51553bac8aa403489a1b135bc101 /usr/bin/dd 030202f3452d23010084c2a6cf7de1aeefa119220df0da265a7c44d34380f0d97002e7c778d09cfcf88c018e6595df3ee70eda926851f159332f852e7981a8fca1bc5e959958d06d234a0896861f13cc60da825905c8ed234df26c1deecfa816d5aa9bfb11b905e2814084a86b588be60423afada8dd0dd5a143774c6d890b64195ac42fb47ef5a9a00f0d6c80711d8e0c2b843ec38c02f60fd46bc46c7b4c329ad2dbb1b7625293703f9c739dc4c2bf0769126a2f3cb2cd031d1881cd0af64bf20fd474a993b48620f103a5c14999a2f17d60721bcc019a896b4138a688a59f50cb6cd94a4cfe3b8052e82dec025fef4feabb08c7ce412e3de850f903797e293ec27c329f57fd84e0\n"
- "10 06e804489a77ddab51b9ef27e17053c0e5d503bd ima-sig sha1:1cb84b12db45d7da8de58ba6744187db84082f0e /usr/bin/zmore 030202531f402500483046022100bff9c02dc7b270c83cc94bfec10eecd42831de2cdcb04f024369a14623bc3a91022100cc4d015ae932fb98d6846645ed7d1bb1afd4621ec9089bc087126f191886dd31\n"
+ "10 1e70a3e1af66f42826ad63b761b4cb9c4df195e1 ima-sig sha256:d33d5d13792292e202dbf69a6f1b07bc8a02f01424db8489ba7bb7d43c0290ef /usr/bin/dd 030204f3452d2301009dd340c852f37e35748363586939d4199b6684be27e7c1236ca1528f708372ed9cd52a0d991f66448790f5616ed5bd7f9bbd22193b1e3e54f6bf29a1497945a34d1b418b24f4cbeaef897bf3cebca27065ebb8761b46bc2662fe76f141245b9186a5ac8493c7f4976cf0d6dfc085c3e503e3f771bc3ccb121230db76fd8aba4f45f060ad64ab3afd99b4e52824b9eba12e93e46f9dcb2fa01d9cef89f298a0da02a82a4fb56924afd3e3c277a1302d99f770d488449df2d43eb5b174a0a528827e6877b965c2f0b7c89cf1aa26a7417a892df4c2294e2872d62748b72ea04ecb0689b5d792e615a9bf9d56f6e0f298560bf9441df0a22729c5f23389f028c25f\n"
+ "10 5d4d5141ccd5066d50dc3f21d79ba02fedc24256 ima-sig sha256:b8ae0b8dd04a5935cd8165aa2260cd11b658bd71629bdb52256a675a1f73907b /usr/bin/zmore 030204531f402500483046022100fe24678d21083ead47660e1a2d553a592d777c478d1b0466de6ed484b54956b3022100cad3adb37f277bbb03544d6107751b4cd4f2289d8353fa36257400a99334d5c3\n"
)
COMBINED = MEASUREMENTS + SIGNATURES

View File

@ -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

View File

@ -1,136 +0,0 @@
From eb5112dd597336b566378b3a157e76fe3cbbbfee Mon Sep 17 00:00:00 2001
From: Thore Sommer <mail@thson.de>
Date: Mon, 16 Jan 2023 07:26:08 -0300
Subject: [PATCH 3/3] logging: remove option to log into separate file
The implementation had the issue that only the main loggers were added and that
the permissions were not set strict enough. Users should use the logging
provided by systemd instead.
Signed-off-by: Thore Sommer <mail@thson.de>
---
keylime.conf | 10 ----------
keylime/keylime_logging.py | 31 ------------------------------
scripts/templates/2.0/registrar.j2 | 9 ---------
scripts/templates/2.0/verifier.j2 | 9 ---------
4 files changed, 59 deletions(-)
diff --git a/keylime.conf b/keylime.conf
index d896f9f..043b6a8 100644
--- a/keylime.conf
+++ b/keylime.conf
@@ -342,11 +342,6 @@ tomtou_errors = False
# signature check before storing them in the database.
require_allow_list_signatures = False
-# Destination for log output, in addition to console. Values can be 'file',
-# with the file being named after the "service" - cloud_verifier - created under
-# /var/log/keylime), 'stream' or it can be left empty (which results in
-# logging to console only, recommended when running inside a container)
-log_destination = file
#=============================================================================
[tenant]
@@ -595,11 +590,6 @@ auto_migrate_db = True
# The file to use for SQLite persistence of provider hypervisor data.
prov_db_filename = provider_reg_data.sqlite
-# Destination for log output, in addition to console. Values can be 'file',
-# with the file being named after the "service" - registrar - created under
-# /var/log/keylime), 'stream' or it can be left empty (which results in
-# logging to console only, recommended when running inside a container)
-log_destination = file
#=============================================================================
[ca]
diff --git a/keylime/keylime_logging.py b/keylime/keylime_logging.py
index bc8a11d..f7c7a8f 100644
--- a/keylime/keylime_logging.py
+++ b/keylime/keylime_logging.py
@@ -1,17 +1,10 @@
import logging
-import os
from logging import Logger
from logging import config as logging_config
from typing import Any, Callable, Dict
from keylime import config
-LOG_TO_FILE = set()
-LOG_TO_STREAM = set()
-LOGDIR = os.getenv("KEYLIME_LOGDIR", "/var/log/keylime")
-# not clear that this works right. console logging may not work
-LOGSTREAM = os.path.join(LOGDIR, "keylime-stream.log")
-
logging_config.fileConfig(config.get_config("logging"))
@@ -50,31 +43,7 @@ def log_http_response(logger: Logger, loglevel: int, response_body: Dict[str, An
def init_logging(loggername: str) -> Logger:
-
- if loggername in ("verifier", "registrar"):
- logdest = config.get(loggername, "log_destination", fallback="")
- if logdest == "file":
- LOG_TO_FILE.add(loggername)
- if logdest == "stream":
- LOG_TO_STREAM.add(loggername)
-
logger = logging.getLogger(f"keylime.{loggername}")
logging.getLogger("requests").setLevel(logging.WARNING)
- mainlogger = logging.getLogger("keylime")
- basic_formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
- if loggername in LOG_TO_FILE:
- logfilename = os.path.join(LOGDIR, f"{loggername}.log")
- if not os.path.exists(LOGDIR):
- os.makedirs(LOGDIR, 0o750)
- fh = logging.FileHandler(logfilename)
- fh.setLevel(logger.getEffectiveLevel())
- fh.setFormatter(basic_formatter)
- mainlogger.addHandler(fh)
-
- if loggername in LOG_TO_STREAM:
- fh = logging.FileHandler(filename=LOGSTREAM, mode="w")
- fh.setLevel(logger.getEffectiveLevel())
- fh.setFormatter(basic_formatter)
- mainlogger.addHandler(fh)
return logger
diff --git a/scripts/templates/2.0/registrar.j2 b/scripts/templates/2.0/registrar.j2
index 3d92303..8de7a50 100644
--- a/scripts/templates/2.0/registrar.j2
+++ b/scripts/templates/2.0/registrar.j2
@@ -71,12 +71,3 @@ auto_migrate_db = {{ registrar.auto_migrate_db }}
# The file to use for SQLite persistence of provider hypervisor data.
prov_db_filename: {{ registrar.prov_db_filename }}
-
-# Destination for log output, in addition to console. If left empty, the log
-# output will only be printed to console (recommended for containers to avoid
-# filling data storage). The accepted values are:
-# 'file': The log output will also be written to a file named after the
-# component in '/var/log/keylime/registrar.log'
-# 'stream': The log output will be written to a common file in
-# 'var/log/keylime/keylime-stream.log'
-log_destination = {{ registrar.log_destination }}
diff --git a/scripts/templates/2.0/verifier.j2 b/scripts/templates/2.0/verifier.j2
index d1584df..7a66cb1 100644
--- a/scripts/templates/2.0/verifier.j2
+++ b/scripts/templates/2.0/verifier.j2
@@ -196,12 +196,3 @@ zmq_port = {{ verifier.zmq_port }}
# Webhook url for revocation notifications.
webhook_url = {{ verifier.webhook_url }}
-
-# Destination for log output, in addition to console. If left empty, the log
-# output will only be printed to console (recommended for containers to avoid
-# filling data storage). The accepted values are:
-# 'file': The log output will also be written to a file named after the
-# component in '/var/log/keylime/verifier.log'
-# 'stream': The log output will be written to a common file in
-# 'var/log/keylime/keylime-stream.log'
-log_destination = {{ verifier.log_destination }}
--
2.38.1

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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"],

View File

@ -0,0 +1,59 @@
--- a/scripts/create_runtime_policy.sh 2023-10-09 17:04:26.121194607 +0200
+++ b/scripts/create_runtime_policy.sh 2023-10-09 17:06:02.089855614 +0200
@@ -42,7 +42,7 @@
exit $NOARGS;
fi
-ALGO=sha1sum
+ALGO=sha256sum
ALGO_LIST=("sha1sum" "sha256sum" "sha512sum")
@@ -78,7 +78,7 @@
# Where to look for initramfs image
-INITRAMFS_LOC="/boot/"
+INITRAMFS_LOC="/boot"
if [ -d "/ostree" ]; then
# If we are on an ostree system change where we look for initramfs image
loc=$(grep -E "/ostree/[^/]([^/]*)" -o /proc/cmdline | head -n 1 | cut -d / -f 3)
@@ -121,7 +121,7 @@
cp -r /tmp/ima/$i-extracted-unmk/. /tmp/ima/$i-extracted
fi
elif [[ -x "/usr/lib/dracut/skipcpio" ]] ; then
- /usr/lib/dracut/skipcpio $i | gunzip -c | cpio -i -d 2> /dev/null
+ /usr/lib/dracut/skipcpio $i | gunzip -c 2> /dev/null | cpio -i -d 2> /dev/null
else
echo "ERROR: No tools for initramfs image processing found!"
break
@@ -130,9 +130,26 @@
find -type f -exec $ALGO "./{}" \; | sed "s| \./\./| /|" >> $OUTPUT
done
-# Convert to runtime policy
-echo "Converting created allowlist to Keylime runtime policy"
-python3 $WORKING_DIR/../keylime/cmd/convert_runtime_policy.py -a $OUTPUT -o $OUTPUT
+# when ROOTFS_LOC = '/', the path starts on allowlist ends up with double '//'
+#
+# Example:
+#
+# b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c //bar
+#
+# Replace the unwanted '//' with a single '/'
+sed -i 's| /\+| /|g' $ALLOWLIST_DIR/${OUTPUT}
+
+# When the file name contains newlines or backslashes, the output of sha256sum
+# adds a backslash at the beginning of the line.
+#
+# Example:
+#
+# $ echo foo > ba\\r
+# $ sha256sum ba\\r
+# \b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c ba\\r
+#
+# Remove the unwanted backslash prefix
+sed -i 's/^\\//g' $ALLOWLIST_DIR/${OUTPUT}
# Clean up
rm -rf /tmp/ima

View File

@ -0,0 +1,44 @@
diff --git a/keylime/cloud_verifier_common.py b/keylime/cloud_verifier_common.py
index a7399d2..c0f416d 100644
--- a/keylime/cloud_verifier_common.py
+++ b/keylime/cloud_verifier_common.py
@@ -8,7 +8,7 @@ from keylime.agentstates import AgentAttestState, AgentAttestStates, TPMClockInf
from keylime.common import algorithms
from keylime.db.verifier_db import VerfierMain
from keylime.failure import Component, Event, Failure
-from keylime.ima import file_signatures
+from keylime.ima import file_signatures, ima
from keylime.ima.types import RuntimePolicyType
from keylime.tpm import tpm_util
from keylime.tpm.tpm_main import Tpm
@@ -271,7 +271,7 @@ def process_get_status(agent: VerfierMain) -> Dict[str, Any]:
logger.debug('The contents of the agent %s attribute "mb_refstate" are %s', agent.agent_id, agent.mb_refstate)
has_runtime_policy = 0
- if agent.ima_policy.generator and agent.ima_policy.generator > 1:
+ if agent.ima_policy.generator and agent.ima_policy.generator > ima.RUNTIME_POLICY_GENERATOR.EmptyAllowList:
has_runtime_policy = 1
response = {
diff --git a/keylime/cmd/create_policy.py b/keylime/cmd/create_policy.py
index 0841d64..086b92a 100755
--- a/keylime/cmd/create_policy.py
+++ b/keylime/cmd/create_policy.py
@@ -6,6 +6,7 @@ import argparse
import binascii
import collections
import copy
+import datetime
import gzip
import json
import multiprocessing
@@ -580,6 +581,9 @@ def main() -> None:
policy["excludes"] = sorted(list(set(policy["excludes"])))
policy["ima"]["ignored_keyrings"] = sorted(list(set(policy["ima"]["ignored_keyrings"])))
+ policy["meta"]["generator"] = ima.RUNTIME_POLICY_GENERATOR.LegacyAllowList
+ policy["meta"]["timestamp"] = str(datetime.datetime.now())
+
try:
ima.validate_runtime_policy(policy)
except ima.ImaValidationError as ex:

View File

@ -1,5 +1,5 @@
%global srcname keylime
%global policy_version 1.0.0
%global policy_version 1.2.0
%global with_selinux 1
%global selinuxtype targeted
@ -8,8 +8,8 @@
%global debug_package %{nil}
Name: keylime
Version: 6.5.2
Release: 4%{?dist}
Version: 7.3.0
Release: 12%{?dist}
Summary: Open source TPM software for Bootstrapping and Maintaining Trust
URL: https://github.com/keylime/keylime
@ -17,9 +17,19 @@ Source0: https://github.com/keylime/keylime/archive/refs/tags/v%{version}
Source1: %{srcname}.sysusers
Source2: https://github.com/RedHat-SP-Security/%{name}-selinux/archive/v%{policy_version}/keylime-selinux-%{policy_version}.tar.gz
Patch: 0001-Do-not-use-default-values-that-need-reading-the-conf.patch
Patch: 0002-Switch-to-sha256-hashes-for-signatures.patch
Patch: 0003-logging-remove-option-to-log-into-separate-file.patch
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
Patch: 0012-Restore-create-allowlist.patch
Patch: 0013-Set-generator-and-timestamp-in-create-policy.patch
License: ASL 2.0 and MIT
@ -31,6 +41,7 @@ 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}
@ -52,7 +63,9 @@ 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
@ -88,6 +101,7 @@ Requires: python3-gpg
Requires: python3-lark-parser
Requires: python3-pyasn1
Requires: python3-pyasn1-modules
Requires: python3-jsonschema
Requires: tpm2-tools
Requires: openssl
@ -169,33 +183,32 @@ for comp in "verifier" "tenant" "registrar" "ca" "logging"; do
install -Dpm 400 config/${comp}.conf %{buildroot}/%{_sysconfdir}/%{srcname}
done
# Remove agent.
rm -f %{buildroot}/%{_bindir}/%{srcname}_agent
rm -f %{buildroot}%{python3_sitelib}/%{srcname}/__pycache__/%{srcname}_agent*
rm -f %{buildroot}%{python3_sitelib}/%{srcname}/cmd/__pycache__/agent.*
rm -f %{buildroot}%{python3_sitelib}/%{srcname}/cmd/agent.*
rm -f %{buildroot}%{python3_sitelib}/%{srcname}/%{srcname}_agent.*
# Remove misc progs.
rm -f %{buildroot}/%{_bindir}/%{srcname}_ima_emulator
rm -f %{buildroot}/%{_bindir}/%{srcname}_userdata_encrypt
# Ship some scripts.
mkdir -p %{buildroot}/%{_datadir}/%{srcname}/scripts
for s in create_allowlist.sh \
create_mb_refstate \
create_policy \
for s in create_mb_refstate \
ek-openssl-verify; do
install -Dpm 755 scripts/${s} \
%{buildroot}/%{_datadir}/%{srcname}/scripts/${s}
done
# On RHEL 9.3, install create_runtime_policy.sh as create_allowlist.sh
# The convert_runtime_policy.py script to convert allowlist and excludelist into
# runtime policy is not called anymore.
# See: https://issues.redhat.com/browse/RHEL-11866
install -Dpm 755 scripts/create_runtime_policy.sh \
%{buildroot}/%{_datadir}/%{srcname}/scripts/create_allowlist.sh
# 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
@ -216,6 +229,10 @@ install -p -D -m 0644 %{SOURCE1} %{buildroot}%{_sysusersdir}/%{srcname}.conf
%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}
@ -227,7 +244,6 @@ if [ -d %{_sysconfdir}/%{srcname} ]; then
done
fi
[ -d %{_sharedstatedir}/%{srcname} ] && \
chown -R %{srcname} %{_sharedstatedir}/%{srcname}/
@ -240,10 +256,18 @@ fi
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
@ -288,16 +312,15 @@ fi
%files verifier
%license LICENSE
%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/verifier.conf.d
%config(noreplace) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/verifier.conf
%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/verifier.conf
%{_bindir}/%{srcname}_verifier
%{_bindir}/%{srcname}_ca
%{_bindir}/%{srcname}_migrations_apply
%{_unitdir}/keylime_verifier.service
%files registrar
%license LICENSE
%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/registrar.conf.d
%config(noreplace) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/registrar.conf
%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/registrar.conf
%{_bindir}/%{srcname}_registrar
%{_unitdir}/keylime_registrar.service
@ -311,7 +334,7 @@ fi
%files tenant
%license LICENSE
%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/tenant.conf.d
%config(noreplace) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/tenant.conf
%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/tenant.conf
%{_bindir}/%{srcname}_tenant
%files -n python3-%{srcname}
@ -319,15 +342,18 @@ fi
%{python3_sitelib}/%{srcname}-*.egg-info/
%{python3_sitelib}/%{srcname}
%{_datadir}/%{srcname}/scripts/create_mb_refstate
%{_datadir}/%{srcname}/scripts/create_policy
%{_bindir}/keylime_convert_ima_policy
%{_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) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/ca.conf
%config(noreplace) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/logging.conf
%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}
@ -337,11 +363,71 @@ fi
%{_sysusersdir}/%{srcname}.conf
%{_datadir}/%{srcname}/scripts/create_allowlist.sh
%{_datadir}/%{srcname}/scripts/ek-openssl-verify
%{_datadir}/%{srcname}/templates
%{_bindir}/keylime_upgrade_config
%files
%license LICENSE
%changelog
* Tue Oct 17 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-12
- Set the generator and timestamp in create_policy.py
Related: RHEL-11866
* Mon Oct 09 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-11
- Suppress unnecessary error message
Related: RHEL-11866
* Fri Oct 06 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-10
- Restore allowlist generation script
Resolves: RHEL-11866
Resolves: RHEL-11867
* 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