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