From 490d36e65ac24e34e3021c2a0947384aee138c88 Mon Sep 17 00:00:00 2001 From: Malf Furious Date: Wed, 13 Apr 2016 21:05:14 -0400 Subject: Root commit for new Compass repository This is the Alpha version of ComPASS, originally developed sometime in 2014. --- Cryptor.cpp | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 Cryptor.cpp (limited to 'Cryptor.cpp') diff --git a/Cryptor.cpp b/Cryptor.cpp new file mode 100644 index 0000000..57ded9a --- /dev/null +++ b/Cryptor.cpp @@ -0,0 +1,244 @@ +#include "Cryptor.h" + +bool Cryptor::haveKey = false; +unsigned char Cryptor::key[CryptoPP::AES::DEFAULT_KEYLENGTH]; + +void Cryptor::encryptAndSave(std::string remoteHost, std::string port, std::string directory, std::string payload) { + // Key + if (!haveKey) + assembleKey(true); + + // IV + unsigned char iv[CryptoPP::AES::BLOCKSIZE]; + CryptoPP::AutoSeededRandomPool randl; + randl.GenerateBlock(iv, sizeof(iv)); + + // Encrypt + std::string cipher; + CryptoPP::CBC_Mode::Encryption enc(key, sizeof(key), iv); + CryptoPP::StringSource(payload, true, new CryptoPP::StreamTransformationFilter(enc, new CryptoPP::StringSink(cipher))); + + // Save Data + std::string encIV, encCipher; + CryptoPP::StringSource(iv, sizeof(iv), true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(encIV))); + CryptoPP::StringSource(cipher, true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(encCipher))); + if (remoteHost == "") { + if (directory[directory.size() - 1] != '/') directory += "/"; + directory += KEYCHAIN_FILE; + std::ofstream f(directory.c_str()); + f << encIV << std::endl; + f << encCipher << std::endl; + f.close(); + } + else { + Socket s; + std::string err = ""; + s.conn(remoteHost, port); + s.sendline("store"); + s.sendline(directory); + s.sendline(encIV); + s.sendline(encCipher); + err = s.readline(); + s.clo(); + if (err != "OK") throw 1; + } +} + +std::string Cryptor::loadAndDecrypt(std::string remoteHost, std::string port, std::string directory) { + // Load Data + std::string encIV, encCipher, ivstr, cipher; + if (remoteHost == "") { + if (directory[directory.size() - 1] != '/') directory += "/"; + directory += KEYCHAIN_FILE; + std::ifstream f(directory.c_str()); + if (!f.good()) { + f.close(); + throw 1; + } + f >> encIV; + f >> encCipher; + f.close(); + } + else { + Socket s; + std::string err = ""; + s.conn(remoteHost, port); + s.sendline("fetch"); + s.sendline(directory); + err = s.readline(); + if (err != "OK") { + s.clo(); + throw 1; + } + encIV = s.readline(); + encCipher = s.readline(); + s.clo(); + } + CryptoPP::StringSource(encIV, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(ivstr))); + CryptoPP::StringSource(encCipher, true, new CryptoPP::HexDecoder(new CryptoPP::StringSink(cipher))); + + // Key + if (!haveKey) + assembleKey(); + + // IV + unsigned char iv[CryptoPP::AES::BLOCKSIZE]; + memcpy(iv, ivstr.c_str(), ivstr.size()); + + // Decrypt + std::string payload; + CryptoPP::CBC_Mode::Decryption dec(key, sizeof(key), iv); + CryptoPP::StringSource(cipher, true, new CryptoPP::StreamTransformationFilter(dec, new CryptoPP::StringSink(payload))); + + return payload; +} + +std::string Cryptor::createRandomPassword(PasswordSpec spec) { + CryptoPP::AutoSeededRandomPool randl; + std::string password; + + std::vector validChars; + + // Always allow lower-case alphabetic characters + for (int i = 0; i < 26; i++) + validChars.push_back('a' + i); + + // Allow special chars? + if (!spec.ns) { + validChars.push_back('`'); + validChars.push_back('~'); + validChars.push_back('!'); + validChars.push_back('@'); + validChars.push_back('#'); + validChars.push_back('$'); + validChars.push_back('%'); + validChars.push_back('^'); + validChars.push_back('&'); + validChars.push_back('*'); + validChars.push_back('('); + validChars.push_back(')'); + validChars.push_back('-'); + validChars.push_back('_'); + validChars.push_back('='); + validChars.push_back('+'); + validChars.push_back('['); + validChars.push_back('{'); + validChars.push_back(']'); + validChars.push_back('}'); + validChars.push_back('\\'); + validChars.push_back('|'); + validChars.push_back(';'); + validChars.push_back(':'); + validChars.push_back(','); + validChars.push_back('<'); + validChars.push_back('.'); + validChars.push_back('>'); + validChars.push_back('/'); + validChars.push_back('?'); + } + + // Allow capital letters? + if (!spec.nc) { + for (int i = 0; i < 26; i++) + validChars.push_back('A' + i); + } + + // Allow numbers? + if (!spec.nn) { + for (int i = 0; i < 10; i++) + validChars.push_back('0' + i); + } + + + // Build string + for (int i = 0; i < spec.ml; i++) { + unsigned char r[1]; + char c; + randl.GenerateBlock(r, sizeof(r)); + c = validChars[r[0] % validChars.size()]; + password += c; + } + + return password; +} + +void Cryptor::rekey() { + haveKey = false; +} + +void Cryptor::sha256(std::string str) { + CryptoPP::SHA256 hash; + std::string rtr; + CryptoPP::StringSource(str, true, new CryptoPP::HashFilter(hash, new CryptoPP::StringSink(rtr), false, CryptoPP::AES::DEFAULT_KEYLENGTH)); + memcpy(key, rtr.c_str(), rtr.size()); + haveKey = true; +} + +std::string Cryptor::readPassword(bool confirm) { + std::string password; + + #ifdef WIN32 + + HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hstdin, &mode); + SetConsoleMode(hstdin, mode & ~ENABLE_ECHO_INPUT); + + password = promptPassword(confirm); + + SetConsoleMode(hstdin, mode); + + #else + + termios oldt; + tcgetattr(STDIN_FILENO, &oldt); + termios newt = oldt; + newt.c_lflag &= ~ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + + password = promptPassword(confirm); + + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + + #endif // WIN32 + + return password; +} + +std::string Cryptor::readPassword() { + return readPassword(false); +} + +void Cryptor::assembleKey(bool confirm) { + sha256(readPassword(confirm)); +} + +void Cryptor::assembleKey() { + assembleKey(false); +} + +std::string Cryptor::promptPassword(bool confirm) { + std::string password; + + while (true) { + std::cout << PASSWORD_PROMPT; + std::cin >> password; + std::cout << std::endl; + + if (confirm) { + std::string conf; + std::cout << PASSWORD_CONF; + std::cin >> conf; + std::cout << std::endl; + + if (password == conf) + break; + else + std::cout << PASSWORD_ERROR << std::endl; + } + else + break; + } + + return password; +} -- cgit v1.2.3