94 lines
2.3 KiB
C++
94 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <mio/mmap.hpp>
|
|
#include <sodium.h>
|
|
|
|
class CBufferPool;
|
|
|
|
constexpr std::size_t M2PACK_MAGIC_SIZE = 8;
|
|
constexpr std::size_t M2PACK_HASH_SIZE = 32;
|
|
constexpr std::size_t M2PACK_SIGNATURE_SIZE = 64;
|
|
constexpr std::size_t M2PACK_KEY_SIZE = crypto_aead_xchacha20poly1305_ietf_KEYBYTES;
|
|
constexpr std::size_t M2PACK_NONCE_SIZE = crypto_aead_xchacha20poly1305_ietf_NPUBBYTES;
|
|
constexpr std::size_t M2PACK_PUBLIC_KEY_SIZE = crypto_sign_PUBLICKEYBYTES;
|
|
|
|
#pragma pack(push, 1)
|
|
struct TM2PackHeader
|
|
{
|
|
char magic[M2PACK_MAGIC_SIZE];
|
|
uint32_t version;
|
|
uint32_t flags;
|
|
uint32_t key_id;
|
|
uint64_t manifest_offset;
|
|
uint64_t manifest_size;
|
|
uint8_t manifest_hash[M2PACK_HASH_SIZE];
|
|
uint8_t manifest_signature[M2PACK_SIGNATURE_SIZE];
|
|
uint8_t reserved[60];
|
|
};
|
|
|
|
struct TM2PackManifestHeader
|
|
{
|
|
uint32_t entry_count;
|
|
uint32_t flags;
|
|
};
|
|
|
|
struct TM2PackManifestEntryFixed
|
|
{
|
|
uint16_t path_size;
|
|
uint8_t compression;
|
|
uint8_t flags;
|
|
uint64_t data_offset;
|
|
uint64_t original_size;
|
|
uint64_t stored_size;
|
|
uint8_t nonce[M2PACK_NONCE_SIZE];
|
|
uint8_t plaintext_hash[M2PACK_HASH_SIZE];
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
struct TM2PackEntry
|
|
{
|
|
std::string path;
|
|
uint8_t compression = 0;
|
|
uint64_t data_offset = 0;
|
|
uint64_t original_size = 0;
|
|
uint64_t stored_size = 0;
|
|
std::array<uint8_t, M2PACK_NONCE_SIZE> nonce {};
|
|
std::array<uint8_t, M2PACK_HASH_SIZE> plaintext_hash {};
|
|
};
|
|
|
|
class CM2Pack : public std::enable_shared_from_this<CM2Pack>
|
|
{
|
|
public:
|
|
CM2Pack() = default;
|
|
~CM2Pack() = default;
|
|
|
|
bool Load(const std::string& path);
|
|
const std::vector<TM2PackEntry>& GetIndex() const { return m_index; }
|
|
|
|
bool GetFile(const TM2PackEntry& entry, std::vector<uint8_t>& result);
|
|
bool GetFileWithPool(const TM2PackEntry& entry, std::vector<uint8_t>& result, CBufferPool* pPool);
|
|
|
|
private:
|
|
bool ValidateManifest();
|
|
bool DecryptEntryPayload(const TM2PackEntry& entry, std::vector<uint8_t>& decrypted, CBufferPool* pPool);
|
|
|
|
private:
|
|
TM2PackHeader m_header {};
|
|
std::vector<uint8_t> m_manifest_bytes;
|
|
std::vector<TM2PackEntry> m_index;
|
|
mio::mmap_source m_file;
|
|
};
|
|
|
|
using TM2PackFileMapEntry = std::pair<std::shared_ptr<CM2Pack>, TM2PackEntry>;
|
|
using TM2PackFileMap = std::unordered_map<std::string, TM2PackFileMapEntry>;
|
|
|
|
#include "M2PackKeys.h"
|