forked from Minki/linux
PKCS#7: Introduce pkcs7_get_digest()
IMA will need to access the digest of the PKCS7 message (as calculated by the kernel) before the signature is verified, so introduce pkcs7_get_digest() for that purpose. Also, modify pkcs7_digest() to detect when the digest was already calculated so that it doesn't have to do redundant work. Verifying that sinfo->sig->digest isn't NULL is sufficient because both places which allocate sinfo->sig (pkcs7_parse_message() and pkcs7_note_signed_info()) use kzalloc() so sig->digest is always initialized to zero. Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> Cc: David Howells <dhowells@redhat.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
parent
2a7bf67118
commit
e201af16d1
@ -12,6 +12,7 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/asn1.h>
|
#include <linux/asn1.h>
|
||||||
#include <crypto/hash.h>
|
#include <crypto/hash.h>
|
||||||
|
#include <crypto/hash_info.h>
|
||||||
#include <crypto/public_key.h>
|
#include <crypto/public_key.h>
|
||||||
#include "pkcs7_parser.h"
|
#include "pkcs7_parser.h"
|
||||||
|
|
||||||
@ -29,6 +30,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
|
|||||||
|
|
||||||
kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
|
kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
|
||||||
|
|
||||||
|
/* The digest was calculated already. */
|
||||||
|
if (sig->digest)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!sinfo->sig->hash_algo)
|
if (!sinfo->sig->hash_algo)
|
||||||
return -ENOPKG;
|
return -ENOPKG;
|
||||||
|
|
||||||
@ -117,6 +122,34 @@ error_no_desc:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
|
||||||
|
enum hash_algo *hash_algo)
|
||||||
|
{
|
||||||
|
struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function doesn't support messages with more than one signature.
|
||||||
|
*/
|
||||||
|
if (sinfo == NULL || sinfo->next != NULL)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
ret = pkcs7_digest(pkcs7, sinfo);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*buf = sinfo->sig->digest;
|
||||||
|
*len = sinfo->sig->digest_size;
|
||||||
|
|
||||||
|
for (i = 0; i < HASH_ALGO__LAST; i++)
|
||||||
|
if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
|
||||||
|
*hash_algo = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7
|
* Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7
|
||||||
* uses the issuer's name and the issuing certificate serial number for
|
* uses the issuer's name and the issuing certificate serial number for
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define _CRYPTO_PKCS7_H
|
#define _CRYPTO_PKCS7_H
|
||||||
|
|
||||||
#include <linux/verification.h>
|
#include <linux/verification.h>
|
||||||
|
#include <linux/hash_info.h>
|
||||||
#include <crypto/public_key.h>
|
#include <crypto/public_key.h>
|
||||||
|
|
||||||
struct key;
|
struct key;
|
||||||
@ -40,4 +41,7 @@ extern int pkcs7_verify(struct pkcs7_message *pkcs7,
|
|||||||
extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
|
extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
|
||||||
const void *data, size_t datalen);
|
const void *data, size_t datalen);
|
||||||
|
|
||||||
|
extern int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf,
|
||||||
|
u32 *len, enum hash_algo *hash_algo);
|
||||||
|
|
||||||
#endif /* _CRYPTO_PKCS7_H */
|
#endif /* _CRYPTO_PKCS7_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user