diff options
author | saturneric <[email protected]> | 2023-12-25 12:51:01 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2023-12-25 12:51:01 +0000 |
commit | 5260d7a5634279408b3eb36a5f26fe71fb6f9e69 (patch) | |
tree | 670e0878a41e8c6b1651fedbd224bfbea94e0849 | |
parent | fix: use the new async encrypt symmetric api at gui app (diff) | |
download | GpgFrontend-5260d7a5634279408b3eb36a5f26fe71fb6f9e69.tar.gz GpgFrontend-5260d7a5634279408b3eb36a5f26fe71fb6f9e69.zip |
feat: upgrade basical operations fully to async style and update test cases
25 files changed, 654 insertions, 460 deletions
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp index aa944348..36bd25f6 100644 --- a/src/core/function/gpg/GpgBasicOperator.cpp +++ b/src/core/function/gpg/GpgBasicOperator.cpp @@ -33,17 +33,18 @@ #include "core/GpgModel.h" #include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" +#include "core/model/GpgSignResult.h" +#include "core/model/GpgVerifyResult.h" #include "core/utils/AsyncUtils.h" #include "core/utils/GpgUtils.h" namespace GpgFrontend { -GpgFrontend::GpgBasicOperator::GpgBasicOperator(int channel) +GpgBasicOperator::GpgBasicOperator(int channel) : SingletonFunctionObject<GpgBasicOperator>(channel) {} -void GpgFrontend::GpgBasicOperator::Encrypt(std::vector<GpgKey> keys, - GFBuffer in_buffer, bool ascii, - const GpgOperationCallback& cb) { +void GpgBasicOperator::Encrypt(KeyArgsList keys, GFBuffer in_buffer, bool ascii, + const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); @@ -66,8 +67,8 @@ void GpgFrontend::GpgBasicOperator::Encrypt(std::vector<GpgKey> keys, cb, "gpgme_op_encrypt", "2.1.0"); } -void GpgFrontend::GpgBasicOperator::Decrypt(GFBuffer in_buffer, - const GpgOperationCallback& cb) { +void GpgBasicOperator::Decrypt(GFBuffer in_buffer, + const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { GpgData data_in(in_buffer); @@ -84,126 +85,117 @@ void GpgFrontend::GpgBasicOperator::Decrypt(GFBuffer in_buffer, cb, "gpgme_op_decrypt", "2.1.0"); } -auto GpgFrontend::GpgBasicOperator::Verify(BypeArrayRef& in_buffer, - ByteArrayPtr& sig_buffer, - GpgVerifyResult& result) const - -> GpgFrontend::GpgError { - GpgError err; - - GpgData data_in(in_buffer.data(), in_buffer.size()); - GpgData data_out; - - if (sig_buffer != nullptr && !sig_buffer->empty()) { - GpgData sig_data(sig_buffer->data(), sig_buffer->size()); - err = CheckGpgError( - gpgme_op_verify(ctx_.DefaultContext(), sig_data, data_in, nullptr)); - } else { - err = CheckGpgError( - gpgme_op_verify(ctx_.DefaultContext(), data_in, nullptr, data_out)); - } - - auto temp_result = NewResult(gpgme_op_verify_result(ctx_.DefaultContext())); - std::swap(result, temp_result); +void GpgBasicOperator::Verify(GFBuffer in_buffer, GFBuffer sig_buffer, + const GpgOperationCallback& cb) { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; - return err; -} + GpgData data_in(in_buffer); + GpgData data_out; -auto GpgFrontend::GpgBasicOperator::Sign( - KeyListPtr signers, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - gpgme_sig_mode_t mode, GpgSignResult& result) -> GpgFrontend::GpgError { - GpgError err; + if (!sig_buffer.Empty()) { + GpgData sig_data(sig_buffer); + err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data, + data_in, nullptr)); + } else { + err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in, + nullptr, data_out)); + } - // Set Singers of this opera - SetSigners(*signers); + data_object->Swap({ + GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())), + }); - GpgData data_in(in_buffer.data(), in_buffer.size()); - GpgData data_out; + return err; + }, + cb, "gpgme_op_verify", "2.1.0"); +} - err = CheckGpgError( - gpgme_op_sign(ctx_.DefaultContext(), data_in, data_out, mode)); +void GpgBasicOperator::Sign(KeyArgsList signers, GFBuffer in_buffer, + GpgSignMode mode, bool ascii, + const GpgOperationCallback& cb) { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; - auto temp_data_out = data_out.Read2Buffer(); - std::swap(temp_data_out, out_buffer); + // Set Singers of this opera + SetSigners(signers, ascii); - auto temp_result = NewResult(gpgme_op_sign_result(ctx_.DefaultContext())); + GpgData data_in(in_buffer); + GpgData data_out; - std::swap(result, temp_result); + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode)); - return err; + data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)), + data_out.Read2GFBuffer()}); + return err; + }, + cb, "gpgme_op_sign", "2.1.0"); } -auto GpgFrontend::GpgBasicOperator::DecryptVerify( - BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) -> GpgError { - GpgError err; - - GpgData data_in(in_buffer.data(), in_buffer.size()); - GpgData data_out; - - err = CheckGpgError( - gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out)); +void GpgBasicOperator::DecryptVerify(GFBuffer in_buffer, + const GpgOperationCallback& cb) { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; - auto temp_data_out = data_out.Read2Buffer(); - std::swap(temp_data_out, out_buffer); + GpgData data_in(in_buffer); + GpgData data_out; - auto temp_decr_result = - NewResult(gpgme_op_decrypt_result(ctx_.DefaultContext())); - std::swap(decrypt_result, temp_decr_result); + err = CheckGpgError( + gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out)); - auto temp_verify_result = - NewResult(gpgme_op_verify_result(ctx_.DefaultContext())); - std::swap(verify_result, temp_verify_result); + data_object->Swap( + {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())), + GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())), + data_out.Read2GFBuffer()}); - return err; + return err; + }, + cb, "gpgme_op_decrypt_verify", "2.1.0"); } -auto GpgFrontend::GpgBasicOperator::EncryptSign( - KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer, - ByteArrayPtr& out_buffer, GpgEncrResult& encr_result, - GpgSignResult& sign_result) -> GpgError { - GpgError err; - SetSigners(*signers); - - // gpgme_encrypt_result_t e_result; - gpgme_key_t recipients[keys->size() + 1]; +void GpgBasicOperator::EncryptSign(KeyArgsList keys, KeyArgsList signers, + GFBuffer in_buffer, bool ascii, + const GpgOperationCallback& cb) { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); - // set key for user - int index = 0; - for (const auto& key : *keys) { - recipients[index++] = static_cast<gpgme_key_t>(key); - } + // Last entry data_in array has to be nullptr + recipients.emplace_back(nullptr); - // Last entry dataIn array has to be nullptr - recipients[keys->size()] = nullptr; + SetSigners(signers, ascii); - GpgData data_in(in_buffer.data(), in_buffer.size()); - GpgData data_out; + GpgData data_in(in_buffer); + GpgData data_out; - // If the last parameter isnt 0, a private copy of data is made - err = CheckGpgError(gpgme_op_encrypt_sign(ctx_.DefaultContext(), recipients, - GPGME_ENCRYPT_ALWAYS_TRUST, data_in, - data_out)); + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(), + GPGME_ENCRYPT_ALWAYS_TRUST, + data_in, data_out)); - auto temp_data_out = data_out.Read2Buffer(); - std::swap(temp_data_out, out_buffer); + data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + GpgSignResult(gpgme_op_sign_result(ctx)), + data_out.Read2GFBuffer()}); + return err; + }, + cb, "gpgme_op_encrypt_sign", "2.1.0"); +} - auto temp_encr_result = - NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext())); - swap(encr_result, temp_encr_result); - auto temp_sign_result = - NewResult(gpgme_op_sign_result(ctx_.DefaultContext())); - swap(sign_result, temp_sign_result); +void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) { + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); - return err; -} + gpgme_signers_clear(ctx); -void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) { - gpgme_signers_clear(ctx_.DefaultContext()); for (const GpgKey& key : signers) { SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint()); if (key.IsHasActualSigningCapability()) { SPDLOG_DEBUG("signer"); - auto error = gpgme_signers_add(ctx_.DefaultContext(), gpgme_key_t(key)); + auto error = gpgme_signers_add(ctx, gpgme_key_t(key)); CheckGpgError(error); } } @@ -211,19 +203,20 @@ void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) { SPDLOG_DEBUG("not all signers added"); } -auto GpgFrontend::GpgBasicOperator::GetSigners() - -> std::unique_ptr<GpgFrontend::KeyArgsList> { - auto count = gpgme_signers_count(ctx_.DefaultContext()); +auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> { + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + + auto count = gpgme_signers_count(ctx); auto signers = std::make_unique<std::vector<GpgKey>>(); for (auto i = 0U; i < count; i++) { - auto key = GpgKey(gpgme_signers_enum(ctx_.DefaultContext(), i)); + auto key = GpgKey(gpgme_signers_enum(ctx, i)); signers->push_back(GpgKey(std::move(key))); } return signers; } -void GpgFrontend::GpgBasicOperator::EncryptSymmetric( - GFBuffer in_buffer, bool ascii, const GpgOperationCallback& cb) { +void GpgBasicOperator::EncryptSymmetric(GFBuffer in_buffer, bool ascii, + const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { GpgData data_in(in_buffer); diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h index 6836e390..4b1a2688 100644 --- a/src/core/function/gpg/GpgBasicOperator.h +++ b/src/core/function/gpg/GpgBasicOperator.h @@ -53,19 +53,13 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator int channel = SingletonFunctionObject::GetDefaultChannel()); /** - * @brief Call the interface provided by gpgme for encryption operation + * @brief * * All incoming data pointers out_buffer will be replaced with new valid * values * - * @param keys list of public keys - * @param in_buffer data that needs to be encrypted - * @param out_buffer encrypted data - * @param result the result of the operation - * @return error code */ - void Encrypt(std::vector<GpgKey>, GFBuffer, bool, - const GpgOperationCallback&); + void Encrypt(KeyArgsList, GFBuffer, bool, const GpgOperationCallback&); /** * @brief Call the interface provided by GPGME to symmetrical encryption @@ -91,9 +85,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param sign_result Signature result * @return */ - auto EncryptSign(KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer, - ByteArrayPtr& out_buffer, GpgEncrResult& encr_result, - GpgSignResult& sign_result) -> GpgError; + void EncryptSign(KeyArgsList keys, KeyArgsList signers, GFBuffer in_buffer, + bool ascii, const GpgOperationCallback& cb); /** * @brief Call the interface provided by gpgme for decryption operation @@ -115,9 +108,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param verify_result the result of the verifying operation * @return error code */ - auto DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, - GpgDecrResult& decrypt_result, - GpgVerifyResult& verify_result) -> GpgError; + void DecryptVerify(GFBuffer in_buffer, const GpgOperationCallback& cb); /** * @brief Call the interface provided by gpgme for verification operation @@ -127,8 +118,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - auto Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer, - GpgVerifyResult& result) const -> GpgError; + void Verify(GFBuffer in_buffer, GFBuffer sig_buffer, + const GpgOperationCallback& cb); /** * @brief Call the interface provided by gpgme for signing operation @@ -150,9 +141,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - auto Sign(KeyListPtr signers, BypeArrayRef in_buffer, - ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode, - GpgSignResult& result) -> GpgError; + void Sign(KeyArgsList signers, GFBuffer in_buffer, GpgSignMode mode, + bool ascii, const GpgOperationCallback& cb); /** * @brief Set the private key for signatures, this operation is a global @@ -160,14 +150,14 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * * @param keys */ - void SetSigners(KeyArgsList& signers); + void SetSigners(const KeyArgsList& signers, bool ascii); /** * @brief Get a global signature private keys that has been set. * * @return Intelligent pointer pointing to the private key list */ - auto GetSigners() -> std::unique_ptr<KeyArgsList>; + auto GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList>; private: GpgContext& ctx_ = GpgContext::GetInstance( diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp index cbfbc8b1..1c577997 100644 --- a/src/core/function/gpg/GpgFileOpera.cpp +++ b/src/core/function/gpg/GpgFileOpera.cpp @@ -31,16 +31,20 @@ #include "core/function/gpg/GpgBasicOperator.h" #include "core/model/GFBuffer.h" +#include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" #include "core/model/GpgKey.h" +#include "core/model/GpgSignResult.h" +#include "core/model/GpgVerifyResult.h" #include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" -void GpgFrontend::GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, - const std::string& in_path, - const std::string& out_path, - bool ascii, - const GpgOperationCallback& cb) { +namespace GpgFrontend { + +void GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, + const std::string& in_path, + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -64,20 +68,18 @@ void GpgFrontend::GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, } auto result = ExtractParams<GpgEncryptResult>(data_object, 0); auto buffer = ExtractParams<GFBuffer>(data_object, 1); - if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { - cb(err, TransferParams(result)); - return; - } - - if (!WriteFileGFBuffer(out_path_std, buffer)) { - throw std::runtime_error("write buffer to file error"); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + if (!WriteFileGFBuffer(out_path_std, buffer)) { + throw std::runtime_error("write buffer to file error"); + } } + cb(err, TransferParams(result)); }); } -void GpgFrontend::GpgFileOpera::DecryptFile(const std::string& in_path, - const std::string& out_path, - const GpgOperationCallback& cb) { +void GpgFileOpera::DecryptFile(const std::string& in_path, + const std::string& out_path, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -96,10 +98,10 @@ void GpgFrontend::GpgFileOpera::DecryptFile(const std::string& in_path, GpgBasicOperator::GetInstance().Decrypt( std::get<1>(read_result), [=](GpgError err, const DataObjectPtr& data_object) { - if (!data_object->Check<GpgEncryptResult, GFBuffer>()) { + if (!data_object->Check<GpgDecryptResult, GFBuffer>()) { throw std::runtime_error("data object transfers wrong arguments"); } - auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto result = ExtractParams<GpgDecryptResult>(data_object, 0); auto buffer = ExtractParams<GFBuffer>(data_object, 1); if (CheckGpgError(err) == GPG_ERR_NO_ERROR && @@ -111,11 +113,9 @@ void GpgFrontend::GpgFileOpera::DecryptFile(const std::string& in_path, }); } -auto GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys, - const std::string& in_path, - const std::string& out_path, - GpgSignResult& result, int _channel) - -> gpgme_error_t { +void GpgFileOpera::SignFile(KeyArgsList keys, const std::string& in_path, + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -126,27 +126,31 @@ auto GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys, auto out_path_std = std::filesystem::path(out_path); #endif - std::string in_buffer; - if (!ReadFileStd(in_path_std, in_buffer)) { + auto read_result = ReadFileGFBuffer(in_path_std); + if (!std::get<0>(read_result)) { throw std::runtime_error("read file error"); } - ByteArrayPtr out_buffer; - auto err = GpgBasicOperator::GetInstance(_channel).Sign( - std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result); - - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) - if (!WriteFileStd(out_path_std, *out_buffer)) { - throw std::runtime_error("WriteBufferToFile error"); - }; + GpgBasicOperator::GetInstance().Sign( + std::move(keys), std::get<1>(read_result), GPGME_SIG_MODE_DETACH, ascii, + [=](GpgError err, const DataObjectPtr& data_object) { + if (!data_object->Check<GpgSignResult, GFBuffer>()) { + throw std::runtime_error("data object transfers wrong arguments"); + } + auto result = ExtractParams<GpgSignResult>(data_object, 0); + auto buffer = ExtractParams<GFBuffer>(data_object, 1); - return err; + if (CheckGpgError(err) == GPG_ERR_NO_ERROR && + !WriteFileGFBuffer(out_path_std, buffer)) { + throw std::runtime_error("write buffer to file error"); + } + cb(err, TransferParams(result)); + }); } -auto GpgFrontend::GpgFileOpera::VerifyFile(const std::string& data_path, - const std::string& sign_path, - GpgVerifyResult& result, - int _channel) -> gpgme_error_t { +void GpgFileOpera::VerifyFile(const std::string& data_path, + const std::string& sign_path, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto data_path_std = std::filesystem::path(QString::fromStdString(data_path).toStdU16String()); @@ -157,27 +161,35 @@ auto GpgFrontend::GpgFileOpera::VerifyFile(const std::string& data_path, auto sign_path_std = std::filesystem::path(sign_path); #endif - std::string in_buffer; - if (!ReadFileStd(data_path_std, in_buffer)) { + auto read_result = ReadFileGFBuffer(data_path_std); + if (!std::get<0>(read_result)) { throw std::runtime_error("read file error"); } - ByteArrayPtr sign_buffer = nullptr; + + GFBuffer sign_buffer; if (!sign_path.empty()) { - std::string sign_buffer_str; - if (!ReadFileStd(sign_path_std, sign_buffer_str)) { + auto read_result = ReadFileGFBuffer(sign_path_std); + if (!std::get<0>(read_result)) { throw std::runtime_error("read file error"); } - sign_buffer = std::make_unique<std::string>(sign_buffer_str); + sign_buffer = std::get<1>(read_result); } - auto err = GpgBasicOperator::GetInstance(_channel).Verify( - in_buffer, sign_buffer, result); - return err; + + GpgBasicOperator::GetInstance().Verify( + std::get<1>(read_result), sign_buffer, + [=](GpgError err, const DataObjectPtr& data_object) { + if (!data_object->Check<GpgVerifyResult>()) { + throw std::runtime_error("data object transfers wrong arguments"); + } + auto result = ExtractParams<GpgVerifyResult>(data_object, 0); + cb(err, TransferParams(result)); + }); } -auto GpgFrontend::GpgFileOpera::EncryptSignFile( - KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path, - const std::string& out_path, GpgEncrResult& encr_res, - GpgSignResult& sign_res, int _channel) -> gpg_error_t { +void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys, + const std::string& in_path, + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -188,29 +200,32 @@ auto GpgFrontend::GpgFileOpera::EncryptSignFile( auto out_path_std = std::filesystem::path(out_path); #endif - std::string in_buffer; - if (!ReadFileStd(in_path_std, in_buffer)) { + auto read_result = ReadFileGFBuffer(in_path_std); + if (!std::get<0>(read_result)) { throw std::runtime_error("read file error"); } - ByteArrayPtr out_buffer = nullptr; - - auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign( - std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res, - sign_res); - - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) - if (!WriteFileStd(out_path_std, *out_buffer)) { - throw std::runtime_error("WriteBufferToFile error"); - }; - return err; + GpgBasicOperator::GetInstance().EncryptSign( + std::move(keys), std::move(signer_keys), std::get<1>(read_result), ascii, + [=](GpgError err, const DataObjectPtr& data_object) { + if (!data_object->Check<GpgEncryptResult, GpgSignResult, GFBuffer>()) { + throw std::runtime_error("data object transfers wrong arguments"); + } + auto encrypt_result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_object, 1); + auto buffer = ExtractParams<GFBuffer>(data_object, 2); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + if (!WriteFileGFBuffer(out_path_std, buffer)) { + throw std::runtime_error("write buffer to file error"); + } + } + cb(err, TransferParams(encrypt_result, sign_result)); + }); } -auto GpgFrontend::GpgFileOpera::DecryptVerifyFile(const std::string& in_path, - const std::string& out_path, - GpgDecrResult& decr_res, - GpgVerifyResult& verify_res) - -> gpg_error_t { +void GpgFileOpera::DecryptVerifyFile(const std::string& in_path, + const std::string& out_path, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -221,25 +236,32 @@ auto GpgFrontend::GpgFileOpera::DecryptVerifyFile(const std::string& in_path, auto out_path_std = std::filesystem::path(out_path); #endif - std::string in_buffer; - if (!ReadFileStd(in_path_std, in_buffer)) { + auto read_result = ReadFileGFBuffer(in_path_std); + if (!std::get<0>(read_result)) { throw std::runtime_error("read file error"); } - ByteArrayPtr out_buffer = nullptr; - auto err = GpgBasicOperator::GetInstance().DecryptVerify( - in_buffer, out_buffer, decr_res, verify_res); - - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) - if (!WriteFileStd(out_path_std, *out_buffer)) { - throw std::runtime_error("write file error"); - }; - - return err; + GpgBasicOperator::GetInstance().DecryptVerify( + std::get<1>(read_result), + [=](GpgError err, const DataObjectPtr& data_object) { + if (!data_object + ->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>()) { + throw std::runtime_error("data object transfers wrong arguments"); + } + auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object, 0); + auto verify_result = ExtractParams<GpgVerifyResult>(data_object, 1); + auto buffer = ExtractParams<GFBuffer>(data_object, 2); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + if (!WriteFileGFBuffer(out_path_std, buffer)) { + throw std::runtime_error("write buffer to file error"); + } + } + cb(err, TransferParams(decrypt_result, verify_result)); + }); } -void GpgFrontend::GpgFileOpera::EncryptFileSymmetric( - const std::string& in_path, const std::string& out_path, bool ascii, - const GpgOperationCallback& cb) { +void GpgFileOpera::EncryptFileSymmetric(const std::string& in_path, + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -273,3 +295,5 @@ void GpgFrontend::GpgFileOpera::EncryptFileSymmetric( } }); } + +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h index ec34487c..0f0d65bf 100644 --- a/src/core/function/gpg/GpgFileOpera.h +++ b/src/core/function/gpg/GpgFileOpera.h @@ -50,7 +50,7 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param channel Channel in context * @return unsigned int error code */ - static void EncryptFile(std::vector<GpgKey> keys, const std::string& in_path, + static void EncryptFile(KeyArgsList keys, const std::string& in_path, const std::string& out_path, bool ascii, const GpgOperationCallback& cb); @@ -89,9 +89,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param channel * @return GpgError */ - static auto SignFile(KeyListPtr keys, const std::string& in_path, - const std::string& out_path, GpgSignResult& result, - int channel = kGpgFrontendDefaultChannel) -> GpgError; + static void SignFile(KeyArgsList keys, const std::string& in_path, + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb); /** * @brief Verify file with public key @@ -102,9 +102,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param channel Channel in context * @return GpgError */ - static auto VerifyFile(const std::string& data_path, - const std::string& sign_path, GpgVerifyResult& result, - int channel = kGpgFrontendDefaultChannel) -> GpgError; + static void VerifyFile(const std::string& data_path, + const std::string& sign_path, + const GpgOperationCallback& cb); /** * @brief Encrypt and sign file with public key and private key @@ -118,12 +118,10 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param channel * @return GpgError */ - static auto EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys, + static void EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys, const std::string& in_path, - const std::string& out_path, - GpgEncrResult& encr_res, GpgSignResult& sign_res, - int channel = kGpgFrontendDefaultChannel) - -> GpgError; + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb); /** * @brief @@ -134,10 +132,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param verify_res * @return GpgError */ - static auto DecryptVerifyFile(const std::string& in_path, + static void DecryptVerifyFile(const std::string& in_path, const std::string& out_path, - GpgDecrResult& decr_res, - GpgVerifyResult& verify_res) -> GpgError; + const GpgOperationCallback& cb); }; } // namespace GpgFrontend diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp index 9273c850..a97e9871 100644 --- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp +++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp @@ -32,10 +32,12 @@ #include "core/function/gpg/GpgKeyGetter.h" GpgFrontend::GpgDecryptResultAnalyse::GpgDecryptResultAnalyse( - GpgError m_error, GpgDecrResult m_result) - : error_(m_error), result_(std::move(m_result)) {} + GpgError m_error, GpgDecryptResult m_result) + : error_(m_error), result_(m_result) {} void GpgFrontend::GpgDecryptResultAnalyse::doAnalyse() { + auto *result = result_.GetRaw(); + stream_ << "[#] " << _("Decrypt Operation"); if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) { @@ -44,24 +46,24 @@ void GpgFrontend::GpgDecryptResultAnalyse::doAnalyse() { stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_) << std::endl; setStatus(-1); - if (result_ != nullptr && result_->unsupported_algorithm != nullptr) { + if (result != nullptr && result->unsupported_algorithm != nullptr) { stream_ << "------------>" << std::endl; - stream_ << _("Unsupported Algo") << ": " << result_->unsupported_algorithm + stream_ << _("Unsupported Algo") << ": " << result->unsupported_algorithm << std::endl; } } - if (result_ != nullptr && result_->recipients != nullptr) { + if (result != nullptr && result->recipients != nullptr) { stream_ << "------------>" << std::endl; - if (result_->file_name != nullptr) { - stream_ << _("File Name") << ": " << result_->file_name << std::endl; + if (result->file_name != nullptr) { + stream_ << _("File Name") << ": " << result->file_name << std::endl; stream_ << std::endl; } - if (result_->is_mime) { + if (result->is_mime) { stream_ << _("MIME") << ": " << _("true") << std::endl; } - auto *recipient = result_->recipients; + auto *recipient = result->recipients; if (recipient != nullptr) stream_ << _("Recipient(s)") << ": " << std::endl; while (recipient != nullptr) { print_recipient(stream_, recipient); diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h index 55b9afee..fe0aab7b 100644 --- a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h +++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h @@ -29,6 +29,7 @@ #pragma once #include "GpgResultAnalyse.h" +#include "core/model/GpgDecryptResult.h" namespace GpgFrontend { @@ -45,7 +46,7 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse * @param m_error * @param m_result */ - explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result); + explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecryptResult m_result); protected: /** @@ -63,8 +64,8 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResultAnalyse */ void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient); - GpgError error_; ///< - GpgDecrResult result_; ///< + GpgError error_; ///< + GpgDecryptResult result_; ///< }; } // namespace GpgFrontend diff --git a/src/core/function/result_analyse/GpgResultAnalyse.h b/src/core/function/result_analyse/GpgResultAnalyse.h index b034f40a..3f22db09 100644 --- a/src/core/function/result_analyse/GpgResultAnalyse.h +++ b/src/core/function/result_analyse/GpgResultAnalyse.h @@ -33,12 +33,6 @@ namespace GpgFrontend { -using GpgEncrResult = std::shared_ptr<struct _gpgme_op_encrypt_result>; ///< -using GpgDecrResult = std::shared_ptr<struct _gpgme_op_decrypt_result>; ///< -using GpgSignResult = std::shared_ptr<struct _gpgme_op_sign_result>; ///< -using GpgVerifyResult = std::shared_ptr<struct _gpgme_op_verify_result>; ///< -using GpgGenKeyResult = std::shared_ptr<struct _gpgme_op_genkey_result>; ///< - class GPGFRONTEND_CORE_EXPORT GpgResultAnalyse { public: /** diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp index bb24c40f..53704528 100644 --- a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp +++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp @@ -37,6 +37,8 @@ GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error, GpgSignResult result) : error_(error), result_(std::move(result)) {} void GpgSignResultAnalyse::doAnalyse() { + auto *result = this->result_.GetRaw(); + SPDLOG_DEBUG("start sign result analyse"); stream_ << "[#] " << _("Sign Operation") << " "; @@ -49,11 +51,11 @@ void GpgSignResultAnalyse::doAnalyse() { setStatus(-1); } - if (result_ != nullptr && - (result_->signatures != nullptr || result_->invalid_signers != nullptr)) { + if (result != nullptr && + (result->signatures != nullptr || result->invalid_signers != nullptr)) { SPDLOG_DEBUG("sign result analyse getting result"); stream_ << "------------>" << std::endl; - auto *new_sign = result_->signatures; + auto *new_sign = result->signatures; while (new_sign != nullptr) { stream_ << "[>]" << _("New Signature") << ": " << std::endl; @@ -96,7 +98,7 @@ void GpgSignResultAnalyse::doAnalyse() { SPDLOG_DEBUG("sign result analyse getting invalid signer"); - auto *invalid_signer = result_->invalid_signers; + auto *invalid_signer = result->invalid_signers; if (invalid_signer != nullptr) { stream_ << _("Invalid Signers") << ": " << std::endl; diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.h b/src/core/function/result_analyse/GpgSignResultAnalyse.h index a6c23362..97544e8e 100644 --- a/src/core/function/result_analyse/GpgSignResultAnalyse.h +++ b/src/core/function/result_analyse/GpgSignResultAnalyse.h @@ -29,6 +29,7 @@ #pragma once #include "GpgResultAnalyse.h" +#include "core/model/GpgSignResult.h" namespace GpgFrontend { diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp index e9c922ac..449306b7 100644 --- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp +++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp @@ -38,9 +38,11 @@ GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse( GpgError error, GpgVerifyResult result) - : error_(error), result_(std::move(result)) {} + : error_(error), result_(result) {} void GpgFrontend::GpgVerifyResultAnalyse::doAnalyse() { + auto *result = this->result_.GetRaw(); + SPDLOG_DEBUG("started"); stream_ << "[#] " << _("Verify Operation") << " "; @@ -53,9 +55,9 @@ void GpgFrontend::GpgVerifyResultAnalyse::doAnalyse() { setStatus(-1); } - if (result_ != nullptr && result_->signatures != nullptr) { + if (result != nullptr && result->signatures != nullptr) { stream_ << "------------>" << std::endl; - auto *sign = result_->signatures; + auto *sign = result->signatures; stream_ << "[>] " << _("Signed On") << "(" << _("UTC") << ")" << " " @@ -210,13 +212,13 @@ auto GpgFrontend::GpgVerifyResultAnalyse::print_signer( auto GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const -> gpgme_signature_t { - if (result_) { - return result_->signatures; + if (result_.IsGood()) { + return result_.GetRaw()->signatures; } return nullptr; } auto GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult() -> GpgFrontend::GpgVerifyResult { - return std::move(result_); + return result_; } diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h index 9b6051b2..266f9b24 100644 --- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h +++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h @@ -29,6 +29,7 @@ #pragma once #include "GpgResultAnalyse.h" +#include "core/model/GpgVerifyResult.h" namespace GpgFrontend { /** diff --git a/src/core/model/GFBuffer.cpp b/src/core/model/GFBuffer.cpp index 379873c1..7608e9f5 100644 --- a/src/core/model/GFBuffer.cpp +++ b/src/core/model/GFBuffer.cpp @@ -72,10 +72,12 @@ auto GFBuffer::Data() -> std::byte* { return buffer_->data(); } void GFBuffer::Resize(size_t size) { buffer_->resize(size); } -auto GFBuffer::Size() -> size_t { return buffer_->size(); } +auto GFBuffer::Size() const -> size_t { return buffer_->size(); } auto GFBuffer::ConvertToQByteArray() -> QByteArray { return QByteArray::fromRawData(reinterpret_cast<const char*>(Data()), static_cast<qsizetype>(Size())); } + +auto GFBuffer::Empty() const -> bool { return this->Size() == 0; } } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GFBuffer.h b/src/core/model/GFBuffer.h index cc233e86..57fbbc43 100644 --- a/src/core/model/GFBuffer.h +++ b/src/core/model/GFBuffer.h @@ -51,7 +51,9 @@ class GPGFRONTEND_CORE_EXPORT GFBuffer { void Resize(size_t size); - auto Size() -> size_t; + [[nodiscard]] auto Size() const -> size_t; + + [[nodiscard]] auto Empty() const -> bool; auto ConvertToQByteArray() -> QByteArray; diff --git a/src/core/model/GpgDecryptResult.cpp b/src/core/model/GpgDecryptResult.cpp index 670b8cb7..a0719c0c 100644 --- a/src/core/model/GpgDecryptResult.cpp +++ b/src/core/model/GpgDecryptResult.cpp @@ -44,6 +44,10 @@ GpgDecryptResult::~GpgDecryptResult() = default; auto GpgDecryptResult::IsGood() -> bool { return result_ref_ != nullptr; } +auto GpgDecryptResult::GetRaw() -> gpgme_decrypt_result_t { + return result_ref_.get(); +} + auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> { std::vector<GpgRecipient> result; for (auto* reci = result_ref_->recipients; reci != nullptr; diff --git a/src/core/model/GpgDecryptResult.h b/src/core/model/GpgDecryptResult.h index b7ceee9a..8289d97d 100644 --- a/src/core/model/GpgDecryptResult.h +++ b/src/core/model/GpgDecryptResult.h @@ -37,6 +37,8 @@ class GPGFRONTEND_CORE_EXPORT GpgDecryptResult { public: auto IsGood() -> bool; + auto GetRaw() -> gpgme_decrypt_result_t; + auto Recipients() -> std::vector<GpgRecipient>; explicit GpgDecryptResult(gpgme_decrypt_result_t); diff --git a/src/core/model/GpgEncryptResult.cpp b/src/core/model/GpgEncryptResult.cpp index 821b10d5..6f39ed68 100644 --- a/src/core/model/GpgEncryptResult.cpp +++ b/src/core/model/GpgEncryptResult.cpp @@ -43,6 +43,10 @@ GpgEncryptResult::~GpgEncryptResult() = default; auto GpgEncryptResult::IsGood() -> bool { return result_ref_ != nullptr; } +auto GpgEncryptResult::GetRaw() -> gpgme_encrypt_result_t { + return result_ref_.get(); +} + auto GpgEncryptResult::InvalidRecipients() -> std::vector<std::tuple<std::string, GpgError>> { std::vector<std::tuple<std::string, GpgError>> result; @@ -59,7 +63,4 @@ auto GpgEncryptResult::InvalidRecipients() return result; } -auto GpgEncryptResult::GetRaw() -> gpgme_encrypt_result_t { - return result_ref_.get(); -} } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgEncryptResult.h b/src/core/model/GpgEncryptResult.h index c5c01228..4ce282cb 100644 --- a/src/core/model/GpgEncryptResult.h +++ b/src/core/model/GpgEncryptResult.h @@ -36,10 +36,10 @@ class GPGFRONTEND_CORE_EXPORT GpgEncryptResult { public: auto IsGood() -> bool; - auto InvalidRecipients() -> std::vector<std::tuple<std::string, GpgError>>; - auto GetRaw() -> gpgme_encrypt_result_t; + auto InvalidRecipients() -> std::vector<std::tuple<std::string, GpgError>>; + explicit GpgEncryptResult(gpgme_encrypt_result_t); GpgEncryptResult(); diff --git a/src/core/model/GpgSignResult.cpp b/src/core/model/GpgSignResult.cpp new file mode 100644 index 00000000..aa35e57a --- /dev/null +++ b/src/core/model/GpgSignResult.cpp @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgSignResult.h" + +namespace GpgFrontend { +GpgSignResult::GpgSignResult(gpgme_sign_result_t r) + : result_ref_(std::shared_ptr<struct _gpgme_op_sign_result>( + (gpgme_result_ref(r), r), [](gpgme_sign_result_t p) { + if (p != nullptr) { + gpgme_result_unref(p); + } + })) {} + +GpgSignResult::GpgSignResult() = default; + +GpgSignResult::~GpgSignResult() = default; + +auto GpgSignResult::IsGood() -> bool { return result_ref_ != nullptr; } + +auto GpgSignResult::GetRaw() -> gpgme_sign_result_t { + return result_ref_.get(); +} + +auto GpgSignResult::InvalidSigners() + -> std::vector<std::tuple<std::string, GpgError>> { + std::vector<std::tuple<std::string, GpgError>> result; + for (auto* invalid_key = result_ref_->invalid_signers; invalid_key != nullptr; + invalid_key = invalid_key->next) { + try { + result.emplace_back(std::string{invalid_key->fpr}, invalid_key->reason); + } catch (...) { + SPDLOG_ERROR( + "caught exception when processing invalid_signers, " + "maybe nullptr of fpr"); + } + } + return result; +} +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgSignResult.h b/src/core/model/GpgSignResult.h new file mode 100644 index 00000000..14537971 --- /dev/null +++ b/src/core/model/GpgSignResult.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/GpgFrontendCoreExport.h" +#include "core/typedef/GpgTypedef.h" + +namespace GpgFrontend { + +class GPGFRONTEND_CORE_EXPORT GpgSignResult { + public: + auto IsGood() -> bool; + + auto GetRaw() -> gpgme_sign_result_t; + + auto InvalidSigners() -> std::vector<std::tuple<std::string, GpgError>>; + + explicit GpgSignResult(gpgme_sign_result_t); + + GpgSignResult(); + + virtual ~GpgSignResult(); + + private: + std::shared_ptr<struct _gpgme_op_sign_result> result_ref_ = nullptr; ///< +}; +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgVerifyResult.cpp b/src/core/model/GpgVerifyResult.cpp new file mode 100644 index 00000000..98b0e527 --- /dev/null +++ b/src/core/model/GpgVerifyResult.cpp @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgVerifyResult.h" + +#include "core/model/GpgSignature.h" + +namespace GpgFrontend { +GpgVerifyResult::GpgVerifyResult(gpgme_verify_result_t r) + : result_ref_(std::shared_ptr<struct _gpgme_op_verify_result>( + (gpgme_result_ref(r), r), [](gpgme_verify_result_t p) { + if (p != nullptr) { + gpgme_result_unref(p); + } + })) {} + +GpgVerifyResult::GpgVerifyResult() = default; + +GpgVerifyResult::~GpgVerifyResult() = default; + +auto GpgVerifyResult::IsGood() const -> bool { return result_ref_ != nullptr; } + +auto GpgVerifyResult::GetRaw() const -> gpgme_verify_result_t { + return result_ref_.get(); +} + +auto GpgVerifyResult::GetSignature() const -> std::vector<GpgSignature> { + std::vector<GpgSignature> sigatures; + + auto* signature = result_ref_->signatures; + while (signature != nullptr) { + sigatures.emplace_back(signature); + signature = signature->next; + } +} +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgVerifyResult.h b/src/core/model/GpgVerifyResult.h new file mode 100644 index 00000000..cae43c10 --- /dev/null +++ b/src/core/model/GpgVerifyResult.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/GpgFrontendCoreExport.h" +#include "core/typedef/GpgTypedef.h" + +namespace GpgFrontend { + +class GPGFRONTEND_CORE_EXPORT GpgVerifyResult { + public: + [[nodiscard]] auto IsGood() const -> bool; + + [[nodiscard]] auto GetRaw() const -> gpgme_verify_result_t; + + [[nodiscard]] auto GetSignature() const -> std::vector<GpgSignature>; + + explicit GpgVerifyResult(gpgme_verify_result_t); + + GpgVerifyResult(); + + virtual ~GpgVerifyResult(); + + private: + std::shared_ptr<struct _gpgme_op_verify_result> result_ref_ = nullptr; ///< +}; +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h index f4bd5401..ca901a34 100644 --- a/src/core/typedef/GpgTypedef.h +++ b/src/core/typedef/GpgTypedef.h @@ -58,6 +58,8 @@ using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///< using KeyPtr = std::unique_ptr<GpgKey>; ///< using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///< +using GpgSignMode = gpgme_sig_mode_t; + using GpgOperaRunnable = std::function<GpgError(DataObjectPtr)>; using GpgOperationCallback = std::function<void(GpgError, DataObjectPtr)>; using GpgOperationFuture = std::future<std::tuple<GpgError, DataObjectPtr>>; diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp index b9fa59bd..886dc0fc 100644 --- a/src/core/utils/GpgUtils.cpp +++ b/src/core/utils/GpgUtils.cpp @@ -121,34 +121,4 @@ auto TextIsSigned(BypeArrayRef text) -> int { } return 0; } - -auto NewResult(gpgme_encrypt_result_t&& result) -> GpgEncrResult { - gpgme_result_ref(result); - return {result, ResultRefDeletor()}; -} - -auto NewResult(gpgme_decrypt_result_t&& result) -> GpgDecrResult { - gpgme_result_ref(result); - return {result, ResultRefDeletor()}; -} - -auto NewResult(gpgme_sign_result_t&& result) -> GpgSignResult { - gpgme_result_ref(result); - return {result, ResultRefDeletor()}; -} - -auto NewResult(gpgme_verify_result_t&& result) -> GpgVerifyResult { - gpgme_result_ref(result); - return {result, ResultRefDeletor()}; -} - -auto NewResult(gpgme_genkey_result_t&& result) -> GpgGenKeyResult { - gpgme_result_ref(result); - return {result, ResultRefDeletor()}; -} - -void ResultRefDeletor::operator()(void* _result) { - SPDLOG_TRACE("gpgme unref {}", _result); - if (_result != nullptr) gpgme_result_unref(_result); -} } // namespace GpgFrontend diff --git a/src/core/utils/GpgUtils.h b/src/core/utils/GpgUtils.h index 4fe05787..71fa712a 100644 --- a/src/core/utils/GpgUtils.h +++ b/src/core/utils/GpgUtils.h @@ -34,61 +34,6 @@ namespace GpgFrontend { -/** - * @brief Result Deleter - * - */ -struct ResultRefDeletor { - void operator()(void* _result); -}; - -// Convert from gpgme_xxx_result to GpgXXXResult - -/** - * @brief - * - * @param result - * @return GpgEncrResult - */ -auto GPGFRONTEND_CORE_EXPORT NewResult(gpgme_encrypt_result_t&& result) - -> GpgEncrResult; - -/** - * @brief - * - * @param result - * @return GpgDecrResult - */ -auto GPGFRONTEND_CORE_EXPORT NewResult(gpgme_decrypt_result_t&& result) - -> GpgDecrResult; - -/** - * @brief - * - * @param result - * @return GpgSignResult - */ -auto GPGFRONTEND_CORE_EXPORT NewResult(gpgme_sign_result_t&& result) - -> GpgSignResult; - -/** - * @brief - * - * @param result - * @return GpgVerifyResult - */ -auto GPGFRONTEND_CORE_EXPORT NewResult(gpgme_verify_result_t&& result) - -> GpgVerifyResult; - -/** - * @brief - * - * @param result - * @return GpgGenKeyResult - */ -auto GPGFRONTEND_CORE_EXPORT NewResult(gpgme_genkey_result_t&& result) - -> GpgGenKeyResult; - // Error Info Printer /** diff --git a/src/test/core/GpgCoreTestBasicOpera.cpp b/src/test/core/GpgCoreTestBasicOpera.cpp index 8eef1565..de6d6805 100644 --- a/src/test/core/GpgCoreTestBasicOpera.cpp +++ b/src/test/core/GpgCoreTestBasicOpera.cpp @@ -34,6 +34,8 @@ #include "core/function/result_analyse/GpgDecryptResultAnalyse.h" #include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" +#include "core/model/GpgSignResult.h" +#include "core/model/GpgVerifyResult.h" #include "core/utils/GpgUtils.h" namespace GpgFrontend::Test { @@ -41,11 +43,9 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, CoreEncryptDecrTest) { auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - auto encrypt_text = GFBuffer("Hello GpgFrontend!"); - auto const keys = std::vector<GpgKey>{encrypt_key}; GpgBasicOperator::GetInstance().Encrypt( - keys, encrypt_text, true, + {encrypt_key}, GFBuffer("Hello GpgFrontend!"), true, [](GpgError err, const DataObjectPtr& data_obj) { ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GFBuffer>())); auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); @@ -53,9 +53,8 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest) { ASSERT_TRUE(result.InvalidRecipients().empty()); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Decrypt(encr_out_buffer, [](GpgError err, - const DataObjectPtr& data_obj) { + GpgBasicOperator::GetInstance().Decrypt( + encr_out_buffer, [](GpgError err, const DataObjectPtr& data_obj) { auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); @@ -67,6 +66,28 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest) { }); } +TEST_F(GpgCoreTest, CoreEncryptSymmetricDecrTest) { + auto encrypt_text = GFBuffer("Hello GpgFrontend!"); + + GpgBasicOperator::GetInstance().EncryptSymmetric( + encrypt_text, true, [](GpgError err, const DataObjectPtr& data_obj) { + ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GFBuffer>())); + auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); + auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); + ASSERT_TRUE(result.InvalidRecipients().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + GpgBasicOperator::GetInstance().Decrypt( + encr_out_buffer, [](GpgError err, const DataObjectPtr& data_obj) { + auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE(d_result.Recipients().empty()); + ASSERT_EQ(decr_out_buffer, GFBuffer("Hello GpgFrontend!")); + }); + }); +} + TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_1) { auto encr_out_data = GFBuffer( "-----BEGIN PGP MESSAGE-----\n" @@ -81,8 +102,8 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_1) { "=8n2H\n" "-----END PGP MESSAGE-----"); - GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Decrypt(encr_out_data, [=](GpgError err, const DataObjectPtr& data_obj) { + GpgBasicOperator::GetInstance().Decrypt( + encr_out_data, [=](GpgError err, const DataObjectPtr& data_obj) { auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); @@ -105,137 +126,143 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) { "=8n2H\n" "-----END PGP MESSAGE-----"); - GpgDecrResult d_result; - ByteArrayPtr decr_out_data; - GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Decrypt(encr_out_data, [=](GpgError err, const DataObjectPtr& data_obj) { + GpgBasicOperator::GetInstance().Decrypt( + encr_out_data, [=](GpgError err, const DataObjectPtr& data_obj) { auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); ASSERT_FALSE(d_result.Recipients().empty()); ASSERT_EQ(d_result.Recipients()[0].keyid, "A50CFD2F6C677D8C"); - // GpgDecryptResultAnalyse analyse{err, d_result}; - // analyse.Analyse(); - // ASSERT_EQ(analyse.GetStatus(), -1); - // ASSERT_FALSE(analyse.GetResultReport().empty()); + GpgDecryptResultAnalyse analyse{err, d_result}; + analyse.Analyse(); + ASSERT_EQ(analyse.GetStatus(), -1); + ASSERT_FALSE(analyse.GetResultReport().empty()); }); } TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) { - auto encrypt_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetPubkey("467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ByteArray sign_text = "Hello GpgFrontend!"; - ByteArrayPtr sign_out_data; - GpgSignResult s_result; - KeyListPtr keys = std::make_unique<KeyArgsList>(); - keys->push_back(std::move(encrypt_key)); - auto err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Sign(std::move(keys), sign_text, sign_out_data, - GPGME_SIG_MODE_NORMAL, s_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_EQ(s_result->invalid_signers, nullptr); - - GpgVerifyResult v_result; - ByteArrayPtr sign_buff = nullptr; - err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Verify(*sign_out_data, sign_buff, v_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_NE(v_result->signatures, nullptr); - ASSERT_EQ(std::string(v_result->signatures->fpr), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_EQ(v_result->signatures->next, nullptr); + auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + auto sign_text = GFBuffer("Hello GpgFrontend!"); + + GpgBasicOperator::GetInstance().Sign( + {sign_key}, sign_text, GPGME_SIG_MODE_NORMAL, true, + [](GpgError err, const DataObjectPtr& data_obj) { + ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>())); + auto result = ExtractParams<GpgSignResult>(data_obj, 0); + auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); + ASSERT_TRUE(result.InvalidSigners().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + GpgBasicOperator::GetInstance().Verify( + sign_out_buffer, GFBuffer(), + [](GpgError err, const DataObjectPtr& data_obj) { + auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_FALSE(d_result.GetSignature().empty()); + ASSERT_EQ(d_result.GetSignature().at(0), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + }); + }); } TEST_F(GpgCoreTest, CoreSignVerifyDetachTest) { - auto encrypt_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetPubkey("467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ByteArray sign_text = "Hello GpgFrontend!"; - ByteArrayPtr sign_out_data; - GpgSignResult s_result; - KeyListPtr keys = std::make_unique<KeyArgsList>(); - keys->push_back(std::move(encrypt_key)); - auto err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Sign(std::move(keys), sign_text, sign_out_data, - GPGME_SIG_MODE_DETACH, s_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_EQ(s_result->invalid_signers, nullptr); - - GpgVerifyResult v_result; - err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Verify(sign_text, sign_out_data, v_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_NE(v_result->signatures, nullptr); - ASSERT_EQ(std::string(v_result->signatures->fpr), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_EQ(v_result->signatures->next, nullptr); + auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + auto sign_text = GFBuffer("Hello GpgFrontend!"); + + GpgBasicOperator::GetInstance().Sign( + {sign_key}, sign_text, GPGME_SIG_MODE_DETACH, true, + [=](GpgError err, const DataObjectPtr& data_obj) { + ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>())); + auto result = ExtractParams<GpgSignResult>(data_obj, 0); + auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); + ASSERT_TRUE(result.InvalidSigners().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + GpgBasicOperator::GetInstance().Verify( + sign_text, sign_out_buffer, + [](GpgError err, const DataObjectPtr& data_obj) { + auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_FALSE(d_result.GetSignature().empty()); + ASSERT_EQ(d_result.GetSignature().at(0), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + }); + }); } TEST_F(GpgCoreTest, CoreSignVerifyClearTest) { - auto sign_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ByteArray sign_text = "Hello GpgFrontend!"; - ByteArrayPtr sign_out_data; - GpgSignResult s_result; - KeyListPtr keys = std::make_unique<KeyArgsList>(); - keys->push_back(std::move(sign_key)); - auto err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Sign(std::move(keys), sign_text, sign_out_data, - GPGME_SIG_MODE_CLEAR, s_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_EQ(s_result->invalid_signers, nullptr); - - GpgVerifyResult v_result; - ByteArrayPtr sign_buff = nullptr; - err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Verify(*sign_out_data, sign_buff, v_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_NE(v_result->signatures, nullptr); - ASSERT_EQ(std::string(v_result->signatures->fpr), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_EQ(v_result->signatures->next, nullptr); + auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + auto sign_text = GFBuffer("Hello GpgFrontend!"); + + GpgBasicOperator::GetInstance().Sign( + {sign_key}, sign_text, GPGME_SIG_MODE_CLEAR, true, + [](GpgError err, const DataObjectPtr& data_obj) { + ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>())); + auto result = ExtractParams<GpgSignResult>(data_obj, 0); + auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); + ASSERT_TRUE(result.InvalidSigners().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + GpgBasicOperator::GetInstance().Verify( + sign_out_buffer, GFBuffer(), + [](GpgError err, const DataObjectPtr& data_obj) { + auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 0); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_FALSE(verify_reult.GetSignature().empty()); + ASSERT_EQ(verify_reult.GetSignature().at(0), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + }); + }); } TEST_F(GpgCoreTest, CoreEncryptSignDecrVerifyTest) { - auto encrypt_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetPubkey("467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - auto sign_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("8933EB283A18995F45D61DAC021D89771B680FFB"); - // Question? - // ASSERT_FALSE(encrypt_key.is_private_key()); + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + auto sign_key = GpgKeyGetter::GetInstance().GetKey( + "8933EB283A18995F45D61DAC021D89771B680FFB"); + auto encrypt_text = GFBuffer("Hello GpgFrontend!"); + ASSERT_TRUE(sign_key.IsPrivateKey()); ASSERT_TRUE(sign_key.IsHasActualSigningCapability()); - ByteArray encrypt_text = "Hello GpgFrontend!"; - ByteArrayPtr encr_out_data; - GpgEncrResult e_result; - GpgSignResult s_result; - - KeyListPtr keys = std::make_unique<KeyArgsList>(); - KeyListPtr sign_keys = std::make_unique<KeyArgsList>(); - - keys->push_back(std::move(encrypt_key)); - sign_keys->push_back(std::move(sign_key)); - - auto err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .EncryptSign(std::move(keys), std::move(sign_keys), - encrypt_text, encr_out_data, e_result, s_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_EQ(e_result->invalid_recipients, nullptr); - ASSERT_EQ(s_result->invalid_signers, nullptr); - - GpgDecrResult d_result; - GpgVerifyResult v_result; - ByteArrayPtr decr_out_data = nullptr; - err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .DecryptVerify(*encr_out_data, decr_out_data, d_result, v_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_NE(d_result->recipients, nullptr); - ASSERT_EQ(std::string(d_result->recipients->keyid), "F89C95A05088CC93"); - ASSERT_EQ(*decr_out_data, encrypt_text); - ASSERT_NE(v_result->signatures, nullptr); - ASSERT_EQ(std::string(v_result->signatures->fpr), - "8933EB283A18995F45D61DAC021D89771B680FFB"); - ASSERT_EQ(v_result->signatures->next, nullptr); + + GpgBasicOperator::GetInstance().EncryptSign( + {encrypt_key}, {sign_key}, encrypt_text, true, + [](GpgError err, const DataObjectPtr& data_obj) { + ASSERT_TRUE( + (data_obj->Check<GpgEncryptResult, GpgSignResult, GFBuffer>())); + auto encr_result = ExtractParams<GpgEncryptResult>(data_obj, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); + auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 2); + ASSERT_TRUE(encr_result.InvalidRecipients().empty()); + ASSERT_TRUE(sign_result.InvalidSigners().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + GpgBasicOperator::GetInstance().DecryptVerify( + encr_out_buffer, [](GpgError err, const DataObjectPtr& data_obj) { + ASSERT_TRUE( + (data_obj + ->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>())); + auto decrypt_result = + ExtractParams<GpgDecryptResult>(data_obj, 0); + auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 1); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 2); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + ASSERT_FALSE(decrypt_result.Recipients().empty()); + ASSERT_EQ(decr_out_buffer, GFBuffer("Hello GpgFrontend!")); + + ASSERT_EQ(decrypt_result.Recipients()[0].keyid, + "F89C95A05088CC93"); + ASSERT_FALSE(verify_reult.GetSignature().empty()); + ASSERT_EQ(verify_reult.GetSignature().at(0), + "8933EB283A18995F45D61DAC021D89771B680FFB"); + }); + }); } } // namespace GpgFrontend::Test |