Skip to content

Removing warnings from libencrypt and libdecrypt #2629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 114 additions & 78 deletions libs/libdecrypt/src/decryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void Decryption::decryptFile() {
"dummykey\n"
"-----END RSA PRIVATE KEY-----\n"); // Replace with your private key string
#endif
RSA* privateKey = loadPrivateKey(privateKeyString);
EVP_PKEY *privateKey = loadPrivateKey(privateKeyString);
if (!privateKey) {
return;
}
Expand All @@ -42,31 +42,27 @@ void Decryption::decryptFile() {
pugi::xml_parse_result result = encryptedDocLoaded.load_file(encryptedFile_.c_str());
if (!result) {
std::cerr << "XML parse error: " << result.description() << std::endl;
RSA_free(privateKey);
EVP_PKEY_free(privateKey);
return;
}

pugi::xml_node root = encryptedDocLoaded.child("EncryptedData");
std::string base64EncryptedSessionKeyLoaded = root.child_value("SessionKey");
std::string base64EncryptedLoaded = root.child_value("Data");

// Base64 decode encrypted session key and data
std::string encryptedSessionKeyLoaded = base64_decode(base64EncryptedSessionKeyLoaded);
std::string encryptedLoaded = base64_decode(base64EncryptedLoaded);

// Decrypt session key
std::string decryptedSessionKey = decryptSessionKey(encryptedSessionKeyLoaded, privateKey);
std::string decryptedSessionKey = decryptSessionKey(base64EncryptedSessionKeyLoaded, privateKey);

// Decrypt XML string
std::string decrypted = decrypt(encryptedLoaded, privateKey);
std::string decrypted = decryptData(base64EncryptedLoaded, reinterpret_cast<const unsigned char*>(decryptedSessionKey.c_str()));

// Write the decrypted data to a file
// std::ofstream decryptedFile("decrypted.xml");
// decryptedFile << decrypted;
// decryptedFile.close();

decryptedContent_ = decrypted;
RSA_free(privateKey);
EVP_PKEY_free(privateKey);
}

