Fix format

This commit is contained in:
Michele Rodolfi 2020-12-13 00:56:18 +01:00
parent 3d89f30a94
commit 01ff00f3b7
20 changed files with 855 additions and 817 deletions

View File

@ -1,6 +1,6 @@
root = true
[*]
end_of_line = lf
indent_style = tab
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

View File

@ -1,3 +1,5 @@
#include "crypto.h"
#include <openssl/evp.h>
#include <string>
#include <vector>
#include <exception>
@ -7,9 +9,6 @@
#include <iostream>
#include <algorithm>
#include <openssl/evp.h>
#include "crypto.h"
#include "utils.h"
namespace horcrux {
@ -18,64 +17,69 @@ class EvpCipherCtx {
EVP_CIPHER_CTX *ptr;
public:
EvpCipherCtx(){
EvpCipherCtx() {
ptr = EVP_CIPHER_CTX_new();
}
~EvpCipherCtx(){
~EvpCipherCtx() {
EVP_CIPHER_CTX_free(ptr);
}
EVP_CIPHER_CTX* get(){
EVP_CIPHER_CTX* get() {
return ptr;
}
};
EvpCipherCtx AES256_CBC::init(Mode mode,
const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv){
if (key.size() != kKeySize){
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv) {
if (key.size() != kKeySize) {
throw std::runtime_error("Wrong key size");
}
if (iv.size() != kIvSize){
if (iv.size() != kIvSize) {
throw std::runtime_error("Wrong IV size");
}
EvpCipherCtx ctx;
if (mode == Mode::kEncrypt){
if (mode == Mode::kEncrypt) {
if (EVP_EncryptInit(ctx.get(), EVP_aes_256_cbc(),
(key.data()), (iv.data())) == 0){
key.data(), iv.data()) == 0) {
throw std::runtime_error("EVP_EncryptInit");
}
} else if (mode == Mode::kDecrypt){
} else if (mode == Mode::kDecrypt) {
if (EVP_DecryptInit(ctx.get(), EVP_aes_256_cbc(),
(key.data()), (iv.data())) == 0){
key.data(), iv.data()) == 0) {
throw std::runtime_error("EVP_DecryptInit");
}
} else throw std::invalid_argument("Invalid Cipher mode");
} else {
throw std::invalid_argument("Invalid Cipher mode");
}
return ctx;
}
size_t AES256_CBC::process_chunk(Mode mode, EvpCipherCtx& ctx,
size_t AES256_CBC::process_chunk(
Mode mode, EvpCipherCtx& ctx,
std::vector<unsigned char>::const_iterator begin,
std::vector<unsigned char>::const_iterator end,
std::vector<unsigned char>& output, size_t output_offset,
bool resize_in, bool resize_out)
{
bool resize_in, bool resize_out) {
auto chunk_size = end - begin;
int len;
if(resize_in){
if (resize_in) {
// Make sure ouput is large enough to add encrypted data + padding
output.resize(output_offset + chunk_size + kIvSize);
}
if (mode == Mode::kEncrypt) {
if (1 != EVP_EncryptUpdate(ctx.get(),
output.data() + output_offset, &len, &*begin, chunk_size)){
output.data() + output_offset, &len,
&*begin, chunk_size)) {
throw std::runtime_error("EVP_EncryptUpdate");
}
} else {
if (1 != EVP_DecryptUpdate(ctx.get(),
output.data() + output_offset, &len, &*begin, chunk_size)){
output.data() + output_offset, &len,
&*begin, chunk_size)) {
throw std::runtime_error("EVP_DecryptUpdate");
}
}
@ -85,20 +89,22 @@ size_t AES256_CBC::process_chunk(Mode mode, EvpCipherCtx& ctx,
}
size_t AES256_CBC::process_final(Mode mode, EvpCipherCtx& ctx,
std::vector<unsigned char>& output, size_t output_offset,
bool resize_in, bool resize_out)
{
std::vector<unsigned char>& output,
size_t output_offset,
bool resize_in, bool resize_out) {
int len;
if (resize_in) {
// Make sure output is large enough to add the last block
output.resize(output_offset + kIvSize);
}
if (mode == Mode::kEncrypt) {
if (1 != EVP_EncryptFinal_ex(ctx.get(), output.data() + output_offset, &len)){
if (1 != EVP_EncryptFinal_ex(ctx.get(), output.data() + output_offset,
&len)) {
throw std::runtime_error("EVP_EncryptFinal");
}
} else {
if (1 != EVP_DecryptFinal_ex(ctx.get(), (output.data()) + output_offset, &len)){
if (1 != EVP_DecryptFinal_ex(ctx.get(), (output.data()) + output_offset,
&len)) {
throw std::runtime_error("EVP_DecryptFinal");
}
}
@ -107,58 +113,65 @@ size_t AES256_CBC::process_final(Mode mode, EvpCipherCtx& ctx,
return len;
}
size_t AES256_CBC::process_all(Mode mode, EvpCipherCtx& ctx,
size_t AES256_CBC::process_all(
Mode mode, EvpCipherCtx& ctx,
std::vector<unsigned char>::const_iterator begin,
std::vector<unsigned char>::const_iterator end,
std::vector<unsigned char>& output, size_t output_offset,
bool resize_in, bool resize_out)
{
int len = process_chunk(mode, ctx, begin, end,
output, output_offset, resize_in, false);
len += process_final(mode, ctx,
output, output_offset + len, false, resize_out);
bool resize_in, bool resize_out) {
int len = process_chunk(mode, ctx, begin, end, output, output_offset,
resize_in, false);
len += process_final(mode, ctx, output, output_offset + len, false,
resize_out);
return len;
}
std::vector<unsigned char> AES256_CBC::process(const std::vector<unsigned char>& inputdata) {
std::vector<unsigned char> AES256_CBC::process(
const std::vector<unsigned char>& inputdata) {
if (mode == Mode::kEncrypt)
return encrypt(inputdata);
else
return decrypt(inputdata);
}
std::vector<unsigned char> AES256_CBC::encrypt(const std::vector<unsigned char>& plaintext) {
return encrypt(encryption_key, horcrux::generate_random(kIvSize), plaintext);
std::vector<unsigned char> AES256_CBC::encrypt(
const std::vector<unsigned char>& plaintext) {
return encrypt(encryption_key, horcrux::generate_random(kIvSize),
plaintext);
}
std::vector<unsigned char> AES256_CBC::decrypt(const std::vector<unsigned char>& ciphertext) {
std::vector<unsigned char> AES256_CBC::decrypt(
const std::vector<unsigned char>& ciphertext) {
return decrypt(encryption_key, ciphertext);
}
std::vector<unsigned char> AES256_CBC::encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input)
{
std::vector<unsigned char> AES256_CBC::encrypt(
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input) {
auto ctx = init(Mode::kEncrypt, key, iv);
// Make sure ouput is large enough to contain IV + encrypted data + padding
std::vector<unsigned char> output(input.size() + (2 * kIvSize));
std::copy(iv.begin(), iv.end(), output.begin());
process_all(Mode::kEncrypt, ctx, input.begin(), input.end(), output, kIvSize);
process_all(Mode::kEncrypt, ctx, input.begin(), input.end(), output,
kIvSize);
return output;
}
int AES256_CBC::encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input, std::vector<unsigned char>& output)
{
int AES256_CBC::encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input,
std::vector<unsigned char>& output) {
auto ctx = init(Mode::kEncrypt, key, iv);
process_all(Mode::kEncrypt, ctx, input.begin(), input.end(), output, 0);
return 0;
}
int AES256_CBC::encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
int AES256_CBC::encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
std::istream input, const size_t input_len,
std::ostream output, size_t& output_len){
std::ostream output, size_t& output_len) {
auto inbuf = std::vector<unsigned char>(input_len);
auto outbuf = std::vector<unsigned char>(input_len + 16);
input.read(reinterpret_cast<char*>(inbuf.data()), input_len);
@ -170,25 +183,29 @@ int AES256_CBC::encrypt(const std::vector<unsigned char>& key, const std::vector
return 0;
}
int AES256_CBC::decrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input, std::vector<unsigned char>& output)
{
int AES256_CBC::decrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input,
std::vector<unsigned char>& output) {
auto ctx = init(Mode::kDecrypt, key, iv);
process_all(Mode::kDecrypt, ctx, input.begin(), input.end(), output, 0);
return 0;
}
std::vector<unsigned char> AES256_CBC::decrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& ciphertext){
std::vector<unsigned char> iv(ciphertext.begin(), ciphertext.begin() + kIvSize);
std::vector<unsigned char> AES256_CBC::decrypt(
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& ciphertext) {
std::vector<unsigned char> iv(ciphertext.begin(),
ciphertext.begin() + kIvSize);
return decrypt(key, iv, ciphertext.begin() + kIvSize, ciphertext.end());
}
std::vector<unsigned char> AES256_CBC::decrypt(
const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
std::vector<unsigned char>::const_iterator begin, std::vector<unsigned char>::const_iterator end)
{
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
std::vector<unsigned char>::const_iterator begin,
std::vector<unsigned char>::const_iterator end) {
auto ctx = init(Mode::kDecrypt, key, iv);
std::vector<unsigned char> output;
process_all(Mode::kDecrypt, ctx, begin, end, output, 0);
return output;
}
}; //namespace
}; // namespace horcrux

View File

@ -8,12 +8,12 @@
namespace horcrux {
enum class Mode {kEncrypt, kDecrypt};
enum class Mode { kEncrypt, kDecrypt };
class Cipher {
protected:
Cipher() = delete;
Cipher(Mode m) : mode(m) { }
explicit Cipher(Mode m) : mode(m) { }
Cipher(Mode m, const std::vector<unsigned char>& key) :
mode(m), encryption_key(key) {}
@ -21,18 +21,25 @@ protected:
mode(m), encryption_key(key) {}
std::vector<unsigned char> encryption_key;
public:
const Mode mode;
const std::vector<unsigned char>& get_encryption_key() {return encryption_key;}
const std::vector<unsigned char>& get_encryption_key() {
return encryption_key;
}
virtual std::vector<unsigned char> process(const std::vector<unsigned char>& inputdata) = 0;
virtual std::vector<unsigned char> encrypt(const std::vector<unsigned char>& plaintext) = 0;
virtual std::vector<unsigned char> decrypt(const std::vector<unsigned char>& ciphertext) = 0;
virtual std::vector<unsigned char> process(
const std::vector<unsigned char>& inputdata) = 0;
virtual std::vector<unsigned char> encrypt(
const std::vector<unsigned char>& plaintext) = 0;
virtual std::vector<unsigned char> decrypt(
const std::vector<unsigned char>& ciphertext) = 0;
};
class EvpCipherCtx;
class AES256_CBC : public Cipher {
const size_t kKeySize = 32;
const size_t kIvSize = 16;
@ -40,53 +47,67 @@ public:
AES256_CBC() : Cipher(Mode::kEncrypt) {
encryption_key = horcrux::generate_random(kKeySize);
}
AES256_CBC(const std::vector<unsigned char>& key) : Cipher(Mode::kDecrypt, key)
{
explicit AES256_CBC(const std::vector<unsigned char>& key)
: Cipher(Mode::kDecrypt, key) {
if (key.size() != kKeySize)
throw std::invalid_argument("Invalid key size");
}
AES256_CBC(std::vector<unsigned char>&& key) : Cipher(Mode::kDecrypt, key)
{
explicit AES256_CBC(std::vector<unsigned char>&& key)
: Cipher(Mode::kDecrypt, key) {
if (key.size() != kKeySize)
throw std::invalid_argument("Invalid key size");
}
std::vector<unsigned char> process(const std::vector<unsigned char>& inputdata) override;
std::vector<unsigned char> encrypt(const std::vector<unsigned char>& plaintext) override;
std::vector<unsigned char> decrypt(const std::vector<unsigned char>& ciphertext) override;
std::vector<unsigned char> process(
const std::vector<unsigned char>& inputdata) override;
std::vector<unsigned char> encrypt(
const std::vector<unsigned char>& plaintext) override;
std::vector<unsigned char> decrypt(
const std::vector<unsigned char>& ciphertext) override;
std::vector<unsigned char> encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
std::vector<unsigned char> encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input);
int encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input, std::vector<unsigned char>& output);
int encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input,
std::vector<unsigned char>& output);
int encrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
int encrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
std::istream input, const size_t input_len,
std::ostream output, size_t& output_len);
int decrypt(const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input, std::vector<unsigned char>& output);
int decrypt(const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& input,
std::vector<unsigned char>& output);
std::vector<unsigned char> decrypt(const std::vector<unsigned char>& key,
std::vector<unsigned char> decrypt(
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& ciphertext);
std::vector<unsigned char> decrypt(
const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv,
std::vector<unsigned char>::const_iterator begin, std::vector<unsigned char>::const_iterator end);
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
std::vector<unsigned char>::const_iterator begin,
std::vector<unsigned char>::const_iterator end);
private:
EvpCipherCtx init(Mode mode,
const std::vector<unsigned char>& key, const std::vector<unsigned char>& iv);
EvpCipherCtx init(Mode mode, const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv);
size_t process_chunk(Mode mode, EvpCipherCtx& ctx,
std::vector<unsigned char>::const_iterator begin,
std::vector<unsigned char>::const_iterator end,
std::vector<unsigned char>& output, size_t output_offset,
std::vector<unsigned char>& output,
size_t output_offset,
bool resize_in = true, bool resize_out = true);
size_t process_final(Mode mode, EvpCipherCtx& ctx,
std::vector<unsigned char>& output, size_t output_offset,
std::vector<unsigned char>& output,
size_t output_offset,
bool resize_in = true, bool resize_out = true);
size_t process_all(Mode mode, EvpCipherCtx& ctx,
@ -96,5 +117,5 @@ private:
bool resize_in = true, bool resize_out = true);
};
}; //namespace
#endif //HORCRUX_SRC_CRYPTO_H
}; // namespace horcrux
#endif // HORCRUX_SRC_CRYPTO_H

View File

@ -1,17 +1,17 @@
#include "horcrux.h"
#include <iostream>
#include <exception>
#include "horcrux.h"
#include "utils.h"
namespace horcrux {
Horcrux::Horcrux(HorcruxOptions&& opt) : options(opt){ init(); }
Horcrux::Horcrux(const HorcruxOptions& opt) : options(opt){ init(); }
void Horcrux::init(){
if (options.count <= 0){
Horcrux::Horcrux(HorcruxOptions&& opt) : options(opt) { init(); }
Horcrux::Horcrux(const HorcruxOptions& opt) : options(opt) { init(); }
void Horcrux::init() {
if (options.count <= 0) {
throw std::invalid_argument("Invalid horcrux count");
}
switch (options.mode){
switch (options.mode) {
case Mode::kEncrypt:
cipher = std::make_unique<AES256_CBC>();
input = std::make_unique<FsPlainInput>(options.input[0]);
@ -20,8 +20,9 @@ void Horcrux::init(){
options.base64_key = to_base64(cipher->get_encryption_key());
break;
case Mode::kDecrypt:
if (options.count != options.input.size())
if (options.count != options.input.size()) {
throw std::invalid_argument("Invalid horcrux count");
}
cipher = std::make_unique<AES256_CBC>(from_base64(options.base64_key));
input = std::make_unique<FsCryptoInput>(options.input);
output = std::make_unique<FsPlainOutput>(options.output);
@ -31,31 +32,31 @@ void Horcrux::init(){
}
}
void Horcrux::execute(){
void Horcrux::execute() {
if (options.mode == Mode::kEncrypt)
output->write(cipher->encrypt(input->read()));
else
output->write(cipher->decrypt(input->read()));
}
static void print_usage(const std::string& program){
static void print_usage(const std::string& program) {
std::cout << "Usage:" << std::endl <<
"\t\t" << program << " create -n <horcrux count> <input path> <output path>" << std::endl <<
"\t\t" << program << " load -k <decryption key> <input files> <output_path>" << std::endl;
}
static void parse_error(const std::string& program, const std::string& error){
static void parse_error(const std::string& program, const std::string& error) {
print_usage(program);
throw std::invalid_argument(error);
}
HorcruxOptions parse_arguments(std::vector<std::string>&& arguments){
if (arguments.size() < 6){
HorcruxOptions parse_arguments(std::vector<std::string>&& arguments) {
if (arguments.size() < 6) {
parse_error(std::string(arguments[0]), "Wrong argument number");
}
HorcruxOptions opt;
if (arguments[1] == "create") {
if (arguments.size() != 6){
if (arguments.size() != 6) {
parse_error(std::string(arguments[0]), "Wrong argument number");
}
opt.mode = Mode::kEncrypt;
@ -64,12 +65,13 @@ HorcruxOptions parse_arguments(std::vector<std::string>&& arguments){
opt.count = std::stoi(arguments[3]);
opt.input.emplace_back(arguments[4]);
opt.output = arguments[5];
} else if (arguments[1] == "load"){
} else if (arguments[1] == "load") {
opt.mode = Mode::kDecrypt;
if (arguments[2] != "-k")
parse_error(arguments[0], "load: unknown option " + arguments[2]);
opt.base64_key = arguments[3];
opt.input.insert(opt.input.begin(), arguments.begin() + 4, arguments.end() - 1);
opt.input.insert(opt.input.begin(), arguments.begin() + 4,
arguments.end() - 1);
opt.count = opt.input.size();
opt.output = arguments.back();
} else {
@ -77,6 +79,4 @@ HorcruxOptions parse_arguments(std::vector<std::string>&& arguments){
}
return opt;
}
}; //namespace
}; // namespace horcrux

View File

@ -18,7 +18,6 @@ struct HorcruxOptions {
};
class Horcrux {
HorcruxOptions options;
std::unique_ptr<Cipher> cipher;
std::unique_ptr<Input> input;
@ -27,15 +26,14 @@ class Horcrux {
void init();
public:
Horcrux(const HorcruxOptions& opt);
Horcrux(HorcruxOptions&& opt);
explicit Horcrux(const HorcruxOptions& opt);
explicit Horcrux(HorcruxOptions&& opt);
void execute();
const Mode& mode() { return options.mode; }
const std::string& key() { return options.base64_key; }
};
HorcruxOptions parse_arguments(std::vector<std::string>&& arguments);
}; //namespace
#endif //HORCRUX_HORCRUX_H
}; // namespace horcrux
#endif // HORCRUX_HORCRUX_H

View File

@ -1,50 +1,49 @@
#include <iostream>
#include "io.h"
#include <iostream>
#include "utils.h"
namespace horcrux {
namespace fs = std::filesystem;
FsPlainInput::FsPlainInput(const std::string& path) : file_path(fs::absolute(path))
{
if (fs::status(path).type() != fs::file_type::regular){
FsPlainInput::FsPlainInput(const std::string& path)
: file_path(fs::absolute(path)) {
if (fs::status(path).type() != fs::file_type::regular) {
throw std::invalid_argument("Input is not a regular file");
}
file_size = fs::file_size(file_path);
if (file_size == 0){
if (file_size == 0) {
throw std::invalid_argument("Input is empty, nothing to encrypt");
}
file_stream = std::ifstream(file_path, std::ios::binary);
}
std::vector<unsigned char> FsPlainInput::read(){
std::vector<unsigned char> FsPlainInput::read() {
std::vector<unsigned char> result(file_size);
file_stream.read(reinterpret_cast<char*>(result.data()), file_size);
return result;
}
FsCryptoInput::FsCryptoInput(const std::vector<std::string>& filenames)
{
FsCryptoInput::FsCryptoInput(const std::vector<std::string>& filenames) {
if (filenames.empty()){
throw std::invalid_argument("No files to decrypt");
}
for (auto name : filenames){
for (auto name : filenames) {
auto path = absolute(fs::absolute({name}));
if (fs::status(path).type() != fs::file_type::regular){
if (fs::status(path).type() != fs::file_type::regular) {
throw std::invalid_argument("Input is not a regular file");
}
file_paths.emplace_back(path, fs::file_size(path));
total_size += file_paths.back().second;
}
if (total_size == 0){
if (total_size == 0) {
throw std::invalid_argument("No data to decrypt");
}
}
std::vector<unsigned char> FsCryptoInput::read(){
std::vector<unsigned char> FsCryptoInput::read() {
std::vector<unsigned char> result(total_size);
size_t data_read{0};
for (auto& f : file_paths){
for (auto& f : file_paths) {
std::ifstream ifstream(f.first);
ifstream.read(reinterpret_cast<char*>(result.data()) + data_read, f.second);
data_read += f.second;
@ -53,13 +52,13 @@ std::vector<unsigned char> FsCryptoInput::read(){
}
FsPlainOutput::FsPlainOutput(const std::string& filename)
: file_path(fs::absolute(filename))
{
if (fs::exists(file_path) && fs::status(file_path).type() != fs::file_type::regular){
: file_path(fs::absolute(filename)) {
if (fs::exists(file_path)
&& fs::status(file_path).type() != fs::file_type::regular) {
throw std::invalid_argument("Output file is not a regular file");
}
}
size_t FsPlainOutput::write(const std::vector<unsigned char>& to_write){
size_t FsPlainOutput::write(const std::vector<unsigned char>& to_write) {
std::ofstream out(file_path, std::ios::binary);
out.write(reinterpret_cast<const char*>(to_write.data()), to_write.size());
return to_write.size();
@ -68,29 +67,29 @@ size_t FsPlainOutput::write(const std::vector<unsigned char>& to_write){
FsCryptoOutput::FsCryptoOutput(const std::string& folder, const int horcrux_num,
const std::string& filename, const size_t horcrux_size)
: folder_path(fs::absolute(folder)), base_name(filename),
num(horcrux_num), size(horcrux_size)
{
if (fs::status(folder_path).type() != fs::file_type::directory){
num(horcrux_num), size(horcrux_size) {
if (fs::status(folder_path).type() != fs::file_type::directory) {
throw std::invalid_argument("Output is not a directory");
}
if (horcrux_num <= 0){
if (horcrux_num <= 0) {
throw std::invalid_argument("Invalid horcrux num");
}
}
size_t FsCryptoOutput::write(const std::vector<unsigned char>& to_write){
size_t FsCryptoOutput::write(const std::vector<unsigned char>& to_write) {
size = to_write.size() / num;
std::ofstream f;
created_files.clear();
size_t data_written{0};
for (int i = 0; i < num; ++i){
for (int i = 0; i < num; ++i) {
std::string name = base_name + '.' + std::to_string(i) + ".enc";
created_files.emplace_back(folder_path / name);
f = std::ofstream(created_files.back(),
std::ios::binary | std::ios::trunc);
auto chunk_size = i + 1 != num ? size : size + to_write.size() % size;
f.write(reinterpret_cast<const char*>(to_write.data()) + data_written, chunk_size);
f.write(reinterpret_cast<const char*>(to_write.data()) + data_written,
chunk_size);
data_written += chunk_size;
}
return data_written;

View File

@ -4,6 +4,7 @@
#include <filesystem>
#include <fstream>
#include <vector>
#include <utility>
namespace horcrux {
@ -27,7 +28,7 @@ class FsPlainInput : public Input {
FsPlainInput() = delete;
public:
FsPlainInput(const std::string& path);
explicit FsPlainInput(const std::string& path);
std::vector<unsigned char> read() override;
};
@ -37,7 +38,7 @@ class FsCryptoInput : public Input{
FsCryptoInput() = delete;
public:
FsCryptoInput(const std::vector<std::string>& filenames);
explicit FsCryptoInput(const std::vector<std::string>& filenames);
std::vector<unsigned char> read() override;
};
@ -46,7 +47,7 @@ class FsPlainOutput : public Output {
FsPlainOutput() = delete;
public:
FsPlainOutput(const std::string& filename);
explicit FsPlainOutput(const std::string& filename);
size_t write(const std::vector<unsigned char>& to_write) override;
};
@ -61,8 +62,9 @@ public:
std::vector<std::filesystem::path> created_files;
FsCryptoOutput(const std::string& folder, const int horcrux_num,
const std::string& filename = "horcrux", const size_t horcrux_size = 0);
const std::string& filename = "horcrux",
const size_t horcrux_size = 0);
size_t write(const std::vector<unsigned char>& to_write) override;
};
};
#endif //HORCRUX_SRC_IO_H
}; // namespace horcrux
#endif // HORCRUX_SRC_IO_H

View File

@ -5,23 +5,23 @@
int main(const int argc, const char *argv[]) {
int ret = -1;
std::vector<std::string> arguments;
for (int i = 0; i < argc; ++i){
for (int i = 0; i < argc; ++i) {
arguments.emplace_back(argv[i]);
}
try {
horcrux::Horcrux h(horcrux::parse_arguments(std::move(arguments)));
h.execute();
if (h.mode() == horcrux::Mode::kEncrypt){
//print encryption key to stdout
if (h.mode() == horcrux::Mode::kEncrypt) {
// print encryption key to stdout
std::cout << h.key() << std::endl;
}
ret = 0;
} catch (std::invalid_argument& ex){
} catch (std::invalid_argument& ex) {
std::cerr << "Error: Invalid arguments. " << ex.what() << std::endl;
} catch (std::runtime_error& ex){
} catch (std::runtime_error& ex) {
std::cerr << "Runtime error: " << ex.what() << std::endl;
} catch (std::exception& ex){
} catch (std::exception& ex) {
std::cerr << "Unknown error: " << ex.what() << std::endl;
}

View File

@ -1,40 +1,38 @@
#include "utils.h"
#include <openssl/rand.h>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <openssl/rand.h>
#include "utils.h"
std::string horcrux::to_base64(const std::vector<unsigned char>& binary)
{
std::string horcrux::to_base64(const std::vector<unsigned char>& binary) {
using namespace boost::archive::iterators;
using It = base64_from_binary<transform_width<std::vector<unsigned char>::const_iterator, 6, 8>>;
using It = base64_from_binary<transform_width<
std::vector<unsigned char>::const_iterator, 6, 8>>;
auto base64 = std::string(It(binary.begin()), It(binary.end()));
// Add padding.
return base64.append((3 - binary.size() % 3) % 3, '=');
}
std::vector<unsigned char> horcrux::from_base64(const std::string& base64)
{
std::vector<unsigned char> horcrux::from_base64(const std::string& base64) {
using namespace boost::archive::iterators;
using It = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
auto binary = std::vector<unsigned char>(It(base64.begin()), It(base64.end()));
using It = transform_width<binary_from_base64<std::string::const_iterator>,
8, 6>;
auto binary = std::vector<unsigned char>(It(base64.begin()),
It(base64.end()));
// Remove padding.
auto length = base64.size();
if(binary.size() > 2 && base64[length - 1] == '=' && base64[length - 2] == '=')
{
if (binary.size() > 2 && base64[length - 1] == '='
&& base64[length - 2] == '=') {
binary.erase(binary.end() - 2, binary.end());
}
else if(binary.size() > 1 && base64[length - 1] == '=')
{
} else if (binary.size() > 1 && base64[length - 1] == '=') {
binary.erase(binary.end() - 1, binary.end());
}
return binary;
}
std::vector<unsigned char> horcrux::generate_random(const size_t size){
std::vector<unsigned char> horcrux::generate_random(const size_t size) {
std::vector<unsigned char> res(size);
if(!RAND_bytes(res.data(), size)){
if (!RAND_bytes(res.data(), size)) {
throw std::exception();
}
return res;

View File

@ -11,4 +11,4 @@ std::vector<unsigned char> from_base64(const std::string& base64);
std::vector<unsigned char> generate_random(const size_t buf_len);
}
#endif //HORCRUX_SRC_UTILS_H
#endif // HORCRUX_SRC_UTILS_H

View File

@ -1,8 +1,8 @@
#include "gtest/gtest.h"
#include "test.h"
#include "gtest/gtest.h"
/* Utility functions */
std::vector<unsigned char> generic_read_file(const std::string& filename){
std::vector<unsigned char> generic_read_file(const std::string& filename) {
auto ifstream = std::ifstream{filename, std::ios::binary};
auto path = std::filesystem::path{filename};
auto size = std::filesystem::file_size(path);
@ -11,24 +11,27 @@ std::vector<unsigned char> generic_read_file(const std::string& filename){
return buf;
}
std::vector<std::string> get_created_filenames(const horcrux::FsCryptoOutput& out){
std::vector<std::string> get_created_filenames(
const horcrux::FsCryptoOutput& out) {
std::vector<std::string> result(out.created_files.size());
transform(out.created_files.begin(), out.created_files.end(), result.begin(),
[](auto path){return path.string();});
transform(out.created_files.begin(), out.created_files.end(),
result.begin(), [](auto path) { return path.string(); } );
return result;
}
void delete_created_files(const horcrux::FsCryptoOutput& out){
void delete_created_files(const horcrux::FsCryptoOutput& out) {
std::for_each(out.created_files.begin(), out.created_files.end(),
[](auto f){std::filesystem::remove(f);});
[](auto f) { std::filesystem::remove(f); } );
}
std::vector<std::string> get_encrypted_files(const std::string& folder, const std::string& basename) {
std::vector<std::string> get_encrypted_files(const std::string& folder,
const std::string& basename) {
std::vector<std::string> result;
for (auto& p: std::filesystem::directory_iterator(folder)){
if (p.path().string().starts_with(basename) &&
p.path().string().ends_with(".enc"))
for (auto& p: std::filesystem::directory_iterator(folder)) {
if (p.path().string().starts_with(basename)
&& p.path().string().ends_with(".enc")) {
result.push_back(p.path().string());
}
}
std::sort(result.begin(), result.end());
return result;
}