All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
To: linux-integrity@vger.kernel.org
Cc: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>,
	Roberto Sassu <roberto.sassu@huawei.com>,
	"Bruno E . O . Meneguele" <brdeoliv@redhat.com>,
	Mimi Zohar <zohar@linux.vnet.ibm.com>
Subject: [PATCH 05/10] ima-evm-utils: support verifying the measurement list using multiple keys
Date: Mon, 22 Jan 2018 09:54:00 -0500	[thread overview]
Message-ID: <1516632845-7087-6-git-send-email-zohar@linux.vnet.ibm.com> (raw)
In-Reply-To: <1516632845-7087-1-git-send-email-zohar@linux.vnet.ibm.com>

On a running system, different software packages might be signed by
different parties.  Support verifying signatures in the measurement
list using multiple public keys(eg.  -k "key1, key2, ...").

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 README          |  2 +-
 src/evmctl.c    |  4 +++
 src/imaevm.h    |  1 +
 src/libimaevm.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/README b/README
index da828cf..1c4bc7a 100644
--- a/README
+++ b/README
@@ -31,7 +31,7 @@ COMMANDS
  ima_sign [--sigfile] [--key key] [--pass password] file
  ima_verify file
  ima_hash file
- ima_measurement file
+ ima_measurement [--key "key1, key2, ..."] file
  ima_fix [-t fdsxm] path
  sign_hash [--key key] [--pass password]
  hmac [--imahash | --imasig ] file
diff --git a/src/evmctl.c b/src/evmctl.c
index 746fc09..e0ed93d 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1419,6 +1419,10 @@ static int ima_measurement(const char *file)
 		return -1;
 	}
 
+	/* Support multiple public keys */
+	if (params.keyfile)
+		init_public_keys(params.keyfile);
+
 	while (fread(&entry.header, sizeof(entry.header), 1, fp)) {
 		ima_extend_pcr(pcr, entry.header.digest, SHA_DIGEST_LENGTH);
 
diff --git a/src/imaevm.h b/src/imaevm.h
index e397743..ea6a7b1 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -205,5 +205,6 @@ int key2bin(RSA *key, unsigned char *pub);
 int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
 int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen);
 int ima_verify_signature(const char *file, unsigned char *sig, int siglen);
+void init_public_keys(const char *keyfiles);
 
 #endif
diff --git a/src/libimaevm.c b/src/libimaevm.c
index a92deed..0ad290a 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -408,6 +408,61 @@ int verify_hash_v1(const unsigned char *hash, int size, unsigned char *sig, int
 	return 0;
 }
 
+struct public_key_entry {
+	struct public_key_entry *next;
+	uint32_t keyid;
+	char name[9];
+	RSA *key;
+};
+static struct public_key_entry *public_keys = NULL;
+
+static RSA *find_keyid(uint32_t keyid)
+{
+	struct public_key_entry *entry;
+
+	for (entry = public_keys; entry != NULL; entry = entry->next) {
+		if (entry->keyid == keyid)
+			return entry->key;
+	}
+	return NULL;
+}
+
+void init_public_keys(const char *keyfiles)
+{
+	struct public_key_entry *entry;
+	char *tmp_keyfiles;
+	char *keyfile;
+	int i = 1;
+
+	tmp_keyfiles = strdup(keyfiles);
+
+	while ((keyfile = strsep(&tmp_keyfiles, ", \t")) != NULL) {
+		if (!keyfile)
+			break;
+		if ((*keyfile == '\0') || (*keyfile == ' ') ||
+		    (*keyfile == '\t'))
+			continue;
+
+		entry = malloc(sizeof(struct public_key_entry));
+		if (!entry) {
+			perror("malloc");
+			break;
+		}
+
+		entry->key = read_pub_key(keyfile, 1);
+		if (!entry->key) {
+			free(entry);
+			continue;
+		}
+
+		calc_keyid_v2(&entry->keyid, entry->name, entry->key);
+		sprintf(entry->name, "%x", __be32_to_cpup(&entry->keyid));
+		log_info("key %d: %s %s\n", i++, entry->name, keyfile);
+		entry->next = public_keys;
+		public_keys = entry;
+	}
+}
+
 int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int siglen, const char *keyfile)
 {
 	int err, len;
@@ -419,12 +474,22 @@ int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int
 	log_info("hash: ");
 	log_dump(hash, size);
 
-	key = read_pub_key(keyfile, 1);
-	if (!key)
-		return 1;
+	if (public_keys) {
+		key = find_keyid(hdr->keyid);
+		if (!key) {
+			log_err("Unknown keyid: %x\n",
+				__be32_to_cpup(&hdr->keyid));
+			return -1;
+		}
+	} else {
+		key = read_pub_key(keyfile, 1);
+		if (!key)
+			return 1;
+	}
 
-	err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr), out, key, RSA_PKCS1_PADDING);
-	RSA_free(key);
+
+	err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr),
+				 out, key, RSA_PKCS1_PADDING);
 	if (err < 0) {
 		log_err("RSA_public_decrypt() failed: %d\n", err);
 		return 1;
-- 
2.7.4

  parent reply	other threads:[~2018-01-22 14:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
2018-01-22 14:53 ` [PATCH 01/10] ima-evm-utils: fix "ima_measurement" template fields length Mimi Zohar
2018-01-22 14:53 ` [PATCH 02/10] ima-evm-utils: revert the change to use printf instead of log_info() Mimi Zohar
2018-01-22 14:53 ` [PATCH 03/10] ima-evm-utils: fix spelling error Mimi Zohar
2018-01-22 14:53 ` [PATCH 04/10] ima-evm-utils: remove the unnecessary display of the keyid Mimi Zohar
2018-01-22 14:54 ` Mimi Zohar [this message]
2018-01-22 14:54 ` [PATCH 06/10] ima-evm-utils: indicate measurement list signature verification failure Mimi Zohar
2018-01-22 14:54 ` [PATCH 07/10] ima-evm-utils: add support for specifying the pcr file location Mimi Zohar
2018-01-22 14:54 ` [PATCH 08/10] ima-evm-utils: verify the measurement list signature based on the list digest Mimi Zohar
2018-01-22 14:54 ` [PATCH 09/10] ima-evm-utils: verify IMA file hashes stored as xattrs Mimi Zohar
2018-01-22 14:54 ` [PATCH 10/10] ima-evm-utils: add support for validating multiple pcrs Mimi Zohar
2018-01-28 19:01 ` [PATCH 00/10] ima-evm-utils Mimi Zohar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1516632845-7087-6-git-send-email-zohar@linux.vnet.ibm.com \
    --to=zohar@linux.vnet.ibm.com \
    --cc=brdeoliv@redhat.com \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=linux-integrity@vger.kernel.org \
    --cc=roberto.sassu@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.