Skip to content

Commit 3eca1f6

Browse files
committed
Updating libencryption/libdecryption for compatibility with openssl3
1 parent 115d237 commit 3eca1f6

File tree

5 files changed

+315
-200
lines changed

5 files changed

+315
-200
lines changed

libs/libdecrypt/src/decryption.cpp

Lines changed: 117 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void Decryption::decryptFile() {
3232
"dummykey\n"
3333
"-----END RSA PRIVATE KEY-----\n"); // Replace with your private key string
3434
#endif
35-
RSA* privateKey = loadPrivateKey(privateKeyString);
35+
EVP_PKEY *privateKey = loadPrivateKey(privateKeyString);
3636
if (!privateKey) {
3737
return;
3838
}
@@ -42,31 +42,27 @@ void Decryption::decryptFile() {
4242
pugi::xml_parse_result result = encryptedDocLoaded.load_file(encryptedFile_.c_str());
4343
if (!result) {
4444
std::cerr << "XML parse error: " << result.description() << std::endl;
45-
RSA_free(privateKey);
45+
EVP_PKEY_free(privateKey);
4646
return;
4747
}
4848

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

53-
// Base64 decode encrypted session key and data
54-
std::string encryptedSessionKeyLoaded = base64_decode(base64EncryptedSessionKeyLoaded);
55-
std::string encryptedLoaded = base64_decode(base64EncryptedLoaded);
56-
5753
// Decrypt session key
58-
std::string decryptedSessionKey = decryptSessionKey(encryptedSessionKeyLoaded, privateKey);
54+
std::string decryptedSessionKey = decryptSessionKey(base64EncryptedSessionKeyLoaded, privateKey);
5955

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

6359
// Write the decrypted data to a file
64-
// std::ofstream decryptedFile("decrypted.xml");
65-
// decryptedFile << decrypted;
66-
// decryptedFile.close();
60+
std::ofstream decryptedFile("decrypted.xml");
61+
decryptedFile << decrypted;
62+
decryptedFile.close();
6763

6864
decryptedContent_ = decrypted;
69-
RSA_free(privateKey);
65+
EVP_PKEY_free(privateKey);
7066
}
7167

