Compare commits

..

No commits in common. 'cs10' and 'c9' have entirely different histories.
cs10 ... c9

4
.gitignore vendored

@ -1,2 +1,2 @@
SOURCES/keylime-selinux-38.1.0.tar.gz SOURCES/keylime-selinux-1.2.0.tar.gz
SOURCES/v7.9.0.tar.gz SOURCES/v7.3.0.tar.gz

@ -1,2 +1,2 @@
1bdc12a3d0baf4a01d6abdca0efffd0a7c5e2ebd SOURCES/keylime-selinux-38.1.0.tar.gz 9130beade415b8e3b02aac8d06678f2c45b939fe SOURCES/keylime-selinux-1.2.0.tar.gz
0a1cb85dc9c884869e486d09f0507b784647bc57 SOURCES/v7.9.0.tar.gz 400e2b019060b8a6cc255dbfc14c582121acbee1 SOURCES/v7.3.0.tar.gz

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

@ -1,389 +0,0 @@
--- a/scripts/create_runtime_policy.sh 2024-01-30 18:17:19.000000000 +0100
+++ b/scripts/create_runtime_policy.sh 2024-08-16 17:25:50.871701853 +0200
@@ -1,282 +1,155 @@
-#!/usr/bin/env bash
+#!/usr/bin/bash
################################################################################
# SPDX-License-Identifier: Apache-2.0
# Copyright 2017 Massachusetts Institute of Technology.
################################################################################
-
-if [ $0 != "-bash" ] ; then
- pushd `dirname "$0"` > /dev/null 2>&1
-fi
-KCRP_BASE_DIR=$(pwd)
-if [ $0 != "-bash" ] ; then
- popd 2>&1 > /dev/null
-fi
-KCRP_BASE_DIR=$KCRP_BASE_DIR/..
-
-function detect_hash {
- local hashstr=$1
-
- case "${#hashstr}" in
- 32) hashalgo=md5sum ;;
- 40) hashalgo=sha1sum ;;
- 64) hashalgo=sha256sum ;;
- 128) hashalgo=sha512sum ;;
- *) hashalgo="na";;
- esac
-
- echo $hashalgo
-}
-
-function announce {
- # 1 - MESSAGE
-
- MESSAGE=$(echo "${1}" | tr '\n' ' ')
- MESSAGE=$(echo $MESSAGE | sed "s/\t\t*/ /g")
-
- echo "==> $(date) - ${0} - $MESSAGE"
-}
-
-function valid_algo {
- local algo=$1
-
- [[ " ${ALGO_LIST[@]} " =~ " ${algo} " ]]
-}
-
# Configure the installer here
INITRAMFS_TOOLS_GIT=https://salsa.debian.org/kernel-team/initramfs-tools.git
INITRAMFS_TOOLS_VER="master"
-# All defaults
-ALGO=sha1sum
-WORK_DIR=/tmp/kcrp
-OUTPUT_DIR=${WORK_DIR}/output
-ALLOWLIST_DIR=${WORK_DIR}/allowlist
-INITRAMFS_LOC="/boot/"
-INITRAMFS_STAGING_DIR=${WORK_DIR}/ima_ramfs/
-INITRAMFS_TOOLS_DIR=${WORK_DIR}/initramfs-tools
-BOOT_AGGREGATE_LOC="/sys/kernel/security/ima/ascii_runtime_measurements"
-ROOTFS_LOC="/"
-EXCLUDE_LIST="none"
-SKIP_PATH="none"
-ALGO_LIST=("sha1sum" "sha256sum" "sha512sum")
+WORKING_DIR=$(readlink -f "$0")
+WORKING_DIR=$(dirname "$WORKING_DIR")
# Grabs Debian's initramfs_tools from Git repo if no other options exist
if [[ ! `command -v unmkinitramfs` && ! -x "/usr/lib/dracut/skipcpio" ]] ; then
# Create temp dir for pulling in initramfs-tools
- announce "INFO: Downloading initramfs-tools: $INITRAMFS_TOOLS_DIR"
+ TMPDIR=`mktemp -d` || exit 1
+ echo "INFO: Downloading initramfs-tools: $TMPDIR"
- mkdir -p $INITRAMFS_TOOLS_DIR
# Clone initramfs-tools repo
- pushd $INITRAMFS_TOOLS_DIR > /dev/null 2>&1
- git clone $INITRAMFS_TOOLS_GIT initramfs-tools > /dev/null 2>&1
- pushd initramfs-tools > /dev/null 2>&1
- git checkout $INITRAMFS_TOOLS_VER > /dev/null 2>&1
- popd > /dev/null 2>&1
- popd > /dev/null 2>&1
+ pushd $TMPDIR
+ git clone $INITRAMFS_TOOLS_GIT initramfs-tools
+ pushd initramfs-tools
+ git checkout $INITRAMFS_TOOLS_VER
+ popd # $TMPDIR
+ popd
shopt -s expand_aliases
- alias unmkinitramfs=$INITRAMFS_TOOLS_DIR/initramfs-tools/unmkinitramfs
-
- which unmkinitramfs > /dev/null 2>&1 || exit 1
+ alias unmkinitramfs=$TMPDIR/initramfs-tools/unmkinitramfs
fi
+
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
-USAGE=$(cat <<-END
- Usage: $0 -o/--output_file FILENAME [-a/--algo ALGO] [-x/--ramdisk-location PATH] [-y/--boot_aggregate-location PATH] [-z/--rootfs-location PATH] [-e/--exclude_list FILENAME] [-s/--skip-path PATH] [-h/--help]
+if [ $# -lt 1 ]
+then
+ echo "No arguments provided" >&2
+ echo "Usage: `basename $0` -o [filename] -h [hash-algo]" >&2
+ exit $NOARGS;
+fi
- optional arguments:
- -a/--algo (checksum algorithm to be used, default: $ALGO)
- -x/--ramdisk-location (path to initramdisk, default: $INITRAMFS_LOC, set to "none" to skip)
- -y/--boot_aggregate-location (path for IMA log, used for boot aggregate extraction, default: $BOOT_AGGREGATE_LOC, set to "none" to skip)
- -z/--rootfs-location (path to root filesystem, default: $ROOTFS_LOC, cannot be skipped)
- -e/--exclude_list (filename containing a list of paths to be excluded (i.e., verifier will not try to match checksums, default: $EXCLUDE_LIST)
- -s/--skip-path (comma-separated path list, files found there will not have checksums calculated, default: $SKIP_PATH)
- -h/--help (show this message and exit)
-END
-)
+ALGO=sha256sum
-while [[ $# -gt 0 ]]
-do
- key="$1"
+ALGO_LIST=("sha1sum" "sha256sum" "sha512sum")
+
+valid_algo() {
+ local algo=$1
- case $key in
- -a|--algo)
- ALGO="$2"
- shift
- ;;
- -a=*|--algo=*)
- ALGO=$(echo $key | cut -d '=' -f 2)
- ;;
- -x|--ramdisk-location)
- INITRAMFS_LOC="$2"
- shift
- ;;
- -x=*|--ramdisk-location=*)
- INITRAMFS_LOC=$(echo $key | cut -d '=' -f 2)
- ;;
- -y|--boot_aggregate-location)
- BOOT_AGGREGATE_LOC=$2
- shift
- ;;
- -y=*|--boot_aggregate-location=*)
- BOOT_AGGREGATE_LOC=$(echo $key | cut -d '=' -f 2)
- ;;
- -z|--rootfs-location)
- ROOTFS_LOC=$2
- shift
- ;;
- -z=*|--rootfs-location=*)
- ROOTFS_LOC=$(echo $key | cut -d '=' -f 2)
- ;;
- -e|--exclude_list)
- EXCLUDE_LIST=$2
- shift
- ;;
- -e=*|--exclude_list=*)
- EXCLUDE_LIST=$(echo $key | cut -d '=' -f 2)
- ;;
- -o=*|--output_file=*)
- OUTPUT=$(echo $key | cut -d '=' -f 2)
- ;;
- -o|--output_file)
- OUTPUT=$2
- shift
- ;;
- -s=*|--skip-path=*)
- SKIP_PATH=$(echo $key | cut -d '=' -f 2)
- ;;
- -s|--skip-path)
- SKIP_PATH=$2
- shift
- ;;
- -h|--help)
- printf "%s\n" "$USAGE"
- exit 0
- shift
- ;;
- *)
- # unknown option
- ;;
- esac
- shift
+ [[ " ${ALGO_LIST[@]} " =~ " ${algo} " ]]
+}
+
+while getopts ":o:h:" opt; do
+ case $opt in
+ o)
+ OUTPUT=$(readlink -f $OPTARG)
+ rm -f $OUTPUT
+ ;;
+ h)
+ if valid_algo $OPTARG; then
+ ALGO=$OPTARG
+ else
+ echo "Invalid hash function argument: use sha1sum, sha256sum, or sha512sum"
+ exit 1
+ fi
+ ;;
+ esac
done
-if ! valid_algo $ALGO
+if [ ! "$OUTPUT" ]
then
- echo "Invalid hash function argument: pick from \"${ALGO_LIST[@]}\""
+ echo "Missing argument for -o" >&2;
+ echo "Usage: $0 -o [filename] -h [hash-algo]" >&2;
exit 1
fi
-if [[ -z $OUTPUT ]]
-then
- printf "%s\n" "$USAGE"
- exit 1
+
+# Where to look for initramfs image
+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)
+ INITRAMFS_LOC="/boot/ostree/${loc}/"
fi
-rm -rf $ALLOWLIST_DIR
-rm -rf $INITRAMFS_STAGING_DIR
-rm -rf $OUTPUT_DIR
-announce "Writing allowlist $ALLOWLIST_DIR/${OUTPUT} with $ALGO..."
-mkdir -p $ALLOWLIST_DIR
+echo "Writing allowlist to $OUTPUT with $ALGO..."
-if [[ $BOOT_AGGREGATE_LOC != "none" ]]
-then
- announce "--- Adding boot agregate from $BOOT_AGGREGATE_LOC on allowlist $ALLOWLIST_DIR/${OUTPUT} ..."
# Add boot_aggregate from /sys/kernel/security/ima/ascii_runtime_measurements (IMA Log) file.
# The boot_aggregate measurement is always the first line in the IMA Log file.
# The format of the log lines is the following:
# <PCR_ID> <PCR_Value> <IMA_Template> <File_Digest> <File_Name> <File_Signature>
# File_Digest may start with the digest algorithm specified (e.g "sha1:", "sha256:") depending on the template used.
- head -n 1 $BOOT_AGGREGATE_LOC | awk '{ print $4 " boot_aggregate" }' | sed 's/.*://' >> $ALLOWLIST_DIR/${OUTPUT}
+head -n 1 /sys/kernel/security/ima/ascii_runtime_measurements | awk '{ print $4 " boot_aggregate" }' | sed 's/.*://' >> $OUTPUT
- bagghash=$(detect_hash $(cat $ALLOWLIST_DIR/${OUTPUT} | cut -d ' ' -f 1))
- if [[ $ALGO != $bagghash ]]
- then
- announce "ERROR: \"boot aggregate\" has was calculated with $bagghash, but files will be calculated with $ALGO. Use option -a $bagghash"
- exit 1
- fi
-else
- announce "--- Skipping boot aggregate..."
-fi
-
-announce "--- Adding all appropriate files from $ROOTFS_LOC on allowlist $ALLOWLIST_DIR/${OUTPUT} ..."
# Add all appropriate files under root FS to allowlist
-pushd $ROOTFS_LOC > /dev/null 2>&1
-BASE_EXCLUDE_DIRS="\bsys\b\|\brun\b\|\bproc\b\|\blost+found\b\|\bdev\b\|\bmedia\b\|\bsnap\b\|\bmnt\b\|\bvar\b\|\btmp\b"
-ROOTFS_FILE_LIST=$(ls | grep -v $BASE_EXCLUDE_DIRS)
-if [[ $SKIP_PATH != "none" ]]
-then
- SKIP_PATH=$(echo $SKIP_PATH | sed -e "s#^$ROOTFS_LOC##g" -e "s#,$ROOTFS_LOC##g" -e "s#,#\\\|#g")
- ROOTFS_FILE_LIST=$(echo "$ROOTFS_FILE_LIST" | grep -v "$SKIP_PATH")
-fi
-find $ROOTFS_FILE_LIST \( -fstype rootfs -o -xtype f -type l -o -type f \) -uid 0 -exec $ALGO "$ROOTFS_LOC/{}" >> $ALLOWLIST_DIR/${OUTPUT} \;
-popd > /dev/null 2>&1
+cd /
+find `ls / | grep -v "\bsys\b\|\brun\b\|\bproc\b\|\blost+found\b\|\bdev\b\|\bmedia\b\|\bsnap\b\|mnt"` \( -fstype rootfs -o -xtype f -type l -o -type f \) -uid 0 -exec $ALGO '/{}' >> $OUTPUT \;
# Create staging area for init ram images
-mkdir -p $INITRAMFS_STAGING_DIR
-
-if [[ $INITRAMFS_LOC != "none" ]]
-then
- # Where to look for initramfs image
- if [[ -d "/ostree" ]]
- then
- X=$INITRAMFS_LOC
- # 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)
- INITRAMFS_LOC="/boot/ostree/${loc}/"
- announce "--- The location of initramfs was overriden from \"${X}\" to \"$INITRAMFS_LOC\""
- fi
+rm -rf /tmp/ima/
+mkdir -p /tmp/ima
- announce "--- Creating allowlist for init ram disks found under \"$INITRAMFS_LOC\" to $ALLOWLIST_DIR/${OUTPUT} ..."
- for i in $(ls ${INITRAMFS_LOC}/initr* 2> /dev/null)
- do
- announce " extracting $i"
- mkdir -p $INITRAMFS_STAGING_DIR/$i-extracted
- cd $INITRAMFS_STAGING_DIR/$i-extracted
-
- # platform-specific handling of init ram disk images
- if [[ `command -v unmkinitramfs` ]] ; then
- mkdir -p $INITRAMFS_STAGING_DIR/$i-extracted-unmk
- unmkinitramfs $i $INITRAMFS_STAGING_DIR/$i-extracted-unmk
- if [[ -d "$INITRAMFS_STAGING_DIR/$i-extracted-unmk/main/" ]] ; then
- cp -r $INITRAMFS_STAGING_DIR/$i-extracted-unmk/main/. /tmp/ima/$i-extracted
- else
- cp -r $INITRAMFS_STAGING_DIR/$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
+# Iterate through init ram disks and add files to allowlist
+echo "Creating allowlist for init ram disk"
+for i in `ls ${INITRAMFS_LOC}/initr*`
+do
+ echo "extracting $i"
+ mkdir -p /tmp/ima/$i-extracted
+ cd /tmp/ima/$i-extracted
+
+ # platform-specific handling of init ram disk images
+ if [[ `command -v unmkinitramfs` ]] ; then
+ mkdir -p /tmp/ima/$i-extracted-unmk
+ unmkinitramfs $i /tmp/ima/$i-extracted-unmk
+ if [[ -d "/tmp/ima/$i-extracted-unmk/main/" ]] ; then
+ cp -r /tmp/ima/$i-extracted-unmk/main/. /tmp/ima/$i-extracted
else
- announce "ERROR: No tools for initramfs image processing found!"
- exit 1
+ 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 2> /dev/null | cpio -i -d 2> /dev/null
+ else
+ echo "ERROR: No tools for initramfs image processing found!"
+ break
+ fi
- find -type f -exec $ALGO "./{}" \; | sed "s| \./\./| /|" >> $ALLOWLIST_DIR/${OUTPUT}
- done
-fi
+ find -type f -exec $ALGO "./{}" \; | sed "s| \./\./| /|" >> $OUTPUT
+done
-# Non-critical cleanup on the resulting file (when ROOTFS_LOC = '/', the path starts on allowlist ends up with double '//' )
-sed -i "s^ //^ /^g" $ALLOWLIST_DIR/${OUTPUT}
-# A bit of cleanup on the resulting file (among other problems, sha256sum might output a hash with the prefix '\\')
-sed -i "s/^\\\//g" $ALLOWLIST_DIR/${OUTPUT}
-
-# Convert to runtime policy
-mkdir -p $OUTPUT_DIR
-announce "Converting created allowlist ($ALLOWLIST_DIR/${OUTPUT}) to Keylime runtime policy ($OUTPUT_DIR/${OUTPUT}) ..."
-CONVERT_CMD_OPTS="--allowlist $ALLOWLIST_DIR/${OUTPUT} --output_file $OUTPUT_DIR/${OUTPUT}"
-[ -f $EXCLUDE_LIST ] && CONVERT_CMD_OPTS="$CONVERT_CMD_OPTS --excludelist $EXCLUDE_LIST"
-
-pushd $KCRP_BASE_DIR > /dev/null 2>&1
-export PYTHONPATH=$KCRP_BASE_DIR:$PYTHONPATH
-# only 3 dependencies required: pip3 install cryptography lark packaging
-python3 ./keylime/cmd/convert_runtime_policy.py $CONVERT_CMD_OPTS; echo " "
-if [[ $? -eq 0 ]]
-then
- announce "Done, new runtime policy file present at ${OUTPUT_DIR}/$OUTPUT. It can be used on the tenant keylime host with \"keylime_tenant -c add --runtime-policy ${OUTPUT_DIR}/$OUTPUT <other options>"
-fi
-popd > /dev/null 2>&1
+# 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' ${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' ${OUTPUT}
+
+# Clean up
+rm -rf /tmp/ima

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

