45e748
From 34e751ccee43f799dd32f6b9c64020106dba9fac Mon Sep 17 00:00:00 2001
45e748
From: Jes Sorensen <jsorensen@fb.com>
45e748
Date: Mon, 13 Apr 2020 18:21:36 -0400
45e748
Subject: [PATCH 23/33] Process verity tag on package read
45e748
45e748
This processes verity signature tags on package read, and provides
45e748
accessor functions to access them.
45e748
45e748
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
45e748
---
45e748
 lib/rpmfi.c          | 27 +++++++++++++++++++++++++++
45e748
 lib/rpmfi.h          |  8 ++++++++
45e748
 lib/rpmfiles.h       | 10 ++++++++++
45e748
 sign/rpmsignverity.c | 20 ++++++++++++++++----
45e748
 4 files changed, 61 insertions(+), 4 deletions(-)
45e748
45e748
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
45e748
index 8c69d3e40..5fdbe02a2 100644
45e748
--- a/lib/rpmfi.c
45e748
+++ b/lib/rpmfi.c
45e748
@@ -116,8 +116,10 @@ struct rpmfiles_s {
45e748
 
45e748
     int digestalgo;		/*!< File digest algorithm */
45e748
     uint32_t *signatureoffs;	/*!< File signature offsets */
45e748
+    int veritysiglength;	/*!< Verity signature length */
45e748
     unsigned char * digests;	/*!< File digests in binary. */
45e748
     unsigned char * signatures; /*!< File signatures in binary. */
45e748
+    unsigned char * veritysigs; /*!< Verity signatures in binary. */
45e748
 
45e748
     struct nlinkHash_s * nlinks;/*!< Files connected by hardlinks */
45e748
     rpm_off_t * replacedSizes;	/*!< (TR_ADDED) */
45e748
@@ -582,6 +584,19 @@ const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len)
45e748
     return signature;
45e748
 }
45e748
 
45e748
+const unsigned char * rpmfilesVSignature(rpmfiles fi, int ix, size_t *len)
45e748
+{
45e748
+    const unsigned char *vsignature = NULL;
45e748
+
45e748
+    if (fi != NULL && ix >= 0 && ix < rpmfilesFC(fi)) {
45e748
+	if (fi->veritysigs != NULL)
45e748
+	    vsignature = fi->veritysigs + (fi->veritysiglength * ix);
45e748
+	if (len)
45e748
+	    *len = fi->veritysiglength;
45e748
+    }
45e748
+    return vsignature;
45e748
+}
45e748
+
45e748
 const char * rpmfilesFLink(rpmfiles fi, int ix)
45e748
 {
45e748
     const char * flink = NULL;
45e748
@@ -1268,6 +1283,7 @@ rpmfiles rpmfilesFree(rpmfiles fi)
45e748
 	fi->digests = _free(fi->digests);
45e748
 	fi->signatures = _free(fi->signatures);
45e748
 	fi->signatureoffs = _free(fi->signatureoffs);
45e748
+	fi->veritysigs = _free(fi->veritysigs);
45e748
 	fi->fcaps = _free(fi->fcaps);
45e748
 
45e748
 	fi->cdict = _free(fi->cdict);
45e748
@@ -1649,6 +1665,12 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
45e748
 				 totalfc, &fi->signatureoffs);
45e748
     }
45e748
 
45e748
+    fi->veritysigs = NULL;
45e748
+    if (!(flags & RPMFI_NOVERITYSIGNATURES)) {
45e748
+	fi->veritysigs = base2bin(h, RPMTAG_VERITYSIGNATURES,
45e748
+				  totalfc, &fi->veritysiglength);
45e748
+    }
45e748
+
45e748
     /* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
45e748
     if (!(flags & RPMFI_NOFILEMTIMES))
45e748
 	_hgfi(h, RPMTAG_FILEMTIMES, &td, scareFlags, fi->fmtimes);
45e748
@@ -1939,6 +1961,11 @@ const unsigned char * rpmfiFSignature(rpmfi fi, size_t *len)
45e748
     return rpmfilesFSignature(fi->files, fi ? fi->i : -1, len);
45e748
 }
45e748
 
45e748
+const unsigned char * rpmfiVSignature(rpmfi fi, size_t *len)
45e748
+{
45e748
+    return rpmfilesVSignature(fi->files, fi ? fi->i : -1, len);
45e748
+}
45e748
+
45e748
 uint32_t rpmfiFDepends(rpmfi fi, const uint32_t ** fddictp)
45e748
 {
45e748
     return rpmfilesFDepends(fi->files,  fi ? fi->i : -1, fddictp);
45e748
diff --git a/lib/rpmfi.h b/lib/rpmfi.h
45e748
index 6ef70cd28..fcb9d3acd 100644
45e748
--- a/lib/rpmfi.h
45e748
+++ b/lib/rpmfi.h
45e748
@@ -190,6 +190,14 @@ char * rpmfiFDigestHex(rpmfi fi, int *algo);
45e748
  */
45e748
 const unsigned char * rpmfiFSignature(rpmfi fi, size_t *siglen);
45e748
 
45e748
+/** \ingroup rpmfi
45e748
+ * Return current verity (binary) signature of file info set iterator.
45e748
+ * @param fi		file info set iterator
45e748
+ * @retval siglen	signature length (pass NULL to ignore)
45e748
+ * @return		current verity signature, NULL on invalid
45e748
+ */
45e748
+const unsigned char * rpmfiVSignature(rpmfi fi, size_t *siglen);
45e748
+
45e748
 /** \ingroup rpmfi
45e748
  * Return current file linkto (i.e. symlink(2) target) from file info set iterator.
45e748
  * @param fi		file info set iterator
45e748
diff --git a/lib/rpmfiles.h b/lib/rpmfiles.h
45e748
index daf572cf4..81b3d01a1 100644
45e748
--- a/lib/rpmfiles.h
45e748
+++ b/lib/rpmfiles.h
45e748
@@ -119,6 +119,7 @@ enum rpmfiFlags_e {
45e748
     RPMFI_NOFILEVERIFYFLAGS	= (1 << 16),
45e748
     RPMFI_NOFILEFLAGS		= (1 << 17),
45e748
     RPMFI_NOFILESIGNATURES	= (1 << 18),
45e748
+    RPMFI_NOVERITYSIGNATURES	= (1 << 19),
45e748
 };
45e748
 
45e748
 typedef rpmFlags rpmfiFlags;
45e748
@@ -442,6 +443,15 @@ const unsigned char * rpmfilesFDigest(rpmfiles fi, int ix, int *algo, size_t *le
45e748
  */
45e748
 const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len);
45e748
 
45e748
+/** \ingroup rpmfiles
45e748
+ * Return file verity signature (binary)
45e748
+ * @param fi            file info set
45e748
+ * @param ix            file index
45e748
+ * @retval len       signature length (pass NULL to ignore)
45e748
+ * @return              verity signature, NULL on invalid
45e748
+ */
45e748
+const unsigned char * rpmfilesVSignature(rpmfiles fi, int ix, size_t *len);
45e748
+
45e748
 /** \ingroup rpmfiles
45e748
  * Return file rdev from file info set.
45e748
  * @param fi		file info set
45e748
diff --git a/sign/rpmsignverity.c b/sign/rpmsignverity.c
45e748
index 3bb23a18d..177561957 100644
45e748
--- a/sign/rpmsignverity.c
45e748
+++ b/sign/rpmsignverity.c
45e748
@@ -15,6 +15,7 @@
45e748
 #include "lib/rpmtypes.h"	/* rpmRC */
45e748
 #include <libfsverity.h>
45e748
 #include "rpmio/rpmio_internal.h"
45e748
+#include "rpmio/rpmbase64.h"
45e748
 #include "lib/rpmvs.h"
45e748
 
45e748
 #include "sign/rpmsignverity.h"
45e748
@@ -40,7 +41,7 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
45e748
     struct libfsverity_signature_params sig_params;
45e748
     struct libfsverity_digest *digest = NULL;
45e748
     rpm_loff_t file_size;
45e748
-    char *digest_hex, *sig_hex = NULL;
45e748
+    char *digest_hex, *digest_base64, *sig_base64 = NULL, *sig_hex = NULL;
45e748
     uint8_t *sig = NULL;
45e748
     int status;
45e748
 
45e748
@@ -60,8 +61,14 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
45e748
     }
45e748
 
45e748
     digest_hex = pgpHexStr(digest->digest, digest->digest_size);
45e748
-    rpmlog(RPMLOG_DEBUG, _("digest(%i): %s\n"),
45e748
-	   digest->digest_size, digest_hex);
45e748
+    digest_base64 = rpmBase64Encode(digest->digest, digest->digest_size, -1);
45e748
+    rpmlog(RPMLOG_DEBUG, _("file(size %li): %s: digest(%i): %s, idx %i\n"),
45e748
+	   file_size, rpmfiFN(fi), digest->digest_size, digest_hex,
45e748
+	   rpmfiFX(fi));
45e748
+    rpmlog(RPMLOG_DEBUG, _("file(size %li): %s: digest sz (%i): base64 sz (%li), %s, idx %i\n"),
45e748
+	   file_size, rpmfiFN(fi), digest->digest_size, strlen(digest_base64),
45e748
+	   digest_base64, rpmfiFX(fi));
45e748
+
45e748
     free(digest_hex);
45e748
 
45e748
     memset(&sig_params, 0, sizeof(struct libfsverity_signature_params));
45e748
@@ -73,10 +80,15 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
45e748
     }
45e748
 
45e748
     sig_hex = pgpHexStr(sig, *sig_size);
45e748
+    sig_base64 = rpmBase64Encode(sig, *sig_size, -1);
45e748
+    rpmlog(RPMLOG_DEBUG, _("%s: sig_size(%li), base64_size(%li), idx %i: signature:\n%s\n"),
45e748
+	   rpmfiFN(fi), *sig_size, strlen(sig_base64), rpmfiFX(fi), sig_hex);
45e748
  out:
45e748
+    free(sig_hex);
45e748
+
45e748
     free(digest);
45e748
     free(sig);
45e748
-    return sig_hex;
45e748
+    return sig_base64;
45e748
 }
45e748
 
45e748
 rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
45e748
-- 
45e748
2.27.0
45e748