]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - kernel/system_keyring.c
MODSIGN: Extract the blob PKCS#7 signature verifier from module signing
[mirror_ubuntu-artful-kernel.git] / kernel / system_keyring.c
index 4cda71ee51c7a1171c8ebccf1a791164173b077f..95f2dcbc761626dfad3f61d48ce6073396576a21 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <keys/asymmetric-type.h>
 #include <keys/system_keyring.h>
+#include <crypto/pkcs7.h>
 
 struct key *system_trusted_keyring;
 EXPORT_SYMBOL_GPL(system_trusted_keyring);
@@ -103,3 +104,52 @@ dodgy_cert:
        return 0;
 }
 late_initcall(load_system_certificate_list);
+
+#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
+
+/**
+ * Verify a PKCS#7-based signature on system data.
+ * @data: The data to be verified.
+ * @len: Size of @data.
+ * @raw_pkcs7: The PKCS#7 message that is the signature.
+ * @pkcs7_len: The size of @raw_pkcs7.
+ */
+int system_verify_data(const void *data, unsigned long len,
+                      const void *raw_pkcs7, size_t pkcs7_len)
+{
+       struct pkcs7_message *pkcs7;
+       bool trusted;
+       int ret;
+
+       pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
+       if (IS_ERR(pkcs7))
+               return PTR_ERR(pkcs7);
+
+       /* The data should be detached - so we need to supply it. */
+       if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
+               pr_err("PKCS#7 signature with non-detached data\n");
+               ret = -EBADMSG;
+               goto error;
+       }
+
+       ret = pkcs7_verify(pkcs7);
+       if (ret < 0)
+               goto error;
+
+       ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
+       if (ret < 0)
+               goto error;
+
+       if (!trusted) {
+               pr_err("PKCS#7 signature not signed with a trusted key\n");
+               ret = -ENOKEY;
+       }
+
+error:
+       pkcs7_free_message(pkcs7);
+       pr_devel("<==%s() = %d\n", __func__, ret);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(system_verify_data);
+
+#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */