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