From 53d457d060cfaf270dbc8fc5f8575124c9360667 Mon Sep 17 00:00:00 2001 From: mkhan Date: Wed, 30 Aug 2017 16:43:36 +1000 Subject: [PATCH] some fixes and issues raised --- cli/mine.cc | 79 +++++++++++++++++++++++++++++++++++++++++----- src/base16.cc | 4 +-- test/base16-test.h | 12 +++++++ test/main.cc | 6 ++-- test/zlib-test.h | 34 ++++++++++++++++++++ 5 files changed, 122 insertions(+), 13 deletions(-) diff --git a/cli/mine.cc b/cli/mine.cc index 86a9104..42a1427 100644 --- a/cli/mine.cc +++ b/cli/mine.cc @@ -32,18 +32,27 @@ void displayUsage() // we want to keep the order so can't use std::map or std::unordered_map std::vector> options = { {"--version", "Display version information"}, + + // operations {"-e", "Encrypt / encode / inflate the data"}, {"-d", "Decrypt / decrypt / deflate the data"}, {"-g", "Generate a random key"}, + + // modes {"--aes", "AES operations"}, - {"--key", "Symmetric key for encryption / decryption"}, - {"--iv", "Initializaion vector for decription"}, + {"--zlib", "ZLib compression/decompression"}, {"--base64", "Base64 operations"}, {"--hex", "Base16 operations"}, + + // parameters + {"--key", "Symmetric key for encryption / decryption"}, + {"--iv", "Initializaion vector for decription"}, {"--length", "Specify key length"}, + {"--in", "Input data from file (path)"}, + {"--output", "Output file (path)"}, }; - std::cout << "mine [-d | -e | -g | -s | -v] [--in ] [--key ] [--in-key ] [--out-public ] [--out-private ] [--iv ] [--base64] [--length ] [--aes []] [--hex]" << std::endl; + std::cout << "mine [-e | -d | -g] [--aes] [--hex] [--base64] [--zlib] [--in ] [--output ] [--key ] [--iv ] [--length ]" << std::endl; std::cout << std::endl; const std::size_t LONGEST = 20; for (auto& option : options) { @@ -65,7 +74,7 @@ std::string normalizeBase16(std::string enc) void displayVersion() { - std::cout << "Mine - Minimal cryptography library" << std::endl << "Version: " << MINE_VERSION << std::endl << "https://muflihun.com" << std::endl; + std::cout << "Mine - Minimal cryptography library" << std::endl << "Version: " << MINE_VERSION << std::endl << "https://muflihun.github.io" << std::endl; } #define TRY try { @@ -125,6 +134,50 @@ void decodeHex(std::string& data) CATCH } +void compress(std::string& data, bool isBase64, const std::string& outputFile) +{ + TRY + std::string o = ZLib::compressString(data); + + if (isBase64) { + o = Base64::encode(o); + } else { + o = Base16::encode(o); + } + if (outputFile.empty()) { + std::cout << o; + } else { + std::ofstream out(outputFile); + out << o; + out.close(); + } + CATCH +} + +void decompress(std::string& data, bool isBase64, const std::string& outputFile) +{ + TRY + try { + if (isBase64) { + data = Base64::decode(data); + } else { + data = Base16::decode(data); + } + } catch (const std::exception& e) { + //ignore + std::cout << "ERROR: " << e.what() << std::endl; + } + std::string o = ZLib::decompressString(data); + if (outputFile.empty()) { + std::cout << o; + } else { + std::ofstream out(outputFile); + out << o; + out.close(); + } + CATCH +} + int main(int argc, char* argv[]) { if (argc < 2) { @@ -144,7 +197,9 @@ int main(int argc, char* argv[]) std::string iv; int keyLength = 256; std::string data; + std::string outputFile; bool isAES = false; + bool isZlib = false; bool isBase64 = false; bool isHex = false; bool fileArgSpecified = false; @@ -162,8 +217,6 @@ int main(int argc, char* argv[]) isBase64 = true; } else if (arg == "--hex") { isHex = true; - } else if (arg == "--key" && hasNext) { - key = argv[++i]; } else if (arg == "--aes") { isAES = true; if (i + 1 < argc) { @@ -174,6 +227,10 @@ int main(int argc, char* argv[]) --i; } } + } else if (arg == "--zlib") { + isZlib = true; + } else if (arg == "--key" && hasNext) { + key = argv[++i]; } else if (arg == "--length" && hasNext) { keyLength = atoi(argv[++i]); } else if (arg == "--iv" && hasNext) { @@ -186,6 +243,8 @@ int main(int argc, char* argv[]) data = std::string((std::istreambuf_iterator(fs) ), (std::istreambuf_iterator())); fs.close(); + } else if (arg == "--out" && hasNext) { + outputFile = argv[++i]; } } @@ -199,22 +258,26 @@ int main(int argc, char* argv[]) data.erase(data.size() - 1); } - if (type == 1) { // Decrypt / Decode + if (type == 1) { // Decrypt / Decode / Decompress if (isBase64 && key.empty() && iv.empty()) { // base64 decode decodeBase64(data); } else if (isHex && key.empty() && iv.empty()) { // hex to ascii decodeHex(data); + } else if (isZlib) { + decompress(data, isBase64, outputFile); } else { // AES decrypt (base64-flexible) decryptAES(data, key, iv, isBase64); } - } else if (type == 2) { // Encrypt / Encode + } else if (type == 2) { // Encrypt / Encode / Compress if (isBase64 && key.empty() && iv.empty()) { encodeBase64(data); } else if (isHex && key.empty() && iv.empty()) { encodeHex(data); + } else if (isZlib) { + compress(data, isBase64, outputFile); } else { encryptAES(data, key, iv, isBase64); } diff --git a/src/base16.cc b/src/base16.cc index 25560a5..ab4b87e 100644 --- a/src/base16.cc +++ b/src/base16.cc @@ -55,7 +55,7 @@ void Base16::decode(char a, char b, std::ostringstream& ss) int b1 = b & 0xff; try { ss << static_cast((b0 << 4) | kDecodeMap.at(b1)); - } catch (const std::exception&) { - throw std::invalid_argument("Invalid base-16 encoding"); + } catch (const std::exception& e) { + throw std::invalid_argument("Invalid base-16 encoding: " + std::string(e.what())); } } diff --git a/test/base16-test.h b/test/base16-test.h index e1a8dc6..4d16451 100644 --- a/test/base16-test.h +++ b/test/base16-test.h @@ -32,6 +32,10 @@ static TestData InvalidBase16EncodingData = { TestCase("48656C6C6F20576F726C64F"), }; +static TestData EncodingDecodingData = { + TestCase("78DA2B492D2E0100045D01C1"), +}; + TEST(Base16Test, Encode) { for (const auto& item : Base16TestData) { @@ -40,6 +44,14 @@ TEST(Base16Test, Encode) } } +TEST(Base16Test, EncodeDecodingTest) +{ + for (const auto& item : EncodingDecodingData) { + std::string decoded = Base16::decode(PARAM(0)); + ASSERT_STREQ(PARAM(0).c_str(), Base16::encode(decoded).c_str()); + } +} + TEST(Base16Test, EncodeByteArray) { for (const auto& item : Base16ByteArrayEncodingTestData) { diff --git a/test/main.cc b/test/main.cc index a85a1fd..f496792 100644 --- a/test/main.cc +++ b/test/main.cc @@ -1,9 +1,9 @@ #include "test.h" -#include "base16-test.h" -#include "base64-test.h" -//#include "zlib-test.h" +#include "zlib-test.h" #include "rsa-test.h" #include "aes-test.h" +#include "base64-test.h" +#include "base16-test.h" INITIALIZE_EASYLOGGINGPP diff --git a/test/zlib-test.h b/test/zlib-test.h index 2116316..d770c81 100644 --- a/test/zlib-test.h +++ b/test/zlib-test.h @@ -7,10 +7,44 @@ # include "package/mine.h" #else # include "src/zlib.h" +# include "src/base64.h" +# include "src/base16.h" #endif namespace mine { +static TestData ZLibData = { + TestCase("abcd", "eNpLTEpOAQAD2AGL"), +}; + +static TestData ZLibDataHex = { + TestCase("test", "78DA2B492D2E0100045D01C1"), +}; + +TEST(ZLibTest, Compress) +{ + for (const auto& item : ZLibData) { + std::string encoded = ZLib::compressString(PARAM(0)); + ASSERT_EQ(PARAM(1), Base64::encode(encoded)); + } +} + +TEST(ZLibTest, Decompress) +{ + for (const auto& item : ZLibData) { + std::string decoded = ZLib::decompressString(Base64::decode(PARAM(1))); + ASSERT_EQ(PARAM(0), decoded); + } +} + +TEST(ZLibTest, DecompressHex) +{ + for (const auto& item : ZLibDataHex) { + std::string decoded = ZLib::decompressString(Base16::decode(PARAM(1))); + ASSERT_EQ(PARAM(0), decoded); + } +} + } #endif // ZLIB_TEST_H