aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/security/keys.txt65
-rw-r--r--crypto/asymmetric_keys/asymmetric_keys.h8
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c223
-rw-r--r--crypto/asymmetric_keys/pkcs7_key_type.c2
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c99
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.h6
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c87
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c102
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c55
-rw-r--r--crypto/asymmetric_keys/x509_parser.h6
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c102
-rw-r--r--fs/cifs/cifs_spnego.c1
-rw-r--r--fs/cifs/cifsacl.c1
-rw-r--r--fs/nfs/idmap.c2
-rw-r--r--include/crypto/public_key.h5
-rw-r--r--include/keys/asymmetric-type.h38
-rw-r--r--include/keys/user-type.h1
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/key-type.h34
-rw-r--r--lib/hexdump.c16
-rw-r--r--net/ceph/crypto.c1
-rw-r--r--net/dns_resolver/dns_key.c18
-rw-r--r--net/rxrpc/ar-key.c2
-rw-r--r--security/keys/big_key.c2
-rw-r--r--security/keys/encrypted-keys/encrypted.c1
-rw-r--r--security/keys/internal.h21
-rw-r--r--security/keys/key.c2
-rw-r--r--security/keys/keyctl.c2
-rw-r--r--security/keys/keyring.c58
-rw-r--r--security/keys/proc.c8
-rw-r--r--security/keys/process_keys.c13
-rw-r--r--security/keys/request_key.c21
-rw-r--r--security/keys/request_key_auth.c10
-rw-r--r--security/keys/trusted.c1
-rw-r--r--security/keys/user_defined.c14
35 files changed, 690 insertions, 338 deletions
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 8727c194ca16..821c936e1a63 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -888,11 +888,11 @@ payload contents" for more information.
888 const char *callout_info); 888 const char *callout_info);
889 889
890 This is used to request a key or keyring with a description that matches 890 This is used to request a key or keyring with a description that matches
891 the description specified according to the key type's match function. This 891 the description specified according to the key type's match_preparse()
892 permits approximate matching to occur. If callout_string is not NULL, then 892 method. This permits approximate matching to occur. If callout_string is
893 /sbin/request-key will be invoked in an attempt to obtain the key from 893 not NULL, then /sbin/request-key will be invoked in an attempt to obtain
894 userspace. In that case, callout_string will be passed as an argument to 894 the key from userspace. In that case, callout_string will be passed as an
895 the program. 895 argument to the program.
896 896
897 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be 897 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
898 returned. 898 returned.
@@ -1170,7 +1170,7 @@ The structure has a number of fields, some of which are mandatory:
1170 The method should return 0 if successful or a negative error code 1170 The method should return 0 if successful or a negative error code
1171 otherwise. 1171 otherwise.
1172 1172
1173 1173
1174 (*) void (*free_preparse)(struct key_preparsed_payload *prep); 1174 (*) void (*free_preparse)(struct key_preparsed_payload *prep);
1175 1175
1176 This method is only required if the preparse() method is provided, 1176 This method is only required if the preparse() method is provided,
@@ -1225,16 +1225,55 @@ The structure has a number of fields, some of which are mandatory:
1225 It is safe to sleep in this method. 1225 It is safe to sleep in this method.
1226 1226
1227 1227
1228 (*) int (*match)(const struct key *key, const void *desc); 1228 (*) int (*match_preparse)(struct key_match_data *match_data);
1229
1230 This method is optional. It is called when a key search is about to be
1231 performed. It is given the following structure:
1229 1232
1230 This method is called to match a key against a description. It should 1233 struct key_match_data {
1231 return non-zero if the two match, zero if they don't. 1234 bool (*cmp)(const struct key *key,
1235 const struct key_match_data *match_data);
1236 const void *raw_data;
1237 void *preparsed;
1238 unsigned lookup_type;
1239 };
1232 1240
1233 This method should not need to lock the key in any way. The type and 1241 On entry, raw_data will be pointing to the criteria to be used in matching
1234 description can be considered invariant, and the payload should not be 1242 a key by the caller and should not be modified. (*cmp)() will be pointing
1235 accessed (the key may not yet be instantiated). 1243 to the default matcher function (which does an exact description match
1244 against raw_data) and lookup_type will be set to indicate a direct lookup.
1236 1245
1237 It is not safe to sleep in this method; the caller may hold spinlocks. 1246 The following lookup_type values are available:
1247
1248 [*] KEYRING_SEARCH_LOOKUP_DIRECT - A direct lookup hashes the type and
1249 description to narrow down the search to a small number of keys.
1250
1251 [*] KEYRING_SEARCH_LOOKUP_ITERATE - An iterative lookup walks all the
1252 keys in the keyring until one is matched. This must be used for any
1253 search that's not doing a simple direct match on the key description.
1254
1255 The method may set cmp to point to a function of its choice that does some
1256 other form of match, may set lookup_type to KEYRING_SEARCH_LOOKUP_ITERATE
1257 and may attach something to the preparsed pointer for use by (*cmp)().
1258 (*cmp)() should return true if a key matches and false otherwise.
1259
1260 If preparsed is set, it may be necessary to use the match_free() method to
1261 clean it up.
1262
1263 The method should return 0 if successful or a negative error code
1264 otherwise.
1265
1266 It is permitted to sleep in this method, but (*cmp)() may not sleep as
1267 locks will be held over it.
1268
1269 If match_preparse() is not provided, keys of this type will be matched
1270 exactly by their description.
1271
1272
1273 (*) void (*match_free)(struct key_match_data *match_data);
1274
1275 This method is optional. If given, it called to clean up
1276 match_data->preparsed after a successful call to match_preparse().
1238 1277
1239 1278
1240 (*) void (*revoke)(struct key *key); 1279 (*) void (*revoke)(struct key *key);
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
index a63c551c6557..fd21ac28e0a0 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -9,9 +9,13 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12int asymmetric_keyid_match(const char *kid, const char *id); 12extern bool asymmetric_match_key_ids(const struct asymmetric_key_ids *kids,
13 const struct asymmetric_key_id *match_id);
13 14
14static inline const char *asymmetric_key_id(const struct key *key) 15extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
16
17static inline
18const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
15{ 19{
16 return key->type_data.p[1]; 20 return key->type_data.p[1];
17} 21}
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index eb8cd46961a5..f0f2111d2c66 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -15,6 +15,7 @@
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/ctype.h>
18#include "asymmetric_keys.h" 19#include "asymmetric_keys.h"
19 20
20MODULE_LICENSE("GPL"); 21MODULE_LICENSE("GPL");
@@ -22,85 +23,166 @@ MODULE_LICENSE("GPL");
22static LIST_HEAD(asymmetric_key_parsers); 23static LIST_HEAD(asymmetric_key_parsers);
23static DECLARE_RWSEM(asymmetric_key_parsers_sem); 24static DECLARE_RWSEM(asymmetric_key_parsers_sem);
24 25
25/* 26/**
26 * Match asymmetric key id with partial match 27 * asymmetric_key_generate_id: Construct an asymmetric key ID
27 * @id: key id to match in a form "id:<id>" 28 * @val_1: First binary blob
29 * @len_1: Length of first binary blob
30 * @val_2: Second binary blob
31 * @len_2: Length of second binary blob
32 *
33 * Construct an asymmetric key ID from a pair of binary blobs.
34 */
35struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
36 size_t len_1,
37 const void *val_2,
38 size_t len_2)
39{
40 struct asymmetric_key_id *kid;
41
42 kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2,
43 GFP_KERNEL);
44 if (!kid)
45 return ERR_PTR(-ENOMEM);
46 kid->len = len_1 + len_2;
47 memcpy(kid->data, val_1, len_1);
48 memcpy(kid->data + len_1, val_2, len_2);
49 return kid;
50}
51EXPORT_SYMBOL_GPL(asymmetric_key_generate_id);
52
53/**
54 * asymmetric_key_id_same - Return true if two asymmetric keys IDs are the same.
55 * @kid_1, @kid_2: The key IDs to compare
28 */ 56 */
29int asymmetric_keyid_match(const char *kid, const char *id) 57bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
58 const struct asymmetric_key_id *kid2)
30{ 59{
31 size_t idlen, kidlen; 60 if (!kid1 || !kid2)
61 return false;
62 if (kid1->len != kid2->len)
63 return false;
64 return memcmp(kid1->data, kid2->data, kid1->len) == 0;
65}
66EXPORT_SYMBOL_GPL(asymmetric_key_id_same);
32 67
33 if (!kid || !id) 68/**
34 return 0; 69 * asymmetric_match_key_ids - Search asymmetric key IDs
70 * @kids: The list of key IDs to check
71 * @match_id: The key ID we're looking for
72 */
73bool asymmetric_match_key_ids(const struct asymmetric_key_ids *kids,
74 const struct asymmetric_key_id *match_id)
75{
76 if (!kids || !match_id)
77 return false;
78 if (asymmetric_key_id_same(kids->id[0], match_id))
79 return true;
80 if (asymmetric_key_id_same(kids->id[1], match_id))
81 return true;
82 return false;
83}
84EXPORT_SYMBOL_GPL(asymmetric_match_key_ids);
35 85
36 /* make it possible to use id as in the request: "id:<id>" */ 86/**
37 if (strncmp(id, "id:", 3) == 0) 87 * asymmetric_key_hex_to_key_id - Convert a hex string into a key ID.
38 id += 3; 88 * @id: The ID as a hex string.
89 */
90struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
91{
92 struct asymmetric_key_id *match_id;
93 size_t hexlen;
94 int ret;
39 95
40 /* Anything after here requires a partial match on the ID string */ 96 if (!*id)
41 idlen = strlen(id); 97 return ERR_PTR(-EINVAL);
42 kidlen = strlen(kid); 98 hexlen = strlen(id);
43 if (idlen > kidlen) 99 if (hexlen & 1)
44 return 0; 100 return ERR_PTR(-EINVAL);
101
102 match_id = kmalloc(sizeof(struct asymmetric_key_id) + hexlen / 2,
103 GFP_KERNEL);
104 if (!match_id)
105 return ERR_PTR(-ENOMEM);
106 match_id->len = hexlen / 2;
107 ret = hex2bin(match_id->data, id, hexlen / 2);
108 if (ret < 0) {
109 kfree(match_id);
110 return ERR_PTR(-EINVAL);
111 }
112 return match_id;
113}
45 114
46 kid += kidlen - idlen; 115/*
47 if (strcasecmp(id, kid) != 0) 116 * Match asymmetric keys by ID.
48 return 0; 117 */
118static bool asymmetric_key_cmp(const struct key *key,
119 const struct key_match_data *match_data)
120{
121 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
122 const struct asymmetric_key_id *match_id = match_data->preparsed;
49 123
50 return 1; 124 return asymmetric_match_key_ids(kids, match_id);
51} 125}
52EXPORT_SYMBOL_GPL(asymmetric_keyid_match);
53 126
54/* 127/*
55 * Match asymmetric keys on (part of) their name 128 * Preparse the match criterion. If we don't set lookup_type and cmp,
56 * We have some shorthand methods for matching keys. We allow: 129 * the default will be an exact match on the key description.
130 *
131 * There are some specifiers for matching key IDs rather than by the key
132 * description:
57 * 133 *
58 * "<desc>" - request a key by description 134 * "id:<id>" - request a key by any available ID
59 * "id:<id>" - request a key matching the ID 135 *
60 * "<subtype>:<id>" - request a key of a subtype 136 * These have to be searched by iteration rather than by direct lookup because
137 * the key is hashed according to its description.
61 */ 138 */
62static int asymmetric_key_match(const struct key *key, const void *description) 139static int asymmetric_key_match_preparse(struct key_match_data *match_data)
63{ 140{
64 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 141 struct asymmetric_key_id *match_id;
65 const char *spec = description; 142 const char *spec = match_data->raw_data;
66 const char *id; 143 const char *id;
67 ptrdiff_t speclen;
68 144
69 if (!subtype || !spec || !*spec) 145 if (!spec || !*spec)
70 return 0; 146 return -EINVAL;
71 147 if (spec[0] == 'i' &&
72 /* See if the full key description matches as is */ 148 spec[1] == 'd' &&
73 if (key->description && strcmp(key->description, description) == 0) 149 spec[2] == ':') {
74 return 1; 150 id = spec + 3;
75 151 } else {
76 /* All tests from here on break the criterion description into a 152 goto default_match;
77 * specifier, a colon and then an identifier. 153 }
78 */
79 id = strchr(spec, ':');
80 if (!id)
81 return 0;
82
83 speclen = id - spec;
84 id++;
85 154
86 if (speclen == 2 && memcmp(spec, "id", 2) == 0) 155 match_id = asymmetric_key_hex_to_key_id(id);
87 return asymmetric_keyid_match(asymmetric_key_id(key), id); 156 if (!match_id)
157 return -ENOMEM;
88 158
89 if (speclen == subtype->name_len && 159 match_data->preparsed = match_id;
90 memcmp(spec, subtype->name, speclen) == 0) 160 match_data->cmp = asymmetric_key_cmp;
91 return 1; 161 match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
162 return 0;
92 163
164default_match:
93 return 0; 165 return 0;
94} 166}
95 167
96/* 168/*
169 * Free the preparsed the match criterion.
170 */
171static void asymmetric_key_match_free(struct key_match_data *match_data)
172{
173 kfree(match_data->preparsed);
174}
175
176/*
97 * Describe the asymmetric key 177 * Describe the asymmetric key
98 */ 178 */
99static void asymmetric_key_describe(const struct key *key, struct seq_file *m) 179static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
100{ 180{
101 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 181 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
102 const char *kid = asymmetric_key_id(key); 182 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
103 size_t n; 183 const struct asymmetric_key_id *kid;
184 const unsigned char *p;
185 int n;
104 186
105 seq_puts(m, key->description); 187 seq_puts(m, key->description);
106 188
@@ -108,13 +190,16 @@ static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
108 seq_puts(m, ": "); 190 seq_puts(m, ": ");
109 subtype->describe(key, m); 191 subtype->describe(key, m);
110 192
111 if (kid) { 193 if (kids && kids->id[0]) {
194 kid = kids->id[0];
112 seq_putc(m, ' '); 195 seq_putc(m, ' ');
113 n = strlen(kid); 196 n = kid->len;
114 if (n <= 8) 197 p = kid->data;
115 seq_puts(m, kid); 198 if (n > 8) {
116 else 199 p += n - 8;
117 seq_puts(m, kid + n - 8); 200 n = 8;
201 }
202 seq_printf(m, "%*phN", n, p);
118 } 203 }
119 204
120 seq_puts(m, " ["); 205 seq_puts(m, " [");
@@ -165,6 +250,7 @@ static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
165static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) 250static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
166{ 251{
167 struct asymmetric_key_subtype *subtype = prep->type_data[0]; 252 struct asymmetric_key_subtype *subtype = prep->type_data[0];
253 struct asymmetric_key_ids *kids = prep->type_data[1];
168 254
169 pr_devel("==>%s()\n", __func__); 255 pr_devel("==>%s()\n", __func__);
170 256
@@ -172,7 +258,11 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
172 subtype->destroy(prep->payload[0]); 258 subtype->destroy(prep->payload[0]);
173 module_put(subtype->owner); 259 module_put(subtype->owner);
174 } 260 }
175 kfree(prep->type_data[1]); 261 if (kids) {
262 kfree(kids->id[0]);
263 kfree(kids->id[1]);
264 kfree(kids);
265 }
176 kfree(prep->description); 266 kfree(prep->description);
177} 267}
178 268
@@ -182,13 +272,20 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
182static void asymmetric_key_destroy(struct key *key) 272static void asymmetric_key_destroy(struct key *key)
183{ 273{
184 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 274 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
275 struct asymmetric_key_ids *kids = key->type_data.p[1];
276
185 if (subtype) { 277 if (subtype) {
186 subtype->destroy(key->payload.data); 278 subtype->destroy(key->payload.data);
187 module_put(subtype->owner); 279 module_put(subtype->owner);
188 key->type_data.p[0] = NULL; 280 key->type_data.p[0] = NULL;
189 } 281 }
190 kfree(key->type_data.p[1]); 282
191 key->type_data.p[1] = NULL; 283 if (kids) {
284 kfree(kids->id[0]);
285 kfree(kids->id[1]);
286 kfree(kids);
287 key->type_data.p[1] = NULL;
288 }
192} 289}
193 290
194struct key_type key_type_asymmetric = { 291struct key_type key_type_asymmetric = {
@@ -196,10 +293,10 @@ struct key_type key_type_asymmetric = {
196 .preparse = asymmetric_key_preparse, 293 .preparse = asymmetric_key_preparse,
197 .free_preparse = asymmetric_key_free_preparse, 294 .free_preparse = asymmetric_key_free_preparse,
198 .instantiate = generic_key_instantiate, 295 .instantiate = generic_key_instantiate,
199 .match = asymmetric_key_match, 296 .match_preparse = asymmetric_key_match_preparse,
297 .match_free = asymmetric_key_match_free,
200 .destroy = asymmetric_key_destroy, 298 .destroy = asymmetric_key_destroy,
201 .describe = asymmetric_key_describe, 299 .describe = asymmetric_key_describe,
202 .def_lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE,
203}; 300};
204EXPORT_SYMBOL_GPL(key_type_asymmetric); 301EXPORT_SYMBOL_GPL(key_type_asymmetric);
205 302
diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c
index 3de5fb011de0..751f8fd7335d 100644
--- a/crypto/asymmetric_keys/pkcs7_key_type.c
+++ b/crypto/asymmetric_keys/pkcs7_key_type.c
@@ -72,11 +72,9 @@ error:
72 */ 72 */
73static struct 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,
76 .preparse = pkcs7_preparse, 75 .preparse = pkcs7_preparse,
77 .free_preparse = user_free_preparse, 76 .free_preparse = user_free_preparse,
78 .instantiate = generic_key_instantiate, 77 .instantiate = generic_key_instantiate,
79 .match = user_match,
80 .revoke = user_revoke, 78 .revoke = user_revoke,
81 .destroy = user_destroy, 79 .destroy = user_destroy,
82 .describe = user_describe, 80 .describe = user_describe,
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 42e56aa7d277..3bd5a1e4c493 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -29,8 +29,25 @@ struct pkcs7_parse_context {
29 enum OID last_oid; /* Last OID encountered */ 29 enum OID last_oid; /* Last OID encountered */
30 unsigned x509_index; 30 unsigned x509_index;
31 unsigned sinfo_index; 31 unsigned sinfo_index;
32 const void *raw_serial;
33 unsigned raw_serial_size;
34 unsigned raw_issuer_size;
35 const void *raw_issuer;
32}; 36};
33 37
38/*
39 * Free a signed information block.
40 */
41static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
42{
43 if (sinfo) {
44 mpi_free(sinfo->sig.mpi[0]);
45 kfree(sinfo->sig.digest);
46 kfree(sinfo->signing_cert_id);
47 kfree(sinfo);
48 }
49}
50
34/** 51/**
35 * pkcs7_free_message - Free a PKCS#7 message 52 * pkcs7_free_message - Free a PKCS#7 message
36 * @pkcs7: The PKCS#7 message to free 53 * @pkcs7: The PKCS#7 message to free
@@ -54,9 +71,7 @@ void pkcs7_free_message(struct pkcs7_message *pkcs7)
54 while (pkcs7->signed_infos) { 71 while (pkcs7->signed_infos) {
55 sinfo = pkcs7->signed_infos; 72 sinfo = pkcs7->signed_infos;
56 pkcs7->signed_infos = sinfo->next; 73 pkcs7->signed_infos = sinfo->next;
57 mpi_free(sinfo->sig.mpi[0]); 74 pkcs7_free_signed_info(sinfo);
58 kfree(sinfo->sig.digest);
59 kfree(sinfo);
60 } 75 }
61 kfree(pkcs7); 76 kfree(pkcs7);
62 } 77 }
@@ -71,51 +86,46 @@ EXPORT_SYMBOL_GPL(pkcs7_free_message);
71struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen) 86struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
72{ 87{
73 struct pkcs7_parse_context *ctx; 88 struct pkcs7_parse_context *ctx;
74 struct pkcs7_message *msg; 89 struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
75 long ret; 90 int ret;
76 91
77 ret = -ENOMEM;
78 msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
79 if (!msg)
80 goto error_no_sig;
81 ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL); 92 ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
82 if (!ctx) 93 if (!ctx)
83 goto error_no_ctx; 94 goto out_no_ctx;
95 ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
96 if (!ctx->msg)
97 goto out_no_msg;
84 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 98 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
85 if (!ctx->sinfo) 99 if (!ctx->sinfo)
86 goto error_no_sinfo; 100 goto out_no_sinfo;
87 101
88 ctx->msg = msg;
89 ctx->data = (unsigned long)data; 102 ctx->data = (unsigned long)data;
90 ctx->ppcerts = &ctx->certs; 103 ctx->ppcerts = &ctx->certs;
91 ctx->ppsinfo = &ctx->msg->signed_infos; 104 ctx->ppsinfo = &ctx->msg->signed_infos;
92 105
93 /* Attempt to decode the signature */ 106 /* Attempt to decode the signature */
94 ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen); 107 ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
95 if (ret < 0) 108 if (ret < 0) {
96 goto error_decode; 109 msg = ERR_PTR(ret);
110 goto out;
111 }
97 112
113 msg = ctx->msg;
114 ctx->msg = NULL;
115
116out:
98 while (ctx->certs) { 117 while (ctx->certs) {
99 struct x509_certificate *cert = ctx->certs; 118 struct x509_certificate *cert = ctx->certs;
100 ctx->certs = cert->next; 119 ctx->certs = cert->next;
101 x509_free_certificate(cert); 120 x509_free_certificate(cert);
102 } 121 }
103 mpi_free(ctx->sinfo->sig.mpi[0]); 122 pkcs7_free_signed_info(ctx->sinfo);
104 kfree(ctx->sinfo->sig.digest); 123out_no_sinfo:
105 kfree(ctx->sinfo); 124 pkcs7_free_message(ctx->msg);
125out_no_msg:
106 kfree(ctx); 126 kfree(ctx);
127out_no_ctx:
107 return msg; 128 return msg;
108
109error_decode:
110 mpi_free(ctx->sinfo->sig.mpi[0]);
111 kfree(ctx->sinfo->sig.digest);
112 kfree(ctx->sinfo);
113error_no_sinfo:
114 kfree(ctx);
115error_no_ctx:
116 pkcs7_free_message(msg);
117error_no_sig:
118 return ERR_PTR(ret);
119} 129}
120EXPORT_SYMBOL_GPL(pkcs7_parse_message); 130EXPORT_SYMBOL_GPL(pkcs7_parse_message);
121 131
@@ -246,10 +256,10 @@ int pkcs7_extract_cert(void *context, size_t hdrlen,
246 if (IS_ERR(x509)) 256 if (IS_ERR(x509))
247 return PTR_ERR(x509); 257 return PTR_ERR(x509);
248 258
249 pr_debug("Got cert for %s\n", x509->subject);
250 pr_debug("- fingerprint %s\n", x509->fingerprint);
251
252 x509->index = ++ctx->x509_index; 259 x509->index = ++ctx->x509_index;
260 pr_debug("Got cert %u for %s\n", x509->index, x509->subject);
261 pr_debug("- fingerprint %*phN\n", x509->id->len, x509->id->data);
262
253 *ctx->ppcerts = x509; 263 *ctx->ppcerts = x509;
254 ctx->ppcerts = &x509->next; 264 ctx->ppcerts = &x509->next;
255 return 0; 265 return 0;
@@ -338,8 +348,8 @@ int pkcs7_sig_note_serial(void *context, size_t hdrlen,
338 const void *value, size_t vlen) 348 const void *value, size_t vlen)
339{ 349{
340 struct pkcs7_parse_context *ctx = context; 350 struct pkcs7_parse_context *ctx = context;
341 ctx->sinfo->raw_serial = value; 351 ctx->raw_serial = value;
342 ctx->sinfo->raw_serial_size = vlen; 352 ctx->raw_serial_size = vlen;
343 return 0; 353 return 0;
344} 354}
345 355
@@ -351,8 +361,8 @@ int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
351 const void *value, size_t vlen) 361 const void *value, size_t vlen)
352{ 362{
353 struct pkcs7_parse_context *ctx = context; 363 struct pkcs7_parse_context *ctx = context;
354 ctx->sinfo->raw_issuer = value; 364 ctx->raw_issuer = value;
355 ctx->sinfo->raw_issuer_size = vlen; 365 ctx->raw_issuer_size = vlen;
356 return 0; 366 return 0;
357} 367}
358 368
@@ -385,10 +395,21 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen,
385 const void *value, size_t vlen) 395 const void *value, size_t vlen)
386{ 396{
387 struct pkcs7_parse_context *ctx = context; 397 struct pkcs7_parse_context *ctx = context;
388 398 struct pkcs7_signed_info *sinfo = ctx->sinfo;
389 ctx->sinfo->index = ++ctx->sinfo_index; 399 struct asymmetric_key_id *kid;
390 *ctx->ppsinfo = ctx->sinfo; 400
391 ctx->ppsinfo = &ctx->sinfo->next; 401 /* Generate cert issuer + serial number key ID */
402 kid = asymmetric_key_generate_id(ctx->raw_serial,
403 ctx->raw_serial_size,
404 ctx->raw_issuer,
405 ctx->raw_issuer_size);
406 if (IS_ERR(kid))
407 return PTR_ERR(kid);
408
409 sinfo->signing_cert_id = kid;
410 sinfo->index = ++ctx->sinfo_index;
411 *ctx->ppsinfo = sinfo;
412 ctx->ppsinfo = &sinfo->next;
392 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); 413 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
393 if (!ctx->sinfo) 414 if (!ctx->sinfo)
394 return -ENOMEM; 415 return -ENOMEM;
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
index d25f4d15370f..efc7dc9b8f9c 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.h
+++ b/crypto/asymmetric_keys/pkcs7_parser.h
@@ -23,6 +23,7 @@ struct pkcs7_signed_info {
23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */ 23 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */
24 unsigned index; 24 unsigned index;
25 bool trusted; 25 bool trusted;
26 bool unsupported_crypto; /* T if not usable due to missing crypto */
26 27
27 /* Message digest - the digest of the Content Data (or NULL) */ 28 /* Message digest - the digest of the Content Data (or NULL) */
28 const void *msgdigest; 29 const void *msgdigest;
@@ -33,10 +34,7 @@ struct pkcs7_signed_info {
33 const void *authattrs; 34 const void *authattrs;
34 35
35 /* Issuing cert serial number and issuer's name */ 36 /* Issuing cert serial number and issuer's name */
36 const void *raw_serial; 37 struct asymmetric_key_id *signing_cert_id;
37 unsigned raw_serial_size;
38 unsigned raw_issuer_size;
39 const void *raw_issuer;
40 38
41 /* Message signature. 39 /* Message signature.
42 * 40 *
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index e666eb011a85..ae47be6128c4 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -23,9 +23,9 @@
23/** 23/**
24 * Check the trust on one PKCS#7 SignedInfo block. 24 * Check the trust on one PKCS#7 SignedInfo block.
25 */ 25 */
26int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, 26static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
27 struct pkcs7_signed_info *sinfo, 27 struct pkcs7_signed_info *sinfo,
28 struct key *trust_keyring) 28 struct key *trust_keyring)
29{ 29{
30 struct public_key_signature *sig = &sinfo->sig; 30 struct public_key_signature *sig = &sinfo->sig;
31 struct x509_certificate *x509, *last = NULL, *p; 31 struct x509_certificate *x509, *last = NULL, *p;
@@ -35,6 +35,11 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
35 35
36 kenter(",%u,", sinfo->index); 36 kenter(",%u,", sinfo->index);
37 37
38 if (sinfo->unsupported_crypto) {
39 kleave(" = -ENOPKG [cached]");
40 return -ENOPKG;
41 }
42
38 for (x509 = sinfo->signer; x509; x509 = x509->signer) { 43 for (x509 = sinfo->signer; x509; x509 = x509->signer) {
39 if (x509->seen) { 44 if (x509->seen) {
40 if (x509->verified) { 45 if (x509->verified) {
@@ -49,15 +54,17 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
49 /* Look to see if this certificate is present in the trusted 54 /* Look to see if this certificate is present in the trusted
50 * keys. 55 * keys.
51 */ 56 */
52 key = x509_request_asymmetric_key(trust_keyring, x509->subject, 57 key = x509_request_asymmetric_key(trust_keyring, x509->id);
53 x509->fingerprint); 58 if (!IS_ERR(key)) {
54 if (!IS_ERR(key))
55 /* One of the X.509 certificates in the PKCS#7 message 59 /* One of the X.509 certificates in the PKCS#7 message
56 * is apparently the same as one we already trust. 60 * is apparently the same as one we already trust.
57 * Verify that the trusted variant can also validate 61 * Verify that the trusted variant can also validate
58 * the signature on the descendant. 62 * the signature on the descendant.
59 */ 63 */
64 pr_devel("sinfo %u: Cert %u as key %x\n",
65 sinfo->index, x509->index, key_serial(key));
60 goto matched; 66 goto matched;
67 }
61 if (key == ERR_PTR(-ENOMEM)) 68 if (key == ERR_PTR(-ENOMEM))
62 return -ENOMEM; 69 return -ENOMEM;
63 70
@@ -77,16 +84,34 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
77 /* No match - see if the root certificate has a signer amongst the 84 /* No match - see if the root certificate has a signer amongst the
78 * trusted keys. 85 * trusted keys.
79 */ 86 */
80 if (!last || !last->issuer || !last->authority) { 87 if (last && last->authority) {
81 kleave(" = -ENOKEY [no backref]"); 88 key = x509_request_asymmetric_key(trust_keyring, last->authority);
82 return -ENOKEY; 89 if (!IS_ERR(key)) {
90 x509 = last;
91 pr_devel("sinfo %u: Root cert %u signer is key %x\n",
92 sinfo->index, x509->index, key_serial(key));
93 goto matched;
94 }
95 if (PTR_ERR(key) != -ENOKEY)
96 return PTR_ERR(key);
97 }
98
99 /* As a last resort, see if we have a trusted public key that matches
100 * the signed info directly.
101 */
102 key = x509_request_asymmetric_key(trust_keyring,
103 sinfo->signing_cert_id);
104 if (!IS_ERR(key)) {
105 pr_devel("sinfo %u: Direct signer is key %x\n",
106 sinfo->index, key_serial(key));
107 x509 = NULL;
108 goto matched;
83 } 109 }
110 if (PTR_ERR(key) != -ENOKEY)
111 return PTR_ERR(key);
84 112
85 key = x509_request_asymmetric_key(trust_keyring, last->issuer, 113 kleave(" = -ENOKEY [no backref]");
86 last->authority); 114 return -ENOKEY;
87 if (IS_ERR(key))
88 return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY;
89 x509 = last;
90 115
91matched: 116matched:
92 ret = verify_signature(key, sig); 117 ret = verify_signature(key, sig);
@@ -100,10 +125,12 @@ matched:
100 } 125 }
101 126
102verified: 127verified:
103 x509->verified = true; 128 if (x509) {
104 for (p = sinfo->signer; p != x509; p = p->signer) { 129 x509->verified = true;
105 p->verified = true; 130 for (p = sinfo->signer; p != x509; p = p->signer) {
106 p->trusted = trusted; 131 p->verified = true;
132 p->trusted = trusted;
133 }
107 } 134 }
108 sinfo->trusted = trusted; 135 sinfo->trusted = trusted;
109 kleave(" = 0"); 136 kleave(" = 0");
@@ -141,24 +168,28 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
141{ 168{
142 struct pkcs7_signed_info *sinfo; 169 struct pkcs7_signed_info *sinfo;
143 struct x509_certificate *p; 170 struct x509_certificate *p;
144 int cached_ret = 0, ret; 171 int cached_ret = -ENOKEY;
172 int ret;
145 173
146 for (p = pkcs7->certs; p; p = p->next) 174 for (p = pkcs7->certs; p; p = p->next)
147 p->seen = false; 175 p->seen = false;
148 176
149 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 177 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
150 ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring); 178 ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring);
151 if (ret < 0) { 179 switch (ret) {
152 if (ret == -ENOPKG) { 180 case -ENOKEY:
181 continue;
182 case -ENOPKG:
183 if (cached_ret == -ENOKEY)
153 cached_ret = -ENOPKG; 184 cached_ret = -ENOPKG;
154 } else if (ret == -ENOKEY) { 185 continue;
155 if (cached_ret == 0) 186 case 0:
156 cached_ret = -ENOKEY; 187 *_trusted |= sinfo->trusted;
157 } else { 188 cached_ret = 0;
158 return ret; 189 continue;
159 } 190 default:
191 return ret;
160 } 192 }
161 *_trusted |= sinfo->trusted;
162 } 193 }
163 194
164 return cached_ret; 195 return cached_ret;
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index c62cf8006e1f..cd455450b069 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -131,8 +131,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
131 struct x509_certificate *x509; 131 struct x509_certificate *x509;
132 unsigned certix = 1; 132 unsigned certix = 1;
133 133
134 kenter("%u,%u,%u", 134 kenter("%u", sinfo->index);
135 sinfo->index, sinfo->raw_serial_size, sinfo->raw_issuer_size);
136 135
137 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) { 136 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) {
138 /* I'm _assuming_ that the generator of the PKCS#7 message will 137 /* I'm _assuming_ that the generator of the PKCS#7 message will
@@ -140,21 +139,11 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
140 * PKCS#7 message - but I can't be 100% sure of that. It's 139 * PKCS#7 message - but I can't be 100% sure of that. It's
141 * possible this will need element-by-element comparison. 140 * possible this will need element-by-element comparison.
142 */ 141 */
143 if (x509->raw_serial_size != sinfo->raw_serial_size || 142 if (!asymmetric_key_id_same(x509->id, sinfo->signing_cert_id))
144 memcmp(x509->raw_serial, sinfo->raw_serial,
145 sinfo->raw_serial_size) != 0)
146 continue; 143 continue;
147 pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 144 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
148 sinfo->index, certix); 145 sinfo->index, certix);
149 146
150 if (x509->raw_issuer_size != sinfo->raw_issuer_size ||
151 memcmp(x509->raw_issuer, sinfo->raw_issuer,
152 sinfo->raw_issuer_size) != 0) {
153 pr_warn("Sig %u: X.509 subject and PKCS#7 issuer don't match\n",
154 sinfo->index);
155 continue;
156 }
157
158 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) { 147 if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) {
159 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 148 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
160 sinfo->index); 149 sinfo->index);
@@ -164,9 +153,14 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
164 sinfo->signer = x509; 153 sinfo->signer = x509;
165 return 0; 154 return 0;
166 } 155 }
167 pr_warn("Sig %u: Issuing X.509 cert not found (#%*ph)\n", 156
168 sinfo->index, sinfo->raw_serial_size, sinfo->raw_serial); 157 /* The relevant X.509 cert isn't found here, but it might be found in
169 return -ENOKEY; 158 * the trust keyring.
159 */
160 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
161 sinfo->index,
162 sinfo->signing_cert_id->len, sinfo->signing_cert_id->data);
163 return 0;
170} 164}
171 165
172/* 166/*
@@ -184,15 +178,18 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
184 p->seen = false; 178 p->seen = false;
185 179
186 for (;;) { 180 for (;;) {
187 pr_debug("verify %s: %s\n", x509->subject, x509->fingerprint); 181 pr_debug("verify %s: %*phN\n",
182 x509->subject,
183 x509->raw_serial_size, x509->raw_serial);
188 x509->seen = true; 184 x509->seen = true;
189 ret = x509_get_sig_params(x509); 185 ret = x509_get_sig_params(x509);
190 if (ret < 0) 186 if (ret < 0)
191 return ret; 187 goto maybe_missing_crypto_in_x509;
192 188
193 pr_debug("- issuer %s\n", x509->issuer); 189 pr_debug("- issuer %s\n", x509->issuer);
194 if (x509->authority) 190 if (x509->authority)
195 pr_debug("- authkeyid %s\n", x509->authority); 191 pr_debug("- authkeyid %*phN\n",
192 x509->authority->len, x509->authority->data);
196 193
197 if (!x509->authority || 194 if (!x509->authority ||
198 strcmp(x509->subject, x509->issuer) == 0) { 195 strcmp(x509->subject, x509->issuer) == 0) {
@@ -209,7 +206,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
209 206
210 ret = x509_check_signature(x509->pub, x509); 207 ret = x509_check_signature(x509->pub, x509);
211 if (ret < 0) 208 if (ret < 0)
212 return ret; 209 goto maybe_missing_crypto_in_x509;
213 x509->signer = x509; 210 x509->signer = x509;
214 pr_debug("- self-signed\n"); 211 pr_debug("- self-signed\n");
215 return 0; 212 return 0;
@@ -218,13 +215,14 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
218 /* Look through the X.509 certificates in the PKCS#7 message's 215 /* Look through the X.509 certificates in the PKCS#7 message's
219 * list to see if the next one is there. 216 * list to see if the next one is there.
220 */ 217 */
221 pr_debug("- want %s\n", x509->authority); 218 pr_debug("- want %*phN\n",
219 x509->authority->len, x509->authority->data);
222 for (p = pkcs7->certs; p; p = p->next) { 220 for (p = pkcs7->certs; p; p = p->next) {
223 pr_debug("- cmp [%u] %s\n", p->index, p->fingerprint); 221 if (!p->skid)
224 if (p->raw_subject_size == x509->raw_issuer_size && 222 continue;
225 strcmp(p->fingerprint, x509->authority) == 0 && 223 pr_debug("- cmp [%u] %*phN\n",
226 memcmp(p->raw_subject, x509->raw_issuer, 224 p->index, p->skid->len, p->skid->data);
227 x509->raw_issuer_size) == 0) 225 if (asymmetric_key_id_same(p->skid, x509->authority))
228 goto found_issuer; 226 goto found_issuer;
229 } 227 }
230 228
@@ -233,7 +231,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
233 return 0; 231 return 0;
234 232
235 found_issuer: 233 found_issuer:
236 pr_debug("- issuer %s\n", p->subject); 234 pr_debug("- subject %s\n", p->subject);
237 if (p->seen) { 235 if (p->seen) {
238 pr_warn("Sig %u: X.509 chain contains loop\n", 236 pr_warn("Sig %u: X.509 chain contains loop\n",
239 sinfo->index); 237 sinfo->index);
@@ -250,6 +248,17 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
250 x509 = p; 248 x509 = p;
251 might_sleep(); 249 might_sleep();
252 } 250 }
251
252maybe_missing_crypto_in_x509:
253 /* Just prune the certificate chain at this point if we lack some
254 * crypto module to go further. Note, however, we don't want to set
255 * sinfo->missing_crypto as the signed info block may still be
256 * validatable against an X.509 cert lower in the chain that we have a
257 * trusted copy of.
258 */
259 if (ret == -ENOPKG)
260 return 0;
261 return ret;
253} 262}
254 263
255/* 264/*
@@ -269,11 +278,14 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
269 if (ret < 0) 278 if (ret < 0)
270 return ret; 279 return ret;
271 280
272 /* Find the key for the signature */ 281 /* Find the key for the signature if there is one */
273 ret = pkcs7_find_key(pkcs7, sinfo); 282 ret = pkcs7_find_key(pkcs7, sinfo);
274 if (ret < 0) 283 if (ret < 0)
275 return ret; 284 return ret;
276 285
286 if (!sinfo->signer)
287 return 0;
288
277 pr_devel("Using X.509[%u] for sig %u\n", 289 pr_devel("Using X.509[%u] for sig %u\n",
278 sinfo->signer->index, sinfo->index); 290 sinfo->signer->index, sinfo->index);
279 291
@@ -291,11 +303,33 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
291/** 303/**
292 * pkcs7_verify - Verify a PKCS#7 message 304 * pkcs7_verify - Verify a PKCS#7 message
293 * @pkcs7: The PKCS#7 message to be verified 305 * @pkcs7: The PKCS#7 message to be verified
306 *
307 * Verify a PKCS#7 message is internally consistent - that is, the data digest
308 * matches the digest in the AuthAttrs and any signature in the message or one
309 * of the X.509 certificates it carries that matches another X.509 cert in the
310 * message can be verified.
311 *
312 * This does not look to match the contents of the PKCS#7 message against any
313 * external public keys.
314 *
315 * Returns, in order of descending priority:
316 *
317 * (*) -EKEYREJECTED if a signature failed to match for which we found an
318 * appropriate X.509 certificate, or:
319 *
320 * (*) -EBADMSG if some part of the message was invalid, or:
321 *
322 * (*) -ENOPKG if none of the signature chains are verifiable because suitable
323 * crypto modules couldn't be found, or:
324 *
325 * (*) 0 if all the signature chains that don't incur -ENOPKG can be verified
326 * (note that a signature chain may be of zero length), or:
294 */ 327 */
295int pkcs7_verify(struct pkcs7_message *pkcs7) 328int pkcs7_verify(struct pkcs7_message *pkcs7)
296{ 329{
297 struct pkcs7_signed_info *sinfo; 330 struct pkcs7_signed_info *sinfo;
298 struct x509_certificate *x509; 331 struct x509_certificate *x509;
332 int enopkg = -ENOPKG;
299 int ret, n; 333 int ret, n;
300 334
301 kenter(""); 335 kenter("");
@@ -304,18 +338,24 @@ int pkcs7_verify(struct pkcs7_message *pkcs7)
304 ret = x509_get_sig_params(x509); 338 ret = x509_get_sig_params(x509);
305 if (ret < 0) 339 if (ret < 0)
306 return ret; 340 return ret;
307 pr_debug("X.509[%u] %s\n", n, x509->authority); 341 pr_debug("X.509[%u] %*phN\n",
342 n, x509->authority->len, x509->authority->data);
308 } 343 }
309 344
310 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 345 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
311 ret = pkcs7_verify_one(pkcs7, sinfo); 346 ret = pkcs7_verify_one(pkcs7, sinfo);
312 if (ret < 0) { 347 if (ret < 0) {
348 if (ret == -ENOPKG) {
349 sinfo->unsupported_crypto = true;
350 continue;
351 }
313 kleave(" = %d", ret); 352 kleave(" = %d", ret);
314 return ret; 353 return ret;
315 } 354 }
355 enopkg = 0;
316 } 356 }
317 357
318 kleave(" = 0"); 358 kleave(" = %d", enopkg);
319 return 0; 359 return enopkg;
320} 360}
321EXPORT_SYMBOL_GPL(pkcs7_verify); 361EXPORT_SYMBOL_GPL(pkcs7_verify);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index ac72348c186a..96151b2b91a2 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -46,7 +46,8 @@ void x509_free_certificate(struct x509_certificate *cert)
46 public_key_destroy(cert->pub); 46 public_key_destroy(cert->pub);
47 kfree(cert->issuer); 47 kfree(cert->issuer);
48 kfree(cert->subject); 48 kfree(cert->subject);
49 kfree(cert->fingerprint); 49 kfree(cert->id);
50 kfree(cert->skid);
50 kfree(cert->authority); 51 kfree(cert->authority);
51 kfree(cert->sig.digest); 52 kfree(cert->sig.digest);
52 mpi_free(cert->sig.rsa.s); 53 mpi_free(cert->sig.rsa.s);
@@ -62,6 +63,7 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
62{ 63{
63 struct x509_certificate *cert; 64 struct x509_certificate *cert;
64 struct x509_parse_context *ctx; 65 struct x509_parse_context *ctx;
66 struct asymmetric_key_id *kid;
65 long ret; 67 long ret;
66 68
67 ret = -ENOMEM; 69 ret = -ENOMEM;
@@ -89,6 +91,17 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
89 if (ret < 0) 91 if (ret < 0)
90 goto error_decode; 92 goto error_decode;
91 93
94 /* Generate cert issuer + serial number key ID */
95 kid = asymmetric_key_generate_id(cert->raw_serial,
96 cert->raw_serial_size,
97 cert->raw_issuer,
98 cert->raw_issuer_size);
99 if (IS_ERR(kid)) {
100 ret = PTR_ERR(kid);
101 goto error_decode;
102 }
103 cert->id = kid;
104
92 kfree(ctx); 105 kfree(ctx);
93 return cert; 106 return cert;
94 107
@@ -407,36 +420,34 @@ int x509_process_extension(void *context, size_t hdrlen,
407 const void *value, size_t vlen) 420 const void *value, size_t vlen)
408{ 421{
409 struct x509_parse_context *ctx = context; 422 struct x509_parse_context *ctx = context;
423 struct asymmetric_key_id *kid;
410 const unsigned char *v = value; 424 const unsigned char *v = value;
411 char *f;
412 int i; 425 int i;
413 426
414 pr_debug("Extension: %u\n", ctx->last_oid); 427 pr_debug("Extension: %u\n", ctx->last_oid);
415 428
416 if (ctx->last_oid == OID_subjectKeyIdentifier) { 429 if (ctx->last_oid == OID_subjectKeyIdentifier) {
417 /* Get hold of the key fingerprint */ 430 /* Get hold of the key fingerprint */
418 if (vlen < 3) 431 if (ctx->cert->skid || vlen < 3)
419 return -EBADMSG; 432 return -EBADMSG;
420 if (v[0] != ASN1_OTS || v[1] != vlen - 2) 433 if (v[0] != ASN1_OTS || v[1] != vlen - 2)
421 return -EBADMSG; 434 return -EBADMSG;
422 v += 2; 435 v += 2;
423 vlen -= 2; 436 vlen -= 2;
424 437
425 f = kmalloc(vlen * 2 + 1, GFP_KERNEL); 438 kid = asymmetric_key_generate_id(v, vlen,
426 if (!f) 439 ctx->cert->raw_subject,
427 return -ENOMEM; 440 ctx->cert->raw_subject_size);
428 for (i = 0; i < vlen; i++) 441 if (IS_ERR(kid))
429 sprintf(f + i * 2, "%02x", v[i]); 442 return PTR_ERR(kid);
430 pr_debug("fingerprint %s\n", f); 443 ctx->cert->skid = kid;
431 ctx->cert->fingerprint = f; 444 pr_debug("subjkeyid %*phN\n", kid->len, kid->data);
432 return 0; 445 return 0;
433 } 446 }
434 447
435 if (ctx->last_oid == OID_authorityKeyIdentifier) { 448 if (ctx->last_oid == OID_authorityKeyIdentifier) {
436 size_t key_len;
437
438 /* Get hold of the CA key fingerprint */ 449 /* Get hold of the CA key fingerprint */
439 if (vlen < 5) 450 if (ctx->cert->authority || vlen < 5)
440 return -EBADMSG; 451 return -EBADMSG;
441 452
442 /* Authority Key Identifier must be a Constructed SEQUENCE */ 453 /* Authority Key Identifier must be a Constructed SEQUENCE */
@@ -454,7 +465,7 @@ int x509_process_extension(void *context, size_t hdrlen,
454 v[3] > vlen - 4) 465 v[3] > vlen - 4)
455 return -EBADMSG; 466 return -EBADMSG;
456 467
457 key_len = v[3]; 468 vlen = v[3];
458 v += 4; 469 v += 4;
459 } else { 470 } else {
460 /* Long Form length */ 471 /* Long Form length */
@@ -476,17 +487,17 @@ int x509_process_extension(void *context, size_t hdrlen,
476 v[sub + 1] > vlen - 4 - sub) 487 v[sub + 1] > vlen - 4 - sub)
477 return -EBADMSG; 488 return -EBADMSG;
478 489
479 key_len = v[sub + 1]; 490 vlen = v[sub + 1];
480 v += (sub + 2); 491 v += (sub + 2);
481 } 492 }
482 493
483 f = kmalloc(key_len * 2 + 1, GFP_KERNEL); 494 kid = asymmetric_key_generate_id(v, vlen,
484 if (!f) 495 ctx->cert->raw_issuer,
485 return -ENOMEM; 496 ctx->cert->raw_issuer_size);
486 for (i = 0; i < key_len; i++) 497 if (IS_ERR(kid))
487 sprintf(f + i * 2, "%02x", v[i]); 498 return PTR_ERR(kid);
488 pr_debug("authority %s\n", f); 499 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
489 ctx->cert->authority = f; 500 ctx->cert->authority = kid;
490 return 0; 501 return 0;
491 } 502 }
492 503
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 1b76f207c1f3..4e1a384901ed 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -19,8 +19,9 @@ struct x509_certificate {
19 struct public_key_signature sig; /* Signature parameters */ 19 struct public_key_signature sig; /* Signature parameters */
20 char *issuer; /* Name of certificate issuer */ 20 char *issuer; /* Name of certificate issuer */
21 char *subject; /* Name of certificate subject */ 21 char *subject; /* Name of certificate subject */
22 char *fingerprint; /* Key fingerprint as hex */ 22 struct asymmetric_key_id *id; /* Issuer + serial number */
23 char *authority; /* Authority key fingerprint as hex */ 23 struct asymmetric_key_id *skid; /* Subject key identifier */
24 struct asymmetric_key_id *authority; /* Authority key identifier */
24 struct tm valid_from; 25 struct tm valid_from;
25 struct tm valid_to; 26 struct tm valid_to;
26 const void *tbs; /* Signed data */ 27 const void *tbs; /* Signed data */
@@ -37,6 +38,7 @@ struct x509_certificate {
37 bool seen; /* Infinite recursion prevention */ 38 bool seen; /* Infinite recursion prevention */
38 bool verified; 39 bool verified;
39 bool trusted; 40 bool trusted;
41 bool unsupported_crypto; /* T if can't be verified due to missing crypto */
40}; 42};
41 43
42/* 44/*
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index f3d62307e6ee..1d9a4c555376 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -25,7 +25,7 @@
25#include "x509_parser.h" 25#include "x509_parser.h"
26 26
27static bool use_builtin_keys; 27static bool use_builtin_keys;
28static char *ca_keyid; 28static struct asymmetric_key_id *ca_keyid;
29 29
30#ifndef MODULE 30#ifndef MODULE
31static int __init ca_keys_setup(char *str) 31static int __init ca_keys_setup(char *str)
@@ -33,10 +33,16 @@ static int __init ca_keys_setup(char *str)
33 if (!str) /* default system keyring */ 33 if (!str) /* default system keyring */
34 return 1; 34 return 1;
35 35
36 if (strncmp(str, "id:", 3) == 0) 36 if (strncmp(str, "id:", 3) == 0) {
37 ca_keyid = str; /* owner key 'id:xxxxxx' */ 37 struct asymmetric_key_id *p;
38 else if (strcmp(str, "builtin") == 0) 38 p = asymmetric_key_hex_to_key_id(str);
39 if (p == ERR_PTR(-EINVAL))
40 pr_err("Unparsable hex string in ca_keys\n");
41 else if (!IS_ERR(p))
42 ca_keyid = p; /* owner key 'id:xxxxxx' */
43 } else if (strcmp(str, "builtin") == 0) {
39 use_builtin_keys = true; 44 use_builtin_keys = true;
45 }
40 46
41 return 1; 47 return 1;
42} 48}
@@ -46,31 +52,28 @@ __setup("ca_keys=", ca_keys_setup);
46/** 52/**
47 * x509_request_asymmetric_key - Request a key by X.509 certificate params. 53 * x509_request_asymmetric_key - Request a key by X.509 certificate params.
48 * @keyring: The keys to search. 54 * @keyring: The keys to search.
49 * @subject: The name of the subject to whom the key belongs. 55 * @kid: The key ID.
50 * @key_id: The subject key ID as a hex string.
51 * 56 *
52 * Find a key in the given keyring by subject name and key ID. These might, 57 * 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 58 * for instance, be the issuer name and the authority key ID of an X.509
54 * certificate that needs to be verified. 59 * certificate that needs to be verified.
55 */ 60 */
56struct key *x509_request_asymmetric_key(struct key *keyring, 61struct key *x509_request_asymmetric_key(struct key *keyring,
57 const char *subject, 62 const struct asymmetric_key_id *kid)
58 const char *key_id)
59{ 63{
60 key_ref_t key; 64 key_ref_t key;
61 size_t subject_len = strlen(subject), key_id_len = strlen(key_id); 65 char *id, *p;
62 char *id;
63 66
64 /* Construct an identifier "<subjname>:<keyid>". */ 67 /* Construct an identifier "id:<keyid>". */
65 id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL); 68 p = id = kmalloc(2 + 1 + kid->len * 2 + 1, GFP_KERNEL);
66 if (!id) 69 if (!id)
67 return ERR_PTR(-ENOMEM); 70 return ERR_PTR(-ENOMEM);
68 71
69 memcpy(id, subject, subject_len); 72 *p++ = 'i';
70 id[subject_len + 0] = ':'; 73 *p++ = 'd';
71 id[subject_len + 1] = ' '; 74 *p++ = ':';
72 memcpy(id + subject_len + 2, key_id, key_id_len); 75 p = bin2hex(p, kid->data, kid->len);
73 id[subject_len + 2 + key_id_len] = 0; 76 *p = 0;
74 77
75 pr_debug("Look up: \"%s\"\n", id); 78 pr_debug("Look up: \"%s\"\n", id);
76 79
@@ -112,6 +115,8 @@ int x509_get_sig_params(struct x509_certificate *cert)
112 115
113 pr_devel("==>%s()\n", __func__); 116 pr_devel("==>%s()\n", __func__);
114 117
118 if (cert->unsupported_crypto)
119 return -ENOPKG;
115 if (cert->sig.rsa.s) 120 if (cert->sig.rsa.s)
116 return 0; 121 return 0;
117 122
@@ -124,8 +129,13 @@ int x509_get_sig_params(struct x509_certificate *cert)
124 * big the hash operational data will be. 129 * big the hash operational data will be.
125 */ 130 */
126 tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0); 131 tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0);
127 if (IS_ERR(tfm)) 132 if (IS_ERR(tfm)) {
128 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 133 if (PTR_ERR(tfm) == -ENOENT) {
134 cert->unsupported_crypto = true;
135 return -ENOPKG;
136 }
137 return PTR_ERR(tfm);
138 }
129 139
130 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 140 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
131 digest_size = crypto_shash_digestsize(tfm); 141 digest_size = crypto_shash_digestsize(tfm);
@@ -172,6 +182,8 @@ int x509_check_signature(const struct public_key *pub,
172 return ret; 182 return ret;
173 183
174 ret = public_key_verify_signature(pub, &cert->sig); 184 ret = public_key_verify_signature(pub, &cert->sig);
185 if (ret == -ENOPKG)
186 cert->unsupported_crypto = true;
175 pr_debug("Cert Verification: %d\n", ret); 187 pr_debug("Cert Verification: %d\n", ret);
176 return ret; 188 return ret;
177} 189}
@@ -195,11 +207,10 @@ static int x509_validate_trust(struct x509_certificate *cert,
195 if (!trust_keyring) 207 if (!trust_keyring)
196 return -EOPNOTSUPP; 208 return -EOPNOTSUPP;
197 209
198 if (ca_keyid && !asymmetric_keyid_match(cert->authority, ca_keyid)) 210 if (ca_keyid && !asymmetric_key_id_same(cert->authority, ca_keyid))
199 return -EPERM; 211 return -EPERM;
200 212
201 key = x509_request_asymmetric_key(trust_keyring, 213 key = x509_request_asymmetric_key(trust_keyring, cert->authority);
202 cert->issuer, cert->authority);
203 if (!IS_ERR(key)) { 214 if (!IS_ERR(key)) {
204 if (!use_builtin_keys 215 if (!use_builtin_keys
205 || test_bit(KEY_FLAG_BUILTIN, &key->flags)) 216 || test_bit(KEY_FLAG_BUILTIN, &key->flags))
@@ -214,9 +225,11 @@ static int x509_validate_trust(struct x509_certificate *cert,
214 */ 225 */
215static int x509_key_preparse(struct key_preparsed_payload *prep) 226static int x509_key_preparse(struct key_preparsed_payload *prep)
216{ 227{
228 struct asymmetric_key_ids *kids;
217 struct x509_certificate *cert; 229 struct x509_certificate *cert;
230 const char *q;
218 size_t srlen, sulen; 231 size_t srlen, sulen;
219 char *desc = NULL; 232 char *desc = NULL, *p;
220 int ret; 233 int ret;
221 234
222 cert = x509_cert_parse(prep->data, prep->datalen); 235 cert = x509_cert_parse(prep->data, prep->datalen);
@@ -249,19 +262,12 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
249 pkey_algo_name[cert->sig.pkey_algo], 262 pkey_algo_name[cert->sig.pkey_algo],
250 hash_algo_name[cert->sig.pkey_hash_algo]); 263 hash_algo_name[cert->sig.pkey_hash_algo]);
251 264
252 if (!cert->fingerprint) {
253 pr_warn("Cert for '%s' must have a SubjKeyId extension\n",
254 cert->subject);
255 ret = -EKEYREJECTED;
256 goto error_free_cert;
257 }
258
259 cert->pub->algo = pkey_algo[cert->pub->pkey_algo]; 265 cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
260 cert->pub->id_type = PKEY_ID_X509; 266 cert->pub->id_type = PKEY_ID_X509;
261 267
262 /* Check the signature on the key if it appears to be self-signed */ 268 /* Check the signature on the key if it appears to be self-signed */
263 if (!cert->authority || 269 if (!cert->authority ||
264 strcmp(cert->fingerprint, cert->authority) == 0) { 270 asymmetric_key_id_same(cert->skid, cert->authority)) {
265 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 271 ret = x509_check_signature(cert->pub, cert); /* self-signed */
266 if (ret < 0) 272 if (ret < 0)
267 goto error_free_cert; 273 goto error_free_cert;
@@ -273,31 +279,47 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
273 279
274 /* Propose a description */ 280 /* Propose a description */
275 sulen = strlen(cert->subject); 281 sulen = strlen(cert->subject);
276 srlen = strlen(cert->fingerprint); 282 srlen = cert->raw_serial_size;
283 q = cert->raw_serial;
284 if (srlen > 1 && *q == 0) {
285 srlen--;
286 q++;
287 }
288
277 ret = -ENOMEM; 289 ret = -ENOMEM;
278 desc = kmalloc(sulen + 2 + srlen + 1, GFP_KERNEL); 290 desc = kmalloc(sulen + 2 + srlen * 2 + 1, GFP_KERNEL);
279 if (!desc) 291 if (!desc)
280 goto error_free_cert; 292 goto error_free_cert;
281 memcpy(desc, cert->subject, sulen); 293 p = memcpy(desc, cert->subject, sulen);
282 desc[sulen] = ':'; 294 p += sulen;
283 desc[sulen + 1] = ' '; 295 *p++ = ':';
284 memcpy(desc + sulen + 2, cert->fingerprint, srlen); 296 *p++ = ' ';
285 desc[sulen + 2 + srlen] = 0; 297 p = bin2hex(p, q, srlen);
298 *p = 0;
299
300 kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL);
301 if (!kids)
302 goto error_free_desc;
303 kids->id[0] = cert->id;
304 kids->id[1] = cert->skid;
286 305
287 /* We're pinning the module by being linked against it */ 306 /* We're pinning the module by being linked against it */
288 __module_get(public_key_subtype.owner); 307 __module_get(public_key_subtype.owner);
289 prep->type_data[0] = &public_key_subtype; 308 prep->type_data[0] = &public_key_subtype;
290 prep->type_data[1] = cert->fingerprint; 309 prep->type_data[1] = kids;
291 prep->payload[0] = cert->pub; 310 prep->payload[0] = cert->pub;
292 prep->description = desc; 311 prep->description = desc;
293 prep->quotalen = 100; 312 prep->quotalen = 100;
294 313
295 /* We've finished with the certificate */ 314 /* We've finished with the certificate */
296 cert->pub = NULL; 315 cert->pub = NULL;
297 cert->fingerprint = NULL; 316 cert->id = NULL;
317 cert->skid = NULL;
298 desc = NULL; 318 desc = NULL;
299 ret = 0; 319 ret = 0;
300 320
321error_free_desc:
322 kfree(desc);
301error_free_cert: 323error_free_cert:
302 x509_free_certificate(cert); 324 x509_free_certificate(cert);
303 return ret; 325 return ret;
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index a3e932547617..f4cf200b3c76 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -62,7 +62,6 @@ cifs_spnego_key_destroy(struct key *key)
62struct key_type cifs_spnego_key_type = { 62struct key_type cifs_spnego_key_type = {
63 .name = "cifs.spnego", 63 .name = "cifs.spnego",
64 .instantiate = cifs_spnego_key_instantiate, 64 .instantiate = cifs_spnego_key_instantiate,
65 .match = user_match,
66 .destroy = cifs_spnego_key_destroy, 65 .destroy = cifs_spnego_key_destroy,
67 .describe = user_describe, 66 .describe = user_describe,
68}; 67};
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 7ff866dbb89e..6d00c419cbae 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -84,7 +84,6 @@ static struct key_type cifs_idmap_key_type = {
84 .instantiate = cifs_idmap_key_instantiate, 84 .instantiate = cifs_idmap_key_instantiate,
85 .destroy = cifs_idmap_key_destroy, 85 .destroy = cifs_idmap_key_destroy,
86 .describe = user_describe, 86 .describe = user_describe,
87 .match = user_match,
88}; 87};
89 88
90static char * 89static char *
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 7dd55b745c4d..2f5db844c172 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -177,7 +177,6 @@ static struct key_type key_type_id_resolver = {
177 .preparse = user_preparse, 177 .preparse = user_preparse,
178 .free_preparse = user_free_preparse, 178 .free_preparse = user_free_preparse,
179 .instantiate = generic_key_instantiate, 179 .instantiate = generic_key_instantiate,
180 .match = user_match,
181 .revoke = user_revoke, 180 .revoke = user_revoke,
182 .destroy = user_destroy, 181 .destroy = user_destroy,
183 .describe = user_describe, 182 .describe = user_describe,
@@ -401,7 +400,6 @@ static struct key_type key_type_id_resolver_legacy = {
401 .preparse = user_preparse, 400 .preparse = user_preparse,
402 .free_preparse = user_free_preparse, 401 .free_preparse = user_free_preparse,
403 .instantiate = generic_key_instantiate, 402 .instantiate = generic_key_instantiate,
404 .match = user_match,
405 .revoke = user_revoke, 403 .revoke = user_revoke,
406 .destroy = user_destroy, 404 .destroy = user_destroy,
407 .describe = user_describe, 405 .describe = user_describe,
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
index 0d164c6af539..fa73a6fd536c 100644
--- a/include/crypto/public_key.h
+++ b/include/crypto/public_key.h
@@ -15,6 +15,7 @@
15#define _LINUX_PUBLIC_KEY_H 15#define _LINUX_PUBLIC_KEY_H
16 16
17#include <linux/mpi.h> 17#include <linux/mpi.h>
18#include <keys/asymmetric-type.h>
18#include <crypto/hash_info.h> 19#include <crypto/hash_info.h>
19 20
20enum pkey_algo { 21enum pkey_algo {
@@ -98,8 +99,8 @@ struct key;
98extern int verify_signature(const struct key *key, 99extern int verify_signature(const struct key *key,
99 const struct public_key_signature *sig); 100 const struct public_key_signature *sig);
100 101
102struct asymmetric_key_id;
101extern struct key *x509_request_asymmetric_key(struct key *keyring, 103extern struct key *x509_request_asymmetric_key(struct key *keyring,
102 const char *issuer, 104 const struct asymmetric_key_id *kid);
103 const char *key_id);
104 105
105#endif /* _LINUX_PUBLIC_KEY_H */ 106#endif /* _LINUX_PUBLIC_KEY_H */
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 @@
19extern struct key_type key_type_asymmetric; 19extern struct key_type key_type_asymmetric;
20 20
21/* 21/*
22 * Identifiers for an asymmetric key ID. We have three ways of looking up a
23 * key derived from an X.509 certificate:
24 *
25 * (1) Serial Number & Issuer. Non-optional. This is the only valid way to
26 * map a PKCS#7 signature to an X.509 certificate.
27 *
28 * (2) Issuer & Subject Unique IDs. Optional. These were the original way to
29 * match X.509 certificates, but have fallen into disuse in favour of (3).
30 *
31 * (3) Auth & Subject Key Identifiers. Optional. SKIDs are only provided on
32 * CA keys that are intended to sign other keys, so don't appear in end
33 * user certificates unless forced.
34 *
35 * We could also support an PGP key identifier, which is just a SHA1 sum of the
36 * public key and certain parameters, but since we don't support PGP keys at
37 * the moment, we shall ignore those.
38 *
39 * What we actually do is provide a place where binary identifiers can be
40 * stashed and then compare against them when checking for an id match.
41 */
42struct asymmetric_key_id {
43 unsigned short len;
44 unsigned char data[];
45};
46
47struct asymmetric_key_ids {
48 void *id[2];
49};
50
51extern bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
52 const struct asymmetric_key_id *kid2);
53
54extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
55 size_t len_1,
56 const void *val_2,
57 size_t len_2);
58
59/*
22 * The payload is at the discretion of the subtype. 60 * The payload is at the discretion of the subtype.
23 */ 61 */
24 62
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index 3ab1873a4bfa..cebefb069c44 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -40,7 +40,6 @@ struct key_preparsed_payload;
40extern int user_preparse(struct key_preparsed_payload *prep); 40extern int user_preparse(struct key_preparsed_payload *prep);
41extern void user_free_preparse(struct key_preparsed_payload *prep); 41extern void user_free_preparse(struct key_preparsed_payload *prep);
42extern int user_update(struct key *key, struct key_preparsed_payload *prep); 42extern int user_update(struct key *key, struct key_preparsed_payload *prep);
43extern int user_match(const struct key *key, const void *criterion);
44extern void user_revoke(struct key *key); 43extern void user_revoke(struct key *key);
45extern void user_destroy(struct key *key); 44extern void user_destroy(struct key *key);
46extern void user_describe(const struct key *user, struct seq_file *m); 45extern void user_describe(const struct key *user, struct seq_file *m);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4c52907a6d8b..89a0b8e5a952 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -500,6 +500,7 @@ static inline char * __deprecated pack_hex_byte(char *buf, u8 byte)
500 500
501extern int hex_to_bin(char ch); 501extern int hex_to_bin(char ch);
502extern int __must_check hex2bin(u8 *dst, const char *src, size_t count); 502extern int __must_check hex2bin(u8 *dst, const char *src, size_t count);
503extern char *bin2hex(char *dst, const void *src, size_t count);
503 504
504int mac_pton(const char *s, u8 *mac); 505int mac_pton(const char *s, u8 *mac);
505 506
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 44792ee649de..ff9f1d394235 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -53,6 +53,24 @@ typedef int (*request_key_actor_t)(struct key_construction *key,
53 const char *op, void *aux); 53 const char *op, void *aux);
54 54
55/* 55/*
56 * Preparsed matching criterion.
57 */
58struct key_match_data {
59 /* Comparison function, defaults to exact description match, but can be
60 * overridden by type->match_preparse(). Should return true if a match
61 * is found and false if not.
62 */
63 bool (*cmp)(const struct key *key,
64 const struct key_match_data *match_data);
65
66 const void *raw_data; /* Raw match data */
67 void *preparsed; /* For ->match_preparse() to stash stuff */
68 unsigned lookup_type; /* Type of lookup for this search. */
69#define KEYRING_SEARCH_LOOKUP_DIRECT 0x0000 /* Direct lookup by description. */
70#define KEYRING_SEARCH_LOOKUP_ITERATE 0x0001 /* Iterative search. */
71};
72
73/*
56 * kernel managed key type definition 74 * kernel managed key type definition
57 */ 75 */
58struct key_type { 76struct key_type {
@@ -65,11 +83,6 @@ struct key_type {
65 */ 83 */
66 size_t def_datalen; 84 size_t def_datalen;
67 85
68 /* Default key search algorithm. */
69 unsigned def_lookup_type;
70#define KEYRING_SEARCH_LOOKUP_DIRECT 0x0000 /* Direct lookup by description. */
71#define KEYRING_SEARCH_LOOKUP_ITERATE 0x0001 /* Iterative search. */
72
73 /* vet a description */ 86 /* vet a description */
74 int (*vet_description)(const char *description); 87 int (*vet_description)(const char *description);
75 88
@@ -96,8 +109,15 @@ struct key_type {
96 */ 109 */
97 int (*update)(struct key *key, struct key_preparsed_payload *prep); 110 int (*update)(struct key *key, struct key_preparsed_payload *prep);
98 111
99 /* match a key against a description */ 112 /* Preparse the data supplied to ->match() (optional). The
100 int (*match)(const struct key *key, const void *desc); 113 * data to be preparsed can be found in match_data->raw_data.
114 * The lookup type can also be set by this function.
115 */
116 int (*match_preparse)(struct key_match_data *match_data);
117
118 /* Free preparsed match data (optional). This should be supplied it
119 * ->match_preparse() is supplied. */
120 void (*match_free)(struct key_match_data *match_data);
101 121
102 /* clear some of the data from a key on revokation (optional) 122 /* clear some of the data from a key on revokation (optional)
103 * - the key's semaphore will be write-locked by the caller 123 * - the key's semaphore will be write-locked by the caller
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 8499c810909a..270773b91923 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -59,6 +59,22 @@ int hex2bin(u8 *dst, const char *src, size_t count)
59EXPORT_SYMBOL(hex2bin); 59EXPORT_SYMBOL(hex2bin);
60 60
61/** 61/**
62 * bin2hex - convert binary data to an ascii hexadecimal string
63 * @dst: ascii hexadecimal result
64 * @src: binary data
65 * @count: binary data length
66 */
67char *bin2hex(char *dst, const void *src, size_t count)
68{
69 const unsigned char *_src = src;
70
71 while (count--)
72 dst = hex_byte_pack(dst, *_src++);
73 return dst;
74}
75EXPORT_SYMBOL(bin2hex);
76
77/**
62 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory 78 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
63 * @buf: data blob to dump 79 * @buf: data blob to dump
64 * @len: number of bytes in the @buf 80 * @len: number of bytes in the @buf
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index ffeba8f9dda9..62fc5e7a9acf 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -476,7 +476,6 @@ struct key_type key_type_ceph = {
476 .preparse = ceph_key_preparse, 476 .preparse = ceph_key_preparse,
477 .free_preparse = ceph_key_free_preparse, 477 .free_preparse = ceph_key_free_preparse,
478 .instantiate = generic_key_instantiate, 478 .instantiate = generic_key_instantiate,
479 .match = user_match,
480 .destroy = ceph_key_destroy, 479 .destroy = ceph_key_destroy,
481}; 480};
482 481
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index f380b2c58178..31cd4fd75486 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -176,11 +176,11 @@ static void dns_resolver_free_preparse(struct key_preparsed_payload *prep)
176 * The domain name may be a simple name or an absolute domain name (which 176 * The domain name may be a simple name or an absolute domain name (which
177 * should end with a period). The domain name is case-independent. 177 * should end with a period). The domain name is case-independent.
178 */ 178 */
179static int 179static bool dns_resolver_cmp(const struct key *key,
180dns_resolver_match(const struct key *key, const void *description) 180 const struct key_match_data *match_data)
181{ 181{
182 int slen, dlen, ret = 0; 182 int slen, dlen, ret = 0;
183 const char *src = key->description, *dsp = description; 183 const char *src = key->description, *dsp = match_data->raw_data;
184 184
185 kenter("%s,%s", src, dsp); 185 kenter("%s,%s", src, dsp);
186 186
@@ -209,6 +209,16 @@ no_match:
209} 209}
210 210
211/* 211/*
212 * Preparse the match criterion.
213 */
214static int dns_resolver_match_preparse(struct key_match_data *match_data)
215{
216 match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
217 match_data->cmp = dns_resolver_cmp;
218 return 0;
219}
220
221/*
212 * Describe a DNS key 222 * Describe a DNS key
213 */ 223 */
214static void dns_resolver_describe(const struct key *key, struct seq_file *m) 224static void dns_resolver_describe(const struct key *key, struct seq_file *m)
@@ -242,7 +252,7 @@ struct key_type key_type_dns_resolver = {
242 .preparse = dns_resolver_preparse, 252 .preparse = dns_resolver_preparse,
243 .free_preparse = dns_resolver_free_preparse, 253 .free_preparse = dns_resolver_free_preparse,
244 .instantiate = generic_key_instantiate, 254 .instantiate = generic_key_instantiate,
245 .match = dns_resolver_match, 255 .match_preparse = dns_resolver_match_preparse,
246 .revoke = user_revoke, 256 .revoke = user_revoke,
247 .destroy = user_destroy, 257 .destroy = user_destroy,
248 .describe = dns_resolver_describe, 258 .describe = dns_resolver_describe,
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 3907add75932..10c6cb694b43 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -44,7 +44,6 @@ struct key_type key_type_rxrpc = {
44 .preparse = rxrpc_preparse, 44 .preparse = rxrpc_preparse,
45 .free_preparse = rxrpc_free_preparse, 45 .free_preparse = rxrpc_free_preparse,
46 .instantiate = generic_key_instantiate, 46 .instantiate = generic_key_instantiate,
47 .match = user_match,
48 .destroy = rxrpc_destroy, 47 .destroy = rxrpc_destroy,
49 .describe = rxrpc_describe, 48 .describe = rxrpc_describe,
50 .read = rxrpc_read, 49 .read = rxrpc_read,
@@ -61,7 +60,6 @@ struct key_type key_type_rxrpc_s = {
61 .preparse = rxrpc_preparse_s, 60 .preparse = rxrpc_preparse_s,
62 .free_preparse = rxrpc_free_preparse_s, 61 .free_preparse = rxrpc_free_preparse_s,
63 .instantiate = generic_key_instantiate, 62 .instantiate = generic_key_instantiate,
64 .match = user_match,
65 .destroy = rxrpc_destroy_s, 63 .destroy = rxrpc_destroy_s,
66 .describe = rxrpc_describe, 64 .describe = rxrpc_describe,
67}; 65};
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index c2f91a0cf889..b6adb94f6d52 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -33,11 +33,9 @@ MODULE_LICENSE("GPL");
33 */ 33 */
34struct key_type key_type_big_key = { 34struct key_type key_type_big_key = {
35 .name = "big_key", 35 .name = "big_key",
36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
37 .preparse = big_key_preparse, 36 .preparse = big_key_preparse,
38 .free_preparse = big_key_free_preparse, 37 .free_preparse = big_key_free_preparse,
39 .instantiate = generic_key_instantiate, 38 .instantiate = generic_key_instantiate,
40 .match = user_match,
41 .revoke = big_key_revoke, 39 .revoke = big_key_revoke,
42 .destroy = big_key_destroy, 40 .destroy = big_key_destroy,
43 .describe = big_key_describe, 41 .describe = big_key_describe,
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 5fe443d120af..db9675db1026 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -970,7 +970,6 @@ struct key_type key_type_encrypted = {
970 .name = "encrypted", 970 .name = "encrypted",
971 .instantiate = encrypted_instantiate, 971 .instantiate = encrypted_instantiate,
972 .update = encrypted_update, 972 .update = encrypted_update,
973 .match = user_match,
974 .destroy = encrypted_destroy, 973 .destroy = encrypted_destroy,
975 .describe = user_describe, 974 .describe = user_describe,
976 .read = encrypted_read, 975 .read = encrypted_read,
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 5f20da01fd8d..b8960c4959a5 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -107,20 +107,16 @@ extern int iterate_over_keyring(const struct key *keyring,
107 int (*func)(const struct key *key, void *data), 107 int (*func)(const struct key *key, void *data),
108 void *data); 108 void *data);
109 109
110typedef int (*key_match_func_t)(const struct key *, const void *);
111
112struct keyring_search_context { 110struct keyring_search_context {
113 struct keyring_index_key index_key; 111 struct keyring_index_key index_key;
114 const struct cred *cred; 112 const struct cred *cred;
115 key_match_func_t match; 113 struct key_match_data match_data;
116 const void *match_data;
117 unsigned flags; 114 unsigned flags;
118#define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */ 115#define KEYRING_SEARCH_NO_STATE_CHECK 0x0001 /* Skip state checks */
119#define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */ 116#define KEYRING_SEARCH_DO_STATE_CHECK 0x0002 /* Override NO_STATE_CHECK */
120#define KEYRING_SEARCH_DO_STATE_CHECK 0x0004 /* Override NO_STATE_CHECK */ 117#define KEYRING_SEARCH_NO_UPDATE_TIME 0x0004 /* Don't update times */
121#define KEYRING_SEARCH_NO_UPDATE_TIME 0x0008 /* Don't update times */ 118#define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */
122#define KEYRING_SEARCH_NO_CHECK_PERM 0x0010 /* Don't check permissions */ 119#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */
123#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0020 /* Give an error on excessive depth */
124 120
125 int (*iterator)(const void *object, void *iterator_data); 121 int (*iterator)(const void *object, void *iterator_data);
126 122
@@ -131,6 +127,8 @@ struct keyring_search_context {
131 struct timespec now; 127 struct timespec now;
132}; 128};
133 129
130extern bool key_default_cmp(const struct key *key,
131 const struct key_match_data *match_data);
134extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, 132extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
135 struct keyring_search_context *ctx); 133 struct keyring_search_context *ctx);
136 134
@@ -152,7 +150,8 @@ extern struct key *request_key_and_link(struct key_type *type,
152 struct key *dest_keyring, 150 struct key *dest_keyring,
153 unsigned long flags); 151 unsigned long flags);
154 152
155extern int lookup_user_key_possessed(const struct key *key, const void *target); 153extern bool lookup_user_key_possessed(const struct key *key,
154 const struct key_match_data *match_data);
156extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, 155extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
157 key_perm_t perm); 156 key_perm_t perm);
158#define KEY_LOOKUP_CREATE 0x01 157#define KEY_LOOKUP_CREATE 0x01
diff --git a/security/keys/key.c b/security/keys/key.c
index b90a68c4e2c4..8c0092ca0443 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -799,7 +799,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
799 } 799 }
800 800
801 key_ref = ERR_PTR(-EINVAL); 801 key_ref = ERR_PTR(-EINVAL);
802 if (!index_key.type->match || !index_key.type->instantiate || 802 if (!index_key.type->instantiate ||
803 (!index_key.description && !index_key.type->preparse)) 803 (!index_key.description && !index_key.type->preparse))
804 goto error_put_type; 804 goto error_put_type;
805 805
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index e26f860e5f2e..eff88a5f5d40 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -37,6 +37,8 @@ static int key_get_type_from_user(char *type,
37 return ret; 37 return ret;
38 if (ret == 0 || ret >= len) 38 if (ret == 0 || ret >= len)
39 return -EINVAL; 39 return -EINVAL;
40 if (type[0] == '.')
41 return -EPERM;
40 type[len - 1] = '\0'; 42 type[len - 1] = '\0';
41 return 0; 43 return 0;
42} 44}
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 8314a7d2104d..8177010174f7 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -89,7 +89,6 @@ struct key_type key_type_keyring = {
89 .preparse = keyring_preparse, 89 .preparse = keyring_preparse,
90 .free_preparse = keyring_free_preparse, 90 .free_preparse = keyring_free_preparse,
91 .instantiate = keyring_instantiate, 91 .instantiate = keyring_instantiate,
92 .match = user_match,
93 .revoke = keyring_revoke, 92 .revoke = keyring_revoke,
94 .destroy = keyring_destroy, 93 .destroy = keyring_destroy,
95 .describe = keyring_describe, 94 .describe = keyring_describe,
@@ -512,6 +511,15 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
512EXPORT_SYMBOL(keyring_alloc); 511EXPORT_SYMBOL(keyring_alloc);
513 512
514/* 513/*
514 * By default, we keys found by getting an exact match on their descriptions.
515 */
516bool key_default_cmp(const struct key *key,
517 const struct key_match_data *match_data)
518{
519 return strcmp(key->description, match_data->raw_data) == 0;
520}
521
522/*
515 * Iteration function to consider each key found. 523 * Iteration function to consider each key found.
516 */ 524 */
517static int keyring_search_iterator(const void *object, void *iterator_data) 525static int keyring_search_iterator(const void *object, void *iterator_data)
@@ -545,7 +553,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
545 } 553 }
546 554
547 /* keys that don't match */ 555 /* keys that don't match */
548 if (!ctx->match(key, ctx->match_data)) { 556 if (!ctx->match_data.cmp(key, &ctx->match_data)) {
549 kleave(" = 0 [!match]"); 557 kleave(" = 0 [!match]");
550 return 0; 558 return 0;
551 } 559 }
@@ -585,8 +593,7 @@ skipped:
585 */ 593 */
586static int search_keyring(struct key *keyring, struct keyring_search_context *ctx) 594static int search_keyring(struct key *keyring, struct keyring_search_context *ctx)
587{ 595{
588 if ((ctx->flags & KEYRING_SEARCH_LOOKUP_TYPE) == 596 if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_DIRECT) {
589 KEYRING_SEARCH_LOOKUP_DIRECT) {
590 const void *object; 597 const void *object;
591 598
592 object = assoc_array_find(&keyring->keys, 599 object = assoc_array_find(&keyring->keys,
@@ -627,7 +634,7 @@ static bool search_nested_keyrings(struct key *keyring,
627 /* Check to see if this top-level keyring is what we are looking for 634 /* Check to see if this top-level keyring is what we are looking for
628 * and whether it is valid or not. 635 * and whether it is valid or not.
629 */ 636 */
630 if (ctx->flags & KEYRING_SEARCH_LOOKUP_ITERATE || 637 if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_ITERATE ||
631 keyring_compare_object(keyring, &ctx->index_key)) { 638 keyring_compare_object(keyring, &ctx->index_key)) {
632 ctx->skipped_ret = 2; 639 ctx->skipped_ret = 2;
633 ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK; 640 ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK;
@@ -885,16 +892,25 @@ key_ref_t keyring_search(key_ref_t keyring,
885 .index_key.type = type, 892 .index_key.type = type,
886 .index_key.description = description, 893 .index_key.description = description,
887 .cred = current_cred(), 894 .cred = current_cred(),
888 .match = type->match, 895 .match_data.cmp = key_default_cmp,
889 .match_data = description, 896 .match_data.raw_data = description,
890 .flags = (type->def_lookup_type | 897 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
891 KEYRING_SEARCH_DO_STATE_CHECK), 898 .flags = KEYRING_SEARCH_DO_STATE_CHECK,
892 }; 899 };
900 key_ref_t key;
901 int ret;
893 902
894 if (!ctx.match) 903 if (type->match_preparse) {
895 return ERR_PTR(-ENOKEY); 904 ret = type->match_preparse(&ctx.match_data);
905 if (ret < 0)
906 return ERR_PTR(ret);
907 }
896 908
897 return keyring_search_aux(keyring, &ctx); 909 key = keyring_search_aux(keyring, &ctx);
910
911 if (type->match_free)
912 type->match_free(&ctx.match_data);
913 return key;
898} 914}
899EXPORT_SYMBOL(keyring_search); 915EXPORT_SYMBOL(keyring_search);
900 916
@@ -1014,7 +1030,7 @@ static int keyring_detect_cycle_iterator(const void *object,
1014 1030
1015 /* We might get a keyring with matching index-key that is nonetheless a 1031 /* We might get a keyring with matching index-key that is nonetheless a
1016 * different keyring. */ 1032 * different keyring. */
1017 if (key != ctx->match_data) 1033 if (key != ctx->match_data.raw_data)
1018 return 0; 1034 return 0;
1019 1035
1020 ctx->result = ERR_PTR(-EDEADLK); 1036 ctx->result = ERR_PTR(-EDEADLK);
@@ -1031,14 +1047,14 @@ static int keyring_detect_cycle_iterator(const void *object,
1031static int keyring_detect_cycle(struct key *A, struct key *B) 1047static int keyring_detect_cycle(struct key *A, struct key *B)
1032{ 1048{
1033 struct keyring_search_context ctx = { 1049 struct keyring_search_context ctx = {
1034 .index_key = A->index_key, 1050 .index_key = A->index_key,
1035 .match_data = A, 1051 .match_data.raw_data = A,
1036 .iterator = keyring_detect_cycle_iterator, 1052 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
1037 .flags = (KEYRING_SEARCH_LOOKUP_DIRECT | 1053 .iterator = keyring_detect_cycle_iterator,
1038 KEYRING_SEARCH_NO_STATE_CHECK | 1054 .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
1039 KEYRING_SEARCH_NO_UPDATE_TIME | 1055 KEYRING_SEARCH_NO_UPDATE_TIME |
1040 KEYRING_SEARCH_NO_CHECK_PERM | 1056 KEYRING_SEARCH_NO_CHECK_PERM |
1041 KEYRING_SEARCH_DETECT_TOO_DEEP), 1057 KEYRING_SEARCH_DETECT_TOO_DEEP),
1042 }; 1058 };
1043 1059
1044 rcu_read_lock(); 1060 rcu_read_lock();
diff --git a/security/keys/proc.c b/security/keys/proc.c
index d3f6f2fd21db..972eeb336b81 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -194,10 +194,10 @@ static int proc_keys_show(struct seq_file *m, void *v)
194 .index_key.type = key->type, 194 .index_key.type = key->type,
195 .index_key.description = key->description, 195 .index_key.description = key->description,
196 .cred = current_cred(), 196 .cred = current_cred(),
197 .match = lookup_user_key_possessed, 197 .match_data.cmp = lookup_user_key_possessed,
198 .match_data = key, 198 .match_data.raw_data = key,
199 .flags = (KEYRING_SEARCH_NO_STATE_CHECK | 199 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
200 KEYRING_SEARCH_LOOKUP_DIRECT), 200 .flags = KEYRING_SEARCH_NO_STATE_CHECK,
201 }; 201 };
202 202
203 key_ref = make_key_ref(key, 0); 203 key_ref = make_key_ref(key, 0);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 0cf8a130a267..bd536cb221e2 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -489,9 +489,10 @@ found:
489/* 489/*
490 * See if the key we're looking at is the target key. 490 * See if the key we're looking at is the target key.
491 */ 491 */
492int lookup_user_key_possessed(const struct key *key, const void *target) 492bool lookup_user_key_possessed(const struct key *key,
493 const struct key_match_data *match_data)
493{ 494{
494 return key == target; 495 return key == match_data->raw_data;
495} 496}
496 497
497/* 498/*
@@ -516,9 +517,9 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
516 key_perm_t perm) 517 key_perm_t perm)
517{ 518{
518 struct keyring_search_context ctx = { 519 struct keyring_search_context ctx = {
519 .match = lookup_user_key_possessed, 520 .match_data.cmp = lookup_user_key_possessed,
520 .flags = (KEYRING_SEARCH_NO_STATE_CHECK | 521 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
521 KEYRING_SEARCH_LOOKUP_DIRECT), 522 .flags = KEYRING_SEARCH_NO_STATE_CHECK,
522 }; 523 };
523 struct request_key_auth *rka; 524 struct request_key_auth *rka;
524 struct key *key; 525 struct key *key;
@@ -673,7 +674,7 @@ try_again:
673 ctx.index_key.type = key->type; 674 ctx.index_key.type = key->type;
674 ctx.index_key.description = key->description; 675 ctx.index_key.description = key->description;
675 ctx.index_key.desc_len = strlen(key->description); 676 ctx.index_key.desc_len = strlen(key->description);
676 ctx.match_data = key; 677 ctx.match_data.raw_data = key;
677 kdebug("check possessed"); 678 kdebug("check possessed");
678 skey_ref = search_process_keyrings(&ctx); 679 skey_ref = search_process_keyrings(&ctx);
679 kdebug("possessed=%p", skey_ref); 680 kdebug("possessed=%p", skey_ref);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 381411941cc1..dc6ed32b7844 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -531,9 +531,9 @@ struct key *request_key_and_link(struct key_type *type,
531 .index_key.type = type, 531 .index_key.type = type,
532 .index_key.description = description, 532 .index_key.description = description,
533 .cred = current_cred(), 533 .cred = current_cred(),
534 .match = type->match, 534 .match_data.cmp = key_default_cmp,
535 .match_data = description, 535 .match_data.raw_data = description,
536 .flags = KEYRING_SEARCH_LOOKUP_DIRECT, 536 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
537 }; 537 };
538 struct key *key; 538 struct key *key;
539 key_ref_t key_ref; 539 key_ref_t key_ref;
@@ -543,6 +543,14 @@ struct key *request_key_and_link(struct key_type *type,
543 ctx.index_key.type->name, ctx.index_key.description, 543 ctx.index_key.type->name, ctx.index_key.description,
544 callout_info, callout_len, aux, dest_keyring, flags); 544 callout_info, callout_len, aux, dest_keyring, flags);
545 545
546 if (type->match_preparse) {
547 ret = type->match_preparse(&ctx.match_data);
548 if (ret < 0) {
549 key = ERR_PTR(ret);
550 goto error;
551 }
552 }
553
546 /* search all the process keyrings for a key */ 554 /* search all the process keyrings for a key */
547 key_ref = search_process_keyrings(&ctx); 555 key_ref = search_process_keyrings(&ctx);
548 556
@@ -555,7 +563,7 @@ struct key *request_key_and_link(struct key_type *type,
555 if (ret < 0) { 563 if (ret < 0) {
556 key_put(key); 564 key_put(key);
557 key = ERR_PTR(ret); 565 key = ERR_PTR(ret);
558 goto error; 566 goto error_free;
559 } 567 }
560 } 568 }
561 } else if (PTR_ERR(key_ref) != -EAGAIN) { 569 } else if (PTR_ERR(key_ref) != -EAGAIN) {
@@ -565,12 +573,15 @@ struct key *request_key_and_link(struct key_type *type,
565 * should consult userspace if we can */ 573 * should consult userspace if we can */
566 key = ERR_PTR(-ENOKEY); 574 key = ERR_PTR(-ENOKEY);
567 if (!callout_info) 575 if (!callout_info)
568 goto error; 576 goto error_free;
569 577
570 key = construct_key_and_link(&ctx, callout_info, callout_len, 578 key = construct_key_and_link(&ctx, callout_info, callout_len,
571 aux, dest_keyring, flags); 579 aux, dest_keyring, flags);
572 } 580 }
573 581
582error_free:
583 if (type->match_free)
584 type->match_free(&ctx.match_data);
574error: 585error:
575 kleave(" = %p", key); 586 kleave(" = %p", key);
576 return key; 587 return key;
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 842e6f410d50..6639e2cb8853 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -44,12 +44,12 @@ struct key_type key_type_request_key_auth = {
44 .read = request_key_auth_read, 44 .read = request_key_auth_read,
45}; 45};
46 46
47int request_key_auth_preparse(struct key_preparsed_payload *prep) 47static int request_key_auth_preparse(struct key_preparsed_payload *prep)
48{ 48{
49 return 0; 49 return 0;
50} 50}
51 51
52void request_key_auth_free_preparse(struct key_preparsed_payload *prep) 52static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
53{ 53{
54} 54}
55 55
@@ -246,9 +246,9 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
246 .index_key.type = &key_type_request_key_auth, 246 .index_key.type = &key_type_request_key_auth,
247 .index_key.description = description, 247 .index_key.description = description,
248 .cred = current_cred(), 248 .cred = current_cred(),
249 .match = user_match, 249 .match_data.cmp = key_default_cmp,
250 .match_data = description, 250 .match_data.raw_data = description,
251 .flags = KEYRING_SEARCH_LOOKUP_DIRECT, 251 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
252 }; 252 };
253 struct key *authkey; 253 struct key *authkey;
254 key_ref_t authkey_ref; 254 key_ref_t authkey_ref;
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 6b804aa4529a..c0594cb07ada 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -1096,7 +1096,6 @@ struct key_type key_type_trusted = {
1096 .name = "trusted", 1096 .name = "trusted",
1097 .instantiate = trusted_instantiate, 1097 .instantiate = trusted_instantiate,
1098 .update = trusted_update, 1098 .update = trusted_update,
1099 .match = user_match,
1100 .destroy = trusted_destroy, 1099 .destroy = trusted_destroy,
1101 .describe = user_describe, 1100 .describe = user_describe,
1102 .read = trusted_read, 1101 .read = trusted_read,
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index eee340011f2b..36b47bbd3d8c 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -26,12 +26,10 @@ static int logon_vet_description(const char *desc);
26 */ 26 */
27struct key_type key_type_user = { 27struct key_type key_type_user = {
28 .name = "user", 28 .name = "user",
29 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
30 .preparse = user_preparse, 29 .preparse = user_preparse,
31 .free_preparse = user_free_preparse, 30 .free_preparse = user_free_preparse,
32 .instantiate = generic_key_instantiate, 31 .instantiate = generic_key_instantiate,
33 .update = user_update, 32 .update = user_update,
34 .match = user_match,
35 .revoke = user_revoke, 33 .revoke = user_revoke,
36 .destroy = user_destroy, 34 .destroy = user_destroy,
37 .describe = user_describe, 35 .describe = user_describe,
@@ -48,12 +46,10 @@ EXPORT_SYMBOL_GPL(key_type_user);
48 */ 46 */
49struct key_type key_type_logon = { 47struct key_type key_type_logon = {
50 .name = "logon", 48 .name = "logon",
51 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
52 .preparse = user_preparse, 49 .preparse = user_preparse,
53 .free_preparse = user_free_preparse, 50 .free_preparse = user_free_preparse,
54 .instantiate = generic_key_instantiate, 51 .instantiate = generic_key_instantiate,
55 .update = user_update, 52 .update = user_update,
56 .match = user_match,
57 .revoke = user_revoke, 53 .revoke = user_revoke,
58 .destroy = user_destroy, 54 .destroy = user_destroy,
59 .describe = user_describe, 55 .describe = user_describe,
@@ -139,16 +135,6 @@ error:
139EXPORT_SYMBOL_GPL(user_update); 135EXPORT_SYMBOL_GPL(user_update);
140 136
141/* 137/*
142 * match users on their name
143 */
144int user_match(const struct key *key, const void *description)
145{
146 return strcmp(key->description, description) == 0;
147}
148
149EXPORT_SYMBOL_GPL(user_match);
150
151/*
152 * dispose of the links from a revoked keyring 138 * dispose of the links from a revoked keyring
153 * - called with the key sem write-locked 139 * - called with the key sem write-locked
154 */ 140 */