libkmod: Return module signature information in kmod_module_get_info()

If the module is built with CONFIG_MODULE_SIG, add the the signer's
name, hexadecimal key id and hash algorithm to the list returned in
kmod_module_get_info(). The modinfo output then looks like this:

filename:       /home/mmarek/kmod/testsuite/rootfs-pristine/test-modinfo/ext4-x86_64-sha256.ko
license:        GPL
description:    Fourth Extended Filesystem
author:         Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others
alias:          ext3
alias:          ext2
depends:        mbcache,jbd2
intree:         Y
vermagic:       3.7.0 SMP mod_unload
signer:         Magrathea: Glacier signing key
sig_key:        E3:C8:FC:A7:3F:B3:1D:DE:84:81:EF:38:E3:4C:DE:4B:0C:FD:1B:F9
sig_hashalgo:   sha256

The signature algorithm (RSA) and key identifier type (X509) are not
displayed, because they are constant information for every signed
module. But it would be trivial to add this. Note: No attempt is made at
verifying the signature, I don't think that modinfo is the right tool
for this.
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 2f4acd5..b1d40b1 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -2120,7 +2120,9 @@
  *
  * Get a list of entries in ELF section ".modinfo", these contain
  * alias, license, depends, vermagic and other keys with respective
- * values.
+ * values. If the module is signed (CONFIG_MODULE_SIG), information
+ * about the module signature is included as well: signer,
+ * sig_key and sig_hashalgo.
  *
  * After use, free the @list by calling kmod_module_info_free_list().
  *
@@ -2131,6 +2133,7 @@
 	struct kmod_elf *elf;
 	char **strings;
 	int i, count, ret = -ENOMEM;
+	struct kmod_signature_info sig_info;
 
 	if (mod == NULL || list == NULL)
 		return -ENOENT;
@@ -2165,6 +2168,46 @@
 		if (n == NULL)
 			goto list_error;
 	}
+
+	if (kmod_module_signature_info(mod->file, &sig_info)) {
+		struct kmod_list *n;
+		char *key_hex;
+
+		n = kmod_module_info_append(list, "signer", strlen("signer"),
+				sig_info.signer, sig_info.signer_len);
+		if (n == NULL)
+			goto list_error;
+		count++;
+
+		/* Display the key id as 01:12:DE:AD:BE:EF:... */
+		key_hex = malloc(sig_info.key_id_len * 3);
+		if (key_hex == NULL)
+			goto list_error;
+		for (i = 0; i < (int)sig_info.key_id_len; i++) {
+			sprintf(key_hex + i * 3, "%02X",
+					(unsigned char)sig_info.key_id[i]);
+			if (i < (int)sig_info.key_id_len - 1)
+				key_hex[i * 3 + 2] = ':';
+		}
+		n = kmod_module_info_append(list, "sig_key", strlen("sig_key"),
+				key_hex, sig_info.key_id_len * 3 - 1);
+		free(key_hex);
+		if (n == NULL)
+			goto list_error;
+		count++;
+
+		n = kmod_module_info_append(list,
+				"sig_hashalgo", strlen("sig_hashalgo"),
+				sig_info.hash_algo, strlen(sig_info.hash_algo));
+		if (n == NULL)
+			goto list_error;
+		count++;
+
+		/*
+		 * Omit sig_info.id_type and sig_info.algo for now, as these
+		 * are currently constant.
+		 */
+	}
 	ret = count;
 
 list_error: