malmond / rpms / rpm

Forked from rpms/rpm 4 years ago
Clone

Blame SOURCES/0005-Place-file-signatures-into-the-signature-header-wher.patch

657fb1
From d343c335fbf451ff1eebe3b347954c401c22ebf1 Mon Sep 17 00:00:00 2001
657fb1
From: Panu Matilainen <pmatilai@redhat.com>
657fb1
Date: Tue, 10 Oct 2017 11:44:10 +0300
657fb1
Subject: [PATCH 05/33] Place file signatures into the signature header where
657fb1
 they belong
657fb1
657fb1
The original file signing puts the file signatures into the main header
657fb1
immutable region, invalidating all previous signatures and digests so
657fb1
the package no longer appears to be what it was when it came out of the
657fb1
assembly line. Which is bad. Doing that also requires recalculating
657fb1
everything again which is just added complexity, and since it adds
657fb1
stuff to different place from the rest of the signing, it requires yet
657fb1
complexity to deal with that. Moving the file signatures into the
657fb1
signature header solves all that and allows removing a big pile of
657fb1
now unnecessary code.
657fb1
657fb1
Because this means retrofitting tags bass-ackwards into the signature
657fb1
header, the tag definitions are backwards to everything else. Other
657fb1
options would certainly be possible, but this makes things look more
657fb1
normal on the signature header side. "Users" only ever see the
657fb1
unchanged file signature tags as they have always been.
657fb1
657fb1
This also means the signature header can be MUCH bigger than ever before,
657fb1
so bump up the limit (to 64MB, arbitrary something for now), and
657fb1
permit string array types to be migrated from the signature header
657fb1
on package read.
657fb1
657fb1
Caveats:
657fb1
This loses the check for identical existing signatures to keep the
657fb1
complexity down, it's hardly a critical thing and can be added back later.
657fb1
While file signing could now be done separately to other signing, that
657fb1
is not handled here.
657fb1
---
657fb1
 lib/header.c        |   2 +-
657fb1
 lib/package.c       |   4 +-
657fb1
 lib/rpmtag.h        |   4 ++
657fb1
 sign/rpmgensig.c    | 161 +++-------------------------------------------------
657fb1
 sign/rpmsignfiles.c |  14 ++---
657fb1
 sign/rpmsignfiles.h |   5 +-
657fb1
 6 files changed, 26 insertions(+), 164 deletions(-)
657fb1
657fb1
diff --git a/lib/header.c b/lib/header.c
657fb1
index b05fda196..ab96da309 100644
657fb1
--- a/lib/header.c
657fb1
+++ b/lib/header.c
657fb1
@@ -1910,7 +1910,7 @@ rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrbl
657fb1
 
657fb1
     if (regionTag == RPMTAG_HEADERSIGNATURES) {
657fb1
 	il_max = 32;
657fb1
-	dl_max = 8192;
657fb1
+	dl_max = 64 * 1024;
657fb1
     }
657fb1
 
657fb1
     memset(block, 0, sizeof(block));
657fb1
diff --git a/lib/package.c b/lib/package.c
657fb1
index d3fc37324..8ee0e9e7c 100644
657fb1
--- a/lib/package.c
657fb1
+++ b/lib/package.c
657fb1
@@ -69,6 +69,8 @@ void headerMergeLegacySigs(Header h, Header sigh)
657fb1
 	case RPMSIGTAG_SHA256:
657fb1
 	case RPMSIGTAG_DSA:
657fb1
 	case RPMSIGTAG_RSA:
657fb1
+	case RPMSIGTAG_FILESIGNATURELENGTH:
657fb1
+	case RPMSIGTAG_FILESIGNATURES:
657fb1
 	default:
657fb1
 	    if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
657fb1
 		continue;
657fb1
@@ -88,11 +90,11 @@ void headerMergeLegacySigs(Header h, Header sigh)
657fb1
 		    continue;
657fb1
 		break;
657fb1
 	    case RPM_STRING_TYPE:
657fb1
+	    case RPM_STRING_ARRAY_TYPE:
657fb1
 	    case RPM_BIN_TYPE:
657fb1
 		if (td.count >= 16*1024)
657fb1
 		    continue;
657fb1
 		break;
657fb1
-	    case RPM_STRING_ARRAY_TYPE:
657fb1
 	    case RPM_I18NSTRING_TYPE:
657fb1
 		continue;
657fb1
 		break;
