mirror of https://github.com/infosecn1nja/C3.git
Upgrade ByteVector to new version.
parent
37e357fc21
commit
fc53b803ae
|
@ -49,6 +49,11 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)CppCodec\base32_default_crockford.hpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)CppCodec\base64_default_rfc4648.hpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)CppRestSdk\include\cpprest\http_client.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteArray.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteVector.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteView.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\Utils.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)json\json.hpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)libSodium\include\sodium.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Interfaces\Channels\Slack.h" />
|
||||
|
@ -63,10 +68,6 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Interfaces\Peripherals\Mock.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\PrecompiledHeader.hpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Sdk.hpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteArray.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteVector.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteView.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Compression.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Encryption.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Hash.h" />
|
||||
|
|
|
@ -83,14 +83,15 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\WinTools\StructuredExceptionHandling.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)C3_BUILD_VERSION_HASH_PART.hxx" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\WinTools\InjectionBuffer.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteArray.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteVector.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteView.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Utils.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Interfaces\Peripherals\Grunt.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)zlib\include\zconf.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)zlib\include\zlib.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Compression.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\Utils.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteView.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteVector.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\ByteConverter\ByteArray.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,6 +1,8 @@
|
|||
#include "StdAfx.h"
|
||||
#include "Beacon.h"
|
||||
|
||||
using namespace FSecure::Literals;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FSecure::C3::Interfaces::Peripherals::Beacon::Beacon(ByteView arguments)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
namespace FSecure
|
||||
{
|
||||
|
|
|
@ -1,418 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <filesystem>
|
||||
|
||||
#include "ByteView.h"
|
||||
|
||||
/// Example code of specializing ByteConverter for custom type A.
|
||||
/// struct A
|
||||
/// {
|
||||
/// uint16_t m_a, m_b;
|
||||
///
|
||||
/// A(uint16_t a, uint16_t b) : m_a(a), m_b(b) {}
|
||||
/// };
|
||||
///
|
||||
/// namespace FSecure
|
||||
/// {
|
||||
/// template <>
|
||||
/// struct ByteConverter<A>
|
||||
/// {
|
||||
/// static ByteVector To(A const& a)
|
||||
/// {
|
||||
/// return ByteVector::Create(a.m_a, a.m_b);
|
||||
/// }
|
||||
///
|
||||
/// static size_t Size(A const& a)
|
||||
/// {
|
||||
/// return 2 * sizeof(uint16_t);
|
||||
/// }
|
||||
///
|
||||
/// static A From(ByteView& bv)
|
||||
/// {
|
||||
/// auto [a, b] = bv.Read<uint16_t, uint16_t>();
|
||||
/// return A(a, b);
|
||||
/// }
|
||||
/// };
|
||||
/// }
|
||||
|
||||
/// specializations for ByteConverter for common types.
|
||||
namespace FSecure
|
||||
{
|
||||
/// ByteConverter specialization for enum.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<std::is_enum_v<T>>>
|
||||
{
|
||||
/// Serialize enum type to ByteVector.
|
||||
/// @param enumInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(T enumInstance)
|
||||
{
|
||||
return ByteVector::Create(static_cast<std::underlying_type_t<T>>(enumInstance));
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
constexpr static size_t Size()
|
||||
{
|
||||
return sizeof(std::underlying_type_t<T>);
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return enum.
|
||||
static T From(ByteView& bv)
|
||||
{
|
||||
return static_cast<T>(bv.Read<std::underlying_type_t<T>>());
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for std::pair<>.
|
||||
template <typename T1, typename T2>
|
||||
struct ByteConverter<std::pair<T1, T2>>
|
||||
{
|
||||
/// Serialize pair type to ByteVector.
|
||||
/// @param pairInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::pair<T1, T2> const& pairInstance)
|
||||
{
|
||||
return ByteVector::Create(pairInstance.first, pairInstance.second);
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param pairInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(std::pair<T1, T2> const& pairInstance)
|
||||
{
|
||||
return ByteVector::Size(pairInstance.first) + ByteVector::Size(pairInstance.second);
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::pair.
|
||||
static std::pair<T1, T2> From(ByteView& bv)
|
||||
{
|
||||
auto [t1, t2] = bv.Read<T1, T2>();
|
||||
return { std::move(t1), std::move(t2) };
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for std::filesystem::path.
|
||||
template <>
|
||||
struct ByteConverter<std::filesystem::path>
|
||||
{
|
||||
/// Serialize path type to ByteVector.
|
||||
/// @param pathInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::filesystem::path const& pathInstance)
|
||||
{
|
||||
return ByteVector::Create(pathInstance.wstring());
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param pathInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(std::filesystem::path const& pathInstance)
|
||||
{
|
||||
return ByteVector::Size(pathInstance.wstring());
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::filesystem::path.
|
||||
static std::filesystem::path From(ByteView& bv)
|
||||
{
|
||||
return { bv.Read<std::wstring>() };
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for std::byte.
|
||||
template <>
|
||||
struct ByteConverter<std::byte>
|
||||
{
|
||||
/// Serialize byte type to ByteVector.
|
||||
/// @param byteInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::byte byteInstance)
|
||||
{
|
||||
return ByteVector::Create(static_cast<unsigned char>(byteInstance));
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
constexpr static size_t Size()
|
||||
{
|
||||
return sizeof(unsigned char);
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::byte.
|
||||
static std::byte From(ByteView& bv)
|
||||
{
|
||||
return static_cast<std::byte>(bv.Read<unsigned char>());
|
||||
}
|
||||
};
|
||||
|
||||
/// Class allowing reading N bytes without coping data like in ByeView::Read<ByteArray<N>>() or ByteView::Reed(size_t).
|
||||
/// Using Bytes class in read will return ByteView with requested size using simple syntax:
|
||||
/// @code someByteViewObject.Read<int, int, Bytes<7>, std::string> @endCode
|
||||
template<size_t N>
|
||||
class Bytes
|
||||
{
|
||||
/// This class should never be instantiated.
|
||||
Bytes() = delete;
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for FSecure::Bytes.
|
||||
template <size_t N>
|
||||
struct ByteConverter<FSecure::Bytes<N>>
|
||||
{
|
||||
/// Retrieve ByteView substring with requested size.
|
||||
/// @param bv. Buffer with serialized data. Will be moved by N bytes.
|
||||
/// @return ByteView new view with size equal to N.
|
||||
static ByteView From(ByteView& bv)
|
||||
{
|
||||
if (N > bv.size())
|
||||
throw std::out_of_range{ OBF(": Cannot read data from ByteView") };
|
||||
|
||||
auto retVal = bv.SubString(0, N);
|
||||
bv.remove_prefix(N);
|
||||
return retVal;
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for vector types.
|
||||
template <typename T>
|
||||
struct ByteConverter<std::vector<T>>
|
||||
{
|
||||
/// Serialize vector type to ByteVector.
|
||||
/// @param vectorInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::vector<T> const& vectorInstance)
|
||||
{
|
||||
ByteVector ret;
|
||||
ret.reserve(ByteVector::Size(vectorInstance));
|
||||
ret.Write(static_cast<uint32_t>(vectorInstance.size()));
|
||||
for (auto const& e : vectorInstance)
|
||||
ret.Concat(ByteVector::Create(e));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param vectorInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(std::vector<T> const& vectorInstance)
|
||||
{
|
||||
size_t size = sizeof(uint32_t); //four bytes for vector size.
|
||||
for (auto const& e : vectorInstance)
|
||||
size += ByteVector::Size(e);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::vector.
|
||||
static std::vector<T> From(ByteView& bv)
|
||||
{
|
||||
std::vector<T> ret;
|
||||
auto size = bv.Read<uint32_t>();
|
||||
ret.reserve(size);
|
||||
for (auto i = 0u; i < size; ++i)
|
||||
ret.push_back(bv.Read<T>());
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for map types.
|
||||
template <typename T1, typename T2>
|
||||
struct ByteConverter<std::map<T1, T2>>
|
||||
{
|
||||
/// Serialize map type to ByteVector.
|
||||
/// @param mapInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::map<T1, T2> const& mapInstance)
|
||||
{
|
||||
ByteVector ret;
|
||||
ret.reserve(ByteVector::Size(mapInstance));
|
||||
ret.Write(static_cast<uint32_t>(mapInstance.size()));
|
||||
for (auto const& [key, val] : mapInstance)
|
||||
ret.Concat(ByteVector::Create(key, val));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param mapInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(std::map<T1, T2> const& mapInstance)
|
||||
{
|
||||
size_t size = sizeof(uint32_t); //four bytes for map size.
|
||||
for (auto const& [key, val] : mapInstance)
|
||||
size += ByteVector::Size(key) + ByteVector::Size(val);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::map.
|
||||
static std::map<T1, T2> From(ByteView& bv)
|
||||
{
|
||||
std::map<T1, T2> ret;
|
||||
auto size = bv.Read<uint32_t>();
|
||||
for (auto i = 0u; i < size; ++i)
|
||||
{
|
||||
auto [key, val] = bv.Read<T1, T2>();
|
||||
ret.emplace(std::move(key), std::move(val));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for std:array.
|
||||
template <typename T, size_t N>
|
||||
struct ByteConverter<std::array<T, N>>
|
||||
{
|
||||
/// Serialize array type to ByteVector.
|
||||
/// @param arrayInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::array<T, N> const& arrayInstance)
|
||||
{
|
||||
ByteVector ret;
|
||||
ret.reserve(ByteVector::Size(arrayInstance));
|
||||
for (auto const& e : arrayInstance)
|
||||
ret.Write(e);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param arrayInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(std::array<T, N> const& arrayInstance)
|
||||
{
|
||||
auto ret = size_t{ 0 };
|
||||
if constexpr (std::is_arithmetic_v<T>)
|
||||
{
|
||||
static_cast<void>(arrayInstance);
|
||||
ret = sizeof(T) * N; // avoid extra calls when size of array is known.
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto const& e : arrayInstance)
|
||||
ret += ByteVector::Size(e);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::array.
|
||||
static std::array<T, N> From(ByteView& bv)
|
||||
{
|
||||
std::vector<T> temp;
|
||||
temp.reserve(N);
|
||||
for (auto i = 0u; i < N; ++i)
|
||||
temp.push_back(bv.Read<T>());
|
||||
|
||||
return MakeArray(std::move(temp), std::make_index_sequence<N>());
|
||||
}
|
||||
|
||||
private:
|
||||
/// Create array with size N from provided vector.
|
||||
/// This helper function is required because T might not be default constructible, but array must be filled like aggregator.
|
||||
/// Reading data to vector first will ensure order of elements, independent of calling convention.
|
||||
/// @param vec. Temporary vector with data.
|
||||
/// @returns std::array with all elements.
|
||||
template<size_t...Is>
|
||||
static std::array<T, N> MakeArray(std::vector<T>&& vec, std::index_sequence<Is...>)
|
||||
{
|
||||
return { std::move(vec[Is])... };
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for tuple.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<Utils::IsTuple<T>>>
|
||||
{
|
||||
/// Serialize tuple type to ByteVector.
|
||||
/// @param tupleInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(T const& tupleInstance)
|
||||
{
|
||||
ByteVector ret;
|
||||
ret.reserve(Size(tupleInstance));
|
||||
TupleHandler<T>::Write(ret, tupleInstance);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param tupleInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(T const& tupleInstance)
|
||||
{
|
||||
return TupleHandler<T>::Size(tupleInstance);
|
||||
}
|
||||
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::tuple.
|
||||
static auto From(ByteView& bv)
|
||||
{
|
||||
return TupleHandler<T>::Read(bv);
|
||||
}
|
||||
|
||||
private:
|
||||
/// @tparam T. Tuple type to read/write.
|
||||
/// @tparam N. How many elements of tuple to handle. Functions will use recursion, decrementing N with each call.
|
||||
template <typename T, size_t N = std::tuple_size_v<T>>
|
||||
struct TupleHandler
|
||||
{
|
||||
/// Function responsible for recursively packing data to ByteVector.
|
||||
/// @param self. Reference to ByteVector object using TupleHandler.
|
||||
/// @param t. reference to tuple.
|
||||
static void Write(ByteVector& self, T const& t)
|
||||
{
|
||||
if constexpr (N != 0)
|
||||
{
|
||||
self.Write(std::get<std::tuple_size_v<T> - N>(t));
|
||||
TupleHandler<T, N - 1>::Write(self, t);
|
||||
}
|
||||
}
|
||||
|
||||
/// Function responsible for recursively calculating buffer size needed for call with tuple argument.
|
||||
/// @param t. reference to tuple.
|
||||
/// @return size_t number of bytes needed.
|
||||
static size_t Size(T const& t)
|
||||
{
|
||||
if constexpr (N != 0)
|
||||
return ByteVector::Size(std::get<std::tuple_size_v<T> - N>(t)) + TupleHandler<T, N - 1>::Size(t);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Function responsible for recursively packing data to tuple.
|
||||
/// @param self. Reference to ByteView object using generate method.
|
||||
static auto Read(ByteView& self)
|
||||
{
|
||||
if constexpr (N != 0)
|
||||
{
|
||||
auto current = std::make_tuple(self.Read<std::tuple_element_t<std::tuple_size_v<T> - N, T>>());
|
||||
auto rest = TupleHandler<T, N - 1>::Read(self);
|
||||
return std::tuple_cat(current, rest);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::tuple<>{};
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace FSecure
|
||||
{
|
||||
/// Owning container with size known at compilation time.
|
|
@ -0,0 +1,291 @@
|
|||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "ByteView.h"
|
||||
|
||||
/// specializations for ByteConverter for common types.
|
||||
namespace FSecure
|
||||
{
|
||||
/// ByteConverter specialization for arithmetic types.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<std::is_arithmetic_v<T>>>
|
||||
{
|
||||
/// Serialize arithmetic type to ByteVector.
|
||||
/// @param obj. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(T obj)
|
||||
{
|
||||
auto ret = ByteVector{};
|
||||
ret.resize(sizeof(T));
|
||||
*reinterpret_cast<T*>(ret.data()) = obj;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
constexpr static size_t Size()
|
||||
{
|
||||
return sizeof(T);
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return arithmetic type.
|
||||
static T From(ByteView& bv)
|
||||
{
|
||||
T ret;
|
||||
memcpy(&ret, bv.data(), sizeof(T));
|
||||
bv.remove_prefix(sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for enum.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<std::is_enum_v<T>>>
|
||||
{
|
||||
/// Serialize enum type to ByteVector.
|
||||
/// @param enumInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(T enumInstance)
|
||||
{
|
||||
return ByteVector::Create(static_cast<std::underlying_type_t<T>>(enumInstance));
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
constexpr static size_t Size()
|
||||
{
|
||||
return sizeof(std::underlying_type_t<T>);
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return enum.
|
||||
static T From(ByteView& bv)
|
||||
{
|
||||
return static_cast<T>(bv.Read<std::underlying_type_t<T>>());
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for iterable types.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<Utils::Container::IsIterable<T>::value>>
|
||||
{
|
||||
/// Serialize iterable type to ByteVector.
|
||||
/// @param obj. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(T const& obj)
|
||||
{
|
||||
auto ret = ByteVector{};
|
||||
ret.reserve(ByteVector::Size(obj));
|
||||
if (auto numberOfElements = Utils::Container::Size<T>::Calculate(obj); numberOfElements <= std::numeric_limits<uint32_t>::max())
|
||||
ret.Write(static_cast<uint32_t>(numberOfElements));
|
||||
else
|
||||
throw std::out_of_range{ OBF(": Cannot write size to ByteVector ") };
|
||||
|
||||
for (auto&& e : obj)
|
||||
ret.Write(e);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(T const& obj)
|
||||
{
|
||||
using Element = Utils::Container::StoredValue<T>;
|
||||
auto ret = sizeof(uint32_t);
|
||||
if constexpr (ByteSizeFunctionType<Element>::value == ByteSizeFunctionType<Element>::compileTime)
|
||||
ret += ByteConverter<Element>::Size() * obj.size(); // avoid extra calls when size of stored type is known at compile time
|
||||
else
|
||||
for (auto const& e : obj)
|
||||
ret += ByteVector::Size(e);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// Writing to ByteVector is similar for any iterable type, but container construction can heavily differ.
|
||||
/// Utils::Container::Generator is used for unification of this process.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return iterable type.
|
||||
static T From(ByteView& bv)
|
||||
{
|
||||
if (sizeof(uint32_t) > bv.size())
|
||||
throw std::out_of_range{ OBF(": Cannot read size from ByteView ") };
|
||||
|
||||
if constexpr (Utils::Container::GeneratorSignature<T>::value == Utils::Container::GeneratorSignature<T>::queuedAccess)
|
||||
{
|
||||
return Utils::Container::Generator<T>{}(bv.Read<uint32_t>(), [&bv] { return bv.Read<Utils::Container::StoredValue<T>>(); } );
|
||||
}
|
||||
else if constexpr (Utils::Container::GeneratorSignature<T>::value == Utils::Container::GeneratorSignature<T>::directMemoryAccess)
|
||||
{
|
||||
auto size = bv.Read<uint32_t>();
|
||||
auto data = bv.data();
|
||||
auto ret = Utils::Container::Generator<T>{}(size, reinterpret_cast<const char**>(&data));
|
||||
bv.remove_prefix(data - bv.data());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static_assert(Utils::Container::GeneratorSignature<T>::value != Utils::Container::GeneratorSignature<T>::other, "Unable to find container generator for provided type");
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for std::filesystem::path.
|
||||
template <>
|
||||
struct ByteConverter<std::filesystem::path>
|
||||
{
|
||||
/// Serialize path type to ByteVector.
|
||||
/// @param pathInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(std::filesystem::path const& pathInstance)
|
||||
{
|
||||
return ByteVector::Create(pathInstance.wstring());
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param pathInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(std::filesystem::path const& pathInstance)
|
||||
{
|
||||
return ByteVector::Size(pathInstance.wstring());
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::filesystem::path.
|
||||
static std::filesystem::path From(ByteView& bv)
|
||||
{
|
||||
return { bv.Read<std::wstring>() };
|
||||
}
|
||||
};
|
||||
|
||||
/// Tag allowing reading N bytes from ByteView.
|
||||
/// Provides simpler way of joining multiple reads than ByteView::Reed(size_t).
|
||||
/// @code someByteViewObject.Read<int, int, Bytes<7>, std::string> @endCode
|
||||
/// Size must be known at compile time.
|
||||
/// Using Bytes class in read will return ByteView, or ByteVector, depending on HardCopy template argument.
|
||||
template<size_t N, bool HardCopy = false>
|
||||
class Bytes
|
||||
{
|
||||
/// This class should never be instantiated.
|
||||
Bytes() = delete;
|
||||
static constexpr bool Copy = HardCopy;
|
||||
};
|
||||
|
||||
/// Tag always coping data.
|
||||
template<size_t N>
|
||||
using BytesCopy = Bytes<N, true>;
|
||||
|
||||
/// ByteConverter specialization for FSecure::Bytes.
|
||||
template <size_t N, bool HardCopy>
|
||||
struct ByteConverter<Bytes<N, HardCopy>>
|
||||
{
|
||||
/// Retrieve ByteView substring with requested size.
|
||||
/// @param bv. Buffer with serialized data. Will be moved by N bytes.
|
||||
/// @return ByteView new view with size equal to N.
|
||||
static auto From(ByteView& bv) -> std::conditional_t<HardCopy, ByteVector, ByteView>
|
||||
{
|
||||
if (N > bv.size())
|
||||
throw std::out_of_range{ OBF(": Cannot read data from ByteView") };
|
||||
|
||||
auto retVal = bv.SubString(0, N);
|
||||
bv.remove_prefix(N);
|
||||
return retVal;
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for tuple.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<Utils::IsTuple<T>>>
|
||||
{
|
||||
/// Serialize tuple type to ByteVector.
|
||||
/// @param tupleInstance. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(T const& tupleInstance)
|
||||
{
|
||||
ByteVector ret;
|
||||
ret.reserve(Size(tupleInstance));
|
||||
TupleHandler<T>::Write(ret, tupleInstance);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param tupleInstance. Instance for which size should be found.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(T const& tupleInstance)
|
||||
{
|
||||
return TupleHandler<T>::Size(tupleInstance);
|
||||
}
|
||||
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return std::tuple.
|
||||
static auto From(ByteView& bv)
|
||||
{
|
||||
return TupleHandler<T>::ReadExplicit(bv);
|
||||
}
|
||||
|
||||
private:
|
||||
/// @tparam T. Tuple type to read/write.
|
||||
/// @tparam N. How many elements of tuple to handle. Functions will use recursion, decrementing N with each call.
|
||||
template <typename T, size_t N = std::tuple_size_v<T>>
|
||||
struct TupleHandler
|
||||
{
|
||||
/// Function responsible for recursively packing data to ByteVector.
|
||||
/// @param self. Reference to ByteVector object using TupleHandler.
|
||||
/// @param t. reference to tuple.
|
||||
static void Write(ByteVector& self, T const& t)
|
||||
{
|
||||
if constexpr (N != 0)
|
||||
{
|
||||
self.Write(std::get<std::tuple_size_v<T> - N>(t));
|
||||
TupleHandler<T, N - 1>::Write(self, t);
|
||||
}
|
||||
}
|
||||
|
||||
/// Function responsible for recursively calculating buffer size needed for call with tuple argument.
|
||||
/// @param t. reference to tuple.
|
||||
/// @return size_t number of bytes needed.
|
||||
static size_t Size(T const& t)
|
||||
{
|
||||
if constexpr (N != 0)
|
||||
return ByteVector::Size(std::get<std::tuple_size_v<T> - N>(t)) + TupleHandler<T, N - 1>::Size(t);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// C++ allows cast from pair to tuple of two, but not other way around.
|
||||
/// This is oversight, because pair is much older concept than tuple, and no proposition was made to expand old type.
|
||||
/// This function ensures, that TupleHandler always returns requested type, so no cast is necessary.
|
||||
static T ReadExplicit(ByteView& self)
|
||||
{
|
||||
auto tmp = Read(self);
|
||||
if constexpr (Utils::IsPair<T>)
|
||||
return { std::get<0>(tmp), std::get<1>(tmp) };
|
||||
else
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// Function responsible for recursively packing data to tuple.
|
||||
/// @param self. Reference to ByteView object using generate method.
|
||||
static auto Read(ByteView& self)
|
||||
{
|
||||
if constexpr (N != 0)
|
||||
{
|
||||
auto current = std::make_tuple(self.Read<std::tuple_element_t<std::tuple_size_v<T> - N, T>>());
|
||||
auto rest = TupleHandler<T, N - 1>::Read(self);
|
||||
return std::tuple_cat(current, rest);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::tuple<>{};
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
@ -141,8 +143,8 @@ namespace FSecure
|
|||
friend inline bool operator!=(ByteVector const& lhs, ByteVector const& rhs);
|
||||
|
||||
/// Write content of of provided objects.
|
||||
/// Suports arithmetic types, std::string, std::wstring, std::string_view, std::wstring_view, ByteVector and ByteView.
|
||||
/// Include ByteConverter.h to add support for common types like enum, std::vector, std:map, std::pair, std::tuple and others.
|
||||
/// Supports arithmetic types, and basic iterable types.
|
||||
/// Include ByteConverter.h to add support for common types like enum, std::tuple and others.
|
||||
/// Create specialization on ByteConverter for custom types or template types to expand existing serialization functionality.
|
||||
/// @param arg. Object to be stored.
|
||||
/// @param args. Optional other objects to be stored.
|
||||
|
@ -173,19 +175,6 @@ namespace FSecure
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Some versions of msvc can handle fold expression in debug mode, but fails with internal compiler error in release.
|
||||
// For this reason recursive version is used as deafult.
|
||||
//template <typename ...T, typename = std::enable_if_t<((Utils::IsOneOf<T, ByteView, ByteVector>::value && ...))>>
|
||||
//ByteVector& Concat(T const& ...args)
|
||||
//{
|
||||
// auto oldSize = size();
|
||||
// auto foldSize = (args.size() + ...);
|
||||
// resize(oldSize + foldSize);
|
||||
// auto ptr = data() + oldSize;
|
||||
// ((memcpy(ptr, args.data(), args.size()), (ptr += args.size())), ...);
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
/// Create new ByteVector with Variadic list of parameters.
|
||||
/// This function cannot be constructor, because it would be ambiguous with super class constructors.
|
||||
/// @param arg. Object to be stored.
|
||||
|
@ -197,7 +186,6 @@ namespace FSecure
|
|||
return ByteVector{}.Write(arg, args...);
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the size that the argument will take in memory
|
||||
/// @param arg. Argument to be stored.
|
||||
/// @param args. Rest of types that will be handled with recursion.
|
||||
|
@ -221,7 +209,7 @@ namespace FSecure
|
|||
/// @param args. Rest of objects that will be handled with recursion.
|
||||
/// @return itself to allow chaining.
|
||||
template<typename T, typename ...Ts, typename std::enable_if_t<std::is_same_v<decltype(FSecure::ByteConverter<T>::To(std::declval<T>())), FSecure::ByteVector >, int> = 0>
|
||||
ByteVector& Store(T const& arg, Ts const& ...args)
|
||||
ByteVector & Store(T const& arg, Ts const& ...args)
|
||||
{
|
||||
|
||||
Concat(FSecure::ByteConverter<T>::To(arg));
|
||||
|
@ -232,53 +220,6 @@ namespace FSecure
|
|||
}
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for ByteVector, ByteView, std::string, std::string_view, std::wstring, std::wstring_view.
|
||||
/// This is a basic functionality that should be available with ByteVector. This specialization will not be moved to ByteConverter.h.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<Utils::IsOneOf<T, ByteVector, ByteView, std::string, std::string_view, std::wstring, std::wstring_view>::value>>
|
||||
{
|
||||
static ByteVector To(T const& obj)
|
||||
{
|
||||
auto ret = ByteVector{};
|
||||
auto elementSize = static_cast<uint32_t>(obj.size());
|
||||
ret.resize(Size(obj));
|
||||
memcpy(ret.data(), &elementSize, sizeof(elementSize));
|
||||
memcpy(ret.data() + sizeof(elementSize), obj.data(), elementSize * sizeof(typename T::value_type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t Size(T const& obj)
|
||||
{
|
||||
return sizeof(uint32_t) + (obj.size() * sizeof(typename T::value_type));
|
||||
}
|
||||
|
||||
// Reading functions are part of ByteView implementation. To deserialize data include ByteView.h
|
||||
static T From(ByteView& bv);
|
||||
};
|
||||
|
||||
/// ByteConverter specialization for arithmetic types.
|
||||
/// This is a basic functionality that should be available with ByteVector. This specialization will not be moved to ByteConverter.h.
|
||||
template <typename T>
|
||||
struct ByteConverter<T, std::enable_if_t<std::is_arithmetic_v<T>>>
|
||||
{
|
||||
static ByteVector To(T obj)
|
||||
{
|
||||
auto ret = ByteVector{};
|
||||
ret.resize(sizeof(T));
|
||||
*reinterpret_cast<T*>(ret.data()) = obj;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr static size_t Size()
|
||||
{
|
||||
return sizeof(T);
|
||||
}
|
||||
|
||||
// Reading functions are part of ByteView implementation. To deserialize data include ByteView.h
|
||||
static T From(ByteView& bv);
|
||||
};
|
||||
|
||||
namespace Literals
|
||||
{
|
||||
/// Create ByteVector with syntax ""_bvec
|
|
@ -156,9 +156,9 @@ namespace FSecure
|
|||
/// Read object and move ByteView to position after parsed data.
|
||||
/// @tparam T. Mandatory type to be retrieved from ByteView.
|
||||
/// @tparam Ts. Optional types to be retrieved in one call.
|
||||
/// @note Suports arithmetic types, std::string, std::wstring, std::string_view, std::wstring_view, ByteVector and ByteView.
|
||||
/// Include ByteConverter.h to add support for common types like enum, std::vector, std:map, std::pair, std::tuple and others.
|
||||
/// Create specialization on ByteConverter for custom types or template types to expand existing functionality.
|
||||
/// @note Works with types and templates that have specialized ByteConverter.
|
||||
/// Include ByteConverter.h to add support for arithmetic, iterable, tuple and other standard types.
|
||||
/// Create new specializations for custom types.
|
||||
/// @returns one type if Ts was empty, std::tuple with all types otherwise.
|
||||
/// Simple usage:
|
||||
/// @code auto [a, b, c] = someByteView.Read<int, float, std::string>(); @endcode
|
||||
|
@ -174,41 +174,79 @@ namespace FSecure
|
|||
return std::make_tuple(std::move(current), Read<Ts...>());
|
||||
else
|
||||
return std::tuple_cat(std::make_tuple(std::move(current)), Read<Ts...>());
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/// ByteConverter::From specialization for arithmetic types.
|
||||
/// This is a basic functionality that should be available with ByteView. This specialization will not be moved to ByteConverter.h.
|
||||
template <typename T>
|
||||
T ByteConverter<T, std::enable_if_t<Utils::IsOneOf<T, ByteVector, ByteView, std::string, std::string_view, std::wstring, std::wstring_view>::value>>::From(ByteView& bv)
|
||||
/// Helper class for Reading data from ByteView.
|
||||
class ByteReader
|
||||
{
|
||||
if (sizeof(uint32_t) > bv.size())
|
||||
throw std::out_of_range{ OBF(": Cannot read size from ByteView ") };
|
||||
/// Reference to ByteView with data.
|
||||
/// ByteReader will modify ByteView used for it construction.
|
||||
ByteView& m_byteView;
|
||||
|
||||
auto elementCount = *reinterpret_cast<const uint32_t*>(bv.data());
|
||||
auto byteCount = elementCount * sizeof(typename T::value_type);
|
||||
bv.remove_prefix(sizeof(uint32_t));
|
||||
/// Declaration of base template used for pointer to member type deduction.
|
||||
template<class T>
|
||||
struct SplitMemberPointer;
|
||||
|
||||
T retVal;
|
||||
if constexpr (Utils::IsOneOf<T, ByteVector, std::string, std::wstring>::value)
|
||||
retVal.resize(elementCount), std::memcpy(retVal.data(), bv.data(), byteCount);
|
||||
else
|
||||
retVal = T{ reinterpret_cast<typename T::value_type const*>(bv.data()), elementCount };
|
||||
/// Specialization that will perform type deduction.
|
||||
template<class C, class T>
|
||||
struct SplitMemberPointer<T C::*> {
|
||||
using type = T;
|
||||
using declaringType = C;
|
||||
};
|
||||
|
||||
bv.remove_prefix(byteCount);
|
||||
return retVal;
|
||||
}
|
||||
/// Function used to call constructor of type T with tuple of types matching constructor arguments.
|
||||
template<typename T, typename Tpl, size_t... Is>
|
||||
static T TupleToConstructor(Tpl&& tpl, std::integer_sequence<size_t, Is...>)
|
||||
{
|
||||
return T{ std::get<Is>(std::move(tpl))... };
|
||||
}
|
||||
|
||||
/// ByteConverter::from specialization for ByteVector, ByteView, std::string, std::string_view, std::wstring, std::wstring_view.
|
||||
/// This is a basic functionality that should be available with ByteView. This specialization will not be moved to ByteConverter.h.
|
||||
template <typename T>
|
||||
T ByteConverter<T, std::enable_if_t<std::is_arithmetic_v<T>>>::From(ByteView& bv)
|
||||
public:
|
||||
/// Create ByteReader.
|
||||
/// @param bv, ByteView with data to read.
|
||||
ByteReader(ByteView& bv)
|
||||
: m_byteView{bv}
|
||||
{}
|
||||
|
||||
/// Read each of arguments from ByteView.
|
||||
/// @param ts, arguments to tie, and read.
|
||||
template <typename ...Ts>
|
||||
void Read(Ts&... ts)
|
||||
{
|
||||
((ts = m_byteView.Read<decltype(ts)>()), ...);
|
||||
}
|
||||
|
||||
/// Create object by reading provided types, and passing them to object constructor.
|
||||
/// @tparam T, type to be constructed.
|
||||
/// @tparam Ts, types to be read from ByteView, and passed as T constructor arguments.
|
||||
/// @note T is not the same as first template parameter of Create(...).
|
||||
template <typename T, typename ...Ts>
|
||||
auto Create() -> decltype(T{ std::declval<Ts>()... })
|
||||
{
|
||||
return TupleToConstructor<T>(m_byteView.Read<Ts...>(), std::make_index_sequence<sizeof...(Ts)>{});
|
||||
}
|
||||
|
||||
|
||||
/// Create object by reading provided types deduced from pointers to members
|
||||
/// @tparam T, first pointer to member. Ensures that at least one object will be read from ByteView
|
||||
/// @tparam Ts, rest of pointers to members.
|
||||
/// @note T is not the same as first template parameter of Create(void).
|
||||
template <typename T, typename ...Ts>
|
||||
auto Create(T, Ts...) -> decltype(SplitMemberPointer<T>::declaringType{ std::declval<SplitMemberPointer<T>::type>(), std::declval<SplitMemberPointer<Ts>::type>()... })
|
||||
{
|
||||
return TupleToConstructor<SplitMemberPointer<T>::declaringType>(m_byteView.Read<SplitMemberPointer<T>::type, SplitMemberPointer<Ts>::type...>(), std::make_index_sequence<1 + sizeof...(Ts)>{});
|
||||
}
|
||||
};
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
T ret;
|
||||
memcpy(&ret, bv.data(), sizeof(T));
|
||||
bv.remove_prefix(sizeof(T));
|
||||
return ret;
|
||||
/// ByteView is a view.
|
||||
template <>
|
||||
struct IsView<ByteView>
|
||||
{
|
||||
constexpr static bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
namespace Literals
|
|
@ -0,0 +1,225 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#ifndef OBF
|
||||
# define OBF(x) x
|
||||
#endif // !OBF
|
||||
|
||||
namespace FSecure::Utils
|
||||
{
|
||||
/// Prevents compiler from optimizing out call.
|
||||
/// @param ptr pointer to memory to be cleared.
|
||||
/// @param n number of bytes to overwrite.
|
||||
inline void* SecureMemzero(void* ptr, size_t n)
|
||||
{
|
||||
if (ptr) for (auto p = reinterpret_cast<volatile char*>(ptr); n--; *p++ = 0);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// Template to evaluate if T is one of Ts types.
|
||||
template <typename T, typename ...Ts>
|
||||
struct IsOneOf
|
||||
{
|
||||
constexpr static bool value = [](bool ret) { return ret; }((std::is_same_v<T, Ts> || ...));
|
||||
};
|
||||
|
||||
/// Template to strip type out of const, volatile and reference.
|
||||
template <typename T>
|
||||
using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
|
||||
/// Idioms for detecting tuple types.
|
||||
template <typename T>
|
||||
constexpr bool IsTuple = false;
|
||||
template<typename ...T>
|
||||
constexpr bool IsTuple<std::tuple<T...>> = true;
|
||||
template<typename ...T>
|
||||
constexpr bool IsTuple<std::pair<T...>> = true;
|
||||
template<typename T>
|
||||
constexpr bool IsPair = false;
|
||||
template<typename ...T>
|
||||
constexpr bool IsPair<std::pair<T...>> = true;
|
||||
|
||||
|
||||
/// Check if type is designed to view data owned by other container.
|
||||
template <typename T, typename = void>
|
||||
struct IsView
|
||||
{
|
||||
constexpr static bool value = false;
|
||||
};
|
||||
|
||||
/// Every basic_string_view is a view.
|
||||
template <typename T>
|
||||
struct IsView<std::basic_string_view<T>, void>
|
||||
{
|
||||
constexpr static bool value = true;
|
||||
};
|
||||
|
||||
/// Namespace full of helpers for containers template programing.
|
||||
namespace Container
|
||||
{
|
||||
/// Get type stored by container that uses iterators.
|
||||
template <typename T>
|
||||
using StoredValue = RemoveCVR<decltype(*begin(std::declval<T>()))>;
|
||||
|
||||
/// Check if type can be iterated with begin() and end().
|
||||
template <typename T>
|
||||
class IsIterable
|
||||
{
|
||||
template <typename C> static uint8_t test(std::void_t<decltype(begin(std::declval<C>()), end(std::declval<C>()))>*);
|
||||
template <typename C> static uint16_t test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(uint8_t));
|
||||
};
|
||||
|
||||
/// Check if type have own implementation of size method.
|
||||
template <typename T>
|
||||
class Size
|
||||
{
|
||||
template <typename C> static uint8_t test(std::void_t<decltype(size(std::declval<C>()))>*);
|
||||
template <typename C> static uint16_t test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool HasDedicatedImplementation = (sizeof(test<T>(0)) == sizeof(uint8_t));
|
||||
static size_t Calculate(std::enable_if_t<HasDedicatedImplementation || IsIterable<T>::value, T> const& obj)
|
||||
{
|
||||
size_t count = 0;
|
||||
if constexpr (HasDedicatedImplementation) count = size(obj);
|
||||
else for (auto it = obj.begin(); it != obj.end(); ++it, ++count);
|
||||
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
/// Check if type have insert(iterator, value) function.
|
||||
template <typename T>
|
||||
class HasInsert
|
||||
{
|
||||
template <typename C> static uint8_t test(std::void_t<decltype(std::declval<C>().insert(begin(std::declval<C>()), *end(std::declval<C>())))>*);
|
||||
template <typename C> static uint16_t test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(uint8_t));
|
||||
};
|
||||
|
||||
/// Check if type can reserve some space to avoid reallocations.
|
||||
template <typename T>
|
||||
class HasReserve
|
||||
{
|
||||
template <typename C> static uint8_t test(std::void_t<decltype(std::declval<C>().reserve(size_t{}))>*);
|
||||
template <typename C> static uint16_t test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(uint8_t));
|
||||
};
|
||||
|
||||
/// Struct to generalize container construction.
|
||||
/// Defines one of allowed operators that will return requested container.
|
||||
/// @tparam T. Type to be constructed.
|
||||
/// @tparam unnamed typename with default value, to allow easy creation of partial specializations.
|
||||
template <typename T, typename = void>
|
||||
struct Generator
|
||||
{
|
||||
/// Form with queued access to each of container values.
|
||||
/// @param size. Defines numbers of elements in constructed container.
|
||||
/// @param next. Functor returning one of container values at a time.
|
||||
// T operator()(uint32_t size, std::function<StoredValue<T>()> next);
|
||||
|
||||
/// Form with direct access to memory.
|
||||
/// @param size. Defines numbers of elements in constructed container.
|
||||
/// @param data. Allows access to data used to container generation.
|
||||
/// Dereferenced pointer should be changed, to represent number of bytes consumed for container generation.
|
||||
// T operator()(uint32_t size, const char** data)
|
||||
};
|
||||
|
||||
/// Generator for any container that have insert method.
|
||||
template <typename T>
|
||||
struct Generator<T, std::enable_if_t<HasInsert<T>::value>>
|
||||
{
|
||||
/// Form with queued access to each of container values.
|
||||
/// @param size. Defines numbers of elements in constructed container.
|
||||
/// @param next. Functor returning one of container values at a time.
|
||||
T operator()(uint32_t size, std::function<StoredValue<T>()> next)
|
||||
{
|
||||
T ret;
|
||||
if constexpr (HasReserve<T>::value)
|
||||
{
|
||||
ret.reserve(size);
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < size; ++i)
|
||||
ret.insert(ret.end(), next());
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/// Generator for any container that is simmilar to std::basic_string_view.
|
||||
template <typename T>
|
||||
struct Generator<T, std::enable_if_t<IsView<T>::value>>
|
||||
{
|
||||
/// Form with direct access to memory.
|
||||
/// @param size. Defines numbers of elements in constructed container.
|
||||
/// @param data. Allows access to data used to container generation.
|
||||
/// Dereferenced pointer should be changed, to represent number of bytes consumed for container generation.
|
||||
T operator()(uint32_t size, const char** data)
|
||||
{
|
||||
auto ptr = reinterpret_cast<const T::value_type*>(*data);
|
||||
*data += size * sizeof(typename T::value_type);
|
||||
return { ptr, size };
|
||||
}
|
||||
};
|
||||
|
||||
/// Generator for any array types.
|
||||
template <typename T, size_t N>
|
||||
struct Generator<std::array<T, N>>
|
||||
{
|
||||
/// Form with queued access to each of container values.
|
||||
/// @param size. Defines numbers of elements in constructed container.
|
||||
/// @param next. Functor returning one of container values at a time.
|
||||
std::array<T, N> operator()(uint32_t size, std::function<T()> next)
|
||||
{
|
||||
if (size != N)
|
||||
throw std::runtime_error{ OBF("Array size does not match declaration") };
|
||||
|
||||
std::vector<T> temp;
|
||||
temp.reserve(N);
|
||||
for (auto i = 0u; i < N; ++i)
|
||||
temp.push_back(next());
|
||||
|
||||
return MakeArray(std::move(temp), std::make_index_sequence<N>());
|
||||
}
|
||||
|
||||
private:
|
||||
/// Create array with size N from provided vector.
|
||||
/// This helper function is required because T might not be default constructible, but array must be filled like aggregator.
|
||||
/// Reading data to vector first will ensure order of elements, independent of calling convention.
|
||||
/// @param obj. Temporary vector with data.
|
||||
/// @returns std::array with all elements.
|
||||
template<size_t... Is>
|
||||
std::array<T, N> MakeArray(std::vector<T>&& obj, std::index_sequence<Is...>)
|
||||
{
|
||||
return { std::move(obj[Is])... };
|
||||
}
|
||||
};
|
||||
|
||||
/// Used to detect form of Generator operator() at compile time.
|
||||
template <typename T>
|
||||
class GeneratorSignature
|
||||
{
|
||||
template <typename C> static uint32_t test(std::void_t<decltype(Generator<C>{}(std::declval<uint32_t>(), std::declval<std::function<StoredValue<C>()>>()))>*);
|
||||
template <typename C> static uint16_t test(std::void_t<decltype(Generator<C>{}(std::declval<uint32_t>(), std::declval<const char**>()))>*);
|
||||
template <typename C> static uint8_t test(...);
|
||||
|
||||
public:
|
||||
enum { other = 0, directMemoryAccess = (sizeof(uint16_t) - sizeof(uint8_t)), queuedAccess = (sizeof(uint32_t) - sizeof(uint8_t)) };
|
||||
enum { value = (sizeof(test<T>(0)) - sizeof(uint8_t)) };
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteView.h"
|
||||
#include "ByteConverter/ByteView.h"
|
||||
|
||||
namespace FSecure::Compression
|
||||
{
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteView.h"
|
||||
#include "ByteVector.h"
|
||||
|
||||
//
|
||||
#include "ByteConverter/ByteView.h"
|
||||
|
||||
namespace FSecure::Encryption
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
#include "ByteView.h"
|
||||
#include "ByteConverter/ByteConverter.h"
|
||||
#include "Encryption.h"
|
||||
|
||||
#define FSECURE_PAYLOAD_GUID "15e3eda3-74c8-43d5-a4a1-e2e039542240"
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
#include "Common/ADVobfuscator/MetaString.h"
|
||||
|
||||
#define BYTEVECTOR_ZERO_MEMORY_DESTRUCTION //< Increase OpSec by clearing memory when ByteVector is destructed.
|
||||
#include "ByteConverter.h" //< For ByteView, ByteVector and ByteConverter specializations for common types.
|
||||
#include "ByteConverter/ByteConverter.h" //< For ByteView, ByteVector and ByteConverter specializations for common types.
|
||||
#include "Utils.h" //< For common templates and helpers
|
||||
|
||||
|
||||
|
||||
// Literals.
|
||||
using namespace std::string_literals; //< For string literals.
|
||||
using namespace std::string_view_literals; //< For string_view literals.
|
||||
using namespace FSecure::Literals; //< For _b and _bv.
|
||||
using namespace FSecure::Literals; //< For _b and _bv.
|
||||
|
|
|
@ -22,17 +22,6 @@ namespace FSecure::Utils
|
|||
# endif
|
||||
}
|
||||
|
||||
/// Template to evaluate if T is one of Ts types.
|
||||
template <typename T, typename ...Ts>
|
||||
struct IsOneOf
|
||||
{
|
||||
constexpr static bool value = [](bool ret) { return ret; }((std::is_same_v<T, Ts> || ...));
|
||||
};
|
||||
|
||||
/// Template to strip type out of const, volatile and reference.
|
||||
template <typename T>
|
||||
using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
|
||||
/// Changes value to default if it is out of provided range.
|
||||
/// @param value to be clamped.
|
||||
/// @param minValue lowest accepted value.
|
||||
|
@ -60,7 +49,7 @@ namespace FSecure::Utils
|
|||
|
||||
/// Generate random string.
|
||||
/// @param size of returned string.
|
||||
template <typename T = std::string, std::enable_if_t<IsOneOf<T, std::string, std::wstring>::value, int> = 0>
|
||||
template <typename T = std::string, std::enable_if_t<std::is_same_v<T, std::string> || std::is_same_v<T, std::wstring>, int> = 0>
|
||||
T GenerateRandomString(size_t size)
|
||||
{
|
||||
constexpr std::string_view charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
@ -78,7 +67,7 @@ namespace FSecure::Utils
|
|||
|
||||
/// Generate random data.
|
||||
/// @param size of returned string.
|
||||
template <typename T = std::vector<uint8_t>, std::enable_if_t<IsOneOf<T, std::vector<uint8_t>, std::string>::value, int> = 0>
|
||||
template <typename T = std::vector<uint8_t>, std::enable_if_t<std::is_same_v<T, std::string> || std::is_same_v<T, std::vector<uint8_t>>, int> = 0>
|
||||
T GenerateRandomData(size_t size)
|
||||
{
|
||||
static std::random_device rd;
|
||||
|
@ -246,19 +235,4 @@ namespace FSecure::Utils
|
|||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/// Idiom for detecting tuple types.
|
||||
template <typename T>
|
||||
constexpr bool IsTuple = false;
|
||||
template<typename ...T>
|
||||
constexpr bool IsTuple<std::tuple<T...>> = true;
|
||||
|
||||
/// Prevents compiler from optimizing out call.
|
||||
/// @param ptr pointer to memory to be cleared.
|
||||
/// @param n number of bytes to overwrite.
|
||||
inline void* SecureMemzero(void* ptr, size_t n)
|
||||
{
|
||||
if (ptr) for (auto p = reinterpret_cast<volatile char*>(ptr); n--; *p++ = 0);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
namespace FSecure::Crypto
|
||||
{
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Socket.h"
|
||||
#include "Common/FSecure/CppTools/ByteVector.h"
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
namespace FSecure
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "AddrInfo.h"
|
||||
#include "Common/FSecure/CppTools/ByteVector.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
namespace FSecure
|
||||
{
|
||||
|
|
|
@ -37,7 +37,8 @@ namespace FSecure
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
HostInfo::HostInfo() : m_OsVersionInfo{ sizeof m_OsVersionInfo }
|
||||
HostInfo::HostInfo()
|
||||
: m_OsVersionInfo{ sizeof(m_OsVersionInfo) }
|
||||
{
|
||||
// Reserve buffers for winapi calls.
|
||||
DWORD computerNameBufferLength = MAX_COMPUTERNAME_LENGTH + 1, userNameBufferLength = UNLEN + 1;
|
||||
|
@ -75,29 +76,15 @@ namespace FSecure
|
|||
}
|
||||
}
|
||||
|
||||
HostInfo::HostInfo(ByteView bv)
|
||||
: m_ComputerName(bv.Read<std::string>())
|
||||
, m_UserName(bv.Read<std::string>())
|
||||
, m_Domain(bv.Read<std::string>())
|
||||
, m_OsVersionInfo
|
||||
{ [&]
|
||||
{
|
||||
decltype(m_OsVersionInfo) osv{sizeof osv};
|
||||
std::tie
|
||||
(
|
||||
osv.dwMajorVersion,
|
||||
osv.dwMinorVersion,
|
||||
osv.dwBuildNumber,
|
||||
osv.wServicePackMajor,
|
||||
osv.wServicePackMinor,
|
||||
osv.wProductType
|
||||
) = bv.Read<DWORD, DWORD, DWORD, WORD, WORD, BYTE>();
|
||||
return osv;
|
||||
}()
|
||||
}
|
||||
, m_ProcessId(bv.Read<decltype(m_ProcessId)>())
|
||||
, m_IsElevated(bv.Read<bool>())
|
||||
HostInfo::HostInfo(std::string computerName, std::string userName, std::string domain, OSVERSIONINFOEXA osVersionInfo, DWORD processId, bool isElevated)
|
||||
: m_ComputerName{ std::move(computerName) }
|
||||
, m_UserName{ std::move(userName) }
|
||||
, m_Domain{ std::move(domain) }
|
||||
, m_OsVersionInfo{ std::move(osVersionInfo) }
|
||||
, m_ProcessId(processId)
|
||||
, m_IsElevated(isElevated)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HostInfo::HostInfo(const json& json)
|
||||
|
@ -115,25 +102,6 @@ namespace FSecure
|
|||
json.at("IsElevated").get_to(m_IsElevated);
|
||||
}
|
||||
|
||||
ByteVector HostInfo::ToByteVector() const
|
||||
{
|
||||
return ByteVector{}
|
||||
.Write
|
||||
(
|
||||
m_ComputerName,
|
||||
m_UserName,
|
||||
m_Domain,
|
||||
m_OsVersionInfo.dwMajorVersion,
|
||||
m_OsVersionInfo.dwMinorVersion,
|
||||
m_OsVersionInfo.dwBuildNumber,
|
||||
m_OsVersionInfo.wServicePackMajor,
|
||||
m_OsVersionInfo.wServicePackMinor,
|
||||
m_OsVersionInfo.wProductType,
|
||||
m_ProcessId,
|
||||
m_IsElevated
|
||||
);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, HostInfo const& hi)
|
||||
{
|
||||
return os << "Computer name:\t" << hi.m_ComputerName << '\n'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common/json/json.hpp"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
|
||||
namespace FSecure
|
||||
|
@ -17,20 +18,15 @@ namespace FSecure
|
|||
DWORD m_ProcessId; ///< Process Id
|
||||
bool m_IsElevated; ///< Is process run with elevated rights
|
||||
|
||||
/// Gather host information
|
||||
/// Gather info about host.
|
||||
HostInfo();
|
||||
|
||||
/// Deserializing constructor from json
|
||||
/// Aggregate constructor.
|
||||
HostInfo(std::string computerName, std::string userName, std::string domain, OSVERSIONINFOEXA osVersionInfo, DWORD processId, bool isElevated);
|
||||
|
||||
/// Constructor from json
|
||||
/// @param json to read from
|
||||
HostInfo(const json& json);
|
||||
|
||||
/// Deserializing constructor from ByteView
|
||||
/// @param byte view n to read from
|
||||
HostInfo(ByteView bv);
|
||||
|
||||
/// Serialize to ByteVector
|
||||
/// @returns ByteVector representation of host information
|
||||
ByteVector ToByteVector() const;
|
||||
};
|
||||
|
||||
/// Overload ostream operator << for HostInfo
|
||||
|
@ -42,4 +38,80 @@ namespace FSecure
|
|||
/// @param json to write to
|
||||
/// @param host info to write
|
||||
void to_json(json& j, const HostInfo& hi);
|
||||
|
||||
/// overload ByteConverter for OSVERSIONINFOEXA
|
||||
template<>
|
||||
struct ByteConverter<OSVERSIONINFOEXA>
|
||||
{
|
||||
/// Serialize HostInfo type to ByteVector.
|
||||
/// @param obj. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(OSVERSIONINFOEXA const& obj)
|
||||
{
|
||||
auto ret = ByteVector{};
|
||||
ret.reserve(ByteVector::Size(obj));
|
||||
ret.Write(obj.dwOSVersionInfoSize, obj.dwMajorVersion, obj.dwMinorVersion, obj.dwBuildNumber, obj.dwPlatformId);
|
||||
ret.Concat(ByteVector{ obj.szCSDVersion, obj.szCSDVersion + sizeof(obj.szCSDVersion) });
|
||||
ret.Write(obj.wServicePackMajor, obj.wServicePackMinor, obj.wSuiteMask, obj.wProductType);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param obj. Object to be serialized.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(OSVERSIONINFOEXA const& obj)
|
||||
{
|
||||
auto ret = ByteVector::Size(obj.dwOSVersionInfoSize, obj.dwMajorVersion, obj.dwMinorVersion, obj.dwBuildNumber, obj.dwPlatformId);
|
||||
ret += sizeof(obj.szCSDVersion);
|
||||
ret += ByteVector::Size(obj.wServicePackMajor, obj.wServicePackMinor, obj.wSuiteMask, obj.wProductType);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return OSVERSIONINFOEXA.
|
||||
static OSVERSIONINFOEXA From(ByteView& bv)
|
||||
{
|
||||
OSVERSIONINFOEXA obj;
|
||||
ByteReader br{ bv };
|
||||
br.Read(obj.dwOSVersionInfoSize, obj.dwMajorVersion, obj.dwMinorVersion, obj.dwBuildNumber, obj.dwPlatformId);
|
||||
memcpy(obj.szCSDVersion, bv.data(), sizeof(obj.szCSDVersion));
|
||||
bv.remove_prefix(sizeof(obj.szCSDVersion));
|
||||
br.Read(obj.wServicePackMajor, obj.wServicePackMinor, obj.wSuiteMask, obj.wProductType);
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
/// overload ByteConverter for HostInfo
|
||||
template<>
|
||||
struct ByteConverter<HostInfo>
|
||||
{
|
||||
/// Serialize HostInfo type to ByteVector.
|
||||
/// @param obj. Object to be serialized.
|
||||
/// @return ByteVector. Serialized data.
|
||||
static ByteVector To(HostInfo const& obj)
|
||||
{
|
||||
auto ret = ByteVector{};
|
||||
ret.reserve(ByteVector::Size(obj));
|
||||
ret.Write(obj.m_ComputerName, obj.m_UserName, obj.m_Domain, obj.m_OsVersionInfo, obj.m_ProcessId, obj.m_IsElevated);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Get size required after serialization.
|
||||
/// @param obj. Object to be serialized.
|
||||
/// @return size_t. Number of bytes used after serialization.
|
||||
static size_t Size(HostInfo const& obj)
|
||||
{
|
||||
return ByteVector::Size(obj.m_ComputerName, obj.m_UserName, obj.m_Domain, obj.m_OsVersionInfo, obj.m_ProcessId, obj.m_IsElevated);
|
||||
}
|
||||
|
||||
/// Deserialize from ByteView.
|
||||
/// @param bv. Buffer with serialized data.
|
||||
/// @return arithmetic type.
|
||||
static HostInfo From(ByteView& bv)
|
||||
{
|
||||
using T = HostInfo;
|
||||
return ByteReader{ bv }.Create(&T::m_ComputerName, &T::m_UserName, &T::m_Domain, &T::m_OsVersionInfo, &T::m_ProcessId, &T::m_IsElevated);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ std::shared_ptr<FSecure::C3::Relay> FSecure::C3::Utils::CreateGatewayFromConfigu
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
std::shared_ptr<FSecure::C3::Relay> FSecure::C3::Utils::CreateNodeRelayFromImagePatch(LoggerCallback callbackOnLog, InterfaceFactory& interfaceFactory, ByteView buildId, ByteView gatewaySignature, ByteView broadcastKey, std::vector<ByteVector> const& gatewayInitialPackets)
|
||||
{
|
||||
return Core::NodeRelay::CreateAndRun(callbackOnLog, interfaceFactory, gatewaySignature, broadcastKey, gatewayInitialPackets, buildId);
|
||||
return Core::NodeRelay::CreateAndRun(callbackOnLog, interfaceFactory, gatewaySignature, broadcastKey, gatewayInitialPackets, buildId.Read<BuildId>());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -33,7 +33,7 @@ void FSecure::C3::Core::ConnectorBridge::TurnOff()
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void FSecure::C3::Core::ConnectorBridge::PostCommandToBinder(ByteView binderId, ByteView command)
|
||||
{
|
||||
return GetGateRelay()->PostCommandToPeripheral(command, RouteId(binderId));
|
||||
return GetGateRelay()->PostCommandToPeripheral(command, binderId.Read<RouteId>());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "StdAfx.h"
|
||||
#include "Distributor.h"
|
||||
#include "DeviceBridge.h"
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FSecure::C3::Core::Distributor::Distributor(LoggerCallback callbackOnLog, Crypto::PrivateKey const& decryptionKey, Crypto::SymmetricKey const& broadcastKey)
|
||||
|
@ -68,17 +68,19 @@ void FSecure::C3::Core::Distributor::OnProtocolN2N(ByteView packet0, std::shared
|
|||
if (packet0.size() < 1 + RouteId::BinarySize + 1)
|
||||
throw std::invalid_argument{ OBF("N2N packet too short.") };
|
||||
|
||||
packet0.remove_prefix(1);
|
||||
|
||||
// Parse neighbor identifier and check whether is banned.
|
||||
auto neighborRouteId = RouteId(packet0.SubString(1));
|
||||
auto neighborRouteId = packet0.Read<RouteId>();
|
||||
if (IsAgentBanned(neighborRouteId.GetAgentId()))
|
||||
return Log({ OBF("Received packet from a banned Agent ") + neighborRouteId.ToString() + OBF("."), LogMessage::Severity::Warning });
|
||||
|
||||
// Handle Procedure part.
|
||||
return ProceduresN2N::RequestHandler::ParseRequestAndHandleIt(sender, neighborRouteId, packet0.SubString(1 + RouteId::BinarySize));
|
||||
return ProceduresN2N::RequestHandler::ParseRequestAndHandleIt(sender, neighborRouteId, packet0);
|
||||
}
|
||||
catch (std::exception & exception)
|
||||
{
|
||||
throw std::runtime_error{ OBF_STR("Failed to parse N2N packet. ") +exception.what() };
|
||||
throw std::runtime_error{ OBF_STR("Failed to parse N2N packet. ") + exception.what() };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,13 @@ void FSecure::C3::Core::GateRelay::OnProtocolS2G(ByteView packet0, std::shared_p
|
|||
{
|
||||
try
|
||||
{
|
||||
auto decrypted = FSecure::Crypto::DecryptFromAnonymous(packet0.SubString(1), m_AuthenticationKey, m_DecryptionKey);
|
||||
packet0.remove_prefix(1);
|
||||
auto decrypted = FSecure::Crypto::DecryptFromAnonymous(packet0, m_AuthenticationKey, m_DecryptionKey);
|
||||
auto [procedure, rid, timestamp] = ByteView{ decrypted }.Read<ProceduresUnderlyingType, RouteId, int32_t>();
|
||||
if (!m_Profiler->Get().m_Gateway.ConnectionExist(rid.GetAgentId()))
|
||||
throw std::runtime_error{ "S2G packet received from not connected source." };
|
||||
|
||||
ProceduresS2G::RequestHandler::ParseRequestAndHandleIt(sender, procedure, rid, timestamp, packet0.SubString(1));
|
||||
ProceduresS2G::RequestHandler::ParseRequestAndHandleIt(sender, procedure, rid, timestamp, packet0);
|
||||
}
|
||||
catch (std::exception& exception)
|
||||
{
|
||||
|
@ -79,7 +80,7 @@ void FSecure::C3::Core::GateRelay::PostCommandToConnector(ByteView command, std:
|
|||
if (!connector)
|
||||
throw std::runtime_error{ "Connector not found" };
|
||||
|
||||
connector->OnCommandFromBinder(RouteId{ GetAgentId(), senderPeripheral->GetDid() }.ToByteVector(), command);
|
||||
connector->OnCommandFromBinder(ByteVector::Create(RouteId{ GetAgentId(), senderPeripheral->GetDid() }), command);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -295,7 +296,7 @@ void FSecure::C3::Core::GateRelay::On(ProceduresN2N::InitializeRouteQuery query)
|
|||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
||||
auto hash = readView.Read<HashT>();
|
||||
auto lastSeen = readView.Read<int32_t>();
|
||||
HostInfo hostInfo(readView.Read<ByteView>());
|
||||
auto hostInfo = readView.Read<HostInfo>();
|
||||
|
||||
auto receivedFrom = query.GetSenderChannel().lock();
|
||||
if (!receivedFrom)
|
||||
|
@ -327,7 +328,7 @@ void FSecure::C3::Core::GateRelay::On(ProceduresS2G::InitializeRouteQuery query)
|
|||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
||||
auto hash = readView.Read<HashT>();
|
||||
auto lastSeen = readView.Read<int32_t>();
|
||||
HostInfo hostInfo(readView.Read<ByteView>());
|
||||
auto hostInfo= readView.Read<HostInfo>();
|
||||
|
||||
auto receivedFrom = query.GetSenderChannel().lock();
|
||||
if (!receivedFrom)
|
||||
|
@ -363,7 +364,7 @@ void FSecure::C3::Core::GateRelay::On(ProceduresS2G::DeliverToBinder query)
|
|||
if (!connector)
|
||||
throw std::runtime_error{ "Connector not found" };
|
||||
|
||||
auto binder = RouteId{ senderRid.GetAgentId(), deviceId }.ToByteVector();
|
||||
auto binder = ByteVector::Create(RouteId{ senderRid.GetAgentId(), deviceId });
|
||||
connector->OnCommandFromBinder(binder, readView);
|
||||
|
||||
m_Profiler->Get().m_Gateway.UpdateRouteTimestamps(senderRid.GetAgentId(), timestamp);
|
||||
|
|
|
@ -30,10 +30,6 @@ namespace FSecure::C3
|
|||
/// @notes this specialization exist only to satisfy implicit casts requirements.
|
||||
Identifier(std::string const& textId);
|
||||
|
||||
/// Creates an ID object from a ByteView.
|
||||
/// @param byteId a ByteView containing the identifier.
|
||||
Identifier(ByteView byteId);
|
||||
|
||||
/// Creates an ID object with a random ("unique") value.
|
||||
/// @return Identifier object.
|
||||
static Identifier GenerateRandom();
|
||||
|
@ -42,10 +38,6 @@ namespace FSecure::C3
|
|||
/// @return a string that describes this ID object.
|
||||
std::string ToString() const;
|
||||
|
||||
/// Converts this ID to a byte vector.
|
||||
/// @return a byte vector that describes this ID object.
|
||||
ByteVector ToByteVector() const;
|
||||
|
||||
/// Converts identifier to underlying type.
|
||||
/// @returns UnderlyingIntegerType identifier in arithmetic form.
|
||||
UnderlyingIntegerType ToUnderlyingType() const;
|
||||
|
@ -87,31 +79,5 @@ namespace FSecure::C3
|
|||
using BuildId = Identifier<std::uint32_t>; ///< ID of Relay's configuration.
|
||||
}
|
||||
|
||||
namespace FSecure
|
||||
{
|
||||
/// Specialize ByteConverter for identifiers.
|
||||
template <typename T>
|
||||
struct ByteConverter <C3::Identifier<T>>
|
||||
{
|
||||
static ByteVector To(C3::Identifier<T> const& obj)
|
||||
{
|
||||
return obj.ToByteVector();
|
||||
}
|
||||
|
||||
static size_t Size(C3::Identifier<T> const& obj)
|
||||
{
|
||||
return C3::Identifier<T>::BinarySize;
|
||||
}
|
||||
|
||||
static C3::Identifier<T> From(ByteView& bv)
|
||||
{
|
||||
auto ret = C3::Identifier<T>(bv.SubString(0, C3::Identifier<T>::BinarySize));
|
||||
bv.remove_prefix(C3::Identifier<T>::BinarySize);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Include template's implementation.
|
||||
#include "Identifiers.hxx"
|
||||
|
|
|
@ -41,18 +41,6 @@ FSecure::C3::Identifier<UnderlyingIntegerType>::Identifier(std::string const& te
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename UnderlyingIntegerType>
|
||||
FSecure::C3::Identifier<UnderlyingIntegerType>::Identifier(ByteView byteId)
|
||||
{
|
||||
// Sanity check.
|
||||
if (byteId.size() != BinarySize)
|
||||
throw std::runtime_error{ OBF("Invalid byte Identifier size.") };
|
||||
|
||||
// Just make a byte-to-byte copy.
|
||||
memcpy(&m_Id, byteId.data(), sizeof(m_Id));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename UnderlyingIntegerType>
|
||||
FSecure::C3::Identifier<UnderlyingIntegerType> FSecure::C3::Identifier<UnderlyingIntegerType>::GenerateRandom()
|
||||
|
@ -77,13 +65,6 @@ std::string FSecure::C3::Identifier<UnderlyingIntegerType>::ToString() const
|
|||
return ret.substr(0, sizeof(UnderlyingIntegerType) * 2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename UnderlyingIntegerType>
|
||||
FSecure::ByteVector FSecure::C3::Identifier<UnderlyingIntegerType>::ToByteVector() const
|
||||
{
|
||||
return { reinterpret_cast<const std::uint8_t*>(&m_Id), reinterpret_cast<const std::uint8_t*>(&m_Id) + sizeof(m_Id) };
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename UnderlyingIntegerType>
|
||||
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator!() const
|
||||
|
@ -124,3 +105,26 @@ UnderlyingIntegerType FSecure::C3::Identifier<UnderlyingIntegerType>::ToUnderlyi
|
|||
{
|
||||
return m_Id;
|
||||
}
|
||||
|
||||
namespace FSecure
|
||||
{
|
||||
/// Specialize ByteConverter for identifiers.
|
||||
template <typename T>
|
||||
struct ByteConverter <C3::Identifier<T>>
|
||||
{
|
||||
static ByteVector To(C3::Identifier<T> const& obj)
|
||||
{
|
||||
return ByteVector::Create(obj.ToUnderlyingType());
|
||||
}
|
||||
|
||||
static size_t Size()
|
||||
{
|
||||
return sizeof(C3::Identifier<T>::UnderlyingIntegerType);
|
||||
}
|
||||
|
||||
static C3::Identifier<T> From(ByteView& bv)
|
||||
{
|
||||
return bv.Read<C3::Identifier<T>::UnderlyingIntegerType>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "StdAfx.h"
|
||||
#include "NodeRelay.h"
|
||||
#include "DeviceBridge.h"
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
std::shared_ptr<FSecure::C3::Core::NodeRelay> FSecure::C3::Core::NodeRelay::CreateAndRun(LoggerCallback callbackOnLog, InterfaceFactory& interfaceFactory,
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace FSecure::C3::Core
|
|||
/// @return buffer containing composed header.
|
||||
ByteVector CompileProtocolHeader() const override
|
||||
{
|
||||
return ByteVector{}.Write(static_cast<ProtocolsUnderlyingType>(Protocols::N2N), m_SendersRid.ToByteArray());
|
||||
return ByteVector{}.Write(static_cast<ProtocolsUnderlyingType>(Protocols::N2N), m_SendersRid);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -135,7 +135,7 @@ namespace FSecure::C3::Core
|
|||
static std::unique_ptr<InitializeRouteQuery> Create(RouteId sendersRid, BuildId buildId, Crypto::PublicKey gatewayEncryptionKey, Crypto::PublicKey agentsPublicEncryptionKey, HashT grcHash, int32_t timestamp, ResponseType responseType = ResponseType::None)
|
||||
{
|
||||
auto query = std::make_unique<InitializeRouteQuery>(sendersRid, responseType);
|
||||
query->m_QueryPacketBody = Crypto::EncryptAnonymously(buildId.ToByteVector().Write(agentsPublicEncryptionKey.ToByteVector(), grcHash, timestamp, HostInfo().ToByteVector()), gatewayEncryptionKey);
|
||||
query->m_QueryPacketBody = Crypto::EncryptAnonymously(ByteVector::Create(buildId, agentsPublicEncryptionKey.ToByteVector(), grcHash, timestamp, HostInfo()), gatewayEncryptionKey);
|
||||
return query;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace FSecure::C3::Core::ProceduresG2X
|
|||
ByteVector ComposeQueryPacket() const override
|
||||
{
|
||||
assert(m_GatewayPrivateSignature);
|
||||
return CompileProtocolHeader().Concat(Crypto::SignMessage(m_ReceiverRid.ToByteVector().Concat(GetQueryHeader()).Concat(m_QueryPacketBody), *m_GatewayPrivateSignature));
|
||||
return CompileProtocolHeader().Concat(Crypto::SignMessage(ByteVector::Create(m_ReceiverRid).Concat(GetQueryHeader(), m_QueryPacketBody), *m_GatewayPrivateSignature));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -199,7 +199,7 @@ namespace FSecure::C3::Core::ProceduresG2X
|
|||
static std::unique_ptr<RunCommandOnDeviceQuery> Create(RouteId receiverRid, Crypto::PrivateSignature const& gatewayPrivateSignature, Crypto::PublicKey const& agentPublicKey, Crypto::PrivateKey const& gatewayPrivateKey, DeviceId deviceToRunOn, ByteView commandWithArguments, ResponseType responseType = ResponseType::None)
|
||||
{
|
||||
auto query = std::make_unique<RunCommandOnDeviceQuery>(Propagation::Agent, receiverRid, gatewayPrivateSignature, responseType);
|
||||
query->EncrpytQueryWithBody(deviceToRunOn.ToByteVector().Concat(commandWithArguments), agentPublicKey, gatewayPrivateKey);
|
||||
query->EncrpytQueryWithBody(ByteVector::Create(deviceToRunOn).Concat(commandWithArguments), agentPublicKey, gatewayPrivateKey);
|
||||
return query;
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ namespace FSecure::C3::Core::ProceduresG2X
|
|||
static std::unique_ptr<DeliverToBinder> Create(RouteId receiverRid, Crypto::PrivateSignature const& gatewayPrivateSignature, Crypto::PublicKey const& agentPublicKey, Crypto::PrivateKey const& gatewayPrivateKey, DeviceId deliverTo, ByteView commandWithArguments, ResponseType responseType = ResponseType::None)
|
||||
{
|
||||
auto query = std::make_unique<DeliverToBinder>(Propagation::Agent, receiverRid, gatewayPrivateSignature, responseType);
|
||||
query->EncrpytQueryWithBody(deliverTo.ToByteVector().Concat(commandWithArguments), agentPublicKey, gatewayPrivateKey);
|
||||
query->EncrpytQueryWithBody(ByteVector::Create(deliverTo).Concat(commandWithArguments), agentPublicKey, gatewayPrivateKey);
|
||||
return query;
|
||||
}
|
||||
|
||||
|
|
|
@ -327,7 +327,7 @@ void FSecure::C3::Core::Profiler::RestoreFromSnapshot()
|
|||
|
||||
auto creationCommand = base64::decode<ByteVector>(peripheral["startupCommand"]["ByteForm"].get<std::string>());
|
||||
auto readView = ByteView{ creationCommand };
|
||||
auto connectionId = RouteId{ route->m_RouteId.GetAgentId(), DeviceId{ peripheral["iId"].get<std::string>() } }.ToByteVector();
|
||||
auto connectionId = ByteVector::Create(RouteId{ route->m_RouteId.GetAgentId(), DeviceId{ peripheral["iId"].get<std::string>() } });
|
||||
readView.remove_prefix(sizeof(uint16_t)); // remove command id
|
||||
connector->PeripheralCreationCommand(connectionId, readView); // throw away the response.
|
||||
connector->OnCommandFromBinder(connectionId, base64::decode<ByteVector>(peripheral["startupCommand"]["FirstResponse"].get<std::string>()));
|
||||
|
@ -528,7 +528,7 @@ void FSecure::C3::Core::Profiler::Agent::ParseAndRunCommand(json const& jCommand
|
|||
return;
|
||||
|
||||
// Remove connection.
|
||||
connector->CloseConnection(RouteId{ m_Id, *deviceId }.ToByteVector());
|
||||
connector->CloseConnection(ByteVector::Create(RouteId{ m_Id, *deviceId }));
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
@ -610,7 +610,7 @@ void FSecure::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArgument
|
|||
break;
|
||||
|
||||
// Remove connection.
|
||||
connector->CloseConnection(RouteId{ m_Id, element.m_Id }.ToByteVector());
|
||||
connector->CloseConnection(ByteVector::Create(RouteId{ m_Id, element.m_Id }));
|
||||
}
|
||||
|
||||
m_Peripherals.Clear();
|
||||
|
@ -701,7 +701,7 @@ void FSecure::C3::Core::Profiler::Agent::PerformCreateCommand(json const& jComma
|
|||
if (!connector)
|
||||
throw std::runtime_error{ "Connector for requested peripheral is closed" };
|
||||
|
||||
auto updatedArguments = connector->PeripheralCreationCommand(RouteId{ route->m_RouteId.GetAgentId(), newDeviceId}.ToByteVector(), commandReadView, m_IsX64);
|
||||
auto updatedArguments = connector->PeripheralCreationCommand(ByteVector::Create(RouteId{ route->m_RouteId.GetAgentId(), newDeviceId }), commandReadView, m_IsX64);
|
||||
repacked.Concat(updatedArguments);
|
||||
}
|
||||
else
|
||||
|
@ -812,7 +812,7 @@ void FSecure::C3::Core::Profiler::Gateway::ParseAndRunCommand(json const& jComma
|
|||
break;
|
||||
|
||||
// Remove connection.
|
||||
connector->CloseConnection(RouteId{ m_Id, device->GetDid() }.ToByteVector());
|
||||
connector->CloseConnection(ByteVector::Create(RouteId{ m_Id, device->GetDid() }));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1068,7 +1068,7 @@ void FSecure::C3::Core::Profiler::Gateway::PerformCreateCommand(json const& jCom
|
|||
if (!connector)
|
||||
throw std::runtime_error{ "Connector for requested peripheral is closed" };
|
||||
|
||||
updatedArguments = connector->PeripheralCreationCommand(RouteId{ gate.GetAgentId(), DeviceId(m_LastDeviceId + 1) }.ToByteVector(), arguments, FSecure::Utils::IsProcess64bit());
|
||||
updatedArguments = connector->PeripheralCreationCommand(ByteVector::Create(RouteId{ gate.GetAgentId(), DeviceId(m_LastDeviceId + 1) }), arguments, FSecure::Utils::IsProcess64bit());
|
||||
arguments = updatedArguments;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "StdAfx.h"
|
||||
#include "Relay.h"
|
||||
#include "DeviceBridge.h"
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
#include "Common/FSecure/C3/Internals/InterfaceFactory.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -10,11 +10,6 @@ FSecure::C3::RouteId::RouteId(std::string_view textId)
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FSecure::C3::RouteId::RouteId(ByteView byteId)
|
||||
: RouteId(byteId.SubString(0, AgentId::BinarySize), byteId.SubString(AgentId::BinarySize, DeviceId::BinarySize))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FSecure::C3::RouteId FSecure::C3::RouteId::GenerateRandom()
|
||||
|
@ -28,36 +23,6 @@ std::string FSecure::C3::RouteId::ToString() const
|
|||
return m_AgentId.ToString() + OBF(":") + m_InterfaceId.ToString();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FSecure::ByteVector FSecure::C3::RouteId::ToByteVector() const
|
||||
{
|
||||
// Allocate return vector.
|
||||
FSecure::ByteVector retByteVector;
|
||||
retByteVector.reserve(m_AgentId.BinarySize + m_InterfaceId.BinarySize);
|
||||
|
||||
// Fill it with aid and iid.
|
||||
auto aid = m_AgentId.ToByteVector(), iid = m_InterfaceId.ToByteVector();
|
||||
retByteVector.insert(retByteVector.end(), aid.begin(), aid.end());
|
||||
retByteVector.insert(retByteVector.end(), iid.begin(), iid.end());
|
||||
|
||||
// That's it.
|
||||
return retByteVector;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
FSecure::ByteArray<FSecure::C3::RouteId::BinarySize> FSecure::C3::RouteId::ToByteArray() const
|
||||
{
|
||||
FSecure::ByteArray<BinarySize> retArray;
|
||||
|
||||
// Fill it with aid and iid.
|
||||
auto aid = m_AgentId.ToByteVector(), iid = m_InterfaceId.ToByteVector();
|
||||
memcpy(retArray.data(), aid.data(), m_AgentId.BinarySize);
|
||||
memcpy(retArray.data() + m_AgentId.BinarySize, iid.data(), m_InterfaceId.BinarySize);
|
||||
// That's it.
|
||||
return retArray;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool FSecure::C3::RouteId::operator!() const
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common/FSecure/CppTools/ByteView.h"
|
||||
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||
#include "Identifiers.h"
|
||||
|
||||
namespace FSecure::C3
|
||||
|
@ -26,10 +26,6 @@ namespace FSecure::C3
|
|||
/// @param textId text containing the identifier.
|
||||
RouteId(std::string_view textId);
|
||||
|
||||
/// Creates a RouteId object from a vector of bytes.
|
||||
/// @param byteId a ByteView containing the identifier.
|
||||
RouteId(ByteView byteId);
|
||||
|
||||
/// Creates a RouteId object with a random ("unique") value.
|
||||
/// @return Identifier object.
|
||||
static RouteId GenerateRandom();
|
||||
|
@ -38,14 +34,6 @@ namespace FSecure::C3
|
|||
/// @return a string that describes this ID object.
|
||||
std::string ToString() const;
|
||||
|
||||
/// Converts this ID to a byte vector.
|
||||
/// @return a byte vector that describes this ID object.
|
||||
ByteVector ToByteVector() const;
|
||||
|
||||
/// Converts this ID to a byte array.
|
||||
/// @return a byte array that describes this ID object.
|
||||
ByteArray<BinarySize> ToByteArray() const;
|
||||
|
||||
/// Logical negation operator. Can be used to check if ID is set.
|
||||
/// @return true if ID is not set.
|
||||
bool operator !() const;
|
||||
|
@ -94,7 +82,7 @@ namespace FSecure
|
|||
{
|
||||
static ByteVector To(C3::RouteId const& obj)
|
||||
{
|
||||
return obj.ToByteVector();
|
||||
return ByteVector::Create(obj.GetAgentId(), obj.GetInterfaceId());
|
||||
}
|
||||
|
||||
static size_t Size(C3::RouteId const& obj)
|
||||
|
@ -104,9 +92,7 @@ namespace FSecure
|
|||
|
||||
static C3::RouteId From(ByteView& bv)
|
||||
{
|
||||
auto ret = C3::RouteId(bv.SubString(0, C3::RouteId::BinarySize));
|
||||
bv.remove_prefix(C3::RouteId::BinarySize);
|
||||
return ret;
|
||||
return ByteReader{ bv }.Create<C3::RouteId, decltype(C3::RouteId::m_AgentId), decltype(C3::RouteId::m_InterfaceId)>();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue