malmond / rpms / rpm

Forked from rpms/rpm 5 years ago
Clone

Blame SOURCES/0023-rpmSignVerity-Generate-signatures-for-files-not-pres.patch

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