/proc/self/cwd/source/common/crypto/utility_impl.cc
Line | Count | Source (jump to first uncovered line) |
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 | 110 | std::vector<uint8_t> UtilityImpl::getSha256Digest(const Buffer::Instance& buffer) { |
15 | 110 | std::vector<uint8_t> digest(SHA256_DIGEST_LENGTH); |
16 | 110 | bssl::ScopedEVP_MD_CTX ctx; |
17 | 110 | auto rc = EVP_DigestInit(ctx.get(), EVP_sha256()); |
18 | 110 | RELEASE_ASSERT(rc == 1, "Failed to init digest context"); |
19 | 110 | for (const auto& slice : buffer.getRawSlices()) { |
20 | 110 | rc = EVP_DigestUpdate(ctx.get(), slice.mem_, slice.len_); |
21 | 110 | RELEASE_ASSERT(rc == 1, "Failed to update digest"); |
22 | 110 | } |
23 | 110 | rc = EVP_DigestFinal(ctx.get(), digest.data(), nullptr); |
24 | 110 | RELEASE_ASSERT(rc == 1, "Failed to finalize digest"); |
25 | 110 | return digest; |
26 | 110 | } |
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 | 2.42k | const std::vector<uint8_t>& text) { |
41 | | // Step 1: initialize EVP_MD_CTX |
42 | 2.42k | bssl::ScopedEVP_MD_CTX ctx; |
43 | | |
44 | | // Step 2: initialize EVP_MD |
45 | 2.42k | const EVP_MD* md = getHashFunction(hash); |
46 | | |
47 | 2.42k | if (md == nullptr) { |
48 | 1.30k | return {false, absl::StrCat(hash, " is not supported.")}; |
49 | 1.30k | } |
50 | | // Step 3: initialize EVP_DigestVerify |
51 | 1.12k | auto pkey_wrapper = Common::Crypto::Access::getTyped<Common::Crypto::PublicKeyObject>(key); |
52 | 1.12k | EVP_PKEY* pkey = pkey_wrapper->getEVP_PKEY(); |
53 | | |
54 | 1.12k | if (pkey == nullptr) { |
55 | 6 | return {false, "Failed to initialize digest verify."}; |
56 | 6 | } |
57 | | |
58 | 1.11k | int ok = EVP_DigestVerifyInit(ctx.get(), nullptr, md, nullptr, pkey); |
59 | 1.11k | if (!ok) { |
60 | 0 | return {false, "Failed to initialize digest verify."}; |
61 | 0 | } |
62 | | |
63 | | // Step 4: verify signature |
64 | 1.11k | ok = EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), text.data(), text.size()); |
65 | | |
66 | | // Step 5: check result |
67 | 1.11k | if (ok == 1) { |
68 | 1 | return {true, ""}; |
69 | 1 | } |
70 | | |
71 | 1.11k | return {false, absl::StrCat("Failed to verify digest. Error code: ", ok)}; |
72 | 1.11k | } |
73 | | |
74 | 2.42k | CryptoObjectPtr UtilityImpl::importPublicKey(const std::vector<uint8_t>& key) { |
75 | 2.42k | CBS cbs({key.data(), key.size()}); |
76 | | |
77 | 2.42k | return std::make_unique<PublicKeyObject>(EVP_parse_public_key(&cbs)); |
78 | 2.42k | } |
79 | | |
80 | 2.42k | const EVP_MD* UtilityImpl::getHashFunction(absl::string_view name) { |
81 | 2.42k | 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 | 2.42k | if (hash == "sha1") { |
86 | 944 | return EVP_sha1(); |
87 | 1.48k | } else if (hash == "sha224") { |
88 | 26 | return EVP_sha224(); |
89 | 1.45k | } else if (hash == "sha256") { |
90 | 62 | return EVP_sha256(); |
91 | 1.39k | } else if (hash == "sha384") { |
92 | 43 | return EVP_sha384(); |
93 | 1.35k | } else if (hash == "sha512") { |
94 | 48 | return EVP_sha512(); |
95 | 1.30k | } else { |
96 | 1.30k | return nullptr; |
97 | 1.30k | } |
98 | 2.42k | } |
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 |