updated build system
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				BlockStorage/repertory/pipeline/head There was a failure building this commit
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	BlockStorage/repertory/pipeline/head There was a failure building this commit
				
			This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
| @@ -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: | ||||||
|   | |||||||
							
								
								
									
										255
									
								
								support/include/utils/hash.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								support/include/utils/hash.hpp
									
									
									
									
									
										Normal 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_ | ||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
							
								
								
									
										70
									
								
								support/src/utils/hash.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								support/src/utils/hash.cpp
									
									
									
									
									
										Normal 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) | ||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user