updated build system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit

This commit is contained in:
Scott E. Graves 2024-08-05 19:38:13 -05:00
parent 760a1e4322
commit dca0752189
13 changed files with 910 additions and 337 deletions

View File

@ -1,174 +1,174 @@
// NOLINTBEGIN // NOLINTBEGIN
#ifndef _MACARON_BASE64_H_ #ifndef _MACARON_BASE64_H_
#define _MACARON_BASE64_H_ #define _MACARON_BASE64_H_
/** /**
* The MIT License (MIT) * The MIT License (MIT)
* Copyright (c) 2016 tomykaira * Copyright (c) 2016 tomykaira
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be * The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software. * included in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wunknown-warning-option"
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wuseless-cast" #pragma GCC diagnostic ignored "-Wuseless-cast"
#endif #endif
#include <array> #include <array>
#include <string> #include <string>
#include <vector> #include <vector>
namespace macaron::Base64 { namespace macaron::Base64 {
static std::string Encode(const unsigned char *data, std::size_t len) { static std::string Encode(const unsigned char *data, std::size_t len) {
static constexpr std::array<unsigned char, 64U> sEncodingTable{ static constexpr std::array<unsigned char, 64U> sEncodingTable{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
}; };
auto in_len{len}; auto in_len{len};
std::string ret; std::string ret;
if (in_len > 0) { if (in_len > 0) {
std::size_t out_len{4U * ((in_len + 2U) / 3U)}; std::size_t out_len{4U * ((in_len + 2U) / 3U)};
ret = std::string(out_len, '\0'); ret = std::string(out_len, '\0');
std::size_t i; std::size_t i;
auto *p = reinterpret_cast<unsigned char *>(ret.data()); auto *p = reinterpret_cast<unsigned char *>(ret.data());
for (i = 0U; i < in_len - 2U; i += 3U) { for (i = 0U; i < in_len - 2U; i += 3U) {
*p++ = sEncodingTable[(data[i] >> 2U) & 0x3F]; *p++ = sEncodingTable[(data[i] >> 2U) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4U) | *p++ = sEncodingTable[((data[i] & 0x3) << 4U) |
((int)(data[i + 1U] & 0xF0) >> 4U)]; ((int)(data[i + 1U] & 0xF0) >> 4U)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | *p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) |
((int)(data[i + 2U] & 0xC0) >> 6U)]; ((int)(data[i + 2U] & 0xC0) >> 6U)];
*p++ = sEncodingTable[data[i + 2U] & 0x3F]; *p++ = sEncodingTable[data[i + 2U] & 0x3F];
} }
if (i < in_len) { if (i < in_len) {
*p++ = sEncodingTable[(data[i] >> 2U) & 0x3F]; *p++ = sEncodingTable[(data[i] >> 2U) & 0x3F];
if (i == (in_len - 1U)) { if (i == (in_len - 1U)) {
*p++ = sEncodingTable[((data[i] & 0x3) << 4U)]; *p++ = sEncodingTable[((data[i] & 0x3) << 4U)];
*p++ = '='; *p++ = '=';
} else { } else {
*p++ = sEncodingTable[((data[i] & 0x3) << 4U) | *p++ = sEncodingTable[((data[i] & 0x3) << 4U) |
((int)(data[i + 1U] & 0xF0) >> 4U)]; ((int)(data[i + 1U] & 0xF0) >> 4U)];
*p++ = sEncodingTable[((data[i + 1U] & 0xF) << 2U)]; *p++ = sEncodingTable[((data[i + 1U] & 0xF) << 2U)];
} }
*p++ = '='; *p++ = '=';
} }
} }
return ret; return ret;
} }
[[maybe_unused]] static std::string Encode(std::string_view data) { [[maybe_unused]] static std::string Encode(std::string_view data) {
return Encode(reinterpret_cast<const unsigned char *>(data.data()), return Encode(reinterpret_cast<const unsigned char *>(data.data()),
data.size()); data.size());
} }
[[maybe_unused]] static std::vector<unsigned char> [[maybe_unused]] static std::vector<unsigned char>
Decode(std::string_view input) { Decode(std::string_view input) {
static constexpr std::array<unsigned char, 256> kDecodingTable{ static constexpr std::array<unsigned char, 256> kDecodingTable{
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
}; };
std::vector<unsigned char> out; std::vector<unsigned char> out;
if (not input.empty()) { if (not input.empty()) {
auto in_len{input.size()}; auto in_len{input.size()};
if (in_len % 4U != 0U) { if (in_len % 4U != 0U) {
throw std::runtime_error("Input data size is not a multiple of 4"); throw std::runtime_error("Input data size is not a multiple of 4");
} }
std::size_t out_len{in_len / 4U * 3U}; std::size_t out_len{in_len / 4U * 3U};
if (input[in_len - 1U] == '=') { if (input[in_len - 1U] == '=') {
out_len--; out_len--;
} }
if (input[in_len - 2U] == '=') { if (input[in_len - 2U] == '=') {
out_len--; out_len--;
} }
out.resize(out_len); out.resize(out_len);
for (std::size_t i = 0U, j = 0U; i < in_len;) { for (std::size_t i = 0U, j = 0U; i < in_len;) {
std::uint32_t a = std::uint32_t a =
input.at(i) == '=' input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<unsigned char>(input.at(i++))]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t b = std::uint32_t b =
input.at(i) == '=' input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<unsigned char>(input.at(i++))]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t c = std::uint32_t c =
input.at(i) == '=' input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<unsigned char>(input.at(i++))]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t d = std::uint32_t d =
input.at(i) == '=' input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<unsigned char>(input.at(i++))]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t triple = std::uint32_t triple =
(a << 3U * 6U) + (b << 2U * 6U) + (c << 1U * 6U) + (d << 0U * 6U); (a << 3U * 6U) + (b << 2U * 6U) + (c << 1U * 6U) + (d << 0U * 6U);
if (j < out_len) if (j < out_len)
out[j++] = (triple >> 2U * 8U) & 0xFF; out[j++] = (triple >> 2U * 8U) & 0xFF;
if (j < out_len) if (j < out_len)
out[j++] = (triple >> 1U * 8U) & 0xFF; out[j++] = (triple >> 1U * 8U) & 0xFF;
if (j < out_len) if (j < out_len)
out[j++] = (triple >> 0U * 8U) & 0xFF; out[j++] = (triple >> 0U * 8U) & 0xFF;
} }
} }
return out; return out;
} }
} // namespace macaron::Base64 } // namespace macaron::Base64
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif /* _MACARON_BASE64_H_ */ #endif /* _MACARON_BASE64_H_ */
// NOLINTEND // NOLINTEND

