|
|
2f13d7 |
From 7da1e826ccb08fdd404524146736b3f12a473e31 Mon Sep 17 00:00:00 2001
|
|
|
2f13d7 |
From: chantra <chantr4@gmail.com>
|
|
|
2f13d7 |
Date: Mon, 31 Jan 2022 14:42:25 -0800
|
|
|
2f13d7 |
Subject: [PATCH 10/30] [rpm2extents] Make rpmkeys support reading metadata
|
|
|
2f13d7 |
from transcoded footer
|
|
|
2f13d7 |
|
|
|
2f13d7 |
If the file is seekable and is a transcoded file, read signature validation from transcoded file tail metadata
|
|
|
2f13d7 |
---
|
|
|
2f13d7 |
lib/rpmchecksig.c | 112 ++++++++++++++++++++++++++++++++++++++++++-
|
|
|
2f13d7 |
tests/rpm2extents.at | 34 ++++++++++++-
|
|
|
2f13d7 |
2 files changed, 144 insertions(+), 2 deletions(-)
|
|
|
2f13d7 |
|
|
|
2f13d7 |
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
|
|
|
2f13d7 |
index fcdbb424f..6164d012c 100644
|
|
|
2f13d7 |
--- a/lib/rpmchecksig.c
|
|
|
2f13d7 |
+++ b/lib/rpmchecksig.c
|
|
|
2f13d7 |
@@ -24,6 +24,11 @@
|
|
|
2f13d7 |
|
|
|
2f13d7 |
#include "debug.h"
|
|
|
2f13d7 |
|
|
|
2f13d7 |
+/* magic value at end of file (64 bits) that indicates this is a transcoded
|
|
|
2f13d7 |
+ * rpm.
|
|
|
2f13d7 |
+ */
|
|
|
2f13d7 |
+#define MAGIC 3472329499408095051
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
static int doImport(rpmts ts, const char *fn, char *buf, ssize_t blen)
|
|
|
2f13d7 |
{
|
|
|
2f13d7 |
char const * const pgpmark = "-----BEGIN PGP ";
|
|
|
2f13d7 |
@@ -220,6 +225,107 @@ exit:
|
|
|
2f13d7 |
return rc;
|
|
|
2f13d7 |
}
|
|
|
2f13d7 |
|
|
|
2f13d7 |
+static rpmRC isTranscodedRpm(FD_t fd) {
|
|
|
2f13d7 |
+ rpmRC rc = RPMRC_NOTFOUND;
|
|
|
2f13d7 |
+ rpm_loff_t current;
|
|
|
2f13d7 |
+ uint64_t magic;
|
|
|
2f13d7 |
+ size_t len;
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ // If the file is not seekable, we cannot detect whether or not it is transcoded.
|
|
|
2f13d7 |
+ if(Fseek(fd, 0, SEEK_CUR) < 0) {
|
|
|
2f13d7 |
+ return RPMRC_FAIL;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ current = Ftell(fd);
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ if(Fseek(fd, -(sizeof(magic)), SEEK_END) < 0) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("isTranscodedRpm: failed to seek for magic\n"));
|
|
|
2f13d7 |
+ rc = RPMRC_FAIL;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ len = sizeof(magic);
|
|
|
2f13d7 |
+ if (Fread(&magic, len, 1, fd) != len) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("isTranscodedRpm: unable to read magic\n"));
|
|
|
2f13d7 |
+ rc = RPMRC_FAIL;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ if (magic != MAGIC) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_DEBUG, _("isTranscodedRpm: not transcoded\n"));
|
|
|
2f13d7 |
+ rc = RPMRC_NOTFOUND;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ rc = RPMRC_OK;
|
|
|
2f13d7 |
+exit:
|
|
|
2f13d7 |
+ if (Fseek(fd, current, SEEK_SET) < 0) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("isTranscodedRpm: unable to seek back to original location\n"));
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ return rc;
|
|
|
2f13d7 |
+}
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+static int rpmpkgVerifySigsTranscoded(FD_t fd){
|
|
|
2f13d7 |
+ rpm_loff_t current;
|
|
|
2f13d7 |
+ uint64_t magic;
|
|
|
2f13d7 |
+ rpm_loff_t offset;
|
|
|
2f13d7 |
+ int32_t rc;
|
|
|
2f13d7 |
+ size_t len;
|
|
|
2f13d7 |
+ uint64_t content_len;
|
|
|
2f13d7 |
+ char *content = NULL;
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ current = Ftell(fd);
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ if(Fseek(fd, -(sizeof(magic) + 3 * sizeof(offset) ), SEEK_END) < 0) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: failed to seek for offset\n"));
|
|
|
2f13d7 |
+ rc = -1;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ len = sizeof(offset);
|
|
|
2f13d7 |
+ if (Fread(&offset, len, 1, fd) != len) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to read Signature Verification offset\n"));
|
|
|
2f13d7 |
+ rc = -1;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ if(Fseek(fd, offset, SEEK_SET) < 0) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to seek signature verification offset\n"));
|
|
|
2f13d7 |
+ rc = -1;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ len = sizeof(rc);
|
|
|
2f13d7 |
+ if (Fread(&rc, len, 1, fd) != len) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to read Signature Verification RC\n"));
|
|
|
2f13d7 |
+ rc = -1;
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ len = sizeof(content_len);
|
|
|
2f13d7 |
+ if (Fread(&content_len, len, 1, fd) != len) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to read signature content length\n"));
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ content = malloc(content_len + 1);
|
|
|
2f13d7 |
+ if(content == NULL) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to allocate memory to read signature content\n"));
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ content[content_len] = 0;
|
|
|
2f13d7 |
+ if (Fread(content, content_len, 1, fd) != content_len) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: Failed to read signature content\n"));
|
|
|
2f13d7 |
+ goto exit;
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_NOTICE, "%s", content);
|
|
|
2f13d7 |
+exit:
|
|
|
2f13d7 |
+ if(content){
|
|
|
2f13d7 |
+ free(content);
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ if (Fseek(fd, current, SEEK_SET) < 0) {
|
|
|
2f13d7 |
+ rpmlog(RPMLOG_ERR, _("rpmpkgVerifySigsTranscoded: unable to seek back to original location\n"));
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ return rc;
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+}
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
static int rpmpkgVerifySigs(rpmKeyring keyring, int vfylevel, rpmVSFlags flags,
|
|
|
2f13d7 |
FD_t fd, const char *fn)
|
|
|
2f13d7 |
{
|
|
|
2f13d7 |
@@ -229,10 +335,14 @@ static int rpmpkgVerifySigs(rpmKeyring keyring, int vfylevel, rpmVSFlags flags,
|
|
|
2f13d7 |
.verbose = rpmIsVerbose(),
|
|
|
2f13d7 |
};
|
|
|
2f13d7 |
int rc;
|
|
|
2f13d7 |
- struct rpmvs_s *vs = rpmvsCreate(vfylevel, flags, keyring);
|
|
|
2f13d7 |
|
|
|
2f13d7 |
rpmlog(RPMLOG_NOTICE, "%s:%s", fn, vd.verbose ? "\n" : "");
|
|
|
2f13d7 |
|
|
|
2f13d7 |
+ if(isTranscodedRpm(fd) == RPMRC_OK){
|
|
|
2f13d7 |
+ return rpmpkgVerifySigsTranscoded(fd);
|
|
|
2f13d7 |
+ }
|
|
|
2f13d7 |
+ struct rpmvs_s *vs = rpmvsCreate(vfylevel, flags, keyring);
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
rc = rpmpkgRead(vs, fd, NULL, NULL, &msg;;
|
|
|
2f13d7 |
|
|
|
2f13d7 |
if (rc)
|
|
|
2f13d7 |
diff --git a/tests/rpm2extents.at b/tests/rpm2extents.at
|
|
|
2f13d7 |
index baea987e4..18accfc75 100644
|
|
|
2f13d7 |
--- a/tests/rpm2extents.at
|
|
|
2f13d7 |
+++ b/tests/rpm2extents.at
|
|
|
2f13d7 |
@@ -29,7 +29,7 @@ AT_CHECK([runroot_other cat /data/RPMS/hello-2.0-1.x86_64.rpm | runroot_other rp
|
|
|
2f13d7 |
[ignore])
|
|
|
2f13d7 |
AT_CLEANUP
|
|
|
2f13d7 |
|
|
|
2f13d7 |
-# Check that tailer writes checksig return code and content.
|
|
|
2f13d7 |
+# Check that transcoder writes checksig return code and content.
|
|
|
2f13d7 |
#
|
|
|
2f13d7 |
AT_SETUP([rpm2extents signature])
|
|
|
2f13d7 |
AT_KEYWORDS([rpm2extents digest signature])
|
|
|
2f13d7 |
@@ -62,3 +62,35 @@ RPMSignOutput Content Header V4 RSA/SHA256 Signature, key ID 1964c5fc: OK
|
|
|
2f13d7 |
],
|
|
|
2f13d7 |
[])
|
|
|
2f13d7 |
AT_CLEANUP
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+AT_SETUP([rpm2extents signature verification])
|
|
|
2f13d7 |
+AT_KEYWORDS([rpm2extents digest signature])
|
|
|
2f13d7 |
+AT_CHECK([
|
|
|
2f13d7 |
+RPMDB_INIT
|
|
|
2f13d7 |
+
|
|
|
2f13d7 |
+runroot_other cat /data/RPMS/hello-2.0-1.x86_64-signed.rpm | runroot_other rpm2extents SHA256 > ${RPMTEST}/tmp/hello-2.0-1.x86_64-signed.rpm 2> /dev/null
|
|
|
2f13d7 |
+runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64-signed.rpm; echo $?
|
|
|
2f13d7 |
+runroot rpmkeys --import /data/keys/rpm.org-rsa-2048-test.pub
|
|
|
2f13d7 |
+runroot_other cat /data/RPMS/hello-2.0-1.x86_64-signed.rpm | runroot_other rpm2extents SHA256 > ${RPMTEST}/tmp/hello-2.0-1.x86_64-signed.rpm
|
|
|
2f13d7 |
+runroot rpmkeys -Kv /tmp/hello-2.0-1.x86_64-signed.rpm; echo $?
|
|
|
2f13d7 |
+],
|
|
|
2f13d7 |
+[0],
|
|
|
2f13d7 |
+[/tmp/hello-2.0-1.x86_64-signed.rpm:
|
|
|
2f13d7 |
+ Header V4 RSA/SHA256 Signature, key ID 1964c5fc: NOKEY
|
|
|
2f13d7 |
+ Header SHA256 digest: OK
|
|
|
2f13d7 |
+ Header SHA1 digest: OK
|
|
|
2f13d7 |
+ Payload SHA256 digest: OK
|
|
|
2f13d7 |
+ V4 RSA/SHA256 Signature, key ID 1964c5fc: NOKEY
|
|
|
2f13d7 |
+ MD5 digest: OK
|
|
|
2f13d7 |
+1
|
|
|
2f13d7 |
+/tmp/hello-2.0-1.x86_64-signed.rpm:
|
|
|
2f13d7 |
+ Header V4 RSA/SHA256 Signature, key ID 1964c5fc: OK
|
|
|
2f13d7 |
+ Header SHA256 digest: OK
|
|
|
2f13d7 |
+ Header SHA1 digest: OK
|
|
|
2f13d7 |
+ Payload SHA256 digest: OK
|
|
|
2f13d7 |
+ V4 RSA/SHA256 Signature, key ID 1964c5fc: OK
|
|
|
2f13d7 |
+ MD5 digest: OK
|
|
|
2f13d7 |
+0
|
|
|
2f13d7 |
+],
|
|
|
2f13d7 |
+[])
|
|
|
2f13d7 |
+AT_CLEANUP
|
|
|
2f13d7 |
--
|
|
|
2f13d7 |
2.35.1
|
|
|
2f13d7 |
|