1
2
3
4
5
6
7
8
9
10
11
12#define pr_fmt(fmt) "ASYM: "fmt
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <crypto/public_key.h>
17#include "asymmetric_keys.h"
18
19static bool use_builtin_keys;
20static struct asymmetric_key_id *ca_keyid;
21
22#ifndef MODULE
23static struct {
24 struct asymmetric_key_id id;
25 unsigned char data[10];
26} cakey;
27
28static int __init ca_keys_setup(char *str)
29{
30 if (!str)
31 return 1;
32
33 if (strncmp(str, "id:", 3) == 0) {
34 struct asymmetric_key_id *p = &cakey.id;
35 size_t hexlen = (strlen(str) - 3) / 2;
36 int ret;
37
38 if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
39 pr_err("Missing or invalid ca_keys id\n");
40 return 1;
41 }
42
43 ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
44 if (ret < 0)
45 pr_err("Unparsable ca_keys id hex string\n");
46 else
47 ca_keyid = p;
48 } else if (strcmp(str, "builtin") == 0) {
49 use_builtin_keys = true;
50 }
51
52 return 1;
53}
54__setup("ca_keys=", ca_keys_setup);
55#endif
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74int restrict_link_by_signature(struct key *dest_keyring,
75 const struct key_type *type,
76 const union key_payload *payload,
77 struct key *trust_keyring)
78{
79 const struct public_key_signature *sig;
80 struct key *key;
81 int ret;
82
83 pr_devel("==>%s()\n", __func__);
84
85 if (!trust_keyring)
86 return -ENOKEY;
87
88 if (type != &key_type_asymmetric)
89 return -EOPNOTSUPP;
90
91 sig = payload->data[asym_auth];
92 if (!sig)
93 return -ENOPKG;
94 if (!sig->auth_ids[0] && !sig->auth_ids[1])
95 return -ENOKEY;
96
97 if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
98 return -EPERM;
99
100
101 key = find_asymmetric_key(trust_keyring,
102 sig->auth_ids[0], sig->auth_ids[1],
103 false);
104 if (IS_ERR(key))
105 return -ENOKEY;
106
107 if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
108 ret = -ENOKEY;
109 else
110 ret = verify_signature(key, sig);
111 key_put(key);
112 return ret;
113}
114
115static bool match_either_id(const struct asymmetric_key_ids *pair,
116 const struct asymmetric_key_id *single)
117{
118 return (asymmetric_key_id_same(pair->id[0], single) ||
119 asymmetric_key_id_same(pair->id[1], single));
120}
121
122static int key_or_keyring_common(struct key *dest_keyring,
123 const struct key_type *type,
124 const union key_payload *payload,
125 struct key *trusted, bool check_dest)
126{
127 const struct public_key_signature *sig;
128 struct key *key = NULL;
129 int ret;
130
131 pr_devel("==>%s()\n", __func__);
132
133 if (!dest_keyring)
134 return -ENOKEY;
135 else if (dest_keyring->type != &key_type_keyring)
136 return -EOPNOTSUPP;
137
138 if (!trusted && !check_dest)
139 return -ENOKEY;
140
141 if (type != &key_type_asymmetric)
142 return -EOPNOTSUPP;
143
144 sig = payload->data[asym_auth];
145 if (!sig)
146 return -ENOPKG;
147 if (!sig->auth_ids[0] && !sig->auth_ids[1])
148 return -ENOKEY;
149
150 if (trusted) {
151 if (trusted->type == &key_type_keyring) {
152
153 key = find_asymmetric_key(trusted, sig->auth_ids[0],
154 sig->auth_ids[1], false);
155 if (IS_ERR(key))
156 key = NULL;
157 } else if (trusted->type == &key_type_asymmetric) {
158 const struct asymmetric_key_ids *signer_ids;
159
160 signer_ids = asymmetric_key_ids(trusted);
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179 if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
180 const struct asymmetric_key_id *auth_id;
181
182 auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
183 if (match_either_id(signer_ids, auth_id))
184 key = __key_get(trusted);
185
186 } else if (asymmetric_key_id_same(signer_ids->id[1],
187 sig->auth_ids[1]) &&
188 match_either_id(signer_ids,
189 sig->auth_ids[0])) {
190 key = __key_get(trusted);
191 }
192 } else {
193 return -EOPNOTSUPP;
194 }
195 }
196
197 if (check_dest && !key) {
198
199 key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
200 sig->auth_ids[1], false);
201 if (IS_ERR(key))
202 key = NULL;
203 }
204
205 if (!key)
206 return -ENOKEY;
207
208 ret = key_validate(key);
209 if (ret == 0)
210 ret = verify_signature(key, sig);
211
212 key_put(key);
213 return ret;
214}
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234int restrict_link_by_key_or_keyring(struct key *dest_keyring,
235 const struct key_type *type,
236 const union key_payload *payload,
237 struct key *trusted)
238{
239 return key_or_keyring_common(dest_keyring, type, payload, trusted,
240 false);
241}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
262 const struct key_type *type,
263 const union key_payload *payload,
264 struct key *trusted)
265{
266 return key_or_keyring_common(dest_keyring, type, payload, trusted,
267 true);
268}
269