[Rpm-ecosystem] [PATCH v6 05/11] Add support for file signatures to rpmfi and rpmfiles

Mimi Zohar zohar at linux.vnet.ibm.com
Mon Jul 6 18:52:19 UTC 2015


From: "fin at linux.vnet.ibm.com" <fin at linux.vnet.ibm.com>

This patch adds file signatures and file signature length to rpmfiles.
These new members are set in rpmfilesPopulate, and they can be accessed
with rpmfiFSignature.
---
 lib/rpmfi.c    | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 lib/rpmfi.h    |  8 ++++++++
 lib/rpmfiles.h | 10 ++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index 86666f7..cb0190a 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -114,7 +114,9 @@ struct rpmfiles_s {
     struct fingerPrint_s * fps;	/*!< File fingerprint(s). */
 
     int digestalgo;		/*!< File digest algorithm */
+    int signaturelength;	/*!< File signature length */
     unsigned char * digests;	/*!< File digests in binary. */
+    unsigned char * signatures; /*!< File signatures in binary. */
 
     struct nlinkHash_s * nlinks;/*!< Files connected by hardlinks */
     rpm_off_t * replacedSizes;	/*!< (TR_ADDED) */
@@ -569,6 +571,19 @@ char * rpmfiFDigestHex(rpmfi fi, int *algo)
     return fdigest;
 }
 
+const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len)
+{
+	const unsigned char *signature = NULL;
+
+	if (fi != NULL && ix >= 0 && ix < rpmfilesFC(fi)) {
+	     if (fi->signatures != NULL)
+		signature = fi->signatures + (fi->signaturelength * ix);
+	     if (len)
+		*len = fi->signaturelength;
+	}
+	return signature;
+}
+
 const char * rpmfilesFLink(rpmfiles fi, int ix)
 {
     const char * flink = NULL;
@@ -1165,6 +1180,7 @@ rpmfiles rpmfilesFree(rpmfiles fi)
 	fi->flinks = _free(fi->flinks);
 	fi->flangs = _free(fi->flangs);
 	fi->digests = _free(fi->digests);
+	fi->signatures = _free(fi->signatures);
 	fi->fcaps = _free(fi->fcaps);
 
 	fi->cdict = _free(fi->cdict);
@@ -1379,7 +1395,7 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
     headerGetFlags scareFlags = (flags & RPMFI_KEEPHEADER) ? 
 				HEADERGET_MINMEM : HEADERGET_ALLOC;
     headerGetFlags defFlags = HEADERGET_ALLOC;
-    struct rpmtd_s fdigests, digalgo, td;
+    struct rpmtd_s fdigests, fsignatures, digalgo, td;
     unsigned char * t;
 
     /* XXX TODO: all these should be sanity checked, ugh... */
@@ -1430,6 +1446,8 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
 	}
     }
 
+    fi->signaturelength = headerGetNumber(h, RPMTAG_FILESIGNATURELENGTH);
+
     fi->digests = NULL;
     /* grab hex digests from header and store in binary format */
     if (!(flags & RPMFI_NOFILEDIGESTS) &&
@@ -1450,10 +1468,30 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
 	rpmtdFreeData(&fdigests);
     }
 
+    fi->signatures = NULL;
+    /* grab hex signatures from header and store in binary format */
+    if (! (flags & RPMFI_NOFILESIGNATURES) &&
+	headerGet(h, RPMTAG_FILESIGNATURES, &fsignatures, HEADERGET_MINMEM)) {
+	const char *fsignature;
+	fi->signatures = t = xmalloc(rpmtdCount(&fsignatures) * fi->signaturelength);
+
+	while ((fsignature = rpmtdNextString(&fsignatures))) {
+	    if (!(fsignature && *fsignature != '\0')) {
+		memset(t, 0, fi->signaturelength);
+		t += fi->signaturelength;
+		continue;
+	    }
+	    for (int j = 0; j < fi->signaturelength; j++, t++, fsignature += 2)
+		*t = (rnibble(fsignature[0]) << 4) | rnibble(fsignature[1]);
+	}
+	rpmtdFreeData(&fsignatures);
+    }
+
     /* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
     if (!(flags & RPMFI_NOFILEMTIMES))
 	_hgfi(h, RPMTAG_FILEMTIMES, &td, scareFlags, fi->fmtimes);
     if (!(flags & RPMFI_NOFILERDEVS))
+
 	_hgfi(h, RPMTAG_FILERDEVS, &td, scareFlags, fi->frdevs);
     if (!(flags & RPMFI_NOFILEINODES)) {
 	_hgfi(h, RPMTAG_FILEINODES, &td, scareFlags, fi->finodes);
@@ -1728,6 +1766,11 @@ const unsigned char * rpmfiFDigest(rpmfi fi, int *algo, size_t *len)
     return rpmfilesFDigest(fi->files, fi ? fi->i : -1, algo, len);
 }
 
+const unsigned char * rpmfiFSignature(rpmfi fi, size_t *len)
+{
+    return rpmfilesFSignature(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 1752b71..6a00a14 100644
--- a/lib/rpmfi.h
+++ b/lib/rpmfi.h
@@ -183,6 +183,14 @@ const unsigned char * rpmfiFDigest(rpmfi fi, int *algo, size_t *diglen);
 char * rpmfiFDigestHex(rpmfi fi, int *algo);
 
 /** \ingroup rpmfi
+ * Return current file (binary) signature of file info set iterator.
+ * @param fi		file info set iterator
+ * @retval siglen	signature length (pass NULL to ignore)
+ * @return		current file signature, NULL on invalid
+ */
+const unsigned char * rpmfiFSignature(rpmfi fi, size_t *siglen);
+
+/** \ingroup rpmfi
  * Return current file (binary) md5 digest from file info set iterator.
  * @deprecated		Use rpmfiFDigest() instead
  * @param fi		file info set iterator
diff --git a/lib/rpmfiles.h b/lib/rpmfiles.h
index 8a9de31..27fe493 100644
--- a/lib/rpmfiles.h
+++ b/lib/rpmfiles.h
@@ -116,6 +116,7 @@ enum rpmfiFlags_e {
     RPMFI_NOFILECOLORS		= (1 << 15),
     RPMFI_NOFILEVERIFYFLAGS	= (1 << 16),
     RPMFI_NOFILEFLAGS		= (1 << 17),
+    RPMFI_NOFILESIGNATURES	= (1 << 18),
 };
 
 typedef rpmFlags rpmfiFlags;
@@ -428,6 +429,15 @@ rpm_mode_t rpmfilesFMode(rpmfiles fi, int ix);
 const unsigned char * rpmfilesFDigest(rpmfiles fi, int ix, int *algo, size_t *len);
 
 /** \ingroup rpmfiles
+ * Return file (binary) digest of file info set.
+ * @param fi            file info set
+ * @param ix            file index
+ * @retval siglen       signature length (pass NULL to ignore)
+ * @return              file signature, NULL on invalid
+ */
+const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len);
+
+/** \ingroup rpmfiles
  * Return file rdev from file info set.
  * @param fi		file info set
  * @param ix		file index
-- 
2.1.0



More information about the Rpm-ecosystem mailing list