diff --git a/api/python/PE/objects/signature/pySignature.cpp b/api/python/PE/objects/signature/pySignature.cpp index 2b6648d686..0fc1e2f5ae 100644 --- a/api/python/PE/objects/signature/pySignature.cpp +++ b/api/python/PE/objects/signature/pySignature.cpp @@ -53,8 +53,37 @@ void create(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 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", py::arithmetic(), R"delim( diff --git a/include/LIEF/PE/signature/Signature.hpp b/include/LIEF/PE/signature/Signature.hpp index 7e0b764c0d..1419e4c7d0 100644 --- a/include/LIEF/PE/signature/Signature.hpp +++ b/include/LIEF/PE/signature/Signature.hpp @@ -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 diff --git a/src/PE/Binary.cpp b/src/PE/Binary.cpp index d54597faba..a47c5d33e3 100644 --- a/src/PE/Binary.cpp +++ b/src/PE/Binary.cpp @@ -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(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(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; + } + if (flags != Signature::VERIFICATION_FLAGS::OK) { + flags |= Signature::VERIFICATION_FLAGS::BAD_SIGNATURE; } - return Signature::VERIFICATION_FLAGS::OK; +return flags; } diff --git a/src/PE/signature/Signature.cpp b/src/PE/signature/Signature.cpp index 6dd752e9e7..a87837246d 100644 --- a/src/PE/signature/Signature.cpp +++ b/src/PE/signature/Signature.cpp @@ -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) {