[Rpm-maint] [RFC v4 04/11] Add support for file signatures to rpmfi and rpmfiles

fin at linux.vnet.ibm.com fin at linux.vnet.ibm.com
Tue Jan 13 18:33:07 UTC 2015


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.

Signed-off-by: Fionnuala Gunter <fin at linux.vnet.ibm.com>
---
 lib/rpmfi.c    | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/rpmfi.h    | 16 ++++++++++++++++
 lib/rpmfiles.h | 10 ++++++++++
 3 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index 2fba707..d642f39 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -111,7 +111,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) */
@@ -560,6 +562,31 @@ 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;
+}
+
+char *rpmfiFSignatureHex(rpmfi fi)
+{
+    size_t siglen = 0;
+    char *fsignature = NULL;
+    const unsigned char *signature = rpmfiFSignature(fi, &siglen);
+
+    if (signature) {
+	fsignature = pgpHexStr(signature, siglen);
+    }
+    return fsignature;
+}
+
 const char * rpmfilesFLink(rpmfiles fi, int ix)
 {
     const char * flink = NULL;
@@ -1146,6 +1173,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);
@@ -1360,7 +1388,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... */
@@ -1411,6 +1439,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) &&
@@ -1431,10 +1461,29 @@ 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 (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);
@@ -1662,6 +1711,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 dd44451..cc0917c 100644
--- a/lib/rpmfi.h
+++ b/lib/rpmfi.h
@@ -181,6 +181,22 @@ 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 (hex) signature of file info set iterator.
+ * The file info set iterator stores files signatures in binary format to
+ * conserve memory, this converts the binary data back to hex presentation used
+ * in headers.
+ */
+char * rpmfiFSignatureHex(rpmfi fi);
+
+/** \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 928c420..d966590 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;
@@ -417,6 +418,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
-- 
1.9.3



More information about the Rpm-maint mailing list