Skip to content

Commit

Permalink
fix: solve discovered bugs and improve ui operations
Browse files Browse the repository at this point in the history
  • Loading branch information
saturneric committed Jan 19, 2024
1 parent f22ceca commit 5baef3c
Show file tree
Hide file tree
Showing 34 changed files with 258 additions and 180 deletions.
95 changes: 50 additions & 45 deletions src/core/function/KeyPackageOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@

#include "core/function/KeyPackageOperator.h"
#include "core/function/PassphraseGenerator.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
#include "core/model/GpgImportInformation.h"
#include "core/typedef/CoreTypedef.h"
#include "core/utils/AsyncUtils.h"
#include "core/utils/GpgUtils.h"
#include "core/utils/IOUtils.h"

Expand All @@ -54,9 +55,8 @@ void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
const OperationCallback& cb) {
GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name);

GpgKeyImportExporter::GetInstance().ExportKeys(
keys, secret, true, false, false,
[=](GpgError err, const DataObjectPtr& data_obj) {
GpgKeyImportExporter::GetInstance().ExportAllKeys(
keys, secret, true, [=](GpgError err, const DataObjectPtr& data_obj) {
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
GF_LOG_ERROR("export keys error, reason: {}",
DescribeGpgErrCode(err).second);
Expand Down Expand Up @@ -86,47 +86,52 @@ void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
});
}

auto KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
const QString& phrase_path)
-> std::tuple<bool, std::shared_ptr<GpgImportInformation>> {
GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);

QByteArray encrypted_data;
ReadFile(key_package_path, encrypted_data);

if (encrypted_data.isEmpty()) {
GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
return {false, nullptr};
};

QByteArray passphrase;
ReadFile(phrase_path, passphrase);
GF_CORE_LOG_DEBUG("passphrase: {} bytes", passphrase.size());
if (passphrase.size() != 256) {
GF_CORE_LOG_ERROR("failed to read passphrase: {}", phrase_path);
return {false, nullptr};
}

auto hash_key =
QCryptographicHash::hash(passphrase, QCryptographicHash::Sha256);
auto encoded = encrypted_data;

QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);

auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key));
auto key_data = QByteArray::fromBase64(decoded);

GF_CORE_LOG_DEBUG("import key package, read key data size: {}",
key_data.size());
if (!key_data.startsWith(PGP_PUBLIC_KEY_BEGIN) &&
!key_data.startsWith(PGP_PRIVATE_KEY_BEGIN)) {
return {false, nullptr};
}

auto import_info =
GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(key_data));
return {true, import_info};
void KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
const QString& phrase_path,
const OperationCallback& cb) {
RunOperaAsync(
[=](const DataObjectPtr& data_object) -> GFError {
GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);

QByteArray encrypted_data;
ReadFile(key_package_path, encrypted_data);

if (encrypted_data.isEmpty()) {
GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
return -1;
};

QByteArray passphrase;
ReadFile(phrase_path, passphrase);
if (passphrase.size() != 256) {
GF_CORE_LOG_ERROR("passphrase size mismatch: {}", phrase_path);
return -1;
}

auto hash_key =
QCryptographicHash::hash(passphrase, QCryptographicHash::Sha256);
auto encoded = encrypted_data;

QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);

auto decoded =
encryption.removePadding(encryption.decode(encoded, hash_key));
auto key_data = QByteArray::fromBase64(decoded);
if (!key_data.startsWith(PGP_PUBLIC_KEY_BEGIN) &&
!key_data.startsWith(PGP_PRIVATE_KEY_BEGIN)) {
return -1;
}

auto import_info_ptr =
GpgKeyImportExporter::GetInstance().ImportKey(GFBuffer(key_data));
if (import_info_ptr == nullptr) return GPG_ERR_NO_DATA;

auto import_info = *import_info_ptr;
data_object->Swap({import_info});
return 0;
},
cb, "import_key_package");
}

