summaryrefslogtreecommitdiff
path: root/crypto/asymmetric_keys/x509_loader.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-06-21 12:13:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2022-06-21 12:13:53 -0500
commit86e37249b5ca705585e43e7259fd6f123b5ee600 (patch)
tree175f3a61b93fd0ea61a1f43c22733faf9dff0b52 /crypto/asymmetric_keys/x509_loader.c
parentc63768861c255773e21b4de4e277b5badaac300b (diff)
parent041ec6e33d4823d79d56bf5f003ec0f42a7bff92 (diff)
downloadlinux-crypto-86e37249b5ca705585e43e7259fd6f123b5ee600.tar.gz
linux-crypto-86e37249b5ca705585e43e7259fd6f123b5ee600.zip
Merge tag 'certs-20220621' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull signature checking selftest from David Howells: "The signature checking code, as used by module signing, kexec, etc., is non-FIPS compliant as there is no selftest. For a kernel to be FIPS-compliant, signature checking would have to be tested before being used, and the box would need to panic if it's not available (probably reasonable as simply disabling signature checking would prevent you from loading any driver modules). Deal with this by adding a minimal test. This is split into two patches: the first moves load_certificate_list() to the same place as the X.509 code to make it more accessible internally; the second adds a selftest" * tag 'certs-20220621' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: certs: Add FIPS selftests certs: Move load_certificate_list() to be with the asymmetric keys code
Diffstat (limited to 'crypto/asymmetric_keys/x509_loader.c')
-rw-r--r--crypto/asymmetric_keys/x509_loader.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/x509_loader.c
new file mode 100644
index 00000000..1bc169de
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_loader.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/key.h>
+#include <keys/asymmetric-type.h>
+
+int x509_load_certificate_list(const u8 cert_list[],
+ const unsigned long list_size,
+ const struct key *keyring)
+{
+ key_ref_t key;
+ const u8 *p, *end;
+ size_t plen;
+
+ p = cert_list;
+ end = p + list_size;
+ while (p < end) {
+ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
+ * than 256 bytes in size.
+ */
+ if (end - p < 4)
+ goto dodgy_cert;
+ if (p[0] != 0x30 &&
+ p[1] != 0x82)
+ goto dodgy_cert;
+ plen = (p[2] << 8) | p[3];
+ plen += 4;
+ if (plen > end - p)
+ goto dodgy_cert;
+
+ key = key_create_or_update(make_key_ref(keyring, 1),
+ "asymmetric",
+ NULL,
+ p,
+ plen,
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ),
+ KEY_ALLOC_NOT_IN_QUOTA |
+ KEY_ALLOC_BUILT_IN |
+ KEY_ALLOC_BYPASS_RESTRICTION);
+ if (IS_ERR(key)) {
+ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
+ PTR_ERR(key));
+ } else {
+ pr_notice("Loaded X.509 cert '%s'\n",
+ key_ref_to_ptr(key)->description);
+ key_ref_put(key);
+ }
+ p += plen;
+ }
+
+ return 0;
+
+dodgy_cert:
+ pr_err("Problem parsing in-kernel X.509 certificate list\n");
+ return 0;
+}