diff --git a/src/lib/src/private/easysslutils.cpp b/src/lib/src/private/easysslutils.cpp index 31f6b89..f5a4d1e 100644 --- a/src/lib/src/private/easysslutils.cpp +++ b/src/lib/src/private/easysslutils.cpp @@ -16,9 +16,7 @@ namespace EasySSL { void EasySSLUtils::printlastOpenSSlError() { - int error = ERR_get_error(); - char buffer[256]; - ERR_error_string(error, buffer); + ERR_print_errors_fp(stderr); } QByteArray EasySSLUtils::bignumToArray(const BIGNUM *num) { diff --git a/src/lib/src/public/easyssl/authecdsa.h b/src/lib/src/public/easyssl/authecdsa.h index 43093ed..120805d 100644 --- a/src/lib/src/public/easyssl/authecdsa.h +++ b/src/lib/src/public/easyssl/authecdsa.h @@ -9,7 +9,7 @@ #ifndef AUTHECDSA_H #define AUTHECDSA_H -#include "ecdsassl11.h" +#include "ecdsassl.h" #include "asynckeysauth.h" namespace EasySSL { @@ -17,7 +17,7 @@ namespace EasySSL { /** * @brief The AuthECDSA class is ecdsa implementation of the Async authentication. This implementation based on Openssl library. */ -typedef AsyncKeysAuth AuthECDSA; +typedef AsyncKeysAuth AuthECDSA; } diff --git a/src/lib/src/public/easyssl/ecdsassl.cpp b/src/lib/src/public/easyssl/ecdsassl.cpp new file mode 100644 index 0000000..618ed8d --- /dev/null +++ b/src/lib/src/public/easyssl/ecdsassl.cpp @@ -0,0 +1,154 @@ +//# +//# Copyright (C) 2021-2023 QuasarApp. +//# Distributed under the GPLv3 software license, see the accompanying +//# Everyone is permitted to copy and distribute verbatim copies +//# of this license document, but changing it is not allowed. +//# + + +#include "ecdsassl.h" + +#include // for ECDSA_do_sign, ECDSA_do_verify +#include // for NID_secp192k1 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace EasySSL { + + +ECDSASSL::ECDSASSL() {} + +EVP_PKEY * ECDSASSL::makeRawKeys() const { + + EVP_PKEY *pkey = nullptr; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr); + if (!pctx) { + qCritical() << "Error reading public key"; + return nullptr; + } + + EVP_PKEY_keygen_init(pctx); + EVP_PKEY_generate(pctx, &pkey); + EVP_PKEY_CTX_free(pctx); + + return pkey; +} + +ICrypto::Features ECDSASSL::supportedFeatures() const { + return Features::Signing; +} + +QSsl::KeyAlgorithm ECDSASSL::keyAlgorithm() const { + return QSsl::KeyAlgorithm::Ec; +} + +QByteArray ECDSASSL::signMessage(const QByteArray &inputData, + const QByteArray &key) const { + + QByteArray signature; + + auto pkey = EasySSLUtils::byteArrayToBio(key); + auto ecPrivateKey = PEM_read_bio_PrivateKey(pkey, nullptr, nullptr, nullptr); + BIO_free(pkey); + + if (!ecPrivateKey) { + qCritical() << "Error reading private key"; + return {}; + } + + EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); + if (mdctx == nullptr) { + return {}; + } + + // Initialize the signing operation + if (EVP_DigestSignInit(mdctx, nullptr, EVP_sha256(), nullptr, ecPrivateKey) != 1) { + EVP_MD_CTX_free(mdctx); + return {}; + } + + auto hash = QCryptographicHash::hash(inputData, + QCryptographicHash::Sha256); + + // Provide the message to be signed + if (EVP_DigestSignUpdate(mdctx, hash.data(), hash.size()) != 1) { + EVP_MD_CTX_free(mdctx); + return {}; + } + + size_t signatureLength = 0; + // Determine the length of the signature + if (EVP_DigestSignFinal(mdctx, nullptr, &signatureLength) != 1) { + EVP_MD_CTX_free(mdctx); + return {}; + } + + signature.resize(signatureLength); + + // Perform the final signing operation and obtain the signature + if (EVP_DigestSignFinal(mdctx, reinterpret_cast(signature.data()), &signatureLength) != 1) { + EVP_MD_CTX_free(mdctx); + return {}; + } + + EVP_MD_CTX_free(mdctx); + return signature; +} + +bool ECDSASSL::checkSign(const QByteArray &inputData, + const QByteArray &signature, + const QByteArray &key) const { + + + EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); + if (mdctx == nullptr) { + return false; + } + + auto pkey = EasySSLUtils::byteArrayToBio(key); + auto rsaPublickKey = PEM_read_bio_PUBKEY(pkey, nullptr, nullptr, nullptr); + BIO_free(pkey); + + // Initialize the verification operation + if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, rsaPublickKey) != 1) { + EVP_MD_CTX_free(mdctx); + return false; + } + + auto hash = QCryptographicHash::hash(inputData, + QCryptographicHash::Sha256); + + // Provide the message to be verified + if (EVP_DigestVerifyUpdate(mdctx, hash.data(), hash.size()) != 1) { + EVP_MD_CTX_free(mdctx); + return false; + } + + // Perform the signature verification + int verificationResult = EVP_DigestVerifyFinal(mdctx, + reinterpret_cast(signature.data()), + signature.length()); + + EVP_MD_CTX_free(mdctx); + + return verificationResult == 1; + +} + +QByteArray ECDSASSL::decrypt(const QByteArray &, const QByteArray &) { + return {}; +} + +QByteArray ECDSASSL::encrypt(const QByteArray &, const QByteArray &) { + return {}; +} + +} diff --git a/src/lib/src/public/easyssl/ecdsassl11.h b/src/lib/src/public/easyssl/ecdsassl.h similarity index 85% rename from src/lib/src/public/easyssl/ecdsassl11.h rename to src/lib/src/public/easyssl/ecdsassl.h index 2e526dd..8e16ab0 100644 --- a/src/lib/src/public/easyssl/ecdsassl11.h +++ b/src/lib/src/public/easyssl/ecdsassl.h @@ -16,16 +16,15 @@ namespace EasySSL { /** * @brief The ECDSASSL11 class is ecdsa implementation of the Async authentication. This implementation based on Openssl library. - * @note This class compatibility only with ssl 1.1 */ -class EASYSSL_EXPORT ECDSASSL11: public EasySSL::ICrypto +class EASYSSL_EXPORT ECDSASSL: public EasySSL::ICrypto { public: - ECDSASSL11(); - bool makeKeys(QByteArray &pubKey, QByteArray &privKey) const override; + ECDSASSL(); + EVP_PKEY * makeRawKeys() const override; Features supportedFeatures() const override; - + QSsl::KeyAlgorithm keyAlgorithm() const override; QByteArray signMessage(const QByteArray &inputData, const QByteArray &key) const override; bool checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const override; @@ -42,7 +41,7 @@ public: */ QByteArray encrypt(const QByteArray &message, const QByteArray &key) override; - }; +}; } diff --git a/src/lib/src/public/easyssl/ecdsassl11.cpp b/src/lib/src/public/easyssl/ecdsassl11.cpp deleted file mode 100644 index e36688d..0000000 --- a/src/lib/src/public/easyssl/ecdsassl11.cpp +++ /dev/null @@ -1,223 +0,0 @@ -//# -//# Copyright (C) 2021-2023 QuasarApp. -//# Distributed under the GPLv3 software license, see the accompanying -//# Everyone is permitted to copy and distribute verbatim copies -//# of this license document, but changing it is not allowed. -//# - - -#include "ecdsassl11.h" - -#include // for ECDSA_do_sign, ECDSA_do_verify -#include // for NID_secp192k1 -#include -#include - -#include -#include -#include -#include -#include - -namespace EasySSL { - -bool prepareKeyAdnGroupObjects(EC_KEY **eckey, EC_GROUP **ecgroup) { - - // input data should be valid pointers to pointers of key and group objects. - if (!(eckey && ecgroup)) - return false; - - // input pointers should be nullptr; - if ((*eckey) || (*ecgroup)) - return false; - - auto free = [eckey, ecgroup] () { - if (*ecgroup) - EC_GROUP_free(*ecgroup); - - if (*eckey) - EC_KEY_free(*eckey); - }; - - *eckey = EC_KEY_new(); - if (!*eckey) { - EasySSLUtils::printlastOpenSSlError(); - free(); - return false; - } - - *ecgroup = EC_GROUP_new_by_curve_name(NID_secp256k1); - - if (!*ecgroup) { - EasySSLUtils::printlastOpenSSlError(); - free(); - return false; - } - - if (!EC_KEY_set_group(*eckey, *ecgroup)) { - EasySSLUtils::printlastOpenSSlError(); - free(); - return false; - } - - return true; -} - - -ECDSASSL11::ECDSASSL11() {} - -QByteArray extractPrivateKey(EC_KEY* ec_key) { - const BIGNUM* ec_priv = EC_KEY_get0_private_key(ec_key); - return EasySSLUtils::bignumToArray(ec_priv); -} - -QByteArray extractPublicKey(EC_KEY* key, EC_GROUP* group) { - - QByteArray data; - point_conversion_form_t form = EC_GROUP_get_point_conversion_form(group); - - unsigned char* pub_key_buffer; - size_t length = EC_KEY_key2buf(key, form, &pub_key_buffer, nullptr); - - if (length <= 0) { - EasySSLUtils::printlastOpenSSlError(); - return {}; - } - - data.insert(0, reinterpret_cast(pub_key_buffer), length); - - OPENSSL_free(pub_key_buffer); - - return data; -} - -bool ECDSASSL11::makeKeys(QByteArray &pubKey, QByteArray &privKey) const { - - EC_KEY *eckey= nullptr; - EC_GROUP *ecgroup = nullptr; - - if (!prepareKeyAdnGroupObjects(&eckey, &ecgroup)) { - return false; - } - - if (!EC_KEY_generate_key(eckey)) { - EasySSLUtils::printlastOpenSSlError(); - EC_GROUP_free(ecgroup); - EC_KEY_free(eckey); - return false; - } - - pubKey = extractPublicKey(eckey, ecgroup); - privKey = extractPrivateKey(eckey); - - return pubKey.length() && privKey.length(); -} - -ICrypto::Features ECDSASSL11::supportedFeatures() const { - return Features::Signing; -} - -QByteArray ECDSASSL11::signMessage(const QByteArray &inputData, - const QByteArray &key) const { - - EC_KEY *eckey= nullptr; - EC_GROUP *ecgroup = nullptr; - - if (!prepareKeyAdnGroupObjects(&eckey, &ecgroup)) { - return {}; - } - - auto hash = QCryptographicHash::hash(inputData, - QCryptographicHash::Sha256); - - BIGNUM* priv = EasySSLUtils::bignumFromArray(key); - if (!EC_KEY_set_private_key(eckey, priv)) { - EasySSLUtils::printlastOpenSSlError(); - EC_GROUP_free(ecgroup); - EC_KEY_free(eckey); - return {}; - }; - - ECDSA_SIG *signature = ECDSA_do_sign(reinterpret_cast(hash.data()), - hash.length(), eckey); - BN_free(priv); - EC_KEY_free(eckey); - EC_GROUP_free(ecgroup); - - if (!signature) { - EasySSLUtils::printlastOpenSSlError(); - return {}; - } - - const BIGNUM * R, *S; - ECDSA_SIG_get0(signature, &R, &S); - - QByteArray result; - QDataStream stream(&result, QIODevice::WriteOnly); - - stream << EasySSLUtils::bignumToArray(R); - stream << EasySSLUtils::bignumToArray(S); - - ECDSA_SIG_free(signature); - - return result; -} - -bool ECDSASSL11::checkSign(const QByteArray &inputData, - const QByteArray &signature, - const QByteArray &key) const { - - - // extract signature from raw array - - BIGNUM * R, *S; - QDataStream stream(signature); - - QByteArray rR,rS; - stream >> rR; - stream >> rS; - R = EasySSLUtils::bignumFromArray(rR); - S = EasySSLUtils::bignumFromArray(rS); - - ECDSA_SIG *sig = ECDSA_SIG_new(); - ECDSA_SIG_set0(sig, R, S); - - auto hash = QCryptographicHash::hash(inputData, - QCryptographicHash::Sha256); - - EC_KEY *eckey= nullptr; - EC_GROUP *ecgroup = nullptr; - - if (!prepareKeyAdnGroupObjects(&eckey, &ecgroup)) { - ECDSA_SIG_free(sig); - return {}; - } - - // extract key from raw array; - EC_POINT* ec_point = EC_POINT_new(ecgroup); - EC_POINT_oct2point(ecgroup, ec_point, - reinterpret_cast(key.data()), - key.length(), nullptr); - - EC_KEY_set_public_key(eckey, ec_point); - - - int verify_status = ECDSA_do_verify(reinterpret_cast(hash.data()), - hash.length(), sig, eckey); - - ECDSA_SIG_free(sig); - EC_POINT_free(ec_point); - - return verify_status == 1; - -} - -QByteArray ECDSASSL11::decrypt(const QByteArray &, const QByteArray &) { - return {}; -} - -QByteArray ECDSASSL11::encrypt(const QByteArray &, const QByteArray &) { - return {}; -} - -} diff --git a/src/lib/src/public/easyssl/rsassl30.cpp b/src/lib/src/public/easyssl/rsassl.cpp similarity index 63% rename from src/lib/src/public/easyssl/rsassl30.cpp rename to src/lib/src/public/easyssl/rsassl.cpp index 01b4fed..62b0721 100644 --- a/src/lib/src/public/easyssl/rsassl30.cpp +++ b/src/lib/src/public/easyssl/rsassl.cpp @@ -6,21 +6,22 @@ //# -#include "rsassl30.h" +#include "rsassl.h" #include "qcryptographichash.h" #include #include #include #include #include +#include namespace EasySSL { -RSASSL30::RSASSL30() { +RSASSL::RSASSL() { } -EVP_PKEY * RSASSL30::makeRawKeys() const { +EVP_PKEY * RSASSL::makeRawKeys() const { EVP_PKEY *pkey = nullptr; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(nullptr, "RSA", nullptr); @@ -33,11 +34,15 @@ EVP_PKEY * RSASSL30::makeRawKeys() const { return pkey; } -ICrypto::Features RSASSL30::supportedFeatures() const { +ICrypto::Features RSASSL::supportedFeatures() const { return static_cast(Features::Encription | Features::Signing); } -QByteArray RSASSL30::signMessage(const QByteArray &inputData, const QByteArray &key) const { +QSsl::KeyAlgorithm RSASSL::keyAlgorithm() const { + return QSsl::KeyAlgorithm::Rsa; +} + +QByteArray RSASSL::signMessage(const QByteArray &inputData, const QByteArray &key) const { QByteArray signature; auto pkey = EasySSLUtils::byteArrayToBio(key); @@ -45,7 +50,7 @@ QByteArray RSASSL30::signMessage(const QByteArray &inputData, const QByteArray & BIO_free(pkey); if (!rsaPrivateKey) { - perror("Error reading private key"); + qCritical() << "Error reading private key"; return {}; } @@ -88,7 +93,7 @@ QByteArray RSASSL30::signMessage(const QByteArray &inputData, const QByteArray & return signature; } -bool RSASSL30::checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const { +bool RSASSL::checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const { EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); if (mdctx == nullptr) { return false; @@ -123,17 +128,26 @@ bool RSASSL30::checkSign(const QByteArray &inputData, const QByteArray &signatur return verificationResult == 1; } -QByteArray RSASSL30::decrypt(const QByteArray &message, const QByteArray &key) { +QByteArray RSASSL::decrypt(const QByteArray &message, const QByteArray &key) { auto pkey = EasySSLUtils::byteArrayToBio(key); auto rsaPrivateKey = PEM_read_bio_PrivateKey(pkey, nullptr, nullptr, nullptr); BIO_free(pkey); if (!rsaPrivateKey) { - perror("Error reading private key"); + qCritical() << "Error reading private key"; return {}; } + const long long maxDencryptedSize = EVP_PKEY_size(rsaPrivateKey); + if (message.length() % maxDencryptedSize) { + qCritical() << "Error wrong encripted data size."; + qCritical() << "Your key requir size multiple " << maxDencryptedSize; + + return {}; + } + + EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(rsaPrivateKey, nullptr); if (ctx == nullptr) { EVP_PKEY_free(rsaPrivateKey); @@ -152,18 +166,25 @@ QByteArray RSASSL30::decrypt(const QByteArray &message, const QByteArray &key) { return {}; } - size_t decryptedDataLength = 0; - if (EVP_PKEY_decrypt(ctx, nullptr, &decryptedDataLength, reinterpret_cast(message.constData()), message.length()) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(rsaPrivateKey); - return {}; - } + QByteArray decryptedData; - QByteArray decryptedData(decryptedDataLength, 0); - if (EVP_PKEY_decrypt(ctx, reinterpret_cast(decryptedData.data()), &decryptedDataLength, reinterpret_cast(message.constData()), message.length()) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(rsaPrivateKey); - return {}; + for (int index = 0; index < message.size(); index += maxDencryptedSize) { + + QByteArray decryptedDataPart(maxDencryptedSize, 0); + size_t realDecryptedDataPartSize = 0; + if (EVP_PKEY_decrypt(ctx, + reinterpret_cast(decryptedDataPart.data()), + &realDecryptedDataPartSize, + reinterpret_cast(&(message.constData()[index])), + maxDencryptedSize) <= 0) { + + EasySSLUtils::printlastOpenSSlError(); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(rsaPrivateKey); + return {}; + } + + decryptedData += decryptedDataPart.left(realDecryptedDataPartSize); } EVP_PKEY_CTX_free(ctx); @@ -172,13 +193,13 @@ QByteArray RSASSL30::decrypt(const QByteArray &message, const QByteArray &key) { } -QByteArray RSASSL30::encrypt(const QByteArray &message, const QByteArray &key) { +QByteArray RSASSL::encrypt(const QByteArray &message, const QByteArray &key) { auto pkey = EasySSLUtils::byteArrayToBio(key); auto rsaPublicKey = PEM_read_bio_PUBKEY(pkey, nullptr, nullptr, nullptr); BIO_free(pkey); if (!rsaPublicKey) { - perror("Error reading public key"); + qCritical() << "Error reading public key"; return {}; } @@ -200,18 +221,27 @@ QByteArray RSASSL30::encrypt(const QByteArray &message, const QByteArray &key) { return {}; } - size_t encryptedDataLength = 0; - if (EVP_PKEY_encrypt(ctx, nullptr, &encryptedDataLength, reinterpret_cast(message.constData()), message.length()) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(rsaPublicKey); - return {}; - } + const long long maxEncryptedSize = EVP_PKEY_size(rsaPublicKey); + QByteArray encryptedData; - QByteArray encryptedData(encryptedDataLength, 0); - if (EVP_PKEY_encrypt(ctx, reinterpret_cast(encryptedData.data()), &encryptedDataLength, reinterpret_cast(message.constData()), message.length()) <= 0) { - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(rsaPublicKey); - return {}; + for (int index = 0; index < message.size();) { + + QByteArray encryptedDataPart(maxEncryptedSize, 0); + size_t realEncryptedDataPartSize = 0; + int currentPartSize = std::min(message.length() - index, maxEncryptedSize); + if (EVP_PKEY_encrypt(ctx, + reinterpret_cast(encryptedDataPart.data()), + &realEncryptedDataPartSize, + reinterpret_cast(&(message.constData()[index])), + currentPartSize) <= 0) { + + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(rsaPublicKey); + return {}; + } + + encryptedData += encryptedDataPart.left(realEncryptedDataPartSize); + index += currentPartSize; } EVP_PKEY_CTX_free(ctx); diff --git a/src/lib/src/public/easyssl/rsassl30.h b/src/lib/src/public/easyssl/rsassl.h similarity index 90% rename from src/lib/src/public/easyssl/rsassl30.h rename to src/lib/src/public/easyssl/rsassl.h index 951f2a1..33a3bfb 100644 --- a/src/lib/src/public/easyssl/rsassl30.h +++ b/src/lib/src/public/easyssl/rsassl.h @@ -17,13 +17,14 @@ namespace EasySSL { /** * @brief The RSASSL30 class This is wrapper for RSA algorithm of openssl 3.0 libraryry. */ -class EASYSSL_EXPORT RSASSL30: public EasySSL::ICrypto +class EASYSSL_EXPORT RSASSL: public EasySSL::ICrypto { public: - RSASSL30(); + RSASSL(); EVP_PKEY *makeRawKeys() const override; Features supportedFeatures() const override; + QSsl::KeyAlgorithm keyAlgorithm() const override; QByteArray signMessage(const QByteArray &inputData, const QByteArray &key) const override; bool checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const override; @@ -39,6 +40,7 @@ public: * @return empty array. */ QByteArray encrypt(const QByteArray &message, const QByteArray &key) override; + }; } diff --git a/src/lib/src/public/easyssl/rsassl11.cpp b/src/lib/src/public/easyssl/rsassl11.cpp deleted file mode 100644 index da3b05e..0000000 --- a/src/lib/src/public/easyssl/rsassl11.cpp +++ /dev/null @@ -1,199 +0,0 @@ -//# -//# Copyright (C) 2021-2023 QuasarApp. -//# Distributed under the GPLv3 software license, see the accompanying -//# Everyone is permitted to copy and distribute verbatim copies -//# of this license document, but changing it is not allowed. -//# - - -#include "rsassl11.h" -#include "qcryptographichash.h" -#include -#include -#include -#include - -namespace EasySSL { - -RSASSL11::RSASSL11() { - -} - -bool RSASSL11::makeKeys(QByteArray &pubKey, QByteArray &privKey) const { - EVP_PKEY *pkey = EVP_PKEY_new(); - - if (!pkey) { - return false; - } - - BIGNUM * bn = BN_new(); - - int rc = BN_set_word(bn, RSA_F4); - - if (rc != 1) { - BN_free(bn); - EVP_PKEY_free(pkey); - return false; - } - - RSA * rsa = RSA_new(); - - auto failed = [bn, rsa, pkey] () { - BN_free(bn); - RSA_free(rsa); - EVP_PKEY_free(pkey); - return false; - }; - - if (!RSA_generate_key_ex(rsa, 4196, bn, nullptr)) { - return failed(); - } - - q_check_ptr(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - return failed(); - } - - BIO *mem; - mem = BIO_new_mem_buf(pkey, -1); //pkey is of type char* - - auto key = PEM_read_bio_PrivateKey(mem, NULL, NULL, 0); - - - BIO *private_key_bio = BIO_new(BIO_s_mem()); - PEM_write_bio_RSAPrivateKey(private_key_bio, rsa, NULL, NULL, 0, NULL, NULL); - char *private_key_data; - long private_key_size = BIO_get_mem_data(private_key_bio, &private_key_data); - privKey = QByteArray(private_key_data, private_key_size); - BIO_free(private_key_bio); - - BIO *public_key_bio = BIO_new(BIO_s_mem()); - PEM_write_bio_RSAPublicKey(public_key_bio, rsa); - char *public_key_data; - long public_key_size = BIO_get_mem_data(public_key_bio, &public_key_data); - pubKey = QByteArray(public_key_data, public_key_size); - BIO_free(public_key_bio); - - return true; -} - -ICrypto::Features RSASSL11::supportedFeatures() const { - return static_cast(Features::Encription | Features::Signing); -} - -QByteArray RSASSL11::signMessage(const QByteArray &inputData, const QByteArray &key) const { - QByteArray signature; - - BIO* privateKeyBio = BIO_new_mem_buf(key.data(), key.size()); - - RSA* rsaPrivateKey = PEM_read_bio_RSAPrivateKey(privateKeyBio, nullptr, nullptr, nullptr); - BIO_free(privateKeyBio); - - if (!rsaPrivateKey) { - perror("Error reading private key"); - return {}; - } - - auto hash = QCryptographicHash::hash(inputData, - QCryptographicHash::Sha256); - - signature.resize(RSA_size(rsaPrivateKey)); - unsigned int signatureLength = 0; - int result = RSA_sign(NID_sha256, reinterpret_cast(hash.data()), - hash.size(), reinterpret_cast(signature.data()), - &signatureLength, rsaPrivateKey); - RSA_free(rsaPrivateKey); - - if (result != 1) { - perror("Error signing message"); - return {}; - } - - signature.resize(signatureLength); - return signature; -} - -bool RSASSL11::checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const { - BIO* publicKeyBio = BIO_new_mem_buf(key.data(), key.size()); - - RSA* rsaPublicKey = PEM_read_bio_RSA_PUBKEY(publicKeyBio, nullptr, nullptr, nullptr); - BIO_free(publicKeyBio); - - if (!rsaPublicKey) { - perror("Error reading public key"); - return false; - } - - auto hash = QCryptographicHash::hash(inputData, - QCryptographicHash::Sha256); - - int result = RSA_verify(NID_sha256, reinterpret_cast(hash.data()), - hash.size(), reinterpret_cast(signature.data()), - signature.size(), rsaPublicKey); - RSA_free(rsaPublicKey); - - if (result != 1) { - perror("Error verifying signature"); - return false; - } - - return true; -} - -QByteArray RSASSL11::decrypt(const QByteArray &message, const QByteArray &key) { - QByteArray decryptedMessage; - - BIO* privateKeyBio = BIO_new_mem_buf(key.data(), key.size()); - - RSA* rsaPrivateKey = PEM_read_bio_RSAPrivateKey(privateKeyBio, nullptr, nullptr, nullptr); - BIO_free(privateKeyBio); - - if (!rsaPrivateKey) { - perror("Error reading private key"); - return {}; - } - - decryptedMessage.resize(RSA_size(rsaPrivateKey)); - int result = RSA_private_decrypt(message.size(), - reinterpret_cast(message.data()), - reinterpret_cast(decryptedMessage.data()), - rsaPrivateKey, RSA_PKCS1_PADDING); - RSA_free(rsaPrivateKey); - - if (result == -1) { - perror("Error decrypting ciphertext"); - return {}; - } - - return decryptedMessage; -} - -QByteArray RSASSL11::encrypt(const QByteArray &message, const QByteArray &key) { - QByteArray encryptedMessage; - BIO* publicKeyBio = BIO_new_mem_buf(key.data(), key.size()); - - RSA* rsaPublicKey = PEM_read_bio_RSA_PUBKEY(publicKeyBio, nullptr, nullptr, nullptr); - BIO_free(publicKeyBio); - - if (!rsaPublicKey) { - perror("Error reading public key"); - return {}; - } - - encryptedMessage.resize(RSA_size(rsaPublicKey)); - - int result = RSA_public_encrypt(message.size(), - reinterpret_cast(message.data()), - reinterpret_cast(encryptedMessage.data()), - rsaPublicKey, RSA_PKCS1_PADDING); - RSA_free(rsaPublicKey); - - if (result == -1) { - perror("Error encrypting message"); - return {}; - } - - return encryptedMessage; -} - -} diff --git a/src/lib/src/public/easyssl/rsassl11.h b/src/lib/src/public/easyssl/rsassl11.h deleted file mode 100644 index 9f5bb73..0000000 --- a/src/lib/src/public/easyssl/rsassl11.h +++ /dev/null @@ -1,45 +0,0 @@ -//# -//# Copyright (C) 2021-2023 QuasarApp. -//# Distributed under the GPLv3 software license, see the accompanying -//# Everyone is permitted to copy and distribute verbatim copies -//# of this license document, but changing it is not allowed. -//# - - -#ifndef RSASSL11_H -#define RSASSL11_H - -#include "global.h" -#include "icrypto.h" - -namespace EasySSL { - -/** - * @brief The RSASSL11 class This is wrapper of the openssl 1.1 implementation of the RSA alghorithm - */ -class EASYSSL_EXPORT RSASSL11: public EasySSL::ICrypto -{ -public: - RSASSL11(); - - bool makeKeys(QByteArray &pubKey, QByteArray &privKey) const override; - Features supportedFeatures() const override; - - - QByteArray signMessage(const QByteArray &inputData, const QByteArray &key) const override; - bool checkSign(const QByteArray &inputData, const QByteArray &signature, const QByteArray &key) const override; - - /** - * @brief decrypt This method has empty implementation. - * @return empty array. - */ - QByteArray decrypt(const QByteArray &message, const QByteArray &key) override; - - /** - * @brief encrypt This method has empty implementation. - * @return empty array. - */ - QByteArray encrypt(const QByteArray &message, const QByteArray &key) override; -}; -} -#endif // RSASSL11_H diff --git a/src/lib/src/public/easyssl/x509.cpp b/src/lib/src/public/easyssl/x509.cpp index fb2db39..3b629e0 100644 --- a/src/lib/src/public/easyssl/x509.cpp +++ b/src/lib/src/public/easyssl/x509.cpp @@ -52,13 +52,10 @@ SelfSignedSertificate X509::create(const SslSrtData &certificateData) const { if(result.key.isNull()) { EVP_PKEY_free(pkey); X509_free(x509); - BIO_free_all(bp_public); - BIO_free_all(bp_private); qCritical("Failed to generate a random private key"); return {}; } EVP_PKEY_free(pkey); - BIO_free_all(bp_private); BIO * bp_public = BIO_new(BIO_s_mem()); q_check_ptr(bp_public); diff --git a/tests/tstMain.cpp b/tests/tstMain.cpp index fff8538..d96354f 100644 --- a/tests/tstMain.cpp +++ b/tests/tstMain.cpp @@ -8,7 +8,8 @@ #include #include "cryptotest.h" #include "authtest.h" -#include +#include "easyssl/rsassl.h" +#include // Use This macros for initialize your own test classes. // Check exampletests @@ -35,7 +36,8 @@ private slots: // BEGIN TESTS CASES TestCase(authTest, AuthTest) - TestCase(cryptoTest, CryptoTest) + TestCase(cryptoTestESDSA, CryptoTest) + TestCase(cryptoTestRSA, CryptoTest) // END TEST CASES diff --git a/tests/units/cryptotest.h b/tests/units/cryptotest.h index 2f811c1..1e26e13 100644 --- a/tests/units/cryptotest.h +++ b/tests/units/cryptotest.h @@ -20,6 +20,18 @@ class CryptoTest: public Test, protected TestUtils public: void test() override { + // test short messges + testImpl("Test"); + + //test long messages + + const int Mb = 1024 * 1024 * 1024; //1 mb + testImpl(QByteArray(Mb, 'c')); + + } ; + + + void testImpl(const QByteArray& message) const { // create a publick and private keys array. QByteArray pub, priv; TestClass crypto; @@ -29,19 +41,18 @@ public: QVERIFY2(priv.size(), "Private key should be generated successfull"); if (crypto.supportedFeatures() & EasySSL::ICrypto::Features::Signing) { - auto siganture = crypto.signMessage("Test", priv); + auto siganture = crypto.signMessage(message, priv); QVERIFY2(siganture.size(), "Siganture of the message should not be empty"); - QVERIFY2(crypto.checkSign("Test", siganture, pub), "failed to check message"); + QVERIFY2(crypto.checkSign(message, siganture, pub), "failed to check message"); } if (crypto.supportedFeatures() & EasySSL::ICrypto::Features::Encription) { - auto encriptedMsg = crypto.encrypt("Test", pub); + auto encriptedMsg = crypto.encrypt(message, pub); QVERIFY2(encriptedMsg.size(), "Encripted message should not be empty"); auto decryptedMsg = crypto.decrypt(encriptedMsg, priv); - QVERIFY2(decryptedMsg == "Test", "Failed to check message after decryption"); + QVERIFY2(decryptedMsg == message, "Failed to check message after decryption"); } - - } ; + } }; #endif // CRYPTO_TEST_H diff --git a/tests/units/test.cpp b/tests/units/test.cpp index ea1c3c3..f7b9320 100644 --- a/tests/units/test.cpp +++ b/tests/units/test.cpp @@ -6,4 +6,3 @@ //# -#include "test.h"