diff options
author | saturneric <[email protected]> | 2024-01-10 03:41:34 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-01-10 03:41:34 +0000 |
commit | 802d7ed9907a08941af353fd65c6d528a8d5ba2c (patch) | |
tree | 4362de48824e960053fbb57fc29f078797af68e3 /src | |
parent | fix: slove some of the app building issues (diff) | |
download | GpgFrontend-802d7ed9907a08941af353fd65c6d528a8d5ba2c.tar.gz GpgFrontend-802d7ed9907a08941af353fd65c6d528a8d5ba2c.zip |
feat: update core apis, functions and models
Diffstat (limited to 'src')
-rw-r--r-- | src/core/function/KeyPackageOperator.cpp | 53 | ||||
-rw-r--r-- | src/core/function/KeyPackageOperator.h | 6 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyImportExporter.cpp | 155 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyImportExporter.h | 61 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyOpera.cpp | 93 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyOpera.h | 11 | ||||
-rw-r--r-- | src/core/model/GFBuffer.cpp | 9 | ||||
-rw-r--r-- | src/core/model/GFBuffer.h | 6 |
8 files changed, 206 insertions, 188 deletions
diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp index 4232937a..cd8482f2 100644 --- a/src/core/function/KeyPackageOperator.cpp +++ b/src/core/function/KeyPackageOperator.cpp @@ -37,6 +37,7 @@ #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/typedef/CoreTypedef.h" +#include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" namespace GpgFrontend { @@ -48,36 +49,46 @@ auto KeyPackageOperator::GeneratePassphrase( return WriteFileStd(phrase_path, phrase); } -auto KeyPackageOperator::GenerateKeyPackage( +void KeyPackageOperator::GenerateKeyPackage( const std::filesystem::path& key_package_path, - const std::string& key_package_name, KeyIdArgsListPtr& key_ids, - std::string& phrase, bool secret) -> bool { + const std::string& key_package_name, const KeyArgsList& keys, + std::string& phrase, bool secret, const OperationCallback& cb) { GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name); - ByteArrayPtr key_export_data = nullptr; - if (!GpgKeyImportExporter::GetInstance().ExportAllKeys( - key_ids, key_export_data, secret)) { - GF_CORE_LOG_ERROR("failed to export keys"); - return false; - } - - auto key = QByteArray::fromStdString(phrase); - auto data = QString::fromStdString(*key_export_data).toLocal8Bit().toBase64(); - - auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256); - QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, - QAESEncryption::Padding::ISO); - auto encoded = encryption.encode(data, hash_key); - - GF_CORE_LOG_DEBUG("writing key package: {}", key_package_name); - return WriteFileStd(key_package_path, encoded.toStdString()); + GpgKeyImportExporter::GetInstance().ExportKeys( + keys, secret, true, [=](GpgError err, const DataObjectPtr& data_obj) { + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + GF_LOG_ERROR("export keys error, reason: {}", + DescribeGpgErrCode(err).second); + cb(-1, data_obj); + return; + } + + if (data_obj == nullptr || !data_obj->Check<GFBuffer>()) { + throw std::runtime_error("data object doesn't pass checking"); + } + + auto gf_buffer = ExtractParams<GFBuffer>(data_obj, 0); + auto key = QByteArray::fromStdString(phrase); + auto data = gf_buffer.ConvertToQByteArray().toBase64(); + auto hash_key = + QCryptographicHash::hash(key, QCryptographicHash::Sha256); + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + auto encoded_data = encryption.encode(data, hash_key); + GF_CORE_LOG_DEBUG("writing key package, name: {}", key_package_name); + + cb(WriteFileStd(key_package_path, encoded_data.toStdString()) ? 0 : -1, + TransferParams()); + return; + }); } auto KeyPackageOperator::ImportKeyPackage( const std::filesystem::path& key_package_path, const std::filesystem::path& phrase_path, GpgImportInformation& import_info) -> bool { - GF_CORE_LOG_DEBUG("importing key package: {]", key_package_path.u8string()); + GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path.u8string()); std::string encrypted_data; ReadFileStd(key_package_path, encrypted_data); diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h index e2fcc3e4..84b30adc 100644 --- a/src/core/function/KeyPackageOperator.h +++ b/src/core/function/KeyPackageOperator.h @@ -67,10 +67,10 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator { * @return true if key package was generated * @return false if key package was not generated */ - static auto GenerateKeyPackage(const std::filesystem::path &key_package_path, + static void GenerateKeyPackage(const std::filesystem::path &key_package_path, const std::string &key_package_name, - KeyIdArgsListPtr &key_ids, std::string &phrase, - bool secret) -> bool; + const KeyArgsList &keys, std::string &phrase, + bool secret, const OperationCallback &cb); /** * @brief import key package diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp index e9ca3e84..9d474109 100644 --- a/src/core/function/gpg/GpgKeyImportExporter.cpp +++ b/src/core/function/gpg/GpgKeyImportExporter.cpp @@ -29,7 +29,7 @@ #include "GpgKeyImportExporter.h" #include "core/GpgModel.h" -#include "core/function/gpg/GpgKeyGetter.h" +#include "core/utils/AsyncUtils.h" #include "core/utils/GpgUtils.h" namespace GpgFrontend { @@ -67,43 +67,35 @@ auto GpgKeyImportExporter::ImportKey(StdBypeArrayPtr in_buffer) } /** - * Export Key - * @param uid_list key ids - * @param out_buffer output byte array + * Export keys + * @param keys keys used + * @param outBuffer output byte array * @return if success */ -auto GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list, - ByteArrayPtr& out_buffer, - bool secret) const -> bool { - if (uid_list->empty()) return false; +auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii, + bool shortest) const + -> std::tuple<GpgError, GFBuffer> { + if (!key.IsGood()) return {GPG_ERR_CANCELED, {}}; int mode = 0; if (secret) mode |= GPGME_EXPORT_MODE_SECRET; + if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL; - auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list); - auto* keys_array = new gpgme_key_t[keys->size() + 1]; + std::vector<gpgme_key_t> keys_array; - int index = 0; - for (const auto& key : *keys) { - keys_array[index++] = gpgme_key_t(key); - } - keys_array[index] = nullptr; + // Last entry data_in array has to be nullptr + keys_array.emplace_back(key); + keys_array.emplace_back(nullptr); GpgData data_out; - auto err = - gpgme_op_export_keys(ctx_.DefaultContext(), keys_array, mode, data_out); - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false; - - delete[] keys_array; - - GF_CORE_LOG_DEBUG("export keys read_bytes: {}", - gpgme_data_seek(data_out, 0, SEEK_END)); - - auto temp_out_buffer = data_out.Read2Buffer(); - - swap(temp_out_buffer, out_buffer); + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {}; - return true; + GF_CORE_LOG_DEBUG( + "operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii, + gpgme_data_seek(data_out, 0, SEEK_END)); + return {err, data_out.Read2GFBuffer()}; } /** @@ -112,72 +104,34 @@ auto GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list, * @param outBuffer output byte array * @return if success */ -auto GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, - ByteArrayPtr& out_buffer, - bool secret) const -> bool { - KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>(); - for (const auto& key : keys) key_ids->push_back(key.GetId()); - return ExportKeys(key_ids, out_buffer, secret); -} - -/** - * Export all the keys both private and public keys - * @param uid_list key ids - * @param out_buffer output byte array - * @return if success - */ -auto GpgKeyImportExporter::ExportAllKeys(KeyIdArgsListPtr& uid_list, - ByteArrayPtr& out_buffer, - bool secret) const -> bool { - bool result = true; - result = ((static_cast<int>(ExportKeys(uid_list, out_buffer, false)) & - static_cast<int>(result)) != 0); - - ByteArrayPtr temp_buffer; - if (secret) { - result = ((static_cast<int>(ExportKeys(uid_list, temp_buffer, true)) & - static_cast<int>(result)) != 0); - } - out_buffer->append(*temp_buffer); - return result; -} - -/** - * Export the secret key of a key pair(including subkeys) - * @param key target key pair - * @param outBuffer output byte array - * @return if successful - */ -auto GpgKeyImportExporter::ExportSecretKey(const GpgKey& key, - ByteArrayPtr& out_buffer) const - -> bool { - GF_CORE_LOG_DEBUG("export secret key: {}", key.GetId().c_str()); - - gpgme_key_t target_key[2] = {static_cast<gpgme_key_t>(key), nullptr}; - - GpgData data_out; - // export private key to outBuffer - gpgme_error_t err = gpgme_op_export_keys(ctx_.DefaultContext(), target_key, - GPGME_EXPORT_MODE_SECRET, data_out); - - auto temp_out_buffer = data_out.Read2Buffer(); - std::swap(out_buffer, temp_out_buffer); - - return CheckGpgError(err) == GPG_ERR_NO_ERROR; -} - -auto GpgKeyImportExporter::ExportKey(const GpgKey& key, - ByteArrayPtr& out_buffer) const -> bool { - GpgData data_out; - auto err = - gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(), 0, data_out); - - GF_CORE_LOG_DEBUG("export keys 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 CheckGpgError(err) == GPG_ERR_NO_ERROR; +void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret, + bool ascii, + const GpgOperationCallback& cb) const { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + if (keys.empty()) return GPG_ERR_CANCELED; + + int mode = 0; + if (secret) mode |= GPGME_EXPORT_MODE_SECRET; + + std::vector<gpgme_key_t> keys_array(keys.begin(), keys.end()); + + // Last entry data_in array has to be nullptr + keys_array.emplace_back(nullptr); + + GpgData data_out; + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {}; + + GF_CORE_LOG_DEBUG( + "operation of exporting keys finished, ascii: {}, read_bytes: {}", + ascii, gpgme_data_seek(data_out, 0, SEEK_END)); + + data_object->Swap({data_out.Read2GFBuffer()}); + return err; + }, + cb, "gpgme_op_export_keys", "2.1.0"); } auto GpgKeyImportExporter::ExportKeyOpenSSH(const GpgKey& key, @@ -194,19 +148,6 @@ auto GpgKeyImportExporter::ExportKeyOpenSSH(const GpgKey& key, return CheckGpgError(err) == GPG_ERR_NO_ERROR; } -auto GpgKeyImportExporter::ExportSecretKeyShortest( - const GpgKey& key, ByteArrayPtr& out_buffer) const -> bool { - GpgData data_out; - auto err = gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(), - GPGME_EXPORT_MODE_MINIMAL, data_out); - - GF_CORE_LOG_DEBUG("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 CheckGpgError(err) == GPG_ERR_NO_ERROR; -} - GpgImportInformation::GpgImportInformation() = default; GpgImportInformation::GpgImportInformation(gpgme_import_result_t result) { diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h index 3c88c2c5..707bd895 100644 --- a/src/core/function/gpg/GpgKeyImportExporter.h +++ b/src/core/function/gpg/GpgKeyImportExporter.h @@ -30,6 +30,7 @@ #include "core/function/basic/GpgFunctionObject.h" #include "core/function/gpg/GpgContext.h" +#include "core/model/GFBuffer.h" #include "core/typedef/CoreTypedef.h" #include "core/typedef/GpgTypedef.h" @@ -105,26 +106,14 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter /** * @brief * - * @param uid_list - * @param out_buffer - * @param secret - * @return true - * @return false - */ - auto ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, - bool secret = false) const -> bool; - - /** - * @brief - * - * @param keys - * @param outBuffer + * @param key * @param secret - * @return true - * @return false + * @param ascii + * @return std::tuple<GpgError, GFBuffer> */ - auto ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer, - bool secret = false) const -> bool; + [[nodiscard]] auto ExportKey(const GpgKey& key, bool secret, bool ascii, + bool shortest) const + -> std::tuple<GpgError, GFBuffer>; /** * @brief @@ -135,18 +124,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter * @return true * @return false */ - auto ExportAllKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer, - bool secret) const -> bool; - - /** - * @brief - * - * @param key - * @param out_buffer - * @return true - * @return false - */ - auto ExportKey(const GpgKey& key, ByteArrayPtr& out_buffer) const -> bool; + void ExportKeys(const KeyArgsList& keys, bool secret, bool ascii, + const GpgOperationCallback& cb) const; /** * @brief @@ -159,28 +138,6 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter auto ExportKeyOpenSSH(const GpgKey& key, ByteArrayPtr& out_buffer) const -> bool; - /** - * @brief - * - * @param key - * @param outBuffer - * @return true - * @return false - */ - auto ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const - -> bool; - - /** - * @brief - * - * @param key - * @param outBuffer - * @return true - * @return false - */ - auto ExportSecretKeyShortest(const GpgKey& key, ByteArrayPtr& outBuffer) const - -> bool; - private: GpgContext& ctx_; }; diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 49703781..90852b42 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -207,7 +207,7 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params, return CheckGpgError(err); }, - callback, "gpgme_op_passwd", "2.1.0"); + callback, "gpgme_op_createkey", "2.1.0"); } /** @@ -254,6 +254,97 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key, callback, "gpgme_op_createsubkey", "2.1.13"); } +void GpgKeyOpera::GenerateKeyWithSubkey( + const std::shared_ptr<GenKeyInfo>& params, + const std::shared_ptr<GenKeyInfo>& subkey_params, + const GpgOperationCallback& callback) { + RunGpgOperaAsync( + [&ctx = ctx_, params, + subkey_params](const DataObjectPtr& data_object) -> GpgError { + auto userid_utf8 = params->GetUserid(); + const char* userid = userid_utf8.c_str(); + auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr(); + + const char* algo = algo_utf8.c_str(); + unsigned long expires = 0; + expires = to_time_t(boost::posix_time::ptime(params->GetExpireTime())) - + std::chrono::system_clock::to_time_t( + std::chrono ::system_clock::now()); + + GpgError err; + 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; + + GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires, + flags); + err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires, + nullptr, flags); + + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + data_object->Swap({GpgGenerateKeyResult{}}); + return err; + } + + auto genkey_result = + GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())}; + + auto key = + GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint()); + if (!key.IsGood()) { + GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}", + genkey_result.GetFingerprint()); + return err; + } + + if (subkey_params == nullptr || !subkey_params->IsSubKey()) return err; + + GF_CORE_LOG_DEBUG( + "try to generate subkey of key: {}, algo {} key size {}", + key.GetId(), subkey_params->GetAlgo(), + subkey_params->GetKeySizeStr()); + + algo_utf8 = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr()); + algo = algo_utf8.c_str(); + expires = 0; + + expires = to_time_t(boost::posix_time::ptime( + subkey_params->GetExpireTime())) - + std::chrono::system_clock::to_time_t( + std::chrono::system_clock::now()); + + flags = 0; + if (subkey_params->IsAllowEncryption()) flags |= GPGME_CREATE_ENCR; + if (subkey_params->IsAllowSigning()) flags |= GPGME_CREATE_SIGN; + if (subkey_params->IsAllowAuthentication()) flags |= GPGME_CREATE_AUTH; + if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; + if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; + + GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(), + algo, expires, flags); + + err = gpgme_op_createsubkey(ctx.DefaultContext(), + static_cast<gpgme_key_t>(key), algo, 0, + expires, flags); + + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + data_object->Swap( + {genkey_result, GpgGenerateKeyResult{gpgme_op_genkey_result( + ctx.DefaultContext())}}); + } else { + data_object->Swap({genkey_result, GpgGenerateKeyResult{}}); + } + + return CheckGpgError(err); + }, + callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0"); +} + void GpgKeyOpera::ModifyPassword(const GpgKey& key, const GpgOperationCallback& callback) { RunGpgOperaAsync( diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h index 34bcd976..5039aa9e 100644 --- a/src/core/function/gpg/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -131,6 +131,17 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera const std::shared_ptr<GenKeyInfo>& params, const GpgOperationCallback&); + /** + * @brief + * + * @param params + * @param subkey_params + * @param callback + */ + void GenerateKeyWithSubkey(const std::shared_ptr<GenKeyInfo>& params, + const std::shared_ptr<GenKeyInfo>& subkey_params, + const GpgOperationCallback& callback); + private: GpgContext& ctx_ = GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< diff --git a/src/core/model/GFBuffer.cpp b/src/core/model/GFBuffer.cpp index 7608e9f5..117a6f12 100644 --- a/src/core/model/GFBuffer.cpp +++ b/src/core/model/GFBuffer.cpp @@ -68,16 +68,21 @@ auto GFBuffer::operator==(const GFBuffer& o) const -> bool { return equal(buffer_->begin(), buffer_->end(), o.buffer_->begin()); } -auto GFBuffer::Data() -> std::byte* { return buffer_->data(); } +auto GFBuffer::Data() const -> std::byte* { return buffer_->data(); } void GFBuffer::Resize(size_t size) { buffer_->resize(size); } auto GFBuffer::Size() const -> size_t { return buffer_->size(); } -auto GFBuffer::ConvertToQByteArray() -> QByteArray { +auto GFBuffer::ConvertToQByteArray() const -> QByteArray { return QByteArray::fromRawData(reinterpret_cast<const char*>(Data()), static_cast<qsizetype>(Size())); } auto GFBuffer::Empty() const -> bool { return this->Size() == 0; } + +auto GFBuffer::ConvertToStdString() const -> std::string { + return {reinterpret_cast<const char*>(buffer_->data()), buffer_->size()}; +} + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/model/GFBuffer.h b/src/core/model/GFBuffer.h index 57fbbc43..7cd5cbc5 100644 --- a/src/core/model/GFBuffer.h +++ b/src/core/model/GFBuffer.h @@ -47,7 +47,7 @@ class GPGFRONTEND_CORE_EXPORT GFBuffer { auto operator==(const GFBuffer& o) const -> bool; - auto Data() -> std::byte*; + [[nodiscard]] auto Data() const -> std::byte*; void Resize(size_t size); @@ -55,7 +55,9 @@ class GPGFRONTEND_CORE_EXPORT GFBuffer { [[nodiscard]] auto Empty() const -> bool; - auto ConvertToQByteArray() -> QByteArray; + [[nodiscard]] auto ConvertToQByteArray() const -> QByteArray; + + [[nodiscard]] auto ConvertToStdString() const -> std::string; private: std::shared_ptr<std::vector<std::byte>> buffer_; |