diff --git a/README.md b/README.md index 3af29fd..69dc4e6 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Other available solutions are deficient: * WINE implements most of `Wintrust`, but is a massive (and arguably non-native) dependency for a single task. -* [`osslsigncode`](https://sourceforge.net/projects/osslsigncode/) can add signatures and check -timestamps, but is long-abandoned and CLI-focused. +* [`osslsigncode`](https://github.com/mtrojnar/osslsigncode) can add signatures and check +timestamps, but is CLI-focused. ## Beware! diff --git a/src/uthenticode.cpp b/src/uthenticode.cpp index b1be0bc..f8bcd6a 100644 --- a/src/uthenticode.cpp +++ b/src/uthenticode.cpp @@ -65,18 +65,21 @@ static inline std::size_t round(std::size_t x, std::size_t factor) { * @return the hex string */ static inline std::string tohex(std::uint8_t *buf, std::size_t len) { - if (buf == nullptr) { + constexpr static char lookup_table[] = "0123456789ABCDEF"; + + if (!buf || !len) { return {}; } - std::stringstream ss; - ss << std::hex << std::setw(2) << std::setfill('0'); + std::string hexstr; + hexstr.reserve(len * 2); // each byte creates two hex digits - for (std::size_t i = 0; i < len; ++i) { - ss << static_cast(buf[i]); + for (auto i = 0; i < len; i++) { + hexstr += lookup_table[buf[i] >> 4]; + hexstr += lookup_table[buf[i] & 0xF]; } - return ss.str(); + return hexstr; } /** diff --git a/test/signeddata-test.cpp b/test/signeddata-test.cpp index 8a6fb5b..d8f84b3 100644 --- a/test/signeddata-test.cpp +++ b/test/signeddata-test.cpp @@ -18,7 +18,9 @@ TEST_F(Auth32Test, SignedData_properties) { auto checksum = signed_data->get_checksum(); ASSERT_EQ(std::get(checksum), uthenticode::checksum_kind::SHA1); - ASSERT_EQ(std::get(checksum), "6663dd7c24fa84fce7f16eb2689952c06cfa22"); + auto const checksumstr = std::get(checksum); + ASSERT_EQ(checksumstr.size(), 40); + ASSERT_STRCASEEQ(checksumstr.c_str(), "6663dd7c24fa84fce7f16e0b02689952c06cfa22"); ASSERT_EQ(signed_data->get_nested_signed_data(), std::nullopt); } @@ -36,7 +38,9 @@ TEST_F(Auth32PlusTest, SignedData_properties) { auto checksum = signed_data->get_checksum(); ASSERT_EQ(std::get(checksum), uthenticode::checksum_kind::SHA1); - ASSERT_EQ(std::get(checksum), "2559e91a60953a5e16f965f5f88953a2cca5425"); + auto const checksumstr = std::get(checksum); + ASSERT_EQ(checksumstr.size(), 40); + ASSERT_STRCASEEQ(checksumstr.c_str(), "2559e91a60953a5e16f9650f5f88953a2cca5425"); ASSERT_EQ(signed_data->get_nested_signed_data(), std::nullopt); } @@ -59,8 +63,10 @@ TEST_F(AuthNest32Test, SignedData_properties_nested) { auto checksum = nested_signed_data->get_checksum(); ASSERT_EQ(std::get(checksum), uthenticode::checksum_kind::SHA256); - ASSERT_EQ(std::get(checksum), - "f1c260304ec64414a97e10cb19dd4c755f9e7079f85feb38ee7ff9f938db99"); + auto const checksumstr = std::get(checksum); + ASSERT_EQ(checksumstr.size(), 64); + ASSERT_STRCASEEQ(checksumstr.c_str(), + "f10c2600304ec64414a97e10cb19dd4c755f9e7079f85feb38ee7ff9f938db99"); } TEST_F(AuthNest32PlusTest, SignedData_properties_nested) { @@ -81,6 +87,8 @@ TEST_F(AuthNest32PlusTest, SignedData_properties_nested) { auto checksum = nested_signed_data->get_checksum(); ASSERT_EQ(std::get(checksum), uthenticode::checksum_kind::SHA256); - ASSERT_EQ(std::get(checksum), - "ddc5b39c429212745eb86a67eaa331032cc5a0dafaf6e28ec9aaf189c408d"); + auto const checksumstr = std::get(checksum); + ASSERT_EQ(checksumstr.size(), 64); + ASSERT_STRCASEEQ(checksumstr.c_str(), + "ddc5b39c4292120745eb86a67eaa331032cc05a0dafaf6e28ec9aa0f189c408d"); } diff --git a/test/uthenticode-test.cpp b/test/uthenticode-test.cpp index 2edad50..e2beb34 100644 --- a/test/uthenticode-test.cpp +++ b/test/uthenticode-test.cpp @@ -57,13 +57,17 @@ TEST_F(NoAuthTest, calculate_checksum) { EXPECT_TRUE(unk.empty()); auto md5 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::MD5); - EXPECT_EQ(md5, "6f7ac8c1754fad04fba2a552a122e7"); + EXPECT_EQ(md5.size(), 32); + EXPECT_STRCASEEQ(md5.c_str(), "6f7ac8c17504fad04fba2a552a122e07"); auto sha1 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::SHA1); - EXPECT_EQ(sha1, "4ba4c91418e28cb63b97cfde1cff95a91139"); + EXPECT_EQ(sha1.size(), 40); + EXPECT_STRCASEEQ(sha1.c_str(), "4ba40c91418e28cb630b97cfde1cff0905a91139"); auto sha256 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::SHA256); - EXPECT_EQ(sha256, "e260f8a57faa823453bd9552506878fcbfb33203d9b606cb9a27e605a8d7b"); + EXPECT_EQ(sha256.size(), 64); + EXPECT_STRCASEEQ(sha256.c_str(), + "e260f8a57faa823453bd95525068780fcbfb0332003d9b606cb9a27e605a8d7b"); } TEST_F(Auth32Test, calculate_checksum) { @@ -71,13 +75,17 @@ TEST_F(Auth32Test, calculate_checksum) { EXPECT_TRUE(unk.empty()); auto md5 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::MD5); - EXPECT_EQ(md5, "64c29391b57679b2973ac562cf64685d"); + EXPECT_EQ(md5.size(), 32); + EXPECT_STRCASEEQ(md5.c_str(), "64c29391b57679b2973ac562cf64685d"); auto sha1 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::SHA1); - EXPECT_EQ(sha1, "6663dd7c24fa84fce7f16eb2689952c06cfa22"); + EXPECT_EQ(sha1.size(), 40); + EXPECT_STRCASEEQ(sha1.c_str(), "6663dd7c24fa84fce7f16e0b02689952c06cfa22"); auto sha256 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::SHA256); - EXPECT_EQ(sha256, "ea13992f99840f76dcac225dd1262edcec3254511b250a6d1e98d99fc48f815"); + EXPECT_EQ(sha256.size(), 64); + EXPECT_STRCASEEQ(sha256.c_str(), + "ea013992f99840f76dcac225dd1262edcec3254511b250a6d1e98d99fc48f815"); } TEST_F(Auth32PlusTest, calculate_checksum) { @@ -85,13 +93,17 @@ TEST_F(Auth32PlusTest, calculate_checksum) { EXPECT_TRUE(unk.empty()); auto md5 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::MD5); - EXPECT_EQ(md5, "ea235b77d552633c5a38974cef0e2b5"); + EXPECT_EQ(md5.size(), 32); + EXPECT_STRCASEEQ(md5.c_str(), "ea0235b77d552633c5a38974cef0e2b5"); auto sha1 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::SHA1); - EXPECT_EQ(sha1, "2559e91a60953a5e16f965f5f88953a2cca5425"); + EXPECT_EQ(sha1.size(), 40); + EXPECT_STRCASEEQ(sha1.c_str(), "2559e91a60953a5e16f9650f5f88953a2cca5425"); auto sha256 = uthenticode::calculate_checksum(pe, uthenticode::checksum_kind::SHA256); - EXPECT_EQ(sha256, "5c823491c5991914aec971d9456d93d6cf2b8ee7e0ed7abcb7731d8ec073c0"); + EXPECT_EQ(sha256.size(), 64); + EXPECT_STRCASEEQ(sha256.c_str(), + "5c823491c5991914aec971d9456d93d6cf2b8ee7e0ed7abc0b77031d8ec073c0"); } TEST(verify, handles_nullptr) {