|
|
45e748 |
From 22420d9ee652a25357727b00585dc3cfe78b2a80 Mon Sep 17 00:00:00 2001
|
|
|
45e748 |
From: Jes Sorensen <jsorensen@fb.com>
|
|
|
45e748 |
Date: Mon, 13 Apr 2020 18:14:15 -0400
|
|
|
45e748 |
Subject: [PATCH 22/33] rpmSignVerity: Generate signatures for files not
|
|
|
45e748 |
present in archive
|
|
|
45e748 |
|
|
|
45e748 |
This generates signatures for all files in the archive, then picks up
|
|
|
45e748 |
ghost files from the header metadata and generates signatures for them
|
|
|
45e748 |
as well. It finally submits them to RPMTAG_VERITYSIGNATURES in header
|
|
|
45e748 |
file order as we cannot rely on archive order and header order being
|
|
|
45e748 |
the same.
|
|
|
45e748 |
|
|
|
45e748 |
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
|
|
45e748 |
---
|
|
|
45e748 |
lib/package.c | 1 +
|
|
|
45e748 |
sign/rpmsignverity.c | 55 ++++++++++++++++++++++++++++++++++----------
|
|
|
45e748 |
2 files changed, 44 insertions(+), 12 deletions(-)
|
|
|
45e748 |
|
|
|
45e748 |
diff --git a/lib/package.c b/lib/package.c
|
|
|
45e748 |
index b7d996a12..c6108f686 100644
|
|
|
45e748 |
--- a/lib/package.c
|
|
|
45e748 |
+++ b/lib/package.c
|
|
|
45e748 |
@@ -45,6 +45,7 @@ struct taglate_s {
|
|
|
45e748 |
{ RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1, 1 },
|
|
|
45e748 |
{ RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0, 1 },
|
|
|
45e748 |
{ RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1, 1 },
|
|
|
45e748 |
+ { RPMSIGTAG_VERITYSIGNATURES, RPMTAG_VERITYSIGNATURES, 0, 0 },
|
|
|
45e748 |
{ RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 },
|
|
|
45e748 |
{ RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1, 0 },
|
|
|
45e748 |
{ RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 },
|
|
|
45e748 |
diff --git a/sign/rpmsignverity.c b/sign/rpmsignverity.c
|
|
|
45e748 |
index a9818bd08..3bb23a18d 100644
|
|
|
45e748 |
--- a/sign/rpmsignverity.c
|
|
|
45e748 |
+++ b/sign/rpmsignverity.c
|
|
|
45e748 |
@@ -41,7 +41,7 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
|
|
|
45e748 |
struct libfsverity_digest *digest = NULL;
|
|
|
45e748 |
rpm_loff_t file_size;
|
|
|
45e748 |
char *digest_hex, *sig_hex = NULL;
|
|
|
45e748 |
- uint8_t *sig;
|
|
|
45e748 |
+ uint8_t *sig = NULL;
|
|
|
45e748 |
int status;
|
|
|
45e748 |
|
|
|
45e748 |
file_size = rpmfiFSize(fi);
|
|
|
45e748 |
@@ -72,7 +72,7 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
|
|
|
45e748 |
goto out;
|
|
|
45e748 |
}
|
|
|
45e748 |
|
|
|
45e748 |
- sig_hex = pgpHexStr(sig, *sig_size + 1);
|
|
|
45e748 |
+ sig_hex = pgpHexStr(sig, *sig_size);
|
|
|
45e748 |
out:
|
|
|
45e748 |
free(digest);
|
|
|
45e748 |
free(sig);
|
|
|
45e748 |
@@ -86,6 +86,7 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
FD_t gzdi;
|
|
|
45e748 |
rpmfiles files = NULL;
|
|
|
45e748 |
rpmfi fi = NULL;
|
|
|
45e748 |
+ rpmfi hfi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, RPMFI_FLAGS_QUERY);
|
|
|
45e748 |
rpmts ts = rpmtsCreate();
|
|
|
45e748 |
struct rpmtd_s td;
|
|
|
45e748 |
rpm_loff_t file_size;
|
|
|
45e748 |
@@ -93,11 +94,14 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
const char *compr;
|
|
|
45e748 |
char *rpmio_flags = NULL;
|
|
|
45e748 |
char *sig_hex;
|
|
|
45e748 |
+ char **signatures = NULL;
|
|
|
45e748 |
size_t sig_size;
|
|
|
45e748 |
+ int nr_files, idx;
|
|
|
45e748 |
|
|
|
45e748 |
Fseek(fd, 0, SEEK_SET);
|
|
|
45e748 |
rpmtsSetVSFlags(ts, RPMVSF_MASK_NODIGESTS | RPMVSF_MASK_NOSIGNATURES |
|
|
|
45e748 |
RPMVSF_NOHDRCHK);
|
|
|
45e748 |
+
|
|
|
45e748 |
rc = rpmReadPackageFile(ts, fd, "fsverity", &h);
|
|
|
45e748 |
if (rc != RPMRC_OK) {
|
|
|
45e748 |
rpmlog(RPMLOG_DEBUG, _("%s: rpmReadPackageFile returned %i\n"),
|
|
|
45e748 |
@@ -113,6 +117,8 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
|
|
|
45e748 |
gzdi = Fdopen(fdDup(Fileno(fd)), rpmio_flags);
|
|
|
45e748 |
free(rpmio_flags);
|
|
|
45e748 |
+ if (!gzdi)
|
|
|
45e748 |
+ rpmlog(RPMLOG_DEBUG, _("Fdopen() failed\n"));
|
|
|
45e748 |
|
|
|
45e748 |
files = rpmfilesNew(NULL, h, RPMTAG_BASENAMES, RPMFI_FLAGS_QUERY);
|
|
|
45e748 |
fi = rpmfiNewArchiveReader(gzdi, files,
|
|
|
45e748 |
@@ -123,39 +129,64 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
*/
|
|
|
45e748 |
headerDel(sigh, RPMSIGTAG_VERITYSIGNATURES);
|
|
|
45e748 |
|
|
|
45e748 |
- rpmtdReset(&td);
|
|
|
45e748 |
- td.tag = RPMSIGTAG_VERITYSIGNATURES;
|
|
|
45e748 |
- td.type = RPM_STRING_ARRAY_TYPE;
|
|
|
45e748 |
- td.count = 1;
|
|
|
45e748 |
+ /*
|
|
|
45e748 |
+ * The payload doesn't include special files, like ghost files, and
|
|
|
45e748 |
+ * we cannot rely on the file order in the payload to match that of
|
|
|
45e748 |
+ * the header. Instead we allocate an array of pointers and populate
|
|
|
45e748 |
+ * it as we go along. Then walk the header fi and account for the
|
|
|
45e748 |
+ * special files. Last we walk the array and populate the header.
|
|
|
45e748 |
+ */
|
|
|
45e748 |
+ nr_files = rpmfiFC(hfi);
|
|
|
45e748 |
+ signatures = xcalloc(nr_files, sizeof(char *));
|
|
|
45e748 |
+
|
|
|
45e748 |
+ rpmlog(RPMLOG_DEBUG, _("file count - header: %i, payload %i\n"),
|
|
|
45e748 |
+ nr_files, rpmfiFC(fi));
|
|
|
45e748 |
|
|
|
45e748 |
while (rpmfiNext(fi) >= 0) {
|
|
|
45e748 |
file_size = rpmfiFSize(fi);
|
|
|
45e748 |
+ idx = rpmfiFX(fi);
|
|
|
45e748 |
|
|
|
45e748 |
rpmlog(RPMLOG_DEBUG, _("file: %s, (size %li, link %s, idx %i)\n"),
|
|
|
45e748 |
rpmfiFN(fi), file_size, rpmfiFLink(fi), rpmfiFX(fi));
|
|
|
45e748 |
|
|
|
45e748 |
- sig_hex = rpmVeritySignFile(fi, &sig_size, key, keypass, cert);
|
|
|
45e748 |
+ signatures[idx] = rpmVeritySignFile(fi, &sig_size, key, keypass, cert);
|
|
|
45e748 |
+ }
|
|
|
45e748 |
+
|
|
|
45e748 |
+ while (rpmfiNext(hfi) >= 0) {
|
|
|
45e748 |
+ idx = rpmfiFX(hfi);
|
|
|
45e748 |
+ if (signatures[idx])
|
|
|
45e748 |
+ continue;
|
|
|
45e748 |
+ signatures[idx] = rpmVeritySignFile(hfi, &sig_size, key, keypass, cert);
|
|
|
45e748 |
+ }
|
|
|
45e748 |
+
|
|
|
45e748 |
+ rpmtdReset(&td);
|
|
|
45e748 |
+ td.tag = RPMSIGTAG_VERITYSIGNATURES;
|
|
|
45e748 |
+ td.type = RPM_STRING_ARRAY_TYPE;
|
|
|
45e748 |
+ td.count = 1;
|
|
|
45e748 |
+ for (idx = 0; idx < nr_files; idx++) {
|
|
|
45e748 |
+ sig_hex = signatures[idx];
|
|
|
45e748 |
td.data = &sig_hex;
|
|
|
45e748 |
- rpmlog(RPMLOG_DEBUG, _("digest signed, len: %li\n"), sig_size);
|
|
|
45e748 |
-#if 0
|
|
|
45e748 |
- rpmlog(RPMLOG_DEBUG, _("digest: %s\n"), (char *)sig_hex);
|
|
|
45e748 |
-#endif
|
|
|
45e748 |
if (!headerPut(sigh, &td, HEADERPUT_APPEND)) {
|
|
|
45e748 |
rpmlog(RPMLOG_ERR, _("headerPutString failed\n"));
|
|
|
45e748 |
rc = RPMRC_FAIL;
|
|
|
45e748 |
goto out;
|
|
|
45e748 |
}
|
|
|
45e748 |
- free(sig_hex);
|
|
|
45e748 |
+ rpmlog(RPMLOG_DEBUG, _("signature: %s\n"), signatures[idx]);
|
|
|
45e748 |
+ rpmlog(RPMLOG_DEBUG, _("digest signed, len: %li\n"), sig_size);
|
|
|
45e748 |
+ free(signatures[idx]);
|
|
|
45e748 |
+ signatures[idx] = NULL;
|
|
|
45e748 |
}
|
|
|
45e748 |
|
|
|
45e748 |
rpmlog(RPMLOG_DEBUG, _("sigh size: %i\n"), headerSizeof(sigh, 0));
|
|
|
45e748 |
|
|
|
45e748 |
rc = RPMRC_OK;
|
|
|
45e748 |
out:
|
|
|
45e748 |
+ signatures = _free(signatures);
|
|
|
45e748 |
Fseek(fd, offset, SEEK_SET);
|
|
|
45e748 |
|
|
|
45e748 |
rpmfilesFree(files);
|
|
|
45e748 |
rpmfiFree(fi);
|
|
|
45e748 |
+ rpmfiFree(hfi);
|
|
|
45e748 |
rpmtsFree(ts);
|
|
|
45e748 |
return rc;
|
|
|
45e748 |
}
|
|
|
45e748 |
--
|
|
|
45e748 |
2.27.0
|
|
|
45e748 |
|