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\base32_default_crockford.hpp" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)CppCodec\base64_default_rfc4648.hpp" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)CppCodec\base64_default_rfc4648.hpp" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)CppRestSdk\include\cpprest\http_client.h" />
|
<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)json\json.hpp" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)libSodium\include\sodium.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)libSodium\include\sodium.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Interfaces\Channels\Slack.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\Interfaces\Peripherals\Mock.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\PrecompiledHeader.hpp" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\PrecompiledHeader.hpp" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Sdk.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\Compression.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Encryption.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Encryption.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Hash.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Hash.h" />
|
||||||
|
|
|
@ -83,14 +83,15 @@
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\WinTools\StructuredExceptionHandling.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\WinTools\StructuredExceptionHandling.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)C3_BUILD_VERSION_HASH_PART.hxx" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)C3_BUILD_VERSION_HASH_PART.hxx" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\WinTools\InjectionBuffer.h" />
|
<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\CppTools\Utils.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Interfaces\Peripherals\Grunt.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\C3\Interfaces\Peripherals\Grunt.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)zlib\include\zconf.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)zlib\include\zconf.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)zlib\include\zlib.h" />
|
<ClInclude Include="$(MSBuildThisFileDirectory)zlib\include\zlib.h" />
|
||||||
<ClInclude Include="$(MSBuildThisFileDirectory)FSecure\CppTools\Compression.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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,6 +1,8 @@
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "Beacon.h"
|
#include "Beacon.h"
|
||||||
|
|
||||||
|
using namespace FSecure::Literals;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
FSecure::C3::Interfaces::Peripherals::Beacon::Beacon(ByteView arguments)
|
FSecure::C3::Interfaces::Peripherals::Beacon::Beacon(ByteView arguments)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/FSecure/CppTools/ByteView.h"
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
|
|
||||||
namespace FSecure
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace FSecure
|
namespace FSecure
|
||||||
{
|
{
|
||||||
/// Owning container with size known at compilation time.
|
/// 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
|
#pragma once
|
||||||
|
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -141,8 +143,8 @@ namespace FSecure
|
||||||
friend inline bool operator!=(ByteVector const& lhs, ByteVector const& rhs);
|
friend inline bool operator!=(ByteVector const& lhs, ByteVector const& rhs);
|
||||||
|
|
||||||
/// Write content of of provided objects.
|
/// Write content of of provided objects.
|
||||||
/// Suports arithmetic types, std::string, std::wstring, std::string_view, std::wstring_view, ByteVector and ByteView.
|
/// Supports arithmetic types, and basic iterable types.
|
||||||
/// Include ByteConverter.h to add support for common types like enum, std::vector, std:map, std::pair, std::tuple and others.
|
/// 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.
|
/// Create specialization on ByteConverter for custom types or template types to expand existing serialization functionality.
|
||||||
/// @param arg. Object to be stored.
|
/// @param arg. Object to be stored.
|
||||||
/// @param args. Optional other objects to be stored.
|
/// @param args. Optional other objects to be stored.
|
||||||
|
@ -173,19 +175,6 @@ namespace FSecure
|
||||||
return *this;
|
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.
|
/// Create new ByteVector with Variadic list of parameters.
|
||||||
/// This function cannot be constructor, because it would be ambiguous with super class constructors.
|
/// This function cannot be constructor, because it would be ambiguous with super class constructors.
|
||||||
/// @param arg. Object to be stored.
|
/// @param arg. Object to be stored.
|
||||||
|
@ -197,7 +186,6 @@ namespace FSecure
|
||||||
return ByteVector{}.Write(arg, args...);
|
return ByteVector{}.Write(arg, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Calculate the size that the argument will take in memory
|
/// Calculate the size that the argument will take in memory
|
||||||
/// @param arg. Argument to be stored.
|
/// @param arg. Argument to be stored.
|
||||||
/// @param args. Rest of types that will be handled with recursion.
|
/// @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.
|
/// @param args. Rest of objects that will be handled with recursion.
|
||||||
/// @return itself to allow chaining.
|
/// @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>
|
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));
|
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
|
namespace Literals
|
||||||
{
|
{
|
||||||
/// Create ByteVector with syntax ""_bvec
|
/// Create ByteVector with syntax ""_bvec
|
|
@ -156,9 +156,9 @@ namespace FSecure
|
||||||
/// Read object and move ByteView to position after parsed data.
|
/// Read object and move ByteView to position after parsed data.
|
||||||
/// @tparam T. Mandatory type to be retrieved from ByteView.
|
/// @tparam T. Mandatory type to be retrieved from ByteView.
|
||||||
/// @tparam Ts. Optional types to be retrieved in one call.
|
/// @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.
|
/// @note Works with types and templates that have specialized ByteConverter.
|
||||||
/// Include ByteConverter.h to add support for common types like enum, std::vector, std:map, std::pair, std::tuple and others.
|
/// Include ByteConverter.h to add support for arithmetic, iterable, tuple and other standard types.
|
||||||
/// Create specialization on ByteConverter for custom types or template types to expand existing functionality.
|
/// Create new specializations for custom types.
|
||||||
/// @returns one type if Ts was empty, std::tuple with all types otherwise.
|
/// @returns one type if Ts was empty, std::tuple with all types otherwise.
|
||||||
/// Simple usage:
|
/// Simple usage:
|
||||||
/// @code auto [a, b, c] = someByteView.Read<int, float, std::string>(); @endcode
|
/// @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...>());
|
return std::make_tuple(std::move(current), Read<Ts...>());
|
||||||
else
|
else
|
||||||
return std::tuple_cat(std::make_tuple(std::move(current)), Read<Ts...>());
|
return std::tuple_cat(std::make_tuple(std::move(current)), Read<Ts...>());
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ByteConverter::From specialization for arithmetic types.
|
/// Helper class for Reading data from ByteView.
|
||||||
/// This is a basic functionality that should be available with ByteView. This specialization will not be moved to ByteConverter.h.
|
class ByteReader
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (sizeof(uint32_t) > bv.size())
|
/// Reference to ByteView with data.
|
||||||
throw std::out_of_range{ OBF(": Cannot read size from ByteView ") };
|
/// ByteReader will modify ByteView used for it construction.
|
||||||
|
ByteView& m_byteView;
|
||||||
|
|
||||||
auto elementCount = *reinterpret_cast<const uint32_t*>(bv.data());
|
/// Declaration of base template used for pointer to member type deduction.
|
||||||
auto byteCount = elementCount * sizeof(typename T::value_type);
|
template<class T>
|
||||||
bv.remove_prefix(sizeof(uint32_t));
|
struct SplitMemberPointer;
|
||||||
|
|
||||||
T retVal;
|
/// Specialization that will perform type deduction.
|
||||||
if constexpr (Utils::IsOneOf<T, ByteVector, std::string, std::wstring>::value)
|
template<class C, class T>
|
||||||
retVal.resize(elementCount), std::memcpy(retVal.data(), bv.data(), byteCount);
|
struct SplitMemberPointer<T C::*> {
|
||||||
else
|
using type = T;
|
||||||
retVal = T{ reinterpret_cast<typename T::value_type const*>(bv.data()), elementCount };
|
using declaringType = C;
|
||||||
|
};
|
||||||
|
|
||||||
bv.remove_prefix(byteCount);
|
/// Function used to call constructor of type T with tuple of types matching constructor arguments.
|
||||||
return retVal;
|
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.
|
public:
|
||||||
/// This is a basic functionality that should be available with ByteView. This specialization will not be moved to ByteConverter.h.
|
/// Create ByteReader.
|
||||||
template <typename T>
|
/// @param bv, ByteView with data to read.
|
||||||
T ByteConverter<T, std::enable_if_t<std::is_arithmetic_v<T>>>::From(ByteView& bv)
|
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;
|
/// ByteView is a view.
|
||||||
memcpy(&ret, bv.data(), sizeof(T));
|
template <>
|
||||||
bv.remove_prefix(sizeof(T));
|
struct IsView<ByteView>
|
||||||
return ret;
|
{
|
||||||
|
constexpr static bool value = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Literals
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "ByteView.h"
|
#include "ByteConverter/ByteView.h"
|
||||||
|
|
||||||
namespace FSecure::Compression
|
namespace FSecure::Compression
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ByteView.h"
|
#include "ByteConverter/ByteView.h"
|
||||||
#include "ByteVector.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace FSecure::Encryption
|
namespace FSecure::Encryption
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "ByteView.h"
|
#include "ByteConverter/ByteConverter.h"
|
||||||
#include "Encryption.h"
|
#include "Encryption.h"
|
||||||
|
|
||||||
#define FSECURE_PAYLOAD_GUID "15e3eda3-74c8-43d5-a4a1-e2e039542240"
|
#define FSECURE_PAYLOAD_GUID "15e3eda3-74c8-43d5-a4a1-e2e039542240"
|
||||||
|
|
|
@ -15,11 +15,12 @@
|
||||||
#include "Common/ADVobfuscator/MetaString.h"
|
#include "Common/ADVobfuscator/MetaString.h"
|
||||||
|
|
||||||
#define BYTEVECTOR_ZERO_MEMORY_DESTRUCTION //< Increase OpSec by clearing memory when ByteVector is destructed.
|
#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.
|
// Literals.
|
||||||
using namespace std::string_literals; //< For string literals.
|
using namespace std::string_literals; //< For string literals.
|
||||||
using namespace std::string_view_literals; //< For string_view 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
|
# 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.
|
/// Changes value to default if it is out of provided range.
|
||||||
/// @param value to be clamped.
|
/// @param value to be clamped.
|
||||||
/// @param minValue lowest accepted value.
|
/// @param minValue lowest accepted value.
|
||||||
|
@ -60,7 +49,7 @@ namespace FSecure::Utils
|
||||||
|
|
||||||
/// Generate random string.
|
/// Generate random string.
|
||||||
/// @param size of returned 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)
|
T GenerateRandomString(size_t size)
|
||||||
{
|
{
|
||||||
constexpr std::string_view charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
constexpr std::string_view charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
@ -78,7 +67,7 @@ namespace FSecure::Utils
|
||||||
|
|
||||||
/// Generate random data.
|
/// Generate random data.
|
||||||
/// @param size of returned string.
|
/// @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)
|
T GenerateRandomData(size_t size)
|
||||||
{
|
{
|
||||||
static std::random_device rd;
|
static std::random_device rd;
|
||||||
|
@ -246,19 +235,4 @@ namespace FSecure::Utils
|
||||||
|
|
||||||
return retValue;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "Common/FSecure/CppTools/ByteView.h"
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
|
|
||||||
namespace FSecure::Crypto
|
namespace FSecure::Crypto
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Socket.h"
|
#include "Socket.h"
|
||||||
#include "Common/FSecure/CppTools/ByteVector.h"
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
#include "Common/FSecure/CppTools/ByteView.h"
|
|
||||||
|
|
||||||
namespace FSecure
|
namespace FSecure
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AddrInfo.h"
|
#include "AddrInfo.h"
|
||||||
#include "Common/FSecure/CppTools/ByteVector.h"
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
|
|
||||||
namespace FSecure
|
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.
|
// Reserve buffers for winapi calls.
|
||||||
DWORD computerNameBufferLength = MAX_COMPUTERNAME_LENGTH + 1, userNameBufferLength = UNLEN + 1;
|
DWORD computerNameBufferLength = MAX_COMPUTERNAME_LENGTH + 1, userNameBufferLength = UNLEN + 1;
|
||||||
|
@ -75,29 +76,15 @@ namespace FSecure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostInfo::HostInfo(ByteView bv)
|
HostInfo::HostInfo(std::string computerName, std::string userName, std::string domain, OSVERSIONINFOEXA osVersionInfo, DWORD processId, bool isElevated)
|
||||||
: m_ComputerName(bv.Read<std::string>())
|
: m_ComputerName{ std::move(computerName) }
|
||||||
, m_UserName(bv.Read<std::string>())
|
, m_UserName{ std::move(userName) }
|
||||||
, m_Domain(bv.Read<std::string>())
|
, m_Domain{ std::move(domain) }
|
||||||
, m_OsVersionInfo
|
, m_OsVersionInfo{ std::move(osVersionInfo) }
|
||||||
{ [&]
|
, m_ProcessId(processId)
|
||||||
{
|
, m_IsElevated(isElevated)
|
||||||
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(const json& json)
|
HostInfo::HostInfo(const json& json)
|
||||||
|
@ -115,25 +102,6 @@ namespace FSecure
|
||||||
json.at("IsElevated").get_to(m_IsElevated);
|
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)
|
std::ostream& operator<<(std::ostream& os, HostInfo const& hi)
|
||||||
{
|
{
|
||||||
return os << "Computer name:\t" << hi.m_ComputerName << '\n'
|
return os << "Computer name:\t" << hi.m_ComputerName << '\n'
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/json/json.hpp"
|
#include "Common/json/json.hpp"
|
||||||
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
|
|
||||||
|
|
||||||
namespace FSecure
|
namespace FSecure
|
||||||
|
@ -17,20 +18,15 @@ namespace FSecure
|
||||||
DWORD m_ProcessId; ///< Process Id
|
DWORD m_ProcessId; ///< Process Id
|
||||||
bool m_IsElevated; ///< Is process run with elevated rights
|
bool m_IsElevated; ///< Is process run with elevated rights
|
||||||
|
|
||||||
/// Gather host information
|
/// Gather info about host.
|
||||||
HostInfo();
|
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
|
/// @param json to read from
|
||||||
HostInfo(const json& json);
|
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
|
/// Overload ostream operator << for HostInfo
|
||||||
|
@ -42,4 +38,80 @@ namespace FSecure
|
||||||
/// @param json to write to
|
/// @param json to write to
|
||||||
/// @param host info to write
|
/// @param host info to write
|
||||||
void to_json(json& j, const HostInfo& hi);
|
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)
|
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)
|
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 "StdAfx.h"
|
||||||
#include "Distributor.h"
|
#include "Distributor.h"
|
||||||
#include "DeviceBridge.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)
|
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)
|
if (packet0.size() < 1 + RouteId::BinarySize + 1)
|
||||||
throw std::invalid_argument{ OBF("N2N packet too short.") };
|
throw std::invalid_argument{ OBF("N2N packet too short.") };
|
||||||
|
|
||||||
|
packet0.remove_prefix(1);
|
||||||
|
|
||||||
// Parse neighbor identifier and check whether is banned.
|
// Parse neighbor identifier and check whether is banned.
|
||||||
auto neighborRouteId = RouteId(packet0.SubString(1));
|
auto neighborRouteId = packet0.Read<RouteId>();
|
||||||
if (IsAgentBanned(neighborRouteId.GetAgentId()))
|
if (IsAgentBanned(neighborRouteId.GetAgentId()))
|
||||||
return Log({ OBF("Received packet from a banned Agent ") + neighborRouteId.ToString() + OBF("."), LogMessage::Severity::Warning });
|
return Log({ OBF("Received packet from a banned Agent ") + neighborRouteId.ToString() + OBF("."), LogMessage::Severity::Warning });
|
||||||
|
|
||||||
// Handle Procedure part.
|
// 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)
|
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
|
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>();
|
auto [procedure, rid, timestamp] = ByteView{ decrypted }.Read<ProceduresUnderlyingType, RouteId, int32_t>();
|
||||||
if (!m_Profiler->Get().m_Gateway.ConnectionExist(rid.GetAgentId()))
|
if (!m_Profiler->Get().m_Gateway.ConnectionExist(rid.GetAgentId()))
|
||||||
throw std::runtime_error{ "S2G packet received from not connected source." };
|
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)
|
catch (std::exception& exception)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +80,7 @@ void FSecure::C3::Core::GateRelay::PostCommandToConnector(ByteView command, std:
|
||||||
if (!connector)
|
if (!connector)
|
||||||
throw std::runtime_error{ "Connector not found" };
|
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 newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
||||||
auto hash = readView.Read<HashT>();
|
auto hash = readView.Read<HashT>();
|
||||||
auto lastSeen = readView.Read<int32_t>();
|
auto lastSeen = readView.Read<int32_t>();
|
||||||
HostInfo hostInfo(readView.Read<ByteView>());
|
auto hostInfo = readView.Read<HostInfo>();
|
||||||
|
|
||||||
auto receivedFrom = query.GetSenderChannel().lock();
|
auto receivedFrom = query.GetSenderChannel().lock();
|
||||||
if (!receivedFrom)
|
if (!receivedFrom)
|
||||||
|
@ -327,7 +328,7 @@ void FSecure::C3::Core::GateRelay::On(ProceduresS2G::InitializeRouteQuery query)
|
||||||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
||||||
auto hash = readView.Read<HashT>();
|
auto hash = readView.Read<HashT>();
|
||||||
auto lastSeen = readView.Read<int32_t>();
|
auto lastSeen = readView.Read<int32_t>();
|
||||||
HostInfo hostInfo(readView.Read<ByteView>());
|
auto hostInfo= readView.Read<HostInfo>();
|
||||||
|
|
||||||
auto receivedFrom = query.GetSenderChannel().lock();
|
auto receivedFrom = query.GetSenderChannel().lock();
|
||||||
if (!receivedFrom)
|
if (!receivedFrom)
|
||||||
|
@ -363,7 +364,7 @@ void FSecure::C3::Core::GateRelay::On(ProceduresS2G::DeliverToBinder query)
|
||||||
if (!connector)
|
if (!connector)
|
||||||
throw std::runtime_error{ "Connector not found" };
|
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);
|
connector->OnCommandFromBinder(binder, readView);
|
||||||
|
|
||||||
m_Profiler->Get().m_Gateway.UpdateRouteTimestamps(senderRid.GetAgentId(), timestamp);
|
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.
|
/// @notes this specialization exist only to satisfy implicit casts requirements.
|
||||||
Identifier(std::string const& textId);
|
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.
|
/// Creates an ID object with a random ("unique") value.
|
||||||
/// @return Identifier object.
|
/// @return Identifier object.
|
||||||
static Identifier GenerateRandom();
|
static Identifier GenerateRandom();
|
||||||
|
@ -42,10 +38,6 @@ namespace FSecure::C3
|
||||||
/// @return a string that describes this ID object.
|
/// @return a string that describes this ID object.
|
||||||
std::string ToString() const;
|
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.
|
/// Converts identifier to underlying type.
|
||||||
/// @returns UnderlyingIntegerType identifier in arithmetic form.
|
/// @returns UnderlyingIntegerType identifier in arithmetic form.
|
||||||
UnderlyingIntegerType ToUnderlyingType() const;
|
UnderlyingIntegerType ToUnderlyingType() const;
|
||||||
|
@ -87,31 +79,5 @@ namespace FSecure::C3
|
||||||
using BuildId = Identifier<std::uint32_t>; ///< ID of Relay's configuration.
|
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 template's implementation.
|
||||||
#include "Identifiers.hxx"
|
#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>
|
template<typename UnderlyingIntegerType>
|
||||||
FSecure::C3::Identifier<UnderlyingIntegerType> FSecure::C3::Identifier<UnderlyingIntegerType>::GenerateRandom()
|
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);
|
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>
|
template<typename UnderlyingIntegerType>
|
||||||
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator!() const
|
bool FSecure::C3::Identifier<UnderlyingIntegerType>::operator!() const
|
||||||
|
@ -124,3 +105,26 @@ UnderlyingIntegerType FSecure::C3::Identifier<UnderlyingIntegerType>::ToUnderlyi
|
||||||
{
|
{
|
||||||
return m_Id;
|
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 "StdAfx.h"
|
||||||
#include "NodeRelay.h"
|
#include "NodeRelay.h"
|
||||||
#include "DeviceBridge.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,
|
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.
|
/// @return buffer containing composed header.
|
||||||
ByteVector CompileProtocolHeader() const override
|
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:
|
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)
|
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);
|
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;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace FSecure::C3::Core::ProceduresG2X
|
||||||
ByteVector ComposeQueryPacket() const override
|
ByteVector ComposeQueryPacket() const override
|
||||||
{
|
{
|
||||||
assert(m_GatewayPrivateSignature);
|
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:
|
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)
|
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);
|
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;
|
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)
|
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);
|
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;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ void FSecure::C3::Core::Profiler::RestoreFromSnapshot()
|
||||||
|
|
||||||
auto creationCommand = base64::decode<ByteVector>(peripheral["startupCommand"]["ByteForm"].get<std::string>());
|
auto creationCommand = base64::decode<ByteVector>(peripheral["startupCommand"]["ByteForm"].get<std::string>());
|
||||||
auto readView = ByteView{ creationCommand };
|
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
|
readView.remove_prefix(sizeof(uint16_t)); // remove command id
|
||||||
connector->PeripheralCreationCommand(connectionId, readView); // throw away the response.
|
connector->PeripheralCreationCommand(connectionId, readView); // throw away the response.
|
||||||
connector->OnCommandFromBinder(connectionId, base64::decode<ByteVector>(peripheral["startupCommand"]["FirstResponse"].get<std::string>()));
|
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;
|
return;
|
||||||
|
|
||||||
// Remove connection.
|
// Remove connection.
|
||||||
connector->CloseConnection(RouteId{ m_Id, *deviceId }.ToByteVector());
|
connector->CloseConnection(ByteVector::Create(RouteId{ m_Id, *deviceId }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
@ -610,7 +610,7 @@ void FSecure::C3::Core::Profiler::Agent::RunCommand(ByteView commandWithArgument
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Remove connection.
|
// Remove connection.
|
||||||
connector->CloseConnection(RouteId{ m_Id, element.m_Id }.ToByteVector());
|
connector->CloseConnection(ByteVector::Create(RouteId{ m_Id, element.m_Id }));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Peripherals.Clear();
|
m_Peripherals.Clear();
|
||||||
|
@ -701,7 +701,7 @@ void FSecure::C3::Core::Profiler::Agent::PerformCreateCommand(json const& jComma
|
||||||
if (!connector)
|
if (!connector)
|
||||||
throw std::runtime_error{ "Connector for requested peripheral is closed" };
|
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);
|
repacked.Concat(updatedArguments);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -812,7 +812,7 @@ void FSecure::C3::Core::Profiler::Gateway::ParseAndRunCommand(json const& jComma
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Remove connection.
|
// Remove connection.
|
||||||
connector->CloseConnection(RouteId{ m_Id, device->GetDid() }.ToByteVector());
|
connector->CloseConnection(ByteVector::Create(RouteId{ m_Id, device->GetDid() }));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1068,7 +1068,7 @@ void FSecure::C3::Core::Profiler::Gateway::PerformCreateCommand(json const& jCom
|
||||||
if (!connector)
|
if (!connector)
|
||||||
throw std::runtime_error{ "Connector for requested peripheral is closed" };
|
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;
|
arguments = updatedArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "Relay.h"
|
#include "Relay.h"
|
||||||
#include "DeviceBridge.h"
|
#include "DeviceBridge.h"
|
||||||
#include "Common/FSecure/CppTools/ByteView.h"
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
#include "Common/FSecure/C3/Internals/InterfaceFactory.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()
|
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();
|
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
|
bool FSecure::C3::RouteId::operator!() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/FSecure/CppTools/ByteView.h"
|
#include "Common/FSecure/CppTools/ByteConverter/ByteConverter.h"
|
||||||
#include "Identifiers.h"
|
#include "Identifiers.h"
|
||||||
|
|
||||||
namespace FSecure::C3
|
namespace FSecure::C3
|
||||||
|
@ -26,10 +26,6 @@ namespace FSecure::C3
|
||||||
/// @param textId text containing the identifier.
|
/// @param textId text containing the identifier.
|
||||||
RouteId(std::string_view textId);
|
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.
|
/// Creates a RouteId object with a random ("unique") value.
|
||||||
/// @return Identifier object.
|
/// @return Identifier object.
|
||||||
static RouteId GenerateRandom();
|
static RouteId GenerateRandom();
|
||||||
|
@ -38,14 +34,6 @@ namespace FSecure::C3
|
||||||
/// @return a string that describes this ID object.
|
/// @return a string that describes this ID object.
|
||||||
std::string ToString() const;
|
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.
|
/// Logical negation operator. Can be used to check if ID is set.
|
||||||
/// @return true if ID is not set.
|
/// @return true if ID is not set.
|
||||||
bool operator !() const;
|
bool operator !() const;
|
||||||
|
@ -94,7 +82,7 @@ namespace FSecure
|
||||||
{
|
{
|
||||||
static ByteVector To(C3::RouteId const& obj)
|
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)
|
static size_t Size(C3::RouteId const& obj)
|
||||||
|
@ -104,9 +92,7 @@ namespace FSecure
|
||||||
|
|
||||||
static C3::RouteId From(ByteView& bv)
|
static C3::RouteId From(ByteView& bv)
|
||||||
{
|
{
|
||||||
auto ret = C3::RouteId(bv.SubString(0, C3::RouteId::BinarySize));
|
return ByteReader{ bv }.Create<C3::RouteId, decltype(C3::RouteId::m_AgentId), decltype(C3::RouteId::m_InterfaceId)>();
|
||||||
bv.remove_prefix(C3::RouteId::BinarySize);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue