diff options
author | saturneric <[email protected]> | 2023-12-23 17:36:40 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2023-12-23 17:36:40 +0000 |
commit | 956c5ed3a8931bcbfa07fbe2b1af8090188b822b (patch) | |
tree | 18ff59a410e2c87d53a05e5483549fb977ec3ddd | |
parent | fix: solve all issues of test cases on macos m1 (diff) | |
download | GpgFrontend-956c5ed3a8931bcbfa07fbe2b1af8090188b822b.tar.gz GpgFrontend-956c5ed3a8931bcbfa07fbe2b1af8090188b822b.zip |
feat: improve core interfaces of encrypt and decrypt
-rw-r--r-- | src/core/function/gpg/GpgBasicOperator.cpp | 47 | ||||
-rw-r--r-- | src/core/function/gpg/GpgBasicOperator.h | 6 | ||||
-rw-r--r-- | src/core/function/gpg/GpgFileOpera.cpp | 106 | ||||
-rw-r--r-- | src/core/function/gpg/GpgFileOpera.h | 13 | ||||
-rw-r--r-- | src/core/model/GFBuffer.cpp | 12 | ||||
-rw-r--r-- | src/core/model/GFBuffer.h | 4 | ||||
-rw-r--r-- | src/core/model/GpgData.cpp | 18 | ||||
-rw-r--r-- | src/core/model/GpgData.h | 8 | ||||
-rw-r--r-- | src/core/model/GpgDecryptResult.cpp | 61 | ||||
-rw-r--r-- | src/core/model/GpgDecryptResult.h | 52 | ||||
-rw-r--r-- | src/core/model/GpgKey.cpp | 11 | ||||
-rw-r--r-- | src/core/model/GpgKey.h | 2 | ||||
-rw-r--r-- | src/core/model/GpgRecipient.cpp | 40 | ||||
-rw-r--r-- | src/core/model/GpgRecipient.h | 51 | ||||
-rw-r--r-- | src/core/utils/IOUtils.cpp | 22 | ||||
-rw-r--r-- | src/core/utils/IOUtils.h | 22 | ||||
-rw-r--r-- | src/test/core/GpgCoreTestBasicOpera.cpp | 67 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowFileSlotFunction.cpp | 14 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotFunction.cpp | 11 |
19 files changed, 432 insertions, 135 deletions
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp index 4a615813..0c027285 100644 --- a/src/core/function/gpg/GpgBasicOperator.cpp +++ b/src/core/function/gpg/GpgBasicOperator.cpp @@ -31,6 +31,7 @@ #include <gpg-error.h> #include "core/GpgModel.h" +#include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" #include "core/utils/AsyncUtils.h" #include "core/utils/GpgUtils.h" @@ -40,25 +41,22 @@ namespace GpgFrontend { GpgFrontend::GpgBasicOperator::GpgBasicOperator(int channel) : SingletonFunctionObject<GpgBasicOperator>(channel) {} -void GpgFrontend::GpgBasicOperator::Encrypt(KeyListPtr keys, - ConstBypeArrayRef in_buffer, +void GpgFrontend::GpgBasicOperator::Encrypt(std::vector<GpgKey> keys, + GFBuffer in_buffer, bool ascii, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { - std::vector<gpgme_key_t> recipients; - for (const auto& key : *keys) { - recipients.emplace_back(key); - } + std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); // Last entry data_in array has to be nullptr recipients.emplace_back(nullptr); - GpgData data_in(in_buffer.data(), in_buffer.size()); + GpgData data_in(in_buffer); GpgData data_out; - auto err = CheckGpgError( - gpgme_op_encrypt(ctx_.DefaultContext(), recipients.data(), - GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); + auto err = CheckGpgError(gpgme_op_encrypt( + ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(), + recipients.data(), GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out)); data_object->Swap( {GpgEncryptResult(gpgme_op_encrypt_result(ctx_.DefaultContext())), data_out.Read2GFBuffer()}); @@ -68,23 +66,22 @@ void GpgFrontend::GpgBasicOperator::Encrypt(KeyListPtr keys, cb, "gpgme_op_encrypt", "2.1.0"); } -auto GpgFrontend::GpgBasicOperator::Decrypt( - GFBuffer in_buffer, GpgFrontend::ByteArrayPtr& out_buffer, - GpgFrontend::GpgDecrResult& result) -> GpgFrontend::GpgError { - GpgError err; - - GpgData data_in(in_buffer.Data(), in_buffer.Size()); - GpgData data_out; - err = - CheckGpgError(gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out)); - - auto temp_data_out = data_out.Read2Buffer(); - std::swap(temp_data_out, out_buffer); +void GpgFrontend::GpgBasicOperator::Decrypt(GFBuffer in_buffer, + const GpgOperationCallback& cb) { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(in_buffer); + GpgData data_out; - auto temp_result = NewResult(gpgme_op_decrypt_result(ctx_.DefaultContext())); - std::swap(result, temp_result); + auto err = CheckGpgError( + gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out)); + data_object->Swap( + {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())), + data_out.Read2GFBuffer()}); - return err; + return err; + }, + cb, "gpgme_op_decrypt", "2.1.0"); } auto GpgFrontend::GpgBasicOperator::Verify(BypeArrayRef& in_buffer, diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h index 9eb10f80..378091b1 100644 --- a/src/core/function/gpg/GpgBasicOperator.h +++ b/src/core/function/gpg/GpgBasicOperator.h @@ -64,7 +64,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - void Encrypt(KeyListPtr, ConstBypeArrayRef, const GpgOperationCallback&); + void Encrypt(std::vector<GpgKey>, GFBuffer, bool, + const GpgOperationCallback&); /** * @brief Call the interface provided by GPGME to symmetrical encryption @@ -102,8 +103,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - auto Decrypt(GFBuffer in_buffer, ByteArrayPtr& out_buffer, - GpgDecrResult& result) -> GpgError; + void Decrypt(GFBuffer in_buffer, const GpgOperationCallback& cb); /** * @brief Call the interface provided by gpgme to perform decryption and diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp index 32f8c3ab..f1e9a3c1 100644 --- a/src/core/function/gpg/GpgFileOpera.cpp +++ b/src/core/function/gpg/GpgFileOpera.cpp @@ -27,47 +27,20 @@ */ #include "GpgFileOpera.h" +#include <utility> + #include "core/function/gpg/GpgBasicOperator.h" +#include "core/model/GFBuffer.h" +#include "core/model/GpgEncryptResult.h" +#include "core/model/GpgKey.h" #include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" -auto GpgFrontend::GpgFileOpera::EncryptFile(KeyListPtr keys, +void GpgFrontend::GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, const std::string& in_path, const std::string& out_path, - GpgEncrResult& result, int _channel) - -> GpgFrontend::GpgError { - // #ifdef WINDOWS - // auto in_path_std = - // std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); - // auto out_path_std = - // std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); - // #else - // auto in_path_std = std::filesystem::path(in_path); - // auto out_path_std = std::filesystem::path(out_path); - // #endif - - // std::string in_buffer; - // if (!ReadFileStd(in_path_std, in_buffer)) { - // throw std::runtime_error("read file error"); - // } - - // ByteArrayPtr out_buffer = nullptr; - - // auto err = GpgBasicOperator::GetInstance(_channel).Encrypt( - // std::move(keys), in_buffer, out_buffer, result); - - // if (CheckGpgError(err) == GPG_ERR_NO_ERROR) - // if (!WriteFileStd(out_path_std, *out_buffer)) { - // throw std::runtime_error("WriteBufferToFile error"); - // }; - - // return err; -} - -auto GpgFrontend::GpgFileOpera::DecryptFile(const std::string& in_path, - const std::string& out_path, - GpgDecrResult& result) - -> GpgFrontend::GpgError { + bool ascii, + const GpgOperationCallback& cb) { #ifdef WINDOWS auto in_path_std = std::filesystem::path(QString::fromStdString(in_path).toStdU16String()); @@ -78,23 +51,64 @@ auto GpgFrontend::GpgFileOpera::DecryptFile(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; - auto err = GpgBasicOperator::GetInstance().Decrypt(GFBuffer(in_buffer), - out_buffer, result); + GpgBasicOperator::GetInstance().Encrypt( + std::move(keys), std::get<1>(read_result), ascii, + [=](GpgError err, const DataObjectPtr& data_object) { + if (!data_object->Check<GpgEncryptResult, GFBuffer>()) { + throw std::runtime_error("data object transfers wrong arguments"); + } + 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"); + } + }); +} - assert(CheckGpgError(err) == GPG_ERR_NO_ERROR); +void GpgFrontend::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()); + auto out_path_std = + std::filesystem::path(QString::fromStdString(out_path).toStdU16String()); +#else + auto in_path_std = std::filesystem::path(in_path); + auto out_path_std = std::filesystem::path(out_path); +#endif - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) - if (!WriteFileStd(out_path_std, *out_buffer)) { - throw std::runtime_error("WriteBufferToFile error"); - }; + auto read_result = ReadFileGFBuffer(in_path_std); + if (!std::get<0>(read_result)) { + throw std::runtime_error("read file error"); + } - return err; + GpgBasicOperator::GetInstance().Decrypt( + std::get<1>(read_result), + [=](GpgError err, const DataObjectPtr& data_object) { + if (!data_object->Check<GpgEncryptResult, GFBuffer>()) { + throw std::runtime_error("data object transfers wrong arguments"); + } + auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto buffer = ExtractParams<GFBuffer>(data_object, 1); + + 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::SignFile(KeyListPtr keys, diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h index 569ea51a..0f278b1f 100644 --- a/src/core/function/gpg/GpgFileOpera.h +++ b/src/core/function/gpg/GpgFileOpera.h @@ -50,10 +50,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param channel Channel in context * @return unsigned int error code */ - static auto EncryptFile(KeyListPtr keys, const std::string& in_path, - const std::string& out_path, GpgEncrResult& result, - int channel = kGpgFrontendDefaultChannel) - -> unsigned int; + static void EncryptFile(std::vector<GpgKey> keys, const std::string& in_path, + const std::string& out_path, bool ascii, + const GpgOperationCallback& cb); /** * @brief Encrypted file symmetrically (with password) @@ -78,9 +77,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera { * @param result * @return GpgError */ - static auto DecryptFile(const std::string& in_path, - const std::string& out_path, GpgDecrResult& result) - -> GpgError; + static void DecryptFile(const std::string& in_path, + const std::string& out_path, + const GpgOperationCallback& cb); /** * @brief Sign file with private key diff --git a/src/core/model/GFBuffer.cpp b/src/core/model/GFBuffer.cpp index 6c1acb90..99154bdd 100644 --- a/src/core/model/GFBuffer.cpp +++ b/src/core/model/GFBuffer.cpp @@ -38,6 +38,7 @@ GFBuffer::GFBuffer(const std::string& str) std::transform(str.begin(), str.end(), buffer_->begin(), [](const char c) { return static_cast<std::byte>(c); }); } + GFBuffer::GFBuffer(const char* c_str) : buffer_(SecureCreateSharedObject<std::vector<std::byte>>()) { if (c_str == nullptr) { @@ -49,6 +50,17 @@ GFBuffer::GFBuffer(const char* c_str) buffer_->assign(reinterpret_cast<const std::byte*>(c_str), reinterpret_cast<const std::byte*>(c_str) + length); } + +GFBuffer::GFBuffer(QByteArray buffer) + : buffer_(SecureCreateSharedObject<std::vector<std::byte>>()) { + std::transform(buffer.begin(), buffer.end(), buffer_->begin(), + [](const char c) { return static_cast<std::byte>(c); }); +} + +auto GFBuffer::operator==(const GFBuffer& o) const -> bool { + return equal(buffer_->begin(), buffer_->end(), o.buffer_->begin()); +} + auto GFBuffer::Data() -> std::byte* { return buffer_->data(); } void GFBuffer::Resize(size_t size) { buffer_->resize(size); } diff --git a/src/core/model/GFBuffer.h b/src/core/model/GFBuffer.h index b99415e3..297c5fc7 100644 --- a/src/core/model/GFBuffer.h +++ b/src/core/model/GFBuffer.h @@ -41,6 +41,10 @@ class GPGFRONTEND_CORE_EXPORT GFBuffer { explicit GFBuffer(const char* c_str); + explicit GFBuffer(QByteArray buffer); + + auto operator==(const GFBuffer& o) const -> bool; + auto Data() -> std::byte*; void Resize(size_t size); diff --git a/src/core/model/GpgData.cpp b/src/core/model/GpgData.cpp index 286ca0ce..19f45e22 100644 --- a/src/core/model/GpgData.cpp +++ b/src/core/model/GpgData.cpp @@ -34,7 +34,7 @@ namespace GpgFrontend { constexpr size_t kBufferSize = 32 * 1024; -GpgFrontend::GpgData::GpgData() { +GpgData::GpgData() { gpgme_data_t data; auto err = gpgme_data_new(&data); @@ -43,7 +43,17 @@ GpgFrontend::GpgData::GpgData() { data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data); } -GpgFrontend::GpgData::GpgData(const void* buffer, size_t size, bool copy) { +GpgData::GpgData(GFBuffer buffer) : cached_buffer_(buffer) { + gpgme_data_t data; + + auto err = gpgme_data_new_from_mem( + &data, reinterpret_cast<const char*>(buffer.Data()), buffer.Size(), 0); + assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); + + data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data); +} + +GpgData::GpgData(const void* buffer, size_t size, bool copy) { gpgme_data_t data; auto err = gpgme_data_new_from_mem(&data, static_cast<const char*>(buffer), @@ -53,7 +63,7 @@ GpgFrontend::GpgData::GpgData(const void* buffer, size_t size, bool copy) { data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data); } -auto GpgFrontend::GpgData::Read2Buffer() -> GpgFrontend::ByteArrayPtr { +auto GpgData::Read2Buffer() -> ByteArrayPtr { gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET); ByteArrayPtr out_buffer = std::make_unique<std::string>(); @@ -99,6 +109,6 @@ auto GpgData::Read2GFBuffer() -> GFBuffer { return out_buffer; } -GpgFrontend::GpgData::operator gpgme_data_t() { return data_ref_.get(); } +GpgData::operator gpgme_data_t() { return data_ref_.get(); } } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgData.h b/src/core/model/GpgData.h index a7c51c06..cd2e193e 100644 --- a/src/core/model/GpgData.h +++ b/src/core/model/GpgData.h @@ -55,6 +55,12 @@ class GPGFRONTEND_CORE_EXPORT GpgData { GpgData(const void* buffer, size_t size, bool copy = true); /** + * @brief Construct a new Gpg Data object + * + */ + explicit GpgData(GFBuffer); + + /** * @brief * * @return gpgme_data_t @@ -86,6 +92,8 @@ class GPGFRONTEND_CORE_EXPORT GpgData { } }; + GFBuffer cached_buffer_; + std::unique_ptr<struct gpgme_data, DataRefDeleter> data_ref_ = nullptr; ///< }; diff --git a/src/core/model/GpgDecryptResult.cpp b/src/core/model/GpgDecryptResult.cpp new file mode 100644 index 00000000..670b8cb7 --- /dev/null +++ b/src/core/model/GpgDecryptResult.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 "GpgDecryptResult.h" + +namespace GpgFrontend { + +GpgDecryptResult::GpgDecryptResult(gpgme_decrypt_result_t r) + : result_ref_(std::shared_ptr<struct _gpgme_op_decrypt_result>( + (gpgme_result_ref(r), r), [](gpgme_decrypt_result_t p) { + if (p != nullptr) { + gpgme_result_unref(p); + } + })) {} + +GpgDecryptResult::GpgDecryptResult() = default; + +GpgDecryptResult::~GpgDecryptResult() = default; + +auto GpgDecryptResult::IsGood() -> bool { return result_ref_ != nullptr; } + +auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> { + std::vector<GpgRecipient> result; + for (auto* reci = result_ref_->recipients; reci != nullptr; + reci = reci->next) { + try { + result.emplace_back(reci); + } catch (...) { + SPDLOG_ERROR( + "caught exception when processing invalid_recipients, " + "maybe nullptr of fpr"); + } + } + return result; +} +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgDecryptResult.h b/src/core/model/GpgDecryptResult.h new file mode 100644 index 00000000..b7ceee9a --- /dev/null +++ b/src/core/model/GpgDecryptResult.h @@ -0,0 +1,52 @@ +/** + * 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/model/GpgRecipient.h" +#include "core/typedef/GpgTypedef.h" + +namespace GpgFrontend { + +class GPGFRONTEND_CORE_EXPORT GpgDecryptResult { + public: + auto IsGood() -> bool; + + auto Recipients() -> std::vector<GpgRecipient>; + + explicit GpgDecryptResult(gpgme_decrypt_result_t); + + GpgDecryptResult(); + + virtual ~GpgDecryptResult(); + + private: + std::shared_ptr<struct _gpgme_op_decrypt_result> result_ref_ = nullptr; ///< +}; + +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp index 9e6df32b..6e2f1083 100644 --- a/src/core/model/GpgKey.cpp +++ b/src/core/model/GpgKey.cpp @@ -43,10 +43,7 @@ auto GpgKey::operator=(GpgKey &&k) noexcept -> GpgKey & { GpgKey::GpgKey(const GpgKey &key) { auto *key_ref = key.key_ref_.get(); - { - const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex_); - gpgme_key_ref(key_ref); - } + gpgme_key_ref(key_ref); this->key_ref_ = KeyRefHandler(key_ref); } @@ -56,10 +53,8 @@ auto GpgKey::operator=(const GpgKey &key) -> GpgKey & { } auto *key_ref = key.key_ref_.get(); - { - const std::lock_guard<std::mutex> guard(gpgme_key_opera_mutex_); - gpgme_key_ref(key_ref); - } + gpgme_key_ref(key_ref); + this->key_ref_ = KeyRefHandler(key_ref); return *this; } diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h index b45a2c2a..5d53c9d2 100644 --- a/src/core/model/GpgKey.h +++ b/src/core/model/GpgKey.h @@ -369,8 +369,6 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { using KeyRefHandler = std::unique_ptr<struct _gpgme_key, KeyRefDeleter>; ///< KeyRefHandler key_ref_ = nullptr; ///< - - mutable std::mutex gpgme_key_opera_mutex_; // mutex for gpgme key operations }; } // namespace GpgFrontend diff --git a/src/core/model/GpgRecipient.cpp b/src/core/model/GpgRecipient.cpp new file mode 100644 index 00000000..34c50edc --- /dev/null +++ b/src/core/model/GpgRecipient.cpp @@ -0,0 +1,40 @@ +/** + * 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 "GpgRecipient.h" + +namespace GpgFrontend { + +GpgRecipient::GpgRecipient() = default; + +GpgRecipient::GpgRecipient(gpgme_recipient_t r) { + this->keyid = std::string{r->keyid}; + this->pubkey_algo = std::string{gpgme_pubkey_algo_name(r->pubkey_algo)}; + this->status = r->status; +} +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GpgRecipient.h b/src/core/model/GpgRecipient.h new file mode 100644 index 00000000..9c686817 --- /dev/null +++ b/src/core/model/GpgRecipient.h @@ -0,0 +1,51 @@ +/** + * 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 { + +struct GPGFRONTEND_CORE_EXPORT GpgRecipient { + /* The key ID of key for which the text was encrypted. */ + std::string keyid; + + /* The public key algorithm of the recipient key. */ + std::string pubkey_algo; + + /* The status of the recipient. */ + GpgError status; + + GpgRecipient(); + + explicit GpgRecipient(gpgme_recipient_t r); +}; + +} // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/IOUtils.cpp b/src/core/utils/IOUtils.cpp index 5d0a2a54..e0849a5f 100644 --- a/src/core/utils/IOUtils.cpp +++ b/src/core/utils/IOUtils.cpp @@ -70,12 +70,34 @@ auto ReadFileStd(const std::filesystem::path& file_name, std::string& data) return res; } +auto GPGFRONTEND_CORE_EXPORT ReadFileGFBuffer( + const std::filesystem::path& file_name) -> std::tuple<bool, GFBuffer> { + QByteArray byte_data; +#ifdef WINDOWS + const bool res = ReadFile( + QString::fromStdU16String(file_name.u16string()).toUtf8(), byte_data); +#else + const bool res = ReadFile( + QString::fromStdString(file_name.u8string()).toUtf8(), byte_data); +#endif + + return {res, GFBuffer(byte_data)}; +} + auto WriteFileStd(const std::filesystem::path& file_name, const std::string& data) -> bool { return WriteFile(QString::fromStdString(file_name.u8string()).toUtf8(), QByteArray::fromStdString(data)); } +auto GPGFRONTEND_CORE_EXPORT WriteFileGFBuffer( + const std::filesystem::path& file_name, GFBuffer data) -> bool { + return WriteFile( + QString::fromStdString(file_name.u8string()).toUtf8(), + QByteArray::fromRawData(reinterpret_cast<const char*>(data.Data()), + static_cast<qsizetype>(data.Size()))); +} + auto CalculateHash(const std::filesystem::path& file_path) -> std::string { // Returns empty QByteArray() on failure. QFileInfo info(QString::fromStdString(file_path.string())); diff --git a/src/core/utils/IOUtils.h b/src/core/utils/IOUtils.h index 3240e88a..bb286cd6 100644 --- a/src/core/utils/IOUtils.h +++ b/src/core/utils/IOUtils.h @@ -28,6 +28,8 @@ #pragma once +#include "core/model/GFBuffer.h" + namespace GpgFrontend { /** @@ -42,6 +44,15 @@ auto GPGFRONTEND_CORE_EXPORT ReadFileStd(const std::filesystem::path &file_name, std::string &data) -> bool; /** + * @brief + * + * @param file_name + * @return GFBuffer + */ +auto GPGFRONTEND_CORE_EXPORT ReadFileGFBuffer( + const std::filesystem::path &file_name) -> std::tuple<bool, GFBuffer>; + +/** * @brief write file content using std struct * * @param file_name file name @@ -52,6 +63,17 @@ auto GPGFRONTEND_CORE_EXPORT WriteFileStd( const std::filesystem::path &file_name, const std::string &data) -> bool; /** + * @brief + * + * @param file_name + * @param data + * @return true + * @return false + */ +auto GPGFRONTEND_CORE_EXPORT WriteFileGFBuffer( + const std::filesystem::path &file_name, GFBuffer data) -> bool; + +/** * @brief read file content * * @param file_name file name diff --git a/src/test/core/GpgCoreTestBasicOpera.cpp b/src/test/core/GpgCoreTestBasicOpera.cpp index b79ca659..8eef1565 100644 --- a/src/test/core/GpgCoreTestBasicOpera.cpp +++ b/src/test/core/GpgCoreTestBasicOpera.cpp @@ -32,6 +32,7 @@ #include "core/function/gpg/GpgBasicOperator.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/result_analyse/GpgDecryptResultAnalyse.h" +#include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" #include "core/utils/GpgUtils.h" @@ -40,27 +41,29 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, CoreEncryptDecrTest) { auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ByteArray encrypt_text = "Hello GpgFrontend!"; - KeyListPtr keys = std::make_unique<KeyArgsList>(); - keys->push_back(std::move(encrypt_key)); + auto encrypt_text = GFBuffer("Hello GpgFrontend!"); + auto const keys = std::vector<GpgKey>{encrypt_key}; GpgBasicOperator::GetInstance().Encrypt( - keys, encrypt_text, - [encrypt_text](GpgError err, const DataObjectPtr& data_obj) { + keys, 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); - GpgDecrResult d_result; - ByteArrayPtr decr_out_data; - err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Decrypt(encr_out_buffer, decr_out_data, d_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_NE(d_result->recipients, nullptr); - ASSERT_EQ(std::string(d_result->recipients->keyid), "6A2764F8298DEB29"); - ASSERT_EQ(*decr_out_data, encrypt_text); + GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) + .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_FALSE(d_result.Recipients().empty()); + ASSERT_EQ(d_result.Recipients()[0].keyid, "6A2764F8298DEB29"); + + ASSERT_EQ(decr_out_buffer, GFBuffer("Hello GpgFrontend!")); + }); }); } @@ -78,13 +81,14 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_1) { "=8n2H\n" "-----END PGP MESSAGE-----"); - GpgDecrResult d_result; - ByteArrayPtr decr_out_data; - auto err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Decrypt(encr_out_data, decr_out_data, d_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); - ASSERT_NE(d_result->recipients, nullptr); - ASSERT_EQ(std::string(d_result->recipients->keyid), "A50CFD2F6C677D8C"); + GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) + .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"); + }); } TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) { @@ -103,16 +107,19 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) { GpgDecrResult d_result; ByteArrayPtr decr_out_data; - auto err = GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) - .Decrypt(encr_out_data, decr_out_data, d_result); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); - ASSERT_NE(d_result->recipients, nullptr); - ASSERT_EQ(std::string(d_result->recipients->keyid), "A50CFD2F6C677D8C"); - - GpgDecryptResultAnalyse analyse{err, d_result}; - analyse.Analyse(); - ASSERT_EQ(analyse.GetStatus(), -1); - ASSERT_FALSE(analyse.GetResultReport().empty()); + GpgBasicOperator::GetInstance(kGpgFrontendDefaultChannel) + .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()); + }); } TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) { diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp index e7a25396..444cc224 100644 --- a/src/ui/main_window/MainWindowFileSlotFunction.cpp +++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp @@ -256,9 +256,11 @@ void MainWindow::SlotFileEncrypt() { process_operation(this, _("Encrypting"), [&](DataObjectPtr) -> int { try { - error = - GpgFileOpera::EncryptFile(std::move(p_keys), path.toStdString(), - out_path.toStdString(), result, _channel); + // TODO + // error = + // GpgFileOpera::EncryptFile(std::move(p_keys), path.toStdString(), + // out_path.toStdString(), result, + // _channel); } catch (const std::runtime_error& e) { if_error = true; } @@ -319,8 +321,10 @@ void MainWindow::SlotFileDecrypt() { bool if_error = false; process_operation(this, _("Decrypting"), [&](DataObjectPtr) -> int { try { - error = GpgFileOpera::DecryptFile(path.toStdString(), out_path.u8string(), - result); + // TODO + // error = GpgFileOpera::DecryptFile(path.toStdString(), + // out_path.u8string(), + // result); } catch (const std::runtime_error& e) { if_error = true; } diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 728818ab..0ef8c9e2 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -65,7 +65,8 @@ void MainWindow::slot_encrypt() { } auto key_ids = m_key_list_->GetChecked(); - auto buffer = edit_->CurTextPage()->GetTextPage()->toPlainText(); + auto buffer = GFBuffer( + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString()); if (key_ids->empty()) { // Symmetric Encrypt @@ -139,9 +140,8 @@ void MainWindow::slot_encrypt() { CommonUtils::WaitForOpera( this, _("Encrypting"), [this, keys, buffer](const OperaWaitingHd& hd) { - SPDLOG_DEBUG("[*] size of gpg key list: {}", keys->size()); GpgFrontend::GpgBasicOperator::GetInstance().Encrypt( - keys, buffer.toStdString(), + {keys->begin(), keys->end()}, buffer, true, [this, hd](GpgError err, const DataObjectPtr& data_obj) { auto result = ExtractParams<GpgEncrResult>(data_obj, 0); auto buffer = ExtractParams<ByteArrayPtr>(data_obj, 1); @@ -270,8 +270,9 @@ void MainWindow::slot_decrypt() { try { GpgDecrResult result = nullptr; auto decrypted = GpgFrontend::SecureCreateSharedObject<ByteArray>(); - GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt( - GFBuffer(buffer), decrypted, result); + // GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt( + // GFBuffer(buffer), decrypted, result); + GpgError error; data_object->Swap({error, result, decrypted}); } catch (const std::runtime_error& e) { |