Merge tag 'libnvdimm-for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
[cascardo/linux.git] / crypto / asymmetric_keys / pkcs7_parser.c
index 40de03f..af4cd86 100644 (file)
@@ -44,9 +44,7 @@ struct pkcs7_parse_context {
 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
 {
        if (sinfo) {
-               kfree(sinfo->sig.s);
-               kfree(sinfo->sig.digest);
-               kfree(sinfo->signing_cert_id);
+               public_key_signature_free(sinfo->sig);
                kfree(sinfo);
        }
 }
@@ -125,6 +123,10 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
        ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
        if (!ctx->sinfo)
                goto out_no_sinfo;
+       ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
+                                 GFP_KERNEL);
+       if (!ctx->sinfo->sig)
+               goto out_no_sig;
 
        ctx->data = (unsigned long)data;
        ctx->ppcerts = &ctx->certs;
@@ -150,6 +152,7 @@ out:
                ctx->certs = cert->next;
                x509_free_certificate(cert);
        }
+out_no_sig:
        pkcs7_free_signed_info(ctx->sinfo);
 out_no_sinfo:
        pkcs7_free_message(ctx->msg);
@@ -165,24 +168,25 @@ EXPORT_SYMBOL_GPL(pkcs7_parse_message);
  * @pkcs7: The preparsed PKCS#7 message to access
  * @_data: Place to return a pointer to the data
  * @_data_len: Place to return the data length
- * @want_wrapper: True if the ASN.1 object header should be included in the data
+ * @_headerlen: Size of ASN.1 header not included in _data
  *
- * Get access to the data content of the PKCS#7 message, including, optionally,
- * the header of the ASN.1 object that contains it.  Returns -ENODATA if the
- * data object was missing from the message.
+ * Get access to the data content of the PKCS#7 message.  The size of the
+ * header of the ASN.1 object that contains it is also provided and can be used
+ * to adjust *_data and *_data_len to get the entire object.
+ *
+ * Returns -ENODATA if the data object was missing from the message.
  */
 int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
                           const void **_data, size_t *_data_len,
-                          bool want_wrapper)
+                          size_t *_headerlen)
 {
-       size_t wrapper;
-
        if (!pkcs7->data)
                return -ENODATA;
 
-       wrapper = want_wrapper ? pkcs7->data_hdrlen : 0;
-       *_data = pkcs7->data - wrapper;
-       *_data_len = pkcs7->data_len + wrapper;
+       *_data = pkcs7->data;
+       *_data_len = pkcs7->data_len;
+       if (_headerlen)
+               *_headerlen = pkcs7->data_hdrlen;
        return 0;
 }
 EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
@@ -218,25 +222,26 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
 
        switch (ctx->last_oid) {
        case OID_md4:
-               ctx->sinfo->sig.hash_algo = "md4";
+               ctx->sinfo->sig->hash_algo = "md4";
                break;
        case OID_md5:
-               ctx->sinfo->sig.hash_algo = "md5";
+               ctx->sinfo->sig->hash_algo = "md5";
                break;
        case OID_sha1:
-               ctx->sinfo->sig.hash_algo = "sha1";
+               ctx->sinfo->sig->hash_algo = "sha1";
                break;
        case OID_sha256:
-               ctx->sinfo->sig.hash_algo = "sha256";
+               ctx->sinfo->sig->hash_algo = "sha256";
                break;
        case OID_sha384:
-               ctx->sinfo->sig.hash_algo = "sha384";
+               ctx->sinfo->sig->hash_algo = "sha384";
                break;
        case OID_sha512:
-               ctx->sinfo->sig.hash_algo = "sha512";
+               ctx->sinfo->sig->hash_algo = "sha512";
                break;
        case OID_sha224:
-               ctx->sinfo->sig.hash_algo = "sha224";
+               ctx->sinfo->sig->hash_algo = "sha224";
+               break;
        default:
                printk("Unsupported digest algo: %u\n", ctx->last_oid);
                return -ENOPKG;
@@ -255,7 +260,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
 
        switch (ctx->last_oid) {
        case OID_rsaEncryption:
-               ctx->sinfo->sig.pkey_algo = "rsa";
+               ctx->sinfo->sig->pkey_algo = "rsa";
                break;
        default:
                printk("Unsupported pkey algo: %u\n", ctx->last_oid);
@@ -615,11 +620,11 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen,
 {
        struct pkcs7_parse_context *ctx = context;
 
-       ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL);
-       if (!ctx->sinfo->sig.s)
+       ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
+       if (!ctx->sinfo->sig->s)
                return -ENOMEM;
 
-       ctx->sinfo->sig.s_size = vlen;
+       ctx->sinfo->sig->s_size = vlen;
        return 0;
 }
 
@@ -655,12 +660,16 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen,
 
        pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
 
-       sinfo->signing_cert_id = kid;
+       sinfo->sig->auth_ids[0] = kid;
        sinfo->index = ++ctx->sinfo_index;
        *ctx->ppsinfo = sinfo;
        ctx->ppsinfo = &sinfo->next;
        ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
        if (!ctx->sinfo)
                return -ENOMEM;
+       ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
+                                 GFP_KERNEL);
+       if (!ctx->sinfo->sig)
+               return -ENOMEM;
        return 0;
 }