xref: /linux/crypto/asymmetric_keys/x509_public_key.c (revision 110e6f26af80dfd90b6e5c645b1aed7228aa580d)
1 /* Instantiate a public key crypto key from an X.509 Certificate
2  *
3  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11 
12 #define pr_fmt(fmt) "X.509: "fmt
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <keys/asymmetric-subtype.h>
17 #include <keys/asymmetric-parser.h>
18 #include <keys/system_keyring.h>
19 #include <crypto/hash.h>
20 #include "asymmetric_keys.h"
21 #include "x509_parser.h"
22 
23 static bool use_builtin_keys;
24 static struct asymmetric_key_id *ca_keyid;
25 
26 #ifndef MODULE
27 static struct {
28 	struct asymmetric_key_id id;
29 	unsigned char data[10];
30 } cakey;
31 
32 static int __init ca_keys_setup(char *str)
33 {
34 	if (!str)		/* default system keyring */
35 		return 1;
36 
37 	if (strncmp(str, "id:", 3) == 0) {
38 		struct asymmetric_key_id *p = &cakey.id;
39 		size_t hexlen = (strlen(str) - 3) / 2;
40 		int ret;
41 
42 		if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
43 			pr_err("Missing or invalid ca_keys id\n");
44 			return 1;
45 		}
46 
47 		ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
48 		if (ret < 0)
49 			pr_err("Unparsable ca_keys id hex string\n");
50 		else
51 			ca_keyid = p;	/* owner key 'id:xxxxxx' */
52 	} else if (strcmp(str, "builtin") == 0) {
53 		use_builtin_keys = true;
54 	}
55 
56 	return 1;
57 }
58 __setup("ca_keys=", ca_keys_setup);
59 #endif
60 
61 /**
62  * x509_request_asymmetric_key - Request a key by X.509 certificate params.
63  * @keyring: The keys to search.
64  * @id: The issuer & serialNumber to look for or NULL.
65  * @skid: The subjectKeyIdentifier to look for or NULL.
66  * @partial: Use partial match if true, exact if false.
67  *
68  * Find a key in the given keyring by identifier.  The preferred identifier is
69  * the issuer + serialNumber and the fallback identifier is the
70  * subjectKeyIdentifier.  If both are given, the lookup is by the former, but
71  * the latter must also match.
72  */
73 struct key *x509_request_asymmetric_key(struct key *keyring,
74 					const struct asymmetric_key_id *id,
75 					const struct asymmetric_key_id *skid,
76 					bool partial)
77 {
78 	struct key *key;
79 	key_ref_t ref;
80 	const char *lookup;
81 	char *req, *p;
82 	int len;
83 
84 	if (id) {
85 		lookup = id->data;
86 		len = id->len;
87 	} else {
88 		lookup = skid->data;
89 		len = skid->len;
90 	}
91 
92 	/* Construct an identifier "id:<keyid>". */
93 	p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
94 	if (!req)
95 		return ERR_PTR(-ENOMEM);
96 
97 	if (partial) {
98 		*p++ = 'i';
99 		*p++ = 'd';
100 	} else {
101 		*p++ = 'e';
102 		*p++ = 'x';
103 	}
104 	*p++ = ':';
105 	p = bin2hex(p, lookup, len);
106 	*p = 0;
107 
108 	pr_debug("Look up: \"%s\"\n", req);
109 
110 	ref = keyring_search(make_key_ref(keyring, 1),
111 			     &key_type_asymmetric, req);
112 	if (IS_ERR(ref))
113 		pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
114 	kfree(req);
115 
116 	if (IS_ERR(ref)) {
117 		switch (PTR_ERR(ref)) {
118 			/* Hide some search errors */
119 		case -EACCES:
120 		case -ENOTDIR:
121 		case -EAGAIN:
122 			return ERR_PTR(-ENOKEY);
123 		default:
124 			return ERR_CAST(ref);
125 		}
126 	}
127 
128 	key = key_ref_to_ptr(ref);
129 	if (id && skid) {
130 		const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
131 		if (!kids->id[1]) {
132 			pr_debug("issuer+serial match, but expected SKID missing\n");
133 			goto reject;
134 		}
135 		if (!asymmetric_key_id_same(skid, kids->id[1])) {
136 			pr_debug("issuer+serial match, but SKID does not\n");
137 			goto reject;
138 		}
139 	}
140 
141 	pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
142 	return key;
143 
144 reject:
145 	key_put(key);
146 	return ERR_PTR(-EKEYREJECTED);
147 }
148 EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
149 
150 /*
151  * Set up the signature parameters in an X.509 certificate.  This involves
152  * digesting the signed data and extracting the signature.
153  */
154 int x509_get_sig_params(struct x509_certificate *cert)
155 {
156 	struct crypto_shash *tfm;
157 	struct shash_desc *desc;
158 	size_t digest_size, desc_size;
159 	void *digest;
160 	int ret;
161 
162 	pr_devel("==>%s()\n", __func__);
163 
164 	if (cert->unsupported_crypto)
165 		return -ENOPKG;
166 	if (cert->sig.s)
167 		return 0;
168 
169 	cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size,
170 			      GFP_KERNEL);
171 	if (!cert->sig.s)
172 		return -ENOMEM;
173 
174 	cert->sig.s_size = cert->raw_sig_size;
175 
176 	/* Allocate the hashing algorithm we're going to need and find out how
177 	 * big the hash operational data will be.
178 	 */
179 	tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0);
180 	if (IS_ERR(tfm)) {
181 		if (PTR_ERR(tfm) == -ENOENT) {
182 			cert->unsupported_crypto = true;
183 			return -ENOPKG;
184 		}
185 		return PTR_ERR(tfm);
186 	}
187 
188 	desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
189 	digest_size = crypto_shash_digestsize(tfm);
190 
191 	/* We allocate the hash operational data storage on the end of the
192 	 * digest storage space.
193 	 */
194 	ret = -ENOMEM;
195 	digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,
196 			 GFP_KERNEL);
197 	if (!digest)
198 		goto error;
199 
200 	cert->sig.digest = digest;
201 	cert->sig.digest_size = digest_size;
202 
203 	desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
204 	desc->tfm = tfm;
205 	desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
206 
207 	ret = crypto_shash_init(desc);
208 	if (ret < 0)
209 		goto error;
210 	might_sleep();
211 	ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest);
212 error:
213 	crypto_free_shash(tfm);
214 	pr_devel("<==%s() = %d\n", __func__, ret);
215 	return ret;
216 }
217 EXPORT_SYMBOL_GPL(x509_get_sig_params);
218 
219 /*
220  * Check the signature on a certificate using the provided public key
221  */
222 int x509_check_signature(const struct public_key *pub,
223 			 struct x509_certificate *cert)
224 {
225 	int ret;
226 
227 	pr_devel("==>%s()\n", __func__);
228 
229 	ret = x509_get_sig_params(cert);
230 	if (ret < 0)
231 		return ret;
232 
233 	ret = public_key_verify_signature(pub, &cert->sig);
234 	if (ret == -ENOPKG)
235 		cert->unsupported_crypto = true;
236 	pr_debug("Cert Verification: %d\n", ret);
237 	return ret;
238 }
239 EXPORT_SYMBOL_GPL(x509_check_signature);
240 
241 /*
242  * Check the new certificate against the ones in the trust keyring.  If one of
243  * those is the signing key and validates the new certificate, then mark the
244  * new certificate as being trusted.
245  *
246  * Return 0 if the new certificate was successfully validated, 1 if we couldn't
247  * find a matching parent certificate in the trusted list and an error if there
248  * is a matching certificate but the signature check fails.
249  */
250 static int x509_validate_trust(struct x509_certificate *cert,
251 			       struct key *trust_keyring)
252 {
253 	struct key *key;
254 	int ret = 1;
255 
256 	if (!trust_keyring)
257 		return -EOPNOTSUPP;
258 
259 	if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))
260 		return -EPERM;
261 
262 	key = x509_request_asymmetric_key(trust_keyring,
263 					  cert->akid_id, cert->akid_skid,
264 					  false);
265 	if (!IS_ERR(key))  {
266 		if (!use_builtin_keys
267 		    || test_bit(KEY_FLAG_BUILTIN, &key->flags))
268 			ret = x509_check_signature(key->payload.data[asym_crypto],
269 						   cert);
270 		key_put(key);
271 	}
272 	return ret;
273 }
274 
275 /*
276  * Attempt to parse a data blob for a key as an X509 certificate.
277  */
278 static int x509_key_preparse(struct key_preparsed_payload *prep)
279 {
280 	struct asymmetric_key_ids *kids;
281 	struct x509_certificate *cert;
282 	const char *q;
283 	size_t srlen, sulen;
284 	char *desc = NULL, *p;
285 	int ret;
286 
287 	cert = x509_cert_parse(prep->data, prep->datalen);
288 	if (IS_ERR(cert))
289 		return PTR_ERR(cert);
290 
291 	pr_devel("Cert Issuer: %s\n", cert->issuer);
292 	pr_devel("Cert Subject: %s\n", cert->subject);
293 
294 	if (!cert->pub->pkey_algo ||
295 	    !cert->sig.pkey_algo ||
296 	    !cert->sig.hash_algo) {
297 		ret = -ENOPKG;
298 		goto error_free_cert;
299 	}
300 
301 	pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
302 	pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
303 	pr_devel("Cert Signature: %s + %s\n",
304 		 cert->sig.pkey_algo,
305 		 cert->sig.hash_algo);
306 
307 	cert->pub->id_type = "X509";
308 
309 	/* Check the signature on the key if it appears to be self-signed */
310 	if ((!cert->akid_skid && !cert->akid_id) ||
311 	    asymmetric_key_id_same(cert->skid, cert->akid_skid) ||
312 	    asymmetric_key_id_same(cert->id, cert->akid_id)) {
313 		ret = x509_check_signature(cert->pub, cert); /* self-signed */
314 		if (ret < 0)
315 			goto error_free_cert;
316 	} else if (!prep->trusted) {
317 		ret = x509_validate_trust(cert, get_system_trusted_keyring());
318 		if (ret)
319 			ret = x509_validate_trust(cert, get_ima_mok_keyring());
320 		if (!ret)
321 			prep->trusted = 1;
322 	}
323 
324 	/* Propose a description */
325 	sulen = strlen(cert->subject);
326 	if (cert->raw_skid) {
327 		srlen = cert->raw_skid_size;
328 		q = cert->raw_skid;
329 	} else {
330 		srlen = cert->raw_serial_size;
331 		q = cert->raw_serial;
332 	}
333 
334 	ret = -ENOMEM;
335 	desc = kmalloc(sulen + 2 + srlen * 2 + 1, GFP_KERNEL);
336 	if (!desc)
337 		goto error_free_cert;
338 	p = memcpy(desc, cert->subject, sulen);
339 	p += sulen;
340 	*p++ = ':';
341 	*p++ = ' ';
342 	p = bin2hex(p, q, srlen);
343 	*p = 0;
344 
345 	kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL);
346 	if (!kids)
347 		goto error_free_desc;
348 	kids->id[0] = cert->id;
349 	kids->id[1] = cert->skid;
350 
351 	/* We're pinning the module by being linked against it */
352 	__module_get(public_key_subtype.owner);
353 	prep->payload.data[asym_subtype] = &public_key_subtype;
354 	prep->payload.data[asym_key_ids] = kids;
355 	prep->payload.data[asym_crypto] = cert->pub;
356 	prep->description = desc;
357 	prep->quotalen = 100;
358 
359 	/* We've finished with the certificate */
360 	cert->pub = NULL;
361 	cert->id = NULL;
362 	cert->skid = NULL;
363 	desc = NULL;
364 	ret = 0;
365 
366 error_free_desc:
367 	kfree(desc);
368 error_free_cert:
369 	x509_free_certificate(cert);
370 	return ret;
371 }
372 
373 static struct asymmetric_key_parser x509_key_parser = {
374 	.owner	= THIS_MODULE,
375 	.name	= "x509",
376 	.parse	= x509_key_preparse,
377 };
378 
379 /*
380  * Module stuff
381  */
382 static int __init x509_key_init(void)
383 {
384 	return register_asymmetric_key_parser(&x509_key_parser);
385 }
386 
387 static void __exit x509_key_exit(void)
388 {
389 	unregister_asymmetric_key_parser(&x509_key_parser);
390 }
391 
392 module_init(x509_key_init);
393 module_exit(x509_key_exit);
394 
395 MODULE_DESCRIPTION("X.509 certificate parser");
396 MODULE_LICENSE("GPL");
397