auto KeyPackageOperator::GenerateKeyPackageName() -> QString {
Expand Down
6 changes: 3 additions & 3 deletions src/core/function/KeyPackageOperator.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator {
* @return true if key package was imported
* @return false if key package was not imported
*/
static auto ImportKeyPackage(const QString &key_package_path,
const QString &phrase_path)
-> std::tuple<bool, std::shared_ptr<GpgImportInformation>>;
static void ImportKeyPackage(const QString &key_package_path,
const QString &phrase_path,
const OperationCallback &cb);

private:
/**
Expand Down
3 changes: 0 additions & 3 deletions src/core/function/gpg/GpgFileOpera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,6 @@ void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
ArchiveFileOperator::ExtractArchiveFromDataExchanger(
ex, out_path, [](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
GF_CORE_LOG_INFO("//////////////");
});

RunGpgOperaAsync(
Expand All @@ -462,10 +461,8 @@ void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
GpgData data_in(in_path, true);
GpgData data_out(ex);

GF_CORE_LOG_INFO("-----------------------");
err = CheckGpgError(
gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
GF_CORE_LOG_INFO("++++++++++++++++++++++++");

data_object->Swap({
GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
Expand Down
26 changes: 17 additions & 9 deletions src/core/function/gpg/GpgKeyGetter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,16 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}

auto FetchKey() -> KeyLinkListPtr {
if (keys_cache_.empty()) {
if (keys_search_cache_.empty()) {
FlushKeyCache();
}

auto keys_list = std::make_unique<GpgKeyLinkList>();

{
// get the lock
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
for (const auto& [key, value] : keys_cache_) {
keys_list->push_back(value);
for (const auto& key : keys_cache_) {
keys_list->push_back(key);
}
}
return keys_list;
Expand All @@ -98,6 +97,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {

// clear the keys cache
keys_cache_.clear();
keys_search_cache_.clear();

// init
GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
Expand All @@ -123,12 +123,14 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
gpg_key = GetKey(gpg_key.GetId(), false);
}

keys_cache_.insert({gpg_key.GetId(), std::move(gpg_key)});
keys_cache_.push_back(gpg_key);
keys_search_cache_.insert(gpg_key.GetId(), gpg_key);
keys_search_cache_.insert(gpg_key.GetFingerprint(), gpg_key);
}
}

GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
static_cast<void*>(&keys_cache_),
static_cast<void*>(&keys_search_cache_),
static_cast<void*>(this));

// for debug
Expand Down Expand Up @@ -181,7 +183,13 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
* @brief cache the keys with key id
*
*/
std::map<QString, GpgKey> keys_cache_;
QMap<QString, GpgKey> keys_search_cache_;

/**
* @brief
*
*/
QList<GpgKey> keys_cache_;

/**
* @brief shared mutex for the keys cache
Expand All @@ -197,10 +205,10 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
*/
auto get_key_in_cache(const QString& key_id) -> GpgKey {
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
if (keys_cache_.find(key_id) != keys_cache_.end()) {
if (keys_search_cache_.find(key_id) != keys_search_cache_.end()) {
std::lock_guard<std::mutex> lock(ctx_mutex_);
// return a copy of the key in cache
return keys_cache_[key_id];
return keys_search_cache_[key_id];
}

// return a bad key
Expand Down
3 changes: 0 additions & 3 deletions src/core/function/gpg/GpgKeyImportExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
import_info->imported_keys.emplace_back(key);
status = status->next;
}

return import_info;
}

Expand Down Expand Up @@ -152,8 +151,6 @@ void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
if (keys.empty()) return GPG_ERR_CANCELED;

int mode = 0;
if (secret) mode |= GPGME_EXPORT_MODE_SECRET;

std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end());

// Last entry data_in array has to be nullptr
Expand Down
1 change: 0 additions & 1 deletion src/core/model/GpgData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ auto GFWriteExCb(void* handle, const void* buffer, size_t size) -> ssize_t {
}

void GFReleaseExCb(void* handle) {
GF_CORE_LOG_INFO("$$$$$$$$$$$$$$$$$$$$$$$");
auto* ex = static_cast<GFDataExchanger*>(handle);
ex->CloseWrite();
}
Expand Down
28 changes: 28 additions & 0 deletions src/core/utils/AsyncUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,32 @@ auto RunIOOperaAsync(const OperaRunnable& runnable,
handler.Start();
return handler;
}

auto RunOperaAsync(const OperaRunnable& runnable,
const OperationCallback& callback, const QString& operation)
-> Thread::Task::TaskHandler {
auto handler =
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->RegisterTask(
operation,
[=](const DataObjectPtr& data_object) -> int {
auto custom_data_object = TransferParams();
GpgError err = runnable(custom_data_object);

data_object->Swap({err, custom_data_object});
return 0;
},
[=](int rtn, const DataObjectPtr& data_object) {
if (rtn < 0) {
callback(-1, ExtractParams<DataObjectPtr>(data_object, 1));
} else {
callback(ExtractParams<GFError>(data_object, 0),
ExtractParams<DataObjectPtr>(data_object, 1));
}
},
TransferParams());
handler.Start();
return handler;
}
} // namespace GpgFrontend
13 changes: 13 additions & 0 deletions src/core/utils/AsyncUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,17 @@ auto GPGFRONTEND_CORE_EXPORT RunIOOperaAsync(const OperaRunnable& runnable,
const OperationCallback& callback,
const QString& operation)
-> Thread::Task::TaskHandler;

