aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpg/function
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpg/function')
-rw-r--r--src/gpg/function/BasicOperator.cpp206
-rw-r--r--src/gpg/function/BasicOperator.h69
-rw-r--r--src/gpg/function/GpgCommandExecutor.cpp59
-rw-r--r--src/gpg/function/GpgCommandExecutor.h52
-rw-r--r--src/gpg/function/GpgFileOpera.cpp162
-rw-r--r--src/gpg/function/GpgFileOpera.h58
-rw-r--r--src/gpg/function/GpgKeyGetter.cpp75
-rw-r--r--src/gpg/function/GpgKeyGetter.h52
-rw-r--r--src/gpg/function/GpgKeyImportExportor.cpp117
-rw-r--r--src/gpg/function/GpgKeyImportExportor.h100
-rw-r--r--src/gpg/function/GpgKeyManager.cpp88
-rw-r--r--src/gpg/function/GpgKeyManager.h58
-rw-r--r--src/gpg/function/GpgKeyOpera.cpp217
-rw-r--r--src/gpg/function/GpgKeyOpera.h54
-rw-r--r--src/gpg/function/UidOperator.cpp64
-rw-r--r--src/gpg/function/UidOperator.h76
16 files changed, 1507 insertions, 0 deletions
diff --git a/src/gpg/function/BasicOperator.cpp b/src/gpg/function/BasicOperator.cpp
new file mode 100644
index 00000000..912119e2
--- /dev/null
+++ b/src/gpg/function/BasicOperator.cpp
@@ -0,0 +1,206 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/BasicOperator.h"
+
+#include <vector>
+
+#include "gpg/function/GpgKeyGetter.h"
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::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 = GpgEncrResult(gpgme_op_encrypt_result(ctx));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::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 = GpgDecrResult(gpgme_op_decrypt_result(ctx));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::Verify(
+ BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer,
+ GpgVerifyResult& result) const {
+ gpgme_error_t err;
+
+ GpgData data_in(in_buffer.data(), in_buffer.size());
+
+ 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_in));
+
+ auto temp_result = GpgVerifyResult(gpgme_op_verify_result(ctx));
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyListPtr keys,
+ BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer,
+ gpgme_sig_mode_t mode,
+ GpgSignResult& result) {
+ gpgme_error_t err;
+
+ // Set Singers of this opera
+ SetSigners(*keys);
+
+ GpgData data_in(in_buffer.data(), in_buffer.size()), data_out;
+
+ /**
+ `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.
+ */
+
+ 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 = GpgSignResult(gpgme_op_sign_result(ctx));
+
+ std::swap(result, temp_result);
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::BasicOperator::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 = GpgDecrResult(gpgme_op_decrypt_result(ctx));
+ std::swap(decrypt_result, temp_decr_result);
+
+ auto temp_verify_result = GpgVerifyResult(gpgme_op_verify_result(ctx));
+ std::swap(verify_result, temp_verify_result);
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::BasicOperator::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 = GpgEncrResult(gpgme_op_encrypt_result(ctx));
+ swap(encr_result, temp_encr_result);
+ auto temp_sign_result = GpgSignResult(gpgme_op_sign_result(ctx));
+ swap(sign_result, temp_sign_result);
+
+ return err;
+}
+
+void GpgFrontend::BasicOperator::SetSigners(KeyArgsList& keys) {
+ gpgme_signers_clear(ctx);
+ for (const GpgKey& key : keys) {
+ if (key.CanSignActual()) {
+ auto gpgmeError = gpgme_signers_add(ctx, gpgme_key_t(key));
+ check_gpg_error(gpgmeError);
+ }
+ }
+ if (keys.size() != gpgme_signers_count(ctx))
+ DLOG(INFO) << "No All Signers Added";
+}
+
+std::unique_ptr<GpgFrontend::KeyArgsList>
+GpgFrontend::BasicOperator::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;
+}
diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h
new file mode 100644
index 00000000..39f93668
--- /dev/null
+++ b/src/gpg/function/BasicOperator.h
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+#define GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class BasicOperator : public SingletonFunctionObject<BasicOperator> {
+ public:
+ gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, GpgEncrResult& result);
+
+ gpgme_error_t EncryptSign(KeyListPtr keys, KeyListPtr signers,
+ BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgEncrResult& encr_result,
+ GpgSignResult& sign_result);
+
+ gpgme_error_t Decrypt(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& result);
+
+ gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, ByteArrayPtr& out_buffer,
+ GpgDecrResult& decrypt_result,
+ GpgVerifyResult& verify_result);
+
+ gpgme_error_t Verify(BypeArrayRef in_buffer, ByteArrayPtr& sig_buffer,
+ GpgVerifyResult& result) const;
+
+ gpg_error_t Sign(KeyListPtr keys, BypeArrayRef in_buffer,
+ ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode,
+ GpgSignResult& result);
+
+ void SetSigners(KeyArgsList& keys);
+
+ std::unique_ptr<KeyArgsList> GetSigners();
+
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_BASICOPERATOR_H
diff --git a/src/gpg/function/GpgCommandExecutor.cpp b/src/gpg/function/GpgCommandExecutor.cpp
new file mode 100644
index 00000000..9b99b400
--- /dev/null
+++ b/src/gpg/function/GpgCommandExecutor.cpp
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#include "gpg/function/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/gpg/function/GpgCommandExecutor.h b/src/gpg/function/GpgCommandExecutor.h
new file mode 100644
index 00000000..f28caca8
--- /dev/null
+++ b/src/gpg/function/GpgCommandExecutor.h
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+#define GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
+
+#ifndef WINDOWS
+#include <boost/process.hpp>
+#endif
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+
+namespace GpgFrontend {
+class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> {
+ public:
+
+#ifndef WINDOWS
+ 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();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGCOMMANDEXECUTOR_H
diff --git a/src/gpg/function/GpgFileOpera.cpp b/src/gpg/function/GpgFileOpera.cpp
new file mode 100644
index 00000000..c3f75cf8
--- /dev/null
+++ b/src/gpg/function/GpgFileOpera.cpp
@@ -0,0 +1,162 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+#include "gpg/function/GpgFileOpera.h"
+
+#include <memory>
+#include <string>
+
+#include "GpgConstants.h"
+#include "gpg/function/BasicOperator.h"
+
+GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile(
+ KeyListPtr keys, const std::string& path, GpgEncrResult& result) {
+ std::string in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err = BasicOperator::GetInstance().Encrypt(std::move(keys), in_buffer,
+ out_buffer, result);
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(path + ".asc", *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile(
+ const std::string& path, GpgDecrResult& result) {
+ std::string in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err =
+ BasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result);
+
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+
+ std::string out_file_name = get_only_file_name_with_path(path),
+ file_extension = get_file_extension(path);
+
+ if (!(file_extension == ".asc" || file_extension == ".gpg"))
+ out_file_name += ".out";
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(out_file_name, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys,
+ const std::string& path,
+ GpgSignResult& result) {
+ auto in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer;
+
+ auto err = BasicOperator::GetInstance().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 (!write_buffer_to_file(path + ".sig", *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile(const std::string& path,
+ GpgVerifyResult& result) {
+ auto in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> sign_buffer = nullptr;
+
+ if (get_file_extension(path) == ".gpg") {
+ auto err =
+ BasicOperator::GetInstance().Verify(in_buffer, sign_buffer, result);
+ assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR);
+ return err;
+ } else {
+ sign_buffer =
+ std::make_unique<std::string>(read_all_data_in_file(path + ".sig"));
+
+ auto err =
+ BasicOperator::GetInstance().Verify(in_buffer, sign_buffer, result);
+ return err;
+ }
+}
+
+// TODO
+
+gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile(
+ KeyListPtr keys, KeyListPtr signer_keys, const std::string& path,
+ GpgEncrResult& encr_res, GpgSignResult& sign_res) {
+ auto in_buffer = read_all_data_in_file(path);
+ std::unique_ptr<std::string> out_buffer = nullptr;
+
+ // TODO dealing with signer keys
+ auto err = BasicOperator::GetInstance().EncryptSign(
+ std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res,
+ sign_res);
+
+ auto out_path = path + ".gpg";
+ LOG(INFO) << "EncryptSignFile out_path" << out_path;
+ LOG(INFO) << "EncryptSignFile out_buffer size" << out_buffer->size();
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(out_path, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
+
+gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile(
+ const std::string& path, GpgDecrResult& decr_res,
+ GpgVerifyResult& verify_res) {
+ LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile Called";
+
+ auto in_buffer = read_all_data_in_file(path);
+
+ LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile in_buffer"
+ << in_buffer.size();
+ std::unique_ptr<std::string> out_buffer = nullptr;
+
+ auto err = BasicOperator::GetInstance().DecryptVerify(in_buffer, out_buffer,
+ decr_res, verify_res);
+
+ std::string out_file_name = get_only_file_name_with_path(path),
+ file_extension = get_file_extension(path);
+
+ if (!(file_extension == ".asc" || file_extension == ".gpg"))
+ out_file_name = path + ".out";
+ LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile out_file_name"
+ << out_file_name;
+
+ if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR)
+ if (!write_buffer_to_file(out_file_name, *out_buffer)) {
+ throw std::runtime_error("write_buffer_to_file error");
+ };
+
+ return err;
+}
diff --git a/src/gpg/function/GpgFileOpera.h b/src/gpg/function/GpgFileOpera.h
new file mode 100644
index 00000000..4aaf09f1
--- /dev/null
+++ b/src/gpg/function/GpgFileOpera.h
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_GPGFILEOPERA_H
+#define GPGFRONTEND_GPGFILEOPERA_H
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> {
+ public:
+ static GpgError EncryptFile(KeyListPtr keys, const std::string& path,
+ GpgEncrResult& result);
+
+ static GpgError DecryptFile(const std::string& path, GpgDecrResult& result);
+
+ static GpgError SignFile(KeyListPtr keys, const std::string& path,
+ GpgSignResult& result);
+
+ static GpgError VerifyFile(const std::string& path, GpgVerifyResult& result);
+
+ static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys,
+ const std::string& path,
+ GpgEncrResult& encr_res,
+ GpgSignResult& sign_res);
+
+ static GpgError DecryptVerifyFile(const std::string& path,
+ GpgDecrResult& decr_res,
+ GpgVerifyResult& verify_res);
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_GPGFILEOPERA_H
diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp
new file mode 100644
index 00000000..be27d69e
--- /dev/null
+++ b/src/gpg/function/GpgKeyGetter.cpp
@@ -0,0 +1,75 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyGetter.h"
+
+#include <gpg-error.h>
+
+#include "GpgConstants.h"
+
+GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetKey(const std::string& fpr) {
+ gpgme_key_t _p_key;
+ 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;
+ 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(GpgKey(std::move(key)));
+ }
+
+ assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF);
+
+ err = gpgme_op_keylist_end(ctx);
+
+ 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;
+}
diff --git a/src/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h
new file mode 100644
index 00000000..c8f5d73a
--- /dev/null
+++ b/src/gpg/function/GpgKeyGetter.h
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+#define GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> {
+ public:
+ GpgKeyGetter() = default;
+
+ GpgKey GetKey(const std::string& fpr);
+
+ KeyListPtr GetKeys(const KeyIdArgsListPtr& ids);
+
+ GpgKey GetPubkey(const std::string& fpr);
+
+ KeyLinkListPtr FetchKey();
+
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
+};
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYGETTER_H
diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExportor.cpp
new file mode 100644
index 00000000..f4b88c60
--- /dev/null
+++ b/src/gpg/function/GpgKeyImportExportor.cpp
@@ -0,0 +1,117 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyImportExportor.h"
+
+#include "GpgConstants.h"
+
+/**
+ * Import key pair
+ * @param inBuffer input byte array
+ * @return Import information
+ */
+GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey(
+ StdBypeArrayPtr in_buffer) {
+ if (in_buffer->empty()) return GpgImportInformation();
+
+ GpgData data_in(in_buffer->data(), in_buffer->size());
+ auto err = check_gpg_error(gpgme_op_import(ctx, data_in));
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+ 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::GpgKeyImportExportor::ExportKeys(
+ KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const {
+ if (uid_list->empty()) return false;
+
+ // Alleviate another crash problem caused by an unknown array out-of-bounds
+ // access
+ for (size_t i = 0; i < uid_list->size(); i++) {
+ GpgData data_out;
+ auto err = gpgme_op_export(ctx, (*uid_list)[i].c_str(), 0, data_out);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ 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 true;
+}
+
+/**
+ * Export keys
+ * @param keys keys used
+ * @param outBuffer output byte array
+ * @return if success
+ */
+bool GpgFrontend::GpgKeyImportExportor::ExportKeys(
+ const KeyArgsList& keys, ByteArrayPtr& out_buffer) const {
+ KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>();
+ for (const auto& key : keys) key_ids->push_back(key.id());
+ return ExportKeys(key_ids, out_buffer);
+}
+
+/**
+ * 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::GpgKeyImportExportor::ExportSecretKey(
+ const GpgKey& key, ByteArrayPtr& out_buffer) const {
+ DLOG(INFO) << "Export Secret Key" << key.id().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;
+}
diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExportor.h
new file mode 100644
index 00000000..bceb87ef
--- /dev/null
+++ b/src/gpg/function/GpgKeyImportExportor.h
@@ -0,0 +1,100 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef _GPGKEYIMPORTEXPORTOR_H
+#define _GPGKEYIMPORTEXPORTOR_H
+
+#include <string>
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgImportedKey {
+ public:
+ std::string fpr;
+ int import_status;
+};
+
+typedef std::list<GpgImportedKey> GpgImportedKeyList;
+
+class GpgImportInformation {
+ public:
+ GpgImportInformation() = default;
+
+ 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;
+};
+
+class GpgKeyImportExportor
+ : public SingletonFunctionObject<GpgKeyImportExportor> {
+ public:
+ GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer);
+
+ bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const;
+
+ bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer) const;
+
+ bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const;
+
+ private:
+ GpgContext& ctx =
+ GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel());
+};
+
+} // namespace GpgFrontend
+
+#endif // _GPGKEYIMPORTEXPORTOR_H \ No newline at end of file
diff --git a/src/gpg/function/GpgKeyManager.cpp b/src/gpg/function/GpgKeyManager.cpp
new file mode 100644
index 00000000..9e24b3d6
--- /dev/null
+++ b/src/gpg/function/GpgKeyManager.cpp
@@ -0,0 +1,88 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyManager.h"
+
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <string>
+
+#include "gpg/function/BasicOperator.h"
+#include "gpg/function/GpgKeyGetter.h"
+
+bool GpgFrontend::GpgKeyManager::signKey(
+ const GpgFrontend::GpgKey& target, GpgFrontend::KeyArgsList& keys,
+ const std::string& uid,
+ const std::unique_ptr<boost::gregorian::date>& expires) {
+ using namespace boost::posix_time;
+
+ BasicOperator::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(ptime(*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.good());
+ 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::gregorian::date>& 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->fpr().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/gpg/function/GpgKeyManager.h b/src/gpg/function/GpgKeyManager.h
new file mode 100644
index 00000000..2b07425c
--- /dev/null
+++ b/src/gpg/function/GpgKeyManager.h
@@ -0,0 +1,58 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+#define GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgFunctionObject.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> {
+ public:
+ /**
+ * 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::gregorian::date>& expires);
+
+ bool revSign(const GpgFrontend::GpgKey& key,
+ const GpgFrontend::SignIdArgsListPtr& signature_id);
+
+ bool setExpire(const GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
+ std::unique_ptr<boost::gregorian::date>& expires);
+
+ private:
+ GpgContext& ctx = GpgContext::GetInstance();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H
diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp
new file mode 100644
index 00000000..c60f9157
--- /dev/null
+++ b/src/gpg/function/GpgKeyOpera.cpp
@@ -0,0 +1,217 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/GpgKeyOpera.h"
+
+#include <boost/asio.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <boost/process/async_pipe.hpp>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgGenKeyInfo.h"
+#include "gpg/function/GpgCommandExecutor.h"
+#include "gpg/function/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.good()) {
+ LOG(INFO) << "GpgKeyOpera DeleteKeys Get Key Good";
+ err = check_gpg_error(gpgme_op_delete(ctx, gpgme_key_t(key), 1));
+ assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
+ } else
+ LOG(WARNING) << "GpgKeyOpera DeleteKeys Get Key Bad";
+ }
+}
+
+/**
+ * Set the expire date and time of a key pair(actually the master key) or subkey
+ * @param key target key pair
+ * @param subkey null if master 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::gregorian::date>& expires) {
+ unsigned long expires_time = 0;
+ if (expires != nullptr) {
+ using namespace boost::posix_time;
+ using namespace std::chrono;
+ expires_time = to_time_t(ptime(*expires)) -
+ system_clock::to_time_t(system_clock::now());
+ }
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::SetExpire" << key.id() << subkey_fpr
+ << expires_time;
+
+ GpgError err;
+ if (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.fpr()};
+
+ 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) {
+ auto userid_utf8 = params->getUserid();
+ const char* userid = userid_utf8.c_str();
+ auto algo_utf8 = params->getAlgo() + params->getKeySizeStr();
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey 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->getExpired())) -
+ 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;
+ if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
+
+ LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Args: " << userid << algo
+ << expires << flags;
+
+ auto err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags);
+ 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->getExpired())) -
+ 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.id()
+ << algo << expires << flags;
+
+ auto err =
+ gpgme_op_createsubkey(ctx, gpgme_key_t(key), algo, 0, expires, flags);
+ return check_gpg_error(err);
+} \ No newline at end of file
diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h
new file mode 100644
index 00000000..71e2de8b
--- /dev/null
+++ b/src/gpg/function/GpgKeyOpera.h
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef _GPGKEYOPERA_H
+#define _GPGKEYOPERA_H
+
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgContext.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+class GenKeyInfo;
+class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> {
+ public:
+ void DeleteKeys(KeyIdArgsListPtr key_ids);
+
+ GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
+ std::unique_ptr<boost::gregorian::date>& expires);
+
+ static void GenerateRevokeCert(const GpgKey& key,
+ const std::string& output_file_name);
+
+ GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params);
+
+ GpgFrontend::GpgError GenerateSubkey(
+ const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params);
+
+ private:
+ GpgContext& ctx = GpgContext::GetInstance();
+};
+} // namespace GpgFrontend
+
+#endif // _GPGKEYOPERA_H \ No newline at end of file
diff --git a/src/gpg/function/UidOperator.cpp b/src/gpg/function/UidOperator.cpp
new file mode 100644
index 00000000..d7acc3b1
--- /dev/null
+++ b/src/gpg/function/UidOperator.cpp
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "gpg/function/UidOperator.h"
+
+#include "boost/format.hpp"
+
+bool GpgFrontend::UidOperator::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::UidOperator::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::UidOperator::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::UidOperator::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/gpg/function/UidOperator.h b/src/gpg/function/UidOperator.h
new file mode 100644
index 00000000..7d5df254
--- /dev/null
+++ b/src/gpg/function/UidOperator.h
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ *
+ * Foobar 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 Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+#define GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H
+
+#include "gpg/GpgContext.h"
+#include "gpg/GpgModel.h"
+
+namespace GpgFrontend {
+
+class UidOperator : public SingletonFunctionObject<UidOperator> {
+ public:
+ /**
+ * 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();
+};
+
+} // namespace GpgFrontend
+
+#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H