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
73int restrict_link_by_signature(struct key *dest_keyring,
74 const struct key_type *type,
75 const union key_payload *payload,
76 struct key *trust_keyring)
77{
78 const struct public_key_signature *sig;
79 struct key *key;
80 int ret;
81
82 pr_devel("==>%s()\n", __func__);
83
84 if (!trust_keyring)
85 return -ENOKEY;
86
87 if (type != &key_type_asymmetric)
88 return -EOPNOTSUPP;
89
90 sig = payload->data[asym_auth];
91 if (!sig->auth_ids[0] && !sig->auth_ids[1])
92 return -ENOKEY;
93
94 if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
95 return -EPERM;
96
97
98 key = find_asymmetric_key(trust_keyring,
99 sig->auth_ids[0], sig->auth_ids[1],
100 false);
101 if (IS_ERR(key))
102 return -ENOKEY;
103
104 if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
105 ret = -ENOKEY;
106 else
107 ret = verify_signature(key, sig);
108 key_put(key);
109 return ret;
110}
111
112static bool match_either_id(const struct asymmetric_key_ids *pair,
113 const struct asymmetric_key_id *single)
114{
115 return (asymmetric_key_id_same(pair->id[0], single) ||
116 asymmetric_key_id_same(pair->id[1], single));
117}
118
119static int key_or_keyring_common(struct key *dest_keyring,
120 const struct key_type *type,
121 const union key_payload *payload,
122 struct key *trusted, bool check_dest)
123{
124 const struct public_key_signature *sig;
125 struct key *key = NULL;
126 int ret;
127
128 pr_devel("==>%s()\n", __func__);
129
130 if (!dest_keyring)
131 return -ENOKEY;
132 else if (dest_keyring->type != &key_type_keyring)
133 return -EOPNOTSUPP;
134
135 if (!trusted && !check_dest)
136 return -ENOKEY;
137
138 if (type != &key_type_asymmetric)
139 return -EOPNOTSUPP;
140
141 sig = payload->data[asym_auth];
142 if (!sig->auth_ids[0] && !sig->auth_ids[1])
143 return -ENOKEY;
144
145 if (trusted) {
146 if (trusted->type == &key_type_keyring) {
147
148 key = find_asymmetric_key(trusted, sig->auth_ids[0],
149 sig->auth_ids[1], false);
150 if (IS_ERR(key))
151 key = NULL;
152 } else if (trusted->type == &key_type_asymmetric) {
153 const struct asymmetric_key_ids *signer_ids;
154
155 signer_ids = asymmetric_key_ids(trusted);
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
175 const struct asymmetric_key_id *auth_id;
176
177 auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
178 if (match_either_id(signer_ids, auth_id))
179 key = __key_get(trusted);
180
181 } else if (asymmetric_key_id_same(signer_ids->id[1],
182 sig->auth_ids[1]) &&
183 match_either_id(signer_ids,
184 sig->auth_ids[0])) {
185 key = __key_get(trusted);
186 }
187 } else {
188 return -EOPNOTSUPP;
189 }
190 }
191
192 if (check_dest && !key) {
193
194 key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
195 sig->auth_ids[1], false);
196 if (IS_ERR(key))
197 key = NULL;
198 }
199
200 if (!key)
201 return -ENOKEY;
202
203 ret = key_validate(key);
204 if (ret == 0)
205 ret = verify_signature(key, sig);
206
207 key_put(key);
208 return ret;
209}
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229int restrict_link_by_key_or_keyring(struct key *dest_keyring,
230 const struct key_type *type,
231 const union key_payload *payload,
232 struct key *trusted)
233{
234 return key_or_keyring_common(dest_keyring, type, payload, trusted,
235 false);
236}
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
257 const struct key_type *type,
258 const union key_payload *payload,
259 struct key *trusted)
260{
261 return key_or_keyring_common(dest_keyring, type, payload, trusted,
262 true);
263}
264