@ -1,168 +0,0 @@
diff --git a/keylime/revocation_notifier.py b/keylime/revocation_notifier.py
index 112012b8f..5724af486 100644
--- a/keylime/revocation_notifier.py
+++ b/keylime/revocation_notifier.py
@@ -140,7 +140,7 @@ def worker_webhook(tosend: Dict[str, Any], url: str) -> None:
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)
+ response = session.post(url, json=tosend, timeout=5, verify=requests.utils.DEFAULT_CA_BUNDLE_PATH)
if response.status_code in [200, 202]:
break
diff --git a/keylime/requests_client.py b/keylime/requests_client.py
index 6da703264..16615f7d9 100644
--- a/keylime/requests_client.py
+++ b/keylime/requests_client.py
@@ -1,3 +1,4 @@
+import re
import ssl
from typing import Any, Dict, Optional
@@ -15,6 +16,10 @@ def __init__(
ignore_hostname: bool = True,
**kwargs: Any,
) -> None:
+ # Remove eventual "http?://" from the base url
+ if base_url.startswith("http"):
+ base_url = re.sub(r"https?://", "", base_url)
+
if tls_enabled:
self.base_url = f"https://{base_url}"
else:
diff --git a/keylime/revocation_notifier.py b/keylime/revocation_notifier.py
index 5724af486..5a7cc4b16 100644
--- a/keylime/revocation_notifier.py
+++ b/keylime/revocation_notifier.py
@@ -9,8 +9,9 @@
import requests
-from keylime import config, crypto, json, keylime_logging
+from keylime import config, crypto, json, keylime_logging, web_util
from keylime.common import retry
+from keylime.requests_client import RequestsClient
logger = keylime_logging.init_logging("revocation_notifier")
broker_proc: Optional[Process] = None
@@ -112,7 +113,10 @@ def worker(tosend: Dict[str, Any]) -> None:
exponential_backoff = config.getboolean("verifier", "exponential_backoff")
next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
logger.debug(
- "Unable to publish revocation message %d times, trying again in %f seconds: %s", i, next_retry, e
+ "Unable to publish revocation message %d times, trying again in %f seconds: %s",
+ i,
+ next_retry,
+ e,
)
time.sleep(next_retry)
mysock.close()
@@ -135,30 +139,50 @@ 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")
- 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)
+
+ max_retries = config.getint("verifier", "max_retries")
+ if max_retries <= 0:
+ logger.info("Invalid value found in 'max_retries' option for verifier, using default value")
+ max_retries = 5
+
+ # Get TLS options from the configuration
+ (cert, key, trusted_ca, key_password), verify_server_cert = web_util.get_tls_options(
+ "verifier", is_client=True, logger=logger
+ )
+
+ # Generate the TLS context using the obtained options
+ tls_context = web_util.generate_tls_context(cert, key, trusted_ca, key_password, is_client=True, logger=logger)
+
+ logger.info("Sending revocation event via webhook to %s ...", url)
+ for i in range(max_retries):
+ next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
+
+ with RequestsClient(
+ url,
+ verify_server_cert,
+ tls_context,
+ ) as client:
try:
- response = session.post(url, json=tosend, timeout=5, verify=requests.utils.DEFAULT_CA_BUNDLE_PATH)
- 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,
- )
+ res = client.post("", json=tosend, timeout=5)
+ except requests.exceptions.SSLError as ssl_error:
+ if "TLSV1_ALERT_UNKNOWN_CA" in str(ssl_error):
+ logger.warning(
+ "Keylime does not recognize certificate from peer. Check if verifier 'trusted_server_ca' is configured correctly"
+ )
+
+ raise ssl_error from ssl_error
+
+ if res and res.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 + 1,
+ next_retry,
+ res.status_code,
+ )
time.sleep(next_retry)
@@ -170,7 +194,11 @@ def worker_webhook(tosend: Dict[str, Any], url: str) -> None:
cert_key = None
-def process_revocation(revocation: Dict[str, Any], callback: Callable[[Dict[str, Any]], None], cert_path: str) -> None:
+def process_revocation(
+ revocation: Dict[str, Any],
+ callback: Callable[[Dict[str, Any]], None],
+ cert_path: str,
+) -> None:
global cert_key
if cert_key is None:
@@ -182,10 +210,17 @@ def process_revocation(revocation: Dict[str, Any], callback: Callable[[Dict[str,
cert_key = crypto.x509_import_pubkey(certpem)
if cert_key is None:
- logger.warning("Unable to check signature of revocation message: %s not available", cert_path)
+ logger.warning(
+ "Unable to check signature of revocation message: %s not available",
+ cert_path,
+ )
elif "signature" not in revocation or revocation["signature"] == "none":
logger.warning("No signature on revocation message from server")
- elif not crypto.rsa_verify(cert_key, revocation["msg"].encode("utf-8"), revocation["signature"].encode("utf-8")):
+ elif not crypto.rsa_verify(
+ cert_key,
+ revocation["msg"].encode("utf-8"),
+ revocation["signature"].encode("utf-8"),
+ ):
logger.error("Invalid revocation message siganture %s", revocation)
else:
message = json.loads(revocation["msg"])

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

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

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

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

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

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

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

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

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

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

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

@ -0,0 +1,80 @@
From add9847988e963fd124863736592fc16cc8c716b Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.ibm.com>
Date: Tue, 11 Jul 2023 18:03:28 -0400
Subject: [PATCH 14/14] tpm_util: Replace a logger.error with an Exception in
case of invalid signature
This fixes a possibly severe issue in 7.2.5 & 7.3.0.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
keylime/tpm/tpm_util.py | 6 +-----
keylime/tpm/tpm_util_test.py | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/keylime/tpm/tpm_util.py b/keylime/tpm/tpm_util.py
index ce2ce0f..58a1a04 100644
--- a/keylime/tpm/tpm_util.py
+++ b/keylime/tpm/tpm_util.py
@@ -3,7 +3,6 @@ import string
import struct
from typing import Any, Dict, List, Optional, Tuple, Union
-from cryptography.exceptions import InvalidSignature
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import hashes, hmac, serialization
from cryptography.hazmat.primitives.asymmetric import ec, padding
@@ -155,10 +154,7 @@ def checkquote(
digest.update(quoteblob)
quote_digest = digest.finalize()
- try:
- verify(pubkey, signature, quote_digest, hashfunc)
- except InvalidSignature:
- logger.error("Invalid quote signature!")
+ verify(pubkey, signature, quote_digest, hashfunc)
# Check that reported nonce is expected one
retDict = tpm2_objects.unmarshal_tpms_attest(quoteblob)
diff --git a/keylime/tpm/tpm_util_test.py b/keylime/tpm/tpm_util_test.py
index aaf16cd..2c73997 100644
--- a/keylime/tpm/tpm_util_test.py
+++ b/keylime/tpm/tpm_util_test.py
@@ -2,6 +2,7 @@ import base64
import unittest
from unittest import mock
+from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ec import (
SECP256R1,
EllipticCurve,
@@ -60,6 +61,26 @@ class TestTpmUtil(unittest.TestCase):
except Exception as e:
self.fail(f"checkquote failed with {e}")
+ # test bad input
+ bad_quoteblob = bytearray(quoteblob)
+ bad_quoteblob[5] ^= 0x1
+ with self.assertRaises(InvalidSignature):
+ checkquote(aikblob, nonce, sigblob, bad_quoteblob, pcrblob, "sha256")
+
+ l = list(nonce)
+ l[0] = "a"
+ bad_nonce = "".join(l)
+ with self.assertRaises(Exception):
+ checkquote(aikblob, bad_nonce, sigblob, quoteblob, pcrblob, "sha256")
+
+ bad_pcrblob = bytearray(pcrblob)
+ bad_pcrblob[5] ^= 0x1
+ with self.assertRaises(Exception):
+ checkquote(aikblob, nonce, sigblob, quoteblob, bad_pcrblob, "sha256")
+
+ with self.assertRaises(ValueError):
+ checkquote(aikblob, nonce, sigblob, quoteblob, pcrblob, "sha1")
+
@staticmethod
def not_random(numbytes: int) -> bytes:
return b"\x12" * numbytes
--
2.41.0

@ -1,47 +1,38 @@
## START: Set by rpmautospec
## (rpmautospec version 0.6.5)
## RPMAUTOSPEC: autorelease, autochangelog
%define autorelease(e:s:pb:n) %{?-p:0.}%{lua:
release_number = 8;
base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
print(release_number + base_release_number - 1);
}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
## END: Set by rpmautospec
%global srcname keylime %global srcname keylime
%global policy_version 38.1.0 %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 # Package is actually noarch, but it has an optional dependency that is
# arch-specific. # arch-specific.
%global debug_package %{nil} %global debug_package %{nil}
%global with_selinux 1
%global selinuxtype targeted
Name: keylime Name: keylime
Version: 7.9.0 Version: 7.3.0
Release: %autorelease Release: 13%{?dist}
Summary: Open source TPM software for Bootstrapping and Maintaining Trust Summary: Open source TPM software for Bootstrapping and Maintaining Trust
URL: https://github.com/keylime/keylime URL: https://github.com/keylime/keylime
Source0: https://github.com/keylime/keylime/archive/refs/tags/v%{version}.tar.gz Source0: https://github.com/keylime/keylime/archive/refs/tags/v%{version}.tar.gz
Source1: %{srcname}.sysusers Source1: %{srcname}.sysusers
# The selinux policy for keylime is distributed via this repo: https://github.com/RedHat-SP-Security/keylime-selinux
Source2: https://github.com/RedHat-SP-Security/%{name}-selinux/archive/v%{policy_version}/keylime-selinux-%{policy_version}.tar.gz Source2: https://github.com/RedHat-SP-Security/%{name}-selinux/archive/v%{policy_version}/keylime-selinux-%{policy_version}.tar.gz
# Restore the create_allowlist.sh script Patch: 0001-Remove-usage-of-Required-NotRequired-typing_ext.patch
# https://issues.redhat.com/browse/RHEL-32637 Patch: 0002-Allow-keylime_server_t-tcp-connect-to-several-domain.patch
Patch1: 0001-Restore-create-allowlist.patch Patch: 0003-Use-version-2.0-as-the-minimum-for-the-configuration.patch
# Use TLS for the revocation notification webhook Patch: 0004-Duplicate-str_to_version-for-the-upgrade-tool.patch
# Take into account CA certificates added by configuration file Patch: 0005-elchecking-example-add-ignores-for-EV_PLATFORM_CONFI.patch
# Include the system installed CA certificates Patch: 0006-Revert-mapping-changes.patch
# https://issues.redhat.com/browse/RHEL-49601 Patch: 0007-Handle-session-close-using-a-session-manager.patch
# https://issues.redhat.com/browse/RHEL-51279 Patch: 0008-verifier-should-read-parameters-from-verifier.conf-o.patch
# https://issues.redhat.com/browse/RHEL-51321 Patch: 0009-CVE-2023-38201.patch
Patch2: 0002-Use-TLS-on-revocation-webhook.patch Patch: 0010-CVE-2023-38200.patch
Patch: 0011-Automatically-update-agent-API-version.patch
# Main program: Apache-2.0 Patch: 0012-Restore-create-allowlist.patch
# Icons: MIT Patch: 0013-Set-generator-and-timestamp-in-create-policy.patch
License: Apache-2.0 AND MIT Patch: 0014-tpm_util-Replace-a-logger.error-with-an-Exception-in.patch
License: ASL 2.0 and MIT
BuildRequires: git-core BuildRequires: git-core
BuildRequires: swig BuildRequires: swig
@ -51,26 +42,17 @@ BuildRequires: python3-dbus
BuildRequires: python3-jinja2 BuildRequires: python3-jinja2
BuildRequires: python3-setuptools BuildRequires: python3-setuptools
BuildRequires: systemd-rpm-macros BuildRequires: systemd-rpm-macros
BuildRequires: tpm2-abrmd-selinux
Requires: python3-%{srcname} = %{version}-%{release} Requires: python3-%{srcname} = %{version}-%{release}
Requires: %{srcname}-base = %{version}-%{release} Requires: %{srcname}-base = %{version}-%{release}
Requires: %{srcname}-verifier = %{version}-%{release} Requires: %{srcname}-verifier = %{version}-%{release}
Requires: %{srcname}-registrar = %{version}-%{release} Requires: %{srcname}-registrar = %{version}-%{release}
Requires: %{srcname}-tenant = %{version}-%{release} Requires: %{srcname}-tenant = %{version}-%{release}
Requires: %{srcname}-tools = %{version}-%{release}
# webapp was removed upstream in release 6.4.2.
Obsoletes: %{srcname}-webapp < 6.4.2
# python agent was removed upstream in release 7.0.0.
Obsoletes: python3-%{srcname}-agent < 7.0.0
# Agent. # Agent.
Requires: keylime-agent Requires: keylime-agent
Suggests: %{srcname}-agent-rust Suggests: keylime-agent-rust
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
%{?python_enable_dependency_generator} %{?python_enable_dependency_generator}
%description %description
@ -81,14 +63,12 @@ and runtime integrity measurement solution.
Summary: The base package contains the default configuration Summary: The base package contains the default configuration
License: MIT License: MIT
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
Requires(pre): python3-jinja2 Requires(pre): python3-jinja2
Requires(pre): shadow-utils Requires(pre): shadow-utils
Requires(pre): util-linux
Requires: procps-ng Requires: procps-ng
Requires: tpm2-tss Requires: tpm2-tss
Requires: openssl
%if 0%{?with_selinux} %if 0%{?with_selinux}
# This ensures that the *-selinux package and all its dependencies are not pulled # This ensures that the *-selinux package and all its dependencies are not pulled
@ -108,9 +88,6 @@ The base package contains the Keylime default configuration
Summary: The Python Keylime module Summary: The Python Keylime module
License: MIT License: MIT
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
Requires: %{srcname}-base = %{version}-%{release} Requires: %{srcname}-base = %{version}-%{release}
%{?python_provide:%python_provide python3-%{srcname}} %{?python_provide:%python_provide python3-%{srcname}}
@ -126,8 +103,8 @@ Requires: python3-lark-parser
Requires: python3-pyasn1 Requires: python3-pyasn1
Requires: python3-pyasn1-modules Requires: python3-pyasn1-modules
Requires: python3-jsonschema Requires: python3-jsonschema
Requires: python3-typing-extensions
Requires: tpm2-tools Requires: tpm2-tools
Requires: openssl
%description -n python3-%{srcname} %description -n python3-%{srcname}
The python3-keylime module implements the functionality used The python3-keylime module implements the functionality used
@ -137,9 +114,6 @@ by Keylime components.
Summary: The Python Keylime Verifier component Summary: The Python Keylime Verifier component
License: MIT License: MIT
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
Requires: %{srcname}-base = %{version}-%{release} Requires: %{srcname}-base = %{version}-%{release}
Requires: python3-%{srcname} = %{version}-%{release} Requires: python3-%{srcname} = %{version}-%{release}
@ -151,9 +125,6 @@ of the machine that the agent is running on.
Summary: The Keylime Registrar component Summary: The Keylime Registrar component
License: MIT License: MIT
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
Requires: %{srcname}-base = %{version}-%{release} Requires: %{srcname}-base = %{version}-%{release}
Requires: python3-%{srcname} = %{version}-%{release} Requires: python3-%{srcname} = %{version}-%{release}
@ -179,9 +150,6 @@ Custom SELinux policy module
Summary: The Python Keylime Tenant Summary: The Python Keylime Tenant
License: MIT License: MIT
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
Requires: %{srcname}-base = %{version}-%{release} Requires: %{srcname}-base = %{version}-%{release}
Requires: python3-%{srcname} = %{version}-%{release} Requires: python3-%{srcname} = %{version}-%{release}
@ -189,26 +157,13 @@ Requires: python3-%{srcname} = %{version}-%{release}
%description tenant %description tenant
The Keylime Tenant can be used to provision a Keylime Agent. The Keylime Tenant can be used to provision a Keylime Agent.
%package tools
Summary: Keylime tools
License: MIT
# Conflicts with the monolithic versions of the package, before the split.
Conflicts: keylime < 6.3.0-3
Requires: %{srcname}-base = %{version}-%{release}
Requires: python3-%{srcname} = %{version}-%{release}
%description tools
The keylime tools package includes miscelaneous tools.
%prep %prep
%autosetup -S git -n %{srcname}-%{version} -a2 %autosetup -S git -n %{srcname}-%{version} -a2
%if 0%{?with_selinux} %if 0%{?with_selinux}
# SELinux policy (originally from selinux-policy-contrib) # SELinux policy (originally from selinux-policy-contrib)
# this policy module will override the production module # this policy module will override the production module
mkdir selinux
make -f %{_datadir}/selinux/devel/Makefile %{srcname}.pp make -f %{_datadir}/selinux/devel/Makefile %{srcname}.pp
bzip2 -9 %{srcname}.pp bzip2 -9 %{srcname}.pp
@ -221,6 +176,7 @@ bzip2 -9 %{srcname}.pp
%py3_install %py3_install
mkdir -p %{buildroot}/%{_sharedstatedir}/%{srcname} mkdir -p %{buildroot}/%{_sharedstatedir}/%{srcname}
mkdir -p --mode=0700 %{buildroot}/%{_rundir}/%{srcname} mkdir -p --mode=0700 %{buildroot}/%{_rundir}/%{srcname}
mkdir -p --mode=0700 %{buildroot}/%{_localstatedir}/log/%{srcname}
mkdir -p --mode=0700 %{buildroot}/%{_sysconfdir}/%{srcname}/ mkdir -p --mode=0700 %{buildroot}/%{_sysconfdir}/%{srcname}/
for comp in "verifier" "tenant" "registrar" "ca" "logging"; do for comp in "verifier" "tenant" "registrar" "ca" "logging"; do
@ -236,8 +192,7 @@ for s in create_mb_refstate \
%{buildroot}/%{_datadir}/%{srcname}/scripts/${s} %{buildroot}/%{_datadir}/%{srcname}/scripts/${s}
done done
# To keep the same functionality as in RHEL-9, install create_runtime_policy.sh # On RHEL 9.3, install create_runtime_policy.sh as create_allowlist.sh
# as create_allowlist.sh in RHEL-10
# The convert_runtime_policy.py script to convert allowlist and excludelist into # The convert_runtime_policy.py script to convert allowlist and excludelist into
# runtime policy is not called anymore. # runtime policy is not called anymore.
# See: https://issues.redhat.com/browse/RHEL-11866 # See: https://issues.redhat.com/browse/RHEL-11866
@ -262,6 +217,7 @@ install -Dpm 644 ./services/%{srcname}_registrar.service \
%{buildroot}%{_unitdir}/%{srcname}_registrar.service %{buildroot}%{_unitdir}/%{srcname}_registrar.service
cp -r ./tpm_cert_store %{buildroot}%{_sharedstatedir}/%{srcname}/ cp -r ./tpm_cert_store %{buildroot}%{_sharedstatedir}/%{srcname}/
chmod 400 %{buildroot}%{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem
install -p -d %{buildroot}/%{_tmpfilesdir} install -p -d %{buildroot}/%{_tmpfilesdir}
cat > %{buildroot}/%{_tmpfilesdir}/%{srcname}.conf << EOF cat > %{buildroot}/%{_tmpfilesdir}/%{srcname}.conf << EOF
@ -303,15 +259,29 @@ exit 0
%post verifier %post verifier
/usr/bin/keylime_upgrade_config --component verifier >/dev/null /usr/bin/keylime_upgrade_config --component verifier >/dev/null
%systemd_post %{srcname}_verifier.service %systemd_post %{srcname}_verifier.service
exit 0
%post registrar %post registrar
/usr/bin/keylime_upgrade_config --component registrar >/dev/null /usr/bin/keylime_upgrade_config --component registrar >/dev/null
%systemd_post %{srcname}_registrar.service %systemd_post %{srcname}_registrar.service
exit 0
%post tenant %post tenant
/usr/bin/keylime_upgrade_config --component tenant >/dev/null /usr/bin/keylime_upgrade_config --component tenant >/dev/null
exit 0 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} %if 0%{?with_selinux}
# SELinux contexts are saved so that only affected files can be # SELinux contexts are saved so that only affected files can be
# relabeled after the policy module installation # relabeled after the policy module installation
@ -326,7 +296,7 @@ if [ "$1" -le "1" ]; then # First install
# The services need to be restarted for the custom label to be # The services need to be restarted for the custom label to be
# applied in case they where already present in the system, # applied in case they where already present in the system,
# restart fails silently in case they where not. # restart fails silently in case they where not.
for svc in registrar verifier; do for svc in agent registrar verifier; do
[ -f "%{_unitdir}/%{srcname}_${svc}".service ] && \ [ -f "%{_unitdir}/%{srcname}_${svc}".service ] && \
%systemd_postun_with_restart "%{srcname}_${svc}".service %systemd_postun_with_restart "%{srcname}_${svc}".service
done done
@ -340,21 +310,6 @@ if [ $1 -eq 0 ]; then
fi fi
%endif %endif
%preun verifier
%systemd_preun %{srcname}_verifier.service
%preun registrar
%systemd_preun %{srcname}_registrar.service
%preun tenant
%systemd_preun %{srcname}_registrar.service
%postun verifier
%systemd_postun_with_restart %{srcname}_verifier.service
%postun registrar
%systemd_postun_with_restart %{srcname}_registrar.service
%files verifier %files verifier
%license LICENSE %license LICENSE
%attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/verifier.conf.d %attr(500,%{srcname},%{srcname}) %dir %{_sysconfdir}/%{srcname}/verifier.conf.d
@ -392,11 +347,7 @@ fi
%{_bindir}/keylime_convert_runtime_policy %{_bindir}/keylime_convert_runtime_policy
%{_bindir}/keylime_create_policy %{_bindir}/keylime_create_policy
%{_bindir}/keylime_sign_runtime_policy %{_bindir}/keylime_sign_runtime_policy
%{_bindir}/keylime_userdata_encrypt
%files tools
%license LICENSE
%{_bindir}/%{srcname}_userdata_encrypt
%files base %files base
%license LICENSE %license LICENSE
@ -405,6 +356,7 @@ fi
%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}/ca.conf
%config(noreplace) %verify(not md5 size mode mtime) %attr(400,%{srcname},%{srcname}) %{_sysconfdir}/%{srcname}/logging.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 %{_rundir}/%{srcname}
%attr(700,%{srcname},%{srcname}) %dir %{_localstatedir}/log/%{srcname}
%attr(700,%{srcname},%{srcname}) %dir %{_sharedstatedir}/%{srcname} %attr(700,%{srcname},%{srcname}) %dir %{_sharedstatedir}/%{srcname}
%attr(500,%{srcname},%{srcname}) %dir %{_sharedstatedir}/%{srcname}/tpm_cert_store %attr(500,%{srcname},%{srcname}) %dir %{_sharedstatedir}/%{srcname}/tpm_cert_store
%attr(400,%{srcname},%{srcname}) %{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem %attr(400,%{srcname},%{srcname}) %{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem
@ -419,198 +371,120 @@ fi
%license LICENSE %license LICENSE
%changelog %changelog
## START: Generated by rpmautospec * Fri Jan 05 2024 Sergio Correia <scorreia@redhat.com> - 7.3.0-13
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 7.9.0-8 - Backport fix for CVE-2023-3674
- Bump release for October 2024 mass rebuild: Resolves: RHEL-21013
* Mon Aug 19 2024 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.9.0-7 * Tue Oct 17 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-12
- Use TLS on revocation notification webhook - Set the generator and timestamp in create_policy.py
- Include system installed CA certificates when verifying webhook server Related: RHEL-11866
certificate
- Include the CA certificates added via configuration file option * Mon Oct 09 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-11
'trusted_server_ca' - Suppress unnecessary error message
Related: RHEL-11866
* Fri Aug 16 2024 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.9.0-6
- Restore create_allowlist.sh to be the same as in RHEL-9 * Fri Oct 06 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-10
- Restore allowlist generation script
* Mon Jun 24 2024 Karel Srot <ksrot@redhat.com> - 7.9.0-5 Resolves: RHEL-11866
- Add rhel-10 gating.yaml Resolves: RHEL-11867
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 7.9.0-4 * Wed Sep 06 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-9
- Bump release for June 2024 mass rebuild - Rebuild for properly tagging the resulting build
Resolves: RHEL-1898
* Thu May 09 2024 Karel Srot <ksrot@redhat.com> - 7.9.0-3
- tests: Update CI test plan for C10S * Fri Sep 01 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-8
- Add missing dependencies python3-jinja2 and util-linux
* Mon Feb 12 2024 Sergio Correia <scorreia@redhat.com> - 7.9.0-2 Resolves: RHEL-1898
- Fixes for rawhide
* Mon Aug 28 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-7
* Tue Jan 30 2024 Sergio Correia <scorreia@redhat.com> - 7.9.0-1 - Automatically update agent API version
- Updating for Keylime release v7.9.0 Resolves: RHEL-1518
- Migrated license to SPDX
* Mon Aug 28 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-6
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 7.8.0-3 - Fix registrar is subject to a DoS against SSL (CVE-2023-38200)
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild Resolves: rhbz#2222694
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 7.8.0-2 * Fri Aug 25 2023 Anderson Toshiyuki Sasaki <ansasaki@redhat.com> - 7.3.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - Fix challenge-protocol bypass during agent registration (CVE-2023-38201)
Resolves: rhbz#2222695
* Tue Dec 05 2023 Sergio Correia <scorreia@redhat.com> - 7.8.0-1
- Updating for Keylime release v7.8.0 * 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
* Thu Nov 02 2023 Sergio Correia <scorreia@redhat.com> - 7.7.0-1 Resolves: RHEL-475
- Updating for Keylime release v7.7.0
* Tue Aug 15 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-3
* Thu Aug 24 2023 Sergio Correia <scorreia@redhat.com> - 7.5.0-1 - Fix Keylime configuration upgrades issues introduced in last rebase
- Updating for Keylime release v7.5.0 Resolves: RHEL-475
- Handle session close using a session manager
* Mon Jul 31 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-1 Resolves: RHEL-1252
- Updating for Keylime release v7.3.0 - Add ignores for EV_PLATFORM_CONFIG_FLAGS
Resolves: RHEL-947
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 7.2.5-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild * Tue Aug 8 2023 Patrik Koncity <pkoncity@redhat.com> - 7.3.0-2
- Keylime SELinux policy provides more restricted ports.
* Thu Jun 15 2023 Python Maint <python-maint@redhat.com> - 7.2.5-3 - New SELinux label for ports used by keylime.
- Rebuilt for Python 3.12 - Adding tabrmd interfaces allow unix stream socket communication and dbus communication.
- Allow the keylime_server_t domain to get the attributes of all filesystems.
* Tue Jun 06 2023 Sergio Correia <scorreia@redhat.com> - 7.2.5-2 Resolves: RHEL-595
- Update test plan Resolves: RHEL-390
Resolves: RHEL-948
* Mon Jun 05 2023 Sergio Correia <scorreia@redhat.com> - 7.2.5-1
- Updating for Keylime release v7.2.5 * Wed Jul 19 2023 Sergio Correia <scorreia@redhat.com> - 7.3.0-1
- Update to 7.3.0
* Fri Feb 03 2023 Sergio Correia <scorreia@redhat.com> - 6.6.0-1 Resolves: RHEL-475
- Updating for Keylime release v6.6.0
* Fri Jan 13 2023 Sergio Correia <scorreia@redhat.com> - 6.5.2-4
* Wed Jan 25 2023 Sergio Correia <scorreia@redhat.com> - 6.5.3-2 - Backport upstream PR#1240 - logging: remove option to log into separate file
- e2e tests: do not change the tpm hash alg to sha256 Resolves: rhbz#2154584 - keylime verifier is not logging to /var/log/keylime
* Wed Jan 25 2023 Sergio Correia <scorreia@redhat.com> - 6.5.3-1 * Thu Dec 1 2022 Sergio Correia <scorreia@redhat.com> - 6.5.2-3
- Updating for Keylime release v6.5.3 - Remove leftover policy file
Related: rhbz#2152135
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 6.4.3-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild * Thu Dec 1 2022 Patrik Koncity <pkoncity@redhat.com> - 6.5.2-2
- Use keylime selinux policy from upstream.
* Mon Dec 12 2022 Karel Srot <ksrot@redhat.com> - 6.4.3-7 Resolves: rhbz#2152135
- Ignore non-keylime AVCs on Fedora Rawhide
* Mon Nov 14 2022 Sergio Correia <scorreia@redhat.com> - 6.5.2-1
* Fri Dec 09 2022 Sergio Correia <scorreia@redhat.com> - 6.4.3-6 - Update to 6.5.2
- Proper exception handling in tornado_requests Resolves: CVE-2022-3500
Resolves: rhbz#2138167 - agent fails IMA attestation when one scripts is executed quickly after the other
* Fri Dec 09 2022 Sergio Correia <scorreia@redhat.com> - 6.4.3-5 Resolves: rhbz#2140670 - Segmentation fault in /usr/share/keylime/create_mb_refstate script
- Do not remove tag-repository.repo Resolves: rhbz#142009 - Registrar may crash during EK validation when require_ek_cert is enabled
* Thu Dec 01 2022 Karel Srot <ksrot@redhat.com> - 6.4.3-4 * Tue Sep 13 2022 Sergio Correia <scorreia@redhat.com> - 6.5.0-1
- Add dynamic_ref reference to e2e_tests.fmf - Update to 6.5.0
Resolves: rhbz#2120686 - Keylime configuration is too complex
* Tue Oct 25 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.3-3
- Add keylime selinux policy as subpackage and update CI * Fri Aug 26 2022 Sergio Correia <scorreia@redhat.com> - 6.4.3-1
- Update to 6.4.3
* Wed Sep 14 2022 Sergio Correia <scorreia@redhat.com> - 6.4.3-2 Resolves: rhbz#2121044 - Error parsing EK ASN.1 certificate of Nuvoton HW TPM
- Update tests branch to fedora-main
* Fri Aug 26 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-6
* Thu Aug 25 2022 Sergio Correia <scorreia@redhat.com> - 6.4.3-1 - Update keylime SELinux policy
- Updating for Keylime release v6.4.3 - Resolves: rhbz#2121058
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 6.4.2-4 * Fri Aug 26 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - Update keylime SELinux policy and removed duplicate rules
- Resolves: rhbz#2121058
* Mon Jul 11 2022 Sergio Correia <scorreia@redhat.com> - 6.4.2-3
- Wrap efivar-libs dependency in a "ifarch %%efi" * Fri Aug 26 2022 Patrik Koncity <pkoncity@redhat.com> - 6.4.2-4
- Update keylime SELinux policy
* Fri Jul 08 2022 Sergio Correia <scorreia@redhat.com> - 6.4.2-2 - 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 - Fix efivar-libs dependency
- Some arches do not have efivar-libs, so let's require it conditionally. Related: rhbz#2082989
* Fri Jul 08 2022 Sergio Correia <scorreia@redhat.com> - 6.4.2-1
- Updating for Keylime release v6.4.2
- Remove keylime-webapp and mark package as obsolete
- Configure tmpfiles.d
- Move common python dependencies to python3-keylime
- Change dependency from python3-gnupg to python3-gpg
- Use sysusers.d for handling user creation
* Fri Jul 08 2022 Sergio Correia <scorreia@redhat.com> - 6.4.1-4
- Adjust Fedora CI test plan as per upstream
* Thu Jul 07 2022 Sergio Correia <scorreia@redhat.com> - 6.4.1-3
- Opt in to rpmautospec
* Mon Jun 13 2022 Python Maint <python-maint@redhat.com> - 6.4.1-2
- Rebuilt for Python 3.11
* Mon Jun 06 2022 Sergio Correia <scorreia@redhat.com> - 6.4.1-1
- Updating for Keylime release v6.4.1
* Wed May 04 2022 Sergio Correia <scorreia@redhat.com> - 6.4.0-1
- Updating for Keylime release v6.4.0
* Wed Apr 06 2022 Sergio Correia <scorreia@redhat.com> - 6.3.2-1
- Updating for Keylime release v6.3.2
* Mon Feb 14 2022 Sergio Correia <scorreia@redhat.com> - 6.3.1-1
- Updating for Keylime release v6.3.1
* Tue Feb 08 2022 Sergio Correia <scorreia@redhat.com> - 6.0.3-4
- Add Conflicts clauses for the subpackages
* Mon Feb 07 2022 Sergio Correia <scorreia@redhat.com> - 6.3.0-3
- Split keylime into subpackages
Related: rhbz#2045874 - Keylime subpackaging and agent alternatives
* Thu Jan 27 2022 Sergio Correia <scorreia@redhat.com> - 6.3.0-2
- Fix permissions of config file
* Thu Jan 27 2022 Sergio Correia <scorreia@redhat.com> - 6.3.0-1
- Updating for Keylime release v6.3.0
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 6.1.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 6.1.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Fri Jun 04 2021 Python Maint <python-maint@redhat.com> - 6.1.0-3
- Rebuilt for Python 3.10
* Thu Mar 25 2021 Luke Hinds <lhinds@redhat.com> 6.0.1-1
- Updating for Keylime release v6.1.0
* Wed Mar 03 2021 Luke Hinds <lhinds@redhat.com> 6.0.1-1
- Updating for Keylime release v6.0.1
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 6.0.0-2
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Wed Feb 24 2021 Luke Hinds <lhinds@redhat.com> 6.0.0-1
- Updating for Keylime release v6.0.0
* Tue Feb 02 2021 Luke Hinds <lhinds@redhat.com> 5.8.1-1
- Updating for Keylime release v5.8.1
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 5.8.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Sat Jan 23 2021 Luke Hinds <lhinds@redhat.com> 5.8.0-1
- Updating for Keylime release v5.8.0
* Fri Jul 17 2020 Luke Hinds <lhinds@redhat.com> 5.7.2-1
- Updating for Keylime release v5.7.2
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 5.6.2-2
- Rebuilt for Python 3.9
* Fri May 01 2020 Luke Hinds <lhinds@redhat.com> 5.6.2-1
- Updating for Keylime release v5.6.2
* Thu Feb 06 2020 Luke Hinds <lhinds@redhat.com> 5.5.0-1
- Updating for Keylime release v5.5.0
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 5.4.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Dec 12 2019 Luke Hinds <lhinds@redhat.com> 5.4.1-1 * Thu Jul 07 2022 Sergio Correia <scorreia@redhat.com> - 6.4.2-1
Initial Packaging - Update to 6.4.2
Related: rhbz#2082989
## END: Generated by rpmautospec * Tue Jun 21 2022 Sergio Correia <scorreia@redhat.com> - 6.4.1-1
- Add keylime to RHEL-9
Resolves: rhbz#2082989

Loading…
Cancel
Save