Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
## v2.0.2-rc ### BREAKING CHANGES * Refactored `config.json` - will need to verify configuration settings prior to mounting ### Issues * \#12 \[Unit Test\] Complete all providers unit tests * \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup * \#16 Add support for bucket name in Sia provider * \#17 Update to common c++ build system * A single 64-bit Linux Jenkins server is used to build all Linux and Windows versions * All dependency sources are now included * MSVC is no longer supported * MSYS2 is required for building Windows binaries on Windows * OS X support is temporarily disabled * \#19 \[bug\] Rename file is broken for files that are existing * \#23 \[bug\] Incorrect file size displayed while upload is pending * \#24 RocksDB implementations should be transactional * \#25 Writes should block when maximum cache size is reached * \#26 Complete ring buffer and direct download support ### Changes from v2.0.1-rc * Ability to choose between RocksDB and SQLite databases * Added direct reads and implemented download fallback * Corrected file times on S3 and Sia providers * Corrected handling of `chown()` and `chmod()` * Fixed erroneous download of chunks after resize Reviewed-on: #27
284 lines
9.9 KiB
C++
284 lines
9.9 KiB
C++
/*
|
|
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do
|
|
so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
#include "test.hpp"
|
|
|
|
#if defined(PROJECT_ENABLE_LIBSODIUM)
|
|
|
|
namespace repertory {
|
|
static constexpr const std::string_view token{"moose"};
|
|
static constexpr const std::wstring_view token_w{L"moose"};
|
|
|
|
TEST(utils_encryption, generate_key) {
|
|
auto key1 =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
EXPECT_STREQ(
|
|
"ab4a0b004e824962913f7c0f79582b6ec7a3b8726426ca61d1a0a28ce5049e96",
|
|
utils::collection::to_hex_string(key1).c_str());
|
|
|
|
auto key2 =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>("moose");
|
|
auto key3 =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>("moose");
|
|
EXPECT_EQ(key2, key3);
|
|
|
|
auto key4 =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>("moose2");
|
|
EXPECT_NE(key2, key4);
|
|
|
|
auto key1_w =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token_w);
|
|
EXPECT_NE(key1, key1_w);
|
|
#if defined(_WIN32)
|
|
EXPECT_STREQ(
|
|
L"4f5eb2a2ab34e3777b230465283923080b9ba59311e74058ccd74185131d11fe",
|
|
utils::collection::to_hex_wstring(key1_w).c_str());
|
|
#else // !defined(_WIN32)
|
|
EXPECT_STREQ(
|
|
L"0392d95ed3eee9772fbb9af68fedf829a8eb0adbe8575d9691cc9a752196766a",
|
|
utils::collection::to_hex_wstring(key1_w).c_str());
|
|
#endif
|
|
|
|
auto key2_w =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(L"moose");
|
|
auto key3_w =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(L"moose");
|
|
EXPECT_EQ(key2_w, key3_w);
|
|
EXPECT_NE(key2_w, key2);
|
|
EXPECT_NE(key3_w, key3);
|
|
|
|
auto key4_w =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(L"moose2");
|
|
EXPECT_NE(key2_w, key4_w);
|
|
EXPECT_NE(key4_w, key4);
|
|
}
|
|
|
|
TEST(utils_encryption, generate_key_default_hasher_is_blake2b_256) {
|
|
auto key1 =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
auto key2 = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
|
token, [](auto &&data, auto &&size) -> auto {
|
|
return utils::encryption::create_hash_blake2b_256(
|
|
std::string_view(reinterpret_cast<const char *>(data), size));
|
|
});
|
|
EXPECT_EQ(key1, key2);
|
|
|
|
auto key1_w =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token_w);
|
|
auto key2_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
|
token_w, [](auto &&data, auto &&size) -> auto {
|
|
return utils::encryption::create_hash_blake2b_256(std::wstring_view(
|
|
reinterpret_cast<const wchar_t *>(data), size / sizeof(wchar_t)));
|
|
});
|
|
EXPECT_EQ(key1_w, key2_w);
|
|
|
|
EXPECT_NE(key1_w, key1);
|
|
EXPECT_NE(key2_w, key2);
|
|
}
|
|
|
|
TEST(utils_encryption, generate_key_with_hasher) {
|
|
auto key1 = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
|
token, utils::encryption::blake2b_256_hasher);
|
|
EXPECT_STREQ(
|
|
"ab4a0b004e824962913f7c0f79582b6ec7a3b8726426ca61d1a0a28ce5049e96",
|
|
utils::collection::to_hex_string(key1).c_str());
|
|
|
|
auto key2 = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
|
token, utils::encryption::sha256_hasher);
|
|
EXPECT_NE(key1, key2);
|
|
|
|
EXPECT_STREQ(
|
|
"182072537ada59e4d6b18034a80302ebae935f66adbdf0f271d3d36309c2d481",
|
|
utils::collection::to_hex_string(key2).c_str());
|
|
|
|
auto key1_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
|
token_w, utils::encryption::blake2b_256_hasher);
|
|
#if defined(_WIN32)
|
|
EXPECT_STREQ(
|
|
L"4f5eb2a2ab34e3777b230465283923080b9ba59311e74058ccd74185131d11fe",
|
|
utils::collection::to_hex_wstring(key1_w).c_str());
|
|
#else // !defined(_WIN32)
|
|
EXPECT_STREQ(
|
|
L"0392d95ed3eee9772fbb9af68fedf829a8eb0adbe8575d9691cc9a752196766a",
|
|
utils::collection::to_hex_wstring(key1_w).c_str());
|
|
#endif
|
|
|
|
auto key2_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
|
token_w, utils::encryption::sha256_hasher);
|
|
EXPECT_NE(key1_w, key2_w);
|
|
|
|
#if defined(_WIN32)
|
|
EXPECT_STREQ(
|
|
L"918e4c6d39bb373f139b5fac8ec0548a9770da399b2835608974ffeac7fab6c4",
|
|
utils::collection::to_hex_wstring(key2_w).c_str());
|
|
#else // !defined(_WIN32)
|
|
EXPECT_STREQ(
|
|
L"590ac70125bec4501172937f6a2cbdeb22a87b5e40d5595eccd06b2b20548d8f",
|
|
utils::collection::to_hex_wstring(key2_w).c_str());
|
|
#endif
|
|
|
|
EXPECT_NE(key1_w, key1);
|
|
EXPECT_NE(key2_w, key2);
|
|
}
|
|
|
|
#if defined(PROJECT_ENABLE_BOOST)
|
|
static const std::string buffer = "cow moose dog chicken";
|
|
|
|
static void test_encrypted_result(const data_buffer &result) {
|
|
EXPECT_EQ(buffer.size() + utils::encryption::encryption_header_size,
|
|
result.size());
|
|
std::string data;
|
|
EXPECT_TRUE(utils::encryption::decrypt_data(token, result, data));
|
|
EXPECT_EQ(buffer.size(), data.size());
|
|
EXPECT_STREQ(buffer.c_str(), data.c_str());
|
|
}
|
|
|
|
TEST(utils_encryption, encrypt_data_buffer) {
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(token, buffer, result);
|
|
test_encrypted_result(result);
|
|
}
|
|
|
|
TEST(utils_encryption, encrypt_data_buffer_with_key) {
|
|
const auto key =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(key, buffer, result);
|
|
test_encrypted_result(result);
|
|
}
|
|
|
|
TEST(utils_encryption, encrypt_data_pointer) {
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(
|
|
token, reinterpret_cast<const unsigned char *>(buffer.data()),
|
|
buffer.size(), result);
|
|
test_encrypted_result(result);
|
|
}
|
|
|
|
TEST(utils_encryption, encrypt_data_pointer_with_key) {
|
|
const auto key =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(
|
|
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
|
buffer.size(), result);
|
|
test_encrypted_result(result);
|
|
}
|
|
|
|
TEST(utils_encryption, decrypt_data_pointer) {
|
|
const auto key =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(
|
|
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
|
buffer.size(), result);
|
|
|
|
std::string data;
|
|
EXPECT_TRUE(utils::encryption::decrypt_data(token, result.data(),
|
|
result.size(), data));
|
|
|
|
EXPECT_EQ(buffer.size(), data.size());
|
|
EXPECT_STREQ(buffer.c_str(), data.c_str());
|
|
}
|
|
|
|
TEST(utils_encryption, decrypt_data_buffer_with_key) {
|
|
const auto key =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(
|
|
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
|
buffer.size(), result);
|
|
|
|
std::string data;
|
|
EXPECT_TRUE(utils::encryption::decrypt_data(key, result, data));
|
|
|
|
EXPECT_EQ(buffer.size(), data.size());
|
|
EXPECT_STREQ(buffer.c_str(), data.c_str());
|
|
}
|
|
|
|
TEST(utils_encryption, decrypt_data_pointer_with_key) {
|
|
const auto key =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(
|
|
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
|
buffer.size(), result);
|
|
|
|
std::string data;
|
|
EXPECT_TRUE(
|
|
utils::encryption::decrypt_data(key, result.data(), result.size(), data));
|
|
|
|
EXPECT_EQ(buffer.size(), data.size());
|
|
EXPECT_STREQ(buffer.c_str(), data.c_str());
|
|
}
|
|
|
|
TEST(utils_encryption, decryption_failure) {
|
|
const auto key =
|
|
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
|
data_buffer result;
|
|
utils::encryption::encrypt_data(
|
|
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
|
buffer.size(), result);
|
|
result[0U] = 0U;
|
|
result[1U] = 1U;
|
|
result[2U] = 2U;
|
|
|
|
std::string data;
|
|
EXPECT_FALSE(utils::encryption::decrypt_data(key, result, data));
|
|
}
|
|
|
|
TEST(utils_encryption, decrypt_file_name) {
|
|
auto &source_file = test::create_random_file(
|
|
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
|
EXPECT_TRUE(source_file);
|
|
if (source_file) {
|
|
stop_type stop_requested{false};
|
|
utils::encryption::encrypting_reader reader(
|
|
"test.dat", source_file.get_path(), stop_requested, token,
|
|
std::nullopt);
|
|
|
|
auto file_name = reader.get_encrypted_file_name();
|
|
|
|
EXPECT_EQ(true, utils::encryption::decrypt_file_name(token, file_name));
|
|
EXPECT_STREQ("test.dat", file_name.c_str());
|
|
}
|
|
}
|
|
|
|
TEST(utils_encryption, decrypt_file_path) {
|
|
auto &source_file = test::create_random_file(
|
|
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
|
EXPECT_TRUE(source_file);
|
|
if (source_file) {
|
|
stop_type stop_requested{false};
|
|
utils::encryption::encrypting_reader reader(
|
|
"test.dat", source_file.get_path(), stop_requested, token, "moose/cow");
|
|
|
|
auto file_path = reader.get_encrypted_file_path();
|
|
|
|
EXPECT_EQ(true, utils::encryption::decrypt_file_path(token, file_path));
|
|
EXPECT_STREQ("/moose/cow/test.dat", file_path.c_str());
|
|
}
|
|
}
|
|
#endif // defined(PROJECT_ENABLE_BOOST)
|
|
} // namespace repertory
|
|
|
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|