Skip to content

Commit

Permalink
Finalize RSA
Browse files Browse the repository at this point in the history
  • Loading branch information
baderouaich committed Jul 9, 2024
1 parent b81e463 commit eb46261
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 92 deletions.
91 changes: 91 additions & 0 deletions src/Algorithm/RSA/RSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@ RSA::RSA(const Algorithm::Intent intent) noexcept
RSA::~RSA() noexcept {
}

void RSA::setSettings(RSA::RSASettings&& settings) {
m_settings = std::make_unique<RSASettings>(std::move(settings));
initialize();
}

void RSA::initialize() {
m_params = std::make_unique<CryptoPP::InvertibleRSAFunction>();
m_params->GenerateRandomWithKeySize(*m_auto_seeded_random_pool, m_settings->keySize);

if (static_cast<bool>(m_intent & Intent::Encrypt)) {
m_private_key = std::make_unique<CryptoPP::RSA::PrivateKey>(*m_params);
m_public_key = std::make_unique<CryptoPP::RSA::PublicKey>(*m_params);
m_rsa_encryptor = std::make_unique<decltype(m_rsa_encryptor)::element_type>(*m_public_key);
}
if (static_cast<bool>(m_intent & Intent::Decrypt)) {
ENIGMA_ASSERT_OR_THROW(m_settings->privateKey or m_settings->privateKeyFilename, "RSA private key was not set for decryption");
if (m_settings->privateKey)
setPrivateKey(*m_settings->privateKey);
else {
std::vector<byte> pk;
FileUtils::Read(*m_settings->privateKeyFilename, pk);
setPrivateKey(std::string(pk.begin(), pk.end()));
}
m_rsa_decryptor = std::make_unique<decltype(m_rsa_decryptor)::element_type>(*m_private_key);
}
}

