From: James Bottomley Trying to run pkcs7_validate_trust() on something that parsed correctly but is not verified doesn't work because the signature digest hasn't been calculated. Fix this by adding a digest calclation in to pkcs7_validate_one(). This is almost a nop if the digest exists. Additionally, the trust validation doesn't know the data payload, so adjust the digest calculator to skip checking the data digest if pkcs7->data is NULL. A check is added in pkcs7_verify() for pkcs7->data being null (returning -EBADMSG) to guard against someone forgetting to supply data and getting an invalid success return. Signed-off-by: James Bottomley --- crypto/asymmetric_keys/pkcs7_parser.h | 3 +++ crypto/asymmetric_keys/pkcs7_trust.c | 8 ++++++++ crypto/asymmetric_keys/pkcs7_verify.c | 13 +++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h index 203062a33def..cbe823aeac06 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.h +++ b/crypto/asymmetric_keys/pkcs7_parser.h @@ -66,3 +66,6 @@ struct pkcs7_message { size_t data_hdrlen; /* Length of Data ASN.1 header */ const void *data; /* Content Data (or 0) */ }; + +int pkcs7_digest(struct pkcs7_message *pkcs7, + struct pkcs7_signed_info *sinfo); diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 78ebfb6373b6..7cb0a6bc7b32 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -30,6 +30,14 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, kenter(",%u,", sinfo->index); + /* + * if we're being called immediately after parse, the + * signature won't have a calculated digest yet, so calculate + * one. This function returns immediately if a digest has + * already been calculated + */ + pkcs7_digest(pkcs7, sinfo); + if (sinfo->unsupported_crypto) { kleave(" = -ENOPKG [cached]"); return -ENOPKG; diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 474e2c1ae21b..3080f0ec52e0 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -19,8 +19,8 @@ /* * Digest the relevant parts of the PKCS#7 data */ -static int pkcs7_digest(struct pkcs7_message *pkcs7, - struct pkcs7_signed_info *sinfo) +int pkcs7_digest(struct pkcs7_message *pkcs7, + struct pkcs7_signed_info *sinfo) { struct public_key_signature *sig = sinfo->sig; struct crypto_shash *tfm; @@ -93,8 +93,8 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, goto error; } - if (memcmp(sig->m, sinfo->msgdigest, - sinfo->msgdigest_len) != 0) { + if (pkcs7->data && memcmp(sig->m, sinfo->msgdigest, + sinfo->msgdigest_len) != 0) { pr_warn("Sig %u: Message digest doesn't match\n", sinfo->index); ret = -EKEYREJECTED; @@ -463,6 +463,11 @@ int pkcs7_verify(struct pkcs7_message *pkcs7, return -EINVAL; } + if (!pkcs7->data) { + pr_warn("Data not supplied to verify operation\n"); + return -EBADMSG; + } + for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { ret = pkcs7_verify_one(pkcs7, sinfo); if (sinfo->blacklisted) { -- 2.52.0