PKCS#7: Make the signature a pointer rather than embedding it

Point to the public_key_signature struct from the pkcs7_signed_info struct
rather than embedding it.  This makes the code consistent with the X.509
signature handling and makes it possible to have a common cleanup function.

We also save a copy of the digest in the signature without sharing the
memory with the crypto layer metadata.

Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
David Howells
2016-04-06 16:13:33 +01:00
parent 77d0910d15
commit 566a117a8b
4 changed files with 55 additions and 48 deletions

View 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);
@@ -218,25 +221,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 +259,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 +619,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 +659,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;
}