2024-07-01 17:41:03 +08:00
|
|
|
From a73dd3e60daf96ee2519495bce2c7d62134e582f Mon Sep 17 00:00:00 2001
|
2020-07-14 09:04:38 +02:00
|
|
|
From: Roberto Sassu <roberto.sassu@huawei.com>
|
|
|
|
|
Date: Wed, 26 Feb 2020 15:54:24 +0100
|
2024-07-01 17:41:03 +08:00
|
|
|
Subject: [PATCH] Add digest list plugin
|
2020-07-14 09:04:38 +02:00
|
|
|
|
2024-07-01 17:41:03 +08:00
|
|
|
Add RPM plugin for IMA digest list uploading and removing.
|
|
|
|
|
|
|
|
|
|
v1:
|
|
|
|
|
call process_digest_list after files are added
|
|
|
|
|
|
|
|
|
|
v2:
|
|
|
|
|
fix lsetxattr error in container
|
|
|
|
|
The digest list plugin in rpm will set security.ima xattr to IMA digest lists
|
|
|
|
|
when installing or updating an rpm package. However, in a container without
|
|
|
|
|
CAP_SYS_ADMIN, we'll get error messages when calling lsetxattr.
|
|
|
|
|
|
|
|
|
|
v3:
|
|
|
|
|
Add license to digest_list.c
|
|
|
|
|
|
|
|
|
|
v4:
|
|
|
|
|
Check rpm parser
|
|
|
|
|
|
|
|
|
|
v5:
|
|
|
|
|
fix lsetxattr error in container
|
|
|
|
|
The digest list plugin in rpm will set security.ima xattr to IMA digest lists
|
|
|
|
|
when installing or updating an rpm package. However, in a container without
|
|
|
|
|
CAP_SYS_ADMIN, we'll get error messages when calling lsetxattr.
|
|
|
|
|
This patch is to skip lsetxattr when CAP_SYS_ADMIN is missing.
|
|
|
|
|
|
|
|
|
|
v6:
|
|
|
|
|
call process_digest_list after files are added
|
|
|
|
|
|
|
|
|
|
v7:
|
|
|
|
|
dont remove ima xattr of parser when upgrading
|
|
|
|
|
|
|
|
|
|
v8:
|
|
|
|
|
support add the signature within a IMA header
|
|
|
|
|
|
|
|
|
|
Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
|
2020-07-14 09:04:38 +02:00
|
|
|
---
|
|
|
|
|
macros.in | 1 +
|
|
|
|
|
plugins/Makefile.am | 4 +
|
2024-07-01 17:41:03 +08:00
|
|
|
plugins/digest_list.c | 624 ++++++++++++++++++++++++++++++++++++++++++
|
2020-07-24 00:06:48 +02:00
|
|
|
rpmio/digest.h | 1 +
|
|
|
|
|
rpmio/rpmpgp.c | 3 +
|
2024-07-01 17:41:03 +08:00
|
|
|
5 files changed, 633 insertions(+)
|
2020-07-14 09:04:38 +02:00
|
|
|
create mode 100644 plugins/digest_list.c
|
|
|
|
|
|
|
|
|
|
diff --git a/macros.in b/macros.in
|
2024-07-01 17:41:03 +08:00
|
|
|
index 4531fcb..643b02b 100644
|
2020-07-14 09:04:38 +02:00
|
|
|
--- a/macros.in
|
|
|
|
|
+++ b/macros.in
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -1150,6 +1150,7 @@ package or when debugging this package.\
|
2020-07-14 09:04:38 +02:00
|
|
|
%__transaction_prioreset %{__plugindir}/prioreset.so
|
|
|
|
|
%__transaction_audit %{__plugindir}/audit.so
|
2021-12-21 17:39:32 +08:00
|
|
|
%__transaction_dbus_announce %{__plugindir}/dbus_announce.so
|
2020-07-14 09:04:38 +02:00
|
|
|
+%__transaction_digest_list %{__plugindir}/digest_list.so
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Macros for further automated spec %setup and patch application
|
|
|
|
|
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
|
2024-07-01 17:41:03 +08:00
|
|
|
index 3a929d0..fd9be81 100644
|
2020-07-14 09:04:38 +02:00
|
|
|
--- a/plugins/Makefile.am
|
|
|
|
|
+++ b/plugins/Makefile.am
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -69,3 +69,7 @@ audit_la_sources = audit.c
|
2020-07-14 09:04:38 +02:00
|
|
|
audit_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @WITH_AUDIT_LIB@
|
|
|
|
|
plugins_LTLIBRARIES += audit.la
|
|
|
|
|
endif
|
|
|
|
|
+
|
|
|
|
|
+digest_list_la_sources = digest_list.c
|
|
|
|
|
+digest_list_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
|
|
|
|
|
+plugins_LTLIBRARIES += digest_list.la
|
|
|
|
|
diff --git a/plugins/digest_list.c b/plugins/digest_list.c
|
|
|
|
|
new file mode 100644
|
2024-07-01 17:41:03 +08:00
|
|
|
index 0000000..c1864c7
|
2020-07-14 09:04:38 +02:00
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/plugins/digest_list.c
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -0,0 +1,624 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * Copyright (C) 2020-2021 Huawei Technologies Duesseldorf GmbH
|
|
|
|
|
+ *
|
|
|
|
|
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
|
|
|
|
|
+ *
|
|
|
|
|
+ * This program is free software; you can redistribute it and/or
|
|
|
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
|
|
|
+ * published by the Free Software Foundation, version 2 of the
|
|
|
|
|
+ * License.
|
|
|
|
|
+ *
|
|
|
|
|
+ * File: digest_list.c
|
|
|
|
|
+ * Plugin to load digest lists in the Linux kernel.
|
|
|
|
|
+ */
|
|
|
|
|
+
|
2020-07-14 09:04:38 +02:00
|
|
|
+#include "system.h"
|
|
|
|
|
+#include "errno.h"
|
|
|
|
|
+
|
2021-12-21 17:39:32 +08:00
|
|
|
+#include <fcntl.h>
|
2020-07-14 09:04:38 +02:00
|
|
|
+#include <rpm/rpmlog.h>
|
|
|
|
|
+#include <rpm/rpmts.h>
|
|
|
|
|
+#include <rpm/header.h>
|
2020-07-24 00:06:48 +02:00
|
|
|
+#include <rpmio/digest.h>
|
|
|
|
|
+#include <rpmio/rpmpgp.h>
|
2020-07-14 09:04:38 +02:00
|
|
|
+#include <rpm/rpmfileutil.h>
|
|
|
|
|
+#include "lib/rpmplugin.h"
|
2020-07-24 00:06:48 +02:00
|
|
|
+#include <netinet/in.h>
|
2020-07-14 09:04:38 +02:00
|
|
|
+#include <sys/stat.h>
|
|
|
|
|
+#include <openssl/sha.h>
|
|
|
|
|
+#include <sys/xattr.h>
|
2024-07-01 17:41:03 +08:00
|
|
|
+#include <sys/capability.h>
|
2020-07-14 09:04:38 +02:00
|
|
|
+#include <linux/xattr.h>
|
|
|
|
|
+#include <asm/byteorder.h>
|
|
|
|
|
+#include <sys/wait.h>
|
|
|
|
|
+
|
|
|
|
|
+#include "debug.h"
|
|
|
|
|
+
|
|
|
|
|
+#define IMA_DIR "/sys/kernel/security/ima"
|
|
|
|
|
+#define DIGEST_LIST_DATA_PATH IMA_DIR "/digest_list_data"
|
|
|
|
|
+#define DIGEST_LIST_DATA_DEL_PATH IMA_DIR "/digest_list_data_del"
|
|
|
|
|
+#define DIGEST_LIST_COUNT IMA_DIR "/digests_count"
|
|
|
|
|
+#define DIGEST_LIST_DEFAULT_PATH "/etc/ima/digest_lists"
|
|
|
|
|
+#define RPM_PARSER "/usr/libexec/rpm_parser"
|
|
|
|
|
+
|
|
|
|
|
+enum hash_algo {
|
|
|
|
|
+ HASH_ALGO_MD4,
|
|
|
|
|
+ HASH_ALGO_MD5,
|
|
|
|
|
+ HASH_ALGO_SHA1,
|
|
|
|
|
+ HASH_ALGO_RIPE_MD_160,
|
|
|
|
|
+ HASH_ALGO_SHA256,
|
|
|
|
|
+ HASH_ALGO_SHA384,
|
|
|
|
|
+ HASH_ALGO_SHA512,
|
|
|
|
|
+ HASH_ALGO_SHA224,
|
|
|
|
|
+ HASH_ALGO_RIPE_MD_128,
|
|
|
|
|
+ HASH_ALGO_RIPE_MD_256,
|
|
|
|
|
+ HASH_ALGO_RIPE_MD_320,
|
|
|
|
|
+ HASH_ALGO_WP_256,
|
|
|
|
|
+ HASH_ALGO_WP_384,
|
|
|
|
|
+ HASH_ALGO_WP_512,
|
|
|
|
|
+ HASH_ALGO_TGR_128,
|
|
|
|
|
+ HASH_ALGO_TGR_160,
|
|
|
|
|
+ HASH_ALGO_TGR_192,
|
|
|
|
|
+ HASH_ALGO_SM3_256,
|
|
|
|
|
+ HASH_ALGO__LAST
|
|
|
|
|
+};
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+#define PGPHASHALGO__LAST PGPHASHALGO_SHA224 + 1
|
|
|
|
|
+enum hash_algo pgp_algo_mapping[PGPHASHALGO__LAST] = {
|
|
|
|
|
+ [PGPHASHALGO_MD5] = HASH_ALGO_MD5,
|
|
|
|
|
+ [PGPHASHALGO_SHA1] = HASH_ALGO_SHA1,
|
|
|
|
|
+ [PGPHASHALGO_SHA224] = HASH_ALGO_SHA224,
|
|
|
|
|
+ [PGPHASHALGO_SHA256] = HASH_ALGO_SHA256,
|
|
|
|
|
+ [PGPHASHALGO_SHA384] = HASH_ALGO_SHA384,
|
|
|
|
|
+ [PGPHASHALGO_SHA512] = HASH_ALGO_SHA512,
|
2020-07-14 09:04:38 +02:00
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* from integrity.h */
|
|
|
|
|
+enum evm_ima_xattr_type {
|
|
|
|
|
+ IMA_XATTR_DIGEST = 0x01,
|
|
|
|
|
+ EVM_XATTR_HMAC,
|
|
|
|
|
+ EVM_IMA_XATTR_DIGSIG,
|
|
|
|
|
+ IMA_XATTR_DIGEST_NG,
|
|
|
|
|
+ EVM_XATTR_PORTABLE_DIGSIG,
|
|
|
|
|
+ EVM_IMA_XATTR_DIGEST_LIST,
|
|
|
|
|
+ IMA_XATTR_LAST
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+struct evm_ima_xattr_data {
|
|
|
|
|
+ uint8_t type;
|
|
|
|
|
+ uint8_t digest[SHA512_DIGEST_LENGTH + 1];
|
|
|
|
|
+} __attribute__((packed));
|
|
|
|
|
+
|
|
|
|
|
+struct signature_v2_hdr {
|
|
|
|
|
+ uint8_t type; /* xattr type */
|
|
|
|
|
+ uint8_t version; /* signature format version */
|
|
|
|
|
+ uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */
|
|
|
|
|
+ __be32 keyid; /* IMA key identifier - not X509/PGP specific */
|
|
|
|
|
+ __be16 sig_size; /* signature size */
|
|
|
|
|
+ uint8_t sig[0]; /* signature payload */
|
|
|
|
|
+} __attribute__((packed));
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+static int digest_list_count_is_zero(void)
|
2020-07-14 09:04:38 +02:00
|
|
|
+{
|
2024-07-01 17:41:03 +08:00
|
|
|
+ int fd = 0, ret = 0;
|
|
|
|
|
+ char first = 0;
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
|
|
|
|
+ fd = open(DIGEST_LIST_COUNT, O_RDONLY);
|
|
|
|
|
+ if (fd < 0) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not open IMA interface "
|
|
|
|
|
+ "'%s': %s\n", DIGEST_LIST_COUNT, strerror(errno));
|
|
|
|
|
+ return -EACCES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ ret = read(fd, &first, 1);
|
2020-07-14 09:04:38 +02:00
|
|
|
+ if (ret <= 0) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not read from IMA "
|
|
|
|
|
+ "interface '%s': %s\n", DIGEST_LIST_COUNT,
|
|
|
|
|
+ strerror(errno));
|
2024-07-01 17:41:03 +08:00
|
|
|
+ close(fd);
|
2020-07-14 09:04:38 +02:00
|
|
|
+ return -EACCES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ close(fd);
|
2024-08-16 12:00:53 +08:00
|
|
|
+ return (first == '0');
|
2024-07-01 17:41:03 +08:00
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int upload_digest_list(char *path, int type, int digest_list_signed)
|
|
|
|
|
+{
|
|
|
|
|
+ int ret = 0, fd = 0;
|
|
|
|
|
+ pid_t pid = 0;
|
|
|
|
|
+ size_t size = 0;
|
|
|
|
|
+ struct stat st;
|
|
|
|
|
+ const char *ima_path = NULL;
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ ima_path = (type == TR_REMOVED) ? DIGEST_LIST_DATA_DEL_PATH :
|
|
|
|
|
+ DIGEST_LIST_DATA_PATH;
|
|
|
|
|
+ if (stat(ima_path, &st) == -1) {
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: '%s' interface "
|
|
|
|
|
+ "not exist\n", ima_path);
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ /* First determine if kernel interface can accept new digest lists */
|
|
|
|
|
+ if (digest_list_count_is_zero()) {
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: the count is 0, not "
|
|
|
|
|
+ "upload '%s' to IMA interface '%s'\n", path, ima_path);
|
2020-07-14 09:04:38 +02:00
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* If the digest list is not signed, execute the RPM parser */
|
|
|
|
|
+ if (!digest_list_signed) {
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (stat(RPM_PARSER, &st) == -1) {
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: %s not found, "
|
|
|
|
|
+ "not uploading digest list\n", RPM_PARSER);
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2020-07-14 09:04:38 +02:00
|
|
|
+ if ((pid = fork()) == 0) {
|
|
|
|
|
+ execlp(RPM_PARSER, RPM_PARSER, (type == TR_ADDED) ?
|
|
|
|
|
+ "add" : "del", path, NULL);
|
|
|
|
|
+ _exit(EXIT_FAILURE);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ waitpid(pid, &ret, 0);
|
|
|
|
|
+ if (ret != 0)
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: %s returned %d\n",
|
|
|
|
|
+ RPM_PARSER, ret);
|
2024-07-01 17:41:03 +08:00
|
|
|
+ return RPMRC_OK;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ /* If the digest list is signed, write path to the IMA interface */
|
2020-07-14 09:04:38 +02:00
|
|
|
+ fd = open(ima_path, O_WRONLY);
|
|
|
|
|
+ if (fd < 0) {
|
2024-07-01 17:41:03 +08:00
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: rcould not open IMA interface "
|
2020-07-14 09:04:38 +02:00
|
|
|
+ "'%s': %s\n", ima_path, strerror(errno));
|
|
|
|
|
+ return -EACCES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Write the path of the digest list to securityfs */
|
|
|
|
|
+ size = write(fd, path, strlen(path));
|
|
|
|
|
+ if (size != strlen(path)) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not write '%s' to IMA "
|
|
|
|
|
+ "interface '%s': %s\n", path, ima_path, strerror(errno));
|
|
|
|
|
+ ret = -EIO;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: written '%s' to '%s'\n", path,
|
|
|
|
|
+ ima_path);
|
|
|
|
|
+out:
|
|
|
|
|
+ close(fd);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static int write_rpm_digest_list(rpmte te, char *path)
|
|
|
|
|
+{
|
|
|
|
|
+ FD_t fd;
|
|
|
|
|
+ int ret = 0;
|
2024-07-01 17:41:03 +08:00
|
|
|
+ ssize_t written = 0;
|
|
|
|
|
+ Header rpm = rpmteHeader(te);
|
|
|
|
|
+ rpmtd immutable = rpmtdNew();
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
|
|
|
|
+ headerGet(rpm, RPMTAG_HEADERIMMUTABLE, immutable, 0);
|
|
|
|
|
+
|
|
|
|
|
+ fd = Fopen(path, "w.ufdio");
|
|
|
|
|
+ if (fd == NULL || Ferror(fd)) {
|
|
|
|
|
+ ret = -EACCES;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ written = Fwrite(rpm_header_magic, sizeof(uint8_t),
|
|
|
|
|
+ sizeof(rpm_header_magic), fd);
|
|
|
|
|
+ if (written != sizeof(rpm_header_magic)) {
|
|
|
|
|
+ ret = -EIO;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ written = Fwrite(immutable->data, sizeof(uint8_t),
|
|
|
|
|
+ immutable->count, fd);
|
|
|
|
|
+ if (written != immutable->count || Ferror(fd))
|
|
|
|
|
+ ret = -EIO;
|
|
|
|
|
+out:
|
|
|
|
|
+ Fclose(fd);
|
|
|
|
|
+ rpmtdFree(immutable);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+static int write_rpm_digest_list_ima_xattr(rpmte te, char *path)
|
2020-07-14 09:04:38 +02:00
|
|
|
+{
|
2024-07-01 17:41:03 +08:00
|
|
|
+ FD_t fd;
|
|
|
|
|
+ ssize_t written = 0;
|
|
|
|
|
+ int ret = 0, sig_size = 0, sig_size_rounded = 0;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ uint8_t sig[2048] = { 0 };
|
|
|
|
|
+ pgpDigParams sigp = NULL;
|
|
|
|
|
+ struct signature_v2_hdr *sig_hdr = (struct signature_v2_hdr *)sig;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ Header rpm = rpmteHeader(te);
|
2024-07-01 17:41:03 +08:00
|
|
|
+ rpmtd signature = rpmtdNew();
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
|
|
|
|
+ headerGet(rpm, RPMTAG_RSAHEADER, signature, 0);
|
2020-07-24 00:06:48 +02:00
|
|
|
+ ret = pgpPrtParams(signature->data, signature->count,
|
|
|
|
|
+ PGPTAG_SIGNATURE, &sigp);
|
|
|
|
|
+ if (ret) {
|
|
|
|
|
+ ret = -ENOENT;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ goto out;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ fd = Fopen(path, "a.ufdio");
|
2020-07-14 09:04:38 +02:00
|
|
|
+ if (fd == NULL || Ferror(fd)) {
|
|
|
|
|
+ ret = -EACCES;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ written = Fwrite(sigp->hash, sizeof(uint8_t),
|
|
|
|
|
+ sigp->hashlen, fd);
|
|
|
|
|
+ if (written != sigp->hashlen || Ferror(fd)) {
|
2020-07-14 09:04:38 +02:00
|
|
|
+ ret = -EIO;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (sigp->version == 4) {
|
|
|
|
|
+ /* V4 trailer is six octets long (rfc4880) */
|
|
|
|
|
+ uint8_t trailer[6];
|
|
|
|
|
+ uint32_t nb = sigp->hashlen;
|
|
|
|
|
+ nb = htonl(nb);
|
|
|
|
|
+ trailer[0] = sigp->version;
|
|
|
|
|
+ trailer[1] = 0xff;
|
|
|
|
|
+ memcpy(trailer+2, &nb, 4);
|
|
|
|
|
+
|
|
|
|
|
+ written = Fwrite(trailer, sizeof(uint8_t), sizeof(trailer), fd);
|
|
|
|
|
+ if (written != sizeof(trailer) || Ferror(fd)) {
|
|
|
|
|
+ ret = -EIO;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Fclose(fd);
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ sig_hdr->type = EVM_IMA_XATTR_DIGSIG;
|
|
|
|
|
+ sig_hdr->version = 2;
|
|
|
|
|
+ sig_hdr->hash_algo = pgp_algo_mapping[sigp->hash_algo];
|
|
|
|
|
+ memcpy((void *)&sig_hdr->keyid, sigp->signid + sizeof(uint32_t),
|
|
|
|
|
+ sizeof(uint32_t));
|
|
|
|
|
+
|
|
|
|
|
+ sig_size = (pgpMpiBits(sigp->data) + 7) >> 3;
|
|
|
|
|
+ if (sizeof(sig_hdr) + sig_size > sizeof(sig)) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR,
|
|
|
|
|
+ "digest_list: signature in %s too big\n", path);
|
|
|
|
|
+ ret = -E2BIG;
|
|
|
|
|
+ goto out;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ sig_size_rounded = ((sig_size + 7) >> 3) * 8;
|
|
|
|
|
+ sig_hdr->sig_size = __cpu_to_be16(sig_size_rounded);
|
|
|
|
|
+
|
|
|
|
|
+ memcpy(sig_hdr->sig + sig_size_rounded - sig_size,
|
|
|
|
|
+ (uint8_t *)sigp->data + 2, sig_size);
|
|
|
|
|
+
|
|
|
|
|
+ ret = lsetxattr(path, XATTR_NAME_IMA,
|
|
|
|
|
+ sig, sizeof(*sig_hdr) + sig_size_rounded, 0);
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not apply security.ima "
|
|
|
|
|
+ "on '%s': %s\n", path, strerror(errno));
|
|
|
|
|
+ else
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima successfully "
|
|
|
|
|
+ "applied on '%s'\n", path);
|
2020-07-14 09:04:38 +02:00
|
|
|
+out:
|
2020-07-24 00:06:48 +02:00
|
|
|
+ pgpDigParamsFree(sigp);
|
|
|
|
|
+ rpmtdFree(signature);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+static int fill_pgp_signature_header(rpmte te, struct signature_v2_hdr *sig_hdr)
|
2020-07-24 00:06:48 +02:00
|
|
|
+{
|
2024-07-01 17:41:03 +08:00
|
|
|
+ int ret = 0;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ pgpDigParams sigp = NULL;
|
|
|
|
|
+ Header rpm = rpmteHeader(te);
|
2024-07-01 17:41:03 +08:00
|
|
|
+ rpmtd signature = rpmtdNew();
|
2020-07-24 00:06:48 +02:00
|
|
|
+
|
|
|
|
|
+ headerGet(rpm, RPMTAG_RSAHEADER, signature, 0);
|
|
|
|
|
+ ret = pgpPrtParams(signature->data, signature->count,
|
|
|
|
|
+ PGPTAG_SIGNATURE, &sigp);
|
|
|
|
|
+ if (ret) {
|
|
|
|
|
+ ret = -ENOENT;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sig_hdr->type = EVM_IMA_XATTR_DIGSIG;
|
|
|
|
|
+ sig_hdr->version = 2;
|
|
|
|
|
+ sig_hdr->hash_algo = HASH_ALGO_SHA256;
|
|
|
|
|
+ memcpy((void *)&sig_hdr->keyid, sigp->signid + sizeof(uint32_t),
|
|
|
|
|
+ sizeof(uint32_t));
|
2024-07-01 17:41:03 +08:00
|
|
|
+out:
|
|
|
|
|
+ pgpDigParamsFree(sigp);
|
|
|
|
|
+ rpmtdFree(signature);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
2020-07-24 00:06:48 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+static int write_digest_list_ima_xattr(rpmte te, char *path, char *path_sig)
|
|
|
|
|
+{
|
|
|
|
|
+ FD_t fd;
|
|
|
|
|
+ struct stat st;
|
|
|
|
|
+ int ret = 0, sig_size, hdr_exist;
|
|
|
|
|
+ uint8_t sig[2048] = { 0 };
|
|
|
|
|
+ struct signature_v2_hdr *sig_hdr = (struct signature_v2_hdr *)sig;
|
|
|
|
|
+
|
|
|
|
|
+ if (stat(path_sig, &st) == -1)
|
|
|
|
|
+ return -EACCES;
|
|
|
|
|
+
|
|
|
|
|
+ /* Check if the signature has already included a header */
|
|
|
|
|
+ hdr_exist = (sig_size - sizeof(sig_hdr) % 128) == 0 ? 0 : 1;
|
|
|
|
|
+ if (!hdr_exist) {
|
|
|
|
|
+ ret = fill_pgp_signature_header(te, sig_hdr);
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ return ret;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (sizeof(sig_hdr) + st.st_size > sizeof(sig)) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: signature in %s too big\n",
|
|
|
|
|
+ path);
|
2024-07-01 17:41:03 +08:00
|
|
|
+ return -E2BIG;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fd = Fopen(path_sig, "r.ufdio");
|
|
|
|
|
+ if (fd < 0) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not open '%s': %s\n",
|
|
|
|
|
+ path_sig, strerror(errno));
|
2024-07-01 17:41:03 +08:00
|
|
|
+ return -EACCES;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sig_size = Fread(sig_hdr->sig, sizeof(uint8_t), st.st_size, fd);
|
|
|
|
|
+ if (sig_size != st.st_size || Ferror(fd)) {
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not read '%s': %s\n",
|
|
|
|
|
+ path_sig, strerror(errno));
|
|
|
|
|
+ Fclose(fd);
|
2024-07-01 17:41:03 +08:00
|
|
|
+ return -EIO;
|
2020-07-24 00:06:48 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ sig_hdr->sig_size = __cpu_to_be16(sig_size);
|
2024-07-01 17:41:03 +08:00
|
|
|
+ Fclose(fd);
|
2020-07-24 00:06:48 +02:00
|
|
|
+ rpmlog(RPMLOG_DEBUG,
|
|
|
|
|
+ "digest_list: read signature of %d bytes from '%s'\n",
|
|
|
|
|
+ sig_size, path_sig);
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ /* The signature may include the header */
|
|
|
|
|
+ if (hdr_exist)
|
|
|
|
|
+ ret = lsetxattr(path, XATTR_NAME_IMA, sig_hdr->sig, sig_size, 0);
|
|
|
|
|
+ else
|
|
|
|
|
+ ret = lsetxattr(path, XATTR_NAME_IMA, sig, sizeof(*sig_hdr) + sig_size, 0);
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ if (ret < 0)
|
|
|
|
|
+ rpmlog(RPMLOG_ERR, "digest_list: could not apply security.ima "
|
|
|
|
|
+ "on '%s': %s\n", path, strerror(errno));
|
|
|
|
|
+ else
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima successfully "
|
|
|
|
|
+ "applied on '%s'\n", path);
|
2024-07-01 17:41:03 +08:00
|
|
|
+
|
2020-07-14 09:04:38 +02:00
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+static int process_digest_list(rpmte te, int parser, int pre)
|
2020-07-14 09:04:38 +02:00
|
|
|
+{
|
|
|
|
|
+ char *path = NULL, *path_sig = NULL;
|
|
|
|
|
+ int digest_list_signed = 0;
|
|
|
|
|
+ struct stat st;
|
|
|
|
|
+ ssize_t size;
|
2024-07-01 17:41:03 +08:00
|
|
|
+ int type = rpmteType(te);
|
|
|
|
|
+ struct __user_cap_header_struct cap_header_data;
|
|
|
|
|
+ cap_user_header_t cap_header = &cap_header_data;
|
|
|
|
|
+ struct __user_cap_data_struct cap_data_data;
|
|
|
|
|
+ cap_user_data_t cap_data = &cap_data_data;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ rpmRC ret = RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ path = malloc(PATH_MAX);
|
|
|
|
|
+ if (!path) {
|
|
|
|
|
+ ret = RPMRC_FAIL;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ path_sig = malloc(PATH_MAX);
|
|
|
|
|
+ if (!path_sig) {
|
|
|
|
|
+ ret = RPMRC_FAIL;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (parser)
|
|
|
|
|
+ snprintf(path_sig, PATH_MAX,
|
|
|
|
|
+ "%s.sig/0-parser_list-compact-libexec.sig",
|
|
|
|
|
+ DIGEST_LIST_DEFAULT_PATH);
|
|
|
|
|
+ else
|
|
|
|
|
+ snprintf(path_sig, PATH_MAX,
|
|
|
|
|
+ "%s.sig/0-metadata_list-compact-%s-%s-%s.%s.sig",
|
|
|
|
|
+ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te),
|
|
|
|
|
+ rpmteR(te), rpmteA(te));
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (!stat(path_sig, &st)) {
|
2020-07-14 09:04:38 +02:00
|
|
|
+ digest_list_signed = 1;
|
2024-07-01 17:41:03 +08:00
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: digest_list_signed = 1\n");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: digest_list_signed = 0\n");
|
|
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (parser && !digest_list_signed) {
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: parser has to be signed!");
|
2020-07-26 23:29:14 +02:00
|
|
|
+ goto out;
|
2024-07-01 17:41:03 +08:00
|
|
|
+ }
|
2020-07-26 23:29:14 +02:00
|
|
|
+
|
2020-07-14 09:04:38 +02:00
|
|
|
+ if (parser)
|
|
|
|
|
+ snprintf(path, PATH_MAX, "%s/0-parser_list-compact-libexec",
|
|
|
|
|
+ DIGEST_LIST_DEFAULT_PATH);
|
|
|
|
|
+ else
|
|
|
|
|
+ snprintf(path, PATH_MAX,
|
|
|
|
|
+ "%s/0-metadata_list-compact-%s-%s-%s.%s",
|
|
|
|
|
+ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te),
|
|
|
|
|
+ rpmteR(te), rpmteA(te));
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (stat(path, &st) == -1) {
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "digest_list: failed to find digest list file path!");
|
2020-07-14 09:04:38 +02:00
|
|
|
+ goto out;
|
2024-07-01 17:41:03 +08:00
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ if (!parser && !digest_list_signed)
|
2020-07-14 09:04:38 +02:00
|
|
|
+ snprintf(path, PATH_MAX, "%s/0-metadata_list-rpm-%s-%s-%s.%s",
|
|
|
|
|
+ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te),
|
|
|
|
|
+ rpmteR(te), rpmteA(te));
|
|
|
|
|
+
|
2020-07-24 00:06:48 +02:00
|
|
|
+ size = lgetxattr(path, XATTR_NAME_IMA, NULL, 0);
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (type == TR_ADDED && !pre && size < 0) {
|
2020-07-14 09:04:38 +02:00
|
|
|
+ if (!digest_list_signed) {
|
|
|
|
|
+ /* Write RPM header to the disk */
|
|
|
|
|
+ ret = write_rpm_digest_list(te, path);
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ ret = RPMRC_FAIL;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
2024-07-01 17:41:03 +08:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* don't call lsetxattr without CAP_SYS_ADMIN */
|
|
|
|
|
+ cap_header->pid = getpid();
|
|
|
|
|
+ cap_header->version = _LINUX_CAPABILITY_VERSION_1;
|
|
|
|
|
+ if (capget(cap_header, cap_data) < 0) {
|
|
|
|
|
+ ret = -ENOENT;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!(cap_data->effective & CAP_TO_MASK(CAP_SYS_ADMIN))) {
|
|
|
|
|
+ ret = -EPERM;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (!digest_list_signed) {
|
2020-07-14 09:04:38 +02:00
|
|
|
+ /* Write RPM header sig to security.ima */
|
2020-07-24 00:06:48 +02:00
|
|
|
+ ret = write_rpm_digest_list_ima_xattr(te, path);
|
2020-07-14 09:04:38 +02:00
|
|
|
+ } else {
|
2020-07-24 00:06:48 +02:00
|
|
|
+ ret = write_digest_list_ima_xattr(te, path, path_sig);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (ret < 0) {
|
|
|
|
|
+ ret = RPMRC_FAIL;
|
|
|
|
|
+ goto out;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ }
|
2024-07-01 17:41:03 +08:00
|
|
|
+ } else if (type == TR_ADDED && pre) {
|
|
|
|
|
+ if (size < 0)
|
|
|
|
|
+ goto out;
|
|
|
|
|
+
|
|
|
|
|
+ /* rpm is overwriting the digest list, remove from the kernel */
|
|
|
|
|
+ type = TR_REMOVED;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Upload digest list to securityfs */
|
2024-07-01 17:41:03 +08:00
|
|
|
+ upload_digest_list(path, type, digest_list_signed);
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (type == TR_REMOVED) {
|
2020-07-28 23:53:47 +02:00
|
|
|
+ if (!digest_list_signed) {
|
|
|
|
|
+ unlink(path);
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+ }
|
|
|
|
|
+out:
|
|
|
|
|
+ free(path);
|
|
|
|
|
+ free(path_sig);
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+rpmte cur_te;
|
|
|
|
|
+int digest_list_counter;
|
|
|
|
|
+
|
2020-07-14 09:04:38 +02:00
|
|
|
+static rpmRC digest_list_psm_pre(rpmPlugin plugin, rpmte te)
|
|
|
|
|
+{
|
2024-07-01 17:41:03 +08:00
|
|
|
+ Header rpm = rpmteHeader(te);
|
|
|
|
|
+ rpmtd dirnames, dirindexes;
|
|
|
|
|
+ int i = -1;
|
|
|
|
|
+
|
|
|
|
|
+ digest_list_counter = 0;
|
|
|
|
|
+
|
|
|
|
|
+ dirnames = rpmtdNew();
|
|
|
|
|
+ headerGet(rpm, RPMTAG_DIRNAMES, dirnames, 0);
|
|
|
|
|
+
|
|
|
|
|
+ while ((i = rpmtdNext(dirnames)) >= 0) {
|
|
|
|
|
+ char *dirname = (char *) rpmtdGetString(dirnames);
|
|
|
|
|
+
|
|
|
|
|
+ if (!strncmp(dirname, DIGEST_LIST_DEFAULT_PATH,
|
|
|
|
|
+ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1) &&
|
|
|
|
|
+ dirname[sizeof(DIGEST_LIST_DEFAULT_PATH) - 1] == '/')
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ rpmtdFree(dirnames);
|
|
|
|
|
+
|
|
|
|
|
+ if (i == -1)
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ dirindexes = rpmtdNew();
|
|
|
|
|
+ headerGet(rpm, RPMTAG_DIRINDEXES, dirindexes, 0);
|
|
|
|
|
+ while (rpmtdNext(dirindexes) >= 0)
|
|
|
|
|
+ if (rpmtdGetNumber(dirindexes) == i)
|
|
|
|
|
+ digest_list_counter++;
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ rpmtdFree(dirindexes);
|
|
|
|
|
+
|
|
|
|
|
+ cur_te = te;
|
2020-07-14 09:04:38 +02:00
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi,
|
|
|
|
|
+ const char* path, mode_t file_mode,
|
|
|
|
|
+ rpmFsmOp op, int pre, int res)
|
2020-07-14 09:04:38 +02:00
|
|
|
+{
|
2024-07-01 17:41:03 +08:00
|
|
|
+ rpmFileAction action = XFO_ACTION(op);
|
|
|
|
|
+
|
|
|
|
|
+ if (!digest_list_counter)
|
2020-07-14 09:04:38 +02:00
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+ if (!cur_te)
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ if (!pre && res != RPMRC_OK)
|
|
|
|
|
+ return res;
|
|
|
|
|
+
|
|
|
|
|
+ if (!pre && rpmteType(cur_te) != TR_ADDED)
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ if (pre && action == FA_SKIP)
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ if (strncmp(path, DIGEST_LIST_DEFAULT_PATH,
|
|
|
|
|
+ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1) ||
|
|
|
|
|
+ path[sizeof(DIGEST_LIST_DEFAULT_PATH) - 1] != '/')
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ if (!pre && --digest_list_counter)
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "process ima digest, pre: %d, action: %d, teType: %d\n",
|
|
|
|
|
+ pre, action, rpmteType(cur_te));
|
|
|
|
|
+ process_digest_list(cur_te, 0, pre);
|
|
|
|
|
+ if (!strcmp(rpmteN(cur_te), "digest-list-tools")) {
|
|
|
|
|
+ if (pre && rpmteType(cur_te) == TR_REMOVED)
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+
|
|
|
|
|
+ rpmlog(RPMLOG_DEBUG, "process parser digest\n");
|
|
|
|
|
+ process_digest_list(cur_te, 1, pre);
|
|
|
|
|
+ }
|
2020-07-14 09:04:38 +02:00
|
|
|
+
|
|
|
|
|
+ return RPMRC_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2024-07-01 17:41:03 +08:00
|
|
|
+static rpmRC digest_list_file_pre(rpmPlugin plugin, rpmfi fi,
|
|
|
|
|
+ const char* path, mode_t file_mode,
|
|
|
|
|
+ rpmFsmOp op)
|
|
|
|
|
+{
|
|
|
|
|
+ return digest_list_file_common(plugin, fi, path, file_mode, op, 1, 0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static rpmRC digest_list_file_post(rpmPlugin plugin, rpmfi fi,
|
|
|
|
|
+ const char* path, mode_t file_mode,
|
|
|
|
|
+ rpmFsmOp op, int res)
|
|
|
|
|
+{
|
|
|
|
|
+ return digest_list_file_common(plugin, fi, path, file_mode, op, 0, res);
|
|
|
|
|
+}
|
|
|
|
|
+
|
2020-07-14 09:04:38 +02:00
|
|
|
+struct rpmPluginHooks_s digest_list_hooks = {
|
|
|
|
|
+ .psm_pre = digest_list_psm_pre,
|
2024-07-01 17:41:03 +08:00
|
|
|
+ .fsm_file_pre = digest_list_file_pre,
|
|
|
|
|
+ .fsm_file_post = digest_list_file_post,
|
2020-07-14 09:04:38 +02:00
|
|
|
+};
|
2020-07-24 00:06:48 +02:00
|
|
|
diff --git a/rpmio/digest.h b/rpmio/digest.h
|
2024-07-01 17:41:03 +08:00
|
|
|
index ec7f339..0d11d80 100644
|
2020-07-24 00:06:48 +02:00
|
|
|
--- a/rpmio/digest.h
|
|
|
|
|
+++ b/rpmio/digest.h
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -25,6 +25,7 @@ struct pgpDigAlg_s {
|
2020-07-24 00:06:48 +02:00
|
|
|
struct pgpDigParams_s {
|
|
|
|
|
char * userid;
|
|
|
|
|
uint8_t * hash;
|
|
|
|
|
+ const uint8_t * data;
|
|
|
|
|
uint8_t tag;
|
|
|
|
|
|
|
|
|
|
uint8_t version; /*!< version number. */
|
|
|
|
|
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
|
2024-07-01 17:41:03 +08:00
|
|
|
index d36bd62..e508062 100644
|
2020-07-24 00:06:48 +02:00
|
|
|
--- a/rpmio/rpmpgp.c
|
|
|
|
|
+++ b/rpmio/rpmpgp.c
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -627,6 +627,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
|
2020-07-24 00:06:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p = ((uint8_t *)v) + sizeof(*v);
|
|
|
|
|
+ _digp->data = p;
|
|
|
|
|
rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
|
|
|
|
|
} break;
|
|
|
|
|
case 4:
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -689,6 +690,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
|
2021-12-21 17:39:32 +08:00
|
|
|
if (p > hend)
|
2020-07-24 00:06:48 +02:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
+ _digp->data = p;
|
|
|
|
|
rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
2024-07-01 17:41:03 +08:00
|
|
|
@@ -804,6 +806,7 @@ static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen,
|
2020-07-24 00:06:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p = ((uint8_t *)v) + sizeof(*v);
|
|
|
|
|
+ _digp->data = p;
|
|
|
|
|
rc = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _digp);
|
|
|
|
|
}
|
|
|
|
|
} break;
|
2020-07-14 09:04:38 +02:00
|
|
|
--
|
2024-07-01 17:41:03 +08:00
|
|
|
2.33.0
|
2020-07-14 09:04:38 +02:00
|
|
|
|