aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-08-05 10:52:01 -0400
committerJames Morris <james.l.morris@oracle.com>2014-08-05 10:52:01 -0400
commit478d085524c57cf4283699f529d5a4c22188ea69 (patch)
treee97cdfff78867f247871be7f89341f087c766311
parent103ae675b12dee75ec099abf3d22857d1384b3bc (diff)
parentcf5b50fd2d70fdd907d433bcebaf8d89a9490334 (diff)
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:
70 * user defined keys take an arbitrary string as the description and an 70 * user defined keys take an arbitrary string as the description and an
71 * arbitrary blob of data as the payload 71 * arbitrary blob of data as the payload
72 */ 72 */
73struct key_type key_type_pkcs7 = { 73static struct key_type key_type_pkcs7 = {
74 .name = "pkcs7_test", 74 .name = "pkcs7_test",
75 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 75 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
76 .preparse = pkcs7_preparse, 76 .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 @@
20#include "public_key.h" 20#include "public_key.h"
21#include "pkcs7_parser.h" 21#include "pkcs7_parser.h"
22 22
23/*
24 * Request an asymmetric key.
25 */
26static struct key *pkcs7_request_asymmetric_key(
27 struct key *keyring,
28 const char *signer, size_t signer_len,
29 const char *authority, size_t auth_len)
30{
31 key_ref_t key;
32 char *id;
33
34 kenter(",%zu,,%zu", signer_len, auth_len);
35
36 /* Construct an identifier. */
37 id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL);
38 if (!id)
39 return ERR_PTR(-ENOMEM);
40
41 memcpy(id, signer, signer_len);
42 id[signer_len + 0] = ':';
43 id[signer_len + 1] = ' ';
44 memcpy(id + signer_len + 2, authority, auth_len);
45 id[signer_len + 2 + auth_len] = 0;
46
47 pr_debug("Look up: \"%s\"\n", id);
48
49 key = keyring_search(make_key_ref(keyring, 1),
50 &key_type_asymmetric, id);
51 if (IS_ERR(key))
52 pr_debug("Request for module key '%s' err %ld\n",
53 id, PTR_ERR(key));
54 kfree(id);
55
56 if (IS_ERR(key)) {
57 switch (PTR_ERR(key)) {
58 /* Hide some search errors */
59 case -EACCES:
60 case -ENOTDIR:
61 case -EAGAIN:
62 return ERR_PTR(-ENOKEY);
63 default:
64 return ERR_CAST(key);
65 }
66 }
67
68 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key)));
69 return key_ref_to_ptr(key);
70}
71
72/** 23/**
73 * Check the trust on one PKCS#7 SignedInfo block. 24 * Check the trust on one PKCS#7 SignedInfo block.
74 */ 25 */
@@ -98,10 +49,8 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
98 /* Look to see if this certificate is present in the trusted 49 /* Look to see if this certificate is present in the trusted
99 * keys. 50 * keys.
100 */ 51 */
101 key = pkcs7_request_asymmetric_key( 52 key = x509_request_asymmetric_key(trust_keyring, x509->subject,
102 trust_keyring, 53 x509->fingerprint);
103 x509->subject, strlen(x509->subject),
104 x509->fingerprint, strlen(x509->fingerprint));
105 if (!IS_ERR(key)) 54 if (!IS_ERR(key))
106 /* One of the X.509 certificates in the PKCS#7 message 55 /* One of the X.509 certificates in the PKCS#7 message
107 * is apparently the same as one we already trust. 56 * is apparently the same as one we already trust.
@@ -133,10 +82,8 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
133 return -ENOKEY; 82 return -ENOKEY;
134 } 83 }
135 84
136 key = pkcs7_request_asymmetric_key( 85 key = x509_request_asymmetric_key(trust_keyring, last->issuer,
137 trust_keyring, 86 last->authority);
138 last->issuer, strlen(last->issuer),
139 last->authority, strlen(last->authority));
140 if (IS_ERR(key)) 87 if (IS_ERR(key))
141 return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY; 88 return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY;
142 x509 = last; 89 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,
190 if (ret < 0) 190 if (ret < 0)
191 return ret; 191 return ret;
192 192
193 if (x509->issuer) 193 pr_debug("- issuer %s\n", x509->issuer);
194 pr_debug("- issuer %s\n", x509->issuer);
195 if (x509->authority) 194 if (x509->authority)
196 pr_debug("- authkeyid %s\n", x509->authority); 195 pr_debug("- authkeyid %s\n", x509->authority);
197 196
198 if (!x509->authority || 197 if (!x509->authority ||
199 (x509->subject && 198 strcmp(x509->subject, x509->issuer) == 0) {
200 strcmp(x509->subject, x509->issuer) == 0)) {
201 /* If there's no authority certificate specified, then 199 /* If there's no authority certificate specified, then
202 * the certificate must be self-signed and is the root 200 * the certificate must be self-signed and is the root
203 * of the chain. Likewise if the cert is its own 201 * 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)
43__setup("ca_keys=", ca_keys_setup); 43__setup("ca_keys=", ca_keys_setup);
44#endif 44#endif
45 45
46/* 46/**
47 * Find a key in the given keyring by issuer and authority. 47 * x509_request_asymmetric_key - Request a key by X.509 certificate params.
48 * @keyring: The keys to search.
49 * @subject: The name of the subject to whom the key belongs.
50 * @key_id: The subject key ID as a hex string.
51 *
52 * Find a key in the given keyring by subject name and key ID. These might,
53 * for instance, be the issuer name and the authority key ID of an X.509
54 * certificate that needs to be verified.
48 */ 55 */
49static struct key *x509_request_asymmetric_key(struct key *keyring, 56struct key *x509_request_asymmetric_key(struct key *keyring,
50 const char *signer, 57 const char *subject,
51 size_t signer_len, 58 const char *key_id)
52 const char *authority,
53 size_t auth_len)
54{ 59{
55 key_ref_t key; 60 key_ref_t key;
61 size_t subject_len = strlen(subject), key_id_len = strlen(key_id);
56 char *id; 62 char *id;
57 63
58 /* Construct an identifier. */ 64 /* Construct an identifier "<subjname>:<keyid>". */
59 id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL); 65 id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL);
60 if (!id) 66 if (!id)
61 return ERR_PTR(-ENOMEM); 67 return ERR_PTR(-ENOMEM);
62 68
63 memcpy(id, signer, signer_len); 69 memcpy(id, subject, subject_len);
64 id[signer_len + 0] = ':'; 70 id[subject_len + 0] = ':';
65 id[signer_len + 1] = ' '; 71 id[subject_len + 1] = ' ';
66 memcpy(id + signer_len + 2, authority, auth_len); 72 memcpy(id + subject_len + 2, key_id, key_id_len);
67 id[signer_len + 2 + auth_len] = 0; 73 id[subject_len + 2 + key_id_len] = 0;
68 74
69 pr_debug("Look up: \"%s\"\n", id); 75 pr_debug("Look up: \"%s\"\n", id);
70 76
71 key = keyring_search(make_key_ref(keyring, 1), 77 key = keyring_search(make_key_ref(keyring, 1),
72 &key_type_asymmetric, id); 78 &key_type_asymmetric, id);
73 if (IS_ERR(key)) 79 if (IS_ERR(key))
74 pr_debug("Request for module key '%s' err %ld\n", 80 pr_debug("Request for key '%s' err %ld\n", id, PTR_ERR(key));
75 id, PTR_ERR(key));
76 kfree(id); 81 kfree(id);
77 82
78 if (IS_ERR(key)) { 83 if (IS_ERR(key)) {
@@ -91,6 +96,7 @@ static struct key *x509_request_asymmetric_key(struct key *keyring,
91 key_serial(key_ref_to_ptr(key))); 96 key_serial(key_ref_to_ptr(key)));
92 return key_ref_to_ptr(key); 97 return key_ref_to_ptr(key);
93} 98}
99EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
94 100
95/* 101/*
96 * Set up the signature parameters in an X.509 certificate. This involves 102 * 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,
193 return -EPERM; 199 return -EPERM;
194 200
195 key = x509_request_asymmetric_key(trust_keyring, 201 key = x509_request_asymmetric_key(trust_keyring,
196 cert->issuer, strlen(cert->issuer), 202 cert->issuer, cert->authority);
197 cert->authority,
198 strlen(cert->authority));
199 if (!IS_ERR(key)) { 203 if (!IS_ERR(key)) {
200 if (!use_builtin_keys 204 if (!use_builtin_keys
201 || test_bit(KEY_FLAG_BUILTIN, &key->flags)) 205 || 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;
98extern int verify_signature(const struct key *key, 98extern int verify_signature(const struct key *key,
99 const struct public_key_signature *sig); 99 const struct public_key_signature *sig);
100 100
101extern struct key *x509_request_asymmetric_key(struct key *keyring,
102 const char *issuer,
103 const char *key_id);
104
101#endif /* _LINUX_PUBLIC_KEY_H */ 105#endif /* _LINUX_PUBLIC_KEY_H */