7268
/**
@@ -79,108 +75,147 @@ std::string Decryption::getDecryptedContent() const {
7975
}
8076

8177
/**
82-
* @brief Decrypts the given ciphertext using the provided RSA key.
78+
* @brief Loads the private key from the given PEM string.
8379
*
84-
* @param ciphertext The ciphertext to decrypt.
85-
* @param key The RSA key for decryption.
86-
* @return The decrypted plaintext.
80+
* @param privateKeyString The PEM string representing the private key.
81+
* @return The loaded EVP private key.
8782
*/
88-
std::string Decryption::decrypt(const std::string& ciphertext, RSA* key) {
89-
int rsaLen = RSA_size(key);
90-
int len = ciphertext.size();
91-
std::string plaintext;
92-
93-
for (int i = 0; i < len; i += rsaLen) {
94-
std::vector<unsigned char> buffer(rsaLen);
95-
std::string substr = ciphertext.substr(i, rsaLen);
96-
97-
int result = RSA_private_decrypt(substr.size(), reinterpret_cast<const unsigned char*>(substr.data()), buffer.data(), key, RSA_PKCS1_OAEP_PADDING);
98-
if (result == -1) {
99-
std::cerr << "Decryption error: " << ERR_error_string(ERR_get_error(), NULL) << std::endl;
100-
return "";
101-
}
102-
103-
plaintext.append(reinterpret_cast<char*>(buffer.data()), result);
83+
EVP_PKEY *Decryption::loadPrivateKey(const std::string& privateKeyString) {
84+
EVP_PKEY *pkey = nullptr;
85+
BIO* privateKeyBio = BIO_new_mem_buf(privateKeyString.data(), privateKeyString.size());
86+
87+
if (!privateKeyBio) {
88+
std::cerr << "Error creating BIO for private key" << std::endl;
89+
return nullptr;
90+
}
91+
92+
char* passphrase_cstr = const_cast<char*>(passphrase.c_str());
93+
if (!PEM_read_bio_PrivateKey(privateKeyBio, &pkey, NULL, passphrase_cstr)) {
94+
std::cerr << "Error reading private key" << std::endl;
95+
BIO_free(privateKeyBio);
96+
return nullptr;
10497
}
10598

106-
return plaintext;
99+
BIO_free(privateKeyBio);
100+
return pkey;
107101
}
108102

109103
/**
110-
* @brief Decodes the given base64-encoded string.
104+
* @brief
111105
*
112-
* @param input The base64-encoded input string.
113-
* @return The decoded output string.
106+
* @param encoded he base64-encoded input string.
107+
* @return std::vector<unsigned char> The decoded dynamic array of characters.
114108
*/
115-
std::string Decryption::base64_decode(const std::string& input) {
109+
std::vector<unsigned char> Decryption::base64Decode(const std::string& encoded) {
110+
BIO* bio = BIO_new_mem_buf(encoded.data(), -1);
116111
BIO* b64 = BIO_new(BIO_f_base64());
117112
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
113+
bio = BIO_push(b64, bio);
118114

119-
BIO* bmem = BIO_new_mem_buf(input.data(), input.size());
120-
b64 = BIO_push(b64, bmem);
121-
122-
std::string output;
123-
output.resize(input.size());
124-
125-
int decoded_size = BIO_read(b64, &output[0], input.size());
126-
output.resize(decoded_size);
127-
BIO_free_all(b64);
115+
std::vector<unsigned char> decoded(encoded.length());
116+
int decodedLen = BIO_read(bio, decoded.data(), encoded.length());
117+
decoded.resize(decodedLen);
128118

129-
return output;
119+
BIO_free_all(bio);
120+
return decoded;
130121
}
131122

132123
/**
133-
* @brief Loads the private key from the given PEM string.
124+
* @brief Decrypts the given encrypted session key using the provided EVP key.
134125
*
135-
* @param privateKeyString The PEM string representing the private key.
136-
* @return The loaded RSA private key.
126+
* @param encryptedSessionKey The encrypted session key.
127+
* @param privateKey The EVP key for decryption.
128+
* @return The decrypted session key.
137129
*/
138-
RSA* Decryption::loadPrivateKey(const std::string& privateKeyString) {
139-
RSA* key = nullptr;
140-
BIO* privateKeyBio = BIO_new_mem_buf(privateKeyString.data(), privateKeyString.size());
130+
std::string Decryption::decryptSessionKey(const std::string& encryptedSessionKey, EVP_PKEY* privateKey) {
131+
std::vector<unsigned char> decodedKey = base64Decode(encryptedSessionKey);
141132

142-
if (!privateKeyBio) {
143-
std::cerr << "Error creating BIO for private key" << std::endl;
144-
return nullptr;
133+
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(privateKey, NULL);
134+
if (!ctx) {
135+
std::cerr << "Failed to create EVP_PKEY_CTX" << std::endl;
136+
return "";
145137
}
146138

147-
char* passphrase_cstr = const_cast<char*>(passphrase.c_str());
148-
if (!PEM_read_bio_RSAPrivateKey(privateKeyBio, &key, NULL, passphrase_cstr)) {
149-
std::cerr << "Error reading private key" << std::endl;
150-
BIO_free(privateKeyBio);
151-
return nullptr;
139+
if (EVP_PKEY_decrypt_init(ctx) <= 0) {
140+
std::cerr << "EVP_PKEY_decrypt_init failed" << std::endl;
141+
EVP_PKEY_CTX_free(ctx);
142+
return "";
152143
}
153144

154-
BIO_free(privateKeyBio);
155-
return key;
145+
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
146+
std::cerr << "EVP_PKEY_CTX_set_rsa_padding failed" << std::endl;
147+
EVP_PKEY_CTX_free(ctx);
148+
return "";
149+
}
150+
151+
size_t outLen;
152+
if (EVP_PKEY_decrypt(ctx, NULL, &outLen, decodedKey.data(), decodedKey.size()) <= 0) {
153+
std::cerr << "EVP_PKEY_decrypt (determine length) failed" << std::endl;
154+
EVP_PKEY_CTX_free(ctx);
155+
return "";
156+
}
157+
158+
std::vector<unsigned char> out(outLen);
159+
if (EVP_PKEY_decrypt(ctx, out.data(), &outLen, decodedKey.data(), decodedKey.size()) <= 0) {
160+
std::cerr << "EVP_PKEY_decrypt failed" << std::endl;
161+
EVP_PKEY_CTX_free(ctx);
162+
return "";
163+
}
164+
165+
EVP_PKEY_CTX_free(ctx);
166+
167+
return std::string(out.begin(), out.begin() + outLen);
156168
}
157169

158170
/**
159-
* @brief Decrypts the given encrypted session key using the provided RSA key.
171+
* @brief
160172
*
161-
* @param encryptedSessionKey The encrypted session key.
162-
* @param key The RSA key for decryption.
163-
* @return The decrypted session key.
173+
* @param encryptedData The encrypted data to decrypt.
174+
* @param sessionKey The session key for data decryption.
175+
* @return std::string The decrypted plaintext.
164176
*/
165-
std::string Decryption::decryptSessionKey(const std::string& encryptedSessionKey, RSA* key) {
166-
std::vector<unsigned char> decryptedSessionKey(RSA_size(key));
167-
if (RSA_private_decrypt(encryptedSessionKey.size(), reinterpret_cast<const unsigned char*>(encryptedSessionKey.data()), decryptedSessionKey.data(), key, RSA_PKCS1_OAEP_PADDING) == -1) {
168-
std::cerr << "Session key decryption error: " << ERR_error_string(ERR_get_error(), NULL) << std::endl;
177+
std::string Decryption::decryptData(const std::string& encryptedData, const unsigned char* sessionKey) {
178+
std::vector<unsigned char> decodedData = base64Decode(encryptedData);
179+
180+
// Extract the IV from the decoded data
181+
unsigned char iv[EVP_MAX_IV_LENGTH];
182+
int iv_len = EVP_CIPHER_iv_length(EVP_aes_128_cbc());
183+
std::copy(decodedData.begin(), decodedData.begin() + iv_len, iv);
184+
const unsigned char* ciphertext = decodedData.data() + iv_len;
185+
size_t ciphertextLen = decodedData.size() - iv_len;
186+
187+
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
188+
if (!ctx) {
189+
std::cerr << "Failed to create EVP_CIPHER_CTX" << std::endl;
169190
return "";
170191
}
171192

172-
return std::string(reinterpret_cast<char*>(decryptedSessionKey.data()), decryptedSessionKey.size());
173-
}
193+
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, sessionKey, iv) != 1) {
194+
std::cerr << "EVP_DecryptInit_ex failed" << std::endl;
195+
EVP_CIPHER_CTX_free(ctx);
196+
return "";
197+
}
198+
199+
std::vector<unsigned char> plaintext(ciphertextLen + EVP_CIPHER_block_size(EVP_aes_128_cbc()));
200+
int len = 0;
201+
int plaintextLen = 0;
174202

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

181-
// std::string encryptedFile = argv[1];
210+
if (EVP_DecryptFinal_ex(ctx, plaintext.data() + plaintextLen, &len) != 1) {
211+
std::cerr << "EVP_DecryptFinal_ex failed" << std::endl;
212+
EVP_CIPHER_CTX_free(ctx);
213+
return "";
214+
}
215+
plaintextLen += len;
216+
plaintext.resize(plaintextLen);
182217

183-
// Decryption decryption(encryptedFile);
218+
EVP_CIPHER_CTX_free(ctx);
184219

185-
// return 0;
186-
// }
220+
return std::string(plaintext.begin(), plaintext.end());
221+
}

libs/libdecrypt/src/decryption.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <openssl/evp.h>
99
#include <openssl/bn.h>
1010
#include <openssl/rand.h>
11+
#include <openssl/evp.h>
1112
#include <iostream>
1213
#include <sstream>
1314
#include <vector>
@@ -49,38 +50,38 @@ class Decryption
4950
std::string decryptedContent_; /**< The decrypted content of the file. */
5051

5152
/**
52-
* @brief Decrypts the given ciphertext using the provided RSA key.
53+
* @brief
5354
*
54-
* @param ciphertext The ciphertext to decrypt.
55-
* @param key The RSA key for decryption.
56-
* @return The decrypted plaintext.
55+
* @param encryptedData The encrypted data to decrypt.
56+
* @param sessionKey The session key for data decryption.
57+
* @return std::string The decrypted plaintext.
5758
*/
58-
static std::string decrypt(const std::string &ciphertext, RSA *key);
59+
static std::string decryptData(const std::string& encryptedData, const unsigned char* sessionKey);
5960

6061
/**
61-
* @brief Decodes the given base64-encoded string.
62+
* @brief
6263
*
63-
* @param input The base64-encoded input string.
64-
* @return The decoded output string.
64+
* @param encoded he base64-encoded input string.
65+
* @return std::vector<unsigned char> The decoded dynamic array of characters.
6566
*/
66-
static std::string base64_decode(const std::string &input);
67+
static std::vector<unsigned char> base64Decode(const std::string& encoded);
6768

6869
/**
6970
* @brief Loads the private key from the given PEM string.
7071
*
7172
* @param privateKeyString The PEM string representing the private key.
72-
* @return The loaded RSA private key.
73+
* @return The loaded EVP private key.
7374
*/
74-
static RSA *loadPrivateKey(const std::string &privateKeyString);
75+
static EVP_PKEY* loadPrivateKey(const std::string& privateKeyString);
7576

7677
/**
77-
* @brief Decrypts the given encrypted session key using the provided RSA key.
78+
* @brief Decrypts the given encrypted session key using the provided EVP key.
7879
*
7980
* @param encryptedSessionKey The encrypted session key.
80-
* @param key The RSA key for decryption.
81+
* @param privateKey The EVP key for decryption.
8182
* @return The decrypted session key.
8283
*/
83-
static std::string decryptSessionKey(const std::string &encryptedSessionKey, RSA *key);
84+
static std::string decryptSessionKey(const std::string& encryptedSessionKey, EVP_PKEY* privateKey);
8485
};
8586

8687
#endif // DECRYPTION_H

libs/libencrypt/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ project(libencrypt)
44
find_package(PkgConfig REQUIRED)
55
pkg_search_module(OPENSSL REQUIRED openssl)
66

7-
file(READ "config.txt" PASSPHRASE_CONTENTS)
8-
string(REPLACE "\n" "\\n" PASSPHRASE_CONTENTS "${PASSPHRASE_CONTENTS}")
9-
set(PASS_PHRASE "${PASSPHRASE_CONTENTS}")
10-
add_compile_definitions(PASS_PHRASE="${PASS_PHRASE}")
11-
127
if(OPENSSL_FOUND)
138
include_directories(${OPENSSL_INCLUDE_DIRS})
149
message(STATUS "Using OpenSSL ${OPENSSL_VERSION}")

0 commit comments

Comments
 (0)