From adea0bada1d719c47cb6a27daccc73a72d37eaca Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Wed, 24 Mar 2021 20:21:59 +0100 Subject: [PATCH] Added examples on how to use the C++11 API + added explicit compiler checks. --- README.md | 6 +- examples/example_decrypt.cpp | 115 +++++++++++++++++++++++++++ examples/example_encrypt.cpp | 113 ++++++++++++++++++++++++++ libslunkcrypt/include/slunkcrypt.h | 10 ++- libslunkcrypt/include/slunkcrypt.hpp | 31 ++++++-- 5 files changed, 264 insertions(+), 11 deletions(-) create mode 100644 examples/example_decrypt.cpp create mode 100644 examples/example_encrypt.cpp diff --git a/README.md b/README.md index 1077533..f819132 100644 --- a/README.md +++ b/README.md @@ -414,10 +414,10 @@ Erase the contents of a byte array, by overwriting it with *zero* bytes. Compile The size of the buffer to be erased, in bytes. -C++ API -------- +C++11 API +--------- -This section describes the "high-level" C++ API of the SlunkCypt library. +This section describes the "high-level" C++11 API of the SlunkCypt library. ### SlunkCryptEncr diff --git a/examples/example_decrypt.cpp b/examples/example_decrypt.cpp new file mode 100644 index 0000000..248b18f --- /dev/null +++ b/examples/example_decrypt.cpp @@ -0,0 +1,115 @@ +/******************************************************************************/ +/* SlunkCrypt, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +//SlunkCrypt API +#include + +//CRT +#include +#include +#include + +//Example password +static std::string EXAMPLE_PASSWORD("cMRe5E5D)'!2?5]QDlCQ4tBb"); + +//Const +#define BUFF_SIZE 4096U + +static int decrypt_main(int argc, char *argv[]) +{ + std::cerr << "SlunkCrypt decrypt sample [" << __DATE__ << "]" << std::endl; + std::cerr << "using libSlunkCrypt v" << SLUNKCRYPT_VERSION_MAJOR << '.' << SLUNKCRYPT_VERSION_MINOR << '.' << SLUNKCRYPT_VERSION_PATCH << '\n' << std::endl; + + if (argc < 4) + { + std::cerr << "Usage:\n decrypt.exe \n" << std::endl; + return -1; + } + + const uint64_t nonce = std::strtoull(argv[1], NULL, 16); + + // ----------------------------------------------------------- + // Open input/output files + // ----------------------------------------------------------- + + std::ifstream file_src(argv[2], std::ios::binary); + if (!file_src.is_open()) + { + std::cerr << "Error: Failed to open input file for reading!" << std::endl; + return -1; + } + + std::ofstream file_dst(argv[3], std::ios::binary); + if (!file_dst.is_open()) + { + std::cerr << "Error: Failed to open output file for writing!" << std::endl; + return -1; + } + + // ----------------------------------------------------------- + // Initialize the SlunkCryptDecr instance + // ----------------------------------------------------------- + + std::cerr << "Initializing key, please wait... " << std::flush; + + uint8_t buffer[BUFF_SIZE]; + SlunkCryptDecr slunk_decrypt(nonce, EXAMPLE_PASSWORD); + + std::cerr << "done.\nSlunk-decrypting the file contents, please wait... " << std::flush; + + // ----------------------------------------------------------- + // Decryption loop + // ----------------------------------------------------------- + + file_src.exceptions(std::ifstream::badbit); + file_dst.exceptions(std::ifstream::failbit | std::ifstream::badbit);; + + try + { + while (file_src.good()) + { + file_src.read(reinterpret_cast(buffer), BUFF_SIZE); + const std::streamsize count = file_src.gcount(); + if (count > 0) + { + if (!slunk_decrypt.decrypt_inplace(buffer, (size_t)count)) + { + std::cerr << "failed!\n\nError: SlunkCrypt decryption has failed!" << std::endl; + return -1; + } + file_dst.write(reinterpret_cast(buffer), count); + } + } + } + catch (std::ios_base::failure e) + { + std::cerr << "failed!\n\nI/O Error: \"" << e.code().message() << "\" [Code: " << e.code().value() << "]\n" << std::endl; + return -1; + } + + // ----------------------------------------------------------- + // Clean up + // ----------------------------------------------------------- + + std::cerr << "done.\n\nCompleted.\n" << std::endl; + + file_src.close(); + file_dst.close(); + + return 0; +} + +int main(int argc, char *argv[]) +{ + try + { + return decrypt_main(argc, argv); + } + catch (std::exception e) + { + std::cerr << "\n\nException: \"" << e.what() << "\"\n" << std::endl; + return -1; + } +} diff --git a/examples/example_encrypt.cpp b/examples/example_encrypt.cpp new file mode 100644 index 0000000..f0e1389 --- /dev/null +++ b/examples/example_encrypt.cpp @@ -0,0 +1,113 @@ +/******************************************************************************/ +/* SlunkCrypt, by LoRd_MuldeR */ +/* This work has been released under the CC0 1.0 Universal license! */ +/******************************************************************************/ + +//SlunkCrypt API +#include + +//CRT +#include +#include +#include + +//Example password +static std::string EXAMPLE_PASSWORD("cMRe5E5D)'!2?5]QDlCQ4tBb"); + +//Const +#define BUFF_SIZE 4096U + +static int encrypt_main(int argc, char *argv[]) +{ + std::cerr << "SlunkCrypt encrypt sample [" << __DATE__ << "]" << std::endl; + std::cerr << "using libSlunkCrypt v" << SLUNKCRYPT_VERSION_MAJOR << '.' << SLUNKCRYPT_VERSION_MINOR << '.' << SLUNKCRYPT_VERSION_PATCH << '\n' << std::endl; + + if (argc < 3) + { + std::cerr << "Usage:\n encrypt.exe \n" << std::endl; + return -1; + } + + // ----------------------------------------------------------- + // Open input/output files + // ----------------------------------------------------------- + + std::ifstream file_src(argv[1], std::ios::binary); + if (!file_src.is_open()) + { + std::cerr << "Error: Failed to open input file for reading!" << std::endl; + return -1; + } + + std::ofstream file_dst(argv[2], std::ios::binary); + if (!file_dst.is_open()) + { + std::cerr << "Error: Failed to open output file for writing!" << std::endl; + return -1; + } + + // ----------------------------------------------------------- + // Initialize the SlunkCryptEncr instance + // ----------------------------------------------------------- + + std::cerr << "Initializing key, please wait... " << std::flush; + + uint8_t buffer[BUFF_SIZE]; + SlunkCryptEncr slunk_encrypt(EXAMPLE_PASSWORD); + + std::cerr << "done.\nSlunk-encrypting the file contents, please wait... " << std::flush; + + // ----------------------------------------------------------- + // Encryption loop + // ----------------------------------------------------------- + + file_src.exceptions(std::ifstream::badbit); + file_dst.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + try + { + while (file_src.good()) + { + file_src.read(reinterpret_cast(buffer), BUFF_SIZE); + const std::streamsize count = file_src.gcount(); + if (count > 0) + { + if (!slunk_encrypt.encrypt_inplace(buffer, (size_t)count)) + { + std::cerr << "failed!\n\nError: SlunkCrypt encryption has failed!" << std::endl; + return -1; + } + file_dst.write(reinterpret_cast(buffer), count); + } + } + } + catch (std::ios_base::failure e) + { + std::cerr << "failed!\n\nI/O Error: \"" << e.code().message() << "\" [Code: " << e.code().value() << "]\n" << std::endl; + return -1; + } + + // ----------------------------------------------------------- + // Clean up + // ----------------------------------------------------------- + + std::cerr << "done.\n\nNonce: " << std::hex << std::uppercase << slunk_encrypt.get_nonce() << '\n' << std::endl; + + file_src.close(); + file_dst.close(); + + return 0; +} + +int main(int argc, char *argv[]) +{ + try + { + return encrypt_main(argc, argv); + } + catch (std::exception e) + { + std::cerr << "\n\nException: \"" << e.what() << "\"\n" << std::endl; + return -1; + } +} diff --git a/libslunkcrypt/include/slunkcrypt.h b/libslunkcrypt/include/slunkcrypt.h index 3eb4470..d8b8714 100644 --- a/libslunkcrypt/include/slunkcrypt.h +++ b/libslunkcrypt/include/slunkcrypt.h @@ -6,6 +6,15 @@ #ifndef INC_SLUNKCRYPT_H #define INC_SLUNKCRYPT_H +/* + * Compiler check + */ +#if defined(__cplusplus) && (__cplusplus < 201103L) && (!defined(_MSVC_LANG) || (_MSVC_LANG < 201103L)) +#error This file requires compiler and library support for the ISO C++11 standard. +#elif !defined(__cplusplus) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)) && (!defined(_MSC_VER) || (_MSC_VER < 1600)) +#error This file requires compiler and library support for the ISO C99 standard. +#endif + /* * Build options */ @@ -111,4 +120,3 @@ SLUNKCRYPT_API void slunkcrypt_bzero(void* const buffer, const size_t length); } #endif #endif - diff --git a/libslunkcrypt/include/slunkcrypt.hpp b/libslunkcrypt/include/slunkcrypt.hpp index 1971e80..3fc813e 100644 --- a/libslunkcrypt/include/slunkcrypt.hpp +++ b/libslunkcrypt/include/slunkcrypt.hpp @@ -6,11 +6,24 @@ #ifndef INC_SLUNKCRYPT_PLUSPLUS #define INC_SLUNKCRYPT_PLUSPLUS +/* + * Compiler check + */ +#if (!defined(__cplusplus) || (__cplusplus < 201103L)) && (!defined(_MSVC_LANG) || (_MSVC_LANG < 201103L)) +#error This file requires compiler and library support for the ISO C++11 standard. +#endif + +/* + * Dependencies + */ #include "slunkcrypt.h" #include #include #include +/* + * SlunkCrypt class for encryption + */ class SlunkCryptEncr { public: @@ -18,11 +31,11 @@ public: { if (slunkcrypt_generate_nonce(&m_nonce) != SLUNKCRYPT_SUCCESS) { - throw std::runtime_error("Failed to generate the seed value!"); + throw std::runtime_error("SlunkCryptEncr: Failed to generate the seed value!"); } if ((m_instance = slunkcrypt_alloc(m_nonce, (const uint8_t*)passwd.c_str(), passwd.length())) == SLUNKCRYPT_NULL) { - throw std::runtime_error("Failed to create encoder instance!"); + throw std::runtime_error("SlunkCryptEncr: Failed to create encoder instance!"); } } @@ -31,6 +44,7 @@ public: this->m_instance = other.m_instance; this->m_nonce = other.m_nonce; other.m_instance = SLUNKCRYPT_NULL; + other.m_nonce = (uint64_t)(-1); } ~SlunkCryptEncr(void) @@ -71,12 +85,15 @@ public: } private: - SlunkCryptEncr(const SlunkCryptEncr&); - SlunkCryptEncr& operator=(const SlunkCryptEncr&); + SlunkCryptEncr(const SlunkCryptEncr&) = delete; + SlunkCryptEncr& operator=(const SlunkCryptEncr&) = delete; uint64_t m_nonce; slunkcrypt_t m_instance; }; +/* + * SlunkCrypt class for decryption + */ class SlunkCryptDecr { public: @@ -84,7 +101,7 @@ public: { if ((m_instance = slunkcrypt_alloc(nonce, (const uint8_t*)passwd.c_str(), passwd.length())) == SLUNKCRYPT_NULL) { - throw std::runtime_error("Failed to create encoder instance!"); + throw std::runtime_error("SlunkCryptDecr: Failed to create decoder instance!"); } } @@ -127,8 +144,8 @@ public: } private: - SlunkCryptDecr(const SlunkCryptDecr&); - SlunkCryptDecr& operator=(const SlunkCryptDecr&); + SlunkCryptDecr(const SlunkCryptDecr&) = delete; + SlunkCryptDecr& operator=(const SlunkCryptDecr&) = delete; slunkcrypt_t m_instance; };