LCOV - code coverage report
Current view: top level - source/common/crypto - utility_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 52 62 83.9 %
Date: 2024-01-05 06:35:25 Functions: 4 5 80.0 %

          Line data    Source code
       1             : #include "source/common/crypto/utility_impl.h"
       2             : 
       3             : #include "source/common/common/assert.h"
       4             : #include "source/common/crypto/crypto_impl.h"
       5             : 
       6             : #include "absl/container/fixed_array.h"
       7             : #include "absl/strings/ascii.h"
       8             : #include "absl/strings/str_cat.h"
       9             : 
      10             : namespace Envoy {
      11             : namespace Common {
      12             : namespace Crypto {
      13             : 
      14          29 : std::vector<uint8_t> UtilityImpl::getSha256Digest(const Buffer::Instance& buffer) {
      15          29 :   std::vector<uint8_t> digest(SHA256_DIGEST_LENGTH);
      16          29 :   bssl::ScopedEVP_MD_CTX ctx;
      17          29 :   auto rc = EVP_DigestInit(ctx.get(), EVP_sha256());
      18          29 :   RELEASE_ASSERT(rc == 1, "Failed to init digest context");
      19          29 :   for (const auto& slice : buffer.getRawSlices()) {
      20          29 :     rc = EVP_DigestUpdate(ctx.get(), slice.mem_, slice.len_);
      21          29 :     RELEASE_ASSERT(rc == 1, "Failed to update digest");
      22          29 :   }
      23          29 :   rc = EVP_DigestFinal(ctx.get(), digest.data(), nullptr);
      24          29 :   RELEASE_ASSERT(rc == 1, "Failed to finalize digest");
      25          29 :   return digest;
      26          29 : }
      27             : 
      28             : std::vector<uint8_t> UtilityImpl::getSha256Hmac(const std::vector<uint8_t>& key,
      29           0 :                                                 absl::string_view message) {
      30           0 :   std::vector<uint8_t> hmac(SHA256_DIGEST_LENGTH);
      31           0 :   const auto ret =
      32           0 :       HMAC(EVP_sha256(), key.data(), key.size(), reinterpret_cast<const uint8_t*>(message.data()),
      33           0 :            message.size(), hmac.data(), nullptr);
      34           0 :   RELEASE_ASSERT(ret != nullptr, "Failed to create HMAC");
      35           0 :   return hmac;
      36           0 : }
      37             : 
      38             : const VerificationOutput UtilityImpl::verifySignature(absl::string_view hash, CryptoObject& key,
      39             :                                                       const std::vector<uint8_t>& signature,
      40         183 :                                                       const std::vector<uint8_t>& text) {
      41             :   // Step 1: initialize EVP_MD_CTX
      42         183 :   bssl::ScopedEVP_MD_CTX ctx;
      43             : 
      44             :   // Step 2: initialize EVP_MD
      45         183 :   const EVP_MD* md = getHashFunction(hash);
      46             : 
      47         183 :   if (md == nullptr) {
      48         150 :     return {false, absl::StrCat(hash, " is not supported.")};
      49         150 :   }
      50             :   // Step 3: initialize EVP_DigestVerify
      51          33 :   auto pkey_wrapper = Common::Crypto::Access::getTyped<Common::Crypto::PublicKeyObject>(key);
      52          33 :   EVP_PKEY* pkey = pkey_wrapper->getEVP_PKEY();
      53             : 
      54          33 :   if (pkey == nullptr) {
      55          11 :     return {false, "Failed to initialize digest verify."};
      56          11 :   }
      57             : 
      58          22 :   int ok = EVP_DigestVerifyInit(ctx.get(), nullptr, md, nullptr, pkey);
      59          22 :   if (!ok) {
      60           0 :     return {false, "Failed to initialize digest verify."};
      61           0 :   }
      62             : 
      63             :   // Step 4: verify signature
      64          22 :   ok = EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), text.data(), text.size());
      65             : 
      66             :   // Step 5: check result
      67          22 :   if (ok == 1) {
      68           1 :     return {true, ""};
      69           1 :   }
      70             : 
      71          21 :   return {false, absl::StrCat("Failed to verify digest. Error code: ", ok)};
      72          22 : }
      73             : 
      74         183 : CryptoObjectPtr UtilityImpl::importPublicKey(const std::vector<uint8_t>& key) {
      75         183 :   CBS cbs({key.data(), key.size()});
      76             : 
      77         183 :   return std::make_unique<PublicKeyObject>(EVP_parse_public_key(&cbs));
      78         183 : }
      79             : 
      80         183 : const EVP_MD* UtilityImpl::getHashFunction(absl::string_view name) {
      81         183 :   const std::string hash = absl::AsciiStrToLower(name);
      82             : 
      83             :   // Hash algorithms set refers
      84             :   // https://github.com/google/boringssl/blob/master/include/openssl/digest.h
      85         183 :   if (hash == "sha1") {
      86          10 :     return EVP_sha1();
      87         173 :   } else if (hash == "sha224") {
      88           4 :     return EVP_sha224();
      89         169 :   } else if (hash == "sha256") {
      90           9 :     return EVP_sha256();
      91         160 :   } else if (hash == "sha384") {
      92           7 :     return EVP_sha384();
      93         153 :   } else if (hash == "sha512") {
      94           3 :     return EVP_sha512();
      95         150 :   } else {
      96         150 :     return nullptr;
      97         150 :   }
      98         183 : }
      99             : 
     100             : // Register the crypto utility singleton.
     101             : static Crypto::ScopedUtilitySingleton* utility_ =
     102             :     new Crypto::ScopedUtilitySingleton(std::make_unique<Crypto::UtilityImpl>());
     103             : 
     104             : } // namespace Crypto
     105             : } // namespace Common
     106             : } // namespace Envoy

Generated by: LCOV version 1.15