Add more information than just BAD_SIGNATURE

This commit is contained in:
Romain Thomas 2021-01-30 21:34:29 +01:00
parent 8d20b9ba65
commit a6d9ea90a2
4 changed files with 67 additions and 8 deletions

View File

@ -53,8 +53,37 @@ void create<Signature>(py::module& m) {
.value("BAD_SIGNATURE", Signature::VERIFICATION_FLAGS::BAD_SIGNATURE)
.value("NO_SIGNATURE", Signature::VERIFICATION_FLAGS::NO_SIGNATURE)
.value("CERT_EXPIRED", Signature::VERIFICATION_FLAGS::CERT_EXPIRED)
.value("CERT_FUTURE", Signature::VERIFICATION_FLAGS::CERT_FUTURE);
.value("CERT_FUTURE", Signature::VERIFICATION_FLAGS::CERT_FUTURE)
.def("__str__", [] (const Signature::VERIFICATION_FLAGS& flags) {
static const std::array<Signature::VERIFICATION_FLAGS, 13> FLAGS = {
Signature::VERIFICATION_FLAGS::OK,
Signature::VERIFICATION_FLAGS::INVALID_SIGNER,
Signature::VERIFICATION_FLAGS::UNSUPPORTED_ALGORITHM,
Signature::VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM,
Signature::VERIFICATION_FLAGS::CERT_NOT_FOUND,
Signature::VERIFICATION_FLAGS::CORRUPTED_CONTENT_INFO,
Signature::VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA,
Signature::VERIFICATION_FLAGS::MISSING_PKCS9_MESSAGE_DIGEST,
Signature::VERIFICATION_FLAGS::BAD_DIGEST,
Signature::VERIFICATION_FLAGS::BAD_SIGNATURE,
Signature::VERIFICATION_FLAGS::NO_SIGNATURE,
Signature::VERIFICATION_FLAGS::CERT_EXPIRED,
Signature::VERIFICATION_FLAGS::CERT_FUTURE,
};
if (flags == Signature::VERIFICATION_FLAGS::OK) {
return Signature::flag_to_string(flags);
}
std::string flags_str;
for (const Signature::VERIFICATION_FLAGS& flag : FLAGS) {
if ((flags & flag) == flag and flag != Signature::VERIFICATION_FLAGS::OK) {
if (not flags_str.empty()) {
flags_str += " | ";
}
flags_str += "VERIFICATION_FLAGS." + Signature::flag_to_string(flag);
}
}
return flags_str;
}, py::prepend{});
LIEF::enum_<Signature::VERIFICATION_CHECKS>(signature, "VERIFICATION_CHECKS", py::arithmetic(),
R"delim(

View File

@ -62,6 +62,10 @@ class LIEF_API Signature : public Object {
CERT_FUTURE = 1 << 11,
};
//! Convert a verification flag into a humman representation.
//! e.g VERIFICATION_FLAGS.BAD_DIGEST | VERIFICATION_FLAGS.BAD_SIGNATURE | VERIFICATION_FLAGS.CERT_EXPIRED
static std::string flag_to_string(VERIFICATION_FLAGS flag);
//! Flags to tweak the verification process of the signature
//!
//! See Signature::check and LIEF::PE::Binary::verify_signature

View File

@ -1206,23 +1206,26 @@ Signature::VERIFICATION_FLAGS Binary::verify_signature(Signature::VERIFICATION_C
return Signature::VERIFICATION_FLAGS::NO_SIGNATURE;
}
Signature::VERIFICATION_FLAGS flags = Signature::VERIFICATION_FLAGS::OK;
for (size_t i = 0; i < this->signatures_.size(); ++i) {
const Signature& sig = this->signatures_[i];
Signature::VERIFICATION_FLAGS flags = this->verify_signature(sig, checks);
flags |= this->verify_signature(sig, checks);
if (flags != Signature::VERIFICATION_FLAGS::OK) {
LIEF_INFO("Verification failed for signature #{:d} (0b{:b})", i, static_cast<uintptr_t>(flags));
return flags;
break;
}
}
return Signature::VERIFICATION_FLAGS::OK;
return flags;
}
Signature::VERIFICATION_FLAGS Binary::verify_signature(const Signature& sig, Signature::VERIFICATION_CHECKS checks) const {
Signature::VERIFICATION_FLAGS flags = Signature::VERIFICATION_FLAGS::OK;
if (not is_true(checks & Signature::VERIFICATION_CHECKS::HASH_ONLY)) {
const Signature::VERIFICATION_FLAGS value = sig.check(checks);
if (value != Signature::VERIFICATION_FLAGS::OK) {
LIEF_INFO("Bad signature (0b{:b})", static_cast<uintptr_t>(value));
return value;
flags |= value;
}
}
@ -1232,9 +1235,12 @@ Signature::VERIFICATION_FLAGS Binary::verify_signature(const Signature& sig, Sig
if (authhash != chash) {
LIEF_INFO("Authentihash and Content info's digest does not match:\n {}\n {}",
hex_dump(authhash), hex_dump(chash));
return Signature::VERIFICATION_FLAGS::BAD_SIGNATURE;
flags |= Signature::VERIFICATION_FLAGS::BAD_DIGEST;
}
return Signature::VERIFICATION_FLAGS::OK;
if (flags != Signature::VERIFICATION_FLAGS::OK) {
flags |= Signature::VERIFICATION_FLAGS::BAD_SIGNATURE;
}
return flags;
}

View File

@ -40,6 +40,7 @@
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509.h"
#include "frozen.hpp"
namespace LIEF {
namespace PE {
@ -50,6 +51,25 @@ inline std::string time_to_string(const x509::date_t& date) {
date[3], date[4], date[5]);
}
std::string Signature::flag_to_string(Signature::VERIFICATION_FLAGS flag) {
CONST_MAP(VERIFICATION_FLAGS, const char*, 13) enumStrings {
{ Signature::VERIFICATION_FLAGS::OK, "OK"},
{ Signature::VERIFICATION_FLAGS::INVALID_SIGNER, "INVALID_SIGNER"},
{ Signature::VERIFICATION_FLAGS::UNSUPPORTED_ALGORITHM, "UNSUPPORTED_ALGORITHM"},
{ Signature::VERIFICATION_FLAGS::INCONSISTENT_DIGEST_ALGORITHM, "INCONSISTENT_DIGEST_ALGORITHM"},
{ Signature::VERIFICATION_FLAGS::CERT_NOT_FOUND, "CERT_NOT_FOUND"},
{ Signature::VERIFICATION_FLAGS::CORRUPTED_CONTENT_INFO, "CORRUPTED_CONTENT_INFO"},
{ Signature::VERIFICATION_FLAGS::CORRUPTED_AUTH_DATA, "CORRUPTED_AUTH_DATA"},
{ Signature::VERIFICATION_FLAGS::MISSING_PKCS9_MESSAGE_DIGEST, "MISSING_PKCS9_MESSAGE_DIGEST"},
{ Signature::VERIFICATION_FLAGS::BAD_DIGEST, "BAD_DIGEST"},
{ Signature::VERIFICATION_FLAGS::BAD_SIGNATURE, "BAD_SIGNATURE"},
{ Signature::VERIFICATION_FLAGS::NO_SIGNATURE, "NO_SIGNATURE"},
{ Signature::VERIFICATION_FLAGS::CERT_EXPIRED, "CERT_EXPIRED"},
{ Signature::VERIFICATION_FLAGS::CERT_FUTURE, "CERT_FUTURE"},
};
auto it = enumStrings.find(flag);
return it == enumStrings.end() ? "UNDEFINED" : it->second;
}
Signature::VERIFICATION_FLAGS verify_ts_counter_signature(const SignerInfo& signer,
const PKCS9CounterSignature& cs, Signature::VERIFICATION_CHECKS checks) {