std::vector<byte> RSA::Encrypt(const std::string& password, const byte *buffer, const std::size_t buffSize) {
ENIGMA_ASSERT_OR_THROW(m_settings, "RSA settings was not set");
ENIGMA_ASSERT_OR_THROW(m_public_key, "RSA Public key is not initialized properly");
Expand Down Expand Up @@ -279,4 +306,68 @@ void RSA::Decrypt(const std::string& password, const fs::path& in_filename, cons
ENIGMA_ASSERT_OR_THROW(digest == footer.hash, "Decryption failure. Original SHA256 hash of file does not match decrypted hash");
}

void RSA::setPrivateKey(const std::string& privateKey) {
std::string privateKeyBase64 = privateKey;
if (privateKeyBase64.starts_with(BEGIN_RSA_PRIVATE_KEY_HEADER)) {
privateKeyBase64.erase(privateKeyBase64.begin(), privateKeyBase64.begin() + BEGIN_RSA_PRIVATE_KEY_HEADER.size());
}
if (privateKeyBase64.ends_with(END_RSA_PRIVATE_KEY_FOOTER)) {
privateKeyBase64.erase(privateKeyBase64.begin() + privateKeyBase64.size() - END_RSA_PRIVATE_KEY_FOOTER.size(), privateKeyBase64.end());
}

std::string decoded;
CryptoPP::StringSource ss(privateKeyBase64, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
m_private_key.reset(new CryptoPP::RSA::PrivateKey());

CryptoPP::ArraySource as(reinterpret_cast<const byte *>(decoded.data()), decoded.size(), true);
m_private_key->Load(as);
}

void RSA::setPublicKey(const std::string& publicKey) {
std::string publicKeyBase64 = publicKey;
if (publicKeyBase64.starts_with(BEGIN_RSA_PUBLIC_KEY_HEADER)) {
publicKeyBase64.erase(publicKeyBase64.begin(), publicKeyBase64.begin() + BEGIN_RSA_PUBLIC_KEY_HEADER.size());
}
if (publicKeyBase64.ends_with(END_RSA_PUBLIC_KEY_FOOTER)) {
publicKeyBase64.erase(publicKeyBase64.begin() + publicKeyBase64.size() - END_RSA_PUBLIC_KEY_FOOTER.size(), publicKeyBase64.end());
}

std::string decoded;
CryptoPP::StringSource ss(publicKeyBase64, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
m_public_key.reset(new CryptoPP::RSA::PublicKey());


CryptoPP::ArraySource as(reinterpret_cast<const byte *>(decoded.data()), decoded.size(), true);
m_public_key->Load(as);
}

std::string RSA::getPrivateKey() const {
std::string derPrivateKey;
CryptoPP::StringSink derSink(derPrivateKey);
m_private_key->DEREncode(derSink);

std::string base64PrivateKey;
CryptoPP::StringSource ss(derPrivateKey, true,
new CryptoPP::Base64Encoder(new CryptoPP::StringSink(base64PrivateKey), true /* with newlines */));
return BEGIN_RSA_PRIVATE_KEY_HEADER + base64PrivateKey + END_RSA_PRIVATE_KEY_FOOTER;
}
std::string RSA::getPublicKey() const {
std::string derPublicKey;
CryptoPP::StringSink derSink(derPublicKey);
m_public_key->DEREncode(derSink);

std::string base64PublicKey;
CryptoPP::StringSource ss(derPublicKey, true,
new CryptoPP::Base64Encoder(new CryptoPP::StringSink(base64PublicKey), true /* with newlines */));
return BEGIN_RSA_PUBLIC_KEY_HEADER + base64PublicKey + END_RSA_PUBLIC_KEY_FOOTER;
}
std::size_t RSA::getMaximumBufferSize() const {
ENIGMA_ASSERT_OR_THROW(m_rsa_encryptor, "RSA encryptor was not initialized properly");
return m_rsa_encryptor->FixedMaxPlaintextLength();
}
constexpr std::size_t RSA::getMaximumBufferSizeFromKeySize(const std::size_t keySize) {
return keySize / 8 - 2 * static_cast<std::size_t>(CryptoPP::SHA256::DIGESTSIZE) - 2;
}


NS_ENIGMA_END
102 changes: 10 additions & 92 deletions src/Algorithm/RSA/RSA.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,8 @@ class RSA : public Algorithm {
//std::optional<fs::path> publicKeyFilename{std::nullopt};
};

void setSettings(RSASettings&& settings) {
m_settings = std::make_unique<RSASettings>(std::move(settings));
initialize();
}

void initialize() {
m_params = std::make_unique<CryptoPP::InvertibleRSAFunction>();
m_params->GenerateRandomWithKeySize(*m_auto_seeded_random_pool, m_settings->keySize);

if (static_cast<bool>(m_intent & Intent::Encrypt)) {
m_private_key = std::make_unique<CryptoPP::RSA::PrivateKey>(*m_params);
m_public_key = std::make_unique<CryptoPP::RSA::PublicKey>(*m_params);
m_rsa_encryptor = std::make_unique<decltype(m_rsa_encryptor)::element_type>(*m_public_key);
}
if (static_cast<bool>(m_intent & Intent::Decrypt)) {
ENIGMA_ASSERT_OR_THROW(m_settings->privateKey or m_settings->privateKeyFilename, "RSA private key was not set for decryption");
if (m_settings->privateKey)
setPrivateKey(*m_settings->privateKey);
else {
std::vector<byte> pk;
FileUtils::Read(*m_settings->privateKeyFilename, pk);
setPrivateKey(std::string(pk.begin(), pk.end()));
}
m_rsa_decryptor = std::make_unique<decltype(m_rsa_decryptor)::element_type>(*m_private_key);
}
}
void setSettings(RSASettings&& settings);


public:
std::vector<byte> Encrypt(const std::string& password, const byte *buffer, const std::size_t buffSize) override;
Expand Down Expand Up @@ -104,78 +80,20 @@ class RSA : public Algorithm {
bool result = verifier.VerifyMessage(message.data(),
message.size(), signature, signature.size());
return result;
}
}it gu

private:
void setPrivateKey(const std::string& privateKey) {
std::string privateKeyBase64 = privateKey;
if (privateKeyBase64.starts_with(BEGIN_RSA_PRIVATE_KEY_HEADER)) {
privateKeyBase64.erase(privateKeyBase64.begin(), privateKeyBase64.begin() + BEGIN_RSA_PRIVATE_KEY_HEADER.size());
}
if (privateKeyBase64.ends_with(END_RSA_PRIVATE_KEY_FOOTER)) {
privateKeyBase64.erase(privateKeyBase64.begin() + privateKeyBase64.size() - END_RSA_PRIVATE_KEY_FOOTER.size(), privateKeyBase64.end());
}

std::string decoded;
CryptoPP::StringSource ss(privateKeyBase64, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
m_private_key.reset(new CryptoPP::RSA::PrivateKey());

CryptoPP::ArraySource as(reinterpret_cast<const byte *>(decoded.data()), decoded.size(), true);
m_private_key->Load(as);
}

void setPublicKey(const std::string& publicKey) {
std::string publicKeyBase64 = publicKey;
if (publicKeyBase64.starts_with(BEGIN_RSA_PUBLIC_KEY_HEADER)) {
publicKeyBase64.erase(publicKeyBase64.begin(), publicKeyBase64.begin() + BEGIN_RSA_PUBLIC_KEY_HEADER.size());
}
if (publicKeyBase64.ends_with(END_RSA_PUBLIC_KEY_FOOTER)) {
publicKeyBase64.erase(publicKeyBase64.begin() + publicKeyBase64.size() - END_RSA_PUBLIC_KEY_FOOTER.size(), publicKeyBase64.end());
}

std::string decoded;
CryptoPP::StringSource ss(publicKeyBase64, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
m_public_key.reset(new CryptoPP::RSA::PublicKey());


CryptoPP::ArraySource as(reinterpret_cast<const byte *>(decoded.data()), decoded.size(), true);
m_public_key->Load(as);
}
void initialize();
void setPrivateKey(const std::string& privateKey);
void setPublicKey(const std::string& publicKey);

public:
std::string getPrivateKey() const {
std::string derPrivateKey;
CryptoPP::StringSink derSink(derPrivateKey);
m_private_key->DEREncode(derSink);

std::string base64PrivateKey;
CryptoPP::StringSource ss(derPrivateKey, true,
new CryptoPP::Base64Encoder(new CryptoPP::StringSink(base64PrivateKey), true /* with newlines */));
return BEGIN_RSA_PRIVATE_KEY_HEADER + base64PrivateKey + END_RSA_PRIVATE_KEY_FOOTER;
}

std::string getPublicKey() const {
std::string derPublicKey;
CryptoPP::StringSink derSink(derPublicKey);
m_public_key->DEREncode(derSink);

std::string base64PublicKey;
CryptoPP::StringSource ss(derPublicKey, true,
new CryptoPP::Base64Encoder(new CryptoPP::StringSink(base64PublicKey), true /* with newlines */));
return BEGIN_RSA_PUBLIC_KEY_HEADER + base64PublicKey + END_RSA_PUBLIC_KEY_FOOTER;
}
std::string getPrivateKey() const;
std::string getPublicKey() const;

public:
std::size_t getMaximumBufferSize() const {
ENIGMA_ASSERT_OR_THROW(m_rsa_encryptor, "RSA encryptor was not initialized properly");
return m_rsa_encryptor->FixedMaxPlaintextLength();
}
// std::size_t getKeySize() const {
// ENIGMA_ASSERT_OR_THROW(m_params, "RSA params was not initialized properly");
// }
static constexpr std::size_t getMaximumBufferSizeFromKeySize(const std::size_t keySize) {
return keySize / 8 - 2 * static_cast<std::size_t>(CryptoPP::SHA256::DIGESTSIZE) - 2;
}
std::size_t getMaximumBufferSize() const;
static constexpr std::size_t getMaximumBufferSizeFromKeySize(const std::size_t keySize);

private:
std::unique_ptr<CryptoPP::RSAES<CryptoPP::OAEP<CryptoPP::SHA256>>::Encryptor> m_rsa_encryptor; /**< RSA encryptor */
Expand Down

0 comments on commit eb46261

Please sign in to comment.