657fb1
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
657fb1
index 8bdf34405..7a9092a6e 100644
657fb1
--- a/lib/rpmtag.h
657fb1
+++ b/lib/rpmtag.h
657fb1
@@ -65,6 +65,8 @@ typedef enum rpmTag_e {
657fb1
     RPMTAG_LONGARCHIVESIZE	= RPMTAG_SIG_BASE+15,	/* l */
657fb1
     /* RPMTAG_SIG_BASE+16 reserved */
657fb1
     RPMTAG_SHA256HEADER		= RPMTAG_SIG_BASE+17,	/* s */
657fb1
+    /* RPMTAG_SIG_BASE+18 reserved for RPMSIGTAG_FILESIGNATURELENGTH */
657fb1
+    /* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURES */
657fb1
 
657fb1
     RPMTAG_NAME  		= 1000,	/* s */
657fb1
 #define	RPMTAG_N	RPMTAG_NAME	/* s */
657fb1
@@ -426,6 +428,8 @@ typedef enum rpmSigTag_e {
657fb1
     RPMSIGTAG_LONGSIZE	= RPMTAG_LONGSIGSIZE,	/*!< internal Header+Payload size (64bit) in bytes. */
657fb1
     RPMSIGTAG_LONGARCHIVESIZE = RPMTAG_LONGARCHIVESIZE, /*!< internal uncompressed payload size (64bit) in bytes. */
657fb1
     RPMSIGTAG_SHA256	= RPMTAG_SHA256HEADER,
657fb1
+    RPMSIGTAG_FILESIGNATURELENGTH	= RPMTAG_SIG_BASE + 18,
657fb1
+    RPMSIGTAG_FILESIGNATURES		= RPMTAG_SIG_BASE + 19,
657fb1
 } rpmSigTag;
657fb1
 
657fb1
 
657fb1
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
657fb1
index e20cbdb12..875b96078 100644
657fb1
--- a/sign/rpmgensig.c
657fb1
+++ b/sign/rpmgensig.c
657fb1
@@ -410,74 +410,12 @@ static void unloadImmutableRegion(Header *hdrp, rpmTagVal tag)
657fb1
     }
657fb1
 }
657fb1
 
