mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: rusty@rustcorp.com.au
Cc: keyrings@linux-nfs.org, jwboyer@redhat.com,
	linux-kernel@vger.kernel.org, dhowells@redhat.com,
	linux-security-module@vger.kernel.org, pjones@redhat.com,
	vgoyal@redhat.com
Subject: [PATCH 06/13] KEYS: Implement binary asymmetric key ID handling
Date: Mon, 08 Sep 2014 16:38:09 +0100	[thread overview]
Message-ID: <20140908153809.28301.79665.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <20140908153704.28301.41578.stgit@warthog.procyon.org.uk>

Implement the first step in using binary key IDs for asymmetric keys rather
than hex string keys.

The previously added match data preparsing will be able to convert hex
criterion strings into binary which can then be compared more rapidly.

Further, we actually want more then one ID string per public key.  The problem
is that X.509 certs refer to other X.509 certs by matching Issuer + AuthKeyId
to Subject + SubjKeyId, but PKCS#7 messages match against X.509 Issuer +
SerialNumber.

This patch just provides facilities for a later patch to make use of.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 crypto/asymmetric_keys/asymmetric_keys.h |    4 +
 crypto/asymmetric_keys/asymmetric_type.c |   82 ++++++++++++++++++++++++++++++
 include/keys/asymmetric-type.h           |   38 ++++++++++++++
 3 files changed, 124 insertions(+)

diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
index a63c551c6557..917be6b985e7 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -10,6 +10,10 @@
  */
 
 int asymmetric_keyid_match(const char *kid, const char *id);
+extern bool asymmetric_match_key_ids(const struct asymmetric_key_ids *kids,
+				     const struct asymmetric_key_id *match_id);
+
+extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
 
 static inline const char *asymmetric_key_id(const struct key *key)
 {
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 7755f918e8d9..3bc71b4e1eed 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -15,6 +15,7 @@
 #include <linux/seq_file.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/ctype.h>
 #include "asymmetric_keys.h"
 
 MODULE_LICENSE("GPL");
@@ -23,6 +24,87 @@ static LIST_HEAD(asymmetric_key_parsers);
 static DECLARE_RWSEM(asymmetric_key_parsers_sem);
 
 /*
+ * Construct an asymmetric key ID from two binary blobs.
+ */
+struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
+						     size_t len_1,
+						     const void *val_2,
+						     size_t len_2)
+{
+	struct asymmetric_key_id *kid;
+
+	kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + 4 + len_2,
+		      GFP_KERNEL);
+	if (!kid)
+		return ERR_PTR(-ENOMEM);
+	kid->len = len_1 + 4 + len_2;
+	memcpy(kid->data, val_1, len_1);
+	kid->data[len_1 + 0] = 0xff;
+	kid->data[len_1 + 1] = 0xff;
+	kid->data[len_1 + 2] = 0xff;
+	kid->data[len_1 + 3] = 0xff;
+	memcpy(kid->data + len_1 + 4, val_2, len_2);
+	return kid;
+}
+
+/*
+ * Return true if two asymmetric keys are the same.
+ */
+bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
+			    const struct asymmetric_key_id *kid2)
+{
+	if (!kid1 || !kid2)
+		return false;
+	if (kid1->len != kid2->len)
+		return false;
+	return memcmp(kid1->data, kid2->data, kid1->len) == 0;
+}
+
+/*
+ * Match asymmetric key id with partial match
+ * @id: key id to match in a form "id:<id>"
+ */
+bool asymmetric_match_key_ids(const struct asymmetric_key_ids *kids,
+			      const struct asymmetric_key_id *match_id)
+{
+	if (!kids || !match_id)
+		return false;
+	if (asymmetric_key_id_same(kids->id[0], match_id))
+		return true;
+	if (asymmetric_key_id_same(kids->id[1], match_id))
+		return true;
+	return false;
+}
+EXPORT_SYMBOL_GPL(asymmetric_match_key_ids);
+
+/**
+ * Convert a hex string into a key ID.
+ */
+struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
+{
+	struct asymmetric_key_id *match_id;
+	const char *p;
+	ptrdiff_t hexlen;
+
+	if (!*id)
+		return ERR_PTR(-EINVAL);
+	for (p = id; *p; p++)
+		if (!isxdigit(*p))
+			return ERR_PTR(-EINVAL);
+	hexlen = p - id;
+	if (hexlen & 1)
+		return ERR_PTR(-EINVAL);
+
+	match_id = kmalloc(sizeof(struct asymmetric_key_id) + hexlen / 2,
+			   GFP_KERNEL);
+	if (!match_id)
+		return ERR_PTR(-ENOMEM);
+	match_id->len = hexlen / 2;
+	hex2bin(match_id->data, id, hexlen / 2);
+	return match_id;
+}
+
+/*
  * Match asymmetric key id with partial match
  * @id:		key id to match in a form "id:<id>"
  */
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
index 7dd473496180..044ab0d3aa45 100644
--- a/include/keys/asymmetric-type.h
+++ b/include/keys/asymmetric-type.h
@@ -19,6 +19,44 @@
 extern struct key_type key_type_asymmetric;
 
 /*
+ * Identifiers for an asymmetric key ID.  We have three ways of looking up a
+ * key derived from an X.509 certificate:
+ *
+ * (1) Serial Number & Issuer.  Non-optional.  This is the only valid way to
+ *     map a PKCS#7 signature to an X.509 certificate.
+ *
+ * (2) Issuer & Subject Unique IDs.  Optional.  These were the original way to
+ *     match X.509 certificates, but have fallen into disuse in favour of (3).
+ *
+ * (3) Auth & Subject Key Identifiers.  Optional.  SKIDs are only provided on
+ *     CA keys that are intended to sign other keys, so don't appear in end
+ *     user certificates unless forced.
+ *
+ * We could also support an PGP key identifier, which is just a SHA1 sum of the
+ * public key and certain parameters, but since we don't support PGP keys at
+ * the moment, we shall ignore those.
+ *
+ * What we actually do is provide a place where binary identifiers can be
+ * stashed and then compare against them when checking for an id match.
+ */
+struct asymmetric_key_id {
+	unsigned short	len;
+	unsigned char	data[];
+};
+
+struct asymmetric_key_ids {
+	void		*id[2];
+};
+
+extern bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
+				   const struct asymmetric_key_id *kid2);
+
+extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
+							    size_t len_1,
+							    const void *val_2,
+							    size_t len_2);
+
+/*
  * The payload is at the discretion of the subtype.
  */
 


  parent reply	other threads:[~2014-09-08 15:38 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-08 15:37 [RFC][PATCH 00/13] MODSIGN: Use PKCS#7 for module signatures David Howells
2014-09-08 15:37 ` [PATCH 01/13] Provide a binary to hex conversion utility David Howells
2014-09-08 15:37 ` [PATCH 02/13] KEYS: Preparse match data David Howells
2014-09-08 15:37 ` [PATCH 03/13] KEYS: Remove key_type::def_lookup_type David Howells
2014-09-08 15:37 ` [PATCH 04/13] KEYS: Remove key_type::match in favour of overriding default by match_preparse David Howells
2014-09-08 15:37 ` [PATCH 05/13] KEYS: Make the key matching functions return bool David Howells
2014-09-08 15:38 ` David Howells [this message]
2014-09-08 15:38 ` [PATCH 07/13] PKCS#7: Clean up the signed info freeing and fix the parser cleanup David Howells
2014-09-08 15:38 ` [PATCH 08/13] KEYS: Overhaul key identification when searching for asymmetric keys David Howells
2014-10-02 15:49   ` Dmitry Kasatkin
2014-10-02 16:04     ` Dmitry Kasatkin
2014-10-02 18:32       ` Dmitry Kasatkin
2014-10-02 18:38       ` Mimi Zohar
2014-10-03 12:20       ` David Howells
2014-10-03 12:22       ` David Howells
2014-10-03 12:13     ` David Howells
2014-10-03 12:25       ` Dmitry Kasatkin
2014-10-03 12:12   ` David Howells
2014-10-03 12:23     ` Dmitry Kasatkin
2014-09-08 15:38 ` [PATCH 09/13] PKCS#7: Better handling of unsupported crypto David Howells
2014-09-08 15:38 ` [PATCH 10/13] PKCS#7: Handle PKCS#7 messages that contain no X.509 certs David Howells
2014-09-08 15:39 ` [PATCH 11/13] PKCS#7: Allow detached data to be supplied for signature checking purposes David Howells
2014-09-08 15:39 ` [PATCH 12/13] MODSIGN: Provide a utility to append a PKCS#7 signature to a module David Howells
2014-09-08 15:39 ` [PATCH 13/13] MODSIGN: Use PKCS#7 messages as module signatures David Howells

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=20140908153809.28301.79665.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=jwboyer@redhat.com \
    --cc=keyrings@linux-nfs.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=pjones@redhat.com \
    --cc=rusty@rustcorp.com.au \
    --cc=vgoyal@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome