check stored digest length before comparing authenticode digests (#2234)

the digest carried in a signature can be shorter than the digest algorithm's output size, so the memcmp in parse_authenticode and pkcs9_countersig_new reads past the stored digest; compare the lengths first, the way countersignature.c already does at its other three digest compares.
This commit is contained in:
jmestwa-coder
2026-07-28 12:59:52 +02:00
committed by GitHub
parent 84b0e3cc0e
commit 605452e580
4 changed files with 17 additions and 2 deletions
@@ -571,7 +571,8 @@ AuthenticodeArray* parse_authenticode(const uint8_t* pe_data, uint64_t pe_len)
}
/* Complete the verification */
if (memcmp(sig->file_digest.data, sig->digest.data, mdlen) != 0)
if (sig->digest.len != mdlen ||
memcmp(sig->file_digest.data, sig->digest.data, mdlen) != 0)
sig->verify_flags = AUTHENTICODE_VFY_WRONG_FILE_DIGEST;
}
@@ -220,7 +220,8 @@ Countersignature* pkcs9_countersig_new(
const uint8_t* data_ptr = decData;
DigestInfo* digest_info = d2i_DigestInfo(NULL, &data_ptr, decLen);
if (digest_info) {
isValid = !memcmp(ASN1_STRING_get0_data(digest_info->digest), calc_digest, mdLen);
isValid = ASN1_STRING_length(digest_info->digest) == (int)mdLen &&
!memcmp(ASN1_STRING_get0_data(digest_info->digest), calc_digest, mdLen);
DigestInfo_free(digest_info);
} else {
isValid = false;
Binary file not shown.
+13
View File
@@ -416,6 +416,19 @@ int main(int argc, char** argv)
"tests/data/"
"3b8b90159fa9b6048cc5410c5d53f116943564e4d05b04a843f9b3d0540d0c1c");
// The messageDigest in SpcIndirectDataContent names sha256 but carries a
// single digest byte, so the stored digest is shorter than the algorithm's
// output size.
assert_true_rule_file(
"import \"pe\" \
rule test { \
condition: \
pe.number_of_signatures == 1 and \
pe.signatures[0].digest_alg == \"sha256\" and \
not pe.signatures[0].verified \
}",
"tests/data/authenticode_short_digest");
#endif
assert_true_rule_file(