diff options
Diffstat (limited to 'src/gpg/function')
-rw-r--r-- | src/gpg/function/BasicOperator.cpp | 9 | ||||
-rw-r--r-- | src/gpg/function/BasicOperator.h | 6 | ||||
-rw-r--r-- | src/gpg/function/GpgCommandExecutor.h | 6 | ||||
-rw-r--r-- | src/gpg/function/GpgFileOpera.cpp | 106 | ||||
-rw-r--r-- | src/gpg/function/GpgFileOpera.h | 37 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyGetter.cpp | 4 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyGetter.h | 6 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyImportExporter.cpp (renamed from src/gpg/function/GpgKeyImportExportor.cpp) | 62 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyImportExporter.h (renamed from src/gpg/function/GpgKeyImportExportor.h) | 16 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyManager.h | 7 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyOpera.cpp | 85 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyOpera.h | 12 | ||||
-rw-r--r-- | src/gpg/function/UidOperator.h | 7 |
13 files changed, 236 insertions, 127 deletions
diff --git a/src/gpg/function/BasicOperator.cpp b/src/gpg/function/BasicOperator.cpp index 56b7ca54..0383f8ab 100644 --- a/src/gpg/function/BasicOperator.cpp +++ b/src/gpg/function/BasicOperator.cpp @@ -75,8 +75,7 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Verify( BypeArrayRef& in_buffer, ByteArrayPtr& sig_buffer, GpgVerifyResult& result) const { gpgme_error_t err; - - LOG(INFO) << "in buffer size" << in_buffer.size(); + GpgData data_in(in_buffer.data(), in_buffer.size()); GpgData data_out; @@ -187,9 +186,11 @@ gpgme_error_t GpgFrontend::BasicOperator::EncryptSign( void GpgFrontend::BasicOperator::SetSigners(KeyArgsList& keys) { gpgme_signers_clear(ctx); for (const GpgKey& key : keys) { + DLOG(INFO) << "key" << key.fpr(); if (key.CanSignActual()) { - auto gpgmeError = gpgme_signers_add(ctx, gpgme_key_t(key)); - check_gpg_error(gpgmeError); + DLOG(INFO) << "signer"; + auto error = gpgme_signers_add(ctx, gpgme_key_t(key)); + check_gpg_error(error); } } if (keys.size() != gpgme_signers_count(ctx)) diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h index 4ea70eea..41bd9b7f 100644 --- a/src/gpg/function/BasicOperator.h +++ b/src/gpg/function/BasicOperator.h @@ -34,6 +34,10 @@ namespace GpgFrontend { class BasicOperator : public SingletonFunctionObject<BasicOperator> { public: + explicit BasicOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<BasicOperator>(channel) {} + gpg_error_t Encrypt(KeyListPtr keys, BypeArrayRef in_buffer, ByteArrayPtr& out_buffer, GpgEncrResult& result); @@ -65,7 +69,7 @@ class BasicOperator : public SingletonFunctionObject<BasicOperator> { private: GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel()); + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgCommandExecutor.h b/src/gpg/function/GpgCommandExecutor.h index f28caca8..dcdd318d 100644 --- a/src/gpg/function/GpgCommandExecutor.h +++ b/src/gpg/function/GpgCommandExecutor.h @@ -35,6 +35,9 @@ namespace GpgFrontend { class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> { public: + explicit GpgCommandExecutor( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgCommandExecutor>(channel) {} #ifndef WINDOWS void Execute(StringArgsRef arguments, @@ -44,7 +47,8 @@ class GpgCommandExecutor : public SingletonFunctionObject<GpgCommandExecutor> { #endif private: - GpgContext &ctx = GpgContext::GetInstance(); + GpgContext &ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgFileOpera.cpp b/src/gpg/function/GpgFileOpera.cpp index 42b37c71..8babfa6d 100644 --- a/src/gpg/function/GpgFileOpera.cpp +++ b/src/gpg/function/GpgFileOpera.cpp @@ -30,15 +30,16 @@ #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); + KeyListPtr keys, const std::string& in_path, const std::string& out_path, + GpgEncrResult& result, int _channel) { + std::string in_buffer = read_all_data_in_file(in_path); std::unique_ptr<std::string> out_buffer; - auto err = BasicOperator::GetInstance().Encrypt(std::move(keys), in_buffer, - out_buffer, result); + auto err = BasicOperator::GetInstance(_channel).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)) { + if (!write_buffer_to_file(out_path, *out_buffer)) { throw std::runtime_error("write_buffer_to_file error"); }; @@ -46,8 +47,9 @@ GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile( } GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile( - const std::string& path, GpgDecrResult& result) { - std::string in_buffer = read_all_data_in_file(path); + const std::string& in_path, const std::string& out_path, + GpgDecrResult& result) { + std::string in_buffer = read_all_data_in_file(in_path); std::unique_ptr<std::string> out_buffer; auto err = @@ -55,14 +57,8 @@ GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile( 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)) { + if (!write_buffer_to_file(out_path, *out_buffer)) { throw std::runtime_error("write_buffer_to_file error"); }; @@ -70,58 +66,49 @@ GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile( } gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys, - const std::string& path, - GpgSignResult& result) { - auto in_buffer = read_all_data_in_file(path); + const std::string& in_path, + const std::string& out_path, + GpgSignResult& result, + int _channel) { + auto in_buffer = read_all_data_in_file(in_path); std::unique_ptr<std::string> out_buffer; - auto err = BasicOperator::GetInstance().Sign( + auto err = BasicOperator::GetInstance(_channel).Sign( std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(path + ".sig", *out_buffer)) { + if (!write_buffer_to_file(out_path, *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); +gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile( + const std::string& data_path, const std::string& sign_path, + GpgVerifyResult& result, int _channel) { + auto in_buffer = read_all_data_in_file(data_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); - return err; - } else { + if (!sign_path.empty()) { 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; + std::make_unique<std::string>(read_all_data_in_file(sign_path)); } + auto err = BasicOperator::GetInstance(_channel).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); + KeyListPtr keys, KeyListPtr signer_keys, const std::string& in_path, + const std::string& out_path, GpgEncrResult& encr_res, + GpgSignResult& sign_res, int _channel) { + auto in_buffer = read_all_data_in_file(in_path); std::unique_ptr<std::string> out_buffer = nullptr; - // TODO dealing with signer keys - auto err = BasicOperator::GetInstance().EncryptSign( + auto err = BasicOperator::GetInstance(_channel).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"); @@ -131,28 +118,33 @@ gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile( } gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile( - const std::string& path, GpgDecrResult& decr_res, - GpgVerifyResult& verify_res) { - LOG(INFO) << "GpgFrontend::GpgFileOpera::DecryptVerifyFile Called"; + const std::string& in_path, const std::string& out_path, + GpgDecrResult& decr_res, GpgVerifyResult& verify_res) { + auto in_buffer = read_all_data_in_file(in_path); - 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 (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; +} +unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric( + const std::string& in_path, const std::string& out_path, + GpgFrontend::GpgEncrResult& result, int _channel) { + std::string in_buffer = read_all_data_in_file(in_path); + std::unique_ptr<std::string> out_buffer; - if (!(file_extension == ".asc" || file_extension == ".gpg")) - out_file_name = path + ".out"; - LOG(INFO) << "out_file_name" << out_file_name; + auto err = BasicOperator::GetInstance(_channel).EncryptSymmetric( + in_buffer, out_buffer, result); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) - if (!write_buffer_to_file(out_file_name, *out_buffer)) { + if (!write_buffer_to_file(out_path, *out_buffer)) { throw std::runtime_error("write_buffer_to_file error"); }; diff --git a/src/gpg/function/GpgFileOpera.h b/src/gpg/function/GpgFileOpera.h index 4aaf09f1..f4508f42 100644 --- a/src/gpg/function/GpgFileOpera.h +++ b/src/gpg/function/GpgFileOpera.h @@ -33,22 +33,41 @@ namespace GpgFrontend { class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> { public: - static GpgError EncryptFile(KeyListPtr keys, const std::string& path, - GpgEncrResult& result); + explicit GpgFileOpera( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgFileOpera>(channel) {} - static GpgError DecryptFile(const std::string& path, GpgDecrResult& result); + static unsigned int EncryptFile(KeyListPtr keys, const std::string& in_path, + const std::string& out_path, + GpgEncrResult& result, + int _channel = GPGFRONTEND_DEFAULT_CHANNEL); - static GpgError SignFile(KeyListPtr keys, const std::string& path, - GpgSignResult& result); + static unsigned int EncryptFileSymmetric( + const std::string& in_path, const std::string& out_path, + GpgEncrResult& result, int _channel = GPGFRONTEND_DEFAULT_CHANNEL); - static GpgError VerifyFile(const std::string& path, GpgVerifyResult& result); + static GpgError DecryptFile(const std::string& in_path, + const std::string& out_path, + GpgDecrResult& result); + + static GpgError SignFile(KeyListPtr keys, const std::string& in_path, + const std::string& out_path, GpgSignResult& result, + int _channel = GPGFRONTEND_DEFAULT_CHANNEL); + + static GpgError VerifyFile(const std::string& data_path, + const std::string& sign_path, + GpgVerifyResult& result, + int _channel = GPGFRONTEND_DEFAULT_CHANNEL); static GpgError EncryptSignFile(KeyListPtr keys, KeyListPtr signer_keys, - const std::string& path, + const std::string& in_path, + const std::string& out_path, GpgEncrResult& encr_res, - GpgSignResult& sign_res); + GpgSignResult& sign_res, + int _channel = GPGFRONTEND_DEFAULT_CHANNEL); - static GpgError DecryptVerifyFile(const std::string& path, + static GpgError DecryptVerifyFile(const std::string& in_path, + const std::string& out_path, GpgDecrResult& decr_res, GpgVerifyResult& verify_res); }; diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp index 664aff56..8a26dcd9 100644 --- a/src/gpg/function/GpgKeyGetter.cpp +++ b/src/gpg/function/GpgKeyGetter.cpp @@ -58,13 +58,15 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { gpgme_key_t key; while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { - keys_list->push_back(GpgKey(std::move(key))); + keys_list->push_back(GetKey(key->fpr)); } assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF); err = gpgme_op_keylist_end(ctx); + assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR); + return keys_list; } diff --git a/src/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h index 3af51815..fcd518d3 100644 --- a/src/gpg/function/GpgKeyGetter.h +++ b/src/gpg/function/GpgKeyGetter.h @@ -33,7 +33,9 @@ namespace GpgFrontend { class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { public: - GpgKeyGetter() = default; + explicit GpgKeyGetter( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyGetter>(channel) {} GpgKey GetKey(const std::string& fpr); @@ -49,7 +51,7 @@ class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { private: GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel()); + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExporter.cpp index 89d3b002..dd027eab 100644 --- a/src/gpg/function/GpgKeyImportExportor.cpp +++ b/src/gpg/function/GpgKeyImportExporter.cpp @@ -22,16 +22,17 @@ * */ -#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyImportExporter.h" #include "GpgConstants.h" +#include "gpg/function/GpgKeyGetter.h" /** * Import key pair * @param inBuffer input byte array * @return Import information */ -GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( +GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExporter::ImportKey( StdBypeArrayPtr in_buffer) { if (in_buffer->empty()) return {}; @@ -60,25 +61,37 @@ GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( * @param out_buffer output byte array * @return if success */ -bool GpgFrontend::GpgKeyImportExportor::ExportKeys( - KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const { +bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list, + ByteArrayPtr& out_buffer, + bool secret) const { if (uid_list->empty()) return false; - // Alleviate another crash problem caused by an unknown array out-of-bounds - // access - auto all_success = true; - 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); - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) all_success = false; - 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); + int _mode = 0; + if (secret) _mode |= GPGME_EXPORT_MODE_SECRET; + + auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list); + auto keys_array = new gpgme_key_t[keys->size() + 1]; + + int index = 0; + for (const auto& key : *keys) { + keys_array[index++] = gpgme_key_t(key); } + keys_array[index] = nullptr; + + GpgData data_out; + auto err = gpgme_op_export_keys(ctx, keys_array, _mode, data_out); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false; + + delete[] keys_array; + + DLOG(INFO) << "exportKeys read_bytes" + << gpgme_data_seek(data_out, 0, SEEK_END); + + auto temp_out_buffer = data_out.Read2Buffer(); + + swap(temp_out_buffer, out_buffer); - return all_success; + return true; } /** @@ -87,11 +100,12 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( * @param outBuffer output byte array * @return if success */ -bool GpgFrontend::GpgKeyImportExportor::ExportKeys( - const KeyArgsList& keys, ByteArrayPtr& out_buffer) const { +bool GpgFrontend::GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, + ByteArrayPtr& out_buffer, + bool secret) const { KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>(); for (const auto& key : keys) key_ids->push_back(key.id()); - return ExportKeys(key_ids, out_buffer); + return ExportKeys(key_ids, out_buffer, secret); } /** @@ -100,7 +114,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( * @param outBuffer output byte array * @return if successful */ -bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( +bool GpgFrontend::GpgKeyImportExporter::ExportSecretKey( const GpgKey& key, ByteArrayPtr& out_buffer) const { DLOG(INFO) << "Export Secret Key" << key.id().c_str(); @@ -117,7 +131,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyImportExportor::ExportKey( +bool GpgFrontend::GpgKeyImportExporter::ExportKey( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; @@ -131,7 +145,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKey( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyImportExportor::ExportKeyOpenSSH( +bool GpgFrontend::GpgKeyImportExporter::ExportKeyOpenSSH( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; @@ -145,7 +159,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeyOpenSSH( return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; } -bool GpgFrontend::GpgKeyImportExportor::ExportSecretKeyShortest( +bool GpgFrontend::GpgKeyImportExporter::ExportSecretKeyShortest( const GpgFrontend::GpgKey& key, GpgFrontend::ByteArrayPtr& out_buffer) const { GpgData data_out; diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExporter.h index ad43d539..64b3b8a9 100644 --- a/src/gpg/function/GpgKeyImportExportor.h +++ b/src/gpg/function/GpgKeyImportExporter.h @@ -79,14 +79,20 @@ class GpgImportInformation { GpgImportedKeyList importedKeys; }; -class GpgKeyImportExportor - : public SingletonFunctionObject<GpgKeyImportExportor> { +class GpgKeyImportExporter + : public SingletonFunctionObject<GpgKeyImportExporter> { public: + explicit GpgKeyImportExporter( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyImportExporter>(channel) {} + GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer); - bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const; + bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, + bool secret = false) const; - bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer) const; + bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer, + bool secret = false) const; bool ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const; @@ -99,7 +105,7 @@ class GpgKeyImportExportor private: GpgContext& ctx = - GpgContext::GetInstance(SingletonFunctionObject::GetDefaultChannel()); + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyManager.h b/src/gpg/function/GpgKeyManager.h index 01254962..b2444e8d 100644 --- a/src/gpg/function/GpgKeyManager.h +++ b/src/gpg/function/GpgKeyManager.h @@ -33,6 +33,10 @@ namespace GpgFrontend { class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { public: + explicit GpgKeyManager( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyManager>(channel) {} + /** * Sign a key pair(actually a certain uid) * @param target target key pair @@ -50,7 +54,8 @@ class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { std::unique_ptr<boost::posix_time::ptime>& expires); private: - GpgContext& ctx = GpgContext::GetInstance(); + GpgContext& ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp index 4bad303d..e9fcbc1d 100644 --- a/src/gpg/function/GpgKeyOpera.cpp +++ b/src/gpg/function/GpgKeyOpera.cpp @@ -26,6 +26,7 @@ #include <boost/asio.hpp> #include <boost/date_time/posix_time/conversion.hpp> +#include <boost/format.hpp> #include <boost/process/async_pipe.hpp> #include <memory> #include <string> @@ -46,18 +47,21 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys( 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)); + err = check_gpg_error( + gpgme_op_delete_ext(ctx, gpgme_key_t(key), + GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE)); assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); - } else - LOG(WARNING) << "GpgKeyOpera DeleteKeys Get Key Bad"; + } else { + LOG(WARNING) << "GpgKeyOpera DeleteKeys get key failed" << tmp; + } } } /** - * Set the expire date and time of a key pair(actually the master key) or subkey + * Set the expire date and time of a key pair(actually the primary key) or + * subkey * @param key target key pair - * @param subkey null if master key + * @param subkey null if primary key * @param expires date and time * @return if successful */ @@ -146,13 +150,12 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( * @return error information */ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( - const std::unique_ptr<GenKeyInfo>& params) { + const std::unique_ptr<GenKeyInfo>& params, GpgGenKeyResult& result) { auto userid_utf8 = params->getUserid(); const char* userid = userid_utf8.c_str(); auto algo_utf8 = params->getAlgo() + params->getKeySizeStr(); - LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Params" - << params->getAlgo() << params->getKeySizeStr(); + LOG(INFO) << "params" << params->getAlgo() << params->getKeySizeStr(); const char* algo = algo_utf8.c_str(); unsigned long expires = 0; @@ -163,19 +166,57 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( system_clock::to_time_t(system_clock::now()); } - unsigned int flags = 0; + GpgError err; - 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; + if (ctx.GetInfo().GnupgVersion >= "2.1.0") { + unsigned int flags = 0; + + if (!params->isSubKey()) flags |= GPGME_CREATE_CERT; + if (params->isAllowEncryption()) flags |= GPGME_CREATE_ENCR; + if (params->isAllowSigning()) flags |= GPGME_CREATE_SIGN; + if (params->isAllowAuthentication()) flags |= GPGME_CREATE_AUTH; + if (params->isNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; + if (params->isNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; + + LOG(INFO) << "args: " << userid << algo << expires << flags; + + err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); - LOG(INFO) << "GpgFrontend::GpgKeyOpera::GenerateKey Args: " << userid << algo - << expires << flags; + } else { + std::stringstream ss; + auto param_format = + boost::format{ + "<GnupgKeyParms format=\"internal\">\n" + "Key-Type: %1%\n" + "Key-Usage: sign\n" + "Key-Length: %2%\n" + "Name-Real: %3%\n" + "Name-Comment: %4%\n" + "Name-Email: %5%\n"} % + params->getAlgo() % params->getKeySize() % params->getName() % + params->getComment() % params->getEmail(); + ss << param_format; + + if (!params->isNonExpired()) { + auto date = params->getExpired().date(); + ss << boost::format{"Expire-Date: %1%\n"} % to_iso_string(date); + } else + ss << boost::format{"Expire-Date: 0\n"}; + if (!params->isNoPassPhrase()) + ss << boost::format{"Passphrase: %1%\n"} % params->getPassPhrase(); + + ss << "</GnupgKeyParms>"; + + DLOG(INFO) << "params" << std::endl << ss.str(); + + err = gpgme_op_genkey(ctx, ss.str().c_str(), nullptr, nullptr); + } + + if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) { + auto temp_result = _new_result(gpgme_op_genkey_result(ctx)); + std::swap(temp_result, result); + } - auto err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags); return check_gpg_error(err); } @@ -234,3 +275,9 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::ModifyTOFUPolicy( auto err = gpgme_op_tofu_policy(ctx, gpgme_key_t(key), tofu_policy); return check_gpg_error(err); } + +void GpgFrontend::GpgKeyOpera::DeleteKey(const GpgFrontend::KeyId& key_id) { + auto keys = std::make_unique<KeyIdArgsList>(); + keys->push_back(key_id); + DeleteKeys(std::move(keys)); +} diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h index 7decfd79..73b8bdb5 100644 --- a/src/gpg/function/GpgKeyOpera.h +++ b/src/gpg/function/GpgKeyOpera.h @@ -33,8 +33,14 @@ namespace GpgFrontend { class GenKeyInfo; class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { public: + explicit GpgKeyOpera( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<GpgKeyOpera>(channel) {} + void DeleteKeys(KeyIdArgsListPtr key_ids); + void DeleteKey(const KeyId& key_id); + GpgError SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, std::unique_ptr<boost::posix_time::ptime>& expires); @@ -46,13 +52,15 @@ class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { GpgFrontend::GpgError ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy); - GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params); + GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params, + GpgGenKeyResult& result); GpgFrontend::GpgError GenerateSubkey( const GpgKey& key, const std::unique_ptr<GenKeyInfo>& params); private: - GpgContext& ctx = GpgContext::GetInstance(); + GpgContext& ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend diff --git a/src/gpg/function/UidOperator.h b/src/gpg/function/UidOperator.h index 7d5df254..d1a92b38 100644 --- a/src/gpg/function/UidOperator.h +++ b/src/gpg/function/UidOperator.h @@ -32,6 +32,10 @@ namespace GpgFrontend { class UidOperator : public SingletonFunctionObject<UidOperator> { public: + explicit UidOperator( + int channel = SingletonFunctionObject::GetDefaultChannel()) + : SingletonFunctionObject<UidOperator>(channel) {} + /** * create a new uid in certain key pair * @param key target key pair @@ -68,7 +72,8 @@ class UidOperator : public SingletonFunctionObject<UidOperator> { bool setPrimaryUID(const GpgKey& key, const std::string& uid); private: - GpgContext& ctx = GpgContext::GetInstance(); + GpgContext& ctx = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); }; } // namespace GpgFrontend |