|
|
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 |
|