Skip to content

Commit a6d9ea9

Browse files
committed
Add more information than just BAD_SIGNATURE
1 parent 8d20b9b commit a6d9ea9

File tree

4 files changed

+67
-8
lines changed

4 files changed

+67
-8
lines changed

api/python/PE/objects/signature/pySignature.cpp

+31-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,37 @@ void create<Signature>(py::module& m) {
5353
.value("BAD_SIGNATURE", Signature::VERIFICATION_FLAGS::BAD_SIGNATURE)
5454
.value("NO_SIGNATURE", Signature::VERIFICATION_FLAGS::NO_SIGNATURE)
5555
.value("CERT_EXPIRED", Signature::VERIFICATION_FLAGS::CERT_EXPIRED)
56-
.value("CERT_FUTURE", Signature::VERIFICATION_FLAGS::CERT_FUTURE);
57-
56+
.value("CERT_FUTURE", Signature::VERIFICATION_FLAGS::CERT_FUTURE)
57+
.def("__str__", [] (const Signature::VERIFICATION_FLAGS& flags) {
58+
static const std::array<Signature::VERIFICATION_FLAGS, 13> FLAGS = {
59+
Signature::VERIFICATION_FLAGS::OK,
60+
Signature::VERIFICATION_FLAGS::INVALID_SIGNER,
61+
Signature::VERIFICATION_FLAGS::UNSUPPORTED_ALGORITHM,
62+
Signature::VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM,
63+
Signature::VERIFICATION_FLAGS::CERT_NOT_FOUND,
64+
Signature::VERIFICATION_FLAGS::CORRUPTED_CONTENT_INFO,
65+
Signature::VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA,
66+
Signature::VERIFICATION_FLAGS::MISSING_PKCS9_MESSAGE_DIGEST,
67+
Signature::VERIFICATION_FLAGS::BAD_DIGEST,
68+
Signature::VERIFICATION_FLAGS::BAD_SIGNATURE,
69+
Signature::VERIFICATION_FLAGS::NO_SIGNATURE,
70+
Signature::VERIFICATION_FLAGS::CERT_EXPIRED,
71+
Signature::VERIFICATION_FLAGS::CERT_FUTURE,
72+
};
73+
if (flags == Signature::VERIFICATION_FLAGS::OK) {
74+
return Signature::flag_to_string(flags);
75+
}
76+
std::string flags_str;
77+
for (const Signature::VERIFICATION_FLAGS& flag : FLAGS) {
78+
if ((flags & flag) == flag and flag != Signature::VERIFICATION_FLAGS::OK) {
79+
if (not flags_str.empty()) {
80+
flags_str += " | ";
81+
}
82+
flags_str += "VERIFICATION_FLAGS." + Signature::flag_to_string(flag);
83+
}
84+
}
85+
return flags_str;
86+
}, py::prepend{});
5887

5988
LIEF::enum_<Signature::VERIFICATION_CHECKS>(signature, "VERIFICATION_CHECKS", py::arithmetic(),
6089
R"delim(

include/LIEF/PE/signature/Signature.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class LIEF_API Signature : public Object {
6262
CERT_FUTURE = 1 << 11,
6363
};
6464

65+
//! Convert a verification flag into a humman representation.
66+
//! e.g VERIFICATION_FLAGS.BAD_DIGEST | VERIFICATION_FLAGS.BAD_SIGNATURE | VERIFICATION_FLAGS.CERT_EXPIRED
67+
static std::string flag_to_string(VERIFICATION_FLAGS flag);
68+
6569
//! Flags to tweak the verification process of the signature
6670
//!
6771
//! See Signature::check and LIEF::PE::Binary::verify_signature

src/PE/Binary.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -1206,23 +1206,26 @@ Signature::VERIFICATION_FLAGS Binary::verify_signature(Signature::VERIFICATION_C
12061206
return Signature::VERIFICATION_FLAGS::NO_SIGNATURE;
12071207
}
12081208

1209+
Signature::VERIFICATION_FLAGS flags = Signature::VERIFICATION_FLAGS::OK;
1210+
12091211
for (size_t i = 0; i < this->signatures_.size(); ++i) {
12101212
const Signature& sig = this->signatures_[i];
1211-
Signature::VERIFICATION_FLAGS flags = this->verify_signature(sig, checks);
1213+
flags |= this->verify_signature(sig, checks);
12121214
if (flags != Signature::VERIFICATION_FLAGS::OK) {
12131215
LIEF_INFO("Verification failed for signature #{:d} (0b{:b})", i, static_cast<uintptr_t>(flags));
1214-
return flags;
1216+
break;
12151217
}
12161218
}
1217-
return Signature::VERIFICATION_FLAGS::OK;
1219+
return flags;
12181220
}
12191221

12201222
Signature::VERIFICATION_FLAGS Binary::verify_signature(const Signature& sig, Signature::VERIFICATION_CHECKS checks) const {
1223+
Signature::VERIFICATION_FLAGS flags = Signature::VERIFICATION_FLAGS::OK;
12211224
if (not is_true(checks & Signature::VERIFICATION_CHECKS::HASH_ONLY)) {
12221225
const Signature::VERIFICATION_FLAGS value = sig.check(checks);
12231226
if (value != Signature::VERIFICATION_FLAGS::OK) {
12241227
LIEF_INFO("Bad signature (0b{:b})", static_cast<uintptr_t>(value));
1225-
return value;
1228+
flags |= value;
12261229
}
12271230
}
12281231

@@ -1232,9 +1235,12 @@ Signature::VERIFICATION_FLAGS Binary::verify_signature(const Signature& sig, Sig
12321235
if (authhash != chash) {
12331236
LIEF_INFO("Authentihash and Content info's digest does not match:\n {}\n {}",
12341237
hex_dump(authhash), hex_dump(chash));
1235-
return Signature::VERIFICATION_FLAGS::BAD_SIGNATURE;
1238+
flags |= Signature::VERIFICATION_FLAGS::BAD_DIGEST;
1239+
}
1240+
if (flags != Signature::VERIFICATION_FLAGS::OK) {
1241+
flags |= Signature::VERIFICATION_FLAGS::BAD_SIGNATURE;
12361242
}
1237-
return Signature::VERIFICATION_FLAGS::OK;
1243+
return flags;
12381244
}
12391245

12401246

src/PE/signature/Signature.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "mbedtls/x509_crt.h"
4141
#include "mbedtls/x509.h"
4242

43+
#include "frozen.hpp"
4344

4445
namespace LIEF {
4546
namespace PE {
@@ -50,6 +51,25 @@ inline std::string time_to_string(const x509::date_t& date) {
5051
date[3], date[4], date[5]);
5152
}
5253

54+
std::string Signature::flag_to_string(Signature::VERIFICATION_FLAGS flag) {
55+
CONST_MAP(VERIFICATION_FLAGS, const char*, 13) enumStrings {
56+
{ Signature::VERIFICATION_FLAGS::OK, "OK"},
57+
{ Signature::VERIFICATION_FLAGS::INVALID_SIGNER, "INVALID_SIGNER"},
58+
{ Signature::VERIFICATION_FLAGS::UNSUPPORTED_ALGORITHM, "UNSUPPORTED_ALGORITHM"},
59+
{ Signature::VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM, "INCONSISTENT_DIGEST_ALGORITHM"},
60+
{ Signature::VERIFICATION_FLAGS::CERT_NOT_FOUND, "CERT_NOT_FOUND"},
61+
{ Signature::VERIFICATION_FLAGS::CORRUPTED_CONTENT_INFO, "CORRUPTED_CONTENT_INFO"},
62+
{ Signature::VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA, "CORRUPTED_AUTH_DATA"},
63+
{ Signature::VERIFICATION_FLAGS::MISSING_PKCS9_MESSAGE_DIGEST, "MISSING_PKCS9_MESSAGE_DIGEST"},
64+
{ Signature::VERIFICATION_FLAGS::BAD_DIGEST, "BAD_DIGEST"},
65+
{ Signature::VERIFICATION_FLAGS::BAD_SIGNATURE, "BAD_SIGNATURE"},
66+
{ Signature::VERIFICATION_FLAGS::NO_SIGNATURE, "NO_SIGNATURE"},
67+
{ Signature::VERIFICATION_FLAGS::CERT_EXPIRED, "CERT_EXPIRED"},
68+
{ Signature::VERIFICATION_FLAGS::CERT_FUTURE, "CERT_FUTURE"},
69+
};
70+
auto it = enumStrings.find(flag);
71+
return it == enumStrings.end() ? "UNDEFINED" : it->second;
72+
}
5373

5474
Signature::VERIFICATION_FLAGS verify_ts_counter_signature(const SignerInfo& signer,
5575
const PKCS9CounterSignature& cs, Signature::VERIFICATION_CHECKS checks) {

0 commit comments

Comments
 (0)