urbackup_backend/clouddrive/CompressEncrypt.h
2021-05-08 20:52:31 +02:00

142 lines
3.1 KiB
C++

#pragma once
#include "ICompressEncrypt.h"
#include "../cryptoplugin/cryptopp_inc.h"
#include "../md5.h"
class CompressEncryptFactory : public ICompressEncryptFactory
{
public:
ICompressAndEncrypt* createCompressAndEncrypt(const std::string& encryption_key, IFile* file, IOnlineKvStore* online_kv_store, unsigned int compression_id);
IDecryptAndDecompress* createDecryptAndDecompress(const std::string& encryption_key, IFile* output_file);
};
void init_compress_encrypt_factory();
namespace
{
enum CompressResult
{
CompressResult_Ok,
CompressResult_End,
CompressResult_Other
};
enum DecompressResult
{
DecompressResult_Ok,
DecompressResult_End,
DecompressResult_Other
};
}
class ICompressor : public IObject
{
public:
virtual void setOut(char* next_out, size_t avail_out) = 0 ;
virtual void setIn(char* next_in, size_t avail_in) = 0;
virtual size_t getAvailOut() = 0;
virtual size_t getAvailIn() = 0;
virtual CompressResult compress(bool finish, int& code) = 0;
virtual unsigned int getId() = 0;
};
class IDecompressor : public IObject
{
public:
virtual void setOut(char* next_out, size_t avail_out) = 0;
virtual void setIn(char* next_in, size_t avail_in) = 0;
virtual size_t getAvailOut() = 0;
virtual size_t getAvailIn() = 0;
virtual DecompressResult decompress(int& code) = 0;
};
class CompressAndEncrypt : public ICompressAndEncrypt
{
public:
CompressAndEncrypt(const std::string& encryption_key, IFile* file, IOnlineKvStore* online_kv_store, ICompressor* compressor);
size_t read(char* buffer, size_t buffer_size);
int64 get_generation();
std::string md5sum();
size_t readBytes()
{
return ret_bytes;
}
private:
std::vector<char> output_buffer;
size_t output_buffer_pos;
IFile* file;
int64 file_pos;
IOnlineKvStore* online_kv_store;
CryptoPP::GCM< CryptoPP::AES >::Encryption encryption;
CryptoPP::AuthenticatedEncryptionFilter encryption_filter;
std::unique_ptr<ICompressor> compressor;
std::vector<char> read_buffer;
std::vector<char> compressed_buffer;
bool compression_ended;
int64 generation;
size_t ret_bytes;
int64 input_file_size;
MD5 md5;
};
const size_t iv_size_v1 = 24;
const size_t iv_size_v2 = 12;
enum EReadState
{
EReadState_Version,
EReadState_Iv,
EReadState_Data
};
class DecryptAndDecompress : public IDecryptAndDecompress
{
public:
DecryptAndDecompress(const std::string& encryption_key, IFile* output_file);
bool put(char* buffer, size_t buffer_size);
bool finalize();
std::string md5sum();
private:
bool decrypt();
bool init_decompression(unsigned int decompressor_id);
unsigned int version;
size_t iv_size;
EReadState read_state;
char header_buf[30];
size_t header_buf_pos;
std::unique_ptr<IDecompressor> decompressor;
std::vector<char> decrypted_buffer;
std::vector<char> output_buf;
CryptoPP::GCM< CryptoPP::AES >::Decryption decryption;
CryptoPP::AuthenticatedDecryptionFilter decryption_filter;
std::string encryption_key;
IFile* output_file;
int64 file_pos;
MD5 md5;
};
bool read_generation( IFile* file, int64 offset, int64& generation);