View File

@ -24,6 +24,8 @@
#include "utils/config.hpp" #include "utils/config.hpp"
#include "utils/string.hpp"
namespace repertory::utils::collection { namespace repertory::utils::collection {
template <typename col_t> template <typename col_t>
[[nodiscard]] inline auto [[nodiscard]] inline auto
@ -94,21 +96,6 @@ inline auto remove_element(col_t &collection,
return collection; return collection;
} }
template <typename col_t, typename string_t>
[[nodiscard]] inline auto to_hex_string_t(const col_t &collection) -> string_t {
static_assert(sizeof(typename col_t::value_type) == 1U,
"value_type must be 1 byte in size");
static constexpr const auto mask = 0xFF;
std::basic_stringstream<typename string_t::value_type> stream{};
for (auto &&val : collection) {
stream << std::setfill('0') << std::setw(2) << std::hex
<< (static_cast<std::uint32_t>(val) & mask);
}
return stream.str();
}
template <typename val_t> template <typename val_t>
inline auto from_hex_string(std::string_view str, val_t &val) -> bool { inline auto from_hex_string(std::string_view str, val_t &val) -> bool {
return from_hex_string_t<val_t, std::string>(str, val); return from_hex_string_t<val_t, std::string>(str, val);
@ -121,12 +108,22 @@ inline auto from_hex_string(std::wstring_view str, val_t &val) -> bool {
template <typename col_t> template <typename col_t>
inline auto to_hex_string(const col_t &collection) -> std::string { inline auto to_hex_string(const col_t &collection) -> std::string {
return to_hex_string_t<col_t, std::string>(collection); static_assert(sizeof(typename col_t::value_type) == 1U,
"value_type must be 1 byte in size");
static constexpr const auto mask = 0xFF;
std::stringstream stream{};
for (auto &&val : collection) {
stream << std::setfill('0') << std::setw(2) << std::hex
<< (static_cast<std::uint32_t>(val) & mask);
}
return stream.str();
} }
template <typename col_t> template <typename col_t>
inline auto to_hex_wstring(const col_t &collection) -> std::wstring { inline auto to_hex_wstring(const col_t &collection) -> std::wstring {
return to_hex_string_t<col_t, std::wstring>(collection); return utils::string::from_utf8(to_hex_string<col_t>(collection));
} }
} // namespace repertory::utils::collection } // namespace repertory::utils::collection

View File

@ -90,10 +90,6 @@ get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port) -> bool; std::uint16_t &available_port) -> bool;
#endif // defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto resolve_variables(std::string str) -> std::string;
[[nodiscard]] auto resolve_variables(std::wstring_view str) -> std::wstring;
template <typename result_t, typename data_t> template <typename result_t, typename data_t>
inline constexpr auto divide_with_ceiling(result_t numerator, inline constexpr auto divide_with_ceiling(result_t numerator,
data_t denominator) -> result_t { data_t denominator) -> result_t {

View File

@ -25,31 +25,46 @@
#include "utils/config.hpp" #include "utils/config.hpp"
namespace repertory::utils::encryption { #include "utils/hash.hpp"
using hash_256_t = std::array<unsigned char, 32U>;
using hash_256_func_t = std::function<hash_256_t(std::string_view)>;
using key_type = std::array<unsigned char, 32U>;
namespace repertory::utils::encryption {
inline constexpr const std::uint32_t encryption_header_size{ inline constexpr const std::uint32_t encryption_header_size{
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES + crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +
crypto_aead_xchacha20poly1305_IETF_ABYTES, crypto_aead_xchacha20poly1305_IETF_ABYTES,
}; };
[[nodiscard]] auto generate_key(std::string_view encryption_token) -> key_type; template <typename hash_t>
[[nodiscard]] inline auto default_create_hash(std::string_view) -> hash_t;
template <typename hash_t>
[[nodiscard]] inline auto default_create_hash(std::wstring_view) -> hash_t;
template <typename hash_t>
inline auto generate_key(
std::string_view password,
std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher = std::nullopt) -> hash_t;
template <typename hash_t>
inline auto generate_key(
std::wstring_view password,
std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher = std::nullopt) -> hash_t;
#if defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto decrypt_data( [[nodiscard]] auto decrypt_data(std::string_view password,
std::string_view data, std::string_view password, std::string_view data) -> data_buffer;
std::optional<hash_256_func_t> hasher = std::nullopt) -> data_buffer;
[[nodiscard]] auto encrypt_data( [[nodiscard]] auto encrypt_data(std::string_view password,
std::string_view data, std::string_view password, std::string_view data) -> data_buffer;
std::optional<hash_256_func_t> hasher = std::nullopt) -> data_buffer;
template <typename result> template <typename result, typename arr_t, std::size_t arr_size>
[[nodiscard]] inline auto [[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
decrypt_data(const key_type &key, const unsigned char *buffer, const unsigned char *buffer,
std::size_t buffer_size, result &res) -> bool { std::size_t buffer_size,
result &res) -> bool {
if (buffer_size > encryption_header_size) { if (buffer_size > encryption_header_size) {
const std::uint32_t size = const std::uint32_t size =
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size)); boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size));
@ -65,34 +80,43 @@ decrypt_data(const key_type &key, const unsigned char *buffer,
return false; return false;
} }
template <typename buffer, typename result> template <typename buffer, typename result, typename arr_t,
[[nodiscard]] inline auto decrypt_data(const key_type &key, const buffer &buf, std::size_t arr_size>
result &res) -> bool { [[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
const buffer &buf, result &res) -> bool {
return decrypt_data<result>( return decrypt_data<result>(
key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(), key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(),
res); res);
} }
template <typename buffer, typename result> template <typename buffer, typename result, typename hash_t = hash_256_t>
[[nodiscard]] inline auto decrypt_data(std::string_view encryption_token, [[nodiscard]] inline auto decrypt_data(
const buffer &buf, result &res) -> bool { std::string_view password, const buffer &buf, result &res,
return decrypt_data<buffer, result>(generate_key(encryption_token), buf, res); std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher = std::nullopt) -> bool {
return decrypt_data<buffer, result>(generate_key(password, hasher), buf, res);
} }
template <typename result> template <typename result, typename hash_t = hash_256_t>
[[nodiscard]] inline auto [[nodiscard]] inline auto decrypt_data(
decrypt_data(std::string_view encryption_token, const unsigned char *buffer, std::string_view password, const unsigned char *buffer,
std::size_t buffer_size, result &res) -> bool { std::size_t buffer_size, result &res,
return decrypt_data<result>(generate_key(encryption_token), buffer,
std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher = std::nullopt) -> bool {
return decrypt_data<result>(generate_key(password, hasher), buffer,
buffer_size, res); buffer_size, res);
} }
template <typename result> template <typename result, typename arr_t, std::size_t arr_size>
inline void inline void
encrypt_data(const std::array<unsigned char, encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const key_type &key, const unsigned char *buffer, const std::array<arr_t, arr_size> &key,
std::size_t buffer_size, result &res) { const unsigned char *buffer, std::size_t buffer_size,
result &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{}; std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{};
const std::uint32_t size = boost::endian::native_to_big( const std::uint32_t size = boost::endian::native_to_big(
@ -113,47 +137,116 @@ encrypt_data(const std::array<unsigned char,
std::memcpy(&res[iv.size()], mac.data(), mac.size()); std::memcpy(&res[iv.size()], mac.data(), mac.size());
} }
template <typename result> template <typename result, typename s, std::size_t t>
inline void encrypt_data(const key_type &key, const unsigned char *buffer, inline void encrypt_data(const std::array<s, t> &key,
std::size_t buffer_size, result &res) { const unsigned char *buffer, std::size_t buffer_size,
result &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> iv{}; std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> iv{};
randombytes_buf(iv.data(), iv.size()); randombytes_buf(iv.data(), iv.size());
encrypt_data<result>(iv, key, buffer, buffer_size, res); encrypt_data<result>(iv, key, buffer, buffer_size, res);
} }
template <typename result> template <typename result, typename hash_t = hash_256_t>
inline void encrypt_data(std::string_view encryption_token, inline void encrypt_data(
const unsigned char *buffer, std::size_t buffer_size, std::string_view password, const unsigned char *buffer,
result &res) { std::size_t buffer_size, result &res,
encrypt_data<result>(generate_key(encryption_token), buffer, buffer_size, std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher = std::nullopt) {
encrypt_data<result>(generate_key(password, hasher), buffer, buffer_size,
res); res);
} }
template <typename buffer, typename result> template <typename buffer, typename result, typename hash_t = hash_256_t>
inline void encrypt_data(std::string_view encryption_token, const buffer &buf, inline void encrypt_data(
result &res) { std::string_view password, const buffer &buf, result &res,
encrypt_data<result>(generate_key(encryption_token), std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher = std::nullopt) {
encrypt_data<result>(generate_key(password, hasher),
reinterpret_cast<const unsigned char *>(buf.data()), reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res); buf.size(), res);
} }
template <typename buffer, typename result> template <typename buffer, typename result, typename s, std::size_t t>
inline void encrypt_data(const key_type &key, const buffer &buf, result &res) { inline void encrypt_data(const std::array<s, t> &key, const buffer &buf,
result &res) {
encrypt_data<result>(key, reinterpret_cast<const unsigned char *>(buf.data()), encrypt_data<result>(key, reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res); buf.size(), res);
} }
template <typename buffer, typename result> template <typename buffer, typename result, typename s, std::size_t t>
inline void inline void
encrypt_data(const std::array<unsigned char, encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const key_type &key, const buffer &buf, result &res) { const std::array<s, t> &key, const buffer &buf, result &res) {
encrypt_data<result>(iv, key, encrypt_data<result>(iv, key,
reinterpret_cast<const unsigned char *>(buf.data()), reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res); buf.size(), res);
} }
#endif // defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_BOOST)
template <>
inline auto
default_create_hash<hash_256_t>(std::string_view data) -> hash_256_t {
return create_hash_sha256(data);
}
template <>
inline auto
default_create_hash<hash_256_t>(std::wstring_view data) -> hash_256_t {
return create_hash_sha256(data);
}
template <>
inline auto
default_create_hash<hash_384_t>(std::string_view data) -> hash_384_t {
return create_hash_blake2b_384(data);
}
template <>
inline auto
default_create_hash<hash_384_t>(std::wstring_view data) -> hash_384_t {
return create_hash_blake2b_384(data);
}
template <>
inline auto
default_create_hash<hash_512_t>(std::string_view data) -> hash_512_t {
return create_hash_sha512(data);
}
template <>
inline auto
default_create_hash<hash_512_t>(std::wstring_view data) -> hash_512_t {
return create_hash_sha512(data);
}
template <typename hash_t>
inline auto generate_key(
std::string_view password,
std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher) -> hash_t {
return hasher.has_value() ? (*hasher)(reinterpret_cast<const unsigned char *>(
password.data()),
password.size())
: default_create_hash<hash_t>(password);
}
template <typename hash_t>
inline auto generate_key(
std::wstring_view password,
std::optional<
std::function<hash_t(const unsigned char *data, std::size_t size)>>
hasher) -> hash_t {
return hasher.has_value()
? (*hasher)(
reinterpret_cast<const unsigned char *>(password.data()),
password.size() * sizeof(std::wstring_view::value_type))
: default_create_hash<hash_t>(password);
}
} // namespace repertory::utils::encryption } // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM) #endif // defined(PROJECT_ENABLE_LIBSODIUM)

View File

@ -74,21 +74,21 @@ public:
[[nodiscard]] auto truncate(std::size_t size) -> bool; [[nodiscard]] auto truncate(std::size_t size) -> bool;
#if defined(PROJECT_ENABLE_JSON)
[[nodiscard]] auto write(const nlohmann::json &data,
std::size_t *total_written = nullptr) -> bool {
auto str_data = data.dump();
return write_(reinterpret_cast<const unsigned char *>(str_data.c_str()),
str_data.size(), 0U, total_written);
}
#endif // defined(PROJECT_ENABLE_JSON)
[[nodiscard]] auto write(const data_buffer &data, std::uint64_t offset, [[nodiscard]] auto write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool { std::size_t *total_written = nullptr) -> bool {
return write_(reinterpret_cast<const unsigned char *>(data.data()), return write_(reinterpret_cast<const unsigned char *>(data.data()),
data.size(), offset, total_written); data.size(), offset, total_written);
} }
#if defined(PROJECT_ENABLE_JSON)
[[nodiscard]] auto write_json(const nlohmann::json &data,
std::size_t *total_written = nullptr) -> bool {
auto str_data = data.dump();
return write_(reinterpret_cast<const unsigned char *>(str_data.c_str()),
str_data.size(), 0U, total_written);
}
#endif // defined(PROJECT_ENABLE_JSON)
[[nodiscard]] operator bool() const { return stream_.is_open(); } [[nodiscard]] operator bool() const { return stream_.is_open(); }
private: private:

View File

@ -0,0 +1,255 @@
/*
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.
*/
#ifndef REPERTORY_INCLUDE_UTILS_HASH_HPP_
#define REPERTORY_INCLUDE_UTILS_HASH_HPP_
#if defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/config.hpp"
namespace repertory::utils::encryption {
using hash_256_t = std::array<unsigned char, 32U>;
using hash_384_t = std::array<unsigned char, 48U>;
using hash_512_t = std::array<unsigned char, 64U>;
[[nodiscard]] auto create_hash_blake2b_256(std::string_view data) -> hash_256_t;
[[nodiscard]] auto
create_hash_blake2b_256(std::wstring_view data) -> hash_256_t;
[[nodiscard]] auto create_hash_blake2b_384(std::string_view data) -> hash_384_t;
[[nodiscard]] auto
create_hash_blake2b_384(std::wstring_view data) -> hash_384_t;
[[nodiscard]] auto create_hash_blake2b_512(std::string_view data) -> hash_512_t;
[[nodiscard]] auto
create_hash_blake2b_512(std::wstring_view data) -> hash_512_t;
template <typename char_t, typename hash_t>
[[nodiscard]] auto
create_hash_blake2b_t(std::basic_string_view<char_t> data) -> hash_t;
template <typename hash_t>
[[nodiscard]] auto create_hash_blake2b_t(const data_buffer &data) -> hash_t;
template <typename char_t, typename hash_t>
[[nodiscard]] auto create_hash_blake2b_t(
const std::vector<std::basic_string<char_t>> &data) -> hash_t;
template <typename arr_t, std::size_t arr_size>
[[nodiscard]] auto
create_hash_blake2b_t(const std::vector<std::array<arr_t, arr_size>> &data)
-> std::array<arr_t, arr_size>;
[[nodiscard]] auto create_hash_sha256(std::string_view data) -> hash_256_t;
[[nodiscard]] auto create_hash_sha256(std::wstring_view data) -> hash_256_t;
[[nodiscard]] auto create_hash_sha512(std::string_view data) -> hash_512_t;
[[nodiscard]] auto create_hash_sha512(std::wstring_view data) -> hash_512_t;
template <typename char_t>
[[nodiscard]] auto
create_hash_sha256_t(std::basic_string_view<char_t> data) -> hash_256_t;
template <typename char_t>
[[nodiscard]] auto create_hash_sha512_t(std::basic_string_view<char_t> data)
-> repertory::utils::encryption::hash_512_t;
template <typename hash_t>
auto create_hash_blake2b_t(const data_buffer &data) -> hash_t {
hash_t hash{};
crypto_generichash_blake2b_state state{};
auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
if (res != 0) {
throw std::runtime_error("failed to initialize blake2b|" +
std::to_string(res));
}
res = crypto_generichash_blake2b_update(
&state, reinterpret_cast<const unsigned char *>(data.data()),
data.size() * sizeof(data_buffer::value_type));
if (res != 0) {
throw std::runtime_error("failed to update blake2b|" + std::to_string(res));
}
res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
if (res != 0) {
throw std::runtime_error("failed to finalize blake2b|" +
std::to_string(res));
}
return hash;
}
template <typename arr_t, std::size_t arr_size>
auto create_hash_blake2b_t(const std::vector<std::array<arr_t, arr_size>> &data)
-> std::array<arr_t, arr_size> {
using hash_t = std::array<arr_t, arr_size>;
hash_t hash{};
crypto_generichash_blake2b_state state{};
auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
if (res != 0) {
throw std::runtime_error("failed to initialize blake2b|" +
std::to_string(res));
}
for (const auto &item : data) {
res = crypto_generichash_blake2b_update(
&state, reinterpret_cast<const unsigned char *>(item.data()),
item.size());
if (res != 0) {
throw std::runtime_error("failed to update blake2b|" +
std::to_string(res));
}
}
res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
if (res != 0) {
throw std::runtime_error("failed to finalize blake2b|" +
std::to_string(res));
}
return hash;
}
template <typename char_t, typename hash_t>
auto create_hash_blake2b_t(const std::vector<std::basic_string<char_t>> &data)
-> hash_t {
hash_t hash{};
crypto_generichash_blake2b_state state{};
auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
if (res != 0) {
throw std::runtime_error("failed to initialize blake2b|" +
std::to_string(res));
}
for (const auto &item : data) {
res = crypto_generichash_blake2b_update(
&state, reinterpret_cast<const unsigned char *>(item.data()),
item.size() * sizeof(char_t));
if (res != 0) {
throw std::runtime_error("failed to update blake2b|" +
std::to_string(res));
}
}
res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
if (res != 0) {
throw std::runtime_error("failed to finalize blake2b|" +
std::to_string(res));
}
return hash;
}
template <typename char_t, typename hash_t>
auto create_hash_blake2b_t(std::basic_string_view<char_t> data) -> hash_t {
hash_t hash{};
crypto_generichash_blake2b_state state{};
auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
if (res != 0) {
throw std::runtime_error("failed to initialize blake2b|" +
std::to_string(res));
}
res = crypto_generichash_blake2b_update(
&state, reinterpret_cast<const unsigned char *>(data.data()),
data.size() * sizeof(char_t));
if (res != 0) {
throw std::runtime_error("failed to update blake2b|" + std::to_string(res));
}
res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
if (res != 0) {
throw std::runtime_error("failed to finalize blake2b|" +
std::to_string(res));
}
return hash;
}
template <typename char_t>
auto create_hash_sha256_t(std::basic_string_view<char_t> data)
-> repertory::utils::encryption::hash_256_t {
repertory::utils::encryption::hash_256_t hash{};
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(data.data()),
data.size() * sizeof(char_t));
if (res != 0) {
throw std::runtime_error("failed to update sha256|" + std::to_string(res));
}
res = crypto_hash_sha256_final(&state, hash.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
return hash;
}
template <typename char_t>
auto create_hash_sha512_t(std::basic_string_view<char_t> data)
-> repertory::utils::encryption::hash_512_t {
repertory::utils::encryption::hash_512_t hash{};
crypto_hash_sha512_state state{};
auto res = crypto_hash_sha512_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha512|" +
std::to_string(res));
}
res = crypto_hash_sha512_update(
&state, reinterpret_cast<const unsigned char *>(data.data()),
data.size() * sizeof(char_t));
if (res != 0) {
throw std::runtime_error("failed to update sha512|" + std::to_string(res));
}
res = crypto_hash_sha512_final(&state, hash.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha512|" +
std::to_string(res));
}
return hash;
}
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#endif // REPERTORY_INCLUDE_UTILS_HASH_HPP_

View File

@ -86,12 +86,21 @@ auto create_uuid_wstring() -> std::wstring {
#if defined(PROJECT_ENABLE_LIBSODIUM) #if defined(PROJECT_ENABLE_LIBSODIUM)
auto generate_random_string(std::size_t length) -> std::string { auto generate_random_string(std::size_t length) -> std::string {
std::string ret; std::string ret;
if (length == 0U) {
return ret;
}
ret.resize(length); ret.resize(length);
for (std::size_t i = 0U; i < length; i++) { for (auto &ch : ret) {
do { std::array<unsigned int, 3U> random_list{
ret[i] = static_cast<char>(generate_random<std::uint8_t>() % 74 + 48); generate_random_between(0U, 57U),
} while (((ret.at(i) >= 91) && (ret.at(i) <= 96)) || generate_random_between(65U, 90U),
((ret.at(i) >= 58) && (ret.at(i) <= 64))); generate_random_between(97U, 255U),
};
ch = static_cast<char>(
random_list.at(repertory::utils::generate_random_between(0U, 2U)) %
74U +
48U);
} }
return ret; return ret;
@ -118,6 +127,10 @@ auto get_environment_variable(std::wstring_view variable) -> std::wstring {
#if defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_BOOST)
auto get_next_available_port(std::uint16_t first_port, auto get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port) -> bool { std::uint16_t &available_port) -> bool {
if (first_port == 0U) {
return false;
}
using namespace boost::asio; using namespace boost::asio;
using ip::tcp; using ip::tcp;
@ -141,13 +154,4 @@ auto get_next_available_port(std::uint16_t first_port,
return not error_code; return not error_code;
} }
#endif // defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_BOOST)
auto resolve_variables(std::string str) -> std::string {
return utils::path::absolute(str);
}
auto resolve_variables(std::wstring_view str) -> std::wstring {
return utils::string::from_utf8(
resolve_variables(utils::string::to_utf8(str)));
}
} // namespace repertory::utils } // namespace repertory::utils

View File

@ -22,33 +22,11 @@
#include "utils/encryption.hpp" #include "utils/encryption.hpp"
#if defined(PROJECT_ENABLE_LIBSODIUM) #if defined(PROJECT_ENABLE_LIBSODIUM)
namespace {
using nonce_t =
std::array<unsigned char, crypto_aead_xchacha20poly1305_ietf_NPUBBYTES>;
static constexpr const auto nonce_size{sizeof(nonce_t)};
[[nodiscard]] static auto create_hash_256(std::string_view data)
-> repertory::utils::encryption::hash_256_t {
repertory::utils::encryption::hash_256_t hash{};
crypto_generichash_blake2b_state state{};
crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
crypto_generichash_blake2b_update(
&state, reinterpret_cast<const unsigned char *>(data.data()),
data.size());
crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
return hash;
}
} // namespace
namespace repertory::utils::encryption { namespace repertory::utils::encryption {
#if defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_BOOST)
auto decrypt_data(std::string_view data, std::string_view password, auto decrypt_data(std::string_view password,
std::optional<hash_256_func_t> hasher) -> data_buffer { std::string_view data) -> data_buffer {
auto key = auto key = generate_key<hash_256_t>(password);
hasher.has_value() ? (*hasher)(password) : create_hash_256(password);
data_buffer buf{}; data_buffer buf{};
if (not decrypt_data(key, if (not decrypt_data(key,
@ -60,10 +38,9 @@ auto decrypt_data(std::string_view data, std::string_view password,
return buf; return buf;
} }
auto encrypt_data(std::string_view data, std::string_view password, auto encrypt_data(std::string_view password,
std::optional<hash_256_func_t> hasher) -> data_buffer { std::string_view data) -> data_buffer {
auto key = auto key = generate_key<hash_256_t>(password);
hasher.has_value() ? (*hasher)(password) : create_hash_256(password);
data_buffer buf{}; data_buffer buf{};
encrypt_data(key, reinterpret_cast<const unsigned char *>(data.data()), encrypt_data(key, reinterpret_cast<const unsigned char *>(data.data()),
@ -72,30 +49,6 @@ auto encrypt_data(std::string_view data, std::string_view password,
return buf; return buf;
} }
#endif // defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_BOOST)
auto generate_key(std::string_view encryption_token) -> key_type {
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(encryption_token.data()),
encryption_token.size());
if (res != 0) {
throw std::runtime_error("failed to update sha256|" + std::to_string(res));
}
key_type ret{};
res = crypto_hash_sha256_final(&state, ret.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
return ret;
}
} // namespace repertory::utils::encryption } // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM) #endif // defined(PROJECT_ENABLE_LIBSODIUM)

View File

@ -276,7 +276,7 @@ auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
if (password.has_value()) { if (password.has_value()) {
auto decrypted_data = auto decrypted_data =
utils::encryption::decrypt_data(json_text, *password); utils::encryption::decrypt_data(*password, json_text);
json_text = {decrypted_data.begin(), decrypted_data.end()}; json_text = {decrypted_data.begin(), decrypted_data.end()};
} }
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
@ -322,7 +322,7 @@ auto write_json_file(std::string_view path,
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
if (password.has_value()) { if (password.has_value()) {
return file.write(utils::encryption::encrypt_data(data.dump(), *password), return file.write(utils::encryption::encrypt_data(*password, data.dump()),
0U); 0U);
} }
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)

View File

@ -0,0 +1,70 @@
/*
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 "utils/hash.hpp"
#if defined(PROJECT_ENABLE_LIBSODIUM)
namespace {} // namespace
namespace repertory::utils::encryption {
auto create_hash_blake2b_256(std::string_view data) -> hash_256_t {
return create_hash_blake2b_t<char, hash_256_t>(data);
}
auto create_hash_blake2b_256(std::wstring_view data) -> hash_256_t {
return create_hash_blake2b_t<wchar_t, hash_256_t>(data);
}
auto create_hash_blake2b_384(std::string_view data) -> hash_384_t {
return create_hash_blake2b_t<char, hash_384_t>(data);
}
auto create_hash_blake2b_384(std::wstring_view data) -> hash_384_t {
return create_hash_blake2b_t<wchar_t, hash_384_t>(data);
}
auto create_hash_blake2b_512(std::string_view data) -> hash_512_t {
return create_hash_blake2b_t<char, hash_512_t>(data);
}
auto create_hash_blake2b_512(std::wstring_view data) -> hash_512_t {
return create_hash_blake2b_t<wchar_t, hash_512_t>(data);
}
auto create_hash_sha256(std::string_view data) -> hash_256_t {
return create_hash_sha256_t<char>(data);
}
auto create_hash_sha256(std::wstring_view data) -> hash_256_t {
return create_hash_sha256_t<wchar_t>(data);
}
auto create_hash_sha512(std::string_view data) -> hash_512_t {
return create_hash_sha512_t<char>(data);
}
auto create_hash_sha512(std::wstring_view data) -> hash_512_t {
return create_hash_sha512_t<wchar_t>(data);
}
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM)

View File

@ -20,10 +20,12 @@
SOFTWARE. SOFTWARE.
*/ */
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <utils/collection.hpp>
#include "utils/common.hpp" #include "utils/common.hpp"
#include "utils/collection.hpp"
#include "utils/string.hpp"
namespace repertory { namespace repertory {
TEST(utils_common, calculate_read_size) { TEST(utils_common, calculate_read_size) {
auto read_size = utils::calculate_read_size(0U, 0U, 0U); auto read_size = utils::calculate_read_size(0U, 0U, 0U);
@ -240,4 +242,72 @@ TEST(utils_common, generate_random_between_throws_error_on_invalid_range) {
}, },
std::range_error); std::range_error);
} }
#if defined(PROJECT_ENABLE_LIBSODIUM)
TEST(utils_common, generate_random_string) {
static constexpr const auto max_iterations{10000L};
const auto test_string = [](auto str) {
static std::vector<decltype(str)> list{};
EXPECT_FALSE(utils::collection::includes(list, str));
list.push_back(str);
EXPECT_EQ(16U, str.size());
for (auto &&ch : str) {
auto ch_int = static_cast<std::uint32_t>(ch);
EXPECT_GE(ch_int, 48U);
EXPECT_LE(ch_int, 73U + 48U);
}
};
for (std::size_t idx = 0U; idx < max_iterations; ++idx) {
test_string(utils::generate_random_string(16U));
test_string(utils::generate_random_wstring(16U));
}
}
TEST(utils_common, generate_random_string_for_zero_length) {
EXPECT_TRUE(utils::generate_random_string(0U).empty());
EXPECT_TRUE(utils::generate_random_wstring(0U).empty());
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
TEST(utils_common, get_environment_variable) {
static constexpr const std::string path_env{"PATH"};
std::string path;
#if defined(_WIN32)
path.resize(MAX_PATH + 1U);
auto size = ::GetEnvironmentVariableA(path_env.c_str(), path.data(), 0U);
path.resize(size);
::GetEnvironmentVariableA(path_env.c_str(), path.data(),
static_cast<DWORD>(path.size()));
#else // !defined(_WIN32)
path = std::getenv(path_env.c_str());
#endif // defined(_WIN32)
EXPECT_STREQ(path.c_str(), utils::get_environment_variable(path_env).c_str());
EXPECT_STREQ(
utils::string::from_utf8(path).c_str(),
utils::get_environment_variable(utils::string::from_utf8(path_env))
.c_str());
}
#if defined(PROJECT_ENABLE_BOOST)
TEST(utils_common, get_next_available_port) {
std::uint16_t available_port{};
for (std::uint16_t port = 1U; port < 65535; ++port) {
EXPECT_TRUE(utils::get_next_available_port(port, available_port));
EXPECT_GE(available_port, port);
}
}
TEST(utils_common, get_next_available_port_fails_if_starting_point_is_zero) {
std::uint16_t available_port{};
EXPECT_FALSE(utils::get_next_available_port(0U, available_port));
EXPECT_EQ(0U, available_port);
}
#endif // defined(PROJECT_ENABLE_BOOST)
} // namespace repertory } // namespace repertory

View File

@ -19,7 +19,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM)
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -27,8 +27,117 @@
#include "utils/encryption.hpp" #include "utils/encryption.hpp"
namespace repertory { namespace repertory {
static const std::string token{"moose"};
static const std::wstring token_w{L"moose"};
TEST(utils_encryption, generate_key) {
auto key1 =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
EXPECT_STREQ(
"182072537ada59e4d6b18034a80302ebae935f66adbdf0f271d3d36309c2d481",
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);
EXPECT_STREQ(
L"590ac70125bec4501172937f6a2cbdeb22a87b5e40d5595eccd06b2b20548d8f",
utils::collection::to_hex_wstring(key1_w).c_str());
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_sha256) {
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_sha256(
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_sha256(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, [](auto &&data, auto &&size) -> auto {
return utils::encryption::create_hash_sha256(
std::string_view(reinterpret_cast<const char *>(data), size));
});
EXPECT_STREQ(
"182072537ada59e4d6b18034a80302ebae935f66adbdf0f271d3d36309c2d481",
utils::collection::to_hex_string(key1).c_str());
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_NE(key1, key2);
EXPECT_STREQ(
"ab4a0b004e824962913f7c0f79582b6ec7a3b8726426ca61d1a0a28ce5049e96",
utils::collection::to_hex_string(key2).c_str());
auto key1_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
token_w, [](auto &&data, auto &&size) -> auto {
return utils::encryption::create_hash_sha256(std::wstring_view(
reinterpret_cast<const wchar_t *>(data), size / sizeof(wchar_t)));
});
EXPECT_STREQ(
L"590ac70125bec4501172937f6a2cbdeb22a87b5e40d5595eccd06b2b20548d8f",
utils::collection::to_hex_wstring(key1_w).c_str());
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_NE(key1_w, key2_w);
EXPECT_STREQ(
L"0392d95ed3eee9772fbb9af68fedf829a8eb0adbe8575d9691cc9a752196766a",
utils::collection::to_hex_wstring(key2_w).c_str());
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 const std::string buffer = "cow moose dog chicken";
static const std::string token = "moose";
static void test_encrypted_result(const data_buffer &result) { static void test_encrypted_result(const data_buffer &result) {
EXPECT_EQ(buffer.size() + utils::encryption::encryption_header_size, EXPECT_EQ(buffer.size() + utils::encryption::encryption_header_size,
@ -39,14 +148,6 @@ static void test_encrypted_result(const data_buffer &result) {
EXPECT_STREQ(buffer.c_str(), data.c_str()); EXPECT_STREQ(buffer.c_str(), data.c_str());
} }
TEST(utils_encryption, generate_key) {
const auto key = utils::encryption::generate_key(token);
const auto str = utils::collection::to_hex_string(key);
EXPECT_STREQ(
"182072537ada59e4d6b18034a80302ebae935f66adbdf0f271d3d36309c2d481",
str.c_str());
}
TEST(utils_encryption, encrypt_data_buffer) { TEST(utils_encryption, encrypt_data_buffer) {
data_buffer result; data_buffer result;
utils::encryption::encrypt_data(token, buffer, result); utils::encryption::encrypt_data(token, buffer, result);
@ -54,7 +155,8 @@ TEST(utils_encryption, encrypt_data_buffer) {
} }
TEST(utils_encryption, encrypt_data_buffer_with_key) { TEST(utils_encryption, encrypt_data_buffer_with_key) {
const auto key = utils::encryption::generate_key(token); const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
data_buffer result; data_buffer result;
utils::encryption::encrypt_data(key, buffer, result); utils::encryption::encrypt_data(key, buffer, result);
test_encrypted_result(result); test_encrypted_result(result);
@ -69,7 +171,8 @@ TEST(utils_encryption, encrypt_data_pointer) {
} }
TEST(utils_encryption, encrypt_data_pointer_with_key) { TEST(utils_encryption, encrypt_data_pointer_with_key) {
const auto key = utils::encryption::generate_key(token); const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
data_buffer result; data_buffer result;
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
key, reinterpret_cast<const unsigned char *>(buffer.data()), key, reinterpret_cast<const unsigned char *>(buffer.data()),
@ -78,7 +181,8 @@ TEST(utils_encryption, encrypt_data_pointer_with_key) {
} }
TEST(utils_encryption, decrypt_data_pointer) { TEST(utils_encryption, decrypt_data_pointer) {
const auto key = utils::encryption::generate_key(token); const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
data_buffer result; data_buffer result;
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
key, reinterpret_cast<const unsigned char *>(buffer.data()), key, reinterpret_cast<const unsigned char *>(buffer.data()),
@ -93,7 +197,8 @@ TEST(utils_encryption, decrypt_data_pointer) {
} }
TEST(utils_encryption, decrypt_data_buffer_with_key) { TEST(utils_encryption, decrypt_data_buffer_with_key) {
const auto key = utils::encryption::generate_key(token); const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
data_buffer result; data_buffer result;
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
key, reinterpret_cast<const unsigned char *>(buffer.data()), key, reinterpret_cast<const unsigned char *>(buffer.data()),
@ -107,7 +212,8 @@ TEST(utils_encryption, decrypt_data_buffer_with_key) {
} }
TEST(utils_encryption, decrypt_data_pointer_with_key) { TEST(utils_encryption, decrypt_data_pointer_with_key) {
const auto key = utils::encryption::generate_key(token); const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
data_buffer result; data_buffer result;
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
key, reinterpret_cast<const unsigned char *>(buffer.data()), key, reinterpret_cast<const unsigned char *>(buffer.data()),
@ -122,7 +228,8 @@ TEST(utils_encryption, decrypt_data_pointer_with_key) {
} }
TEST(utils_encryption, decryption_failure) { TEST(utils_encryption, decryption_failure) {
const auto key = utils::encryption::generate_key(token); const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
data_buffer result; data_buffer result;
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
key, reinterpret_cast<const unsigned char *>(buffer.data()), key, reinterpret_cast<const unsigned char *>(buffer.data()),
@ -134,6 +241,7 @@ TEST(utils_encryption, decryption_failure) {
std::string data; std::string data;
EXPECT_FALSE(utils::encryption::decrypt_data(key, result, data)); EXPECT_FALSE(utils::encryption::decrypt_data(key, result, data));
} }
#endif // defined(PROJECT_ENABLE_BOOST)
} // namespace repertory } // namespace repertory
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM)

View File

@ -304,4 +304,31 @@ TEST(utils_path, absolute) {
// path = utils::path::absolute("~/.local"); // path = utils::path::absolute("~/.local");
} }
TEST(utils_path, absolute_can_resolve_path_variables) {
std::string home{};
#if defined(_WIN32)
home.resize(MAX_PATH + 1U);
auto size = ::GetEnvironmentVariableA("USERPROFILE", home.data(), 0U);
home.resize(size);
::GetEnvironmentVariableA("USERPROFILE", home.data(),
static_cast<DWORD>(home.size()));
home = utils::path::absolute(home);
auto expanded_str = utils::path::absolute("%USERPROFILE%");
EXPECT_STREQ(home.c_str(), expanded_str.c_str());
expanded_str = utils::path::absolute("~");
EXPECT_STREQ(home.c_str(), expanded_str.c_str());
EXPECT_STREQ((home + home).c_str(), expanded_str.c_str());
#else // !defined(_WIN32)
home = std::getenv("HOME");
home = utils::path::absolute(home);
auto expanded_str = utils::path::absolute("~");
EXPECT_STREQ(home.c_str(), expanded_str.c_str());
#endif // defined(_WIN32)
}
} // namespace repertory } // namespace repertory