aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function')
-rw-r--r--src/core/function/ArchiveFileOperator.cpp238
-rw-r--r--src/core/function/ArchiveFileOperator.h79
-rw-r--r--src/core/function/DataObjectOperator.cpp169
-rw-r--r--src/core/function/DataObjectOperator.h82
-rw-r--r--src/core/function/FileOperator.cpp119
-rw-r--r--src/core/function/FileOperator.h92
-rw-r--r--src/core/function/GlobalSettingStation.cpp141
-rw-r--r--src/core/function/GlobalSettingStation.h232
-rw-r--r--src/core/function/KeyPackageOperator.cpp120
-rw-r--r--src/core/function/KeyPackageOperator.h107
-rw-r--r--src/core/function/PassphraseGenerator.cpp29
-rw-r--r--src/core/function/PassphraseGenerator.h83
-rw-r--r--src/core/function/aes/aes_ssl.h74
-rw-r--r--src/core/function/aes/aes_ssl_cbc.cpp99
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp220
-rw-r--r--src/core/function/gpg/GpgBasicOperator.h179
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp63
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.h77
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp182
-rw-r--r--src/core/function/gpg/GpgFileOpera.h153
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp96
-rw-r--r--src/core/function/gpg/GpgKeyGetter.h110
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp178
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.h195
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp92
-rw-r--r--src/core/function/gpg/GpgKeyManager.h93
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp293
-rw-r--r--src/core/function/gpg/GpgKeyOpera.h135
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp68
-rw-r--r--src/core/function/gpg/GpgUIDOperator.h88
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp97
-rw-r--r--src/core/function/result_analyse/GpgDecryptResultAnalyse.h73
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp66
-rw-r--r--src/core/function/result_analyse/GpgEncryptResultAnalyse.h63
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.cpp46
-rw-r--r--src/core/function/result_analyse/GpgResultAnalyse.h86
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.cpp115
-rw-r--r--src/core/function/result_analyse/GpgSignResultAnalyse.h65
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp214
-rw-r--r--src/core/function/result_analyse/GpgVerifyResultAnalyse.h88
40 files changed, 4799 insertions, 0 deletions
diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp
new file mode 100644
index 00000000..6315dcd5
--- /dev/null
+++ b/src/core/function/ArchiveFileOperator.cpp
@@ -0,0 +1,238 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "ArchiveFileOperator.h"
+
+int copy_data(struct archive *ar, struct archive *aw) {
+ int r;
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ for (;;) {
+ r = archive_read_data_block(ar, &buff, &size, &offset);
+ if (r == ARCHIVE_EOF)
+ return (ARCHIVE_OK);
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "archive_read_data_block() failed: " << archive_error_string(ar);
+ return (r);
+ }
+ r = archive_write_data_block(aw, buff, size, offset);
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "archive_write_data_block() failed: " << archive_error_string(aw);
+ return (r);
+ }
+ }
+}
+
+void GpgFrontend::ArchiveFileOperator::CreateArchive(
+ const std::filesystem::path &base_path,
+ const std::filesystem::path &archive_path, int compress,
+ const std::vector<std::filesystem::path> &files) {
+ LOG(INFO) << "CreateArchive: " << archive_path.string();
+
+ auto current_base_path_backup = QDir::currentPath();
+ QDir::setCurrent(base_path.string().c_str());
+
+ auto relative_archive_path = std::filesystem::relative(archive_path, base_path);
+
+ std::vector<std::filesystem::path> relative_files;
+ relative_files.reserve(files.size());
+ for(const auto& file : files) {
+ relative_files.push_back(std::filesystem::relative(file, base_path));
+ }
+
+ struct archive *a;
+ struct archive_entry *entry;
+ ssize_t len;
+ int fd;
+
+ LOG(INFO) << "compress: " << compress;
+
+ a = archive_write_new();
+ switch (compress) {
+#ifndef NO_BZIP2_CREATE
+ case 'j':
+ case 'y':
+ archive_write_add_filter_bzip2(a);
+ break;
+#endif
+#ifndef NO_COMPRESS_CREATE
+ case 'Z':
+ archive_write_add_filter_compress(a);
+ break;
+#endif
+#ifndef NO_GZIP_CREATE
+ case 'z':
+ archive_write_add_filter_gzip(a);
+ break;
+#endif
+ default:
+ archive_write_add_filter_none(a);
+ break;
+ }
+ archive_write_set_format_ustar(a);
+ archive_write_set_format_pax_restricted(a);
+
+ auto filename = relative_archive_path.string();
+ if (!filename.empty() && filename == "-")
+ throw std::runtime_error("cannot write to stdout");
+
+ archive_write_open_filename(a, filename.c_str());
+
+ for (const auto &file : relative_files) {
+ struct archive *disk = archive_read_disk_new();
+#ifndef NO_LOOKUP
+ archive_read_disk_set_standard_lookup(disk);
+#endif
+ int r;
+
+ LOG(INFO) << "ReadFile: " << file.string();
+
+ r = archive_read_disk_open(disk, file.string().c_str());
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "archive_read_disk_open() failed: "
+ << archive_error_string(disk);
+ throw std::runtime_error("archive_read_disk_open() failed");
+ }
+
+ for (;;) {
+ bool needcr = false;
+
+ entry = archive_entry_new();
+ r = archive_read_next_header2(disk, entry);
+ if (r == ARCHIVE_EOF) break;
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "archive_read_next_header2() failed: "
+ << archive_error_string(disk);
+ throw std::runtime_error("archive_read_next_header2() failed");
+ }
+ archive_read_disk_descend(disk);
+ LOG(INFO) << "Adding: " << archive_entry_pathname(entry) << "size"
+ << archive_entry_size(entry) << " bytes"
+ << "file type" << archive_entry_filetype(entry);
+ r = archive_write_header(a, entry);
+ if (r < ARCHIVE_OK) {
+ LOG(ERROR) << "archive_write_header() failed: "
+ << archive_error_string(a);
+ throw std::runtime_error("archive_write_header() failed");
+ }
+ if (r == ARCHIVE_FATAL) throw std::runtime_error("archive fatal");
+ if (r > ARCHIVE_FAILED) {
+ ByteArray buff;
+ FileOperator::ReadFileStd(archive_entry_sourcepath(entry), buff);
+ archive_write_data(a, buff.c_str(), buff.size());
+ }
+ archive_entry_free(entry);
+ }
+ archive_read_close(disk);
+ archive_read_free(disk);
+ }
+ archive_write_close(a);
+ archive_write_free(a);
+
+ QDir::setCurrent(current_base_path_backup);
+}
+
+void GpgFrontend::ArchiveFileOperator::ExtractArchive(
+ const std::filesystem::path &archive_path,
+ const std::filesystem::path &base_path) {
+
+ LOG(INFO) << "ExtractArchive: " << archive_path.string();
+
+ auto current_base_path_backup = QDir::currentPath();
+ QDir::setCurrent(base_path.string().c_str());
+
+ struct archive *a;
+ struct archive *ext;
+ struct archive_entry *entry;
+ int r;
+
+ a = archive_read_new();
+ ext = archive_write_disk_new();
+ archive_write_disk_set_options(ext, 0);
+#ifndef NO_BZIP2_EXTRACT
+ archive_read_support_filter_bzip2(a);
+#endif
+#ifndef NO_GZIP_EXTRACT
+ archive_read_support_filter_gzip(a);
+#endif
+#ifndef NO_COMPRESS_EXTRACT
+ archive_read_support_filter_compress(a);
+#endif
+#ifndef NO_TAR_EXTRACT
+ archive_read_support_format_tar(a);
+#endif
+#ifndef NO_CPIO_EXTRACT
+ archive_read_support_format_cpio(a);
+#endif
+#ifndef NO_LOOKUP
+ archive_write_disk_set_standard_lookup(ext);
+#endif
+
+ auto filename = archive_path.string();
+
+ if (!filename.empty() && filename == "-") {
+ LOG(ERROR) << "cannot read from stdin";
+ }
+ if ((r = archive_read_open_filename(a, filename.c_str(), 10240))) {
+ LOG(ERROR) << "archive_read_open_filename() failed: "
+ << archive_error_string(a);
+ throw std::runtime_error("archive_read_open_filename() failed");
+ }
+ for (;;) {
+ r = archive_read_next_header(a, &entry);
+ if (r == ARCHIVE_EOF)
+ break;
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "archive_read_next_header() failed: "
+ << archive_error_string(a);
+ throw std::runtime_error("archive_read_next_header() failed");
+ }
+ LOG(INFO) << "Extracting: " << archive_entry_pathname(entry)
+ << "size" << archive_entry_size(entry) << " bytes"
+ << "file type" << archive_entry_filetype(entry);
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "archive_write_header() failed: "
+ << archive_error_string(ext);
+ } else {
+ r = copy_data(a, ext);
+ if (r != ARCHIVE_OK) {
+ LOG(ERROR) << "copy_data() failed: " << archive_error_string(ext);
+ }
+ }
+ }
+ archive_read_close(a);
+ archive_read_free(a);
+
+ archive_write_close(ext);
+ archive_write_free(ext);
+
+ QDir::setCurrent(current_base_path_backup);
+}
diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h
new file mode 100644
index 00000000..8e1d9c44
--- /dev/null
+++ b/src/core/function/ArchiveFileOperator.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_ARCHIVEFILEOPERATOR_H
+#define GPGFRONTEND_ARCHIVEFILEOPERATOR_H
+
+#include "core/GpgFrontendCore.h"
+#include "core/function/FileOperator.h"
+
+namespace GpgFrontend {
+
+struct ArchiveStruct {
+ struct archive *archive;
+ struct archive_entry *entry;
+ int fd;
+ bool is_open;
+ std::string name;
+};
+
+class ArchiveFileOperator {
+ public:
+ static void ListArchive(const std::filesystem::path &archive_path) {
+ struct archive *a;
+ struct archive_entry *entry;
+ int r;
+
+ a = archive_read_new();
+ archive_read_support_filter_all(a);
+ archive_read_support_format_all(a);
+ r = archive_read_open_filename(a, archive_path.string().c_str(),
+ 10240); // Note 1
+ if (r != ARCHIVE_OK) return;
+ while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ LOG(INFO) << "File: " << archive_entry_pathname(entry);
+ LOG(INFO) << "File Path: " << archive_entry_pathname(entry);
+ archive_read_data_skip(a); // Note 2
+ }
+ r = archive_read_free(a); // Note 3
+ if (r != ARCHIVE_OK) return;
+ }
+
+ static void CreateArchive(
+ const std::filesystem::path &base_path,
+ const std::filesystem::path &archive_path,
+ int compress,
+ const std::vector<std::filesystem::path> &files);
+
+ static void ExtractArchive(
+ const std::filesystem::path &archive_path,
+ const std::filesystem::path &base_path);
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ARCHIVEFILEOPERATOR_H
diff --git a/src/core/function/DataObjectOperator.cpp b/src/core/function/DataObjectOperator.cpp
new file mode 100644
index 00000000..a3f7fc70
--- /dev/null
+++ b/src/core/function/DataObjectOperator.cpp
@@ -0,0 +1,169 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "DataObjectOperator.h"
+
+#include <qt-aes/qaesencryption.h>
+
+#include "core/function/FileOperator.h"
+#include "core/function/PassphraseGenerator.h"
+
+void GpgFrontend::DataObjectOperator::init_app_secure_key() {
+ LOG(INFO) << "Initializing application secure key";
+ FileOperator::WriteFileStd(app_secure_key_path_,
+ PassphraseGenerator::GetInstance().Generate(256));
+ std::filesystem::permissions(
+ app_secure_key_path_,
+ std::filesystem::perms::owner_read | std::filesystem::perms::owner_write);
+}
+
+GpgFrontend::DataObjectOperator::DataObjectOperator(int channel)
+ : SingletonFunctionObject<DataObjectOperator>(channel) {
+ if (!is_directory(app_secure_path_)) create_directory(app_secure_path_);
+
+ if (!exists(app_secure_key_path_)) {
+ init_app_secure_key();
+ }
+
+ std::string key;
+ if (!FileOperator::ReadFileStd(app_secure_key_path_.string(), key)) {
+ LOG(FATAL) << _("Failed to read app secure key file")
+ << app_secure_key_path_;
+ throw std::runtime_error(_("Failed to read app secure key file"));
+ }
+ hash_key_ = QCryptographicHash::hash(QByteArray::fromStdString(key),
+ QCryptographicHash::Sha256);
+ LOG(INFO) << "App secure key loaded" << hash_key_.size() << "bytes";
+
+ if (!exists(app_data_objs_path_)) create_directory(app_data_objs_path_);
+}
+
+std::string GpgFrontend::DataObjectOperator::SaveDataObj(
+ const std::string& _key, const nlohmann::json& value) {
+
+ std::string _hash_obj_key = {};
+ if (_key.empty()) {
+ _hash_obj_key =
+ QCryptographicHash::hash(
+ hash_key_ + QByteArray::fromStdString(
+ PassphraseGenerator::GetInstance().Generate(32) +
+ to_iso_extended_string(
+ boost::posix_time::second_clock::local_time())),
+ QCryptographicHash::Sha256)
+ .toHex()
+ .toStdString();
+ } else {
+ _hash_obj_key =
+ QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
+ QCryptographicHash::Sha256)
+ .toHex()
+ .toStdString();
+ }
+
+ const auto obj_path = app_data_objs_path_ / _hash_obj_key;
+
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+ auto encoded =
+ encryption.encode(QByteArray::fromStdString(to_string(value)), hash_key_);
+
+ LOG(INFO) << _("Saving data object") << _hash_obj_key << "to" << obj_path << encoded.size() << "bytes";
+
+ FileOperator::WriteFileStd(obj_path.string(), encoded.toStdString());
+
+ return _key.empty() ? _hash_obj_key : std::string();
+}
+
+std::optional<nlohmann::json> GpgFrontend::DataObjectOperator::GetDataObject(
+ const std::string& _key) {
+ try {
+ LOG(INFO) << _("Get data object") << _key;
+ auto _hash_obj_key =
+ QCryptographicHash::hash(hash_key_ + QByteArray::fromStdString(_key),
+ QCryptographicHash::Sha256)
+ .toHex()
+ .toStdString();
+
+ const auto obj_path = app_data_objs_path_ / _hash_obj_key;
+
+ if (!std::filesystem::exists(obj_path)) {
+ LOG(ERROR) << _("Data object not found") << _key;
+ return {};
+ }
+
+ std::string buffer;
+ if (!FileOperator::ReadFileStd(obj_path.string(), buffer)) {
+ LOG(ERROR) << _("Failed to read data object") << _key;
+ return {};
+ }
+
+ LOG(INFO) << _("Data object found") << _key;
+
+ auto encoded = QByteArray::fromStdString(buffer);
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+
+ LOG(INFO) << _("Decrypting data object") << encoded.size() << hash_key_.size();
+
+ auto decoded =
+ encryption.removePadding(encryption.decode(encoded, hash_key_));
+
+ LOG(INFO) << _("Data object decoded") << _key;
+
+ return nlohmann::json::parse(decoded.toStdString());
+ } catch (...) {
+ LOG(ERROR) << _("Failed to get data object") << _key;
+ return {};
+ }
+}
+
+std::optional<nlohmann::json>
+GpgFrontend::DataObjectOperator::GetDataObjectByRef(const std::string& _ref) {
+ if (_ref.size() != 64) return {};
+
+ try {
+ const auto& _hash_obj_key = _ref;
+ const auto obj_path = app_data_objs_path_ / _hash_obj_key;
+
+ if (!std::filesystem::exists(obj_path)) return {};
+
+ std::string buffer;
+ if (!FileOperator::ReadFileStd(obj_path.string(), buffer)) return {};
+ auto encoded = QByteArray::fromStdString(buffer);
+
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+
+ auto decoded =
+ encryption.removePadding(encryption.decode(encoded, hash_key_));
+
+ return nlohmann::json::parse(decoded.toStdString());
+ } catch (...) {
+ return {};
+ }
+}
diff --git a/src/core/function/DataObjectOperator.h b/src/core/function/DataObjectOperator.h
new file mode 100644
index 00000000..0ce4e313
--- /dev/null
+++ b/src/core/function/DataObjectOperator.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_DATAOBJECTOPERATOR_H
+#define GPGFRONTEND_DATAOBJECTOPERATOR_H
+
+#include <json/single_include/nlohmann/json.hpp>
+
+#include "core/GpgFrontendCore.h"
+#include "core/GpgFunctionObject.h"
+#include "core/function/GlobalSettingStation.h"
+
+namespace GpgFrontend {
+
+class DataObjectOperator : public SingletonFunctionObject<DataObjectOperator> {
+ public:
+ /**
+ * @brief DataObjectOperator constructor
+ *
+ * @param channel channel
+ */
+ explicit DataObjectOperator(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
+
+ std::string SaveDataObj(const std::string &_key, const nlohmann::json &value);
+
+ std::optional<nlohmann::json> GetDataObject(const std::string &_key);
+
+ std::optional<nlohmann::json> GetDataObjectByRef(const std::string &_ref);
+
+ private:
+ /**
+ * @brief init the secure key of application data object
+ *
+ */
+ void init_app_secure_key();
+
+ GlobalSettingStation &global_setting_station_ =
+ GlobalSettingStation::GetInstance(); ///< GlobalSettingStation
+ std::filesystem::path app_secure_path_ =
+ global_setting_station_.GetAppConfigPath() /
+ "secure"; ///< Where sensitive information is stored
+ std::filesystem::path app_secure_key_path_ =
+ app_secure_path_ / "app.key"; ///< Where the key of data object is stored
+ std::filesystem::path app_data_objs_path_ =
+ global_setting_station_.GetAppDataPath() / "data_objs"; ///< Where data
+ ///< object is
+ ///< stored
+
+ std::random_device rd_; ///< Random device
+ std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
+ QByteArray hash_key_; ///< Hash key
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_DATAOBJECTOPERATOR_H
diff --git a/src/core/function/FileOperator.cpp b/src/core/function/FileOperator.cpp
new file mode 100644
index 00000000..d0a3df23
--- /dev/null
+++ b/src/core/function/FileOperator.cpp
@@ -0,0 +1,119 @@
+/**
+* Copyright (C) 2021 Saturneric
+*
+* 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 "FileOperator.h"
+
+bool GpgFrontend::FileOperator::ReadFile(const QString& file_name,
+ QByteArray& data) {
+ QFile file(file_name);
+ if (!file.open(QIODevice::ReadOnly)) {
+ LOG(ERROR) << "failed to open file" << file_name.toStdString();
+ return false;
+ }
+ data = file.readAll();
+ file.close();
+ return true;
+}
+
+bool GpgFrontend::FileOperator::WriteFile(const QString& file_name,
+ const QByteArray& data) {
+ QFile file(file_name);
+ if (!file.open(QIODevice::WriteOnly)) {
+ LOG(ERROR) << "failed to open file" << file_name.toStdString();
+ return false;
+ }
+ file.write(data);
+ file.close();
+ return true;
+}
+
+bool GpgFrontend::FileOperator::ReadFileStd(
+ const std::filesystem::path& file_name, std::string& data) {
+ QByteArray byte_data;
+ bool res = ReadFile(QString::fromStdString(file_name.string()), byte_data);
+ data = byte_data.toStdString();
+ return res;
+}
+
+bool GpgFrontend::FileOperator::WriteFileStd(
+ const std::filesystem::path& file_name, const std::string& data) {
+ return WriteFile(QString::fromStdString(file_name.string()),
+ QByteArray::fromStdString(data));
+}
+
+std::string GpgFrontend::FileOperator::CalculateHash(
+ const std::filesystem::path& file_path) {
+ // Returns empty QByteArray() on failure.
+ QFileInfo info(QString::fromStdString(file_path.string()));
+ std::stringstream ss;
+
+ if (info.isFile() && info.isReadable()) {
+ ss << "[#] " << _("File Hash Information") << std::endl;
+ ss << " " << _("filename") << _(": ")
+ << file_path.filename().string().c_str() << std::endl;
+
+
+ QFile f(info.filePath());
+ f.open(QFile::ReadOnly);
+ auto buffer = f.readAll();
+ ss << " " << _("file size(bytes)") << _(": ")
+ << buffer.size() << std::endl;
+ f.close();
+ if (f.open(QFile::ReadOnly)) {
+ auto hash_md5 = QCryptographicHash(QCryptographicHash::Md5);
+ // md5
+ hash_md5.addData(buffer);
+ auto md5 = hash_md5.result().toHex().toStdString();
+ LOG(INFO) << "md5" << md5;
+ ss << " "
+ << "md5" << _(": ") << md5 << std::endl;
+
+ auto hash_sha1 = QCryptographicHash(QCryptographicHash::Sha1);
+ // sha1
+ hash_sha1.addData(buffer);
+ auto sha1 = hash_sha1.result().toHex().toStdString();
+ LOG(INFO) << "sha1" << sha1;
+ ss << " "
+ << "sha1" << _(": ") << sha1 << std::endl;
+
+ auto hash_sha256 = QCryptographicHash(QCryptographicHash::Sha256);
+ // sha1
+ hash_sha256.addData(buffer);
+ auto sha256 = hash_sha256.result().toHex().toStdString();
+ LOG(INFO) << "sha256" << sha256;
+ ss << " "
+ << "sha256" << _(": ") << sha256 << std::endl;
+
+ ss << std::endl;
+ }
+ } else {
+ ss << "[#] " << _("Error in Calculating File Hash ") << std::endl;
+ }
+
+ return ss.str();
+}
diff --git a/src/core/function/FileOperator.h b/src/core/function/FileOperator.h
new file mode 100644
index 00000000..aa2c3b73
--- /dev/null
+++ b/src/core/function/FileOperator.h
@@ -0,0 +1,92 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_FILEOPERATOR_H
+#define GPGFRONTEND_FILEOPERATOR_H
+
+#include "core/GpgFrontendCore.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief provides file operations
+ *
+ */
+class FileOperator {
+ public:
+ /**
+ * @brief read file content using std struct
+ *
+ *
+ * @param file_name file name
+ * @param data data read from file
+ * @return
+ */
+ static bool ReadFileStd(const std::filesystem::path &file_name,
+ std::string &data);
+
+ /**
+ * @brief write file content using std struct
+ *
+ * @param file_name file name
+ * @param data data to write to file
+ * @return
+ */
+ static bool WriteFileStd(const std::filesystem::path &file_name,
+ const std::string &data);
+
+ /**
+ * @brief read file content
+ *
+ * @param file_name file name
+ * @param data data read from file
+ * @return true if success
+ * @return false if failed
+ */
+ static bool ReadFile(const QString &file_name, QByteArray &data);
+
+ /**
+ * @brief write file content
+ *
+ * @param file_name file name
+ * @param data data to write to file
+ * @return true if success
+ * @return false if failed
+ */
+ static bool WriteFile(const QString &file_name, const QByteArray &data);
+
+ /**
+ * calculate the hash of a file
+ * @param file_path
+ * @return
+ */
+ static std::string CalculateHash(const std::filesystem::path &file_path);
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_FILEOPERATOR_H
diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp
new file mode 100644
index 00000000..7b3e868e
--- /dev/null
+++ b/src/core/function/GlobalSettingStation.cpp
@@ -0,0 +1,141 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GlobalSettingStation.h"
+
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+
+#include <vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp>
+#include <vmime/vmime.hpp>
+
+#include "core/function/FileOperator.h"
+
+void GpgFrontend::GlobalSettingStation::SyncSettings() noexcept {
+ using namespace libconfig;
+ try {
+ ui_cfg_.writeFile(ui_config_path_.string().c_str());
+ LOG(INFO) << _("Updated ui configuration successfully written to")
+ << ui_config_path_;
+
+ } catch (const FileIOException &fioex) {
+ LOG(ERROR) << _("I/O error while writing ui configuration file")
+ << ui_config_path_;
+ }
+}
+
+GpgFrontend::GlobalSettingStation::GlobalSettingStation(int channel) noexcept
+ : SingletonFunctionObject<GlobalSettingStation>(channel) {
+ using namespace std::filesystem;
+ using namespace libconfig;
+
+ el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
+
+ LOG(INFO) << _("App Path") << app_path_;
+ LOG(INFO) << _("App Configure Path") << app_configure_path_;
+ LOG(INFO) << _("App Data Path") << app_data_path_;
+ LOG(INFO) << _("App Log Path") << app_log_path_;
+ LOG(INFO) << _("App Locale Path") << app_locale_path_;
+
+ if (!is_directory(app_configure_path_)) create_directory(app_configure_path_);
+
+ if (!is_directory(app_data_path_)) create_directory(app_data_path_);
+
+ if (!is_directory(app_log_path_)) create_directory(app_log_path_);
+
+ if (!is_directory(ui_config_dir_path_)) create_directory(ui_config_dir_path_);
+
+ if (!exists(ui_config_path_)) {
+ try {
+ this->ui_cfg_.writeFile(ui_config_path_.string().c_str());
+ LOG(INFO) << _("UserInterface configuration successfully written to")
+ << ui_config_path_;
+
+ } catch (const FileIOException &fioex) {
+ LOG(ERROR)
+ << _("I/O error while writing UserInterface configuration file")
+ << ui_config_path_;
+ }
+ } else {
+ try {
+ this->ui_cfg_.readFile(ui_config_path_.string().c_str());
+ LOG(INFO) << _("UserInterface configuration successfully read from")
+ << ui_config_path_;
+ } catch (const FileIOException &fioex) {
+ LOG(ERROR) << _("I/O error while reading UserInterface configure file");
+ } catch (const ParseException &pex) {
+ LOG(ERROR) << _("Parse error at ") << pex.getFile() << ":"
+ << pex.getLine() << " - " << pex.getError();
+ }
+ }
+}
+
+void GpgFrontend::GlobalSettingStation::AddRootCert(
+ const std::filesystem::path &path) {
+ std::string out_buffer;
+ if (!FileOperator::ReadFileStd(path.string(), out_buffer)) {
+ LOG(ERROR) << _("Failed to read root certificate file") << path;
+ return;
+ }
+
+ auto mem_bio = std::shared_ptr<BIO>(
+ BIO_new_mem_buf(out_buffer.data(), static_cast<int>(out_buffer.size())),
+ [](BIO *_p) { BIO_free(_p); });
+
+ auto x509 = std::shared_ptr<X509>(
+ PEM_read_bio_X509(mem_bio.get(), nullptr, nullptr, nullptr),
+ [](X509 *_p) { X509_free(_p); });
+
+ if (!x509) return;
+
+ root_certs_.push_back(x509);
+}
+
+vmime::shared_ptr<vmime::security::cert::defaultCertificateVerifier>
+GpgFrontend::GlobalSettingStation::GetCertVerifier() const {
+ auto p_cv =
+ vmime::make_shared<vmime::security::cert::defaultCertificateVerifier>();
+
+ std::vector<vmime::shared_ptr<vmime::security::cert::X509Certificate>>
+ _root_certs;
+ for (const auto &cert : root_certs_) {
+ _root_certs.push_back(
+ std::make_shared<vmime::security::cert::X509Certificate_OpenSSL>(
+ cert.get()));
+ }
+ return p_cv;
+}
+
+const std::vector<std::shared_ptr<X509>>
+ &GpgFrontend::GlobalSettingStation::GetRootCerts() {
+ return root_certs_;
+}
+
+void GpgFrontend::GlobalSettingStation::init_app_secure_key() {}
+
+GpgFrontend::GlobalSettingStation::~GlobalSettingStation() noexcept = default;
diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h
new file mode 100644
index 00000000..d6521c8a
--- /dev/null
+++ b/src/core/function/GlobalSettingStation.h
@@ -0,0 +1,232 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GLOBALSETTINGSTATION_H
+#define GPGFRONTEND_GLOBALSETTINGSTATION_H
+
+#include <openssl/x509.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include "GpgFrontendBuildInstallInfo.h"
+#include "core/GpgFrontendCore.h"
+#include "core/GpgFunctionObject.h"
+
+namespace vmime::security::cert {
+class defaultCertificateVerifier;
+class X509Certificate;
+} // namespace vmime::security::cert
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GlobalSettingStation
+ : public SingletonFunctionObject<GlobalSettingStation> {
+ public:
+ /**
+ * @brief Construct a new Global Setting Station object
+ *
+ */
+ explicit GlobalSettingStation(
+ int channel = SingletonFunctionObject::GetDefaultChannel()) noexcept;
+
+ /**
+ * @brief Destroy the Global Setting Station object
+ *
+ */
+ ~GlobalSettingStation() noexcept override;
+
+ /**
+ * @brief
+ *
+ * @return libconfig::Setting&
+ */
+ libconfig::Setting &GetUISettings() noexcept { return ui_cfg_.getRoot(); }
+
+ /**
+ * @brief Get the App Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetAppDir() const { return app_path_; }
+
+ [[nodiscard]] std::filesystem::path GetAppDataPath() const {
+ return app_data_path_;
+ }
+
+ /**
+ * @brief Get the Log Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetLogDir() const {
+ return app_log_path_;
+ }
+
+ /**
+ * @brief Get the Standalone Database Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetStandaloneDatabaseDir() const {
+ auto db_path = app_configure_path_ / "db";
+ if (!std::filesystem::exists(db_path)) {
+ std::filesystem::create_directory(db_path);
+ }
+ return db_path;
+ }
+
+ [[nodiscard]] std::filesystem::path GetAppConfigPath() const {
+ return app_configure_path_;
+ }
+
+ /**
+ * @brief Get the Standalone Gpg Bin Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetStandaloneGpgBinDir() const {
+ return app_resource_path_ / "gpg1.4" / "gpg";
+ }
+
+ /**
+ * @brief Get the Locale Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetLocaleDir() const {
+ return app_locale_path_;
+ }
+
+ /**
+ * @brief Get the Resource Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetResourceDir() const {
+ return app_resource_path_;
+ }
+
+ /**
+ * @brief Get the Certs Dir object
+ *
+ * @return std::filesystem::path
+ */
+ [[nodiscard]] std::filesystem::path GetCertsDir() const {
+ return app_resource_path_ / "certs";
+ }
+
+ /**
+ * @brief Get the Cert Verifier object
+ *
+ * @return std::shared_ptr<
+ * vmime::security::cert::defaultCertificateVerifier>
+ */
+ [[nodiscard]] std::shared_ptr<
+ vmime::security::cert::defaultCertificateVerifier>
+ GetCertVerifier() const;
+
+ /**
+ * @brief
+ *
+ * @param path
+ */
+ void AddRootCert(const std::filesystem::path &path);
+
+ /**
+ * @brief Get the Root Certs object
+ *
+ * @return const std::vector<std::shared_ptr<X509>>&
+ */
+ const std::vector<std::shared_ptr<X509>> &GetRootCerts();
+
+ /**
+ * @brief
+ *
+ */
+ void ResetRootCerts() { root_certs_.clear(); }
+
+ /**
+ * @brief sync the settings to the file
+ *
+ */
+ void SyncSettings() noexcept;
+
+ private:
+ std::filesystem::path app_path_ =
+ qApp->applicationDirPath().toStdString(); ///< Program Location
+ std::filesystem::path app_data_path_ =
+ QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
+ .toStdString(); ///< Program Data Location
+ std::filesystem::path app_log_path_ =
+ app_data_path_ / "logs"; ///< Program Data Location
+ std::filesystem::path app_data_objs_path_ =
+ app_data_path_ / "objs"; ///< Object storage path
+
+#ifdef LINUX_INSTALL_BUILD
+ std::filesystem::path app_resource_path_ =
+ std::filesystem::path(APP_LOCALSTATE_PATH) /
+ "gpgfrontend"; ///< Program Data Location
+#else
+ std::filesystem::path app_resource_path_ =
+ RESOURCE_DIR_BOOST_PATH(app_path_); ///< Program Data Location
+#endif
+
+#ifdef LINUX_INSTALL_BUILD
+ std::filesystem::path app_locale_path_ =
+ std::string(APP_LOCALE_PATH); ///< Program Data Location
+#else
+ std::filesystem::path app_locale_path_ =
+ app_resource_path_ / "locales"; ///< Program Data Location
+#endif
+
+ std::filesystem::path app_configure_path_ =
+ QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)
+ .toStdString(); ///< Program Configure Location
+ std::filesystem::path ui_config_dir_path_ =
+ app_configure_path_ /
+ "UserInterface"; ///< Configure File Directory Location
+ std::filesystem::path ui_config_path_ =
+ ui_config_dir_path_ / "ui.cfg"; ///< UI Configure File Location
+
+ libconfig::Config ui_cfg_; ///<
+ std::vector<std::shared_ptr<X509>> root_certs_; ///<
+
+ /**
+ * @brief
+ *
+ */
+ void init_app_secure_key();
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GLOBALSETTINGSTATION_H
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp
new file mode 100644
index 00000000..2b2802f7
--- /dev/null
+++ b/src/core/function/KeyPackageOperator.cpp
@@ -0,0 +1,120 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "KeyPackageOperator.h"
+
+#include "FileOperator.h"
+#include "function/PassphraseGenerator.h"
+#include "function/gpg/GpgKeyGetter.h"
+#include "function/gpg/GpgKeyImportExporter.h"
+#include "qt-aes/qaesencryption.h"
+
+namespace GpgFrontend {
+
+bool KeyPackageOperator::GeneratePassphrase(
+ const std::filesystem::path& phrase_path, std::string& phrase) {
+ phrase = PassphraseGenerator::GetInstance().Generate(256);
+ LOG(INFO) << "Generated passphrase: " << phrase.size() << " bytes";
+ return FileOperator::WriteFileStd(phrase_path, phrase);
+}
+
+bool KeyPackageOperator::GenerateKeyPackage(
+ const std::filesystem::path& key_package_path,
+ const std::string& key_package_name, KeyIdArgsListPtr& key_ids,
+ std::string& phrase, bool secret) {
+ LOG(INFO) << "Generating key package: " << key_package_name;
+
+ ByteArrayPtr key_export_data = nullptr;
+ if (!GpgKeyImportExporter::GetInstance().ExportKeys(key_ids, key_export_data,
+ secret)) {
+ LOG(ERROR) << "Failed to export keys";
+ return false;
+ }
+
+ auto key = QByteArray::fromStdString(phrase);
+ auto data = QString::fromStdString(*key_export_data).toLocal8Bit().toBase64();
+
+ auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256);
+ QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
+ QAESEncryption::Padding::ISO);
+ auto encoded = encryption.encode(data, hash_key);
+
+ LOG(INFO) << "Writing key package: " << key_package_name;
+ return FileOperator::WriteFileStd(key_package_path, encoded.toStdString());
+}
+
+bool KeyPackageOperator::ImportKeyPackage(
+ const std::filesystem::path& key_package_path,
+ const std::filesystem::path& phrase_path,
+ GpgFrontend::GpgImportInformation& import_info) {
+
+ LOG(INFO) << "Importing key package: " << key_package_path.string();
+
+ std::string encrypted_data;
+ FileOperator::ReadFileStd(key_package_path, encrypted_data);
+
+ if (encrypted_data.empty()) {
+ LOG(ERROR) << "Failed to read key package: " << key_package_path.string();
+ return false;
+ };
+
+ std::string passphrase;
+ FileOperator::ReadFileStd(phrase_path, passphrase);
+ LOG(INFO) << "Passphrase: " << passphrase.size() << " bytes";
+ if (passphrase.size() != 256) {
+ LOG(ERROR) << "Failed to read passphrase: " << phrase_path.string();
+ return false;
+ }
+
+ auto hash_key = QCryptographicHash::hash(
+ QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256);
+ auto encoded = QByteArray::fromStdString(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);
+
+ LOG(INFO) << "key data" << key_data.size();
+ if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) &&
+ !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) {
+ return false;
+ }
+
+ auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString());
+ import_info =
+ GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr));
+ return true;
+}
+
+std::string KeyPackageOperator::GenerateKeyPackageName() {
+ return generate_key_package_name();
+}
+
+} // namespace GpgFrontend
diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h
new file mode 100644
index 00000000..cd344688
--- /dev/null
+++ b/src/core/function/KeyPackageOperator.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_KEYPACKAGEOPERATOR_H
+#define GPGFRONTEND_KEYPACKAGEOPERATOR_H
+
+#include "core/GpgFrontendCore.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief give the possibility to import or export a key package
+ *
+ */
+class KeyPackageOperator {
+ public:
+ /**
+ * @brief generate passphrase for key package and save it to file
+ *
+ * @param phrase_path path to passphrase file
+ * @param phrase passphrase generated
+ * @return true if passphrase was generated and saved
+ * @return false if passphrase was not generated and saved
+ */
+ static bool GeneratePassphrase(const std::filesystem::path &phrase_path,
+ std::string &phrase);
+
+ /**
+ * @brief generate the name of the key package
+ *
+ * @return std::string name of the key package
+ */
+ static std::string GenerateKeyPackageName();
+
+ /**
+ * @brief generate key package
+ *
+ * @param key_package_path path to key package
+ * @param key_package_name name of the key package
+ * @param key_ids key ids to export
+ * @param phrase passphrase to encrypt key package
+ * @param secret true if secret key should be exported
+ * @return true if key package was generated
+ * @return false if key package was not generated
+ */
+ static bool GenerateKeyPackage(const std::filesystem::path &key_package_path,
+ const std::string &key_package_name,
+ KeyIdArgsListPtr &key_ids, std::string &phrase,
+ bool secret);
+
+ /**
+ * @brief import key package
+ *
+ * @param key_package_path path to key package
+ * @param phrase_path path to passphrase file
+ * @param import_info import info
+ * @return true if key package was imported
+ * @return false if key package was not imported
+ */
+ static bool ImportKeyPackage(const std::filesystem::path &key_package_path,
+ const std::filesystem::path &phrase_path,
+ GpgFrontend::GpgImportInformation &import_info);
+
+ private:
+ /**
+ * @brief generate key package name
+ *
+ * @return std::string key package name
+ */
+ static std::string generate_key_package_name() {
+ std::random_device rd_; ///< Random device
+ auto mt_ = std::mt19937(rd_()); ///< Mersenne twister
+
+ std::uniform_int_distribution<int> dist(999, 99999);
+ auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
+ return file_string.str();
+ }
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_KEYPACKAGEOPERATOR_H
diff --git a/src/core/function/PassphraseGenerator.cpp b/src/core/function/PassphraseGenerator.cpp
new file mode 100644
index 00000000..0267edda
--- /dev/null
+++ b/src/core/function/PassphraseGenerator.cpp
@@ -0,0 +1,29 @@
+/**
+* Copyright (C) 2021 Saturneric
+*
+* 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 "PassphraseGenerator.h"
diff --git a/src/core/function/PassphraseGenerator.h b/src/core/function/PassphraseGenerator.h
new file mode 100644
index 00000000..d1cc7607
--- /dev/null
+++ b/src/core/function/PassphraseGenerator.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_PASSPHRASEGENERATOR_H
+#define GPGFRONTEND_PASSPHRASEGENERATOR_H
+
+#include "core/GpgFrontendCore.h"
+#include "core/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief The PassphraseGenerator class
+ *
+ * This class is used to generate a passphrase.
+ */
+class PassphraseGenerator
+ : public SingletonFunctionObject<PassphraseGenerator> {
+ public:
+ /**
+ * @brief PassphraseGenerator constructor
+ *
+ * @param channel The channel to use
+ */
+ explicit PassphraseGenerator(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<PassphraseGenerator>(channel) {}
+
+ /**
+ * @brief generate passphrase
+ *
+ * @param len length of the passphrase
+ * @return std::string passphrase
+ */
+ std::string Generate(int len) {
+ std::uniform_int_distribution<int> dist(999, 99999);
+
+ auto file_string = boost::format("KeyPackage_%1%") % dist(mt_);
+ static const char alphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ std::string tmp_str;
+ tmp_str.reserve(len);
+
+ for (int i = 0; i < len; ++i) {
+ tmp_str += alphanum[dist(mt_) % (sizeof(alphanum) - 1)];
+ }
+ return tmp_str;
+ }
+
+ std::random_device rd_; ///< Random device
+ std::mt19937 mt_ = std::mt19937(rd_()); ///< Mersenne twister
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_PASSPHRASEGENERATOR_H
diff --git a/src/core/function/aes/aes_ssl.h b/src/core/function/aes/aes_ssl.h
new file mode 100644
index 00000000..b5f0820f
--- /dev/null
+++ b/src/core/function/aes/aes_ssl.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_AES_SSL_H
+#define GPGFRONTEND_AES_SSL_H
+
+#include "GpgFrontend.h"
+
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+
+namespace GpgFrontend::RawAPI {
+
+/**
+ * @brief
+ *
+ * @param key_data
+ * @param key_data_len
+ * @param salt
+ * @param e_ctx
+ * @param d_ctx
+ * @return int
+ */
+int aes_256_cbc_init(uint8_t *key_data, int key_data_len, uint8_t *salt,
+ EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx);
+
+/**
+ * @brief
+ *
+ * @param e
+ * @param plaintext
+ * @param len
+ * @return uint8_t*
+ */
+uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len);
+
+/**
+ * @brief
+ *
+ * @param e
+ * @param ciphertext
+ * @param len
+ * @return uint8_t*
+ */
+uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len);
+
+} // namespace GpgFrontend::RawAPI
+
+#endif // GPGFRONTEND_AES_SSL_H
diff --git a/src/core/function/aes/aes_ssl_cbc.cpp b/src/core/function/aes/aes_ssl_cbc.cpp
new file mode 100644
index 00000000..95ae0ce2
--- /dev/null
+++ b/src/core/function/aes/aes_ssl_cbc.cpp
@@ -0,0 +1,99 @@
+/**
+ * AES encryption/decryption demo program using OpenSSL EVP apis
+ * gcc -Wall openssl_aes.c -lcrypto
+ * this is public domain code.
+ * Saju Pillai ([email protected])
+ **/
+
+#include "aes_ssl.h"
+
+namespace GpgFrontend::RawAPI {
+
+/**
+ * @brief Create a 256 bit key and IV using the supplied key_data. salt can be
+ * added for taste. Fills in the encryption and decryption ctx objects and
+ * returns 0 on success
+ *
+ * @param key_data
+ * @param key_data_len
+ * @param salt
+ * @param e_ctx
+ * @param d_ctx
+ * @return int
+ */
+int aes_256_cbc_init(uint8_t *key_data, int key_data_len, uint8_t *salt,
+ EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx) {
+ int i, nrounds = 5;
+ uint8_t key[32], iv[32];
+
+ /*
+ * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the
+ * supplied key material. nrounds is the number of times the we hash the
+ * material. More rounds are more secure but slower.
+ */
+ i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data,
+ key_data_len, nrounds, key, iv);
+ if (i != 32) {
+ printf("Key size is %d bits - should be 256 bits\n", i);
+ return -1;
+ }
+
+ EVP_CIPHER_CTX_init(e_ctx);
+ EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
+ EVP_CIPHER_CTX_init(d_ctx);
+ EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv);
+
+ return 0;
+}
+
+/**
+ * @brief Encrypt *len bytes of data All data going in & out is considered
+ * binary (uint8_t[])
+ *
+ * @param e
+ * @param plaintext
+ * @param len
+ * @return uint8_t*
+ */
+uint8_t *aes_256_cbc_encrypt(EVP_CIPHER_CTX *e, uint8_t *plaintext, int *len) {
+ /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1
+ * bytes */
+ int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
+ auto *ciphertext = (uint8_t *)malloc(c_len);
+
+ /* allows reusing of 'e' for multiple encryption cycles */
+ EVP_EncryptInit_ex(e, nullptr, nullptr, nullptr, nullptr);
+
+ /* update ciphertext, c_len is filled with the length of ciphertext generated,
+ *len is the size of plaintext in bytes */
+ EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len);
+
+ /* update ciphertext with the final remaining bytes */
+ EVP_EncryptFinal_ex(e, ciphertext + c_len, &f_len);
+
+ *len = c_len + f_len;
+ return ciphertext;
+}
+
+/**
+ * @brief Decrypt *len bytes of ciphertext
+ *
+ * @param e
+ * @param ciphertext
+ * @param len
+ * @return uint8_t*
+ */
+uint8_t *aes_256_cbc_decrypt(EVP_CIPHER_CTX *e, uint8_t *ciphertext, int *len) {
+ /* plaintext will always be equal to or lesser than length of ciphertext*/
+ int p_len = *len, f_len = 0;
+ auto *plaintext = (uint8_t *)malloc(p_len);
+
+ EVP_DecryptInit_ex(e, nullptr, nullptr, nullptr, nullptr);
+ EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
+ EVP_DecryptFinal_ex(e, plaintext + p_len, &f_len);
+
+ *len = p_len + f_len;
+ return plaintext;
+}
+
+} // namespace GpgFrontend::RawAPI \ No newline at end of file
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
new file mode 100644
index 00000000..b92404a9
--- /dev/null
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -0,0 +1,220 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgBasicOperator.h"
+
+#include <vector>
+
+#include "GpgKeyGetter.h"
+
+GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Encrypt(
+ KeyListPtr keys, GpgFrontend::BypeArrayRef in_buffer,
+ GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) {
+ // gpgme_encrypt_result_t e_result;
+ gpgme_key_t recipients[keys->size() + 1];
+
+ int index = 0;
+ for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+
+ // Last entry data_in array has to be nullptr
+ recipients[keys->size()] = nullptr;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
+ ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Decrypt(
+ BypeArrayRef in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
+ GpgFrontend::GpgDecrResult& result) {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+ err = check_gpg_error(gpgme_op_decrypt(ctx_, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_result = _new_result(gpgme_op_decrypt_result(ctx_));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Verify(
+ BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
+ GpgVerifyResult& result) const {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size());
+ GpgData data_out;
+
+ if (sig_buffer != nullptr) {
+ GpgData sig_data(sig_buffer->data(), sig_buffer->size());
+ err = check_gpg_error(gpgme_op_verify(ctx_, sig_data, data_in, nullptr));
+ } else
+ err = check_gpg_error(gpgme_op_verify(ctx_, data_in, nullptr, data_out));
+
+ auto temp_result = _new_result(gpgme_op_verify_result(ctx_));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgBasicOperator::Sign(KeyListPtr signers,
+ BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer,
+ gpgme_sig_mode_t mode,
+ GpgSignResult& result) {
+ gpgme_error_t err;
+
+ // Set Singers of this opera
+ SetSigners(*signers);
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ err = check_gpg_error(gpgme_op_sign(ctx_, data_in, data_out, mode));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_result = _new_result(gpgme_op_sign_result(ctx_));
+
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgBasicOperator::DecryptVerify(
+ BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ err = check_gpg_error(gpgme_op_decrypt_verify(ctx_, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_decr_result = _new_result(gpgme_op_decrypt_result(ctx_));
+ std::swap(decrypt_result, temp_decr_result);
+
+ auto temp_verify_result = _new_result(gpgme_op_verify_result(ctx_));
+ std::swap(verify_result, temp_verify_result);
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgBasicOperator::EncryptSign(
+ KeyListPtr keys, KeyListPtr signers, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, GpgEncrResult& encr_result,
+ GpgSignResult& sign_result) {
+ gpgme_error_t err;
+ SetSigners(*signers);
+
+ // gpgme_encrypt_result_t e_result;
+ gpgme_key_t recipients[keys->size() + 1];
+
+ // set key for user
+ int index = 0;
+ for (const auto& key : *keys) recipients[index++] = gpgme_key_t(key);
+
+ // Last entry dataIn array has to be nullptr
+ recipients[keys->size()] = nullptr;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ // If the last parameter isnt 0, a private copy of data is made
+ err = check_gpg_error(gpgme_op_encrypt_sign(
+ ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ auto temp_encr_result = _new_result(gpgme_op_encrypt_result(ctx_));
+ swap(encr_result, temp_encr_result);
+ auto temp_sign_result = _new_result(gpgme_op_sign_result(ctx_));
+ swap(sign_result, temp_sign_result);
+
+ return err;
+}
+
+void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
+ gpgme_signers_clear(ctx_);
+ for (const GpgKey& key : signers) {
+ DLOG(INFO) << "key" << key.GetFingerprint();
+ if (key.IsHasActualSigningCapability()) {
+ DLOG(INFO) << "signer";
+ auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
+ check_gpg_error(error);
+ }
+ }
+ if (signers.size() != gpgme_signers_count(ctx_))
+ DLOG(INFO) << "No All Signers Added";
+}
+
+std::unique_ptr<GpgFrontend::KeyArgsList>
+GpgFrontend::GpgBasicOperator::GetSigners() {
+ 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_, i));
+ signers->push_back(GpgKey(std::move(key)));
+ }
+ return signers;
+}
+
+gpg_error_t GpgFrontend::GpgBasicOperator::EncryptSymmetric(
+ GpgFrontend::ByteArray& in_buffer, GpgFrontend::ByteArrayPtr& out_buffer,
+ GpgFrontend::GpgEncrResult& result) {
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ gpgme_error_t err = check_gpg_error(gpgme_op_encrypt(
+ ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+
+ auto temp_data_out = data_out.Read2Buffer();
+ std::swap(temp_data_out, out_buffer);
+
+ // TODO(Saturneric): maybe a bug of gpgme
+ if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
+ auto temp_result = _new_result(gpgme_op_encrypt_result(ctx_));
+ std::swap(result, temp_result);
+ }
+
+ return err;
+}
diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h
new file mode 100644
index 00000000..9b9d9f63
--- /dev/null
+++ b/src/core/function/gpg/GpgBasicOperator.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+
+#include "core/GpgConstants.h"
+#include "core/GpgContext.h"
+#include "core/GpgFunctionObject.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief Basic operation collection
+ *
+ */
+class GpgBasicOperator : public SingletonFunctionObject<GpgBasicOperator> {
+ public:
+ /**
+ * @brief Construct a new Basic Operator object
+ *
+ * @param channel Channel corresponding to the context
+ */
+ explicit GpgBasicOperator(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgBasicOperator>(channel) {}
+
+ /**
+ * @brief Call the interface provided by gpgme for encryption operation
+ *
+ * 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
+ */
+ gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, GpgEncrResult& result);
+
+ /**
+ * @brief Call the interface provided by GPGME to symmetrical encryption
+ *
+ * @param in_buffer Data for encryption
+ * @param out_buffer Encrypted data
+ * @param result Encrypted results
+ * @return gpg_error_t
+ */
+ gpg_error_t EncryptSymmetric(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgEncrResult& result);
+
+ /**
+ *
+ * @brief Call the interface provided by gpgme to perform encryption and
+ * signature operations at the same time.
+ *
+ * @param keys List of public keys
+ * @param signers Private key for signatures
+ * @param in_buffer Data for operation
+ * @param out_buffer Encrypted data
+ * @param encr_result Encrypted results
+ * @param sign_result Signature result
+ * @return
+ */
+ gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
+ BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgEncrResult& encr_result,
+ GpgSignResult& sign_result);
+
+ /**
+ * @brief Call the interface provided by gpgme for decryption operation
+ *
+ * @param in_buffer data that needs to be decrypted
+ * @param out_buffer decrypted data
+ * @param result the result of the operation
+ * @return error code
+ */
+ gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& result);
+
+ /**
+ * @brief Call the interface provided by gpgme to perform decryption and
+ * verification operations at the same time.
+ *
+ * @param in_buffer data to be manipulated
+ * @param out_buffer data resulting from decryption operation
+ * @param decrypt_result the result of the decrypting operation
+ * @param verify_result the result of the verifying operation
+ * @return error code
+ */
+ gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& decrypt_result,
+ GpgVerifyResult& verify_result);
+
+ /**
+ * @brief Call the interface provided by gpgme for verification operation
+ *
+ * @param in_buffer data that needs to be verified
+ * @param out_buffer verified data
+ * @param result the result of the operation
+ * @return error code
+ */
+ gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
+ GpgVerifyResult& result) const;
+
+ /**
+ * @brief Call the interface provided by gpgme for signing operation
+ *
+ * The signing modes are as follows:
+ * `GPGME_SIG_MODE_NORMAL'
+ * A normal signature is made, the output includes the plaintext and the
+ * signature.
+ * `GPGME_SIG_MODE_DETACH'
+ * A detached signature is made.
+ * `GPGME_SIG_MODE_CLEAR'
+ * A clear text signature is made. The ASCII armor and text mode settings
+ * of the context are ignored.
+ *
+ * @param signers private keys for signing operations
+ * @param in_buffer data that needs to be signed
+ * @param out_buffer verified data
+ * @param mode signing mode
+ * @param result the result of the operation
+ * @return error code
+ */
+ gpg_error_t Sign(KeyListPtr signers, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
+ GpgSignResult& result);
+
+ /**
+ * @brief Set the private key for signatures, this operation is a global
+ * operation.
+ *
+ * @param keys
+ */
+ void SetSigners(KeyArgsList& signers);
+
+ /**
+ * @brief Get a global signature private keys that has been set.
+ *
+ * @return Intelligent pointer pointing to the private key list
+ */
+ std::unique_ptr<KeyArgsList> GetSigners();
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
new file mode 100644
index 00000000..a6a67d08
--- /dev/null
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgCommandExecutor.h"
+#ifndef WINDOWS
+#include <boost/asio.hpp>
+#endif
+
+#ifndef WINDOWS
+
+using boost::process::async_pipe;
+
+void GpgFrontend::GpgCommandExecutor::Execute(
+ StringArgsRef arguments,
+ const std::function<void(async_pipe& in, async_pipe& out)>& interact_func) {
+ using namespace boost::process;
+
+ boost::asio::io_service ios;
+
+ std::vector<char> buf;
+
+ async_pipe in_pipe_stream(ios);
+ async_pipe out_pipe_stream(ios);
+
+ child child_process(ctx_.GetInfo().AppPath.c_str(), arguments,
+ std_out > in_pipe_stream, std_in < out_pipe_stream);
+
+ boost::asio::async_read(
+ in_pipe_stream, boost::asio::buffer(buf),
+ [&](const boost::system::error_code& ec, std::size_t size) {
+ interact_func(in_pipe_stream, out_pipe_stream);
+ });
+
+ ios.run();
+ child_process.wait();
+ child_process.exit_code();
+}
+
+#endif
diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h
new file mode 100644
index 00000000..49baf406
--- /dev/null
+++ b/src/core/function/gpg/GpgCommandExecutor.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+
+#ifndef WINDOWS
+#include <boost/process.hpp>
+#endif
+
+#include "core/GpgContext.h"
+#include "core/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief Extra commands related to GPG
+ *
+ */
+class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> {
+ public:
+ /**
+ * @brief Construct a new Gpg Command Executor object
+ *
+ * @param channel Corresponding context
+ */
+ explicit GpgCommandExecutor(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgCommandExecutor>(channel) {}
+
+#ifndef WINDOWS
+
+ /**
+ * @brief Excuting an order
+ *
+ * @param arguments Command parameters
+ * @param interact_func Command answering function
+ */
+ void Execute(StringArgsRef arguments,
+ const std::function<void(boost::process::async_pipe &in,
+ boost::process::async_pipe &out)>
+ &interact_func);
+#endif
+
+ private:
+ GpgContext &ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
new file mode 100644
index 00000000..7044353b
--- /dev/null
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -0,0 +1,182 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgFileOpera.h"
+
+#include <memory>
+#include <string>
+
+#include "GpgConstants.h"
+#include "GpgBasicOperator.h"
+#include "function/FileOperator.h"
+
+GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
+ KeyListPtr keys, const std::string& in_path, const std::string& out_path,
+ GpgEncrResult& result, int _channel) {
+
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(in_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+ std::unique_ptr<std::string> out_buffer = nullptr;
+
+ auto err = GpgBasicOperator::GetInstance(_channel).Encrypt(
+ std::move(keys), in_buffer, out_buffer, result);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!FileOperator::WriteFileStd(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
+ const std::string& in_path, const std::string& out_path,
+ GpgDecrResult& result) {
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(in_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err =
+ GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
+
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!FileOperator::WriteFileStd(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
+ const std::string& in_path,
+ const std::string& out_path,
+ GpgSignResult& result,
+ int _channel) {
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(in_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err = GpgBasicOperator::GetInstance(_channel).Sign(
+ std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!FileOperator::WriteFileStd(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(
+ const std::string& data_path, const std::string& sign_path,
+ GpgVerifyResult& result, int _channel) {
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(data_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+ std::unique_ptr<std::string> sign_buffer = nullptr;
+ if (!sign_path.empty()) {
+ std::string sign_buffer_str;
+ if (!FileOperator::ReadFileStd(sign_path, sign_buffer_str)) {
+ throw std::runtime_error("read file error");
+ }
+ sign_buffer =
+ std::make_unique<std::string>(sign_buffer_str);
+ }
+ auto err = GpgBasicOperator::GetInstance(_channel).Verify(in_buffer, sign_buffer,
+ result);
+ return err;
+}
+
+gpg_error_t 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) {
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(in_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+ std::unique_ptr<std::string> 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 (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!FileOperator::WriteFileStd(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
+ const std::string& in_path, const std::string& out_path,
+ GpgDecrResult& decr_res, GpgVerifyResult& verify_res) {
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(in_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+
+ std::unique_ptr<std::string> out_buffer = nullptr;
+ auto err = GpgBasicOperator::GetInstance().DecryptVerify(in_buffer, out_buffer,
+ decr_res, verify_res);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!FileOperator::WriteFileStd(out_path, *out_buffer)) {
+ throw std::runtime_error("write file error");
+ };
+
+ return err;
+}
+unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric(
+ const std::string& in_path, const std::string& out_path,
+ GpgFrontend::GpgEncrResult& result, int _channel) {
+ std::string in_buffer;
+ if(!FileOperator::ReadFileStd(in_path, in_buffer)) {
+ throw std::runtime_error("read file error");
+ }
+
+ std::unique_ptr<std::string> out_buffer;
+ auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric(
+ in_buffer, out_buffer, result);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!FileOperator::WriteFileStd(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h
new file mode 100644
index 00000000..f21bf04c
--- /dev/null
+++ b/src/core/function/gpg/GpgFileOpera.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGFILEOPERA_H
+#define GPGFRONTEND_GPGFILEOPERA_H
+
+#include "core/GpgConstants.h"
+#include "core/GpgContext.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief Executive files related to the basic operations that are provided by
+ * GpgBasicOperator
+ * @class class: GpgBasicOperator
+ */
+class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> {
+ public:
+ explicit GpgFileOpera(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgFileOpera>(channel) {}
+
+ /**
+ * @brief Encrypted file
+ *
+ * @param keys Used public key
+ * @param in_path The path where the enter file is located
+ * @param out_path The path where the output file is located
+ * @param result Encrypted results
+ * @param _channel Channel in context
+ * @return unsigned int error code
+ */
+ static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path,
+ const std::string& out_path,
+ GpgEncrResult& result,
+ int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+
+ /**
+ * @brief 运用对称加密算法加密文件
+ *
+ * @param in_path
+ * @param out_path
+ * @param result
+ * @param _channel
+ * @return unsigned int
+ */
+ static unsigned int EncryptFileSymmetric(
+ const std::string& in_path, const std::string& out_path,
+ GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param result
+ * @return GpgError
+ */
+ static GpgError DecryptFile(const std::string& in_path,
+ const std::string& out_path,
+ GpgDecrResult& result);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param in_path
+ * @param out_path
+ * @param result
+ * @param _channel
+ * @return GpgError
+ */
+ static GpgError SignFile(KeyListPtr keys, const std::string& in_path,
+ const std::string& out_path, GpgSignResult& result,
+ int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+
+ /**
+ * @brief
+ *
+ * @param data_path
+ * @param sign_path
+ * @param result
+ * @param _channel
+ * @return GpgError
+ */
+ static GpgError VerifyFile(const std::string& data_path,
+ const std::string& sign_path,
+ GpgVerifyResult& result,
+ int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param signer_keys
+ * @param in_path
+ * @param out_path
+ * @param encr_res
+ * @param sign_res
+ * @param _channel
+ * @return GpgError
+ */
+ static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
+ const std::string& in_path,
+ const std::string& out_path,
+ GpgEncrResult& encr_res,
+ GpgSignResult& sign_res,
+ int _channel = GPGFRONTEND_DEFAULT_CHANNEL);
+
+ /**
+ * @brief
+ *
+ * @param in_path
+ * @param out_path
+ * @param decr_res
+ * @param verify_res
+ * @return GpgError
+ */
+ static GpgError DecryptVerifyFile(const std::string& in_path,
+ const std::string& out_path,
+ GpgDecrResult& decr_res,
+ GpgVerifyResult& verify_res);
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
new file mode 100644
index 00000000..1a4715e7
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgKeyGetter.h"
+
+#include <gpg-error.h>
+
+#include "GpgConstants.h"
+
+GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) {
+ gpgme_key_t _p_key = nullptr;
+ gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 1);
+ if (_p_key == nullptr) {
+ DLOG(WARNING) << "GpgKeyGetter GetKey Private _p_key Null fpr" << fpr;
+ return GetPubkey(fpr);
+ } else {
+ return GpgKey(std::move(_p_key));
+ }
+}
+
+GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey(
+ const std::string& fpr) {
+ gpgme_key_t _p_key = nullptr;
+ gpgme_get_key(ctx_, fpr.c_str(), &_p_key, 0);
+ if (_p_key == nullptr)
+ DLOG(WARNING) << "GpgKeyGetter GetKey _p_key Null" << fpr;
+ return GpgKey(std::move(_p_key));
+}
+
+GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() {
+ gpgme_error_t err;
+
+ auto keys_list = std::make_unique<GpgKeyLinkList>();
+
+ err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+
+ gpgme_key_t key;
+ while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
+ keys_list->push_back(GetKey(key->fpr));
+ }
+
+ assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx_);
+
+ assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
+
+ return keys_list;
+}
+
+GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys(
+ const KeyIdArgsListPtr& ids) {
+ auto keys = std::make_unique<KeyArgsList>();
+ for (const auto& id : *ids) keys->push_back(GetKey(id));
+ return keys;
+}
+
+GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
+ const GpgFrontend::KeyLinkListPtr& keys) {
+ auto keys_copy = std::make_unique<GpgKeyLinkList>();
+ for (const auto& key : *keys) keys_copy->push_back(key.Copy());
+ return keys_copy;
+}
+
+GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeysCopy(
+ const GpgFrontend::KeyListPtr& keys) {
+ auto keys_copy = std::make_unique<KeyArgsList>();
+ for (const auto& key : *keys) keys_copy->push_back(key.Copy());
+ return keys_copy;
+}
diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h
new file mode 100644
index 00000000..cde027a0
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyGetter.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+
+#include "core/GpgContext.h"
+#include "core/GpgFunctionObject.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> {
+ public:
+ /**
+ * @brief Construct a new Gpg Key Getter object
+ *
+ * @param channel
+ */
+ explicit GpgKeyGetter(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgKeyGetter>(channel) {}
+
+ /**
+ * @brief Get the Key object
+ *
+ * @param fpr
+ * @return GpgKey
+ */
+ GpgKey GetKey(const std::string& fpr);
+
+ /**
+ * @brief Get the Keys object
+ *
+ * @param ids
+ * @return KeyListPtr
+ */
+ KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+
+ /**
+ * @brief Get the Pubkey object
+ *
+ * @param fpr
+ * @return GpgKey
+ */
+ GpgKey GetPubkey(const std::string& fpr);
+
+ /**
+ * @brief
+ *
+ * @return KeyLinkListPtr
+ */
+ KeyLinkListPtr FetchKey();
+
+ /**
+ * @brief Get the Keys Copy object
+ *
+ * @param keys
+ * @return KeyListPtr
+ */
+ static KeyListPtr GetKeysCopy(const KeyListPtr& keys);
+
+ /**
+ * @brief Get the Keys Copy object
+ *
+ * @param keys
+ * @return KeyLinkListPtr
+ */
+ static KeyLinkListPtr GetKeysCopy(const KeyLinkListPtr& keys);
+
+ private:
+ /**
+ * @brief
+ *
+ */
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel());
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
new file mode 100644
index 00000000..0f1ebfa2
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -0,0 +1,178 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgKeyImportExporter.h"
+
+#include "GpgConstants.h"
+#include "GpgKeyGetter.h"
+
+/**
+ * Import key pair
+ * @param inBuffer input byte array
+ * @return Import information
+ */
+GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey(
+ StdBypeArrayPtr in_buffer) {
+ if (in_buffer->empty()) return {};
+
+ GpgData data_in(in_buffer->data(), in_buffer->size());
+ auto err = check_gpg_error(gpgme_op_import(ctx_, data_in));
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
+
+ gpgme_import_result_t result;
+ result = gpgme_op_import_result(ctx_);
+ gpgme_import_status_t status = result->imports;
+ auto import_info = std::make_unique<GpgImportInformation>(result);
+ while (status != nullptr) {
+ GpgImportedKey key;
+ key.import_status = static_cast<int>(status->status);
+ key.fpr = status->fpr;
+ import_info->importedKeys.emplace_back(key);
+ status = status->next;
+ }
+
+ return *import_info;
+}
+
+/**
+ * Export Key
+ * @param uid_list key ids
+ * @param out_buffer output byte array
+ * @return if success
+ */
+bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
+ ByteArrayPtr& out_buffer,
+ bool secret) const {
+ if (uid_list->empty()) return false;
+
+ int _mode = 0;
+ if (secret) _mode |= GPGME_EXPORT_MODE_SECRET;
+
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list);
+ auto keys_array = new gpgme_key_t[keys->size() + 1];
+
+ int index = 0;
+ for (const auto& key : *keys) {
+ keys_array[index++] = gpgme_key_t(key);
+ }
+ keys_array[index] = nullptr;
+
+ GpgData data_out;
+ auto err = gpgme_op_export_keys(ctx_, keys_array, _mode, data_out);
+ if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
+
+ delete[] keys_array;
+
+ DLOG(INFO) << "exportKeys read_bytes"
+ << gpgme_data_seek(data_out, 0, SEEK_END);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+
+ swap(temp_out_buffer, out_buffer);
+
+ return true;
+}
+
+/**
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
+ * @return if success
+ */
+bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys,
+ ByteArrayPtr& out_buffer,
+ bool secret) const {
+ KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
+ for (const auto& key : keys) key_ids->push_back(key.GetId());
+ return ExportKeys(key_ids, out_buffer, secret);
+}
+
+/**
+ * Export the secret key of a key pair(including subkeys)
+ * @param key target key pair
+ * @param outBuffer output byte array
+ * @return if successful
+ */
+bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey(
+ const GpgKey& key, ByteArrayPtr& out_buffer) const {
+ DLOG(INFO) << "Export Secret Key" << key.GetId().c_str();
+
+ gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr};
+
+ GpgData data_out;
+ // export private key to outBuffer
+ gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key,
+ GPGME_EXPORT_MODE_SECRET, data_out);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+ std::swap(out_buffer, temp_out_buffer);
+
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
+
+bool GpgFrontend::GpgKeyImportExporter::ExportKey(
+ const GpgFrontend::GpgKey& key,
+ GpgFrontend::ByteArrayPtr& out_buffer) const {
+ GpgData data_out;
+ auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
+
+ DLOG(INFO) << "exportKeys read_bytes"
+ << gpgme_data_seek(data_out, 0, SEEK_END);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+ std::swap(out_buffer, temp_out_buffer);
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
+
+bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH(
+ const GpgFrontend::GpgKey& key,
+ GpgFrontend::ByteArrayPtr& out_buffer) const {
+ GpgData data_out;
+ auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
+ data_out);
+
+ DLOG(INFO) << "read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+ std::swap(out_buffer, temp_out_buffer);
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
+
+bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest(
+ const GpgFrontend::GpgKey& key,
+ GpgFrontend::ByteArrayPtr& out_buffer) const {
+ GpgData data_out;
+ auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
+ GPGME_EXPORT_MODE_MINIMAL, data_out);
+
+ DLOG(INFO) << "read_bytes" << gpgme_data_seek(data_out, 0, SEEK_END);
+
+ auto temp_out_buffer = data_out.Read2Buffer();
+ std::swap(out_buffer, temp_out_buffer);
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h
new file mode 100644
index 00000000..d7e6deae
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyImportExporter.h
@@ -0,0 +1,195 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef _GPGKEYIMPORTEXPORTOR_H
+#define _GPGKEYIMPORTEXPORTOR_H
+
+#include <string>
+
+#include "core/GpgConstants.h"
+#include "core/GpgContext.h"
+#include "core/GpgFunctionObject.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GpgImportedKey {
+ public:
+ std::string fpr; ///<
+ int import_status; ///<
+};
+
+typedef std::list<GpgImportedKey> GpgImportedKeyList; ///<
+
+/**
+ * @brief
+ *
+ */
+class GpgImportInformation {
+ public:
+ GpgImportInformation() = default;
+
+ /**
+ * @brief Construct a new Gpg Import Information object
+ *
+ * @param result
+ */
+ explicit GpgImportInformation(gpgme_import_result_t result) {
+ if (result->unchanged) unchanged = result->unchanged;
+ if (result->considered) considered = result->considered;
+ if (result->no_user_id) no_user_id = result->no_user_id;
+ if (result->imported) imported = result->imported;
+ if (result->imported_rsa) imported_rsa = result->imported_rsa;
+ if (result->unchanged) unchanged = result->unchanged;
+ if (result->new_user_ids) new_user_ids = result->new_user_ids;
+ if (result->new_sub_keys) new_sub_keys = result->new_sub_keys;
+ if (result->new_signatures) new_signatures = result->new_signatures;
+ if (result->new_revocations) new_revocations = result->new_revocations;
+ if (result->secret_read) secret_read = result->secret_read;
+ if (result->secret_imported) secret_imported = result->secret_imported;
+ if (result->secret_unchanged) secret_unchanged = result->secret_unchanged;
+ if (result->not_imported) not_imported = result->not_imported;
+ }
+
+ int considered = 0; ///<
+ int no_user_id = 0; ///<
+ int imported = 0; ///<
+ int imported_rsa = 0; ///<
+ int unchanged = 0; ///<
+ int new_user_ids = 0; ///<
+ int new_sub_keys = 0; ///<
+ int new_signatures = 0; ///<
+ int new_revocations = 0; ///<
+ int secret_read = 0; ///<
+ int secret_imported = 0; ///<
+ int secret_unchanged = 0; ///<
+ int not_imported = 0; ///<
+ GpgImportedKeyList importedKeys; ///<
+};
+
+/**
+ * @brief
+ *
+ */
+class GpgKeyImportExporter
+ : public SingletonFunctionObject<GpgKeyImportExporter> {
+ public:
+ /**
+ * @brief Construct a new Gpg Key Import Exporter object
+ *
+ * @param channel
+ */
+ explicit GpgKeyImportExporter(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgKeyImportExporter>(channel) {}
+
+ /**
+ * @brief
+ *
+ * @param inBuffer
+ * @return GpgImportInformation
+ */
+ GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+
+ /**
+ * @brief
+ *
+ * @param uid_list
+ * @param out_buffer
+ * @param secret
+ * @return true
+ * @return false
+ */
+ bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer,
+ bool secret = false) const;
+
+ /**
+ * @brief
+ *
+ * @param keys
+ * @param outBuffer
+ * @param secret
+ * @return true
+ * @return false
+ */
+ bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer,
+ bool secret = false) const;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param out_buffer
+ * @return true
+ * @return false
+ */
+ bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param out_buffer
+ * @return true
+ * @return false
+ */
+ bool ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param outBuffer
+ * @return true
+ * @return false
+ */
+ bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param outBuffer
+ * @return true
+ * @return false
+ */
+ bool ExportSecretKeyShortest(const GpgKey& key,
+ ByteArrayPtr& outBuffer) const;
+
+ private:
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
new file mode 100644
index 00000000..c17df49e
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -0,0 +1,92 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgKeyManager.h"
+
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <string>
+
+#include "GpgBasicOperator.h"
+#include "GpgKeyGetter.h"
+
+bool GpgFrontend::GpgKeyManager::SignKey(
+ const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
+ const std::string& uid,
+ const std::unique_ptr<boost::posix_time::ptime>& expires) {
+ using namespace boost::posix_time;
+
+ GpgBasicOperator::GetInstance().SetSigners(keys);
+
+ unsigned int flags = 0;
+ unsigned int expires_time_t = 0;
+
+ if (expires == nullptr)
+ flags |= GPGME_KEYSIGN_NOEXPIRE;
+ else
+ expires_time_t = to_time_t(*expires);
+
+ auto err = check_gpg_error(gpgme_op_keysign(
+ ctx_, gpgme_key_t(target), uid.c_str(), expires_time_t, flags));
+
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
+
+bool GpgFrontend::GpgKeyManager::RevSign(
+ const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id) {
+ auto& key_getter = GpgKeyGetter::GetInstance();
+
+ for (const auto& sign_id : *signature_id) {
+ auto signing_key = key_getter.GetKey(sign_id.first);
+ assert(signing_key.IsGood());
+ auto err = check_gpg_error(gpgme_op_revsig(ctx_, gpgme_key_t(key),
+ gpgme_key_t(signing_key),
+ sign_id.second.c_str(), 0));
+ if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) return false;
+ }
+ return true;
+}
+
+bool GpgFrontend::GpgKeyManager::SetExpire(
+ const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<boost::posix_time::ptime>& expires) {
+ using namespace boost::posix_time;
+
+ unsigned long expires_time = 0;
+
+ if (expires != nullptr) expires_time = to_time_t(ptime(*expires));
+
+ const char* sub_fprs = nullptr;
+
+ if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
+
+ auto err = check_gpg_error(
+ gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, sub_fprs, 0));
+
+ return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR;
+}
diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h
new file mode 100644
index 00000000..5bcac545
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyManager.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+
+#include "core/GpgContext.h"
+#include "core/GpgFunctionObject.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> {
+ public:
+ /**
+ * @brief Construct a new Gpg Key Manager object
+ *
+ * @param channel
+ */
+ explicit GpgKeyManager(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgKeyManager>(channel) {}
+
+ /**
+ * @brief Sign a key pair(actually a certain uid)
+ * @param target target key pair
+ * @param uid target
+ * @param expires expire date and time of the signature
+ * @return if successful
+ */
+ bool SignKey(const GpgKey& target, KeyArgsList& keys, const std::string& uid,
+ const std::unique_ptr<boost::posix_time::ptime>& expires);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param signature_id
+ * @return true
+ * @return false
+ */
+ bool RevSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id);
+
+ /**
+ * @brief Set the Expire object
+ *
+ * @param key
+ * @param subkey
+ * @param expires
+ * @return true
+ * @return false
+ */
+ bool SetExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<boost::posix_time::ptime>& expires);
+
+ private:
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
new file mode 100644
index 00000000..23dcae9f
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -0,0 +1,293 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgKeyOpera.h"
+
+#include <boost/asio.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <boost/format.hpp>
+#include <boost/process/async_pipe.hpp>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "core/GpgConstants.h"
+#include "core/GpgGenKeyInfo.h"
+#include "GpgCommandExecutor.h"
+#include "GpgKeyGetter.h"
+
+/**
+ * Delete keys
+ * @param uidList key ids
+ */
+void GpgFrontend::GpgKeyOpera::DeleteKeys(
+ GpgFrontend::KeyIdArgsListPtr key_ids) {
+ GpgError err;
+ for (const auto& tmp : *key_ids) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
+ if (key.IsGood()) {
+ err = check_gpg_error(
+ gpgme_op_delete_ext(ctx_, gpgme_key_t(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
+ assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
+ } else {
+ LOG(WARNING) << "GpgKeyOpera DeleteKeys get key failed" << tmp;
+ }
+ }
+}
+
+/**
+ * Set the expire date and time of a key pair(actually the primary key) or
+ * subkey
+ * @param key target key pair
+ * @param subkey null if primary key
+ * @param expires date and time
+ * @return if successful
+ */
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
+ const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<boost::posix_time::ptime>& expires) {
+ unsigned long expires_time = 0;
+
+ if (expires != nullptr) {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires_time =
+ to_time_t(*expires) - system_clock::to_time_t(system_clock::now());
+ }
+
+ LOG(INFO) << key.GetId() << subkey_fpr << expires_time;
+
+ GpgError err;
+ if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty())
+ err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time, nullptr, 0);
+ else
+ err = gpgme_op_setexpire(ctx_, gpgme_key_t(key), expires_time,
+ subkey_fpr.c_str(), 0);
+
+ return err;
+}
+
+/**
+ * Generate revoke cert of a key pair
+ * @param key target key pair
+ * @param outputFileName out file name(path)
+ * @return the process doing this job
+ */
+void GpgFrontend::GpgKeyOpera::GenerateRevokeCert(
+ const GpgKey& key, const std::string& output_file_name) {
+ auto args = std::vector<std::string>{"--no-tty",
+ "--command-fd",
+ "0",
+ "--status-fd",
+ "1",
+ "-o",
+ output_file_name,
+ "--gen-revoke",
+ key.GetFingerprint()};
+
+ using boost::asio::async_write;
+ using boost::process::async_pipe;
+#ifndef WINDOWS
+ GpgCommandExecutor::GetInstance().Execute(
+ args, [](async_pipe& in, async_pipe& out) -> void {
+ // boost::asio::streambuf buff;
+ // boost::asio::read_until(in, buff, '\n');
+ //
+ // std::istream is(&buff);
+ //
+ // while (!is.eof()) {
+ // std::string line;
+ // is >> line;
+ // LOG(INFO) << "line" << line;
+ // boost::algorithm::trim(line);
+ // if (line == std::string("[GNUPG:] GET_BOOL
+ // gen_revoke.okay")) {
+ //
+ // } else if (line ==
+ // std::string(
+ // "[GNUPG:] GET_LINE
+ // ask_revocation_reason.code")) {
+ //
+ // } else if (line ==
+ // std::string(
+ // "[GNUPG:] GET_LINE
+ // ask_revocation_reason.text")) {
+ //
+ // } else if (line ==
+ // std::string("[GNUPG:] GET_BOOL
+ // openfile.overwrite.okay")) {
+ //
+ // } else if (line ==
+ // std::string(
+ // "[GNUPG:] GET_BOOL
+ // ask_revocation_reason.okay")) {
+ //
+ // }
+ // }
+ });
+#endif
+}
+
+/**
+ * Generate a new key pair
+ * @param params key generation args
+ * @return error information
+ */
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey(
+ const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) {
+ auto userid_utf8 = params->GetUserid();
+ const char* userid = userid_utf8.c_str();
+ auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr();
+
+ LOG(INFO) << "params" << params->GetAlgo() << params->GetKeySizeStr();
+
+ const char* algo = algo_utf8.c_str();
+ unsigned long expires = 0;
+ {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires = to_time_t(ptime(params->GetExpireTime())) -
+ system_clock::to_time_t(system_clock::now());
+ }
+
+ GpgError err;
+
+ if (ctx_.GetInfo().GnupgVersion >= "2.1.0") {
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+ if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ LOG(INFO) << "args: " << userid << algo << expires << flags;
+
+ err = gpgme_op_createkey(ctx_, userid, algo, 0, expires, nullptr, flags);
+
+ } else {
+ std::stringstream ss;
+ auto param_format =
+ boost::format{
+ "<GnupgKeyParms format=\"internal\">\n"
+ "Key-Type: %1%\n"
+ "Key-Usage: sign\n"
+ "Key-Length: %2%\n"
+ "Name-Real: %3%\n"
+ "Name-Comment: %4%\n"
+ "Name-Email: %5%\n"} %
+ params->GetAlgo() % params->GetKeyLength() % params->GetName() %
+ params->GetComment() % params->GetEmail();
+ ss << param_format;
+
+ if (!params->IsNonExpired()) {
+ auto date = params->GetExpireTime().date();
+ ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date);
+ } else
+ ss << boost::format{"Expire-Date: 0\n"};
+ if (!params->IsNoPassPhrase())
+ ss << boost::format{"Passphrase: %1%\n"} % params->GetPassPhrase();
+
+ ss << "</GnupgKeyParms>";
+
+ DLOG(INFO) << "params" << std::endl << ss.str();
+
+ err = gpgme_op_genkey(ctx_, ss.str().c_str(), nullptr, nullptr);
+ }
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) {
+ auto temp_result = _new_result(gpgme_op_genkey_result(ctx_));
+ std::swap(temp_result, result);
+ }
+
+ return check_gpg_error(err);
+}
+
+/**
+ * Generate a new subkey of a certain key pair
+ * @param key target key pair
+ * @param params opera args
+ * @return error info
+ */
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey(
+ const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params) {
+ if (!params->IsSubKey()) return GPG_ERR_CANCELED;
+
+ auto algo_utf8 = (params->GetAlgo() + params->GetKeySizeStr());
+ const char* algo = algo_utf8.c_str();
+ unsigned long expires = 0;
+ {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires = to_time_t(ptime(params->GetExpireTime())) -
+ system_clock::to_time_t(system_clock::now());
+ }
+ unsigned int flags = 0;
+
+ if (!params->IsSubKey()) flags |= GPGME_CREATE_CERT;
+ if (params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR;
+ if (params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN;
+ if (params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH;
+ if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
+
+ flags |= GPGME_CREATE_NOPASSWD;
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateSubkey Args: " << key.GetId()
+ << algo << expires << flags;
+
+ auto err =
+ gpgme_op_createsubkey(ctx_, gpgme_key_t(key), algo, 0, expires, flags);
+ return check_gpg_error(err);
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyPassword(
+ const GpgFrontend::GpgKey& key) {
+ if (ctx_.GetInfo().GnupgVersion < "2.0.15") {
+ LOG(ERROR) << _("operator not support");
+ return GPG_ERR_NOT_SUPPORTED;
+ }
+ auto err = gpgme_op_passwd(ctx_, gpgme_key_t(key), 0);
+ return check_gpg_error(err);
+}
+GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy(
+ const GpgFrontend::GpgKey& key, gpgme_tofu_policy_t tofu_policy) {
+ if (ctx_.GetInfo().GnupgVersion < "2.1.10") {
+ LOG(ERROR) << _("operator not support");
+ return GPG_ERR_NOT_SUPPORTED;
+ }
+ auto err = gpgme_op_tofu_policy(ctx_, gpgme_key_t(key), tofu_policy);
+ return check_gpg_error(err);
+}
+
+void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) {
+ auto keys = std::make_unique<KeyIdArgsList>();
+ keys->push_back(key_id);
+ DeleteKeys(std::move(keys));
+}
diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h
new file mode 100644
index 00000000..04571c10
--- /dev/null
+++ b/src/core/function/gpg/GpgKeyOpera.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef _GPGKEYOPERA_H
+#define _GPGKEYOPERA_H
+
+#include "core/GpgConstants.h"
+#include "core/GpgContext.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+/**
+ * @brief
+ *
+ */
+class GenKeyInfo;
+
+/**
+ * @brief
+ *
+ */
+class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> {
+ public:
+ /**
+ * @brief Construct a new Gpg Key Opera object
+ *
+ * @param channel
+ */
+ explicit GpgKeyOpera(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgKeyOpera>(channel) {}
+
+ /**
+ * @brief
+ *
+ * @param key_ids
+ */
+ void DeleteKeys(KeyIdArgsListPtr key_ids);
+
+ /**
+ * @brief
+ *
+ * @param key_id
+ */
+ void DeleteKey(const KeyId& key_id);
+
+ /**
+ * @brief Set the Expire object
+ *
+ * @param key
+ * @param subkey_fpr
+ * @param expires
+ * @return GpgError
+ */
+ GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<boost::posix_time::ptime>& expires);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param output_file_name
+ */
+ static void GenerateRevokeCert(const GpgKey& key,
+ const std::string& output_file_name);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @return GpgFrontend::GpgError
+ */
+ GpgFrontend::GpgError ModifyPassword(const GpgKey& key);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param tofu_policy
+ * @return GpgFrontend::GpgError
+ */
+ GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key,
+ gpgme_tofu_policy_t tofu_policy);
+ /**
+ * @brief
+ *
+ * @param params
+ * @param result
+ * @return GpgFrontend::GpgError
+ */
+ GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params,
+ GpgGenKeyResult& result);
+
+ /**
+ * @brief
+ *
+ * @param key
+ * @param params
+ * @return GpgFrontend::GpgError
+ */
+ GpgFrontend::GpgError GenerateSubkey(
+ const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+
+ private:
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+};
+} // namespace GpgFrontend
+
+#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
new file mode 100644
index 00000000..dd0c43f6
--- /dev/null
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgUIDOperator.h"
+
+#include "boost/format.hpp"
+
+bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
+ const std::string& uid) {
+ auto err = gpgme_op_adduid(ctx_, gpgme_key_t(key), uid.c_str(), 0);
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ return true;
+ else
+ return false;
+}
+
+bool GpgFrontend::GpgUIDOperator::RevUID(const GpgFrontend::GpgKey& key,
+ const std::string& uid) {
+ auto err =
+ check_gpg_error(gpgme_op_revuid(ctx_, gpgme_key_t(key), uid.c_str(), 0));
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ return true;
+ else
+ return false;
+}
+
+bool GpgFrontend::GpgUIDOperator::SetPrimaryUID(const GpgFrontend::GpgKey& key,
+ const std::string& uid) {
+ auto err = check_gpg_error(gpgme_op_set_uid_flag(
+ ctx_, gpgme_key_t(key), uid.c_str(), "primary", nullptr));
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ return true;
+ else
+ return false;
+}
+bool GpgFrontend::GpgUIDOperator::AddUID(const GpgFrontend::GpgKey& key,
+ const std::string& name,
+ const std::string& comment,
+ const std::string& email) {
+ LOG(INFO) << "GpgFrontend::UidOperator::AddUID" << name << comment << email;
+ auto uid = boost::format("%1%(%2%)<%3%>") % name % comment % email;
+ return AddUID(key, uid.str());
+}
diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h
new file mode 100644
index 00000000..479505e5
--- /dev/null
+++ b/src/core/function/gpg/GpgUIDOperator.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+
+#include "core/GpgContext.h"
+#include "core/GpgModel.h"
+
+namespace GpgFrontend {
+/**
+ * @brief
+ *
+ */
+class GpgUIDOperator : public SingletonFunctionObject<GpgUIDOperator> {
+ public:
+ explicit GpgUIDOperator(
+ int channel = SingletonFunctionObject::GetDefaultChannel())
+ : SingletonFunctionObject<GpgUIDOperator>(channel) {}
+
+ /**
+ * create a new uid in certain key pair
+ * @param key target key pair
+ * @param uid uid args(combine name&comment&email)
+ * @return if successful
+ */
+ bool AddUID(const GpgKey& key, const std::string& uid);
+
+ /**
+ * create a new uid in certain key pair
+ * @param key target key pair
+ * @param name
+ * @param comment
+ * @param email
+ * @return
+ */
+ bool AddUID(const GpgKey& key, const std::string& name,
+ const std::string& comment, const std::string& email);
+
+ /**
+ * Revoke(Delete) UID from certain key pair
+ * @param key target key pair
+ * @param uid target uid
+ * @return if successful
+ */
+ bool RevUID(const GpgKey& key, const std::string& uid);
+
+ /**
+ * Set one of a uid of a key pair as primary
+ * @param key target key pair
+ * @param uid target uid
+ * @return if successful
+ */
+ bool SetPrimaryUID(const GpgKey& key, const std::string& uid);
+
+ private:
+ GpgContext& ctx_ =
+ GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
new file mode 100644
index 00000000..ff3d2e27
--- /dev/null
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.cpp
@@ -0,0 +1,97 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgDecryptResultAnalyse.h"
+
+#include "function/gpg/GpgKeyGetter.h"
+
+GpgFrontend::GpgDecryptResultAnalyse::GpgDecryptResultAnalyse(GpgError m_error,
+ GpgDecrResult m_result)
+ : error_(m_error), result_(std::move(m_result)) {}
+
+void GpgFrontend::GpgDecryptResultAnalyse::do_analyse() {
+ stream_ << "[#] " << _("Decrypt Operation");
+
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR) {
+ stream_ << "[" << _("Success") << "]" << std::endl;
+ } else {
+ stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
+ << std::endl;
+ set_status(-1);
+ if (result_ != nullptr && result_->unsupported_algorithm != nullptr) {
+ stream_ << "------------>" << std::endl;
+ stream_ << _("Unsupported Algo") << ": " << result_->unsupported_algorithm
+ << std::endl;
+ }
+ }
+
+ if (result_ != nullptr && result_->recipients != nullptr) {
+ stream_ << "------------>" << std::endl;
+ if (result_->file_name != nullptr) {
+ stream_ << _("File Name") << ": " << result_->file_name << std::endl;
+ stream_ << std::endl;
+ }
+ if (result_->is_mime) {
+ stream_ << _("MIME") << ": " << _("true") << std::endl;
+ }
+
+ auto recipient = result_->recipients;
+ if (recipient != nullptr) stream_ << _("Recipient(s)") << ": " << std::endl;
+ while (recipient != nullptr) {
+ print_recipient(stream_, recipient);
+ recipient = recipient->next;
+ }
+ stream_ << "<------------" << std::endl;
+ }
+
+ stream_ << std::endl;
+}
+
+void GpgFrontend::GpgDecryptResultAnalyse::print_recipient(
+ std::stringstream &stream, gpgme_recipient_t recipient) {
+ // check
+ if (recipient->keyid == nullptr) return;
+
+ stream << " {>} " << _("Recipient") << ": ";
+ auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(recipient->keyid);
+ if (key.IsGood()) {
+ stream << key.GetName().c_str();
+ if (!key.GetEmail().empty()) {
+ stream << "<" << key.GetEmail().c_str() << ">";
+ }
+ } else {
+ stream << "<" << _("Unknown") << ">";
+ set_status(0);
+ }
+
+ stream << std::endl;
+
+ stream << " " << _("Key ID") << ": " << recipient->keyid << std::endl;
+ stream << " " << _("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(recipient->pubkey_algo) << std::endl;
+}
diff --git a/src/core/function/result_analyse/GpgDecryptResultAnalyse.h b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
new file mode 100644
index 00000000..af42f995
--- /dev/null
+++ b/src/core/function/result_analyse/GpgDecryptResultAnalyse.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
+#define GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
+
+#include "GpgResultAnalyse.h"
+#include "core/GpgConstants.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GpgDecryptResultAnalyse : public GpgResultAnalyse {
+ public:
+ /**
+ * @brief Construct a new Decrypt Result Analyse object
+ *
+ * @param m_error
+ * @param m_result
+ */
+ explicit GpgDecryptResultAnalyse(GpgError m_error, GpgDecrResult m_result);
+
+ protected:
+ /**
+ * @brief
+ *
+ */
+ void do_analyse() final;
+
+ private:
+ /**
+ * @brief
+ *
+ * @param stream
+ * @param recipient
+ */
+ void print_recipient(std::stringstream &stream, gpgme_recipient_t recipient);
+
+ GpgError error_; ///<
+ GpgDecrResult result_; ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGDECRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
new file mode 100644
index 00000000..053a15a5
--- /dev/null
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgEncryptResultAnalyse.h"
+
+GpgFrontend::GpgEncryptResultAnalyse::GpgEncryptResultAnalyse(GpgError error,
+ GpgEncrResult result)
+ : error_(error), result_(std::move(result)) {}
+
+void GpgFrontend::GpgEncryptResultAnalyse::do_analyse() {
+ LOG(INFO) << _("Start Encrypt Result Analyse");
+
+ stream_ << "[#] " << _("Encrypt Operation") << " ";
+
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
+ stream_ << "[" << _("Success") << "]" << std::endl;
+ else {
+ stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
+ << std::endl;
+ set_status(-1);
+ }
+
+ if (!~status_) {
+ stream_ << "------------>" << std::endl;
+ if (result_ != nullptr) {
+ stream_ << _("Invalid Recipients") << ": " << std::endl;
+ auto inv_reci = result_->invalid_recipients;
+ while (inv_reci != nullptr) {
+ stream_ << _("Fingerprint") << ": " << inv_reci->fpr << std::endl;
+ stream_ << _("Reason") << ": " << gpgme_strerror(inv_reci->reason)
+ << std::endl;
+ stream_ << std::endl;
+
+ inv_reci = inv_reci->next;
+ }
+ }
+ stream_ << "<------------" << std::endl;
+ }
+
+ stream_ << std::endl;
+}
diff --git a/src/core/function/result_analyse/GpgEncryptResultAnalyse.h b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
new file mode 100644
index 00000000..c5125fdc
--- /dev/null
+++ b/src/core/function/result_analyse/GpgEncryptResultAnalyse.h
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
+#define GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
+
+#include "GpgResultAnalyse.h"
+#include "core/GpgConstants.h"
+
+namespace GpgFrontend {
+/**
+ * @brief
+ *
+ */
+class GpgEncryptResultAnalyse : public GpgResultAnalyse {
+ public:
+ /**
+ * @brief Construct a new Encrypt Result Analyse object
+ *
+ * @param error
+ * @param result
+ */
+ explicit GpgEncryptResultAnalyse(GpgError error, GpgEncrResult result);
+
+ protected:
+ /**
+ * @brief
+ *
+ */
+ void do_analyse() final;
+
+ private:
+ GpgError error_; ///<
+ GpgEncrResult result_; ///<
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGENCRYPTRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.cpp b/src/core/function/result_analyse/GpgResultAnalyse.cpp
new file mode 100644
index 00000000..40ba4c3e
--- /dev/null
+++ b/src/core/function/result_analyse/GpgResultAnalyse.cpp
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgResultAnalyse.h"
+
+const std::string GpgFrontend::GpgResultAnalyse::GetResultReport() const {
+ return stream_.str();
+}
+
+int GpgFrontend::GpgResultAnalyse::GetStatus() const { return status_; }
+
+void GpgFrontend::GpgResultAnalyse::set_status(int m_status) {
+ if (m_status < status_) status_ = m_status;
+}
+
+void GpgFrontend::GpgResultAnalyse::Analyse() {
+ if (!analysed_) {
+ do_analyse();
+ analysed_ = true;
+ }
+}
diff --git a/src/core/function/result_analyse/GpgResultAnalyse.h b/src/core/function/result_analyse/GpgResultAnalyse.h
new file mode 100644
index 00000000..888c6449
--- /dev/null
+++ b/src/core/function/result_analyse/GpgResultAnalyse.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+#ifndef GPGFRONTEND_GPGRESULTANALYSE_H
+#define GPGFRONTEND_GPGRESULTANALYSE_H
+
+#include <sstream>
+#include <string>
+
+#include "core/GpgConstants.h"
+namespace GpgFrontend {
+
+class GpgResultAnalyse {
+ public:
+ /**
+ * @brief Construct a new Result Analyse object
+ *
+ */
+ GpgResultAnalyse() = default;
+
+ /**
+ * @brief Get the Result Report object
+ *
+ * @return const std::string
+ */
+ [[nodiscard]] const std::string GetResultReport() const;
+
+ /**
+ * @brief Get the Status object
+ *
+ * @return int
+ */
+ [[nodiscard]] int GetStatus() const;
+
+ /**
+ * @brief
+ *
+ */
+ void Analyse();
+
+ protected:
+ /**
+ * @brief
+ *
+ */
+ virtual void do_analyse() = 0;
+
+ /**
+ * @brief Set the status object
+ *
+ * @param m_status
+ */
+ void set_status(int m_status);
+
+ std::stringstream stream_; ///<
+ int status_ = 1; ///<
+ bool analysed_ = false; ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.cpp b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
new file mode 100644
index 00000000..e389523c
--- /dev/null
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.cpp
@@ -0,0 +1,115 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgSignResultAnalyse.h"
+
+#include "function/gpg/GpgKeyGetter.h"
+
+GpgFrontend::GpgSignResultAnalyse::GpgSignResultAnalyse(GpgError error,
+ GpgSignResult result)
+ : error_(error), result_(std::move(result)) {}
+
+void GpgFrontend::GpgSignResultAnalyse::do_analyse() {
+ LOG(INFO) << _("Start Sign Result Analyse");
+
+ stream_ << "[#] " << _("Sign Operation") << " ";
+
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
+ stream_ << "[" << _("Success") << "]" << std::endl;
+ else {
+ stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
+ << std::endl;
+ set_status(-1);
+ }
+
+ if (result_ != nullptr &&
+ (result_->signatures != nullptr || result_->invalid_signers != nullptr)) {
+ LOG(INFO) << _("Sign Result Analyse Getting Result");
+ stream_ << "------------>" << std::endl;
+ auto new_sign = result_->signatures;
+
+ while (new_sign != nullptr) {
+ stream_ << "[>]" << _("New Signature") << ": " << std::endl;
+
+ LOG(INFO) << _("Signers Fingerprint") << ": " << new_sign->fpr;
+
+ stream_ << " " << _("Sign Mode") << ": ";
+ if (new_sign->type == GPGME_SIG_MODE_NORMAL)
+ stream_ << _("Normal");
+ else if (new_sign->type == GPGME_SIG_MODE_CLEAR)
+ stream_ << _("Clear");
+ else if (new_sign->type == GPGME_SIG_MODE_DETACH)
+ stream_ << _("Detach");
+
+ stream_ << std::endl;
+
+ auto singerKey =
+ GpgFrontend::GpgKeyGetter::GetInstance().GetKey(new_sign->fpr);
+ if (singerKey.IsGood()) {
+ stream_ << " " << _("Signer") << ": "
+ << singerKey.GetUIDs()->front().GetUID() << std::endl;
+ } else {
+ stream_ << " " << _("Signer") << ": "
+ << "<unknown>" << std::endl;
+ }
+ stream_ << " " << _("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(new_sign->pubkey_algo) << std::endl;
+ stream_ << " " << _("Hash Algo") << ": "
+ << gpgme_hash_algo_name(new_sign->hash_algo) << std::endl;
+ stream_ << " " << _("Date") << "(" << _("UTC") << ")"
+ << ": "
+ << boost::posix_time::to_iso_extended_string(
+ boost::posix_time::from_time_t(new_sign->timestamp))
+ << std::endl;
+
+ stream_ << std::endl;
+
+ new_sign = new_sign->next;
+ }
+
+ LOG(INFO) << _("Sign Result Analyse Getting Invalid Signer");
+
+ auto invalid_signer = result_->invalid_signers;
+
+ if (invalid_signer != nullptr)
+ stream_ << _("Invalid Signers") << ": " << std::endl;
+
+ while (invalid_signer != nullptr) {
+ set_status(0);
+ stream_ << "[>] " << _("Signer") << ": " << std::endl;
+ stream_ << " " << _("Fingerprint") << ": " << invalid_signer->fpr
+ << std::endl;
+ stream_ << " " << _("Reason") << ": "
+ << gpgme_strerror(invalid_signer->reason) << std::endl;
+ stream_ << std::endl;
+
+ invalid_signer = invalid_signer->next;
+ }
+ stream_ << "<------------" << std::endl;
+ }
+} \ No newline at end of file
diff --git a/src/core/function/result_analyse/GpgSignResultAnalyse.h b/src/core/function/result_analyse/GpgSignResultAnalyse.h
new file mode 100644
index 00000000..d593b33d
--- /dev/null
+++ b/src/core/function/result_analyse/GpgSignResultAnalyse.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGSIGNRESULTANALYSE_H
+#define GPGFRONTEND_GPGSIGNRESULTANALYSE_H
+
+#include "GpgResultAnalyse.h"
+
+namespace GpgFrontend {
+
+/**
+ * @brief
+ *
+ */
+class GpgSignResultAnalyse : public GpgResultAnalyse {
+ public:
+ /**
+ * @brief Construct a new Sign Result Analyse object
+ *
+ * @param error
+ * @param result
+ */
+ explicit GpgSignResultAnalyse(GpgError error, GpgSignResult result);
+
+ protected:
+ /**
+ * @brief
+ *
+ */
+ void do_analyse();
+
+ private:
+ GpgError error_; ///<
+
+ GpgSignResult result_; ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGSIGNRESULTANALYSE_H
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
new file mode 100644
index 00000000..44031e67
--- /dev/null
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.cpp
@@ -0,0 +1,214 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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 "GpgVerifyResultAnalyse.h"
+
+#include <boost/format.hpp>
+
+#include "GpgFrontend.h"
+#include "core/GpgConstants.h"
+#include "function/gpg/GpgKeyGetter.h"
+
+GpgFrontend::GpgVerifyResultAnalyse::GpgVerifyResultAnalyse(GpgError error,
+ GpgVerifyResult result)
+ : error_(error), result_(std::move(result)) {}
+
+void GpgFrontend::GpgVerifyResultAnalyse::do_analyse() {
+ LOG(INFO) << _("started");
+
+ stream_ << "[#] " << _("Verify Operation") << " ";
+
+ if (gpgme_err_code(error_) == GPG_ERR_NO_ERROR)
+ stream_ << "[" << _("Success") << "]" << std::endl;
+ else {
+ stream_ << "[" << _("Failed") << "] " << gpgme_strerror(error_)
+ << std::endl;
+ set_status(-1);
+ }
+
+ if (result_ != nullptr && result_->signatures != nullptr) {
+ stream_ << "------------>" << std::endl;
+ auto sign = result_->signatures;
+
+ stream_ << "[>] " << _("Signed On") << "(" << _("UTC") << ")"
+ << " "
+ << boost::posix_time::to_iso_extended_string(
+ boost::posix_time::from_time_t(sign->timestamp))
+ << std::endl;
+
+ stream_ << std::endl << "[>] " << _("Signatures List") << ":" << std::endl;
+
+ bool canContinue = true;
+
+ int count = 1;
+ while (sign && canContinue) {
+ stream_ << boost::format(_("Signature [%1%]:")) % count++ << std::endl;
+ switch (gpg_err_code(sign->status)) {
+ case GPG_ERR_BAD_SIGNATURE:
+ stream_ << _("A Bad Signature.") << std::endl;
+ print_signer(stream_, sign);
+ stream_ << _("This Signature is invalid.") << std::endl;
+ canContinue = false;
+ set_status(-1);
+ break;
+ case GPG_ERR_NO_ERROR:
+ stream_ << _("A") << " ";
+ if (sign->summary & GPGME_SIGSUM_GREEN) {
+ stream_ << _("Good") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_RED) {
+ stream_ << _("Bad") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_SIG_EXPIRED) {
+ stream_ << _("Expired") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_KEY_MISSING) {
+ stream_ << _("Missing Key's") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_KEY_REVOKED) {
+ stream_ << _("Revoked Key's") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_KEY_EXPIRED) {
+ stream_ << _("Expired Key's") << " ";
+ }
+ if (sign->summary & GPGME_SIGSUM_CRL_MISSING) {
+ stream_ << _("Missing CRL's") << " ";
+ }
+
+ if (sign->summary & GPGME_SIGSUM_VALID) {
+ stream_ << _("Signature Fully Valid.") << std::endl;
+ } else {
+ stream_ << _("Signature Not Fully Valid.") << std::endl;
+ }
+
+ if (!(sign->status & GPGME_SIGSUM_KEY_MISSING)) {
+ if (!print_signer(stream_, sign)) set_status(0);
+ } else {
+ stream_ << _("Key is NOT present with ID 0x") << sign->fpr
+ << std::endl;
+ }
+
+ set_status(1);
+
+ break;
+ case GPG_ERR_NO_PUBKEY:
+ stream_ << _("A signature could NOT be verified due to a Missing Key")
+ << std::endl;
+ set_status(-2);
+ break;
+ case GPG_ERR_CERT_REVOKED:
+ stream_ << _("A signature is valid but the key used to verify the "
+ "signature has been revoked")
+ << std::endl;
+ if (!print_signer(stream_, sign)) {
+ set_status(0);
+ }
+ set_status(-1);
+ break;
+ case GPG_ERR_SIG_EXPIRED:
+ stream_ << _("A signature is valid but expired") << std::endl;
+ if (!print_signer(stream_, sign)) {
+ set_status(0);
+ }
+ set_status(-1);
+ break;
+ case GPG_ERR_KEY_EXPIRED:
+ stream_ << _("A signature is valid but the key used to "
+ "verify the signature has expired.")
+ << std::endl;
+ if (!print_signer(stream_, sign)) {
+ set_status(0);
+ }
+ break;
+ case GPG_ERR_GENERAL:
+ stream_ << _("There was some other error which prevented "
+ "the signature verification.")
+ << std::endl;
+ status_ = -1;
+ canContinue = false;
+ break;
+ default:
+ auto fpr = std::string(sign->fpr);
+ stream_ << _("Error for key with fingerprint") << " "
+ << GpgFrontend::beautify_fingerprint(fpr);
+ set_status(-1);
+ }
+ stream_ << std::endl;
+ sign = sign->next;
+ }
+ stream_ << "<------------" << std::endl;
+ } else {
+ stream_
+ << "[>] "
+ << _("Could not find information that can be used for verification.")
+ << std::endl;
+ set_status(0);
+ return;
+ }
+}
+
+bool GpgFrontend::GpgVerifyResultAnalyse::print_signer(std::stringstream &stream,
+ gpgme_signature_t sign) {
+ bool keyFound = true;
+ auto key = GpgFrontend::GpgKeyGetter::GetInstance().GetKey(sign->fpr);
+
+ if (!key.IsGood()) {
+ stream << " " << _("Signed By") << ": "
+ << "<" << _("Unknown") << ">" << std::endl;
+ set_status(0);
+ keyFound = false;
+ } else {
+ stream << " " << _("Signed By") << ": "
+ << key.GetUIDs()->front().GetUID() << std::endl;
+ }
+ if (sign->pubkey_algo)
+ stream << " " << _("Public Key Algo") << ": "
+ << gpgme_pubkey_algo_name(sign->pubkey_algo) << std::endl;
+ if (sign->hash_algo)
+ stream << " " << _("Hash Algo") << ": "
+ << gpgme_hash_algo_name(sign->hash_algo) << std::endl;
+ if (sign->timestamp)
+ stream << " " << _("Date") << "(" << _("UTC") << ")"
+ << ": "
+ << boost::posix_time::to_iso_extended_string(
+ boost::posix_time::from_time_t(sign->timestamp))
+ << std::endl;
+ stream << std::endl;
+ return keyFound;
+}
+
+gpgme_signature_t GpgFrontend::GpgVerifyResultAnalyse::GetSignatures() const {
+ if (result_)
+ return result_->signatures;
+ else
+ return nullptr;
+}
+GpgFrontend::GpgVerifyResult
+GpgFrontend::GpgVerifyResultAnalyse::TakeChargeOfResult() {
+ return std::move(result_);
+}
diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
new file mode 100644
index 00000000..12e4b7ff
--- /dev/null
+++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
+#define GPGFRONTEND_GPGVERIFYRESULTANALYSE_H
+
+#include "GpgResultAnalyse.h"
+#include "core/model/GpgKeySignature.h"
+
+namespace GpgFrontend {
+/**
+ * @brief
+ *
+ */
+class GpgVerifyResultAnalyse : public GpgResultAnalyse {
+ public:
+ /**
+ * @brief Construct a new Verify Result Analyse object
+ *
+ * @param error
+ * @param result
+ */
+ explicit GpgVerifyResultAnalyse(GpgError error, GpgVerifyResult result);
+
+ /**
+ * @brief Get the Signatures object
+ *
+ * @return gpgme_signature_t
+ */
+ gpgme_signature_t GetSignatures() const;
+
+ /**
+ * @brief
+ *
+ * @return GpgVerifyResult
+ */
+ GpgVerifyResult TakeChargeOfResult();
+
+ private:
+ /**
+ * @brief
+ *
+ */
+ void do_analyse();
+
+ private:
+ /**
+ * @brief
+ *
+ * @param stream
+ * @param sign
+ * @return true
+ * @return false
+ */
+ bool print_signer(std::stringstream &stream, gpgme_signature_t sign);
+
+ GpgError error_; ///<
+ GpgVerifyResult result_; ///<
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGVERIFYRESULTANALYSE_H