|
@@ -31,6 +31,18 @@ struct pkcs7_parse_context {
|
|
|
unsigned sinfo_index;
|
|
|
};
|
|
|
|
|
|
+/*
|
|
|
+ * Free a signed information block.
|
|
|
+ */
|
|
|
+static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
|
|
|
+{
|
|
|
+ if (sinfo) {
|
|
|
+ mpi_free(sinfo->sig.mpi[0]);
|
|
|
+ kfree(sinfo->sig.digest);
|
|
|
+ kfree(sinfo);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* pkcs7_free_message - Free a PKCS#7 message
|
|
|
* @pkcs7: The PKCS#7 message to free
|
|
@@ -54,9 +66,7 @@ void pkcs7_free_message(struct pkcs7_message *pkcs7)
|
|
|
while (pkcs7->signed_infos) {
|
|
|
sinfo = pkcs7->signed_infos;
|
|
|
pkcs7->signed_infos = sinfo->next;
|
|
|
- mpi_free(sinfo->sig.mpi[0]);
|
|
|
- kfree(sinfo->sig.digest);
|
|
|
- kfree(sinfo);
|
|
|
+ pkcs7_free_signed_info(sinfo);
|
|
|
}
|
|
|
kfree(pkcs7);
|
|
|
}
|
|
@@ -71,51 +81,46 @@ EXPORT_SYMBOL_GPL(pkcs7_free_message);
|
|
|
struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
|
|
|
{
|
|
|
struct pkcs7_parse_context *ctx;
|
|
|
- struct pkcs7_message *msg;
|
|
|
- long ret;
|
|
|
+ struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
|
|
|
+ int ret;
|
|
|
|
|
|
- ret = -ENOMEM;
|
|
|
- msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
|
|
|
- if (!msg)
|
|
|
- goto error_no_sig;
|
|
|
ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
|
|
|
if (!ctx)
|
|
|
- goto error_no_ctx;
|
|
|
+ goto out_no_ctx;
|
|
|
+ ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
|
|
|
+ if (!ctx->msg)
|
|
|
+ goto out_no_msg;
|
|
|
ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
|
|
|
if (!ctx->sinfo)
|
|
|
- goto error_no_sinfo;
|
|
|
+ goto out_no_sinfo;
|
|
|
|
|
|
- ctx->msg = msg;
|
|
|
ctx->data = (unsigned long)data;
|
|
|
ctx->ppcerts = &ctx->certs;
|
|
|
ctx->ppsinfo = &ctx->msg->signed_infos;
|
|
|
|
|
|
/* Attempt to decode the signature */
|
|
|
ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
|
|
|
- if (ret < 0)
|
|
|
- goto error_decode;
|
|
|
+ if (ret < 0) {
|
|
|
+ msg = ERR_PTR(ret);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ msg = ctx->msg;
|
|
|
+ ctx->msg = NULL;
|
|
|
|
|
|
+out:
|
|
|
while (ctx->certs) {
|
|
|
struct x509_certificate *cert = ctx->certs;
|
|
|
ctx->certs = cert->next;
|
|
|
x509_free_certificate(cert);
|
|
|
}
|
|
|
- mpi_free(ctx->sinfo->sig.mpi[0]);
|
|
|
- kfree(ctx->sinfo->sig.digest);
|
|
|
- kfree(ctx->sinfo);
|
|
|
+ pkcs7_free_signed_info(ctx->sinfo);
|
|
|
+out_no_sinfo:
|
|
|
+ pkcs7_free_message(ctx->msg);
|
|
|
+out_no_msg:
|
|
|
kfree(ctx);
|
|
|
+out_no_ctx:
|
|
|
return msg;
|
|
|
-
|
|
|
-error_decode:
|
|
|
- mpi_free(ctx->sinfo->sig.mpi[0]);
|
|
|
- kfree(ctx->sinfo->sig.digest);
|
|
|
- kfree(ctx->sinfo);
|
|
|
-error_no_sinfo:
|
|
|
- kfree(ctx);
|
|
|
-error_no_ctx:
|
|
|
- pkcs7_free_message(msg);
|
|
|
-error_no_sig:
|
|
|
- return ERR_PTR(ret);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(pkcs7_parse_message);
|
|
|
|