KEYS: Generalise system_verify_data() to provide access to internal content
[cascardo/linux.git] / crypto / asymmetric_keys / pkcs7_key_type.c
index e2d0edb..ab9bf53 100644 (file)
 #include <linux/key.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/verification.h>
 #include <linux/key-type.h>
-#include <keys/asymmetric-type.h>
-#include <crypto/pkcs7.h>
 #include <keys/user-type.h>
-#include <keys/system_keyring.h>
-#include "pkcs7_parser.h"
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("PKCS#7 testing key type");
@@ -29,59 +26,46 @@ MODULE_PARM_DESC(pkcs7_usage,
                 "Usage to specify when verifying the PKCS#7 message");
 
 /*
- * Preparse a PKCS#7 wrapped and validated data blob.
+ * Retrieve the PKCS#7 message content.
  */
-static int pkcs7_preparse(struct key_preparsed_payload *prep)
+static int pkcs7_view_content(void *ctx, const void *data, size_t len,
+                             size_t asn1hdrlen)
 {
-       enum key_being_used_for usage = pkcs7_usage;
-       struct pkcs7_message *pkcs7;
-       const void *data, *saved_prep_data;
-       size_t datalen, saved_prep_datalen;
-       bool trusted;
+       struct key_preparsed_payload *prep = ctx;
+       const void *saved_prep_data;
+       size_t saved_prep_datalen;
        int ret;
 
-       kenter("");
-
-       if (usage >= NR__KEY_BEING_USED_FOR) {
-               pr_err("Invalid usage type %d\n", usage);
-               return -EINVAL;
-       }
-
        saved_prep_data = prep->data;
        saved_prep_datalen = prep->datalen;
-       pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen);
-       if (IS_ERR(pkcs7)) {
-               ret = PTR_ERR(pkcs7);
-               goto error;
-       }
-
-       ret = pkcs7_verify(pkcs7, usage);
-       if (ret < 0)
-               goto error_free;
-
-       ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);
-       if (ret < 0)
-               goto error_free;
-       if (!trusted)
-               pr_warn("PKCS#7 message doesn't chain back to a trusted key\n");
-
-       ret = pkcs7_get_content_data(pkcs7, &data, &datalen, false);
-       if (ret < 0)
-               goto error_free;
-
        prep->data = data;
-       prep->datalen = datalen;
+       prep->datalen = len;
+
        ret = user_preparse(prep);
+
        prep->data = saved_prep_data;
        prep->datalen = saved_prep_datalen;
-
-error_free:
-       pkcs7_free_message(pkcs7);
-error:
-       kleave(" = %d", ret);
        return ret;
 }
 
+/*
+ * Preparse a PKCS#7 wrapped and validated data blob.
+ */
+static int pkcs7_preparse(struct key_preparsed_payload *prep)
+{
+       enum key_being_used_for usage = pkcs7_usage;
+
+       if (usage >= NR__KEY_BEING_USED_FOR) {
+               pr_err("Invalid usage type %d\n", usage);
+               return -EINVAL;
+       }
+
+       return verify_pkcs7_signature(NULL, 0,
+                                     prep->data, prep->datalen,
+                                     NULL, -ENOKEY, usage,
+                                     pkcs7_view_content, prep);
+}
+
 /*
  * user defined keys take an arbitrary string as the description and an
  * arbitrary blob of data as the payload