Blob Blame History Raw
From 34e751ccee43f799dd32f6b9c64020106dba9fac Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Mon, 13 Apr 2020 18:21:36 -0400
Subject: [PATCH 23/33] Process verity tag on package read

This processes verity signature tags on package read, and provides
accessor functions to access them.

Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
 lib/rpmfi.c          | 27 +++++++++++++++++++++++++++
 lib/rpmfi.h          |  8 ++++++++
 lib/rpmfiles.h       | 10 ++++++++++
 sign/rpmsignverity.c | 20 ++++++++++++++++----
 4 files changed, 61 insertions(+), 4 deletions(-)

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