657fb1
-#ifdef WITH_IMAEVM
657fb1
-static rpmRC replaceSigDigests(FD_t fd, const char *rpm, Header *sigp,
657fb1
-			       off_t sigStart, off_t sigTargetSize,
657fb1
-			       char *SHA256, char *SHA1, uint8_t *MD5)
657fb1
-{
657fb1
-    off_t archiveSize;
657fb1
-    rpmRC rc = RPMRC_OK;
657fb1
-
657fb1
-    if (Fseek(fd, sigStart, SEEK_SET) < 0) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
657fb1
-		rpm, Fstrerror(fd));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    /* Get payload size from signature tag */
657fb1
-    archiveSize = headerGetNumber(*sigp, RPMSIGTAG_PAYLOADSIZE);
657fb1
-    if (!archiveSize) {
657fb1
-	archiveSize = headerGetNumber(*sigp, RPMSIGTAG_LONGARCHIVESIZE);
657fb1
-    }
657fb1
-
657fb1
-    /* Set reserved space to 0 */
657fb1
-    rpmPushMacro(NULL, "__gpg_reserved_space", NULL, 0, RMIL_GLOBAL);
657fb1
-
657fb1
-    /* Replace old digests in sigh */
657fb1
-    rc = rpmGenerateSignature(SHA256, SHA1, MD5, sigTargetSize, archiveSize, fd);
657fb1
-    if (rc != RPMRC_OK) {
657fb1
-	rpmlog(RPMLOG_ERR, _("generateSignature failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    if (Fseek(fd, sigStart, SEEK_SET) < 0) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
657fb1
-		rpm, Fstrerror(fd));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    headerFree(*sigp);
657fb1
-    rc = rpmReadSignature(fd, sigp, NULL);
657fb1
-    if (rc != RPMRC_OK) {
657fb1
-	rpmlog(RPMLOG_ERR, _("rpmReadSignature failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-exit:
657fb1
-    return rc;
657fb1
-}
657fb1
-#endif
657fb1
-
657fb1
-static rpmRC includeFileSignatures(FD_t fd, const char *rpm,
657fb1
-				   Header *sigp, Header *hdrp,
657fb1
-				   off_t sigStart, off_t headerStart)
657fb1
+static rpmRC includeFileSignatures(Header *sigp, Header *hdrp)
657fb1
 {
657fb1
 #ifdef WITH_IMAEVM
657fb1
-    FD_t ofd = NULL;
657fb1
-    char *trpm = NULL;
657fb1
+    rpmRC rc;
657fb1
     char *key;
657fb1
     char *keypass;
657fb1
-    char *SHA1 = NULL;
657fb1
-    char *SHA256 = NULL;
657fb1
-    uint8_t *MD5 = NULL;
657fb1
-    off_t sigTargetSize;
657fb1
-    rpmRC rc = RPMRC_OK;
657fb1
-    struct rpmtd_s osigtd;
657fb1
-    char *o_sha1 = NULL;
657fb1
-
657fb1
-    unloadImmutableRegion(hdrp, RPMTAG_HEADERIMMUTABLE);
657fb1
 
657fb1
     key = rpmExpand("%{?_file_signing_key}", NULL);
657fb1
 
657fb1
@@ -487,94 +425,10 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm,
657fb1
 	keypass = NULL;
657fb1
     }
657fb1
 
657fb1
-    rc = rpmSignFiles(*hdrp, key, keypass);
657fb1
-    if (rc != RPMRC_OK) {
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    *hdrp = headerReload(*hdrp, RPMTAG_HEADERIMMUTABLE);
657fb1
-    if (*hdrp == NULL) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("headerReload failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    ofd = rpmMkTempFile(NULL, &trpm;;
657fb1
-    if (ofd == NULL || Ferror(ofd)) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    /* Copy archive to temp file */
657fb1
-    if (copyFile(&fd, rpm, &ofd, trpm)) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("copyFile failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-
657fb1
-    if (Fseek(fd, headerStart, SEEK_SET) < 0) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
657fb1
-		rpm, Fstrerror(fd));
657fb1
-	goto exit;
657fb1
-    }
657fb1
+    rc = rpmSignFiles(*sigp, *hdrp, key, keypass);
657fb1
 
657fb1
-    /* Start MD5 calculation */
657fb1
-    fdInitDigestID(fd, PGPHASHALGO_MD5, RPMSIGTAG_MD5, 0);
657fb1
-
657fb1
-    /* Write header to rpm and recalculate digests */
657fb1
-    fdInitDigestID(fd, PGPHASHALGO_SHA1, RPMSIGTAG_SHA1, 0);
657fb1
-    fdInitDigestID(fd, PGPHASHALGO_SHA256, RPMSIGTAG_SHA256, 0);
657fb1
-    rc = headerWrite(fd, *hdrp, HEADER_MAGIC_YES);
657fb1
-    if (rc != RPMRC_OK) {
657fb1
-	rpmlog(RPMLOG_ERR, _("headerWrite failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-    fdFiniDigest(fd, RPMSIGTAG_SHA1, (void **)&SHA1, NULL, 1);
657fb1
-    /* Only add SHA256 if it was there to begin with */
657fb1
-    if (headerIsEntry(*sigp, RPMSIGTAG_SHA256))
657fb1
-	fdFiniDigest(fd, RPMSIGTAG_SHA256, (void **)&SHA256, NULL, 1);
657fb1
-
657fb1
-    /* Copy archive from temp file */
657fb1
-    if (Fseek(ofd, 0, SEEK_SET) < 0) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
657fb1
-		rpm, Fstrerror(fd));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-    if (copyFile(&ofd, trpm, &fd, rpm)) {
657fb1
-	rc = RPMRC_FAIL;
657fb1
-	rpmlog(RPMLOG_ERR, _("copyFile failed\n"));
657fb1
-	goto exit;
657fb1
-    }
657fb1
-    unlink(trpm);
657fb1
-
657fb1
-    sigTargetSize = Ftell(fd) - headerStart;
657fb1
-    fdFiniDigest(fd, RPMSIGTAG_MD5, (void **)&MD5, NULL, 0);
657fb1
-
657fb1
-    if (headerGet(*sigp, RPMSIGTAG_SHA1, &osigtd, HEADERGET_DEFAULT)) {
657fb1
-	o_sha1 = xstrdup(osigtd.data);
657fb1
-	rpmtdFreeData(&osigtd);
657fb1
-    }
657fb1
-
657fb1
-    if (strcmp(SHA1, o_sha1) == 0)
657fb1
-	rpmlog(RPMLOG_WARNING,
657fb1
-	       _("%s already contains identical file signatures\n"),
657fb1
-	       rpm);
657fb1
-    else
657fb1
-	replaceSigDigests(fd, rpm, sigp, sigStart, sigTargetSize, SHA256, SHA1, MD5);
657fb1
-
657fb1
-exit:
657fb1
-    free(trpm);
657fb1
-    free(MD5);
657fb1
-    free(SHA1);
657fb1
-    free(SHA256);
657fb1
-    free(o_sha1);
657fb1
     free(keypass);
657fb1
     free(key);
657fb1
-    if (ofd)
657fb1
-	(void) closeFile(&ofd;;
657fb1
     return rc;
657fb1
 #else
657fb1
     rpmlog(RPMLOG_ERR, _("file signing support not built in\n"));
657fb1
@@ -667,13 +521,14 @@ static int rpmSign(const char *rpm, int deleting, int signfiles)
657fb1
 	goto exit;
657fb1
     }
657fb1
 
657fb1
-    if (signfiles) {
657fb1
-	includeFileSignatures(fd, rpm, &sigh, &h, sigStart, headerStart);
657fb1
-    }
657fb1
-
657fb1
     unloadImmutableRegion(&sigh, RPMTAG_HEADERSIGNATURES);
657fb1
     origSigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
657fb1
 
657fb1
+    if (signfiles) {
657fb1
+	if (includeFileSignatures(&sigh, &h))
657fb1
+	    goto exit;
657fb1
+    }
657fb1
+
657fb1
     if (deleting) {	/* Nuke all the signature tags. */
657fb1
 	deleteSigs(sigh);
657fb1
     } else {
657fb1
diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c
657fb1
index 1fc127cb1..2dcc50400 100644
657fb1
--- a/sign/rpmsignfiles.c
657fb1
+++ b/sign/rpmsignfiles.c
657fb1
@@ -80,7 +80,7 @@ char *keypass)
657fb1
     return siglen + 1;
657fb1
 }
657fb1
 
657fb1
-rpmRC rpmSignFiles(Header h, const char *key, char *keypass)
657fb1
+rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)
657fb1
 {
657fb1
     struct rpmtd_s digests, td;
657fb1
     int algo;
657fb1
@@ -107,19 +107,19 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass)
657fb1
 	return RPMRC_FAIL;
657fb1
     }
657fb1
 
657fb1
-    headerDel(h, RPMTAG_FILESIGNATURELENGTH);
657fb1
-    headerDel(h, RPMTAG_FILESIGNATURES);
657fb1
+    headerDel(sigh, RPMTAG_FILESIGNATURELENGTH);
657fb1
+    headerDel(sigh, RPMTAG_FILESIGNATURES);
657fb1
     siglen = signatureLength(algoname, diglen, key, keypass);
657fb1
 
657fb1
     rpmtdReset(&td);
657fb1
-    td.tag = RPMTAG_FILESIGNATURELENGTH;
657fb1
+    td.tag = RPMSIGTAG_FILESIGNATURELENGTH;
657fb1
     td.type = RPM_INT32_TYPE;
657fb1
     td.data = &siglen;
657fb1
     td.count = 1;
657fb1
-    headerPut(h, &td, HEADERPUT_DEFAULT);
657fb1
+    headerPut(sigh, &td, HEADERPUT_DEFAULT);
657fb1
 
657fb1
     rpmtdReset(&td);
657fb1
-    td.tag = RPMTAG_FILESIGNATURES;
657fb1
+    td.tag = RPMSIGTAG_FILESIGNATURES;
657fb1
     td.type = RPM_STRING_ARRAY_TYPE;
657fb1
     td.data = NULL; /* set in the loop below */
657fb1
     td.count = 1;
657fb1
@@ -133,7 +133,7 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass)
657fb1
 	    goto exit;
657fb1
 	}
657fb1
 	td.data = &signature;
657fb1
-	if (!headerPut(h, &td, HEADERPUT_APPEND)) {
657fb1
+	if (!headerPut(sigh, &td, HEADERPUT_APPEND)) {
657fb1
 	    free(signature);
657fb1
 	    rpmlog(RPMLOG_ERR, _("headerPutString failed\n"));
657fb1
 	    rc = RPMRC_FAIL;
657fb1
diff --git a/sign/rpmsignfiles.h b/sign/rpmsignfiles.h
657fb1
index 4163fafde..2ff623cdf 100644
657fb1
--- a/sign/rpmsignfiles.h
657fb1
+++ b/sign/rpmsignfiles.h
657fb1
@@ -9,14 +9,15 @@ extern "C" {
657fb1
 #endif
657fb1
 
657fb1
 /**
657fb1
- * Sign file digests in header and store the signatures in header
657fb1
+ * Sign file digests in header into signature header
657fb1
+ * @param sigh		package signature header
657fb1
  * @param h		package header
657fb1
  * @param key		signing key
657fb1
  * @param keypass	signing key password
657fb1
  * @return		RPMRC_OK on success
657fb1
  */
657fb1
 RPM_GNUC_INTERNAL
657fb1
-rpmRC rpmSignFiles(Header h, const char *key, char *keypass);
657fb1
+rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass);
657fb1
 
657fb1
 #ifdef _cplusplus
657fb1
 }
657fb1
-- 
657fb1
2.13.5
657fb1