diff options
34 files changed, 2125 insertions, 706 deletions
diff --git a/src/cmd.cpp b/src/cmd.cpp index e19ad218..f060a16b 100644 --- a/src/cmd.cpp +++ b/src/cmd.cpp @@ -41,22 +41,21 @@ namespace GpgFrontend { auto PrintVersion() -> int { - QTextStream stream(stdin); + QTextStream stream(stdout); stream << PROJECT_NAME << " " << "v" << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH << '\n'; - stream << "Copyright (C) 2021 Saturneric <[email protected]>" << '\n' + stream << "Copyright (©) 2021 Saturneric <[email protected]>" << '\n' << QObject::tr( "This is free software; see the source for copying conditions.") << '\n' << '\n'; - stream << QObject::tr("Build Timestamp: ") << BUILD_TIMESTAMP << '\n' + stream << QObject::tr("Build DateTime: ") << BUILD_TIMESTAMP << '\n' << QObject::tr("Build Version: ") << BUILD_VERSION << '\n' << QObject::tr("Source Code Version: ") << GIT_VERSION << '\n'; stream << Qt::endl; - return 0; } diff --git a/src/core/function/ArchiveFileOperator.cpp b/src/core/function/ArchiveFileOperator.cpp index ef04d69f..54c78628 100644 --- a/src/core/function/ArchiveFileOperator.cpp +++ b/src/core/function/ArchiveFileOperator.cpp @@ -159,21 +159,10 @@ void ArchiveFileOperator::NewArchive2DataExchanger( auto fd = open(archive_entry_sourcepath(entry), O_RDONLY); auto len = read(fd, buff.data(), buff.size()); assert(len <= buff.size() && len > 0); - if (len == -1) { - GF_CORE_LOG_ERROR("read() failed, ret: {}, abort ...", len); - archive_entry_free(entry); - close(fd); - break; - } - while (len > 0) { archive_write_data(archive, buff.data(), len); len = read(fd, buff.data(), buff.size()); assert(len <= buff.size() && len > 0); - if (len == -1) { - GF_CORE_LOG_ERROR("read() failed, ret: {}, abort ...", len); - break; - } } close(fd); } diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp index e5916c77..8b62aad0 100644 --- a/src/core/function/gpg/GpgBasicOperator.cpp +++ b/src/core/function/gpg/GpgBasicOperator.cpp @@ -43,9 +43,11 @@ namespace GpgFrontend { GpgBasicOperator::GpgBasicOperator(int channel) : SingletonFunctionObject<GpgBasicOperator>(channel) {} -void GpgBasicOperator::Encrypt(KeyArgsList keys, GFBuffer in_buffer, bool ascii, +void GpgBasicOperator::Encrypt(const KeyArgsList& keys, + const GFBuffer& in_buffer, bool ascii, const GpgOperationCallback& cb) { - RunGpgOperaAsync([=](const DataObjectPtr& data_object) -> GpgError { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { if (keys.empty()) return GPG_ERR_CANCELED; std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); @@ -68,7 +70,71 @@ void GpgBasicOperator::Encrypt(KeyArgsList keys, GFBuffer in_buffer, bool ascii, cb, "gpgme_op_encrypt", "2.1.0"); } -void GpgBasicOperator::Decrypt(GFBuffer in_buffer, +auto GpgBasicOperator::EncryptSync(const KeyArgsList& keys, + const GFBuffer& in_buffer, bool ascii) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + if (keys.empty()) return GPG_ERR_CANCELED; + + std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); + + // Last entry data_in array has to be nullptr + recipients.emplace_back(nullptr); + + GpgData data_in(in_buffer); + GpgData data_out; + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(), + GPGME_ENCRYPT_ALWAYS_TRUST, + data_in, data_out)); + data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + data_out.Read2GFBuffer()}); + + return err; + }, + "gpgme_op_encrypt", "2.1.0"); +} + +void GpgBasicOperator::EncryptSymmetric(const GFBuffer& in_buffer, bool ascii, + const GpgOperationCallback& cb) { + RunGpgOperaAsync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(in_buffer); + GpgData data_out; + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = CheckGpgError(gpgme_op_encrypt( + ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); + data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + data_out.Read2GFBuffer()}); + + return err; + }, + cb, "gpgme_op_encrypt_symmetric", "2.1.0"); +} + +auto GpgBasicOperator::EncryptSymmetricSync(const GFBuffer& in_buffer, + bool ascii) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(in_buffer); + GpgData data_out; + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = CheckGpgError(gpgme_op_encrypt( + ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); + data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + data_out.Read2GFBuffer()}); + + return err; + }, + "gpgme_op_encrypt_symmetric", "2.1.0"); +} + +void GpgBasicOperator::Decrypt(const GFBuffer& in_buffer, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -86,7 +152,26 @@ void GpgBasicOperator::Decrypt(GFBuffer in_buffer, cb, "gpgme_op_decrypt", "2.1.0"); } -void GpgBasicOperator::Verify(GFBuffer in_buffer, GFBuffer sig_buffer, +auto GpgBasicOperator::DecryptSync(const GFBuffer& in_buffer) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(in_buffer); + GpgData data_out; + + auto err = CheckGpgError( + gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out)); + data_object->Swap( + {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())), + data_out.Read2GFBuffer()}); + + return err; + }, + "gpgme_op_decrypt", "2.1.0"); +} + +void GpgBasicOperator::Verify(const GFBuffer& in_buffer, + const GFBuffer& sig_buffer, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -113,9 +198,37 @@ void GpgBasicOperator::Verify(GFBuffer in_buffer, GFBuffer sig_buffer, cb, "gpgme_op_verify", "2.1.0"); } -void GpgBasicOperator::Sign(KeyArgsList signers, GFBuffer in_buffer, - GpgSignMode mode, bool ascii, - const GpgOperationCallback& cb) { +auto GpgBasicOperator::VerifySync(const GFBuffer& in_buffer, + const GFBuffer& sig_buffer) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + + GpgData data_in(in_buffer); + GpgData data_out; + + if (!sig_buffer.Empty()) { + GpgData sig_data(sig_buffer); + err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data, + data_in, nullptr)); + } else { + err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in, + nullptr, data_out)); + } + + data_object->Swap({ + GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())), + }); + + return err; + }, + "gpgme_op_verify", "2.1.0"); +} + +void GpgBasicOperator::Sign(const KeyArgsList& signers, + const GFBuffer& in_buffer, GpgSignMode mode, + bool ascii, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { if (signers.empty()) return GPG_ERR_CANCELED; @@ -138,7 +251,33 @@ void GpgBasicOperator::Sign(KeyArgsList signers, GFBuffer in_buffer, cb, "gpgme_op_sign", "2.1.0"); } -void GpgBasicOperator::DecryptVerify(GFBuffer in_buffer, +auto GpgBasicOperator::SignSync(const KeyArgsList& signers, + const GFBuffer& in_buffer, GpgSignMode mode, + bool ascii) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + if (signers.empty()) return GPG_ERR_CANCELED; + + GpgError err; + + // Set Singers of this opera + SetSigners(signers, ascii); + + GpgData data_in(in_buffer); + GpgData data_out; + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + err = CheckGpgError(gpgme_op_sign(ctx, data_in, data_out, mode)); + + data_object->Swap({GpgSignResult(gpgme_op_sign_result(ctx)), + data_out.Read2GFBuffer()}); + return err; + }, + "gpgme_op_sign", "2.1.0"); +} + +void GpgBasicOperator::DecryptVerify(const GFBuffer& in_buffer, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -160,8 +299,31 @@ void GpgBasicOperator::DecryptVerify(GFBuffer in_buffer, cb, "gpgme_op_decrypt_verify", "2.1.0"); } -void GpgBasicOperator::EncryptSign(KeyArgsList keys, KeyArgsList signers, - GFBuffer in_buffer, bool ascii, +auto GpgBasicOperator::DecryptVerifySync(const GFBuffer& in_buffer) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + + GpgData data_in(in_buffer); + GpgData data_out; + + err = CheckGpgError( + gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out)); + + data_object->Swap( + {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())), + GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())), + data_out.Read2GFBuffer()}); + + return err; + }, + "gpgme_op_decrypt_verify", "2.1.0"); +} + +void GpgBasicOperator::EncryptSign(const KeyArgsList& keys, + const KeyArgsList& signers, + const GFBuffer& in_buffer, bool ascii, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -191,6 +353,38 @@ void GpgBasicOperator::EncryptSign(KeyArgsList keys, KeyArgsList signers, cb, "gpgme_op_encrypt_sign", "2.1.0"); } +auto GpgBasicOperator::EncryptSignSync(const KeyArgsList& keys, + const KeyArgsList& signers, + const GFBuffer& in_buffer, bool ascii) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED; + + GpgError err; + std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); + + // Last entry data_in array has to be nullptr + recipients.emplace_back(nullptr); + + SetSigners(signers, ascii); + + GpgData data_in(in_buffer); + GpgData data_out; + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(), + GPGME_ENCRYPT_ALWAYS_TRUST, + data_in, data_out)); + + data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + GpgSignResult(gpgme_op_sign_result(ctx)), + data_out.Read2GFBuffer()}); + return err; + }, + "gpgme_op_encrypt_sign", "2.1.0"); +} + void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) { auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); @@ -219,22 +413,4 @@ auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> { } return signers; } - -void GpgBasicOperator::EncryptSymmetric(GFBuffer in_buffer, bool ascii, - const GpgOperationCallback& cb) { - RunGpgOperaAsync( - [=](const DataObjectPtr& data_object) -> GpgError { - GpgData data_in(in_buffer); - GpgData data_out; - - auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); - auto err = CheckGpgError(gpgme_op_encrypt( - ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); - data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx)), - data_out.Read2GFBuffer()}); - - return err; - }, - cb, "gpgme_op_encrypt_symmetric", "2.1.0"); -} } // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h index 4b1a2688..37defb45 100644 --- a/src/core/function/gpg/GpgBasicOperator.h +++ b/src/core/function/gpg/GpgBasicOperator.h @@ -55,11 +55,16 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator /** * @brief * - * All incoming data pointers out_buffer will be replaced with new valid - * values + */ + void Encrypt(const KeyArgsList&, const GFBuffer&, bool, + const GpgOperationCallback&); + + /** + * @brief * */ - void Encrypt(KeyArgsList, GFBuffer, bool, const GpgOperationCallback&); + auto EncryptSync(const KeyArgsList&, const GFBuffer&, bool) + -> std::tuple<GpgError, DataObjectPtr>; /** * @brief Call the interface provided by GPGME to symmetrical encryption @@ -69,10 +74,21 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result Encrypted results * @return GpgError */ - void EncryptSymmetric(GFBuffer in_buffer, bool ascii, + void EncryptSymmetric(const GFBuffer& in_buffer, bool ascii, const GpgOperationCallback& cb); /** + * @brief + * + * @param in_buffer + * @param ascii + * @param cb + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto EncryptSymmetricSync(const GFBuffer& in_buffer, bool ascii) + -> std::tuple<GpgError, DataObjectPtr>; + + /** * * @brief Call the interface provided by gpgme to perform encryption and * signature operations at the same time. @@ -80,13 +96,25 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param keys List of public keys * @param signers Private key for signatures * @param in_buffer Data for operation - * @param out_buffer Encrypted data - * @param encr_result Encrypted results - * @param sign_result Signature result + * @param ascii ascii mode * @return */ - void EncryptSign(KeyArgsList keys, KeyArgsList signers, GFBuffer in_buffer, - bool ascii, const GpgOperationCallback& cb); + void EncryptSign(const KeyArgsList& keys, const KeyArgsList& signers, + const GFBuffer& in_buffer, bool ascii, + const GpgOperationCallback& cb); + + /** + * @brief + * + * @param keys + * @param signers + * @param in_buffer + * @param ascii + * @param cb + */ + auto EncryptSignSync(const KeyArgsList& keys, const KeyArgsList& signers, + const GFBuffer& in_buffer, bool ascii) + -> std::tuple<GpgError, DataObjectPtr>; /** * @brief Call the interface provided by gpgme for decryption operation @@ -96,7 +124,15 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - void Decrypt(GFBuffer in_buffer, const GpgOperationCallback& cb); + void Decrypt(const GFBuffer& in_buffer, const GpgOperationCallback& cb); + + /** + * @brief + * + * @param in_buffer + */ + auto DecryptSync(const GFBuffer& in_buffer) + -> std::tuple<GpgError, DataObjectPtr>; /** * @brief Call the interface provided by gpgme to perform decryption and @@ -108,7 +144,15 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param verify_result the result of the verifying operation * @return error code */ - void DecryptVerify(GFBuffer in_buffer, const GpgOperationCallback& cb); + void DecryptVerify(const GFBuffer& in_buffer, const GpgOperationCallback& cb); + + /** + * @brief + * + * @param in_buffer + */ + auto DecryptVerifySync(const GFBuffer& in_buffer) + -> std::tuple<GpgError, DataObjectPtr>; /** * @brief Call the interface provided by gpgme for verification operation @@ -118,10 +162,21 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - void Verify(GFBuffer in_buffer, GFBuffer sig_buffer, + void Verify(const GFBuffer& in_buffer, const GFBuffer& sig_buffer, const GpgOperationCallback& cb); /** + * @brief + * + * @param in_buffer + * @param sig_buffer + * @param cb + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto VerifySync(const GFBuffer& in_buffer, const GFBuffer& sig_buffer) + -> std::tuple<GpgError, DataObjectPtr>; + + /** * @brief Call the interface provided by gpgme for signing operation * * The signing modes are as follows: @@ -141,8 +196,22 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - void Sign(KeyArgsList signers, GFBuffer in_buffer, GpgSignMode mode, - bool ascii, const GpgOperationCallback& cb); + void Sign(const KeyArgsList& signers, const GFBuffer& in_buffer, + GpgSignMode mode, bool ascii, const GpgOperationCallback& cb); + + /** + * @brief + * + * @param signers + * @param in_buffer + * @param mode + * @param ascii + * @param cb + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto SignSync(const KeyArgsList& signers, const GFBuffer& in_buffer, + GpgSignMode mode, bool ascii) + -> std::tuple<GpgError, DataObjectPtr>; /** * @brief Set the private key for signatures, this operation is a global diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp index 104e254f..6523386c 100644 --- a/src/core/function/gpg/GpgContext.cpp +++ b/src/core/function/gpg/GpgContext.cpp @@ -94,16 +94,19 @@ class GpgContext::Impl { int fd) -> gpgme_error_t { size_t res; QString pass = "abcdefg\n"; - auto pass_len = pass.size(); + auto passpahrase_size = pass.size(); size_t off = 0; do { - res = gpgme_io_write(fd, &pass[off], pass_len - off); + res = gpgme_io_write(fd, &pass[off], passpahrase_size - off); if (res > 0) off += res; - } while (res > 0 && off != pass_len); + } while (res > 0 && off != passpahrase_size); - return off == pass_len ? 0 : gpgme_error_from_errno(errno); + res += gpgme_io_write(fd, "\n", 1); + return res == passpahrase_size + 1 + ? 0 + : gpgme_error_from_errno(GPG_ERR_CANCELED); } static auto CustomPassphraseCb(void *hook, const char *uid_hint, diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp index e3d47cf6..94a08c76 100644 --- a/src/core/function/gpg/GpgFileOpera.cpp +++ b/src/core/function/gpg/GpgFileOpera.cpp @@ -45,7 +45,7 @@ constexpr ssize_t kDataExchangerSize = 8192; GpgFileOpera::GpgFileOpera(int channel) : SingletonFunctionObject<GpgFileOpera>(channel) {} -void GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, const QString& in_path, +void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { RunGpgOperaAsync( @@ -69,7 +69,32 @@ void GpgFileOpera::EncryptFile(std::vector<GpgKey> keys, const QString& in_path, cb, "gpgme_op_encrypt", "2.1.0"); } -void GpgFileOpera::EncryptDirectory(std::vector<GpgKey> keys, +auto GpgFileOpera::EncryptFileSync(const KeyArgsList& keys, + const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); + + // Last entry data_in array has to be nullptr + recipients.emplace_back(nullptr); + + GpgData data_in(in_path, true); + GpgData data_out(out_path, false); + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(), + GPGME_ENCRYPT_ALWAYS_TRUST, + data_in, data_out)); + data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))}); + + return err; + }, + "gpgme_op_encrypt", "2.1.0"); +} + +void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { @@ -122,6 +147,24 @@ void GpgFileOpera::DecryptFile(const QString& in_path, const QString& out_path, cb, "gpgme_op_decrypt", "2.1.0"); } +auto GpgFileOpera::DecryptFileSync(const QString& in_path, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(in_path, true); + GpgData data_out(out_path, false); + + auto err = CheckGpgError( + gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out)); + data_object->Swap( + {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))}); + + return err; + }, + "gpgme_op_decrypt", "2.1.0"); +} + void GpgFileOpera::DecryptArchive(const QString& in_path, const QString& out_path, const GpgOperationCallback& cb) { @@ -148,7 +191,7 @@ void GpgFileOpera::DecryptArchive(const QString& in_path, cb, "gpgme_op_decrypt", "2.1.0"); } -void GpgFileOpera::SignFile(KeyArgsList keys, const QString& in_path, +void GpgFileOpera::SignFile(const KeyArgsList& keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { RunGpgOperaAsync( @@ -173,6 +216,31 @@ void GpgFileOpera::SignFile(KeyArgsList keys, const QString& in_path, cb, "gpgme_op_sign", "2.1.0"); } +auto GpgFileOpera::SignFileSync(const KeyArgsList& keys, const QString& in_path, + bool ascii, const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + + // Set Singers of this opera + GpgBasicOperator::GetInstance().SetSigners(keys, ascii); + + GpgData data_in(in_path, true); + GpgData data_out(out_path, false); + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + err = CheckGpgError( + gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH)); + + data_object->Swap({ + GpgSignResult(gpgme_op_sign_result(ctx)), + }); + return err; + }, + "gpgme_op_sign", "2.1.0"); +} + void GpgFileOpera::VerifyFile(const QString& data_path, const QString& sign_path, const GpgOperationCallback& cb) { @@ -200,7 +268,35 @@ void GpgFileOpera::VerifyFile(const QString& data_path, cb, "gpgme_op_verify", "2.1.0"); } -void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys, +auto GpgFileOpera::VerifyFileSync(const QString& data_path, + const QString& sign_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + + GpgData data_in(data_path, true); + GpgData data_out; + if (!sign_path.isEmpty()) { + GpgData sig_data(sign_path, true); + err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data, + data_in, nullptr)); + } else { + err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in, + nullptr, data_out)); + } + + data_object->Swap({ + GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())), + }); + + return err; + }, + "gpgme_op_verify", "2.1.0"); +} + +void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys, + const KeyArgsList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { @@ -231,8 +327,40 @@ void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys, cb, "gpgme_op_encrypt_sign", "2.1.0"); } -void GpgFileOpera::EncryptSignDirectory(KeyArgsList keys, - KeyArgsList signer_keys, +auto GpgFileOpera::EncryptSignFileSync(const KeyArgsList& keys, + const KeyArgsList& signer_keys, + const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + std::vector<gpgme_key_t> recipients(keys.begin(), keys.end()); + + // Last entry data_in array has to be nullptr + recipients.emplace_back(nullptr); + + GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii); + + GpgData data_in(in_path, true); + GpgData data_out(out_path, false); + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(), + GPGME_ENCRYPT_ALWAYS_TRUST, + data_in, data_out)); + + data_object->Swap({ + GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + GpgSignResult(gpgme_op_sign_result(ctx)), + }); + return err; + }, + "gpgme_op_encrypt_sign", "2.1.0"); +} + +void GpgFileOpera::EncryptSignDirectory(const KeyArgsList& keys, + const KeyArgsList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { @@ -293,6 +421,29 @@ void GpgFileOpera::DecryptVerifyFile(const QString& in_path, cb, "gpgme_op_decrypt_verify", "2.1.0"); } +auto GpgFileOpera::DecryptVerifyFileSync(const QString& in_path, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgError err; + + GpgData data_in(in_path, true); + GpgData data_out(out_path, false); + + err = CheckGpgError( + gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out)); + + data_object->Swap({ + GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())), + GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())), + }); + + return err; + }, + "gpgme_op_decrypt_verify", "2.1.0"); +} + void GpgFileOpera::DecryptVerifyArchive(const QString& in_path, const QString& out_path, const GpgOperationCallback& cb) { @@ -343,6 +494,26 @@ void GpgFileOpera::EncryptFileSymmetric(const QString& in_path, bool ascii, cb, "gpgme_op_encrypt_symmetric", "2.1.0"); } +auto GpgFileOpera::EncryptFileSymmetricSync(const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(in_path, true); + GpgData data_out(out_path, false); + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = CheckGpgError(gpgme_op_encrypt( + ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); + data_object->Swap({ + GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + }); + + return err; + }, + "gpgme_op_encrypt_symmetric", "2.1.0"); +} + void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { @@ -369,4 +540,33 @@ void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii, GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err); }); } + +auto GpgFileOpera::EncryptDerectorySymmetricSync(const QString& in_path, + bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr> { + auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize); + + ArchiveFileOperator::NewArchive2DataExchanger( + in_path, ex, [=](GFError err, const DataObjectPtr&) { + GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err); + }); + + return RunGpgOperaSync( + [=](const DataObjectPtr& data_object) -> GpgError { + GpgData data_in(ex); + GpgData data_out(out_path, false); + + auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); + auto err = CheckGpgError(gpgme_op_encrypt( + ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out)); + data_object->Swap({ + GpgEncryptResult(gpgme_op_encrypt_result(ctx)), + }); + + return err; + }, + "gpgme_op_encrypt_symmetric", "2.1.0"); +} + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h index b015ebe9..d7c2d44c 100644 --- a/src/core/function/gpg/GpgFileOpera.h +++ b/src/core/function/gpg/GpgFileOpera.h @@ -61,7 +61,7 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param channel Channel in context * @return unsigned int error code */ - void EncryptFile(KeyArgsList keys, const QString& in_path, bool ascii, + void EncryptFile(const KeyArgsList& keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); /** @@ -71,10 +71,23 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param in_path * @param ascii * @param out_path + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto EncryptFileSync(const KeyArgsList& keys, const QString& in_path, + bool ascii, const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * + * @param keys + * @param in_path + * @param ascii + * @param out_path * @param cb */ - void EncryptDirectory(KeyArgsList keys, const QString& in_path, bool ascii, - const QString& out_path, + void EncryptDirectory(const KeyArgsList& keys, const QString& in_path, + bool ascii, const QString& out_path, const GpgOperationCallback& cb); /** @@ -98,6 +111,18 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @param cb */ + auto EncryptFileSymmetricSync(const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * + * @param in_path + * @param ascii + * @param out_path + * @param cb + */ void EncryptDerectorySymmetric(const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); @@ -106,6 +131,17 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @brief * * @param in_path + * @param ascii + * @param out_path + */ + auto EncryptDerectorySymmetricSync(const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * + * @param in_path * @param out_path * @param result * @return GpgError @@ -119,6 +155,17 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param in_path * @param out_path * @param cb + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto DecryptFileSync(const QString& in_path, const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * + * @param in_path + * @param out_path + * @param cb */ void DecryptArchive(const QString& in_path, const QString& out_path, const GpgOperationCallback& cb); @@ -133,10 +180,23 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param channel * @return GpgError */ - void SignFile(KeyArgsList keys, const QString& in_path, bool ascii, + void SignFile(const KeyArgsList& keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); /** + * @brief + * + * @param keys + * @param in_path + * @param ascii + * @param out_path + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto SignFileSync(const KeyArgsList& keys, const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** * @brief Verify file with public key * * @param data_path The path where the enter file is located @@ -151,6 +211,16 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera /** * @brief * + * @param data_path + * @param sign_path + * @return std::tuple<GpgError, DataObjectPtr> + */ + auto VerifyFileSync(const QString& data_path, const QString& sign_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * * @param keys * @param signer_keys * @param in_path @@ -158,7 +228,7 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @param cb */ - void EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys, + void EncryptSignFile(const KeyArgsList& keys, const KeyArgsList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); @@ -170,9 +240,25 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param in_path * @param ascii * @param out_path + */ + auto EncryptSignFileSync(const KeyArgsList& keys, + const KeyArgsList& signer_keys, + const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * + * @param keys + * @param signer_keys + * @param in_path + * @param ascii + * @param out_path * @param cb */ - void EncryptSignDirectory(KeyArgsList keys, KeyArgsList signer_keys, + void EncryptSignDirectory(const KeyArgsList& keys, + const KeyArgsList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); @@ -194,6 +280,15 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * * @param in_path * @param out_path + */ + auto DecryptVerifyFileSync(const QString& in_path, const QString& out_path) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * + * @param in_path + * @param out_path * @param cb */ void DecryptVerifyArchive(const QString& in_path, const QString& out_path, diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 9a722c0b..5f8daf81 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -161,14 +161,12 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { - auto userid_utf8 = params->GetUserid(); - const char* userid = userid_utf8.toUtf8(); - auto algo_utf8 = params->GetAlgo() + params->GetKeySizeStr(); + auto userid = params->GetUserid(); + auto algo = params->GetAlgo() + params->GetKeySizeStr(); GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(), params->GetKeySizeStr()); - auto algo = algo_utf8.toUtf8(); unsigned long expires = QDateTime::currentDateTime().secsTo(params->GetExpireTime()); @@ -182,10 +180,10 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params, 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); + GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo, + expires, flags); + err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(), + algo.toUtf8(), 0, expires, nullptr, flags); if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { data_object->Swap({GpgGenerateKeyResult{ @@ -199,23 +197,96 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params, callback, "gpgme_op_createkey", "2.1.0"); } -/** - * Generate a new subkey of a certain key pair - * @param key target key pair - * @param params opera args - * @return error info - */ +auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [=, &ctx = ctx_](const DataObjectPtr& data_object) -> GpgError { + auto userid = params->GetUserid(); + auto algo = params->GetAlgo() + params->GetKeySizeStr(); + + GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(), + params->GetKeySizeStr()); + + unsigned long expires = + QDateTime::currentDateTime().secsTo(params->GetExpireTime()); + + 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.toUtf8(), + algo.toUtf8(), 0, expires, nullptr, flags); + + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + data_object->Swap({GpgGenerateKeyResult{ + gpgme_op_genkey_result(ctx.DefaultContext())}}); + } else { + data_object->Swap({GpgGenerateKeyResult{}}); + } + + return CheckGpgError(err); + }, + "gpgme_op_createkey", "2.1.0"); +} + void GpgKeyOpera::GenerateSubkey(const GpgKey& key, const std::shared_ptr<GenKeyInfo>& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( - [key, &ctx = ctx_, params](const DataObjectPtr&) -> GpgError { + [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { + if (!params->IsSubKey()) return GPG_ERR_CANCELED; + + GF_CORE_LOG_DEBUG("generate subkey algo {}, key size {}", + params->GetAlgo(), params->GetKeySizeStr()); + + auto algo = params->GetAlgo() + params->GetKeySizeStr(); + unsigned long expires = + QDateTime::currentDateTime().secsTo(params->GetExpireTime()); + 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("subkey generation args: {} {} {} {}", key.GetId(), + algo, expires, flags); + auto err = gpgme_op_createsubkey(ctx.DefaultContext(), + static_cast<gpgme_key_t>(key), + algo.toUtf8(), 0, expires, flags); + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + data_object->Swap({GpgGenerateKeyResult{}}); + return err; + } + + data_object->Swap({GpgGenerateKeyResult{ + gpgme_op_genkey_result(ctx.DefaultContext())}}); + return CheckGpgError(err); + }, + callback, "gpgme_op_createsubkey", "2.1.13"); +} + +auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key, + const std::shared_ptr<GenKeyInfo>& params) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { if (!params->IsSubKey()) return GPG_ERR_CANCELED; GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}", params->GetAlgo(), params->GetKeySizeStr()); - auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8(); + auto algo = params->GetAlgo() + params->GetKeySizeStr(); unsigned long expires = QDateTime::currentDateTime().secsTo(params->GetExpireTime()); unsigned int flags = 0; @@ -231,11 +302,19 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key, flags); auto err = gpgme_op_createsubkey(ctx.DefaultContext(), - static_cast<gpgme_key_t>(key), algo, 0, - expires, flags); + static_cast<gpgme_key_t>(key), + algo.toUtf8(), 0, expires, flags); + + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + data_object->Swap({GpgGenerateKeyResult{}}); + return err; + } + + data_object->Swap({GpgGenerateKeyResult{ + gpgme_op_genkey_result(ctx.DefaultContext())}}); return CheckGpgError(err); }, - callback, "gpgme_op_createsubkey", "2.1.13"); + "gpgme_op_createsubkey", "2.1.13"); } void GpgKeyOpera::GenerateKeyWithSubkey( @@ -273,6 +352,11 @@ void GpgKeyOpera::GenerateKeyWithSubkey( auto genkey_result = GpgGenerateKeyResult{gpgme_op_genkey_result(ctx.DefaultContext())}; + if (subkey_params == nullptr || !subkey_params->IsSubKey()) { + data_object->Swap({genkey_result}); + return err; + } + auto key = GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint()); if (!key.IsGood()) { @@ -281,8 +365,6 @@ void GpgKeyOpera::GenerateKeyWithSubkey( 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(), @@ -320,6 +402,91 @@ void GpgKeyOpera::GenerateKeyWithSubkey( callback, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0"); } +auto GpgKeyOpera::GenerateKeyWithSubkeySync( + const std::shared_ptr<GenKeyInfo>& params, + const std::shared_ptr<GenKeyInfo>& subkey_params) + -> std::tuple<GpgError, DataObjectPtr> { + return RunGpgOperaSync( + [&ctx = ctx_, params, + subkey_params](const DataObjectPtr& data_object) -> GpgError { + auto userid = params->GetUserid().toUtf8(); + auto algo = (params->GetAlgo() + params->GetKeySizeStr()).toUtf8(); + unsigned long expires = + QDateTime::currentDateTime().secsTo(params->GetExpireTime()); + + 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())}; + + if (subkey_params == nullptr || !subkey_params->IsSubKey()) { + data_object->Swap({genkey_result}); + return err; + } + + 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; + } + + GF_CORE_LOG_DEBUG( + "try to generate subkey of key: {}, algo {} key size {}", + key.GetId(), subkey_params->GetAlgo(), + subkey_params->GetKeySizeStr()); + + algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr()) + .toUtf8(); + expires = + QDateTime::currentDateTime().secsTo(subkey_params->GetExpireTime()); + + 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); + }, + "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 a060af1a..6ffe437c 100644 --- a/src/core/function/gpg/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -118,6 +118,14 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera /** * @brief * + * @param params + */ + auto GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * * @param key * @param params * @return GpgFrontend::GpgError @@ -129,6 +137,16 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera /** * @brief * + * @param key + * @param params + */ + auto GenerateSubkeySync(const GpgKey& key, + const std::shared_ptr<GenKeyInfo>& params) + -> std::tuple<GpgError, DataObjectPtr>; + + /** + * @brief + * * @param params * @param subkey_params * @param callback @@ -137,6 +155,18 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera const std::shared_ptr<GenKeyInfo>& subkey_params, const GpgOperationCallback& callback); + /** + * @brief + * + * @param params + * @param subkey_params + * @param callback + */ + auto GenerateKeyWithSubkeySync( + const std::shared_ptr<GenKeyInfo>& params, + const std::shared_ptr<GenKeyInfo>& subkey_params) + -> std::tuple<GpgError, DataObjectPtr>; + private: GpgContext& ctx_ = GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< diff --git a/src/core/model/GpgGenKeyInfo.cpp b/src/core/model/GpgGenKeyInfo.cpp index 60f76d96..d7daa852 100644 --- a/src/core/model/GpgGenKeyInfo.cpp +++ b/src/core/model/GpgGenKeyInfo.cpp @@ -28,7 +28,6 @@ #include "GpgGenKeyInfo.h" -#include <algorithm> #include <cassert> #include "core/utils/LogUtils.h" @@ -106,7 +105,7 @@ void GenKeyInfo::SetAlgo(const QString &t_algo_args) { suggest_size_addition_step_ = -1; SetKeyLength(-1); } else { - SPDLOG_ERROR("unsupported gen key algo arguments: {}", algo_args); + SPDLOG_ERROR("unsupported genkey algo arguments: {}", algo_args); return; } @@ -180,7 +179,7 @@ auto GenKeyInfo::GetSupportedKeyAlgo() {"ECDSA", "ED25519", ""}, {"ECDSA + ECDH", "ED25519", "CV25519"}, {"ECDSA + ECDH NIST P-256", "ED25519", "NISTP256"}, - {"ECDSA + ECDH BrainPool P-256", "ED25519", "BRAINPOOlP256R1"}, + {"ECDSA + ECDH BrainPooL P-256", "ED25519", "BRAINPOOLP256R1"}, }; return kSupportKeyAlgo; } @@ -195,9 +194,9 @@ auto GenKeyInfo::GetSupportedSubkeyAlgo() {"ECDH NIST P-256", "", "NISTP256"}, {"ECDH NIST P-384", "", "NISTP384"}, {"ECDH NIST P-521", "", "NISTP521"}, - {"ECDH BrainPool P-256", "", "BRAINPOOlP256R1"}, - {"ECDH BrainPool P-384", "", "BRAINPOOlP384R1"}, - {"ECDH BrainPool P-512", "", "BRAINPOOlP512R1"}}; + {"ECDH BrainPooL P-256", "", "BRAINPOOLP256R1"}, + {"ECDH BrainPooL P-384", "", "BRAINPOOLP384R1"}, + {"ECDH BrainPooL P-512", "", "BRAINPOOLP512R1"}}; return kSupportSubkeyAlgo; } diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp index ab962b5d..53842249 100644 --- a/src/core/model/GpgKey.cpp +++ b/src/core/model/GpgKey.cpp @@ -125,6 +125,13 @@ auto GpgKey::GetPublicKeyAlgo() const -> QString { return gpgme_pubkey_algo_name(key_ref_->subkeys->pubkey_algo); } +auto GpgKey::GetKeyAlgo() const -> QString { + auto *buffer = gpgme_pubkey_algo_string(key_ref_->subkeys); + auto algo = QString(buffer); + gpgme_free(buffer); + return algo.toUpper(); +} + auto GpgKey::GetLastUpdateTime() const -> QDateTime { return QDateTime::fromSecsSinceEpoch( static_cast<time_t>(key_ref_->last_update)); diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h index 70599b99..d9c97d59 100644 --- a/src/core/model/GpgKey.h +++ b/src/core/model/GpgKey.h @@ -114,6 +114,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKey { /** * @brief * + * @return QString + */ + [[nodiscard]] auto GetKeyAlgo() const -> QString; + + /** + * @brief + * * @return QDateTime */ [[nodiscard]] auto GetLastUpdateTime() const -> QDateTime; diff --git a/src/core/model/GpgSubKey.cpp b/src/core/model/GpgSubKey.cpp index eaef1498..cb0078de 100644 --- a/src/core/model/GpgSubKey.cpp +++ b/src/core/model/GpgSubKey.cpp @@ -55,6 +55,13 @@ auto GpgSubKey::GetPubkeyAlgo() const -> QString { return gpgme_pubkey_algo_name(subkey_ref_->pubkey_algo); } +auto GpgSubKey::GetKeyAlgo() const -> QString { + auto* buffer = gpgme_pubkey_algo_string(subkey_ref_.get()); + auto algo = QString(buffer); + gpgme_free(buffer); + return algo.toUpper(); +} + auto GpgSubKey::GetKeyLength() const -> unsigned int { return subkey_ref_->length; } diff --git a/src/core/model/GpgSubKey.h b/src/core/model/GpgSubKey.h index d8268c34..83d75e2d 100644 --- a/src/core/model/GpgSubKey.h +++ b/src/core/model/GpgSubKey.h @@ -60,6 +60,13 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey { /** * @brief * + * @return QString + */ + [[nodiscard]] auto GetKeyAlgo() const -> QString; + + /** + * @brief + * * @return unsigned int */ [[nodiscard]] auto GetKeyLength() const -> unsigned int; diff --git a/src/core/utils/AsyncUtils.cpp b/src/core/utils/AsyncUtils.cpp index 6100b83d..40c2ece1 100644 --- a/src/core/utils/AsyncUtils.cpp +++ b/src/core/utils/AsyncUtils.cpp @@ -36,15 +36,18 @@ namespace GpgFrontend { -auto RunGpgOperaAsync(GpgOperaRunnable runnable, GpgOperationCallback callback, +auto RunGpgOperaAsync(const GpgOperaRunnable& runnable, + const GpgOperationCallback& callback, const QString& operation, const QString& minial_version) -> Thread::Task::TaskHandler { const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gnupg_version", minial_version); - GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version); + GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}", + gnupg_version, operation); - if (CompareSoftwareVersion(gnupg_version, "2.0.15") < 0) { - GF_CORE_LOG_ERROR("operator not support"); + if (CompareSoftwareVersion(gnupg_version, minial_version) < 0) { + GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}", + operation, gnupg_version); callback(GPG_ERR_NOT_SUPPORTED, TransferParams()); return Thread::Task::TaskHandler(nullptr); } @@ -74,7 +77,27 @@ auto RunGpgOperaAsync(GpgOperaRunnable runnable, GpgOperationCallback callback, return handler; } -auto RunIOOperaAsync(OperaRunnable runnable, OperationCallback callback, +auto RunGpgOperaSync(const GpgOperaRunnable& runnable, const QString& operation, + const QString& minial_version) + -> std::tuple<GpgError, DataObjectPtr> { + const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gnupg_version", minial_version); + GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}", + gnupg_version, operation); + + if (CompareSoftwareVersion(gnupg_version, minial_version) < 0) { + GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}", + operation, gnupg_version); + return {GPG_ERR_NOT_SUPPORTED, TransferParams()}; + } + + auto data_object = TransferParams(); + auto err = runnable(data_object); + return {err, data_object}; +} + +auto RunIOOperaAsync(const OperaRunnable& runnable, + const OperationCallback& callback, const QString& operation) -> Thread::Task::TaskHandler { auto handler = Thread::TaskRunnerGetter::GetInstance() diff --git a/src/core/utils/AsyncUtils.h b/src/core/utils/AsyncUtils.h index e587fad2..4b5c4d69 100644 --- a/src/core/utils/AsyncUtils.h +++ b/src/core/utils/AsyncUtils.h @@ -43,11 +43,23 @@ namespace GpgFrontend { * @param operation * @param minial_version */ -auto GPGFRONTEND_CORE_EXPORT RunGpgOperaAsync(GpgOperaRunnable runnable, - GpgOperationCallback callback, - const QString& operation, - const QString& minial_version) - -> Thread::Task::TaskHandler; +auto GPGFRONTEND_CORE_EXPORT +RunGpgOperaAsync(const GpgOperaRunnable& runnable, + const GpgOperationCallback& callback, const QString& operation, + const QString& minial_version) -> Thread::Task::TaskHandler; + +/** + * @brief + * + * @param runnable + * @param operation + * @param minial_version + * @return std::tuple<GpgError, DataObjectPtr> + */ +auto GPGFRONTEND_CORE_EXPORT RunGpgOperaSync(const GpgOperaRunnable& runnable, + const QString& operation, + const QString& minial_version) + -> std::tuple<GpgError, DataObjectPtr>; /** * @brief @@ -56,8 +68,8 @@ auto GPGFRONTEND_CORE_EXPORT RunGpgOperaAsync(GpgOperaRunnable runnable, * @param callback * @param operation */ -auto GPGFRONTEND_CORE_EXPORT RunIOOperaAsync(OperaRunnable runnable, - OperationCallback callback, +auto GPGFRONTEND_CORE_EXPORT RunIOOperaAsync(const OperaRunnable& runnable, + const OperationCallback& callback, const QString& operation) -> Thread::Task::TaskHandler; } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/IOUtils.cpp b/src/core/utils/IOUtils.cpp index 5ca765d9..54fbb6c9 100644 --- a/src/core/utils/IOUtils.cpp +++ b/src/core/utils/IOUtils.cpp @@ -128,6 +128,12 @@ auto CreateTempFileAndWriteData(const QString& data) -> QString { return temp_file; } +auto CreateTempFileAndWriteData(const GFBuffer& data) -> QString { + auto temp_file = GetTempFilePath(); + WriteFile(temp_file, data.ConvertToQByteArray()); + return temp_file; +} + auto TargetFilePreCheck(const QString& path, bool read) -> std::tuple<bool, QString> { QFileInfo const file_info(path); diff --git a/src/core/utils/IOUtils.h b/src/core/utils/IOUtils.h index 42c663c3..2c48f38c 100644 --- a/src/core/utils/IOUtils.h +++ b/src/core/utils/IOUtils.h @@ -112,6 +112,15 @@ auto GPGFRONTEND_CORE_EXPORT CreateTempFileAndWriteData(const QString &data) /** * @brief * + * @param data + * @return QString + */ +auto GPGFRONTEND_CORE_EXPORT CreateTempFileAndWriteData(const GFBuffer &data) + -> QString; + +/** + * @brief + * * @param path * @param read * @return std::tuple<bool, QString> diff --git a/src/core/utils/LogUtils.h b/src/core/utils/LogUtils.h index d838e830..a1a5685a 100644 --- a/src/core/utils/LogUtils.h +++ b/src/core/utils/LogUtils.h @@ -109,4 +109,4 @@ void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString &, #define GF_LOG_WARN(ID, ...) \ SPDLOG_LOGGER_WARN(GpgFrontend::GetLogger(ID), __VA_ARGS__) #define GF_LOG_ERROR(ID, ...) \ - SPDLOG_LOGGER_ERROR(GpgFrontend::GetLogger(ID), __VA_ARGS__)
\ No newline at end of file + SPDLOG_LOGGER_ERROR(GpgFrontend::GetLogger(ID), __VA_ARGS__) diff --git a/src/main.cpp b/src/main.cpp index eea2e9f6..abc6ed56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,8 +30,6 @@ * \mainpage GpgFrontend Develop Document Main Page */ -#include <memory> - #include "GpgFrontendContext.h" #include "app.h" #include "cmd.h" @@ -29,6 +29,7 @@ #pragma once #include "core/utils/LogUtils.h" +#include "core/utils/MemoryUtils.h" #define GF_MAIN_LOG_TRACE(...) GF_LOG_TRACE("main", __VA_ARGS__) #define GF_MAIN_LOG_DEBUG(...) GF_LOG_DEBUG("main", __VA_ARGS__) diff --git a/src/test/core/GpgCoreTest.h b/src/test/core/GpgCoreTest.h index 26097f2c..9b18ebf6 100644 --- a/src/test/core/GpgCoreTest.h +++ b/src/test/core/GpgCoreTest.h @@ -30,6 +30,8 @@ #include <gtest/gtest.h> +#include "GpgFrontendTest.h" + namespace GpgFrontend::Test { class GpgCoreTest : public ::testing::Test { diff --git a/src/test/core/GpgCoreTestBasicOpera.cpp b/src/test/core/GpgCoreTestBasicOpera.cpp index 238c9530..da539ad6 100644 --- a/src/test/core/GpgCoreTestBasicOpera.cpp +++ b/src/test/core/GpgCoreTestBasicOpera.cpp @@ -28,7 +28,6 @@ #include "GpgCoreTest.h" #include "core/GpgModel.h" -#include "core/function/basic/ChannelObject.h" #include "core/function/gpg/GpgBasicOperator.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/result_analyse/GpgDecryptResultAnalyse.h" @@ -41,85 +40,59 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, CoreEncryptDecrTest) { - std::atomic_bool callback_called_flag{false}; - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + + auto [err, data_object] = + GpgBasicOperator::GetInstance().EncryptSync({encrypt_key}, buffer, true); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgEncryptResult, GFBuffer>())); + + auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto encr_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + + ASSERT_TRUE(result.InvalidRecipients().empty()); - GpgBasicOperator::GetInstance().Encrypt( - {encrypt_key}, GFBuffer(QString("Hello GpgFrontend!")), true, - [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GFBuffer>())); - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_TRUE(result.InvalidRecipients().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgBasicOperator::GetInstance().Decrypt( - encr_out_buffer, [&callback_called_flag]( - GpgError err, const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); - auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_FALSE(d_result.Recipients().empty()); - ASSERT_EQ(d_result.Recipients()[0].keyid, "6A2764F8298DEB29"); - - ASSERT_EQ(decr_out_buffer, - GFBuffer(QString("Hello GpgFrontend!"))); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err_0, data_object_0] = + GpgBasicOperator::GetInstance().DecryptSync(encr_out_buffer); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult, GFBuffer>())); + + auto decr_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_object_0, 1); + + ASSERT_FALSE(decr_result.Recipients().empty()); + ASSERT_EQ(decr_result.Recipients()[0].keyid, "6A2764F8298DEB29"); + ASSERT_EQ(decr_out_buffer, buffer); } TEST_F(GpgCoreTest, CoreEncryptSymmetricDecrTest) { - std::atomic_bool callback_called_flag{false}; - auto encrypt_text = GFBuffer(QString("Hello GpgFrontend!")); + auto [err, data_object] = + GpgBasicOperator::GetInstance().EncryptSymmetricSync(encrypt_text, true); - GpgBasicOperator::GetInstance().EncryptSymmetric( - encrypt_text, true, - [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GFBuffer>())); - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_TRUE(result.InvalidRecipients().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgBasicOperator::GetInstance().Decrypt( - encr_out_buffer, [&callback_called_flag]( - GpgError err, const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); - auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_TRUE(d_result.Recipients().empty()); - ASSERT_EQ(decr_out_buffer, - GFBuffer(QString("Hello GpgFrontend!"))); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgEncryptResult, GFBuffer>())); + auto encr_result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto encr_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + ASSERT_TRUE(encr_result.InvalidRecipients().empty()); + + auto [err_0, data_object_0] = + GpgBasicOperator::GetInstance().DecryptSync(encr_out_buffer); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult, GFBuffer>())); + auto decr_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_object_0, 1); + + ASSERT_TRUE(decr_result.Recipients().empty()); + ASSERT_EQ(decr_out_buffer, encrypt_text); } TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_1) { - std::atomic_bool callback_called_flag{false}; - auto encr_out_data = GFBuffer(QString( "-----BEGIN PGP MESSAGE-----\n" "\n" @@ -133,30 +106,18 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_1) { "=8n2H\n" "-----END PGP MESSAGE-----")); - GpgBasicOperator::GetInstance().Decrypt( - encr_out_data, - [=, &callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); - auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); - ASSERT_FALSE(d_result.Recipients().empty()); - ASSERT_EQ(d_result.Recipients()[0].keyid, "A50CFD2F6C677D8C"); - - // stop waiting - callback_called_flag = true; - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = + GpgBasicOperator::GetInstance().DecryptSync(encr_out_data); + + auto decr_result = ExtractParams<GpgDecryptResult>(data_object, 0); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); + + ASSERT_FALSE(decr_result.Recipients().empty()); + ASSERT_EQ(decr_result.Recipients()[0].keyid, "A50CFD2F6C677D8C"); } TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) { - std::atomic_bool callback_called_flag{false}; - auto encr_out_data = GFBuffer(QString( "-----BEGIN PGP MESSAGE-----\n" "\n" @@ -170,152 +131,99 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) { "=8n2H\n" "-----END PGP MESSAGE-----")); - GpgBasicOperator::GetInstance().Decrypt( - encr_out_data, - [=, &callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); - auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); - ASSERT_FALSE(d_result.Recipients().empty()); - ASSERT_EQ(d_result.Recipients()[0].keyid, "A50CFD2F6C677D8C"); - - GpgDecryptResultAnalyse analyse{err, d_result}; - analyse.Analyse(); - ASSERT_EQ(analyse.GetStatus(), -1); - ASSERT_FALSE(analyse.GetResultReport().isEmpty()); - - // stop waiting - callback_called_flag = true; - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = + GpgBasicOperator::GetInstance().DecryptSync(encr_out_data); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_SECKEY); + ASSERT_TRUE((data_object->Check<GpgDecryptResult, GFBuffer>())); + + auto decr_result = ExtractParams<GpgDecryptResult>(data_object, 0); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + + ASSERT_FALSE(decr_result.Recipients().empty()); + ASSERT_EQ(decr_result.Recipients()[0].keyid, "A50CFD2F6C677D8C"); + + GpgDecryptResultAnalyse analyse{err, decr_result}; + analyse.Analyse(); + ASSERT_EQ(analyse.GetStatus(), -1); + ASSERT_FALSE(analyse.GetResultReport().isEmpty()); } TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) { - std::atomic_bool callback_called_flag{false}; - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); auto sign_text = GFBuffer(QString("Hello GpgFrontend!")); - GpgBasicOperator::GetInstance().Sign( - {sign_key}, sign_text, GPGME_SIG_MODE_NORMAL, true, - [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>())); - auto result = ExtractParams<GpgSignResult>(data_obj, 0); - auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_TRUE(result.InvalidSigners().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgBasicOperator::GetInstance().Verify( - sign_out_buffer, GFBuffer(), - [&callback_called_flag](GpgError err, - const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_FALSE(d_result.GetSignature().empty()); - ASSERT_EQ(d_result.GetSignature().at(0).GetFingerprint(), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgBasicOperator::GetInstance().SignSync( + {sign_key}, sign_text, GPGME_SIG_MODE_NORMAL, true); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgSignResult, GFBuffer>())); + auto result = ExtractParams<GpgSignResult>(data_object, 0); + auto sign_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + ASSERT_TRUE(result.InvalidSigners().empty()); + + auto [err_0, data_object_0] = + GpgBasicOperator::GetInstance().VerifySync(sign_out_buffer, GFBuffer()); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgVerifyResult>())); + auto verify_result = ExtractParams<GpgVerifyResult>(data_object_0, 0); + ASSERT_FALSE(verify_result.GetSignature().empty()); + ASSERT_EQ(verify_result.GetSignature().at(0).GetFingerprint(), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); } TEST_F(GpgCoreTest, CoreSignVerifyDetachTest) { - std::atomic_bool callback_called_flag{false}; - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); auto sign_text = GFBuffer(QString("Hello GpgFrontend!")); - GpgBasicOperator::GetInstance().Sign( - {sign_key}, sign_text, GPGME_SIG_MODE_DETACH, true, - [=, &callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>())); - auto result = ExtractParams<GpgSignResult>(data_obj, 0); - auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_TRUE(result.InvalidSigners().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgBasicOperator::GetInstance().Verify( - sign_text, sign_out_buffer, - [&callback_called_flag](GpgError err, - const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_FALSE(d_result.GetSignature().empty()); - ASSERT_EQ(d_result.GetSignature().at(0).GetFingerprint(), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgBasicOperator::GetInstance().SignSync( + {sign_key}, sign_text, GPGME_SIG_MODE_DETACH, true); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgSignResult, GFBuffer>())); + auto result = ExtractParams<GpgSignResult>(data_object, 0); + auto sign_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + ASSERT_TRUE(result.InvalidSigners().empty()); + + auto [err_0, data_object_0] = + GpgBasicOperator::GetInstance().VerifySync(sign_text, sign_out_buffer); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgVerifyResult>())); + auto verify_result = ExtractParams<GpgVerifyResult>(data_object_0, 0); + ASSERT_FALSE(verify_result.GetSignature().empty()); + ASSERT_EQ(verify_result.GetSignature().at(0).GetFingerprint(), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); } TEST_F(GpgCoreTest, CoreSignVerifyClearTest) { - std::atomic_bool callback_called_flag{false}; - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); auto sign_text = GFBuffer(QString("Hello GpgFrontend!")); - GpgBasicOperator::GetInstance().Sign( - {sign_key}, sign_text, GPGME_SIG_MODE_CLEAR, true, - [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgSignResult, GFBuffer>())); - auto result = ExtractParams<GpgSignResult>(data_obj, 0); - auto sign_out_buffer = ExtractParams<GFBuffer>(data_obj, 1); - ASSERT_TRUE(result.InvalidSigners().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgBasicOperator::GetInstance().Verify( - sign_out_buffer, GFBuffer(), - [&callback_called_flag](GpgError err, - const DataObjectPtr& data_obj) { - auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 0); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_FALSE(verify_reult.GetSignature().empty()); - ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgBasicOperator::GetInstance().SignSync( + {sign_key}, sign_text, GPGME_SIG_MODE_CLEAR, true); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgSignResult, GFBuffer>())); + auto result = ExtractParams<GpgSignResult>(data_object, 0); + auto sign_out_buffer = ExtractParams<GFBuffer>(data_object, 1); + ASSERT_TRUE(result.InvalidSigners().empty()); + + auto [err_0, data_object_0] = + GpgBasicOperator::GetInstance().VerifySync(sign_out_buffer, GFBuffer()); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + auto verify_reult = ExtractParams<GpgVerifyResult>(data_object_0, 0); + ASSERT_FALSE(verify_reult.GetSignature().empty()); + ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); } TEST_F(GpgCoreTest, CoreEncryptSignDecrVerifyTest) { - std::atomic_bool callback_called_flag{false}; - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); auto sign_key = GpgKeyGetter::GetInstance().GetKey( @@ -325,52 +233,34 @@ TEST_F(GpgCoreTest, CoreEncryptSignDecrVerifyTest) { ASSERT_TRUE(sign_key.IsPrivateKey()); ASSERT_TRUE(sign_key.IsHasActualSigningCapability()); - GpgBasicOperator::GetInstance().EncryptSign( - {encrypt_key}, {sign_key}, encrypt_text, true, - [&callback_called_flag](GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE( - (data_obj->Check<GpgEncryptResult, GpgSignResult, GFBuffer>())); - auto encr_result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); - auto encr_out_buffer = ExtractParams<GFBuffer>(data_obj, 2); - ASSERT_TRUE(encr_result.InvalidRecipients().empty()); - ASSERT_TRUE(sign_result.InvalidSigners().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgBasicOperator::GetInstance().DecryptVerify( - encr_out_buffer, [&callback_called_flag]( - GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE( - (data_obj - ->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>())); - auto decrypt_result = - ExtractParams<GpgDecryptResult>(data_obj, 0); - auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 1); - auto decr_out_buffer = ExtractParams<GFBuffer>(data_obj, 2); - - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - ASSERT_FALSE(decrypt_result.Recipients().empty()); - ASSERT_EQ(decr_out_buffer, - GFBuffer(QString("Hello GpgFrontend!"))); - - ASSERT_EQ(decrypt_result.Recipients()[0].keyid, - "F89C95A05088CC93"); - ASSERT_FALSE(verify_reult.GetSignature().empty()); - ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), - "8933EB283A18995F45D61DAC021D89771B680FFB"); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgBasicOperator::GetInstance().EncryptSignSync( + {encrypt_key}, {sign_key}, encrypt_text, true); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE( + (data_object->Check<GpgEncryptResult, GpgSignResult, GFBuffer>())); + auto encr_result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_object, 1); + auto encr_out_buffer = ExtractParams<GFBuffer>(data_object, 2); + ASSERT_TRUE(encr_result.InvalidRecipients().empty()); + ASSERT_TRUE(sign_result.InvalidSigners().empty()); + + auto [err_0, data_object_0] = + GpgBasicOperator::GetInstance().DecryptVerifySync(encr_out_buffer); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE( + (data_object_0->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>())); + auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + auto verify_reult = ExtractParams<GpgVerifyResult>(data_object_0, 1); + auto decr_out_buffer = ExtractParams<GFBuffer>(data_object_0, 2); + + ASSERT_FALSE(decrypt_result.Recipients().empty()); + ASSERT_EQ(decr_out_buffer, encrypt_text); + ASSERT_EQ(decrypt_result.Recipients()[0].keyid, "F89C95A05088CC93"); + ASSERT_FALSE(verify_reult.GetSignature().empty()); + ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), + "8933EB283A18995F45D61DAC021D89771B680FFB"); } } // namespace GpgFrontend::Test diff --git a/src/test/core/GpgCoreTestDirectoryBasicOpera.cpp b/src/test/core/GpgCoreTestDirectoryBasicOpera.cpp new file mode 100644 index 00000000..a2c7f285 --- /dev/null +++ b/src/test/core/GpgCoreTestDirectoryBasicOpera.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgCoreTest.h" diff --git a/src/test/core/GpgCoreTestFileBasicOpera.cpp b/src/test/core/GpgCoreTestFileBasicOpera.cpp index d5b0f52d..db338893 100644 --- a/src/test/core/GpgCoreTestFileBasicOpera.cpp +++ b/src/test/core/GpgCoreTestFileBasicOpera.cpp @@ -28,11 +28,8 @@ #include "GpgCoreTest.h" #include "core/GpgModel.h" -#include "core/function/basic/ChannelObject.h" -#include "core/function/gpg/GpgBasicOperator.h" #include "core/function/gpg/GpgFileOpera.h" #include "core/function/gpg/GpgKeyGetter.h" -#include "core/function/result_analyse/GpgDecryptResultAnalyse.h" #include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" #include "core/model/GpgSignResult.h" @@ -43,197 +40,264 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, CoreFileEncryptDecrTest) { - std::atomic_bool callback_called_flag{false}; + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + auto input_file = CreateTempFileAndWriteData(buffer); + auto output_file = GetTempFilePath(); + + auto [err, data_object] = GpgFileOpera::GetInstance().EncryptFileSync( + {encrypt_key}, input_file, true, output_file); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgEncryptResult>())); + auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + ASSERT_TRUE(result.InvalidRecipients().empty()); + + auto decrpypt_output_file = GetTempFilePath(); + auto [err_0, data_object_0] = GpgFileOpera::GetInstance().DecryptFileSync( + output_file, decrpypt_output_file); + auto decr_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_FALSE(decr_result.Recipients().empty()); + ASSERT_EQ(decr_result.Recipients()[0].keyid, "6A2764F8298DEB29"); + + const auto [read_success, out_buffer] = + ReadFileGFBuffer(decrpypt_output_file); + ASSERT_TRUE(read_success); + ASSERT_EQ(buffer, out_buffer); +} + +TEST_F(GpgCoreTest, CoreFileEncryptDecrBinaryTest) { auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); + + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + auto input_file = CreateTempFileAndWriteData(buffer); auto output_file = GetTempFilePath(); - GpgFileOpera::GetInstance().EncryptFile( - {encrypt_key}, input_file, true, output_file, - [output_file, &callback_called_flag](GpgError err, - const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgEncryptResult>())); - - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - ASSERT_TRUE(result.InvalidRecipients().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - auto decrpypt_output_file = GetTempFilePath(); - GpgFileOpera::GetInstance().DecryptFile( - output_file, decrpypt_output_file, - [decrpypt_output_file, &callback_called_flag]( - GpgError err, const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgDecryptResult>(data_obj, 0); - - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_FALSE(d_result.Recipients().empty()); - ASSERT_EQ(d_result.Recipients()[0].keyid, "6A2764F8298DEB29"); - - const auto [read_success, buffer] = - ReadFileGFBuffer(decrpypt_output_file); - ASSERT_TRUE(read_success); - ASSERT_EQ(buffer, GFBuffer(QString("Hello GpgFrontend!"))); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgFileOpera::GetInstance().EncryptFileSync( + {encrypt_key}, input_file, false, output_file); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgEncryptResult>())); + auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + ASSERT_TRUE(result.InvalidRecipients().empty()); + + auto decrpypt_output_file = GetTempFilePath(); + auto [err_0, data_object_0] = GpgFileOpera::GetInstance().DecryptFileSync( + output_file, decrpypt_output_file); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult>())); + auto decr_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + ASSERT_FALSE(decr_result.Recipients().empty()); + ASSERT_EQ(decr_result.Recipients()[0].keyid, "6A2764F8298DEB29"); + + const auto [read_success, out_buffer] = + ReadFileGFBuffer(decrpypt_output_file); + ASSERT_TRUE(read_success); + ASSERT_EQ(buffer, out_buffer); } TEST_F(GpgCoreTest, CoreFileEncryptSymmetricDecrTest) { - std::atomic_bool callback_called_flag{false}; + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + auto input_file = CreateTempFileAndWriteData(buffer); + auto output_file = GetTempFilePath(); - auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); + auto [err, data_object] = + GpgFileOpera::GetInstance().EncryptFileSymmetricSync(input_file, true, + output_file); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgEncryptResult>())); + auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + ASSERT_TRUE(result.InvalidRecipients().empty()); + + auto decrpypt_output_file = GetTempFilePath(); + auto [err_0, data_object_0] = GpgFileOpera::GetInstance().DecryptFileSync( + output_file, decrpypt_output_file); + + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult>())); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + ASSERT_TRUE(decrypt_result.Recipients().empty()); + + const auto [read_success, out_buffer] = + ReadFileGFBuffer(decrpypt_output_file); + ASSERT_TRUE(read_success); + ASSERT_EQ(buffer, out_buffer); +} + +TEST_F(GpgCoreTest, CoreFileEncryptSymmetricDecrBinaryTest) { + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + auto input_file = CreateTempFileAndWriteData(buffer); auto output_file = GetTempFilePath(); - GpgFileOpera::GetInstance().EncryptFileSymmetric( - input_file, true, output_file, - [&callback_called_flag, output_file](GpgError err, - const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgEncryptResult>())); - auto result = ExtractParams<GpgEncryptResult>(data_obj, 0); - ASSERT_TRUE(result.InvalidRecipients().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - auto decrpypt_output_file = GetTempFilePath(); - GpgFileOpera::GetInstance().DecryptFile( - output_file, decrpypt_output_file, - [&callback_called_flag, decrpypt_output_file]( - GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgDecryptResult>())); - - auto decrypt_result = - ExtractParams<GpgDecryptResult>(data_obj, 0); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_TRUE(decrypt_result.Recipients().empty()); - - const auto [read_success, buffer] = - ReadFileGFBuffer(decrpypt_output_file); - ASSERT_TRUE(read_success); - ASSERT_EQ(buffer, GFBuffer(QString("Hello GpgFrontend!"))); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = + GpgFileOpera::GetInstance().EncryptFileSymmetricSync(input_file, false, + output_file); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgEncryptResult>())); + auto result = ExtractParams<GpgEncryptResult>(data_object, 0); + ASSERT_TRUE(result.InvalidRecipients().empty()); + + auto decrpypt_output_file = GetTempFilePath(); + auto [err_0, data_object_0] = GpgFileOpera::GetInstance().DecryptFileSync( + output_file, decrpypt_output_file); + + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult>())); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + ASSERT_TRUE(decrypt_result.Recipients().empty()); + + const auto [read_success, out_buffer] = + ReadFileGFBuffer(decrpypt_output_file); + ASSERT_TRUE(read_success); + ASSERT_EQ(buffer, out_buffer); } TEST_F(GpgCoreTest, CoreFileSignVerifyNormalTest) { - std::atomic_bool callback_called_flag{false}; + auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); + auto output_file = GetTempFilePath(); + auto [err, data_object] = GpgFileOpera::GetInstance().SignFileSync( + {sign_key}, input_file, true, output_file); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgSignResult>())); + auto result = ExtractParams<GpgSignResult>(data_object, 0); + ASSERT_TRUE(result.InvalidSigners().empty()); + + auto [err_0, data_object_0] = + GpgFileOpera::GetInstance().VerifyFileSync(input_file, output_file); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgVerifyResult>())); + auto verify_result = ExtractParams<GpgVerifyResult>(data_object_0, 0); + ASSERT_FALSE(verify_result.GetSignature().empty()); + ASSERT_EQ(verify_result.GetSignature().at(0).GetFingerprint(), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); +} + +TEST_F(GpgCoreTest, CoreFileSignVerifyNormalBinaryTest) { auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); auto output_file = GetTempFilePath(); - GpgFileOpera::GetInstance().SignFile( - {sign_key}, input_file, true, output_file, - [&callback_called_flag, input_file, output_file]( - GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgSignResult>())); - auto result = ExtractParams<GpgSignResult>(data_obj, 0); - ASSERT_TRUE(result.InvalidSigners().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - GpgFileOpera::GetInstance().VerifyFile( - input_file, output_file, - [&callback_called_flag](GpgError err, - const DataObjectPtr& data_obj) { - auto d_result = ExtractParams<GpgVerifyResult>(data_obj, 0); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - ASSERT_FALSE(d_result.GetSignature().empty()); - ASSERT_EQ(d_result.GetSignature().at(0).GetFingerprint(), - "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgFileOpera::GetInstance().SignFileSync( + {sign_key}, input_file, false, output_file); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object->Check<GpgSignResult>())); + auto result = ExtractParams<GpgSignResult>(data_object, 0); + ASSERT_TRUE(result.InvalidSigners().empty()); + + auto [err_0, data_object_0] = + GpgFileOpera::GetInstance().VerifyFileSync(input_file, output_file); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgVerifyResult>())); + auto verify_result = ExtractParams<GpgVerifyResult>(data_object_0, 0); + ASSERT_FALSE(verify_result.GetSignature().empty()); + ASSERT_EQ(verify_result.GetSignature().at(0).GetFingerprint(), + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); } TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyTest) { - std::atomic_bool callback_called_flag{false}; + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); + auto sign_key = GpgKeyGetter::GetInstance().GetKey( + "8933EB283A18995F45D61DAC021D89771B680FFB"); + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + auto input_file = CreateTempFileAndWriteData(buffer); + auto output_file = GetTempFilePath(); + ASSERT_TRUE(sign_key.IsPrivateKey()); + ASSERT_TRUE(sign_key.IsHasActualSigningCapability()); + + auto [err, data_object] = GpgFileOpera::GetInstance().EncryptSignFileSync( + {encrypt_key}, {sign_key}, input_file, true, output_file); + + ASSERT_TRUE((data_object->Check<GpgEncryptResult, GpgSignResult>())); + auto encr_result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_object, 1); + ASSERT_TRUE(encr_result.InvalidRecipients().empty()); + ASSERT_TRUE(sign_result.InvalidSigners().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + auto decrpypt_output_file = GetTempFilePath(); + auto [err_0, data_object_0] = + GpgFileOpera::GetInstance().DecryptVerifyFileSync(output_file, + decrpypt_output_file); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult, GpgVerifyResult>())); + auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + auto verify_reult = ExtractParams<GpgVerifyResult>(data_object_0, 1); + + ASSERT_FALSE(decrypt_result.Recipients().empty()); + ASSERT_EQ(decrypt_result.Recipients()[0].keyid, "F89C95A05088CC93"); + ASSERT_FALSE(verify_reult.GetSignature().empty()); + ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), + "8933EB283A18995F45D61DAC021D89771B680FFB"); + + const auto [read_success, out_buffer] = + ReadFileGFBuffer(decrpypt_output_file); + ASSERT_TRUE(read_success); + ASSERT_EQ(buffer, out_buffer); +} + +TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyBinaryTest) { auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); auto sign_key = GpgKeyGetter::GetInstance().GetKey( "8933EB283A18995F45D61DAC021D89771B680FFB"); - auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); + auto buffer = GFBuffer(QString("Hello GpgFrontend!")); + auto input_file = CreateTempFileAndWriteData(buffer); auto output_file = GetTempFilePath(); ASSERT_TRUE(sign_key.IsPrivateKey()); ASSERT_TRUE(sign_key.IsHasActualSigningCapability()); - GpgFileOpera::GetInstance().EncryptSignFile( - {encrypt_key}, {sign_key}, input_file, true, output_file, - [&callback_called_flag, output_file](GpgError err, - const DataObjectPtr& data_obj) { - ASSERT_TRUE((data_obj->Check<GpgEncryptResult, GpgSignResult>())); - auto encr_result = ExtractParams<GpgEncryptResult>(data_obj, 0); - auto sign_result = ExtractParams<GpgSignResult>(data_obj, 1); - ASSERT_TRUE(encr_result.InvalidRecipients().empty()); - ASSERT_TRUE(sign_result.InvalidSigners().empty()); - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - auto decrpypt_output_file = GetTempFilePath(); - GpgFileOpera::GetInstance().DecryptVerifyFile( - output_file, decrpypt_output_file, - [&callback_called_flag, decrpypt_output_file]( - GpgError err, const DataObjectPtr& data_obj) { - ASSERT_TRUE( - (data_obj->Check<GpgDecryptResult, GpgVerifyResult>())); - auto decrypt_result = - ExtractParams<GpgDecryptResult>(data_obj, 0); - auto verify_reult = ExtractParams<GpgVerifyResult>(data_obj, 1); - - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - ASSERT_FALSE(decrypt_result.Recipients().empty()); - ASSERT_EQ(decrypt_result.Recipients()[0].keyid, - "F89C95A05088CC93"); - ASSERT_FALSE(verify_reult.GetSignature().empty()); - ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), - "8933EB283A18995F45D61DAC021D89771B680FFB"); - - const auto [read_success, buffer] = - ReadFileGFBuffer(decrpypt_output_file); - ASSERT_TRUE(read_success); - ASSERT_EQ(buffer, GFBuffer(QString("Hello GpgFrontend!"))); - - // stop waiting - callback_called_flag = true; - }); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + auto [err, data_object] = GpgFileOpera::GetInstance().EncryptSignFileSync( + {encrypt_key}, {sign_key}, input_file, false, output_file); + + ASSERT_TRUE((data_object->Check<GpgEncryptResult, GpgSignResult>())); + auto encr_result = ExtractParams<GpgEncryptResult>(data_object, 0); + auto sign_result = ExtractParams<GpgSignResult>(data_object, 1); + ASSERT_TRUE(encr_result.InvalidRecipients().empty()); + ASSERT_TRUE(sign_result.InvalidSigners().empty()); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + + auto decrpypt_output_file = GetTempFilePath(); + auto [err_0, data_object_0] = + GpgFileOpera::GetInstance().DecryptVerifyFileSync(output_file, + decrpypt_output_file); + + ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); + ASSERT_TRUE((data_object_0->Check<GpgDecryptResult, GpgVerifyResult>())); + auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object_0, 0); + auto verify_reult = ExtractParams<GpgVerifyResult>(data_object_0, 1); + + ASSERT_FALSE(decrypt_result.Recipients().empty()); + ASSERT_EQ(decrypt_result.Recipients()[0].keyid, "F89C95A05088CC93"); + ASSERT_FALSE(verify_reult.GetSignature().empty()); + ASSERT_EQ(verify_reult.GetSignature().at(0).GetFingerprint(), + "8933EB283A18995F45D61DAC021D89771B680FFB"); + + const auto [read_success, out_buffer] = + ReadFileGFBuffer(decrpypt_output_file); + ASSERT_TRUE(read_success); + ASSERT_EQ(buffer, out_buffer); } } // namespace GpgFrontend::Test diff --git a/src/test/core/GpgCoreTestImportExport.cpp b/src/test/core/GpgCoreTestImportExport.cpp index faf8b58a..8cb720ff 100644 --- a/src/test/core/GpgCoreTestImportExport.cpp +++ b/src/test/core/GpgCoreTestImportExport.cpp @@ -26,7 +26,6 @@ * */ -#include <string> #include <vector> #include "GpgCoreTest.h" diff --git a/src/test/core/GpgCoreTestKeyModel.cpp b/src/test/core/GpgCoreTestKeyModel.cpp index cf1fd9ea..1e75a7f9 100644 --- a/src/test/core/GpgCoreTestKeyModel.cpp +++ b/src/test/core/GpgCoreTestKeyModel.cpp @@ -84,16 +84,16 @@ TEST_F(GpgCoreTest, GpgKeyTest) { ASSERT_EQ(key.GetId(), "81704859182661FB"); ASSERT_EQ(key.GetFingerprint(), "9490795B78F8AFE9F93BD09281704859182661FB"); ASSERT_EQ(key.GetExpireTime(), - QDateTime::fromString("20230905T040000", Qt::ISODate)); + QDateTime::fromString("2023-09-05T04:00:00Z", Qt::ISODate)); ASSERT_EQ(key.GetPublicKeyAlgo(), "RSA"); + ASSERT_EQ(key.GetKeyAlgo(), "RSA3072"); ASSERT_EQ(key.GetPrimaryKeyLength(), 3072); ASSERT_EQ(key.GetLastUpdateTime(), - QDateTime::fromString("19700101T000000", Qt::ISODate)); + QDateTime::fromString("1970-01-01T00:00:00Z", Qt::ISODate)); ASSERT_EQ(key.GetCreateTime(), - QDateTime::fromString("20210905T060153", Qt::ISODate)); + QDateTime::fromString("2021-09-05T06:01:53Z", Qt::ISODate)); ASSERT_EQ(key.GetOwnerTrust(), "Unknown"); - ASSERT_EQ(key.IsExpired(), key.GetExpireTime() < QDateTime::currentDateTime()); } @@ -104,12 +104,26 @@ TEST_F(GpgCoreTest, GpgSubKeyTest) { auto sub_keys = key.GetSubKeys(); ASSERT_EQ(sub_keys->size(), 2); + auto& main_key = sub_keys->front(); + + ASSERT_EQ(main_key.GetID(), "81704859182661FB"); + ASSERT_EQ(main_key.GetFingerprint(), + "9490795B78F8AFE9F93BD09281704859182661FB"); + ASSERT_EQ(main_key.GetExpireTime(), + QDateTime::fromString("2023-09-05T04:00:00Z", Qt::ISODate)); + ASSERT_EQ(main_key.GetPubkeyAlgo(), "RSA"); + ASSERT_EQ(main_key.GetKeyAlgo(), "RSA3072"); + ASSERT_EQ(main_key.GetKeyLength(), 3072); + ASSERT_EQ(main_key.GetCreateTime(), + QDateTime::fromString("2021-09-05T06:01:53Z", Qt::ISODate)); + ASSERT_FALSE(main_key.IsCardKey()); + auto& sub_key = sub_keys->back(); ASSERT_FALSE(sub_key.IsRevoked()); ASSERT_FALSE(sub_key.IsDisabled()); ASSERT_EQ(sub_key.GetCreateTime(), - QDateTime::fromString("20210905T060153", Qt::ISODate)); + QDateTime::fromString("2021-09-05T06:01:53Z", Qt::ISODate)); ASSERT_FALSE(sub_key.IsCardKey()); ASSERT_TRUE(sub_key.IsPrivateKey()); @@ -117,13 +131,14 @@ TEST_F(GpgCoreTest, GpgSubKeyTest) { ASSERT_EQ(sub_key.GetFingerprint(), "50D37E8F8EE7340A6794E0592B36803235B5E25B"); ASSERT_EQ(sub_key.GetKeyLength(), 3072); + ASSERT_EQ(sub_key.GetKeyAlgo(), "RSA3072"); ASSERT_EQ(sub_key.GetPubkeyAlgo(), "RSA"); ASSERT_FALSE(sub_key.IsHasCertificationCapability()); ASSERT_FALSE(sub_key.IsHasAuthenticationCapability()); ASSERT_FALSE(sub_key.IsHasSigningCapability()); ASSERT_TRUE(sub_key.IsHasEncryptionCapability()); - ASSERT_EQ(key.GetExpireTime(), - QDateTime::fromString("20230905T040000", Qt::ISODate)); + ASSERT_EQ(sub_key.GetExpireTime(), + QDateTime::fromString("2023-09-05T04:00:00Z", Qt::ISODate)); ASSERT_EQ(sub_key.IsExpired(), sub_key.GetExpireTime() < QDateTime::currentDateTime()); diff --git a/src/test/core/GpgCoreTestKeygen.cpp b/src/test/core/GpgCoreTestKeygen.cpp index 57e7cbb9..8a473aea 100644 --- a/src/test/core/GpgCoreTestKeygen.cpp +++ b/src/test/core/GpgCoreTestKeygen.cpp @@ -26,15 +26,9 @@ * */ -#include <gtest/gtest.h> -#include <qeventloop.h> - -#include <cstddef> - #include "GpgCoreTest.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyOpera.h" -#include "core/function/result_analyse/GpgResultAnalyse.h" #include "core/model/GpgGenKeyInfo.h" #include "core/model/GpgGenerateKeyResult.h" #include "core/model/GpgKey.h" @@ -43,170 +37,466 @@ namespace GpgFrontend::Test { -TEST_F(GpgCoreTest, GenerateKeyTest) { +TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); keygen_info->SetName("foo_0"); keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment(""); - keygen_info->SetKeyLength(1024); + keygen_info->SetComment("foobar"); + keygen_info->SetKeyLength(2048); keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[0])); + keygen_info->SetAllowAuthentication(true); + keygen_info->SetAllowCertification(true); + keygen_info->SetAllowEncryption(true); + keygen_info->SetAllowSigning(true); keygen_info->SetNonExpired(true); - keygen_info->SetNonPassPhrase(true); + keygen_info->SetNonPassPhrase(false); - std::atomic_bool callback_called_flag{false}; + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeySync(keygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + ASSERT_EQ(key.GetName(), "foo_0"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "foobar"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "RSA"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 2048); + ASSERT_EQ(key.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_TRUE(key.IsHasAuthenticationCapability()); + ASSERT_TRUE(key.IsHasEncryptionCapability()); + ASSERT_TRUE(key.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_TRUE(key.IsHasActualAuthenticationCapability()); + ASSERT_TRUE(key.IsHasActualEncryptionCapability()); + ASSERT_TRUE(key.IsHasActualSigningCapability()); GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKey(keygen_info, [&callback_called_flag]( - GpgError err, - const DataObjectPtr& data_object) { - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - ASSERT_EQ(data_object->GetObjectSize(), 1); - ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); - - auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); - ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); - - auto key = - GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); - - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); - - callback_called_flag = true; - ASSERT_FALSE(fpr.isEmpty()); - }); - - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + .DeleteKey(result.GetFingerprint()); } -TEST_F(GpgCoreTest, GenerateKeyTest_1) { +TEST_F(GpgCoreTest, GenerateKeyRSA1024NoPassTest) { auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); keygen_info->SetName("foo_1"); keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("hello gpgfrontend"); + keygen_info->SetComment("foobar_1"); + keygen_info->SetKeyLength(2048); keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[0])); - keygen_info->SetKeyLength(4096); + keygen_info->SetAllowAuthentication(false); + keygen_info->SetAllowCertification(false); + keygen_info->SetAllowEncryption(false); + keygen_info->SetAllowSigning(false); keygen_info->SetNonExpired(false); - keygen_info->SetExpireTime( - QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600))); - keygen_info->SetNonPassPhrase(false); + keygen_info->SetNonPassPhrase(true); - std::atomic_bool callback_called_flag{false}; + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeySync(keygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + ASSERT_EQ(key.GetName(), "foo_1"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "foobar_1"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "RSA"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 2048); + ASSERT_GT(key.GetExpireTime(), QDateTime::currentDateTime()); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_FALSE(key.IsHasAuthenticationCapability()); + ASSERT_FALSE(key.IsHasEncryptionCapability()); + ASSERT_FALSE(key.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_FALSE(key.IsHasActualAuthenticationCapability()); + ASSERT_FALSE(key.IsHasActualEncryptionCapability()); + ASSERT_FALSE(key.IsHasActualSigningCapability()); GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKey(keygen_info, [&callback_called_flag]( - GpgError err, - const DataObjectPtr& data_object) { - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + .DeleteKey(result.GetFingerprint()); +} - ASSERT_EQ(data_object->GetObjectSize(), 1); - ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); +TEST_F(GpgCoreTest, GenerateKeyRSA4096Test) { + auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); + keygen_info->SetName("foo_1"); + keygen_info->SetEmail("[email protected]"); + keygen_info->SetComment("hello gpgfrontend"); + keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[0])); + keygen_info->SetKeyLength(3072); + keygen_info->SetNonExpired(false); - auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); - ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); + auto expire_time = + QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); + keygen_info->SetExpireTime(expire_time); + keygen_info->SetNonPassPhrase(false); - auto key = - GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeySync(keygen_info); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); - callback_called_flag = true; - ASSERT_FALSE(fpr.isEmpty()); - }); + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); - int retry_count = 2000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + ASSERT_EQ(key.GetExpireTime().date(), expire_time.date()); - ASSERT_TRUE(callback_called_flag); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .DeleteKey(result.GetFingerprint()); } -TEST_F(GpgCoreTest, GenerateKeyTest_4) { +TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_2"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment(""); + keygen_info->SetName("foo_1"); + keygen_info->SetEmail("[email protected]"); + keygen_info->SetComment("hello gpgfrontend"); keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[1])); - keygen_info->SetNonExpired(true); + keygen_info->SetKeyLength(2048); + keygen_info->SetAllowAuthentication(true); + keygen_info->SetAllowCertification(true); + keygen_info->SetAllowEncryption(true); + keygen_info->SetAllowSigning(true); + keygen_info->SetNonExpired(false); + + auto expire_time = + QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); + keygen_info->SetExpireTime(expire_time); keygen_info->SetNonPassPhrase(false); - std::atomic_bool callback_called_flag{false}; + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeySync(keygen_info); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + ASSERT_EQ(key.GetName(), "foo_1"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "hello gpgfrontend"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "DSA"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 2048); + ASSERT_GT(key.GetExpireTime(), QDateTime::currentDateTime()); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_TRUE(key.IsHasAuthenticationCapability()); + ASSERT_FALSE(key.IsHasEncryptionCapability()); + ASSERT_TRUE(key.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_TRUE(key.IsHasActualAuthenticationCapability()); + ASSERT_FALSE(key.IsHasActualEncryptionCapability()); + ASSERT_TRUE(key.IsHasActualSigningCapability()); GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKey(keygen_info, [&callback_called_flag]( - GpgError err, - const DataObjectPtr& data_object) { - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); - - auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); - ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); - - auto key = - GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); - - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); - - callback_called_flag = true; - ASSERT_FALSE(fpr.isEmpty()); - }); - - int retry_count = 2000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - ASSERT_TRUE(callback_called_flag); + .DeleteKey(result.GetFingerprint()); } -TEST_F(GpgCoreTest, GenerateKeyTest_5) { +TEST_F(GpgCoreTest, GenerateKeyED25519Test) { auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_3"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment(""); + keygen_info->SetName("foo_4"); + keygen_info->SetEmail("[email protected]"); + keygen_info->SetComment("hello gpgfrontend"); keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[2])); - keygen_info->SetNonExpired(true); + keygen_info->SetKeyLength(0); + keygen_info->SetAllowAuthentication(true); + keygen_info->SetAllowCertification(true); + keygen_info->SetAllowEncryption(true); + keygen_info->SetAllowSigning(true); + keygen_info->SetNonExpired(false); + + auto expire_time = + QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); + keygen_info->SetExpireTime(expire_time); keygen_info->SetNonPassPhrase(false); - std::atomic_bool callback_called_flag{false}; + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeySync(keygen_info); + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + ASSERT_EQ(key.GetName(), "foo_4"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "hello gpgfrontend"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "EdDSA"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 255); + ASSERT_GT(key.GetExpireTime(), QDateTime::currentDateTime()); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_TRUE(key.IsHasAuthenticationCapability()); + ASSERT_FALSE(key.IsHasEncryptionCapability()); + ASSERT_TRUE(key.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_TRUE(key.IsHasActualAuthenticationCapability()); + ASSERT_FALSE(key.IsHasActualEncryptionCapability()); + ASSERT_TRUE(key.IsHasActualSigningCapability()); GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKey(keygen_info, [&callback_called_flag]( - GpgError err, - const DataObjectPtr& data_object) { - ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + .DeleteKey(result.GetFingerprint()); +} - auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); - ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); +TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { + auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); + keygen_info->SetName("foo_ec"); + keygen_info->SetEmail("[email protected]"); + keygen_info->SetComment("ecccc"); + keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[3])); + keygen_info->SetAllowAuthentication(true); + keygen_info->SetAllowCertification(true); + keygen_info->SetAllowEncryption(true); + keygen_info->SetAllowSigning(true); + keygen_info->SetNonExpired(true); + keygen_info->SetNonPassPhrase(true); - auto key = - GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo(std::get<2>(keygen_info->GetSupportedKeyAlgo()[3])); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeyWithSubkeySync(keygen_info, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE( + (data_object->Check<GpgGenerateKeyResult, GpgGenerateKeyResult>())); + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + auto fpr = result.GetFingerprint(); + ASSERT_FALSE(fpr.isEmpty()); + + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); + ASSERT_TRUE(key.IsGood()); + + ASSERT_EQ(key.GetName(), "foo_ec"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "ecccc"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "EdDSA"); + ASSERT_EQ(key.GetKeyAlgo(), "ED25519"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 255); + ASSERT_EQ(key.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_TRUE(key.IsHasAuthenticationCapability()); + ASSERT_TRUE(key.IsHasEncryptionCapability()); + ASSERT_TRUE(key.IsHasSigningCapability()); + + ASSERT_FALSE(key.GetSubKeys()->empty()); + ASSERT_EQ(key.GetSubKeys()->size(), 2); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + ASSERT_EQ(subkey.GetPubkeyAlgo(), "ECDH"); + ASSERT_EQ(subkey.GetKeyAlgo(), "CV25519"); + ASSERT_EQ(subkey.GetKeyLength(), 255); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_FALSE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_FALSE(subkey.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_TRUE(key.IsHasActualAuthenticationCapability()); + ASSERT_TRUE(key.IsHasActualEncryptionCapability()); + ASSERT_TRUE(key.IsHasActualSigningCapability()); + + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); +} - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); +TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { + auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); + keygen_info->SetName("foo_ec2"); + keygen_info->SetEmail("[email protected]"); + keygen_info->SetComment("ecccc"); + keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[4])); + keygen_info->SetAllowAuthentication(true); + keygen_info->SetAllowCertification(true); + keygen_info->SetAllowEncryption(true); + keygen_info->SetAllowSigning(true); + keygen_info->SetNonExpired(true); + keygen_info->SetNonPassPhrase(true); - callback_called_flag = true; - ASSERT_FALSE(fpr.isEmpty()); - }); + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo(std::get<2>(keygen_info->GetSupportedKeyAlgo()[4])); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeyWithSubkeySync(keygen_info, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE( + (data_object->Check<GpgGenerateKeyResult, GpgGenerateKeyResult>())); + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + auto fpr = result.GetFingerprint(); + ASSERT_FALSE(fpr.isEmpty()); + + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); + ASSERT_TRUE(key.IsGood()); + + ASSERT_EQ(key.GetName(), "foo_ec2"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "ecccc"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "EdDSA"); + ASSERT_EQ(key.GetKeyAlgo(), "ED25519"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 255); + ASSERT_EQ(key.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_TRUE(key.IsHasAuthenticationCapability()); + ASSERT_TRUE(key.IsHasEncryptionCapability()); + ASSERT_TRUE(key.IsHasSigningCapability()); + + ASSERT_FALSE(key.GetSubKeys()->empty()); + ASSERT_EQ(key.GetSubKeys()->size(), 2); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + ASSERT_EQ(subkey.GetPubkeyAlgo(), "ECDH"); + ASSERT_EQ(subkey.GetKeyAlgo(), "NISTP256"); + ASSERT_EQ(subkey.GetKeyLength(), 256); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_FALSE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_FALSE(subkey.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_TRUE(key.IsHasActualAuthenticationCapability()); + ASSERT_TRUE(key.IsHasActualEncryptionCapability()); + ASSERT_TRUE(key.IsHasActualSigningCapability()); + + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); +} - int retry_count = 1000; - while (!callback_called_flag && retry_count-- > 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } +TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { + auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); + keygen_info->SetName("foo_ec3"); + keygen_info->SetEmail("[email protected]"); + keygen_info->SetComment("ecccc3"); + keygen_info->SetAlgo(std::get<1>(keygen_info->GetSupportedKeyAlgo()[5])); + keygen_info->SetAllowAuthentication(true); + keygen_info->SetAllowCertification(true); + keygen_info->SetAllowEncryption(true); + keygen_info->SetAllowSigning(true); + keygen_info->SetNonExpired(true); + keygen_info->SetNonPassPhrase(true); - ASSERT_TRUE(callback_called_flag); + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo(std::get<2>(keygen_info->GetSupportedKeyAlgo()[5])); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeyWithSubkeySync(keygen_info, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_TRUE( + (data_object->Check<GpgGenerateKeyResult, GpgGenerateKeyResult>())); + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + auto fpr = result.GetFingerprint(); + ASSERT_FALSE(fpr.isEmpty()); + + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); + ASSERT_TRUE(key.IsGood()); + + ASSERT_EQ(key.GetName(), "foo_ec3"); + ASSERT_EQ(key.GetEmail(), "[email protected]"); + ASSERT_EQ(key.GetComment(), "ecccc3"); + ASSERT_EQ(key.GetPublicKeyAlgo(), "EdDSA"); + ASSERT_EQ(key.GetKeyAlgo(), "ED25519"); + ASSERT_EQ(key.GetOwnerTrustLevel(), 5); + ASSERT_EQ(key.GetPrimaryKeyLength(), 255); + ASSERT_EQ(key.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_TRUE(key.IsHasCertificationCapability()); + ASSERT_TRUE(key.IsHasAuthenticationCapability()); + ASSERT_TRUE(key.IsHasEncryptionCapability()); + ASSERT_TRUE(key.IsHasSigningCapability()); + + ASSERT_FALSE(key.GetSubKeys()->empty()); + ASSERT_EQ(key.GetSubKeys()->size(), 2); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + ASSERT_EQ(subkey.GetPubkeyAlgo(), "ECDH"); + ASSERT_EQ(subkey.GetKeyAlgo(), "BRAINPOOLP256R1"); + ASSERT_EQ(subkey.GetKeyLength(), 256); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_FALSE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_FALSE(subkey.IsHasSigningCapability()); + + ASSERT_TRUE(key.IsHasActualCertificationCapability()); + ASSERT_TRUE(key.IsHasActualAuthenticationCapability()); + ASSERT_TRUE(key.IsHasActualEncryptionCapability()); + ASSERT_TRUE(key.IsHasActualSigningCapability()); + + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); } } // namespace GpgFrontend::Test diff --git a/src/test/core/GpgCoreTestSubkeygen.cpp b/src/test/core/GpgCoreTestSubkeygen.cpp new file mode 100644 index 00000000..983b6a7c --- /dev/null +++ b/src/test/core/GpgCoreTestSubkeygen.cpp @@ -0,0 +1,298 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgCoreTest.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyOpera.h" +#include "core/model/GpgGenKeyInfo.h" +#include "core/model/GpgGenerateKeyResult.h" +#include "core/model/GpgKey.h" +#include "core/utils/GpgUtils.h" +#include "core/utils/MemoryUtils.h" + +namespace GpgFrontend::Test { + +TEST_F(GpgCoreTest, GenerateSubkeyRSA2048Test) { + auto main_key = GpgKeyGetter::GetInstance().GetKey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo( + std::get<2>(subkeygen_info->GetSupportedSubkeyAlgo()[0])); + subkeygen_info->SetKeyLength(2048); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateSubkeySync(main_key, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + + ASSERT_EQ(subkey.GetPubkeyAlgo(), "RSA"); + ASSERT_EQ(subkey.GetKeyAlgo(), "RSA2048"); + ASSERT_EQ(subkey.GetKeyLength(), 2048); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_TRUE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_TRUE(subkey.IsHasSigningCapability()); +} + +TEST_F(GpgCoreTest, GenerateSubkeyDSA2048Test) { + auto main_key = GpgKeyGetter::GetInstance().GetKey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo( + std::get<2>(subkeygen_info->GetSupportedSubkeyAlgo()[1])); + subkeygen_info->SetKeyLength(2048); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateSubkeySync(main_key, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + + ASSERT_EQ(subkey.GetPubkeyAlgo(), "DSA"); + ASSERT_EQ(subkey.GetKeyAlgo(), "DSA2048"); + ASSERT_EQ(subkey.GetKeyLength(), 2048); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_TRUE(subkey.IsHasAuthenticationCapability()); + ASSERT_FALSE(subkey.IsHasEncryptionCapability()); + ASSERT_TRUE(subkey.IsHasSigningCapability()); +} + +TEST_F(GpgCoreTest, GenerateSubkeyED25519Test) { + auto main_key = GpgKeyGetter::GetInstance().GetKey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo( + std::get<2>(subkeygen_info->GetSupportedSubkeyAlgo()[2])); + subkeygen_info->SetKeyLength(2048); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateSubkeySync(main_key, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + + ASSERT_EQ(subkey.GetPubkeyAlgo(), "EdDSA"); + ASSERT_EQ(subkey.GetKeyAlgo(), "ED25519"); + ASSERT_EQ(subkey.GetKeyLength(), 255); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_TRUE(subkey.IsHasAuthenticationCapability()); + ASSERT_FALSE(subkey.IsHasEncryptionCapability()); + ASSERT_TRUE(subkey.IsHasSigningCapability()); +} + +TEST_F(GpgCoreTest, GenerateSubkeyCV25519Test) { + auto main_key = GpgKeyGetter::GetInstance().GetKey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo( + std::get<2>(subkeygen_info->GetSupportedSubkeyAlgo()[3])); + subkeygen_info->SetKeyLength(2048); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateSubkeySync(main_key, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + + ASSERT_EQ(subkey.GetPubkeyAlgo(), "ECDH"); + ASSERT_EQ(subkey.GetKeyAlgo(), "CV25519"); + ASSERT_EQ(subkey.GetKeyLength(), 255); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_FALSE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_FALSE(subkey.IsHasSigningCapability()); +} + +TEST_F(GpgCoreTest, GenerateSubkeyNISTP256Test) { + auto main_key = GpgKeyGetter::GetInstance().GetKey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo( + std::get<2>(subkeygen_info->GetSupportedSubkeyAlgo()[4])); + subkeygen_info->SetKeyLength(2048); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateSubkeySync(main_key, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + + ASSERT_EQ(subkey.GetPubkeyAlgo(), "ECDH"); + ASSERT_EQ(subkey.GetKeyAlgo(), "NISTP256"); + ASSERT_EQ(subkey.GetKeyLength(), 256); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_FALSE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_FALSE(subkey.IsHasSigningCapability()); +} + +TEST_F(GpgCoreTest, GenerateSubkeyBRAINPOOLP256R1Test) { + auto main_key = GpgKeyGetter::GetInstance().GetKey( + "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); + + auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); + subkeygen_info->SetAlgo( + std::get<2>(subkeygen_info->GetSupportedSubkeyAlgo()[7])); + subkeygen_info->SetKeyLength(2048); + subkeygen_info->SetAllowAuthentication(true); + subkeygen_info->SetAllowCertification(true); + subkeygen_info->SetAllowEncryption(true); + subkeygen_info->SetAllowSigning(true); + subkeygen_info->SetNonExpired(true); + subkeygen_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateSubkeySync(main_key, subkeygen_info); + + ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); + ASSERT_EQ(data_object->GetObjectSize(), 1); + ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + ASSERT_TRUE(result.IsGood()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); + auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKey(result.GetFingerprint()); + ASSERT_TRUE(key.IsGood()); + + auto subkeys = key.GetSubKeys(); + auto& subkey = subkeys->back(); + + ASSERT_EQ(subkey.GetPubkeyAlgo(), "ECDH"); + ASSERT_EQ(subkey.GetKeyAlgo(), "BRAINPOOLP256R1"); + ASSERT_EQ(subkey.GetKeyLength(), 256); + ASSERT_EQ(subkey.GetExpireTime(), QDateTime::fromMSecsSinceEpoch(0)); + + ASSERT_FALSE(subkey.IsHasCertificationCapability()); + ASSERT_FALSE(subkey.IsHasAuthenticationCapability()); + ASSERT_TRUE(subkey.IsHasEncryptionCapability()); + ASSERT_FALSE(subkey.IsHasSigningCapability()); +} + +} // namespace GpgFrontend::Test
\ No newline at end of file diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp index 0f6c19d8..08816f98 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.cpp +++ b/src/ui/dialog/key_generate/KeygenDialog.cpp @@ -283,49 +283,63 @@ void KeyGenDialog::slot_activated_key_type(int index) { } void KeyGenDialog::refresh_widgets_state() { - if (gen_key_info_->IsAllowEncryption()) { + if (gen_key_info_->IsAllowEncryption() || + (gen_subkey_info_ != nullptr && gen_subkey_info_->IsAllowEncryption())) { key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Checked); } else { key_usage_check_boxes_[0]->setCheckState(Qt::CheckState::Unchecked); } - if (gen_key_info_->IsAllowChangeEncryption()) { + if (gen_key_info_->IsAllowChangeEncryption() || + (gen_subkey_info_ != nullptr && + gen_subkey_info_->IsAllowChangeEncryption())) { key_usage_check_boxes_[0]->setDisabled(false); } else { key_usage_check_boxes_[0]->setDisabled(true); } - if (gen_key_info_->IsAllowSigning()) { + if (gen_key_info_->IsAllowSigning() || + (gen_subkey_info_ != nullptr && gen_subkey_info_->IsAllowSigning())) { key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Checked); } else { key_usage_check_boxes_[1]->setCheckState(Qt::CheckState::Unchecked); } - if (gen_key_info_->IsAllowChangeSigning()) { + if (gen_key_info_->IsAllowChangeSigning() || + (gen_subkey_info_ != nullptr && + gen_subkey_info_->IsAllowChangeSigning())) { key_usage_check_boxes_[1]->setDisabled(false); } else { key_usage_check_boxes_[1]->setDisabled(true); } - if (gen_key_info_->IsAllowCertification()) { + if (gen_key_info_->IsAllowCertification() || + (gen_subkey_info_ != nullptr && + gen_subkey_info_->IsAllowCertification())) { key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Checked); } else { key_usage_check_boxes_[2]->setCheckState(Qt::CheckState::Unchecked); } - if (gen_key_info_->IsAllowChangeCertification()) { + if (gen_key_info_->IsAllowChangeCertification() || + (gen_subkey_info_ != nullptr && + gen_subkey_info_->IsAllowChangeCertification())) { key_usage_check_boxes_[2]->setDisabled(false); } else { key_usage_check_boxes_[2]->setDisabled(true); } - if (gen_key_info_->IsAllowAuthentication()) { + if (gen_key_info_->IsAllowAuthentication() || + (gen_subkey_info_ != nullptr && + gen_subkey_info_->IsAllowAuthentication())) { key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Checked); } else { key_usage_check_boxes_[3]->setCheckState(Qt::CheckState::Unchecked); } - if (gen_key_info_->IsAllowChangeAuthentication()) { + if (gen_key_info_->IsAllowChangeAuthentication() || + (gen_subkey_info_ != nullptr && + gen_subkey_info_->IsAllowChangeAuthentication())) { key_usage_check_boxes_[3]->setDisabled(false); } else { key_usage_check_boxes_[3]->setDisabled(true); diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp index a91b5fd4..0fce26e5 100644 --- a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp @@ -61,6 +61,7 @@ KeyPairDetailTab::KeyPairDetailTab(const QString& key_id, QWidget* parent) created_var_label_ = new QLabel(); last_update_var_label_ = new QLabel(); algorithm_var_label_ = new QLabel(); + algorithm_detail_var_label_ = new QLabel(); primary_key_exist_var_label_ = new QLabel(); auto* mvbox = new QVBoxLayout(); @@ -76,26 +77,28 @@ KeyPairDetailTab::KeyPairDetailTab(const QString& key_id, QWidget* parent) vbox_kd->addWidget(new QLabel(tr("Key ID") + ": "), 0, 0); vbox_kd->addWidget(new QLabel(tr("Algorithm") + ": "), 1, 0); - vbox_kd->addWidget(new QLabel(tr("Key Size") + ": "), 2, 0); - vbox_kd->addWidget(new QLabel(tr("Nominal Usage") + ": "), 3, 0); - vbox_kd->addWidget(new QLabel(tr("Actual Usage") + ": "), 4, 0); - vbox_kd->addWidget(new QLabel(tr("Owner Trust Level") + ": "), 5, 0); - vbox_kd->addWidget(new QLabel(tr("Create Date (Local Time)") + ": "), 6, 0); - vbox_kd->addWidget(new QLabel(tr("Expires on (Local Time)") + ": "), 7, 0); - vbox_kd->addWidget(new QLabel(tr("Last Update (Local Time)") + ": "), 8, 0); - vbox_kd->addWidget(new QLabel(tr("Primary Key Existence") + ": "), 9, 0); + vbox_kd->addWidget(new QLabel(tr("Algorithm Detail") + ": "), 2, 0); + vbox_kd->addWidget(new QLabel(tr("Key Size") + ": "), 3, 0); + vbox_kd->addWidget(new QLabel(tr("Nominal Usage") + ": "), 4, 0); + vbox_kd->addWidget(new QLabel(tr("Actual Usage") + ": "), 5, 0); + vbox_kd->addWidget(new QLabel(tr("Owner Trust Level") + ": "), 6, 0); + vbox_kd->addWidget(new QLabel(tr("Create Date (Local Time)") + ": "), 7, 0); + vbox_kd->addWidget(new QLabel(tr("Expires on (Local Time)") + ": "), 8, 0); + vbox_kd->addWidget(new QLabel(tr("Last Update (Local Time)") + ": "), 9, 0); + vbox_kd->addWidget(new QLabel(tr("Primary Key Existence") + ": "), 10, 0); key_id_var_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); vbox_kd->addWidget(key_id_var_label, 0, 1, 1, 1); vbox_kd->addWidget(algorithm_var_label_, 1, 1, 1, 2); - vbox_kd->addWidget(key_size_var_label_, 2, 1, 1, 2); - vbox_kd->addWidget(usage_var_label_, 3, 1, 1, 2); - vbox_kd->addWidget(actual_usage_var_label_, 4, 1, 1, 2); - vbox_kd->addWidget(owner_trust_var_label_, 5, 1, 1, 2); - vbox_kd->addWidget(created_var_label_, 6, 1, 1, 2); - vbox_kd->addWidget(expire_var_label_, 7, 1, 1, 2); - vbox_kd->addWidget(last_update_var_label_, 8, 1, 1, 2); - vbox_kd->addWidget(primary_key_exist_var_label_, 9, 1, 1, 2); + vbox_kd->addWidget(algorithm_detail_var_label_, 2, 1, 1, 2); + vbox_kd->addWidget(key_size_var_label_, 3, 1, 1, 2); + vbox_kd->addWidget(usage_var_label_, 4, 1, 1, 2); + vbox_kd->addWidget(actual_usage_var_label_, 5, 1, 1, 2); + vbox_kd->addWidget(owner_trust_var_label_, 6, 1, 1, 2); + vbox_kd->addWidget(created_var_label_, 7, 1, 1, 2); + vbox_kd->addWidget(expire_var_label_, 8, 1, 1, 2); + vbox_kd->addWidget(last_update_var_label_, 9, 1, 1, 2); + vbox_kd->addWidget(primary_key_exist_var_label_, 10, 1, 1, 2); auto* copy_key_id_button = new QPushButton(tr("Copy")); copy_key_id_button->setFlat(true); @@ -234,6 +237,7 @@ void KeyPairDetailTab::slot_refresh_key_info() { QString key_expire_val; QString key_create_time_val; QString key_algo_val; + QString key_algo_detail_val; QString key_last_update_val; key_size_val = QString::number(key_.GetPrimaryKeyLength()); @@ -246,6 +250,7 @@ void KeyPairDetailTab::slot_refresh_key_info() { } key_algo_val = key_.GetPublicKeyAlgo(); + key_algo_detail_val = key_.GetKeyAlgo(); created_var_label_->setText(QLocale::system().toString(key_.GetCreateTime())); @@ -258,6 +263,7 @@ void KeyPairDetailTab::slot_refresh_key_info() { key_size_var_label_->setText(key_size_val); algorithm_var_label_->setText(key_algo_val); + algorithm_detail_var_label_->setText(key_algo_detail_val); fingerprint_var_label_->setText(BeautifyFingerprint(key_.GetFingerprint())); icon_label_->hide(); diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.h b/src/ui/dialog/keypair_details/KeyPairDetailTab.h index b12f108c..bead1d06 100644 --- a/src/ui/dialog/keypair_details/KeyPairDetailTab.h +++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.h @@ -75,8 +75,10 @@ class KeyPairDetailTab : public QWidget { QLabel* created_var_label_; ///< Label containing the keys creation date QLabel* last_update_var_label_; ///< QLabel* algorithm_var_label_; ///< Label containing the keys algorithm - QLabel* key_id_var_label; ///< Label containing the keys keyid - QLabel* fingerprint_var_label_; ///< Label containing the keys fingerprint + QLabel* + algorithm_detail_var_label_; ///< containing the keys algorithm detail + QLabel* key_id_var_label; ///< Label containing the keys keyid + QLabel* fingerprint_var_label_; ///< Label containing the keys fingerprint QLabel* usage_var_label_; QLabel* actual_usage_var_label_; QLabel* primary_key_exist_var_label_; diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp index 3f973fae..e61ad2b9 100644 --- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp @@ -64,21 +64,24 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(const QString& key_id, QWidget* parent) subkey_detail_layout->addWidget(new QLabel(tr("Key ID") + ": "), 0, 0); subkey_detail_layout->addWidget(new QLabel(tr("Algorithm") + ": "), 1, 0); - subkey_detail_layout->addWidget(new QLabel(tr("Key Size") + ": "), 2, 0); - subkey_detail_layout->addWidget(new QLabel(tr("Usage") + ": "), 3, 0); + subkey_detail_layout->addWidget(new QLabel(tr("Algorithm Detail") + ": "), 2, + 0); + subkey_detail_layout->addWidget(new QLabel(tr("Key Size") + ": "), 3, 0); + subkey_detail_layout->addWidget(new QLabel(tr("Usage") + ": "), 4, 0); subkey_detail_layout->addWidget( - new QLabel(tr("Expires On (Local Time)") + ": "), 4, 0); + new QLabel(tr("Expires On (Local Time)") + ": "), 5, 0); subkey_detail_layout->addWidget( - new QLabel(tr("Create Date (Local Time)") + ": "), 5, 0); - subkey_detail_layout->addWidget(new QLabel(tr("Existence") + ": "), 6, 0); - subkey_detail_layout->addWidget(new QLabel(tr("Key in Smart Card") + ": "), 7, + new QLabel(tr("Create Date (Local Time)") + ": "), 6, 0); + subkey_detail_layout->addWidget(new QLabel(tr("Existence") + ": "), 7, 0); + subkey_detail_layout->addWidget(new QLabel(tr("Key in Smart Card") + ": "), 8, 0); - subkey_detail_layout->addWidget(new QLabel(tr("Fingerprint") + ": "), 8, 0); + subkey_detail_layout->addWidget(new QLabel(tr("Fingerprint") + ": "), 9, 0); key_id_var_label_ = new QLabel(this); key_size_var_label_ = new QLabel(this); expire_var_label_ = new QLabel(this); algorithm_var_label_ = new QLabel(this); + algorithm_detail_var_label_ = new QLabel(this); created_var_label_ = new QLabel(this); usage_var_label_ = new QLabel(this); master_key_exist_var_label_ = new QLabel(this); @@ -86,14 +89,15 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(const QString& key_id, QWidget* parent) card_key_label_ = new QLabel(this); subkey_detail_layout->addWidget(key_id_var_label_, 0, 1, 1, 1); - subkey_detail_layout->addWidget(key_size_var_label_, 2, 1, 1, 2); - subkey_detail_layout->addWidget(expire_var_label_, 4, 1, 1, 2); subkey_detail_layout->addWidget(algorithm_var_label_, 1, 1, 1, 2); - subkey_detail_layout->addWidget(created_var_label_, 5, 1, 1, 2); - subkey_detail_layout->addWidget(usage_var_label_, 3, 1, 1, 2); - subkey_detail_layout->addWidget(master_key_exist_var_label_, 6, 1, 1, 2); - subkey_detail_layout->addWidget(card_key_label_, 7, 1, 1, 2); - subkey_detail_layout->addWidget(fingerprint_var_label_, 8, 1, 1, 2); + subkey_detail_layout->addWidget(algorithm_detail_var_label_, 2, 1, 1, 2); + subkey_detail_layout->addWidget(key_size_var_label_, 3, 1, 1, 2); + subkey_detail_layout->addWidget(usage_var_label_, 4, 1, 1, 2); + subkey_detail_layout->addWidget(expire_var_label_, 5, 1, 1, 2); + subkey_detail_layout->addWidget(created_var_label_, 6, 1, 1, 2); + subkey_detail_layout->addWidget(master_key_exist_var_label_, 7, 1, 1, 2); + subkey_detail_layout->addWidget(card_key_label_, 8, 1, 1, 2); + subkey_detail_layout->addWidget(fingerprint_var_label_, 9, 1, 1, 2); auto* copy_key_id_button = new QPushButton(tr("Copy")); copy_key_id_button->setFlat(true); @@ -247,6 +251,7 @@ void KeyPairSubkeyTab::slot_refresh_subkey_detail() { } algorithm_var_label_->setText(subkey.GetPubkeyAlgo()); + algorithm_detail_var_label_->setText(subkey.GetKeyAlgo()); created_var_label_->setText( QLocale::system().toString(subkey.GetCreateTime())); diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h index c179c3e9..afbcc749 100644 --- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h +++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h @@ -80,7 +80,8 @@ class KeyPairSubkeyTab : public QWidget { QLabel* expire_var_label_; ///< Label containing the keys expiration date QLabel* created_var_label_; ///< Label containing the keys creation date QLabel* algorithm_var_label_; ///< Label containing the keys algorithm - QLabel* key_id_var_label_; ///< Label containing the keys keyid + QLabel* algorithm_detail_var_label_; ///< + QLabel* key_id_var_label_; ///< Label containing the keys keyid QLabel* fingerprint_var_label_; ///< Label containing the keys fingerprint QLabel* usage_var_label_; ///< QLabel* master_key_exist_var_label_; ///< |