|
|
0b2921 |
From df089e178da0918dc74a8572a99324b0987bce30 Mon Sep 17 00:00:00 2001
|
|
|
0b2921 |
Message-Id: <df089e178da0918dc74a8572a99324b0987bce30.1554983206.git.pmatilai@redhat.com>
|
|
|
0b2921 |
In-Reply-To: <2ec0832287bd1443ebf336f8a98293f30bfa2036.1554983205.git.pmatilai@redhat.com>
|
|
|
0b2921 |
References: <2ec0832287bd1443ebf336f8a98293f30bfa2036.1554983205.git.pmatilai@redhat.com>
|
|
|
0b2921 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
0b2921 |
Date: Mon, 18 Mar 2019 15:56:34 +0200
|
|
|
0b2921 |
Subject: [PATCH 3/3] Verify packages before signing (RhBug:1646388)
|
|
|
0b2921 |
|
|
|
0b2921 |
Permitting corrupted packages to be signed is bad business for everybody
|
|
|
0b2921 |
involved, this is something we should've always done. Besides being an
|
|
|
0b2921 |
actual security risk, it can lead to odd results with verification
|
|
|
0b2921 |
especially with the payload digest on signed packages.
|
|
|
0b2921 |
|
|
|
0b2921 |
One point worth noting is that this means that pre 4.14-packages cannot
|
|
|
0b2921 |
be signed in FIPS mode now because there's no way to validate the package
|
|
|
0b2921 |
payload range due to MD5 being disabled. This seems like a feature and
|
|
|
0b2921 |
not a limitation, so disabler for the verify step intentionally left out.
|
|
|
0b2921 |
|
|
|
0b2921 |
Optimally we'd verify the package on the same read that's passed
|
|
|
0b2921 |
to gpg but for simplicitys sake that's left as an future exercise,
|
|
|
0b2921 |
now we simply read the package twice.
|
|
|
0b2921 |
---
|
|
|
0b2921 |
sign/rpmgensig.c | 32 ++++++++++++++++++++++++++++++++
|
|
|
0b2921 |
tests/rpmsigdig.at | 20 ++++++++++++++++++++
|
|
|
0b2921 |
2 files changed, 52 insertions(+)
|
|
|
0b2921 |
|
|
|
0b2921 |
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
|
|
|
0b2921 |
index 2bcbab768..5be542001 100644
|
|
|
0b2921 |
--- a/sign/rpmgensig.c
|
|
|
0b2921 |
+++ b/sign/rpmgensig.c
|
|
|
0b2921 |
@@ -21,6 +21,7 @@
|
|
|
0b2921 |
|
|
|
0b2921 |
#include "lib/rpmlead.h"
|
|
|
0b2921 |
#include "lib/signature.h"
|
|
|
0b2921 |
+#include "lib/rpmvs.h"
|
|
|
0b2921 |
#include "sign/rpmsignfiles.h"
|
|
|
0b2921 |
|
|
|
0b2921 |
#include "debug.h"
|
|
|
0b2921 |
@@ -489,6 +490,31 @@ static rpmRC includeFileSignatures(Header *sigp, Header *hdrp)
|
|
|
0b2921 |
#endif
|
|
|
0b2921 |
}
|
|
|
0b2921 |
|
|
|
0b2921 |
+static int msgCb(struct rpmsinfo_s *sinfo, void *cbdata)
|
|
|
0b2921 |
+{
|
|
|
0b2921 |
+ char **msg = cbdata;
|
|
|
0b2921 |
+ if (sinfo->rc && *msg == NULL)
|
|
|
0b2921 |
+ *msg = rpmsinfoMsg(sinfo);
|
|
|
0b2921 |
+ return (sinfo->rc != RPMRC_FAIL);
|
|
|
0b2921 |
+}
|
|
|
0b2921 |
+
|
|
|
0b2921 |
+/* Require valid digests on entire package for signing. */
|
|
|
0b2921 |
+static int checkPkg(FD_t fd, char **msg)
|
|
|
0b2921 |
+{
|
|
|
0b2921 |
+ int rc;
|
|
|
0b2921 |
+ struct rpmvs_s *vs = rpmvsCreate(RPMSIG_DIGEST_TYPE, 0, NULL);
|
|
|
0b2921 |
+ off_t offset = Ftell(fd);
|
|
|
0b2921 |
+
|
|
|
0b2921 |
+ Fseek(fd, 0, SEEK_SET);
|
|
|
0b2921 |
+ rc = rpmpkgRead(vs, fd, NULL, NULL, msg);
|
|
|
0b2921 |
+ if (!rc)
|
|
|
0b2921 |
+ rc = rpmvsVerify(vs, RPMSIG_DIGEST_TYPE, msgCb, msg);
|
|
|
0b2921 |
+ Fseek(fd, offset, SEEK_SET);
|
|
|
0b2921 |
+
|
|
|
0b2921 |
+ rpmvsFree(vs);
|
|
|
0b2921 |
+ return rc;
|
|
|
0b2921 |
+}
|
|
|
0b2921 |
+
|
|
|
0b2921 |
/** \ingroup rpmcli
|
|
|
0b2921 |
* Create/modify elements in signature header.
|
|
|
0b2921 |
* @param rpm path to package
|
|
|
0b2921 |
@@ -519,6 +545,12 @@ static int rpmSign(const char *rpm, int deleting, int signfiles)
|
|
|
0b2921 |
if (manageFile(&fd, rpm, O_RDWR))
|
|
|
0b2921 |
goto exit;
|
|
|
0b2921 |
|
|
|
0b2921 |
+ /* Ensure package is intact before attempting to sign */
|
|
|
0b2921 |
+ if ((rc = checkPkg(fd, &msg))) {
|
|
|
0b2921 |
+ rpmlog(RPMLOG_ERR, "not signing corrupt package %s: %s\n", rpm, msg);
|
|
|
0b2921 |
+ goto exit;
|
|
|
0b2921 |
+ }
|
|
|
0b2921 |
+
|
|
|
0b2921 |
if ((rc = rpmLeadRead(fd, &msg)) != RPMRC_OK) {
|
|
|
0b2921 |
rpmlog(RPMLOG_ERR, "%s: %s\n", rpm, msg);
|
|
|
0b2921 |
goto exit;
|
|
|
0b2921 |
diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at
|
|
|
0b2921 |
index 413c3d2c8..e93420306 100644
|
|
|
0b2921 |
--- a/tests/rpmsigdig.at
|
|
|
0b2921 |
+++ b/tests/rpmsigdig.at
|
|
|
0b2921 |
@@ -472,3 +472,23 @@ run rpmsign --key-id 1964C5FC --addsign "${RPMTEST}"/tmp/hello-2.0-1.x86_64-sign
|
|
|
0b2921 |
[],
|
|
|
0b2921 |
[])
|
|
|
0b2921 |
AT_CLEANUP
|
|
|
0b2921 |
+
|
|
|
0b2921 |
+AT_SETUP([rpmsign --addsign <corrupted>])
|
|
|
0b2921 |
+AT_KEYWORDS([rpmsign signature])
|
|
|
0b2921 |
+AT_CHECK([
|
|
|
0b2921 |
+RPMDB_CLEAR
|
|
|
0b2921 |
+RPMDB_INIT
|
|
|
0b2921 |
+rm -rf "${TOPDIR}"
|
|
|
0b2921 |
+
|
|
|
0b2921 |
+pkg="hello-2.0-1.x86_64.rpm"
|
|
|
0b2921 |
+cp "${RPMTEST}"/data/RPMS/${pkg} "${RPMTEST}"/tmp/${pkg}
|
|
|
0b2921 |
+dd if=/dev/zero of="${RPMTEST}"/tmp/${pkg} \
|
|
|
0b2921 |
+ conv=notrunc bs=1 seek=333 count=4 2> /dev/null
|
|
|
0b2921 |
+run rpmsign --key-id 1964C5FC --addsign "${RPMTEST}/tmp/${pkg}"
|
|
|
0b2921 |
+],
|
|
|
0b2921 |
+[1],
|
|
|
0b2921 |
+[/home/pmatilai/repos/rpm/tests/testing/tmp/hello-2.0-1.x86_64.rpm:
|
|
|
0b2921 |
+],
|
|
|
0b2921 |
+[error: not signing corrupt package /home/pmatilai/repos/rpm/tests/testing/tmp/hello-2.0-1.x86_64.rpm: MD5 digest: BAD (Expected 007ca1d8b35cca02a1854ba301c5432e != 137ca1d8b35cca02a1854ba301c5432e)
|
|
|
0b2921 |
+])
|
|
|
0b2921 |
+AT_CLEANUP
|
|
|
0b2921 |
--
|
|
|
0b2921 |
2.20.1
|
|
|
0b2921 |
|