diff --git a/src/horcrux.cpp b/src/horcrux.cpp index 3fd9899..0a64cf2 100644 --- a/src/horcrux.cpp +++ b/src/horcrux.cpp @@ -5,8 +5,6 @@ namespace horcrux { -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"); @@ -32,7 +30,7 @@ void Horcrux::init() { } } -void Horcrux::execute() { +void Horcrux::run() { if (options.mode == Mode::kEncrypt) output->write(cipher->encrypt(input->read())); else diff --git a/src/horcrux.h b/src/horcrux.h index f0c270d..dfe9261 100644 --- a/src/horcrux.h +++ b/src/horcrux.h @@ -9,30 +9,55 @@ namespace horcrux { +/** @brief options */ struct HorcruxOptions { + /// encrypt (create) or decrypt (load) Mode mode; + /// number of horcrux files (input or output) int count; + /// input files (if mode is created, there is only one input file) std::vector input; + /// output file or folder std::string output; + /// base64 encoded key for decryption std::string base64_key; }; class Horcrux { + /// horcrux parameters HorcruxOptions options; + /// cipher to use std::unique_ptr cipher; + /// input to use std::unique_ptr input; + /// output to use std::unique_ptr output; + /** @brief initialize the Horcrux based on provided options + * @details + * Used cipher, input and output are generic and the actual implementation + * can be selected in this function */ void init(); public: - explicit Horcrux(const HorcruxOptions& opt); - explicit Horcrux(HorcruxOptions&& opt); - void execute(); + /** remove default constructor */ + Horcrux() = delete; + /** @brief constructor + * @param opt the Horcrux parameters */ + explicit Horcrux(const HorcruxOptions& opt) : options(opt) { init (); } + /** get the horcrux mode */ const Mode& mode() { return options.mode; } + /** retreive the base64 encoded key used for decryption/encryption */ const std::string& key() { return options.base64_key; } -}; + /** @brief execute the horcrux process + * @details read from Input, process with Cipher and write to output */ + void run(); +}; +/** @brief utility function to parse the command line arguments + * @param arguments arguments as read from command line + * @return a filled Options object + */ HorcruxOptions parse_arguments(std::vector&& arguments); }; // namespace horcrux diff --git a/src/io.h b/src/io.h index 096d850..680bf21 100644 --- a/src/io.h +++ b/src/io.h @@ -8,64 +8,126 @@ namespace horcrux { +/** @brief Base Class for Input + * @details Derive from this class to implement new Inputs */ class Input { public: virtual ~Input() = default; + /** @brief Read from the input + * @return new buffer containing all read data */ virtual std::vector read() = 0; }; + +/** @brief Base Class for Output + * @details Derive from this class to implement new Outputs */ class Output { public: virtual ~Output() = default; + /** @brief Write to the output + * @param data to write + * @return written data */ virtual size_t write(const std::vector& data) = 0; }; +/** @brief Input that reads data from a regular file */ class FsPlainInput : public Input { + /// input file path std::filesystem::path file_path; + /// input file size size_t file_size; + /// input file stream associated to the input file std::ifstream file_stream; + /// remove default constructor FsPlainInput() = delete; public: - explicit FsPlainInput(const std::string& path); virtual ~FsPlainInput() = default; + + /** @brief constructor + * @param path input file path, must be a regular file */ + explicit FsPlainInput(const std::string& path); + + /** @brief Read from the input + * @return new buffer containing all read data */ std::vector read() override; }; +/** @brief Input that reads scattered data from multiple files */ class FsCryptoInput : public Input{ + /// input files paths std::vector> file_paths; + /// total size of input files size_t total_size{0}; + /// remove default constuctor FsCryptoInput() = delete; public: - explicit FsCryptoInput(const std::vector& filenames); virtual ~FsCryptoInput() = default; + + /* @brief constructor + * @param filenames paths of input files. They will be read in this order */ + explicit FsCryptoInput(const std::vector& filenames); + + /** @brief Read from the input + * @details basically concatenate the input files. + * @return new buffer containing all read data */ std::vector read() override; }; +/** @brief Output that writes to a single regular file */ class FsPlainOutput : public Output { + /// output file path std::filesystem::path file_path; + /// remove default constructor FsPlainOutput() = delete; public: - explicit FsPlainOutput(const std::string& filename); virtual ~FsPlainOutput() = default; + + /** @brief constructor + * @param filename output file. It can be a new file, it must be writable */ + explicit FsPlainOutput(const std::string& filename); + + /** @brief Write to the output + * @param data to write + * @return written data */ size_t write(const std::vector& to_write) override; }; +/** @brief Output that splits the data in equal size chunks and writes them to + * files. + * @details The output files will be created in a user provided folder and + * named as \"basename.n.enc\" where n is a progressive number. */ class FsCryptoOutput : public Output { + /// folder that contains the output files std::filesystem::path folder_path; + /// base name for the output files. std::string base_name; + /// num of the output files int num; + /// size of each ouptut file size_t size; + /// remove default constructor FsCryptoOutput() = delete; public: + /// list of created files std::vector created_files; + virtual ~FsCryptoOutput() = default; + + /** @brief constructor + * @param folder folder where to create the output files + * @param horcrux_num num of ouput files + * @param filename basename for output file + * @param horcrux_size specify output files size. Optional */ FsCryptoOutput(const std::string& folder, const int horcrux_num, const std::string& filename = "horcrux", const size_t horcrux_size = 0); - virtual ~FsCryptoOutput() = default; + + /** @brief Write to the output + * @param data to write + * @return written data */ size_t write(const std::vector& to_write) override; }; }; // namespace horcrux diff --git a/src/main.cpp b/src/main.cpp index da6b2ab..d0287fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,7 @@ int main(const int argc, const char *argv[]) { try { horcrux::Horcrux h(horcrux::parse_arguments(std::move(arguments))); - h.execute(); + h.run(); if (h.mode() == horcrux::Mode::kEncrypt) { // print encryption key to stdout std::cout << h.key() << std::endl; diff --git a/src/utils.h b/src/utils.h index ca752e0..9552dea 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,7 +8,7 @@ namespace horcrux { std::string to_base64(const std::vector& binary); std::vector from_base64(const std::string& base64); -std::vector generate_random(const size_t buf_len); +std::vector generate_random(const size_t size); } #endif // HORCRUX_SRC_UTILS_H diff --git a/test/integration-test.cpp b/test/integration-test.cpp index d020571..18517b3 100644 --- a/test/integration-test.cpp +++ b/test/integration-test.cpp @@ -71,7 +71,7 @@ TEST(IntegrationTest, HorcruxEncryptiDecrypt) { }; Horcrux enc{options}; - enc.execute(); + enc.run(); auto key = enc.key(); HorcruxOptions options2 { @@ -83,7 +83,7 @@ TEST(IntegrationTest, HorcruxEncryptiDecrypt) { }; Horcrux dec{options2}; - dec.execute(); + dec.run(); //Compare input and ouput files EXPECT_EQ(generic_read_file(image), generic_read_file(noexist));