/**
Expand All @@ -79,107 +75,147 @@ std::string Decryption::getDecryptedContent() const {
}

/**
* @brief Decrypts the given ciphertext using the provided RSA key.
* @brief Loads the private key from the given PEM string.
*
* @param ciphertext The ciphertext to decrypt.
* @param key The RSA key for decryption.
* @return The decrypted plaintext.
* @param privateKeyString The PEM string representing the private key.
* @return The loaded EVP private key.
*/
std::string Decryption::decrypt(const std::string& ciphertext, RSA* key) {
int rsaLen = RSA_size(key);
int len = ciphertext.size();
std::string plaintext;

for (int i = 0; i < len; i += rsaLen) {
std::vector<unsigned char> buffer(rsaLen);
std::string substr = ciphertext.substr(i, rsaLen);

int result = RSA_private_decrypt(substr.size(), reinterpret_cast<const unsigned char*>(substr.data()), buffer.data(), key, RSA_PKCS1_OAEP_PADDING);
if (result == -1) {
std::cerr << "Decryption error: " << ERR_error_string(ERR_get_error(), NULL) << std::endl;
return "";
}

plaintext.append(reinterpret_cast<char*>(buffer.data()), result);
EVP_PKEY *Decryption::loadPrivateKey(const std::string& privateKeyString) {
EVP_PKEY *pkey = nullptr;
BIO* privateKeyBio = BIO_new_mem_buf(privateKeyString.data(), privateKeyString.size());

if (!privateKeyBio) {
std::cerr << "Error creating BIO for private key" << std::endl;
return nullptr;
}

char* passphrase_cstr = const_cast<char*>(passphrase.c_str());
if (!PEM_read_bio_PrivateKey(privateKeyBio, &pkey, NULL, passphrase_cstr)) {
std::cerr << "Error reading private key" << std::endl;
BIO_free(privateKeyBio);
return nullptr;
}

return plaintext;
BIO_free(privateKeyBio);
return pkey;
}

/**
* @brief Decodes the given base64-encoded string.
* @brief
*
* @param input The base64-encoded input string.
* @return The decoded output string.
* @param encoded he base64-encoded input string.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"he" -> "the"

* @return std::vector<unsigned char> The decoded dynamic array of characters.
*/
std::string Decryption::base64_decode(const std::string& input) {
std::vector<unsigned char> Decryption::base64Decode(const std::string& encoded) {
BIO* bio = BIO_new_mem_buf(encoded.data(), -1);
BIO* b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bio = BIO_push(b64, bio);

BIO* bmem = BIO_new_mem_buf(input.data(), input.size());
b64 = BIO_push(b64, bmem);

std::string output;
output.resize(input.size());

int decoded_size = BIO_read(b64, &output[0], input.size());
output.resize(decoded_size);
BIO_free_all(b64);
std::vector<unsigned char> decoded(encoded.length());
int decodedLen = BIO_read(bio, decoded.data(), encoded.length());
decoded.resize(decodedLen);

return output;
BIO_free_all(bio);
return decoded;
}

/**
* @brief Loads the private key from the given PEM string.
* @brief Decrypts the given encrypted session key using the provided EVP key.
*
* @param privateKeyString The PEM string representing the private key.
* @return The loaded RSA private key.
* @param encryptedSessionKey The encrypted session key.
* @param privateKey The EVP key for decryption.
* @return The decrypted session key.
*/
RSA* Decryption::loadPrivateKey(const std::string& privateKeyString) {
RSA* key = nullptr;
BIO* privateKeyBio = BIO_new_mem_buf(privateKeyString.data(), privateKeyString.size());
std::string Decryption::decryptSessionKey(const std::string& encryptedSessionKey, EVP_PKEY* privateKey) {
std::vector<unsigned char> decodedKey = base64Decode(encryptedSessionKey);

if (!privateKeyBio) {
std::cerr << "Error creating BIO for private key" << std::endl;
return nullptr;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(privateKey, NULL);
if (!ctx) {
std::cerr << "Failed to create EVP_PKEY_CTX" << std::endl;
return "";
}

if (!PEM_read_bio_RSAPrivateKey(privateKeyBio, &key, NULL, (void*)passphrase.c_str())) {
std::cerr << "Error reading private key" << std::endl;
BIO_free(privateKeyBio);
return nullptr;
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
std::cerr << "EVP_PKEY_decrypt_init failed" << std::endl;
EVP_PKEY_CTX_free(ctx);
return "";
}

BIO_free(privateKeyBio);
return key;
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
std::cerr << "EVP_PKEY_CTX_set_rsa_padding failed" << std::endl;
EVP_PKEY_CTX_free(ctx);
return "";
}

size_t outLen;
if (EVP_PKEY_decrypt(ctx, NULL, &outLen, decodedKey.data(), decodedKey.size()) <= 0) {
std::cerr << "EVP_PKEY_decrypt (determine length) failed" << std::endl;
EVP_PKEY_CTX_free(ctx);
return "";
}

std::vector<unsigned char> out(outLen);
if (EVP_PKEY_decrypt(ctx, out.data(), &outLen, decodedKey.data(), decodedKey.size()) <= 0) {
std::cerr << "EVP_PKEY_decrypt failed" << std::endl;
EVP_PKEY_CTX_free(ctx);
return "";
}

EVP_PKEY_CTX_free(ctx);

return std::string(out.begin(), out.begin() + outLen);
}

/**
* @brief Decrypts the given encrypted session key using the provided RSA key.
* @brief
*
* @param encryptedSessionKey The encrypted session key.
* @param key The RSA key for decryption.
* @return The decrypted session key.
* @param encryptedData The encrypted data to decrypt.
* @param sessionKey The session key for data decryption.
* @return std::string The decrypted plaintext.
*/
std::string Decryption::decryptSessionKey(const std::string& encryptedSessionKey, RSA* key) {
std::vector<unsigned char> decryptedSessionKey(RSA_size(key));
if (RSA_private_decrypt(encryptedSessionKey.size(), reinterpret_cast<const unsigned char*>(encryptedSessionKey.data()), decryptedSessionKey.data(), key, RSA_PKCS1_OAEP_PADDING) == -1) {
std::cerr << "Session key decryption error: " << ERR_error_string(ERR_get_error(), NULL) << std::endl;
std::string Decryption::decryptData(const std::string& encryptedData, const unsigned char* sessionKey) {
std::vector<unsigned char> decodedData = base64Decode(encryptedData);

// Extract the IV from the decoded data
unsigned char iv[EVP_MAX_IV_LENGTH];
int iv_len = EVP_CIPHER_iv_length(EVP_aes_128_cbc());
std::copy(decodedData.begin(), decodedData.begin() + iv_len, iv);
const unsigned char* ciphertext = decodedData.data() + iv_len;
size_t ciphertextLen = decodedData.size() - iv_len;

EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
std::cerr << "Failed to create EVP_CIPHER_CTX" << std::endl;
return "";
}

return std::string(reinterpret_cast<char*>(decryptedSessionKey.data()), decryptedSessionKey.size());
}
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, sessionKey, iv) != 1) {
std::cerr << "EVP_DecryptInit_ex failed" << std::endl;
EVP_CIPHER_CTX_free(ctx);
return "";
}

std::vector<unsigned char> plaintext(ciphertextLen + EVP_CIPHER_block_size(EVP_aes_128_cbc()));
int len = 0;
int plaintextLen = 0;

// int main(int argc, char* argv[]) {
// if (argc < 2) {
// std::cerr << "Usage: " << argv[0] << " <encrypted file> <public key>\n";
// return -1;
// }
if (EVP_DecryptUpdate(ctx, plaintext.data(), &len, ciphertext, ciphertextLen) != 1) {
std::cerr << "EVP_DecryptUpdate failed" << std::endl;
EVP_CIPHER_CTX_free(ctx);
return "";
}
plaintextLen += len;

// std::string encryptedFile = argv[1];
if (EVP_DecryptFinal_ex(ctx, plaintext.data() + plaintextLen, &len) != 1) {
std::cerr << "EVP_DecryptFinal_ex failed" << std::endl;
EVP_CIPHER_CTX_free(ctx);
return "";
}
plaintextLen += len;
plaintext.resize(plaintextLen);

// Decryption decryption(encryptedFile);
EVP_CIPHER_CTX_free(ctx);

// return 0;
// }
return std::string(plaintext.begin(), plaintext.end());
}
29 changes: 15 additions & 14 deletions libs/libdecrypt/src/decryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <iostream>
#include <sstream>
#include <vector>
Expand Down Expand Up @@ -49,38 +50,38 @@ class Decryption
std::string decryptedContent_; /**< The decrypted content of the file. */

/**
* @brief Decrypts the given ciphertext using the provided RSA key.
* @brief
*
* @param ciphertext The ciphertext to decrypt.
* @param key The RSA key for decryption.
* @return The decrypted plaintext.
* @param encryptedData The encrypted data to decrypt.
* @param sessionKey The session key for data decryption.
* @return std::string The decrypted plaintext.
*/
static std::string decrypt(const std::string &ciphertext, RSA *key);
static std::string decryptData(const std::string& encryptedData, const unsigned char* sessionKey);

/**
* @brief Decodes the given base64-encoded string.
* @brief
*
* @param input The base64-encoded input string.
* @return The decoded output string.
* @param encoded he base64-encoded input string.
* @return std::vector<unsigned char> The decoded dynamic array of characters.
*/
static std::string base64_decode(const std::string &input);
static std::vector<unsigned char> base64Decode(const std::string& encoded);

/**
* @brief Loads the private key from the given PEM string.
*
* @param privateKeyString The PEM string representing the private key.
* @return The loaded RSA private key.
* @return The loaded EVP private key.
*/
static RSA *loadPrivateKey(const std::string &privateKeyString);
static EVP_PKEY* loadPrivateKey(const std::string& privateKeyString);

/**
* @brief Decrypts the given encrypted session key using the provided RSA key.
* @brief Decrypts the given encrypted session key using the provided EVP key.
*
* @param encryptedSessionKey The encrypted session key.
* @param key The RSA key for decryption.
* @param privateKey The EVP key for decryption.
* @return The decrypted session key.
*/
static std::string decryptSessionKey(const std::string &encryptedSessionKey, RSA *key);
static std::string decryptSessionKey(const std::string& encryptedSessionKey, EVP_PKEY* privateKey);
};

#endif // DECRYPTION_H
5 changes: 0 additions & 5 deletions libs/libencrypt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ project(libencrypt)
find_package(PkgConfig REQUIRED)
pkg_search_module(OPENSSL REQUIRED openssl)

file(READ "config.txt" PASSPHRASE_CONTENTS)
string(REPLACE "\n" "\\n" PASSPHRASE_CONTENTS "${PASSPHRASE_CONTENTS}")
set(PASS_PHRASE "${PASSPHRASE_CONTENTS}")
add_compile_definitions(PASS_PHRASE="${PASS_PHRASE}")

if(OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIRS})
message(STATUS "Using OpenSSL ${OPENSSL_VERSION}")
Expand Down
Loading
Loading