Remove Storage::Md5 and replace it with the one from Azure::Core. (#1618)
* Add MD5 hashing APIs to Azure::Core available from azure/core/md5.hpp. * Add simplified header test for md5 and base64. * Add changelog entry. * Remove unnecessary include. * Remove Storage::Md5 and replace it with the one from Azure::Core. * Fix clang formatting. * Add required cstdint include directive. * Update storage based on recent changes to Md5 hash APIs.
This commit is contained in:
parent
306913ff1b
commit
5359e2793a
@ -7,6 +7,7 @@
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include <azure/core/cryptography/hash.hpp>
|
||||
#include <azure/storage/common/crypt.hpp>
|
||||
#include <azure/storage/common/file_io.hpp>
|
||||
|
||||
@ -120,10 +121,12 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
auto res = m_blockBlobClient->Download(options);
|
||||
ASSERT_TRUE(res->TransactionalContentHash.HasValue());
|
||||
EXPECT_EQ(res->TransactionalContentHash.GetValue().Algorithm, HashAlgorithm::Md5);
|
||||
EXPECT_EQ(
|
||||
res->TransactionalContentHash.GetValue().Value,
|
||||
Md5::Hash(m_blobContent.data(), downloadLength));
|
||||
|
||||
{
|
||||
Azure::Core::Cryptography::Md5Hash instance;
|
||||
EXPECT_EQ(
|
||||
res->TransactionalContentHash.GetValue().Value,
|
||||
instance.Final(m_blobContent.data(), downloadLength));
|
||||
}
|
||||
options.RangeHashAlgorithm = HashAlgorithm::Crc64;
|
||||
res = m_blockBlobClient->Download(options);
|
||||
ASSERT_TRUE(res->TransactionalContentHash.HasValue());
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <future>
|
||||
#include <vector>
|
||||
|
||||
#include <azure/core/cryptography/hash.hpp>
|
||||
#include <azure/storage/blobs/blob_lease_client.hpp>
|
||||
#include <azure/storage/common/crypt.hpp>
|
||||
#include <azure/storage/common/file_io.hpp>
|
||||
@ -251,7 +252,11 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
Blobs::UploadPageBlobPagesOptions options;
|
||||
ContentHash hash;
|
||||
hash.Algorithm = HashAlgorithm::Md5;
|
||||
hash.Value = Md5::Hash(blobContent.data(), blobContent.size());
|
||||
|
||||
{
|
||||
Azure::Core::Cryptography::Md5Hash instance;
|
||||
hash.Value = instance.Final(blobContent.data(), blobContent.size());
|
||||
}
|
||||
options.TransactionalContentHash = hash;
|
||||
EXPECT_NO_THROW(pageBlobClient.UploadPages(0, &pageContent, options));
|
||||
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
|
||||
## 12.0.0-beta.8 (Unreleased)
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- Remove the `Azure::Storage::Md5` class from `crypt.hpp`. Use the type from `Azure::Core::Cryptography` namespace instead, from `azure/core/cryptography/hash.hpp`.
|
||||
|
||||
## 12.0.0-beta.7 (2021-02-03)
|
||||
|
||||
|
||||
@ -11,31 +11,6 @@
|
||||
|
||||
namespace Azure { namespace Storage {
|
||||
|
||||
class Md5 {
|
||||
public:
|
||||
Md5();
|
||||
~Md5();
|
||||
|
||||
void Update(const uint8_t* data, std::size_t length);
|
||||
|
||||
std::vector<uint8_t> Digest() const;
|
||||
|
||||
static std::vector<uint8_t> Hash(const uint8_t* data, std::size_t length)
|
||||
{
|
||||
Md5 instance;
|
||||
instance.Update(data, length);
|
||||
return instance.Digest();
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> Hash(const std::string& data)
|
||||
{
|
||||
return Hash(reinterpret_cast<const uint8_t*>(data.data()), data.length());
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_context;
|
||||
};
|
||||
|
||||
class Crc64 {
|
||||
public:
|
||||
void Update(const uint8_t* data, std::size_t length);
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
@ -87,7 +86,6 @@ namespace Azure { namespace Storage {
|
||||
{
|
||||
HmacSha256,
|
||||
Sha256,
|
||||
Md5,
|
||||
};
|
||||
|
||||
struct AlgorithmProviderInstance
|
||||
@ -103,10 +101,6 @@ namespace Azure { namespace Storage {
|
||||
{
|
||||
algorithmId = BCRYPT_SHA256_ALGORITHM;
|
||||
}
|
||||
else if (type == AlgorithmType::Md5)
|
||||
{
|
||||
algorithmId = BCRYPT_MD5_ALGORITHM;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("unknwon algorithm type");
|
||||
@ -249,75 +243,6 @@ namespace Azure { namespace Storage {
|
||||
}
|
||||
} // namespace Details
|
||||
|
||||
struct Md5HashContext
|
||||
{
|
||||
std::string buffer;
|
||||
BCRYPT_HASH_HANDLE hashHandle = nullptr;
|
||||
std::size_t hashLength = 0;
|
||||
};
|
||||
|
||||
Md5::Md5()
|
||||
{
|
||||
static Details::AlgorithmProviderInstance AlgorithmProvider(Details::AlgorithmType::Md5);
|
||||
|
||||
Md5HashContext* context = new Md5HashContext;
|
||||
m_context = context;
|
||||
context->buffer.resize(AlgorithmProvider.ContextSize);
|
||||
context->hashLength = AlgorithmProvider.HashLength;
|
||||
|
||||
NTSTATUS status = BCryptCreateHash(
|
||||
AlgorithmProvider.Handle,
|
||||
&context->hashHandle,
|
||||
reinterpret_cast<PUCHAR>(&context->buffer[0]),
|
||||
static_cast<ULONG>(context->buffer.size()),
|
||||
nullptr,
|
||||
0,
|
||||
0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptCreateHash failed");
|
||||
}
|
||||
}
|
||||
|
||||
Md5::~Md5()
|
||||
{
|
||||
Md5HashContext* context = static_cast<Md5HashContext*>(m_context);
|
||||
BCryptDestroyHash(context->hashHandle);
|
||||
delete context;
|
||||
}
|
||||
|
||||
void Md5::Update(const uint8_t* data, std::size_t length)
|
||||
{
|
||||
Md5HashContext* context = static_cast<Md5HashContext*>(m_context);
|
||||
|
||||
NTSTATUS status = BCryptHashData(
|
||||
context->hashHandle,
|
||||
reinterpret_cast<PBYTE>(const_cast<uint8_t*>(data)),
|
||||
static_cast<ULONG>(length),
|
||||
0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptHashData failed");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Md5::Digest() const
|
||||
{
|
||||
Md5HashContext* context = static_cast<Md5HashContext*>(m_context);
|
||||
std::vector<uint8_t> hash;
|
||||
hash.resize(context->hashLength);
|
||||
NTSTATUS status = BCryptFinishHash(
|
||||
context->hashHandle,
|
||||
reinterpret_cast<PUCHAR>(&hash[0]),
|
||||
static_cast<ULONG>(hash.size()),
|
||||
0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
{
|
||||
throw std::runtime_error("BCryptFinishHash failed");
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#elif defined(AZ_PLATFORM_POSIX)
|
||||
|
||||
namespace Details {
|
||||
@ -352,33 +277,6 @@ namespace Azure { namespace Storage {
|
||||
|
||||
} // namespace Details
|
||||
|
||||
Md5::Md5()
|
||||
{
|
||||
MD5_CTX* context = new MD5_CTX;
|
||||
m_context = context;
|
||||
MD5_Init(context);
|
||||
}
|
||||
|
||||
Md5::~Md5()
|
||||
{
|
||||
MD5_CTX* context = static_cast<MD5_CTX*>(m_context);
|
||||
delete context;
|
||||
}
|
||||
|
||||
void Md5::Update(const uint8_t* data, std::size_t length)
|
||||
{
|
||||
MD5_CTX* context = static_cast<MD5_CTX*>(m_context);
|
||||
MD5_Update(context, data, length);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Md5::Digest() const
|
||||
{
|
||||
MD5_CTX* context = static_cast<MD5_CTX*>(m_context);
|
||||
unsigned char hash[MD5_DIGEST_LENGTH];
|
||||
MD5_Final(hash, context);
|
||||
return std::vector<uint8_t>(std::begin(hash), std::end(hash));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static constexpr uint64_t Crc64Poly = 0x9A6C9329AC4BC9B5ULL;
|
||||
|
||||
@ -37,26 +37,6 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
"+SBESxQVhI53mSEdZJcCBpdBkaqwzfPaVYZMAf5LP3c=");
|
||||
}
|
||||
|
||||
TEST(CryptFunctionsTest, Md5)
|
||||
{
|
||||
EXPECT_EQ(Azure::Core::Base64Encode(Md5::Hash("")), "1B2M2Y8AsgTpgAmY7PhCfg==");
|
||||
EXPECT_EQ(Azure::Core::Base64Encode(Md5::Hash("Hello Azure!")), "Pz8543xut4RVSbb2g52Mww==");
|
||||
|
||||
auto data = RandomBuffer(static_cast<std::size_t>(16_MB));
|
||||
Md5 md5Instance;
|
||||
|
||||
std::size_t length = 0;
|
||||
while (length < data.size())
|
||||
{
|
||||
std::size_t s = static_cast<std::size_t>(RandomInt(0, 4_MB));
|
||||
s = std::min(s, data.size() - length);
|
||||
md5Instance.Update(&data[length], s);
|
||||
md5Instance.Update(&data[length], 0);
|
||||
length += s;
|
||||
}
|
||||
EXPECT_EQ(md5Instance.Digest(), Md5::Hash(data.data(), data.size()));
|
||||
}
|
||||
|
||||
TEST(CryptFunctionsTest, Crc64)
|
||||
{
|
||||
EXPECT_EQ(Azure::Core::Base64Encode(Crc64::Hash("")), "AAAAAAAAAAA=");
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
|
||||
#include <azure/core/cryptography/hash.hpp>
|
||||
#include <azure/storage/common/crypt.hpp>
|
||||
#include <azure/storage/common/file_io.hpp>
|
||||
#include <azure/storage/common/storage_common.hpp>
|
||||
@ -600,6 +601,12 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> Hash(const std::string& data)
|
||||
{
|
||||
Azure::Core::Cryptography::Md5Hash instance;
|
||||
return instance.Final(reinterpret_cast<const uint8_t*>(data.data()), data.size());
|
||||
}
|
||||
|
||||
TEST_F(FileShareFileClientTest, RangeUploadDownload)
|
||||
{
|
||||
auto rangeSize = 1 * 1024 * 1024;
|
||||
@ -640,8 +647,9 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
{
|
||||
// MD5 works.
|
||||
memBodyStream.Rewind();
|
||||
auto md5 = Md5::Hash(rangeContent.data(), rangeContent.size());
|
||||
auto invalidMd5 = Md5::Hash(std::string("This is garbage."));
|
||||
Azure::Core::Cryptography::Md5Hash instance;
|
||||
auto md5 = instance.Final(rangeContent.data(), rangeContent.size());
|
||||
auto invalidMd5 = Hash(std::string("This is garbage."));
|
||||
auto fileClient
|
||||
= m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString(10));
|
||||
Files::Shares::UploadShareFileRangeOptions uploadOptions;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user