dcavalca / rpms / rpm

Forked from rpms/rpm a year ago
Clone

Blame 0003-Verify-packages-before-signing-RhBug-1646388.patch

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