common.c 1.2 KB

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