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 */
uint32_t *signatureoffs; /*!< File signature offsets */
+ 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->digests = _free(fi->digests);
fi->signatures = _free(fi->signatures);
fi->signatureoffs = _free(fi->signatureoffs);
+ 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->signatureoffs);
}
+ 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