Merge tag 'apparmor-pr-2021-11-10' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-rpi.git] / certs / common.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include <linux/kernel.h>
4 #include <linux/key.h>
5 #include "common.h"
6
7 int load_certificate_list(const u8 cert_list[],
8                           const unsigned long list_size,
9                           const struct key *keyring)
10 {
11         key_ref_t key;
12         const u8 *p, *end;
13         size_t plen;
14
15         p = cert_list;
16         end = p + list_size;
17         while (p < end) {
18                 /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
19                  * than 256 bytes in size.
20                  */
21                 if (end - p < 4)
22                         goto dodgy_cert;
23                 if (p[0] != 0x30 &&
24                     p[1] != 0x82)
25                         goto dodgy_cert;
26                 plen = (p[2] << 8) | p[3];
27                 plen += 4;
28                 if (plen > end - p)
29                         goto dodgy_cert;
30
31                 key = key_create_or_update(make_key_ref(keyring, 1),
32                                            "asymmetric",
33                                            NULL,
34                                            p,
35                                            plen,
36                                            ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
37                                            KEY_USR_VIEW | KEY_USR_READ),
38                                            KEY_ALLOC_NOT_IN_QUOTA |
39                                            KEY_ALLOC_BUILT_IN |
40                                            KEY_ALLOC_BYPASS_RESTRICTION);
41                 if (IS_ERR(key)) {
42                         pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
43                                PTR_ERR(key));
44                 } else {
45                         pr_notice("Loaded X.509 cert '%s'\n",
46                                   key_ref_to_ptr(key)->description);
47                         key_ref_put(key);
48                 }
49                 p += plen;
50         }
51
52         return 0;
53
54 dodgy_cert:
55         pr_err("Problem parsing in-kernel X.509 certificate list\n");
56         return 0;
57 }