/**
* @brief
*
* @param runnable
* @param callback
* @param operation
* @return Thread::Task::TaskHandler
*/
auto GPGFRONTEND_CORE_EXPORT RunOperaAsync(const OperaRunnable& runnable,
const OperationCallback& callback,
const QString& operation)
-> Thread::Task::TaskHandler;
} // namespace GpgFrontend
4 changes: 2 additions & 2 deletions src/ui/GpgFrontendUIInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#include "GpgFrontendUIInit.h"

#include <clocale>
#include <QtNetwork>

#include "core/GpgConstants.h"
#include "core/function/CoreSignalStation.h"
Expand Down Expand Up @@ -195,7 +195,7 @@ auto RunGpgFrontendUI(QApplication* app) -> int {
main_window->show();

// start the main event loop
return app->exec();
return QApplication::exec();
}

void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI() {}
Expand Down
40 changes: 34 additions & 6 deletions src/ui/UserInterfaceUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@

#include "UserInterfaceUtils.h"

#include <gpg-error.h>
#include <qdialog.h>

#include <QtNetwork>
#include <vector>

#include "core/GpgConstants.h"
#include "core/function/CoreSignalStation.h"
#include "core/function/gpg/GpgKeyGetter.h"
Expand All @@ -44,9 +38,11 @@
#include "core/typedef/GpgTypedef.h"
#include "core/utils/GpgUtils.h"
#include "core/utils/IOUtils.h"
#include "thread/KeyServerImportTask.h"
#include "ui/UISignalStation.h"
#include "ui/dialog/WaitingDialog.h"
#include "ui/dialog/gnupg/GnuPGControllerDialog.h"
#include "ui/dialog/import_export/KeyServerImportDialog.h"
#include "ui/struct/CacheObject.h"
#include "ui/struct/SettingsObject.h"
#include "ui/struct/settings/KeyServerSO.h"
Expand Down Expand Up @@ -476,6 +472,22 @@ void CommonUtils::slot_update_key_status() {
refresh_task);
}

void CommonUtils::slot_update_key_from_server_finished(
bool success, QString err_msg, QByteArray buffer,
std::shared_ptr<GpgImportInformation> info) {
if (!success) {
GF_UI_LOG_ERROR("get err from reply: {}", buffer);
QMessageBox::critical(nullptr, tr("Error"), err_msg);
return;
}

// refresh the key database
emit UISignalStation::GetInstance()->SignalKeyDatabaseRefresh();

// show details
(new KeyImportDetailDialog(std::move(info), this))->exec();
}

void CommonUtils::SlotRestartApplication(int code) {
GF_UI_LOG_DEBUG("application need restart, code: {}", code);

Expand Down Expand Up @@ -525,4 +537,20 @@ void CommonUtils::RemoveKeyFromFavourite(const GpgKey &key) {
json_data.setArray(new_key_array);
}

/**
* @brief
*
*/
void CommonUtils::ImportKeyFromKeyServer(const KeyIdArgsList &key_ids) {
KeyServerSO key_server(SettingsObject("general_settings_state"));
auto target_keyserver = key_server.GetTargetServer();

auto *task = new KeyServerImportTask(target_keyserver, key_ids);
connect(task, &KeyServerImportTask::SignalKeyServerImportResult, this,
&CommonUtils::slot_update_key_from_server_finished);
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
->PostTask(task);
}

} // namespace GpgFrontend::UI
Loading

0 comments on commit 5baef3c

Please sign in to comment.