diff options
Diffstat (limited to 'src/gpg/function')
-rw-r--r-- | src/gpg/function/BasicOperator.cpp | 206 | ||||
-rw-r--r-- | src/gpg/function/BasicOperator.h | 69 | ||||
-rw-r--r-- | src/gpg/function/GpgCommandExecutor.cpp | 59 | ||||
-rw-r--r-- | src/gpg/function/GpgCommandExecutor.h | 52 | ||||
-rw-r--r-- | src/gpg/function/GpgFileOpera.cpp | 162 | ||||
-rw-r--r-- | src/gpg/function/GpgFileOpera.h | 58 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyGetter.cpp | 75 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyGetter.h | 52 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyImportExportor.cpp | 117 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyImportExportor.h | 100 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyManager.cpp | 88 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyManager.h | 58 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyOpera.cpp | 217 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyOpera.h | 54 | ||||
-rw-r--r-- | src/gpg/function/UidOperator.cpp | 64 | ||||
-rw-r--r-- | src/gpg/function/UidOperator.h | 76 |
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 |