aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-12 10:13:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-12 10:13:55 -0400
commit5e40d331bd72447197f26525f21711c4a265b6a6 (patch)
treecfbf5efba46b0c5c5b3c8149395f721eab839945 /crypto
parentd0ca47575ab3b41bb7f0fe5feec13c6cddb2913a (diff)
parent594081ee7145cc30a3977cb4e218f81213b63dc5 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris. Mostly ima, selinux, smack and key handling updates. * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (65 commits) integrity: do zero padding of the key id KEYS: output last portion of fingerprint in /proc/keys KEYS: strip 'id:' from ca_keyid KEYS: use swapped SKID for performing partial matching KEYS: Restore partial ID matching functionality for asymmetric keys X.509: If available, use the raw subjKeyId to form the key description KEYS: handle error code encoded in pointer selinux: normalize audit log formatting selinux: cleanup error reporting in selinux_nlmsg_perm() KEYS: Check hex2bin()'s return when generating an asymmetric key ID ima: detect violations for mmaped files ima: fix race condition on ima_rdwr_violation_check and process_measurement ima: added ima_policy_flag variable ima: return an error code from ima_add_boot_aggregate() ima: provide 'ima_appraise=log' kernel option ima: move keyring initialization to ima_init() PKCS#7: Handle PKCS#7 messages that contain no X.509 certs PKCS#7: Better handling of unsupported crypto KEYS: Overhaul key identification when searching for asymmetric keys KEYS: Implement binary asymmetric key ID handling ...
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asymmetric_keys/asymmetric_keys.h5
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c265
-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.c90
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c102
-rw-r--r--crypto/asymmetric_keys/signature.c1
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c57
-rw-r--r--crypto/asymmetric_keys/x509_parser.h8
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c115
11 files changed, 518 insertions, 232 deletions
diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h
index a63c551c6557..f97330886d58 100644
--- a/crypto/asymmetric_keys/asymmetric_keys.h
+++ b/crypto/asymmetric_keys/asymmetric_keys.h
@@ -9,9 +9,10 @@
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 struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
13 13
14static inline const char *asymmetric_key_id(const struct key *key) 14static inline
15const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
15{ 16{
16 return key->type_data.p[1]; 17 return key->type_data.p[1];
17} 18}
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index eb8cd46961a5..bcbbbd794e1d 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,209 @@ 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.
28 */ 34 */
29int asymmetric_keyid_match(const char *kid, const char *id) 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)
30{ 39{
31 size_t idlen, kidlen; 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);
32 52
33 if (!kid || !id) 53/**
34 return 0; 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
56 */
57bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
58 const struct asymmetric_key_id *kid2)
59{
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);
35 67
36 /* make it possible to use id as in the request: "id:<id>" */ 68/**
37 if (strncmp(id, "id:", 3) == 0) 69 * asymmetric_key_id_partial - Return true if two asymmetric keys IDs
38 id += 3; 70 * partially match
71 * @kid_1, @kid_2: The key IDs to compare
72 */
73bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
74 const struct asymmetric_key_id *kid2)
75{
76 if (!kid1 || !kid2)
77 return false;
78 if (kid1->len < kid2->len)
79 return false;
80 return memcmp(kid1->data + (kid1->len - kid2->len),
81 kid2->data, kid2->len) == 0;
82}
83EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
39 84
40 /* Anything after here requires a partial match on the ID string */ 85/**
41 idlen = strlen(id); 86 * asymmetric_match_key_ids - Search asymmetric key IDs
42 kidlen = strlen(kid); 87 * @kids: The list of key IDs to check
43 if (idlen > kidlen) 88 * @match_id: The key ID we're looking for
44 return 0; 89 * @match: The match function to use
90 */
91static bool asymmetric_match_key_ids(
92 const struct asymmetric_key_ids *kids,
93 const struct asymmetric_key_id *match_id,
94 bool (*match)(const struct asymmetric_key_id *kid1,
95 const struct asymmetric_key_id *kid2))
96{
97 int i;
98
99 if (!kids || !match_id)
100 return false;
101 for (i = 0; i < ARRAY_SIZE(kids->id); i++)
102 if (match(kids->id[i], match_id))
103 return true;
104 return false;
105}
45 106
46 kid += kidlen - idlen; 107/**
47 if (strcasecmp(id, kid) != 0) 108 * asymmetric_key_hex_to_key_id - Convert a hex string into a key ID.
48 return 0; 109 * @id: The ID as a hex string.
110 */
111struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
112{
113 struct asymmetric_key_id *match_id;
114 size_t hexlen;
115 int ret;
49 116
50 return 1; 117 if (!*id)
118 return ERR_PTR(-EINVAL);
119 hexlen = strlen(id);
120 if (hexlen & 1)
121 return ERR_PTR(-EINVAL);
122
123 match_id = kmalloc(sizeof(struct asymmetric_key_id) + hexlen / 2,
124 GFP_KERNEL);
125 if (!match_id)
126 return ERR_PTR(-ENOMEM);
127 match_id->len = hexlen / 2;
128 ret = hex2bin(match_id->data, id, hexlen / 2);
129 if (ret < 0) {
130 kfree(match_id);
131 return ERR_PTR(-EINVAL);
132 }
133 return match_id;
51} 134}
52EXPORT_SYMBOL_GPL(asymmetric_keyid_match);
53 135
54/* 136/*
55 * Match asymmetric keys on (part of) their name 137 * Match asymmetric keys by an exact match on an ID.
56 * We have some shorthand methods for matching keys. We allow:
57 *
58 * "<desc>" - request a key by description
59 * "id:<id>" - request a key matching the ID
60 * "<subtype>:<id>" - request a key of a subtype
61 */ 138 */
62static int asymmetric_key_match(const struct key *key, const void *description) 139static bool asymmetric_key_cmp(const struct key *key,
140 const struct key_match_data *match_data)
63{ 141{
64 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 142 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
65 const char *spec = description; 143 const struct asymmetric_key_id *match_id = match_data->preparsed;
66 const char *id;
67 ptrdiff_t speclen;
68 144
69 if (!subtype || !spec || !*spec) 145 return asymmetric_match_key_ids(kids, match_id,
70 return 0; 146 asymmetric_key_id_same);
147}
71 148
72 /* See if the full key description matches as is */ 149/*
73 if (key->description && strcmp(key->description, description) == 0) 150 * Match asymmetric keys by a partial match on an IDs.
74 return 1; 151 */
152static bool asymmetric_key_cmp_partial(const struct key *key,
153 const struct key_match_data *match_data)
154{
155 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
156 const struct asymmetric_key_id *match_id = match_data->preparsed;
75 157
76 /* All tests from here on break the criterion description into a 158 return asymmetric_match_key_ids(kids, match_id,
77 * specifier, a colon and then an identifier. 159 asymmetric_key_id_partial);
78 */ 160}
79 id = strchr(spec, ':'); 161
80 if (!id) 162/*
81 return 0; 163 * Preparse the match criterion. If we don't set lookup_type and cmp,
164 * the default will be an exact match on the key description.
165 *
166 * There are some specifiers for matching key IDs rather than by the key
167 * description:
168 *
169 * "id:<id>" - find a key by partial match on any available ID
170 * "ex:<id>" - find a key by exact match on any available ID
171 *
172 * These have to be searched by iteration rather than by direct lookup because
173 * the key is hashed according to its description.
174 */
175static int asymmetric_key_match_preparse(struct key_match_data *match_data)
176{
177 struct asymmetric_key_id *match_id;
178 const char *spec = match_data->raw_data;
179 const char *id;
180 bool (*cmp)(const struct key *, const struct key_match_data *) =
181 asymmetric_key_cmp;
82 182
83 speclen = id - spec; 183 if (!spec || !*spec)
84 id++; 184 return -EINVAL;
185 if (spec[0] == 'i' &&
186 spec[1] == 'd' &&
187 spec[2] == ':') {
188 id = spec + 3;
189 cmp = asymmetric_key_cmp_partial;
190 } else if (spec[0] == 'e' &&
191 spec[1] == 'x' &&
192 spec[2] == ':') {
193 id = spec + 3;
194 } else {
195 goto default_match;
196 }
85 197
86 if (speclen == 2 && memcmp(spec, "id", 2) == 0) 198 match_id = asymmetric_key_hex_to_key_id(id);
87 return asymmetric_keyid_match(asymmetric_key_id(key), id); 199 if (IS_ERR(match_id))
200 return PTR_ERR(match_id);
88 201
89 if (speclen == subtype->name_len && 202 match_data->preparsed = match_id;
90 memcmp(spec, subtype->name, speclen) == 0) 203 match_data->cmp = cmp;
91 return 1; 204 match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
205 return 0;
92 206
207default_match:
93 return 0; 208 return 0;
94} 209}
95 210
96/* 211/*
212 * Free the preparsed the match criterion.
213 */
214static void asymmetric_key_match_free(struct key_match_data *match_data)
215{
216 kfree(match_data->preparsed);
217}
218
219/*
97 * Describe the asymmetric key 220 * Describe the asymmetric key
98 */ 221 */
99static void asymmetric_key_describe(const struct key *key, struct seq_file *m) 222static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
100{ 223{
101 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 224 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
102 const char *kid = asymmetric_key_id(key); 225 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
103 size_t n; 226 const struct asymmetric_key_id *kid;
227 const unsigned char *p;
228 int n;
104 229
105 seq_puts(m, key->description); 230 seq_puts(m, key->description);
106 231
@@ -108,13 +233,16 @@ static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
108 seq_puts(m, ": "); 233 seq_puts(m, ": ");
109 subtype->describe(key, m); 234 subtype->describe(key, m);
110 235
111 if (kid) { 236 if (kids && kids->id[1]) {
237 kid = kids->id[1];
112 seq_putc(m, ' '); 238 seq_putc(m, ' ');
113 n = strlen(kid); 239 n = kid->len;
114 if (n <= 8) 240 p = kid->data;
115 seq_puts(m, kid); 241 if (n > 4) {
116 else 242 p += n - 4;
117 seq_puts(m, kid + n - 8); 243 n = 4;
244 }
245 seq_printf(m, "%*phN", n, p);
118 } 246 }
119 247
120 seq_puts(m, " ["); 248 seq_puts(m, " [");
@@ -165,6 +293,8 @@ static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
165static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) 293static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
166{ 294{
167 struct asymmetric_key_subtype *subtype = prep->type_data[0]; 295 struct asymmetric_key_subtype *subtype = prep->type_data[0];
296 struct asymmetric_key_ids *kids = prep->type_data[1];
297 int i;
168 298
169 pr_devel("==>%s()\n", __func__); 299 pr_devel("==>%s()\n", __func__);
170 300
@@ -172,7 +302,11 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
172 subtype->destroy(prep->payload[0]); 302 subtype->destroy(prep->payload[0]);
173 module_put(subtype->owner); 303 module_put(subtype->owner);
174 } 304 }
175 kfree(prep->type_data[1]); 305 if (kids) {
306 for (i = 0; i < ARRAY_SIZE(kids->id); i++)
307 kfree(kids->id[i]);
308 kfree(kids);
309 }
176 kfree(prep->description); 310 kfree(prep->description);
177} 311}
178 312
@@ -182,13 +316,20 @@ static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
182static void asymmetric_key_destroy(struct key *key) 316static void asymmetric_key_destroy(struct key *key)
183{ 317{
184 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 318 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
319 struct asymmetric_key_ids *kids = key->type_data.p[1];
320
185 if (subtype) { 321 if (subtype) {
186 subtype->destroy(key->payload.data); 322 subtype->destroy(key->payload.data);
187 module_put(subtype->owner); 323 module_put(subtype->owner);
188 key->type_data.p[0] = NULL; 324 key->type_data.p[0] = NULL;
189 } 325 }
190 kfree(key->type_data.p[1]); 326
191 key->type_data.p[1] = NULL; 327 if (kids) {
328 kfree(kids->id[0]);
329 kfree(kids->id[1]);
330 kfree(kids);
331 key->type_data.p[1] = NULL;
332 }
192} 333}
193 334
194struct key_type key_type_asymmetric = { 335struct key_type key_type_asymmetric = {
@@ -196,10 +337,10 @@ struct key_type key_type_asymmetric = {
196 .preparse = asymmetric_key_preparse, 337 .preparse = asymmetric_key_preparse,
197 .free_preparse = asymmetric_key_free_preparse, 338 .free_preparse = asymmetric_key_free_preparse,
198 .instantiate = generic_key_instantiate, 339 .instantiate = generic_key_instantiate,
199 .match = asymmetric_key_match, 340 .match_preparse = asymmetric_key_match_preparse,
341 .match_free = asymmetric_key_match_free,
200 .destroy = asymmetric_key_destroy, 342 .destroy = asymmetric_key_destroy,
201 .describe = asymmetric_key_describe, 343 .describe = asymmetric_key_describe,
202 .def_lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE,
203}; 344};
204EXPORT_SYMBOL_GPL(key_type_asymmetric); 345EXPORT_SYMBOL_GPL(key_type_asymmetric);
205 346
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..1d29376072da 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,18 @@ 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 false);
54 if (!IS_ERR(key)) 59 if (!IS_ERR(key)) {
55 /* One of the X.509 certificates in the PKCS#7 message 60 /* One of the X.509 certificates in the PKCS#7 message
56 * is apparently the same as one we already trust. 61 * is apparently the same as one we already trust.
57 * Verify that the trusted variant can also validate 62 * Verify that the trusted variant can also validate
58 * the signature on the descendant. 63 * the signature on the descendant.
59 */ 64 */
65 pr_devel("sinfo %u: Cert %u as key %x\n",
66 sinfo->index, x509->index, key_serial(key));
60 goto matched; 67 goto matched;
68 }
61 if (key == ERR_PTR(-ENOMEM)) 69 if (key == ERR_PTR(-ENOMEM))
62 return -ENOMEM; 70 return -ENOMEM;
63 71
@@ -77,16 +85,36 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
77 /* No match - see if the root certificate has a signer amongst the 85 /* No match - see if the root certificate has a signer amongst the
78 * trusted keys. 86 * trusted keys.
79 */ 87 */
80 if (!last || !last->issuer || !last->authority) { 88 if (last && last->authority) {
81 kleave(" = -ENOKEY [no backref]"); 89 key = x509_request_asymmetric_key(trust_keyring, last->authority,
82 return -ENOKEY; 90 false);
91 if (!IS_ERR(key)) {
92 x509 = last;
93 pr_devel("sinfo %u: Root cert %u signer is key %x\n",
94 sinfo->index, x509->index, key_serial(key));
95 goto matched;
96 }
97 if (PTR_ERR(key) != -ENOKEY)
98 return PTR_ERR(key);
99 }
100
101 /* As a last resort, see if we have a trusted public key that matches
102 * the signed info directly.
103 */
104 key = x509_request_asymmetric_key(trust_keyring,
105 sinfo->signing_cert_id,
106 false);
107 if (!IS_ERR(key)) {
108 pr_devel("sinfo %u: Direct signer is key %x\n",
109 sinfo->index, key_serial(key));
110 x509 = NULL;
111 goto matched;
83 } 112 }
113 if (PTR_ERR(key) != -ENOKEY)
114 return PTR_ERR(key);
84 115
85 key = x509_request_asymmetric_key(trust_keyring, last->issuer, 116 kleave(" = -ENOKEY [no backref]");
86 last->authority); 117 return -ENOKEY;
87 if (IS_ERR(key))
88 return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY;
89 x509 = last;
90 118
91matched: 119matched:
92 ret = verify_signature(key, sig); 120 ret = verify_signature(key, sig);
@@ -100,10 +128,12 @@ matched:
100 } 128 }
101 129
102verified: 130verified:
103 x509->verified = true; 131 if (x509) {
104 for (p = sinfo->signer; p != x509; p = p->signer) { 132 x509->verified = true;
105 p->verified = true; 133 for (p = sinfo->signer; p != x509; p = p->signer) {
106 p->trusted = trusted; 134 p->verified = true;
135 p->trusted = trusted;
136 }
107 } 137 }
108 sinfo->trusted = trusted; 138 sinfo->trusted = trusted;
109 kleave(" = 0"); 139 kleave(" = 0");
@@ -141,24 +171,28 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
141{ 171{
142 struct pkcs7_signed_info *sinfo; 172 struct pkcs7_signed_info *sinfo;
143 struct x509_certificate *p; 173 struct x509_certificate *p;
144 int cached_ret = 0, ret; 174 int cached_ret = -ENOKEY;
175 int ret;
145 176
146 for (p = pkcs7->certs; p; p = p->next) 177 for (p = pkcs7->certs; p; p = p->next)
147 p->seen = false; 178 p->seen = false;
148 179
149 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 180 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
150 ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring); 181 ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring);
151 if (ret < 0) { 182 switch (ret) {
152 if (ret == -ENOPKG) { 183 case -ENOKEY:
184 continue;
185 case -ENOPKG:
186 if (cached_ret == -ENOKEY)
153 cached_ret = -ENOPKG; 187 cached_ret = -ENOPKG;
154 } else if (ret == -ENOKEY) { 188 continue;
155 if (cached_ret == 0) 189 case 0:
156 cached_ret = -ENOKEY; 190 *_trusted |= sinfo->trusted;
157 } else { 191 cached_ret = 0;
158 return ret; 192 continue;
159 } 193 default:
194 return ret;
160 } 195 }
161 *_trusted |= sinfo->trusted;
162 } 196 }
163 197
164 return cached_ret; 198 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/signature.c b/crypto/asymmetric_keys/signature.c
index 50b3f880b4ff..7525fd183574 100644
--- a/crypto/asymmetric_keys/signature.c
+++ b/crypto/asymmetric_keys/signature.c
@@ -11,6 +11,7 @@
11 * 2 of the Licence, or (at your option) any later version. 11 * 2 of the Licence, or (at your option) any later version.
12 */ 12 */
13 13
14#define pr_fmt(fmt) "SIG: "fmt
14#include <keys/asymmetric-subtype.h> 15#include <keys/asymmetric-subtype.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/err.h> 17#include <linux/err.h>
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index ac72348c186a..a668d90302d3 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,36 @@ 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 ctx->cert->raw_skid_size = vlen;
426 if (!f) 439 ctx->cert->raw_skid = v;
427 return -ENOMEM; 440 kid = asymmetric_key_generate_id(ctx->cert->raw_subject,
428 for (i = 0; i < vlen; i++) 441 ctx->cert->raw_subject_size,
429 sprintf(f + i * 2, "%02x", v[i]); 442 v, vlen);
430 pr_debug("fingerprint %s\n", f); 443 if (IS_ERR(kid))
431 ctx->cert->fingerprint = f; 444 return PTR_ERR(kid);
445 ctx->cert->skid = kid;
446 pr_debug("subjkeyid %*phN\n", kid->len, kid->data);
432 return 0; 447 return 0;
433 } 448 }
434 449
435 if (ctx->last_oid == OID_authorityKeyIdentifier) { 450 if (ctx->last_oid == OID_authorityKeyIdentifier) {
436 size_t key_len;
437
438 /* Get hold of the CA key fingerprint */ 451 /* Get hold of the CA key fingerprint */
439 if (vlen < 5) 452 if (ctx->cert->authority || vlen < 5)
440 return -EBADMSG; 453 return -EBADMSG;
441 454
442 /* Authority Key Identifier must be a Constructed SEQUENCE */ 455 /* Authority Key Identifier must be a Constructed SEQUENCE */
@@ -454,7 +467,7 @@ int x509_process_extension(void *context, size_t hdrlen,
454 v[3] > vlen - 4) 467 v[3] > vlen - 4)
455 return -EBADMSG; 468 return -EBADMSG;
456 469
457 key_len = v[3]; 470 vlen = v[3];
458 v += 4; 471 v += 4;
459 } else { 472 } else {
460 /* Long Form length */ 473 /* Long Form length */
@@ -476,17 +489,17 @@ int x509_process_extension(void *context, size_t hdrlen,
476 v[sub + 1] > vlen - 4 - sub) 489 v[sub + 1] > vlen - 4 - sub)
477 return -EBADMSG; 490 return -EBADMSG;
478 491
479 key_len = v[sub + 1]; 492 vlen = v[sub + 1];
480 v += (sub + 2); 493 v += (sub + 2);
481 } 494 }
482 495
483 f = kmalloc(key_len * 2 + 1, GFP_KERNEL); 496 kid = asymmetric_key_generate_id(ctx->cert->raw_issuer,
484 if (!f) 497 ctx->cert->raw_issuer_size,
485 return -ENOMEM; 498 v, vlen);
486 for (i = 0; i < key_len; i++) 499 if (IS_ERR(kid))
487 sprintf(f + i * 2, "%02x", v[i]); 500 return PTR_ERR(kid);
488 pr_debug("authority %s\n", f); 501 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
489 ctx->cert->authority = f; 502 ctx->cert->authority = kid;
490 return 0; 503 return 0;
491 } 504 }
492 505
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 1b76f207c1f3..3dfe6b5d6f0b 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; /* Serial number + issuer */
23 char *authority; /* Authority key fingerprint as hex */ 23 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */
24 struct asymmetric_key_id *authority; /* Authority key identifier (optional) */
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 */
@@ -33,10 +34,13 @@ struct x509_certificate {
33 const void *raw_issuer; /* Raw issuer name in ASN.1 */ 34 const void *raw_issuer; /* Raw issuer name in ASN.1 */
34 const void *raw_subject; /* Raw subject name in ASN.1 */ 35 const void *raw_subject; /* Raw subject name in ASN.1 */
35 unsigned raw_subject_size; 36 unsigned raw_subject_size;
37 unsigned raw_skid_size;
38 const void *raw_skid; /* Raw subjectKeyId in ASN.1 */
36 unsigned index; 39 unsigned index;
37 bool seen; /* Infinite recursion prevention */ 40 bool seen; /* Infinite recursion prevention */
38 bool verified; 41 bool verified;
39 bool trusted; 42 bool trusted;
43 bool unsupported_crypto; /* T if can't be verified due to missing crypto */
40}; 44};
41 45
42/* 46/*
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index f3d62307e6ee..a6c42031628e 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 + 3);
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,35 @@ __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. 56 * @partial: Use partial match if true, exact if false.
51 * 57 *
52 * Find a key in the given keyring by subject name and key ID. These might, 58 * 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 59 * for instance, be the issuer name and the authority key ID of an X.509
54 * certificate that needs to be verified. 60 * certificate that needs to be verified.
55 */ 61 */
56struct key *x509_request_asymmetric_key(struct key *keyring, 62struct key *x509_request_asymmetric_key(struct key *keyring,
57 const char *subject, 63 const struct asymmetric_key_id *kid,
58 const char *key_id) 64 bool partial)
59{ 65{
60 key_ref_t key; 66 key_ref_t key;
61 size_t subject_len = strlen(subject), key_id_len = strlen(key_id); 67 char *id, *p;
62 char *id;
63 68
64 /* Construct an identifier "<subjname>:<keyid>". */ 69 /* Construct an identifier "id:<keyid>". */
65 id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL); 70 p = id = kmalloc(2 + 1 + kid->len * 2 + 1, GFP_KERNEL);
66 if (!id) 71 if (!id)
67 return ERR_PTR(-ENOMEM); 72 return ERR_PTR(-ENOMEM);
68 73
69 memcpy(id, subject, subject_len); 74 if (partial) {
70 id[subject_len + 0] = ':'; 75 *p++ = 'i';
71 id[subject_len + 1] = ' '; 76 *p++ = 'd';
72 memcpy(id + subject_len + 2, key_id, key_id_len); 77 } else {
73 id[subject_len + 2 + key_id_len] = 0; 78 *p++ = 'e';
79 *p++ = 'x';
80 }
81 *p++ = ':';
82 p = bin2hex(p, kid->data, kid->len);
83 *p = 0;
74 84
75 pr_debug("Look up: \"%s\"\n", id); 85 pr_debug("Look up: \"%s\"\n", id);
76 86
@@ -112,6 +122,8 @@ int x509_get_sig_params(struct x509_certificate *cert)
112 122
113 pr_devel("==>%s()\n", __func__); 123 pr_devel("==>%s()\n", __func__);
114 124
125 if (cert->unsupported_crypto)
126 return -ENOPKG;
115 if (cert->sig.rsa.s) 127 if (cert->sig.rsa.s)
116 return 0; 128 return 0;
117 129
@@ -124,8 +136,13 @@ int x509_get_sig_params(struct x509_certificate *cert)
124 * big the hash operational data will be. 136 * big the hash operational data will be.
125 */ 137 */
126 tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0); 138 tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0);
127 if (IS_ERR(tfm)) 139 if (IS_ERR(tfm)) {
128 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 140 if (PTR_ERR(tfm) == -ENOENT) {
141 cert->unsupported_crypto = true;
142 return -ENOPKG;
143 }
144 return PTR_ERR(tfm);
145 }
129 146
130 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 147 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
131 digest_size = crypto_shash_digestsize(tfm); 148 digest_size = crypto_shash_digestsize(tfm);
@@ -172,6 +189,8 @@ int x509_check_signature(const struct public_key *pub,
172 return ret; 189 return ret;
173 190
174 ret = public_key_verify_signature(pub, &cert->sig); 191 ret = public_key_verify_signature(pub, &cert->sig);
192 if (ret == -ENOPKG)
193 cert->unsupported_crypto = true;
175 pr_debug("Cert Verification: %d\n", ret); 194 pr_debug("Cert Verification: %d\n", ret);
176 return ret; 195 return ret;
177} 196}
@@ -195,11 +214,11 @@ static int x509_validate_trust(struct x509_certificate *cert,
195 if (!trust_keyring) 214 if (!trust_keyring)
196 return -EOPNOTSUPP; 215 return -EOPNOTSUPP;
197 216
198 if (ca_keyid && !asymmetric_keyid_match(cert->authority, ca_keyid)) 217 if (ca_keyid && !asymmetric_key_id_partial(cert->authority, ca_keyid))
199 return -EPERM; 218 return -EPERM;
200 219
201 key = x509_request_asymmetric_key(trust_keyring, 220 key = x509_request_asymmetric_key(trust_keyring, cert->authority,
202 cert->issuer, cert->authority); 221 false);
203 if (!IS_ERR(key)) { 222 if (!IS_ERR(key)) {
204 if (!use_builtin_keys 223 if (!use_builtin_keys
205 || test_bit(KEY_FLAG_BUILTIN, &key->flags)) 224 || test_bit(KEY_FLAG_BUILTIN, &key->flags))
@@ -214,9 +233,11 @@ static int x509_validate_trust(struct x509_certificate *cert,
214 */ 233 */
215static int x509_key_preparse(struct key_preparsed_payload *prep) 234static int x509_key_preparse(struct key_preparsed_payload *prep)
216{ 235{
236 struct asymmetric_key_ids *kids;
217 struct x509_certificate *cert; 237 struct x509_certificate *cert;
238 const char *q;
218 size_t srlen, sulen; 239 size_t srlen, sulen;
219 char *desc = NULL; 240 char *desc = NULL, *p;
220 int ret; 241 int ret;
221 242
222 cert = x509_cert_parse(prep->data, prep->datalen); 243 cert = x509_cert_parse(prep->data, prep->datalen);
@@ -249,19 +270,12 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
249 pkey_algo_name[cert->sig.pkey_algo], 270 pkey_algo_name[cert->sig.pkey_algo],
250 hash_algo_name[cert->sig.pkey_hash_algo]); 271 hash_algo_name[cert->sig.pkey_hash_algo]);
251 272
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]; 273 cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
260 cert->pub->id_type = PKEY_ID_X509; 274 cert->pub->id_type = PKEY_ID_X509;
261 275
262 /* Check the signature on the key if it appears to be self-signed */ 276 /* Check the signature on the key if it appears to be self-signed */
263 if (!cert->authority || 277 if (!cert->authority ||
264 strcmp(cert->fingerprint, cert->authority) == 0) { 278 asymmetric_key_id_same(cert->skid, cert->authority)) {
265 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 279 ret = x509_check_signature(cert->pub, cert); /* self-signed */
266 if (ret < 0) 280 if (ret < 0)
267 goto error_free_cert; 281 goto error_free_cert;
@@ -273,31 +287,52 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
273 287
274 /* Propose a description */ 288 /* Propose a description */
275 sulen = strlen(cert->subject); 289 sulen = strlen(cert->subject);
276 srlen = strlen(cert->fingerprint); 290 if (cert->raw_skid) {
291 srlen = cert->raw_skid_size;
292 q = cert->raw_skid;
293 } else {
294 srlen = cert->raw_serial_size;
295 q = cert->raw_serial;
296 }
297 if (srlen > 1 && *q == 0) {
298 srlen--;
299 q++;
300 }
301
277 ret = -ENOMEM; 302 ret = -ENOMEM;
278 desc = kmalloc(sulen + 2 + srlen + 1, GFP_KERNEL); 303 desc = kmalloc(sulen + 2 + srlen * 2 + 1, GFP_KERNEL);
279 if (!desc) 304 if (!desc)
280 goto error_free_cert; 305 goto error_free_cert;
281 memcpy(desc, cert->subject, sulen); 306 p = memcpy(desc, cert->subject, sulen);
282 desc[sulen] = ':'; 307 p += sulen;
283 desc[sulen + 1] = ' '; 308 *p++ = ':';
284 memcpy(desc + sulen + 2, cert->fingerprint, srlen); 309 *p++ = ' ';
285 desc[sulen + 2 + srlen] = 0; 310 p = bin2hex(p, q, srlen);
311 *p = 0;
312
313 kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL);
314 if (!kids)
315 goto error_free_desc;
316 kids->id[0] = cert->id;
317 kids->id[1] = cert->skid;
286 318
287 /* We're pinning the module by being linked against it */ 319 /* We're pinning the module by being linked against it */
288 __module_get(public_key_subtype.owner); 320 __module_get(public_key_subtype.owner);
289 prep->type_data[0] = &public_key_subtype; 321 prep->type_data[0] = &public_key_subtype;
290 prep->type_data[1] = cert->fingerprint; 322 prep->type_data[1] = kids;
291 prep->payload[0] = cert->pub; 323 prep->payload[0] = cert->pub;
292 prep->description = desc; 324 prep->description = desc;
293 prep->quotalen = 100; 325 prep->quotalen = 100;
294 326
295 /* We've finished with the certificate */ 327 /* We've finished with the certificate */
296 cert->pub = NULL; 328 cert->pub = NULL;
297 cert->fingerprint = NULL; 329 cert->id = NULL;
330 cert->skid = NULL;
298 desc = NULL; 331 desc = NULL;
299 ret = 0; 332 ret = 0;
300 333
334error_free_desc:
335 kfree(desc);
301error_free_cert: 336error_free_cert:
302 x509_free_certificate(cert); 337 x509_free_certificate(cert);
303 return ret; 338 return ret;