aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function/gpg
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/function/gpg')
-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
16 files changed, 2222 insertions, 0 deletions
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