summary refs log tree commit diff
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-08-06 00:52:01 +1000
committerJames Morris <james.l.morris@oracle.com>2014-08-06 00:52:01 +1000
commit478d085524c57cf4283699f529d5a4c22188ea69 (patch)
treee97cdfff78867f247871be7f89341f087c766311
parent103ae675b12dee75ec099abf3d22857d1384b3bc (diff)
parentcf5b50fd2d70fdd907d433bcebaf8d89a9490334 (diff)
downloadlinux-478d085524c57cf4283699f529d5a4c22188ea69.tar.gz
Merge tag 'keys-next-20140805' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into next
-rw-r--r--crypto/asymmetric_keys/pkcs7_key_type.c2
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c61
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c6
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c42
-rw-r--r--include/crypto/public_key.h4
5 files changed, 34 insertions, 81 deletions
diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c
index 197ecdc0a5a1..3de5fb011de0 100644
--- a/crypto/asymmetric_keys/pkcs7_key_type.c
+++ b/crypto/asymmetric_keys/pkcs7_key_type.c
@@ -70,7 +70,7 @@ error:
  * user defined keys take an arbitrary string as the description and an
  * arbitrary blob of data as the payload
  */
-struct key_type key_type_pkcs7 = {
+static struct key_type key_type_pkcs7 = {
 	.name			= "pkcs7_test",
 	.def_lookup_type	= KEYRING_SEARCH_LOOKUP_DIRECT,
 	.preparse		= pkcs7_preparse,
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index b6b045131403..e666eb011a85 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -20,55 +20,6 @@
 #include "public_key.h"
 #include "pkcs7_parser.h"
 
-/*
- * Request an asymmetric key.
- */
-static struct key *pkcs7_request_asymmetric_key(
-	struct key *keyring,
-	const char *signer, size_t signer_len,
-	const char *authority, size_t auth_len)
-{
-	key_ref_t key;
-	char *id;
-
-	kenter(",%zu,,%zu", signer_len, auth_len);
-
-	/* Construct an identifier. */
-	id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL);
-	if (!id)
-		return ERR_PTR(-ENOMEM);
-
-	memcpy(id, signer, signer_len);
-	id[signer_len + 0] = ':';
-	id[signer_len + 1] = ' ';
-	memcpy(id + signer_len + 2, authority, auth_len);
-	id[signer_len + 2 + auth_len] = 0;
-
-	pr_debug("Look up: \"%s\"\n", id);
-
-	key = keyring_search(make_key_ref(keyring, 1),
-			     &key_type_asymmetric, id);
-	if (IS_ERR(key))
-		pr_debug("Request for module key '%s' err %ld\n",
-			 id, PTR_ERR(key));
-	kfree(id);
-
-	if (IS_ERR(key)) {
-		switch (PTR_ERR(key)) {
-			/* Hide some search errors */
-		case -EACCES:
-		case -ENOTDIR:
-		case -EAGAIN:
-			return ERR_PTR(-ENOKEY);
-		default:
-			return ERR_CAST(key);
-		}
-	}
-
-	pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key)));
-	return key_ref_to_ptr(key);
-}
-
 /**
  * Check the trust on one PKCS#7 SignedInfo block.
  */
@@ -98,10 +49,8 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
 		/* Look to see if this certificate is present in the trusted
 		 * keys.
 		 */
-		key = pkcs7_request_asymmetric_key(
-			trust_keyring,
-			x509->subject, strlen(x509->subject),
-			x509->fingerprint, strlen(x509->fingerprint));
+		key = x509_request_asymmetric_key(trust_keyring, x509->subject,
+						  x509->fingerprint);
 		if (!IS_ERR(key))
 			/* One of the X.509 certificates in the PKCS#7 message
 			 * is apparently the same as one we already trust.
@@ -133,10 +82,8 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
 		return -ENOKEY;
 	}
 
-	key = pkcs7_request_asymmetric_key(
-		trust_keyring,
-		last->issuer, strlen(last->issuer),
-		last->authority, strlen(last->authority));
+	key = x509_request_asymmetric_key(trust_keyring, last->issuer,
+					  last->authority);
 	if (IS_ERR(key))
 		return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY;
 	x509 = last;
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 51ff36f3a913..c62cf8006e1f 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -190,14 +190,12 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
 		if (ret < 0)
 			return ret;
 
-		if (x509->issuer)
-			pr_debug("- issuer %s\n", x509->issuer);
+		pr_debug("- issuer %s\n", x509->issuer);
 		if (x509->authority)
 			pr_debug("- authkeyid %s\n", x509->authority);
 
 		if (!x509->authority ||
-		    (x509->subject &&
-		     strcmp(x509->subject, x509->issuer) == 0)) {
+		    strcmp(x509->subject, x509->issuer) == 0) {
 			/* If there's no authority certificate specified, then
 			 * the certificate must be self-signed and is the root
 			 * of the chain.  Likewise if the cert is its own
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index a0f7cd196c9b..f3d62307e6ee 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -43,36 +43,41 @@ static int __init ca_keys_setup(char *str)
 __setup("ca_keys=", ca_keys_setup);
 #endif
 
-/*
- * Find a key in the given keyring by issuer and authority.
+/**
+ * x509_request_asymmetric_key - Request a key by X.509 certificate params.
+ * @keyring: The keys to search.
+ * @subject: The name of the subject to whom the key belongs.
+ * @key_id: The subject key ID as a hex string.
+ *
+ * Find a key in the given keyring by subject name and key ID.  These might,
+ * for instance, be the issuer name and the authority key ID of an X.509
+ * certificate that needs to be verified.
  */
-static struct key *x509_request_asymmetric_key(struct key *keyring,
-					       const char *signer,
-					       size_t signer_len,
-					       const char *authority,
-					       size_t auth_len)
+struct key *x509_request_asymmetric_key(struct key *keyring,
+					const char *subject,
+					const char *key_id)
 {
 	key_ref_t key;
+	size_t subject_len = strlen(subject), key_id_len = strlen(key_id);
 	char *id;
 
-	/* Construct an identifier. */
-	id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL);
+	/* Construct an identifier "<subjname>:<keyid>". */
+	id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL);
 	if (!id)
 		return ERR_PTR(-ENOMEM);
 
-	memcpy(id, signer, signer_len);
-	id[signer_len + 0] = ':';
-	id[signer_len + 1] = ' ';
-	memcpy(id + signer_len + 2, authority, auth_len);
-	id[signer_len + 2 + auth_len] = 0;
+	memcpy(id, subject, subject_len);
+	id[subject_len + 0] = ':';
+	id[subject_len + 1] = ' ';
+	memcpy(id + subject_len + 2, key_id, key_id_len);
+	id[subject_len + 2 + key_id_len] = 0;
 
 	pr_debug("Look up: \"%s\"\n", id);
 
 	key = keyring_search(make_key_ref(keyring, 1),
 			     &key_type_asymmetric, id);
 	if (IS_ERR(key))
-		pr_debug("Request for module key '%s' err %ld\n",
-			 id, PTR_ERR(key));
+		pr_debug("Request for key '%s' err %ld\n", id, PTR_ERR(key));
 	kfree(id);
 
 	if (IS_ERR(key)) {
@@ -91,6 +96,7 @@ static struct key *x509_request_asymmetric_key(struct key *keyring,
 		 key_serial(key_ref_to_ptr(key)));
 	return key_ref_to_ptr(key);
 }
+EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
 
 /*
  * Set up the signature parameters in an X.509 certificate.  This involves
@@ -193,9 +199,7 @@ static int x509_validate_trust(struct x509_certificate *cert,
 		return -EPERM;
 
 	key = x509_request_asymmetric_key(trust_keyring,
-					  cert->issuer, strlen(cert->issuer),
-					  cert->authority,
-					  strlen(cert->authority));
+					  cert->issuer, cert->authority);
 	if (!IS_ERR(key))  {
 		if (!use_builtin_keys
 		    || test_bit(KEY_FLAG_BUILTIN, &key->flags))
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index fc09732613ad..0d164c6af539 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -98,4 +98,8 @@ struct key;
 extern int verify_signature(const struct key *key,
 			    const struct public_key_signature *sig);
 
+extern struct key *x509_request_asymmetric_key(struct key *keyring,
+					       const char *issuer,
+					       const char *key_id);
+
 #endif /* _LINUX_PUBLIC_KEY_H */