From 1e95a70ab32fcdb8ef42e7ce8df5ba40b1f251ab Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 2 Feb 2025 18:02:44 +0100 Subject: feat: improve KeyGenerateDialog --- src/core/function/gpg/GpgKeyOpera.cpp | 44 +- src/core/function/gpg/GpgKeyOpera.h | 19 +- src/core/model/GpgGenKeyInfo.cpp | 486 -------------------- src/core/model/GpgGenKeyInfo.h | 384 ---------------- src/core/model/GpgKeyGenerateInfo.cpp | 499 +++++++++++++++++++++ src/core/model/GpgKeyGenerateInfo.h | 383 ++++++++++++++++ src/test/core/GpgCoreTestKeygen.cpp | 58 +-- src/test/core/GpgCoreTestSubkeygen.cpp | 38 +- src/ui/dialog/Wizard.cpp | 2 +- src/ui/dialog/key_generate/KeyGenerateDialog.cpp | 210 ++++++--- src/ui/dialog/key_generate/KeyGenerateDialog.h | 23 +- .../dialog/key_generate/SubkeyGenerateDialog.cpp | 127 +++--- src/ui/dialog/key_generate/SubkeyGenerateDialog.h | 6 +- src/ui/main_window/KeyMgmt.cpp | 2 +- ui/KeyGenDialog.ui | 44 +- 15 files changed, 1205 insertions(+), 1120 deletions(-) delete mode 100644 src/core/model/GpgGenKeyInfo.cpp delete mode 100644 src/core/model/GpgGenKeyInfo.h create mode 100644 src/core/model/GpgKeyGenerateInfo.cpp create mode 100644 src/core/model/GpgKeyGenerateInfo.h diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index cf4d1e3b..82001337 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -28,14 +28,12 @@ #include "GpgKeyOpera.h" -#include - #include "core/GpgModel.h" #include "core/function/gpg/GpgCommandExecutor.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/model/DataObject.h" -#include "core/model/GpgGenKeyInfo.h" #include "core/model/GpgGenerateKeyResult.h" +#include "core/model/GpgKeyGenerateInfo.h" #include "core/module/ModuleManager.h" #include "core/typedef/GpgTypedef.h" #include "core/utils/AsyncUtils.h" @@ -163,8 +161,14 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key, }}); } -auto GenerateKeyImpl(GpgContext& ctx, const QSharedPointer& params, +auto GenerateKeyImpl(GpgContext& ctx, + const QSharedPointer& params, const DataObjectPtr& data_object) -> GpgError { + if (params == nullptr || params->GetAlgo() == KeyGenerateInfo::kNoneAlgo || + params->IsSubKey()) { + return GPG_ERR_CANCELED; + } + const auto userid = params->GetUserid(); const auto algo = params->GetAlgo().Id(); @@ -204,7 +208,7 @@ auto GenerateKeyImpl(GpgContext& ctx, const QSharedPointer& params, * @param params key generation args * @return error information */ -void GpgKeyOpera::GenerateKey(const QSharedPointer& params, +void GpgKeyOpera::GenerateKey(const QSharedPointer& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -213,7 +217,7 @@ void GpgKeyOpera::GenerateKey(const QSharedPointer& params, callback, "gpgme_op_createkey", "2.1.0"); } -auto GpgKeyOpera::GenerateKeySync(const QSharedPointer& params) +auto GpgKeyOpera::GenerateKeySync(const QSharedPointer& params) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -223,12 +227,12 @@ auto GpgKeyOpera::GenerateKeySync(const QSharedPointer& params) } auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKey& key, - const QSharedPointer& params, + const QSharedPointer& params, const DataObjectPtr& data_object) -> GpgError { - if (!params->IsSubKey()) return GPG_ERR_CANCELED; - - LOG_D() << "generate subkey algo: " << params->GetAlgo().Name() - << "key size: " << params->GetKeyLength(); + if (params == nullptr || params->GetAlgo() == KeyGenerateInfo::kNoneAlgo || + !params->IsSubKey()) { + return GPG_ERR_CANCELED; + } auto algo = params->GetAlgo().Id(); unsigned long expires = @@ -259,7 +263,7 @@ auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKey& key, } void GpgKeyOpera::GenerateSubkey(const GpgKey& key, - const QSharedPointer& params, + const QSharedPointer& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -268,8 +272,8 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key, callback, "gpgme_op_createsubkey", "2.1.13"); } -auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key, - const QSharedPointer& params) +auto GpgKeyOpera::GenerateSubkeySync( + const GpgKey& key, const QSharedPointer& params) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -279,8 +283,8 @@ auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key, } auto GenerateKeyWithSubkeyImpl(GpgContext& ctx, GpgKeyGetter& key_getter, - const QSharedPointer& p_params, - const QSharedPointer& s_params, + const QSharedPointer& p_params, + const QSharedPointer& s_params, const DataObjectPtr& data_object) -> GpgError { auto err = GenerateKeyImpl(ctx, p_params, data_object); @@ -306,8 +310,8 @@ auto GenerateKeyWithSubkeyImpl(GpgContext& ctx, GpgKeyGetter& key_getter, } void GpgKeyOpera::GenerateKeyWithSubkey( - const QSharedPointer& p_params, - const QSharedPointer& s_params, + const QSharedPointer& p_params, + const QSharedPointer& s_params, const GpgOperationCallback& callback) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -318,8 +322,8 @@ void GpgKeyOpera::GenerateKeyWithSubkey( } auto GpgKeyOpera::GenerateKeyWithSubkeySync( - const QSharedPointer& p_params, - const QSharedPointer& s_params) + const QSharedPointer& p_params, + const QSharedPointer& s_params) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) -> GpgError { diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h index d724f5f8..f6b7143e 100644 --- a/src/core/function/gpg/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -39,7 +39,7 @@ namespace GpgFrontend { * @brief * */ -class GenKeyInfo; +class KeyGenerateInfo; /** * @brief @@ -115,7 +115,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param result * @return GpgFrontend::GpgError */ - void GenerateKey(const QSharedPointer&, + void GenerateKey(const QSharedPointer&, const GpgOperationCallback&); /** @@ -123,7 +123,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * * @param params */ - auto GenerateKeySync(const QSharedPointer& params) + auto GenerateKeySync(const QSharedPointer& params) -> std::tuple; /** @@ -134,7 +134,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @return GpgFrontend::GpgError */ void GenerateSubkey(const GpgKey& key, - const QSharedPointer& params, + const QSharedPointer& params, const GpgOperationCallback&); /** @@ -144,7 +144,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param params */ auto GenerateSubkeySync(const GpgKey& key, - const QSharedPointer& params) + const QSharedPointer& params) -> std::tuple; /** @@ -154,8 +154,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param subkey_params * @param callback */ - void GenerateKeyWithSubkey(const QSharedPointer& p_params, - const QSharedPointer& s_params, + void GenerateKeyWithSubkey(const QSharedPointer& p_params, + const QSharedPointer& s_params, const GpgOperationCallback& callback); /** @@ -165,8 +165,9 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param subkey_params * @param callback */ - auto GenerateKeyWithSubkeySync(const QSharedPointer& p_params, - const QSharedPointer& s_params) + auto GenerateKeyWithSubkeySync( + const QSharedPointer& p_params, + const QSharedPointer& s_params) -> std::tuple; private: diff --git a/src/core/model/GpgGenKeyInfo.cpp b/src/core/model/GpgGenKeyInfo.cpp deleted file mode 100644 index 2b8a3dbc..00000000 --- a/src/core/model/GpgGenKeyInfo.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/** - * Copyright (C) 2021-2024 Saturneric - * - * 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 . - * - * 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 starting on May 12, 2021. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "GpgGenKeyInfo.h" - -#include - -#include "module/ModuleManager.h" -#include "utils/CommonUtils.h" - -namespace GpgFrontend { - -const QContainer GenKeyInfo::kPrimaryKeyAlgos = { - /** - * Algorithm (DSA) as a government standard for digital signatures. - * Originally, it supported key lengths between 512 and 1024 bits. - * Recently, NIST has declared 512-bit keys obsolete: - * now, DSA is available in 1024, 2048 and 3072-bit lengths. - */ - {"rsa1024", "RSA", "RSA", 1024, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, - {"rsa2048", "RSA", "RSA", 2048, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, - {"rsa3072", "RSA", "RSA", 3072, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, - {"rsa4096", "RSA", "RSA", 4096, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, - {"dsa1024", "DSA", "DSA", 1024, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"dsa2048", "DSA", "DSA", 2048, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"dsa3072", "DSA", "DSA", 3072, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"ed25519", "ED25519", "EdDSA", 256, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"nistp256", "NIST", "ECDSA", 256, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"nistp384", "NIST", "ECDSA", 384, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"nistp521", "NIST", "ECDSA", 521, kSIGN | kAUTH | kCERT, "2.2.0"}, - {"brainpoolp256r1", "BrainPooL", "ECDSA", 256, kSIGN | kAUTH | kCERT, - "2.3.0"}, - {"brainpoolp384r1", "BrainPooL", "ECDSA", 384, kSIGN | kAUTH | kCERT, - "2.3.0"}, - {"brainpoolp512r1", "BrainPooL", "ECDSA", 512, kSIGN | kAUTH | kCERT, - "2.3.0"}, - {"ed448", "ED448", "EdDSA", 448, kSIGN | kAUTH | kCERT, "2.3.0"}, - {"secp256k1", "ED448", "EdDSA", 256, kSIGN | kAUTH | kCERT, "2.3.0"}, -}; - -const QContainer GenKeyInfo::kSubKeyAlgos = { - {"rsa1024", "RSA", "RSA", 1024, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, - {"rsa2048", "RSA", "RSA", 2048, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, - {"rsa3072", "RSA", "RSA", 3072, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, - {"rsa4096", "RSA", "RSA", 4096, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, - {"dsa1024", "DSA", "DSA", 1024, kSIGN | kAUTH, "2.2.0"}, - {"dsa2048", "DSA", "DSA", 2048, kSIGN | kAUTH, "2.2.0"}, - {"dsa3072", "DSA", "DSA", 3072, kSIGN | kAUTH, "2.2.0"}, - {"ed25519", "ED25519", "EdDSA", 256, kSIGN | kAUTH, "2.2.0"}, - {"cv25519", "CV25519", "ECDH", 256, kENCRYPT, "2.2.0"}, - {"nistp256", "NIST", "ECDH", 256, kENCRYPT, "2.2.0"}, - {"nistp384", "NIST", "ECDH", 384, kENCRYPT, "2.2.0"}, - {"nistp521", "NIST", "ECDH", 521, kENCRYPT, "2.2.0"}, - {"brainpoolp256r1", "BrainPooL", "ECDH", 256, kENCRYPT, "2.3.0"}, - {"brainpoolp384r1", "BrainPooL", "ECDH", 384, kENCRYPT, "2.3.0"}, - {"brainpoolp512r1", "BrainPooL", "ECDH", 512, kENCRYPT, "2.3.0"}, - {"x448", "X448", "ECDH", 448, kENCRYPT, "2.3.0"}, - {"secp256k1", "SECP256K1", "ECDH", 256, kENCRYPT, "2.3.0"}, - /** - * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths - * ranging from 1024 to 4096 bits. - */ - {"elg1024", "ELG-E", "ELG-E", 1024, kENCRYPT, "2.2.0"}, - {"elg2048", "ELG-E", "ELG-E", 2048, kENCRYPT, "2.2.0"}, - {"elg3072", "ELG-E", "ELG-E", 3072, kENCRYPT, "2.2.0"}, - {"elg4096", "ELG-E", "ELG-E", 4096, kENCRYPT, "2.2.0"}, -}; - -auto GenKeyInfo::GetSupportedKeyAlgo() -> QContainer { - const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - - QContainer algos; - - for (const auto &algo : kPrimaryKeyAlgos) { - if (!algo.IsSupported(gnupg_version)) continue; - algos.append(algo); - } - - std::sort(algos.begin(), algos.end(), [](const KeyAlgo &a, const KeyAlgo &b) { - return a.Name() < b.Name() && a.KeyLength() < b.KeyLength(); - }); - - return algos; -} - -auto GenKeyInfo::GetSupportedSubkeyAlgo() -> QContainer { - const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - - QContainer algos; - - for (const auto &algo : kSubKeyAlgos) { - if (!algo.IsSupported(gnupg_version)) continue; - algos.append(algo); - } - - std::sort(algos.begin(), algos.end(), [](const KeyAlgo &a, const KeyAlgo &b) { - return a.Name() < b.Name() && a.KeyLength() < b.KeyLength(); - }); - - return algos; -} - -auto GenKeyInfo::SearchPrimaryKeyAlgo(const QString &algo_id) - -> std::tuple { - auto it = - std::find_if(kPrimaryKeyAlgos.cbegin(), kPrimaryKeyAlgos.cend(), - [=](const KeyAlgo &algo) { return algo.Id() == algo_id; }); - - if (it != kPrimaryKeyAlgos.cend()) { - return {true, *it}; - } - - return {false, KeyAlgo{}}; -} - -auto GenKeyInfo::SearchSubKeyAlgo(const QString &algo_id) - -> std::tuple { - auto it = - std::find_if(kSubKeyAlgos.cbegin(), kSubKeyAlgos.cend(), - [=](const KeyAlgo &algo) { return algo.Id() == algo_id; }); - - if (it != kSubKeyAlgos.cend()) { - return {true, *it}; - } - - return {false, KeyAlgo{}}; -} - -void GenKeyInfo::SetAlgo(const KeyAlgo &algo) { - // reset all options - reset_options(); - - this->SetAllowCertification(algo.CanCert()); - this->allow_change_certification_ = false; - - SetAllowEncryption(algo.CanEncrypt()); - allow_change_encryption_ = algo.CanEncrypt(); - - SetAllowSigning(algo.CanSign()); - allow_change_signing_ = algo.CanSign(); - - SetAllowAuthentication(algo.CanAuth()); - allow_change_authentication_ = algo.CanAuth(); - - this->algo_ = algo; -} - -void GenKeyInfo::reset_options() { - allow_change_encryption_ = true; - SetAllowEncryption(true); - - allow_change_certification_ = true; - SetAllowCertification(true); - - allow_change_signing_ = true; - SetAllowSigning(true); - - allow_change_authentication_ = true; - SetAllowAuthentication(true); -} - -void GenKeyInfo::SetExpireTime(const QDateTime &m_expired) { - GenKeyInfo::expired_ = m_expired; -} - -void GenKeyInfo::SetNonExpired(bool m_non_expired) { - if (!m_non_expired) this->expired_ = QDateTime::fromSecsSinceEpoch(0); - GenKeyInfo::non_expired_ = m_non_expired; -} - -void GenKeyInfo::SetAllowEncryption(bool m_allow_encryption) { - if (allow_change_encryption_) { - GenKeyInfo::allow_encryption_ = m_allow_encryption; - } -} - -void GenKeyInfo::SetAllowCertification(bool m_allow_certification) { - if (allow_change_certification_) { - GenKeyInfo::allow_certification_ = m_allow_certification; - } -} - -GenKeyInfo::GenKeyInfo(bool is_subkey) : subkey_(is_subkey) { - assert(!GetSupportedKeyAlgo().empty()); - SetAlgo(GetSupportedKeyAlgo().front()); -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsSubKey() const -> bool { return subkey_; } - -/** - * @brief Set the Is Sub Key object - * - * @param m_sub_key - */ -void GenKeyInfo::SetIsSubKey(bool m_sub_key) { - GenKeyInfo::subkey_ = m_sub_key; -} - -/** - * @brief Get the Userid object - * - * @return QString - */ -[[nodiscard]] auto GenKeyInfo::GetUserid() const -> QString { - return QString("%1(%2)<%3>").arg(name_).arg(comment_).arg(email_); -} - -/** - * @brief Set the Name object - * - * @param m_name - */ -void GenKeyInfo::SetName(const QString &m_name) { this->name_ = m_name; } - -/** - * @brief Set the Email object - * - * @param m_email - */ -void GenKeyInfo::SetEmail(const QString &m_email) { this->email_ = m_email; } - -/** - * @brief Set the Comment object - * - * @param m_comment - */ -void GenKeyInfo::SetComment(const QString &m_comment) { - this->comment_ = m_comment; -} - -/** - * @brief Get the Name object - * - * @return QString - */ -[[nodiscard]] auto GenKeyInfo::GetName() const -> QString { return name_; } - -/** - * @brief Get the Email object - * - * @return QString - */ -[[nodiscard]] auto GenKeyInfo::GetEmail() const -> QString { return email_; } - -/** - * @brief Get the Comment object - * - * @return QString - */ -[[nodiscard]] auto GenKeyInfo::GetComment() const -> QString { - return comment_; -} - -/** - * @brief Get the Algo object - * - * @return const QString& - */ -[[nodiscard]] auto GenKeyInfo::GetAlgo() const -> const KeyAlgo & { - return algo_; -} - -/** - * @brief Get the Key Size object - * - * @return int - */ -[[nodiscard]] auto GenKeyInfo::GetKeyLength() const -> int { - return algo_.KeyLength(); -} - -/** - * @brief Get the Expired object - * - * @return const QDateTime& - */ -[[nodiscard]] auto GenKeyInfo::GetExpireTime() const -> const QDateTime & { - return expired_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsNonExpired() const -> bool { - return non_expired_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsNoPassPhrase() const -> bool { - return this->no_passphrase_; -} - -/** - * @brief Set the Non Pass Phrase object - * - * @param m_non_pass_phrase - */ -void GenKeyInfo::SetNonPassPhrase(bool m_non_pass_phrase) { - GenKeyInfo::no_passphrase_ = m_non_pass_phrase; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowSigning() const -> bool { - return allow_signing_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowNoPassPhrase() const -> bool { - return allow_no_pass_phrase_; -} - -/** - * @brief Set the Allow Signing object - * - * @param m_allow_signing - */ -void GenKeyInfo::SetAllowSigning(bool m_allow_signing) { - if (allow_change_signing_) GenKeyInfo::allow_signing_ = m_allow_signing; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowEncryption() const -> bool { - return allow_encryption_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowCertification() const -> bool { - return allow_certification_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowAuthentication() const -> bool { - return allow_authentication_; -} - -/** - * @brief Set the Allow Authentication object - * - * @param m_allow_authentication - */ -void GenKeyInfo::SetAllowAuthentication(bool m_allow_authentication) { - if (allow_change_authentication_) { - GenKeyInfo::allow_authentication_ = m_allow_authentication; - } -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowChangeSigning() const -> bool { - return allow_change_signing_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowChangeEncryption() const -> bool { - return allow_change_encryption_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowChangeCertification() const -> bool { - return allow_change_certification_; -} - -/** - * @brief - * - * @return true - * @return false - */ -[[nodiscard]] auto GenKeyInfo::IsAllowChangeAuthentication() const -> bool { - return allow_change_authentication_; -} - -KeyAlgo::KeyAlgo(QString id, QString name, QString type, int length, int opera, - QString supported_version) - : id_(std::move(id)), - name_(std::move(name)), - type_(std::move(type)), - length_(length), - supported_version_(std::move(supported_version)) { - encrypt_ = ((opera & kENCRYPT) != 0); - sign_ = ((opera & kSIGN) != 0); - auth_ = ((opera & kAUTH) != 0); - cert_ = ((opera & kCERT) != 0); -}; - -auto KeyAlgo::Id() const -> QString { return id_; } - -auto KeyAlgo::Name() const -> QString { return name_; } - -auto KeyAlgo::KeyLength() const -> int { return length_; } - -auto KeyAlgo::Type() const -> QString { return type_; } - -auto KeyAlgo::CanEncrypt() const -> bool { return encrypt_; } - -auto KeyAlgo::CanSign() const -> bool { return sign_; } - -auto KeyAlgo::CanAuth() const -> bool { return auth_; } - -auto KeyAlgo::CanCert() const -> bool { return cert_; } - -auto KeyAlgo::IsSupported(const QString &version) const -> bool { - return GFCompareSoftwareVersion(version, supported_version_) >= 0; -} - -} // namespace GpgFrontend diff --git a/src/core/model/GpgGenKeyInfo.h b/src/core/model/GpgGenKeyInfo.h deleted file mode 100644 index a6dd03b0..00000000 --- a/src/core/model/GpgGenKeyInfo.h +++ /dev/null @@ -1,384 +0,0 @@ -/** - * Copyright (C) 2021-2024 Saturneric - * - * 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 . - * - * 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 starting on May 12, 2021. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include - -#include "core/GpgFrontendCoreExport.h" -#include "core/function/gpg/GpgKeyOpera.h" -#include "core/typedef/CoreTypedef.h" - -namespace GpgFrontend { - -class GPGFRONTEND_CORE_EXPORT KeyAlgo { - public: - KeyAlgo() = default; - - KeyAlgo(QString id, QString name, QString type, int length, int opera, - QString supported_version); - - KeyAlgo(const KeyAlgo &) = default; - - auto operator=(const KeyAlgo &) -> KeyAlgo & = default; - - [[nodiscard]] auto Id() const -> QString; - - [[nodiscard]] auto Name() const -> QString; - - [[nodiscard]] auto KeyLength() const -> int; - - [[nodiscard]] auto Type() const -> QString; - - [[nodiscard]] auto CanEncrypt() const -> bool; - - [[nodiscard]] auto CanSign() const -> bool; - - [[nodiscard]] auto CanAuth() const -> bool; - - [[nodiscard]] auto CanCert() const -> bool; - - [[nodiscard]] auto IsSupported(const QString &version) const -> bool; - - private: - QString id_; - QString name_; - QString type_; - int length_; - bool encrypt_; - bool sign_; - bool auth_; - bool cert_; - QString supported_version_; -}; - -class GPGFRONTEND_CORE_EXPORT GenKeyInfo { - public: - static const QContainer kPrimaryKeyAlgos; - - static const QContainer kSubKeyAlgos; - - /** - * @brief Construct a new Gen Key Info object - * - * @param m_is_sub_key - * @param m_standalone - */ - explicit GenKeyInfo(bool is_subkey = false); - - /** - * @brief Get the Supported Key Algo object - * - * @return const QContainer& - */ - static auto GetSupportedKeyAlgo() -> QContainer; - - /** - * @brief Get the Supported Subkey Algo object - * - * @return const QContainer& - */ - static auto GetSupportedSubkeyAlgo() -> QContainer; - - /** - * @brief - * - * @param algo_id - * @return std::tuple - */ - static auto SearchPrimaryKeyAlgo(const QString &algo_id) - -> std::tuple; - - /** - * @brief - * - * @param algo_id - * @return std::tuple - */ - static auto SearchSubKeyAlgo(const QString &algo_id) - -> std::tuple; - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsSubKey() const -> bool; - - /** - * @brief Set the Is Sub Key object - * - * @param m_sub_key - */ - void SetIsSubKey(bool); - - /** - * @brief Get the Userid object - * - * @return QString - */ - [[nodiscard]] auto GetUserid() const -> QString; - - /** - * @brief Set the Name object - * - * @param m_name - */ - void SetName(const QString &name); - - /** - * @brief Set the Email object - * - * @param m_email - */ - void SetEmail(const QString &email); - - /** - * @brief Set the Comment object - * - * @param m_comment - */ - void SetComment(const QString &comment); - - /** - * @brief Get the Name object - * - * @return QString - */ - [[nodiscard]] auto GetName() const -> QString; - - /** - * @brief Get the Email object - * - * @return QString - */ - [[nodiscard]] auto GetEmail() const -> QString; - - /** - * @brief Get the Comment object - * - * @return QString - */ - [[nodiscard]] auto GetComment() const -> QString; - - /** - * @brief Get the Algo object - * - * @return const QString& - */ - [[nodiscard]] auto GetAlgo() const -> const KeyAlgo &; - - /** - * @brief Set the Algo object - * - * @param m_algo - */ - void SetAlgo(const KeyAlgo &); - - /** - * @brief Get the Key Size object - * - * @return int - */ - [[nodiscard]] auto GetKeyLength() const -> int; - - /** - * @brief Get the Expired object - * - * @return const QDateTime& - */ - [[nodiscard]] auto GetExpireTime() const -> const QDateTime &; - - /** - * @brief Set the Expired object - * - * @param m_expired - */ - void SetExpireTime(const QDateTime &m_expired); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsNonExpired() const -> bool; - - /** - * @brief Set the Non Expired object - * - * @param m_non_expired - */ - void SetNonExpired(bool m_non_expired); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsNoPassPhrase() const -> bool; - - /** - * @brief Set the Non Pass Phrase object - * - * @param m_non_pass_phrase - */ - void SetNonPassPhrase(bool m_non_pass_phrase); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowSigning() const -> bool; - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowNoPassPhrase() const -> bool; - - /** - * @brief Set the Allow Signing object - * - * @param m_allow_signing - */ - void SetAllowSigning(bool m_allow_signing); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowEncryption() const -> bool; - - /** - * @brief Set the Allow Encryption object - * - * @param m_allow_encryption - */ - void SetAllowEncryption(bool m_allow_encryption); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowCertification() const -> bool; - - /** - * @brief Set the Allow Certification object - * - * @param m_allow_certification - */ - void SetAllowCertification(bool m_allow_certification); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowAuthentication() const -> bool; - - /** - * @brief Set the Allow Authentication object - * - * @param m_allow_authentication - */ - void SetAllowAuthentication(bool m_allow_authentication); - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowChangeSigning() const -> bool; - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowChangeEncryption() const -> bool; - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowChangeCertification() const -> bool; - - /** - * @brief - * - * @return true - * @return false - */ - [[nodiscard]] auto IsAllowChangeAuthentication() const -> bool; - - private: - bool subkey_ = false; ///< - QString name_; ///< - QString email_; ///< - QString comment_; ///< - - KeyAlgo algo_; ///< - QDateTime expired_ = QDateTime::currentDateTime().addYears(2); - bool non_expired_ = false; ///< - - bool no_passphrase_ = false; ///< - bool allow_no_pass_phrase_ = true; ///< - - bool allow_encryption_ = true; ///< - bool allow_change_encryption_ = true; ///< - bool allow_certification_ = true; ///< - bool allow_change_certification_ = true; ///< - bool allow_authentication_ = true; ///< - bool allow_change_authentication_ = true; ///< - bool allow_signing_ = true; ///< - bool allow_change_signing_ = true; ///< - - /** - * @brief - * - */ - void reset_options(); -}; - -} // namespace GpgFrontend diff --git a/src/core/model/GpgKeyGenerateInfo.cpp b/src/core/model/GpgKeyGenerateInfo.cpp new file mode 100644 index 00000000..fda6d09a --- /dev/null +++ b/src/core/model/GpgKeyGenerateInfo.cpp @@ -0,0 +1,499 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * 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 . + * + * 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 starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgKeyGenerateInfo.h" + +#include + +#include "module/ModuleManager.h" +#include "utils/CommonUtils.h" + +namespace GpgFrontend { + +const KeyAlgo KeyGenerateInfo::kNoneAlgo = {"none", "None", "None", + 0, 0, "0.0.0"}; + +const QContainer KeyGenerateInfo::kPrimaryKeyAlgos = { + kNoneAlgo, + + /** + * Algorithm (DSA) as a government standard for digital signatures. + * Originally, it supported key lengths between 512 and 1024 bits. + * Recently, NIST has declared 512-bit keys obsolete: + * now, DSA is available in 1024, 2048 and 3072-bit lengths. + */ + {"rsa1024", "RSA", "RSA", 1024, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, + {"rsa2048", "RSA", "RSA", 2048, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, + {"rsa3072", "RSA", "RSA", 3072, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, + {"rsa4096", "RSA", "RSA", 4096, kENCRYPT | kSIGN | kAUTH | kCERT, "2.2.0"}, + {"dsa1024", "DSA", "DSA", 1024, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"dsa2048", "DSA", "DSA", 2048, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"dsa3072", "DSA", "DSA", 3072, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"ed25519", "ED25519", "EdDSA", 256, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"nistp256", "NIST", "ECDSA", 256, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"nistp384", "NIST", "ECDSA", 384, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"nistp521", "NIST", "ECDSA", 521, kSIGN | kAUTH | kCERT, "2.2.0"}, + {"brainpoolp256r1", "BrainPooL", "ECDSA", 256, kSIGN | kAUTH | kCERT, + "2.3.0"}, + {"brainpoolp384r1", "BrainPooL", "ECDSA", 384, kSIGN | kAUTH | kCERT, + "2.3.0"}, + {"brainpoolp512r1", "BrainPooL", "ECDSA", 512, kSIGN | kAUTH | kCERT, + "2.3.0"}, + {"ed448", "ED448", "EdDSA", 448, kSIGN | kAUTH | kCERT, "2.3.0"}, + {"secp256k1", "ED448", "EdDSA", 256, kSIGN | kAUTH | kCERT, "2.3.0"}, +}; + +const QContainer KeyGenerateInfo::kSubKeyAlgos = { + kNoneAlgo, + + {"rsa1024", "RSA", "RSA", 1024, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, + {"rsa2048", "RSA", "RSA", 2048, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, + {"rsa3072", "RSA", "RSA", 3072, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, + {"rsa4096", "RSA", "RSA", 4096, kENCRYPT | kSIGN | kAUTH, "2.2.0"}, + {"dsa1024", "DSA", "DSA", 1024, kSIGN | kAUTH, "2.2.0"}, + {"dsa2048", "DSA", "DSA", 2048, kSIGN | kAUTH, "2.2.0"}, + {"dsa3072", "DSA", "DSA", 3072, kSIGN | kAUTH, "2.2.0"}, + {"ed25519", "ED25519", "EdDSA", 256, kSIGN | kAUTH, "2.2.0"}, + {"cv25519", "CV25519", "ECDH", 256, kENCRYPT, "2.2.0"}, + {"nistp256", "NIST", "ECDH", 256, kENCRYPT, "2.2.0"}, + {"nistp384", "NIST", "ECDH", 384, kENCRYPT, "2.2.0"}, + {"nistp521", "NIST", "ECDH", 521, kENCRYPT, "2.2.0"}, + {"brainpoolp256r1", "BrainPooL", "ECDH", 256, kENCRYPT, "2.3.0"}, + {"brainpoolp384r1", "BrainPooL", "ECDH", 384, kENCRYPT, "2.3.0"}, + {"brainpoolp512r1", "BrainPooL", "ECDH", 512, kENCRYPT, "2.3.0"}, + {"x448", "X448", "ECDH", 448, kENCRYPT, "2.3.0"}, + {"secp256k1", "SECP256K1", "ECDH", 256, kENCRYPT, "2.3.0"}, + /** + * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths + * ranging from 1024 to 4096 bits. + */ + {"elg1024", "ELG-E", "ELG-E", 1024, kENCRYPT, "2.2.0"}, + {"elg2048", "ELG-E", "ELG-E", 2048, kENCRYPT, "2.2.0"}, + {"elg3072", "ELG-E", "ELG-E", 3072, kENCRYPT, "2.2.0"}, + {"elg4096", "ELG-E", "ELG-E", 4096, kENCRYPT, "2.2.0"}, +}; + +auto KeyGenerateInfo::GetSupportedKeyAlgo() -> QContainer { + const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); + + QContainer algos; + + for (const auto &algo : kPrimaryKeyAlgos) { + if (!algo.IsSupported(gnupg_version)) continue; + algos.append(algo); + } + + std::sort(algos.begin(), algos.end(), [](const KeyAlgo &a, const KeyAlgo &b) { + return a.Name() < b.Name() && a.KeyLength() < b.KeyLength(); + }); + + return algos; +} + +auto KeyGenerateInfo::GetSupportedSubkeyAlgo() -> QContainer { + const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); + + QContainer algos; + + for (const auto &algo : kSubKeyAlgos) { + if (!algo.IsSupported(gnupg_version)) continue; + algos.append(algo); + } + + std::sort(algos.begin(), algos.end(), [](const KeyAlgo &a, const KeyAlgo &b) { + return a.Name() < b.Name() && a.KeyLength() < b.KeyLength(); + }); + + return algos; +} + +KeyGenerateInfo::KeyGenerateInfo(bool is_subkey) + : subkey_(is_subkey), algo_(kNoneAlgo) {} + +auto KeyGenerateInfo::SearchPrimaryKeyAlgo(const QString &algo_id) + -> std::tuple { + auto it = + std::find_if(kPrimaryKeyAlgos.cbegin(), kPrimaryKeyAlgos.cend(), + [=](const KeyAlgo &algo) { return algo.Id() == algo_id; }); + + if (it != kPrimaryKeyAlgos.cend()) { + return {true, *it}; + } + + return {false, KeyAlgo{}}; +} + +auto KeyGenerateInfo::SearchSubKeyAlgo(const QString &algo_id) + -> std::tuple { + auto it = + std::find_if(kSubKeyAlgos.cbegin(), kSubKeyAlgos.cend(), + [=](const KeyAlgo &algo) { return algo.Id() == algo_id; }); + + if (it != kSubKeyAlgos.cend()) { + return {true, *it}; + } + + return {false, KeyAlgo{}}; +} + +void KeyGenerateInfo::SetAlgo(const KeyAlgo &algo) { + // reset all options + reset_options(); + + this->SetAllowCertification(algo.CanCert()); + this->allow_change_certification_ = false; + + SetAllowEncryption(algo.CanEncrypt()); + allow_change_encryption_ = algo.CanEncrypt(); + + SetAllowSigning(algo.CanSign()); + allow_change_signing_ = algo.CanSign(); + + SetAllowAuthentication(algo.CanAuth()); + allow_change_authentication_ = algo.CanAuth(); + + this->algo_ = algo; +} + +void KeyGenerateInfo::reset_options() { + allow_change_encryption_ = true; + SetAllowEncryption(true); + + allow_change_certification_ = true; + SetAllowCertification(true); + + allow_change_signing_ = true; + SetAllowSigning(true); + + allow_change_authentication_ = true; + SetAllowAuthentication(true); +} + +void KeyGenerateInfo::SetExpireTime(const QDateTime &m_expired) { + KeyGenerateInfo::expired_ = m_expired; +} + +void KeyGenerateInfo::SetNonExpired(bool m_non_expired) { + if (!m_non_expired) this->expired_ = QDateTime::fromSecsSinceEpoch(0); + KeyGenerateInfo::non_expired_ = m_non_expired; +} + +void KeyGenerateInfo::SetAllowEncryption(bool m_allow_encryption) { + if (allow_change_encryption_) { + KeyGenerateInfo::allow_encryption_ = m_allow_encryption; + } +} + +void KeyGenerateInfo::SetAllowCertification(bool m_allow_certification) { + if (allow_change_certification_) { + KeyGenerateInfo::allow_certification_ = m_allow_certification; + } +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsSubKey() const -> bool { return subkey_; } + +/** + * @brief Set the Is Sub Key object + * + * @param m_sub_key + */ +void KeyGenerateInfo::SetIsSubKey(bool m_sub_key) { + KeyGenerateInfo::subkey_ = m_sub_key; +} + +/** + * @brief Get the Userid object + * + * @return QString + */ +[[nodiscard]] auto KeyGenerateInfo::GetUserid() const -> QString { + return QString("%1(%2)<%3>").arg(name_).arg(comment_).arg(email_); +} + +/** + * @brief Set the Name object + * + * @param m_name + */ +void KeyGenerateInfo::SetName(const QString &m_name) { this->name_ = m_name; } + +/** + * @brief Set the Email object + * + * @param m_email + */ +void KeyGenerateInfo::SetEmail(const QString &m_email) { + this->email_ = m_email; +} + +/** + * @brief Set the Comment object + * + * @param m_comment + */ +void KeyGenerateInfo::SetComment(const QString &m_comment) { + this->comment_ = m_comment; +} + +/** + * @brief Get the Name object + * + * @return QString + */ +[[nodiscard]] auto KeyGenerateInfo::GetName() const -> QString { return name_; } + +/** + * @brief Get the Email object + * + * @return QString + */ +[[nodiscard]] auto KeyGenerateInfo::GetEmail() const -> QString { + return email_; +} + +/** + * @brief Get the Comment object + * + * @return QString + */ +[[nodiscard]] auto KeyGenerateInfo::GetComment() const -> QString { + return comment_; +} + +/** + * @brief Get the Algo object + * + * @return const QString& + */ +[[nodiscard]] auto KeyGenerateInfo::GetAlgo() const -> const KeyAlgo & { + return algo_; +} + +/** + * @brief Get the Key Size object + * + * @return int + */ +[[nodiscard]] auto KeyGenerateInfo::GetKeyLength() const -> int { + return algo_.KeyLength(); +} + +/** + * @brief Get the Expired object + * + * @return const QDateTime& + */ +[[nodiscard]] auto KeyGenerateInfo::GetExpireTime() const -> const QDateTime & { + return expired_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsNonExpired() const -> bool { + return non_expired_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsNoPassPhrase() const -> bool { + return this->no_passphrase_; +} + +/** + * @brief Set the Non Pass Phrase object + * + * @param m_non_pass_phrase + */ +void KeyGenerateInfo::SetNonPassPhrase(bool m_non_pass_phrase) { + KeyGenerateInfo::no_passphrase_ = m_non_pass_phrase; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowSigning() const -> bool { + return allow_signing_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowNoPassPhrase() const -> bool { + return allow_no_pass_phrase_; +} + +/** + * @brief Set the Allow Signing object + * + * @param m_allow_signing + */ +void KeyGenerateInfo::SetAllowSigning(bool m_allow_signing) { + if (allow_change_signing_) KeyGenerateInfo::allow_signing_ = m_allow_signing; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowEncryption() const -> bool { + return allow_encryption_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowCertification() const -> bool { + return allow_certification_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowAuthentication() const -> bool { + return allow_authentication_; +} + +/** + * @brief Set the Allow Authentication object + * + * @param m_allow_authentication + */ +void KeyGenerateInfo::SetAllowAuthentication(bool m_allow_authentication) { + if (allow_change_authentication_) { + KeyGenerateInfo::allow_authentication_ = m_allow_authentication; + } +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowChangeSigning() const -> bool { + return allow_change_signing_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowChangeEncryption() const -> bool { + return allow_change_encryption_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowChangeCertification() const -> bool { + return allow_change_certification_; +} + +/** + * @brief + * + * @return true + * @return false + */ +[[nodiscard]] auto KeyGenerateInfo::IsAllowChangeAuthentication() const + -> bool { + return allow_change_authentication_; +} + +KeyAlgo::KeyAlgo(QString id, QString name, QString type, int length, int opera, + QString supported_version) + : id_(std::move(id)), + name_(std::move(name)), + type_(std::move(type)), + length_(length), + supported_version_(std::move(supported_version)) { + encrypt_ = ((opera & kENCRYPT) != 0); + sign_ = ((opera & kSIGN) != 0); + auth_ = ((opera & kAUTH) != 0); + cert_ = ((opera & kCERT) != 0); +}; + +auto KeyAlgo::Id() const -> QString { return id_; } + +auto KeyAlgo::Name() const -> QString { return name_; } + +auto KeyAlgo::KeyLength() const -> int { return length_; } + +auto KeyAlgo::Type() const -> QString { return type_; } + +auto KeyAlgo::CanEncrypt() const -> bool { return encrypt_; } + +auto KeyAlgo::CanSign() const -> bool { return sign_; } + +auto KeyAlgo::CanAuth() const -> bool { return auth_; } + +auto KeyAlgo::CanCert() const -> bool { return cert_; } + +auto KeyAlgo::IsSupported(const QString &version) const -> bool { + return GFCompareSoftwareVersion(version, supported_version_) >= 0; +} + +auto KeyAlgo::operator==(const KeyAlgo &o) const -> bool { + return this->id_ == o.id_; +} +} // namespace GpgFrontend diff --git a/src/core/model/GpgKeyGenerateInfo.h b/src/core/model/GpgKeyGenerateInfo.h new file mode 100644 index 00000000..0f3f2d70 --- /dev/null +++ b/src/core/model/GpgKeyGenerateInfo.h @@ -0,0 +1,383 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * 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 . + * + * 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 starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/GpgFrontendCoreExport.h" +#include "core/typedef/CoreTypedef.h" + +namespace GpgFrontend { + +class GPGFRONTEND_CORE_EXPORT KeyAlgo { + public: + KeyAlgo() = default; + + KeyAlgo(QString id, QString name, QString type, int length, int opera, + QString supported_version); + + KeyAlgo(const KeyAlgo &) = default; + + auto operator=(const KeyAlgo &) -> KeyAlgo & = default; + + auto operator==(const KeyAlgo &o) const -> bool; + + [[nodiscard]] auto Id() const -> QString; + + [[nodiscard]] auto Name() const -> QString; + + [[nodiscard]] auto KeyLength() const -> int; + + [[nodiscard]] auto Type() const -> QString; + + [[nodiscard]] auto CanEncrypt() const -> bool; + + [[nodiscard]] auto CanSign() const -> bool; + + [[nodiscard]] auto CanAuth() const -> bool; + + [[nodiscard]] auto CanCert() const -> bool; + + [[nodiscard]] auto IsSupported(const QString &version) const -> bool; + + private: + QString id_; + QString name_; + QString type_; + int length_; + bool encrypt_; + bool sign_; + bool auth_; + bool cert_; + QString supported_version_; +}; + +class GPGFRONTEND_CORE_EXPORT KeyGenerateInfo { + public: + static const KeyAlgo kNoneAlgo; + static const QContainer kPrimaryKeyAlgos; + static const QContainer kSubKeyAlgos; + + /** + * @brief Construct a new Gen Key Info object + * + * @param m_is_sub_key + * @param m_standalone + */ + explicit KeyGenerateInfo(bool is_subkey = false); + + /** + * @brief Get the Supported Key Algo object + * + * @return const QContainer& + */ + static auto GetSupportedKeyAlgo() -> QContainer; + + /** + * @brief Get the Supported Subkey Algo object + * + * @return const QContainer& + */ + static auto GetSupportedSubkeyAlgo() -> QContainer; + + /** + * @brief + * + * @param algo_id + * @return std::tuple + */ + static auto SearchPrimaryKeyAlgo(const QString &algo_id) + -> std::tuple; + + /** + * @brief + * + * @param algo_id + * @return std::tuple + */ + static auto SearchSubKeyAlgo(const QString &algo_id) + -> std::tuple; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsSubKey() const -> bool; + + /** + * @brief Set the Is Sub Key object + * + * @param m_sub_key + */ + void SetIsSubKey(bool); + + /** + * @brief Get the Userid object + * + * @return QString + */ + [[nodiscard]] auto GetUserid() const -> QString; + + /** + * @brief Set the Name object + * + * @param m_name + */ + void SetName(const QString &name); + + /** + * @brief Set the Email object + * + * @param m_email + */ + void SetEmail(const QString &email); + + /** + * @brief Set the Comment object + * + * @param m_comment + */ + void SetComment(const QString &comment); + + /** + * @brief Get the Name object + * + * @return QString + */ + [[nodiscard]] auto GetName() const -> QString; + + /** + * @brief Get the Email object + * + * @return QString + */ + [[nodiscard]] auto GetEmail() const -> QString; + + /** + * @brief Get the Comment object + * + * @return QString + */ + [[nodiscard]] auto GetComment() const -> QString; + + /** + * @brief Get the Algo object + * + * @return const QString& + */ + [[nodiscard]] auto GetAlgo() const -> const KeyAlgo &; + + /** + * @brief Set the Algo object + * + * @param m_algo + */ + void SetAlgo(const KeyAlgo &); + + /** + * @brief Get the Key Size object + * + * @return int + */ + [[nodiscard]] auto GetKeyLength() const -> int; + + /** + * @brief Get the Expired object + * + * @return const QDateTime& + */ + [[nodiscard]] auto GetExpireTime() const -> const QDateTime &; + + /** + * @brief Set the Expired object + * + * @param m_expired + */ + void SetExpireTime(const QDateTime &m_expired); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsNonExpired() const -> bool; + + /** + * @brief Set the Non Expired object + * + * @param m_non_expired + */ + void SetNonExpired(bool m_non_expired); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsNoPassPhrase() const -> bool; + + /** + * @brief Set the Non Pass Phrase object + * + * @param m_non_pass_phrase + */ + void SetNonPassPhrase(bool m_non_pass_phrase); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowSigning() const -> bool; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowNoPassPhrase() const -> bool; + + /** + * @brief Set the Allow Signing object + * + * @param m_allow_signing + */ + void SetAllowSigning(bool m_allow_signing); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowEncryption() const -> bool; + + /** + * @brief Set the Allow Encryption object + * + * @param m_allow_encryption + */ + void SetAllowEncryption(bool m_allow_encryption); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowCertification() const -> bool; + + /** + * @brief Set the Allow Certification object + * + * @param m_allow_certification + */ + void SetAllowCertification(bool m_allow_certification); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowAuthentication() const -> bool; + + /** + * @brief Set the Allow Authentication object + * + * @param m_allow_authentication + */ + void SetAllowAuthentication(bool m_allow_authentication); + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowChangeSigning() const -> bool; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowChangeEncryption() const -> bool; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowChangeCertification() const -> bool; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsAllowChangeAuthentication() const -> bool; + + private: + bool subkey_ = false; ///< + QString name_; ///< + QString email_; ///< + QString comment_; ///< + + KeyAlgo algo_; ///< + QDateTime expired_ = QDateTime::currentDateTime().addYears(2); + bool non_expired_ = false; ///< + + bool no_passphrase_ = false; ///< + bool allow_no_pass_phrase_ = true; ///< + + bool allow_encryption_ = true; ///< + bool allow_change_encryption_ = true; ///< + bool allow_certification_ = true; ///< + bool allow_change_certification_ = true; ///< + bool allow_authentication_ = true; ///< + bool allow_change_authentication_ = true; ///< + bool allow_signing_ = true; ///< + bool allow_change_signing_ = true; ///< + + /** + * @brief + * + */ + void reset_options(); +}; + +} // namespace GpgFrontend diff --git a/src/test/core/GpgCoreTestKeygen.cpp b/src/test/core/GpgCoreTestKeygen.cpp index aa4de244..63b6ad17 100644 --- a/src/test/core/GpgCoreTestKeygen.cpp +++ b/src/test/core/GpgCoreTestKeygen.cpp @@ -29,16 +29,16 @@ #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/model/GpgKeyGenerateInfo.h" #include "core/utils/GpgUtils.h" #include "core/utils/MemoryUtils.h" namespace GpgFrontend::Test { TEST_F(GpgCoreTest, SearchPrimaryKeyAlgoTest) { - auto [find, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + auto [find, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("rsa2048"); ASSERT_TRUE(find); ASSERT_EQ(algo.Id(), "rsa2048"); ASSERT_EQ(algo.Id(), "rsa2048"); @@ -48,7 +48,7 @@ TEST_F(GpgCoreTest, SearchPrimaryKeyAlgoTest) { } TEST_F(GpgCoreTest, SearchSubKeyAlgoTest) { - auto [find, algo] = GenKeyInfo::SearchSubKeyAlgo("rsa2048"); + auto [find, algo] = KeyGenerateInfo::SearchSubKeyAlgo("rsa2048"); ASSERT_TRUE(find); ASSERT_EQ(algo.Id(), "rsa2048"); ASSERT_EQ(algo.Name(), "RSA"); @@ -57,12 +57,12 @@ TEST_F(GpgCoreTest, SearchSubKeyAlgoTest) { } TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_0"); p_info->SetEmail("bar@gpgfrontend.bktus.com"); p_info->SetComment("foobar"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("rsa2048"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "rsa2048"); p_info->SetAlgo(algo); @@ -107,12 +107,12 @@ TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { } TEST_F(GpgCoreTest, GenerateKeyRSA4096Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_1"); p_info->SetEmail("bar@gpgfrontend.bktus.com"); p_info->SetComment("hello gpgfrontend"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa4096"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("rsa4096"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "rsa4096"); p_info->SetAlgo(algo); @@ -146,12 +146,12 @@ TEST_F(GpgCoreTest, GenerateKeyRSA4096Test) { } TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_1"); p_info->SetEmail("bar_1@gpgfrontend.bktus.com"); p_info->SetComment("hello gpgfrontend"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("dsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("dsa2048"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "dsa2048"); p_info->SetAlgo(algo); @@ -200,12 +200,12 @@ TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { } TEST_F(GpgCoreTest, GenerateKeyED25519Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_4"); p_info->SetEmail("bar_ed@gpgfrontend.bktus.com"); p_info->SetComment("hello gpgfrontend"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("ed25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "ed25519"); p_info->SetAlgo(algo); @@ -254,12 +254,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519Test) { } TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_ec"); p_info->SetEmail("ec_bar@gpgfrontend.bktus.com"); p_info->SetComment("ecccc"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("ed25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "ed25519"); p_info->SetAlgo(algo); @@ -267,9 +267,9 @@ TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { p_info->SetNonExpired(true); p_info->SetNonPassPhrase(true); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - std::tie(found, algo) = GenKeyInfo::SearchSubKeyAlgo("cv25519"); + std::tie(found, algo) = KeyGenerateInfo::SearchSubKeyAlgo("cv25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "cv25519"); s_info->SetAlgo(algo); @@ -329,12 +329,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { } TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_ec2"); p_info->SetEmail("ec2_bar@gpgfrontend.bktus.com"); p_info->SetComment("ecccc"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("ed25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "ed25519"); p_info->SetAlgo(algo); @@ -342,9 +342,9 @@ TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { p_info->SetNonExpired(true); p_info->SetNonPassPhrase(true); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - std::tie(found, algo) = GenKeyInfo::SearchSubKeyAlgo("nistp256"); + std::tie(found, algo) = KeyGenerateInfo::SearchSubKeyAlgo("nistp256"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "nistp256"); s_info->SetAlgo(algo); @@ -404,12 +404,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { } TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_ec3"); p_info->SetEmail("ec3_bar@gpgfrontend.bktus.com"); p_info->SetComment("ecccc3"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("ed25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "ed25519"); p_info->SetAlgo(algo); @@ -417,9 +417,9 @@ TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { p_info->SetNonExpired(true); p_info->SetNonPassPhrase(true); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - std::tie(found, algo) = GenKeyInfo::SearchSubKeyAlgo("brainpoolp256r1"); + std::tie(found, algo) = KeyGenerateInfo::SearchSubKeyAlgo("brainpoolp256r1"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "brainpoolp256r1"); s_info->SetAlgo(algo); @@ -479,12 +479,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { } TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_4"); p_info->SetEmail("bar_ed@gpgfrontend.bktus.com"); p_info->SetComment("hello gpgfrontend"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("nistp256"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("nistp256"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "nistp256"); p_info->SetAlgo(algo); @@ -534,12 +534,12 @@ TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { } TEST_F(GpgCoreTest, GenerateKeyED448Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_4"); p_info->SetEmail("bar_ed@gpgfrontend.bktus.com"); p_info->SetComment("hello gpgfrontend"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed448"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("ed448"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "ed448"); p_info->SetAlgo(algo); @@ -589,12 +589,12 @@ TEST_F(GpgCoreTest, GenerateKeyED448Test) { } TEST_F(GpgCoreTest, GenerateKeySECP256K1Test) { - auto p_info = QSharedPointer::create(); + auto p_info = QSharedPointer::create(); p_info->SetName("foo_4"); p_info->SetEmail("bar_ed@gpgfrontend.bktus.com"); p_info->SetComment("hello gpgfrontend"); - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("secp256k1"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("secp256k1"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "secp256k1"); p_info->SetAlgo(algo); diff --git a/src/test/core/GpgCoreTestSubkeygen.cpp b/src/test/core/GpgCoreTestSubkeygen.cpp index 886a6f04..af78a953 100644 --- a/src/test/core/GpgCoreTestSubkeygen.cpp +++ b/src/test/core/GpgCoreTestSubkeygen.cpp @@ -29,9 +29,9 @@ #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/model/GpgKeyGenerateInfo.h" #include "core/utils/GpgUtils.h" #include "core/utils/MemoryUtils.h" @@ -42,9 +42,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyRSA2048Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("rsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("rsa2048"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "rsa2048"); s_info->SetAlgo(algo); @@ -85,9 +85,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyDSA2048Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("dsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("dsa2048"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "dsa2048"); s_info->SetAlgo(algo); @@ -128,9 +128,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyELG2048Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("elg2048"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("elg2048"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "elg2048"); s_info->SetAlgo(algo); @@ -171,9 +171,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyED25519Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("ed25519"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("ed25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "ed25519"); s_info->SetAlgo(algo); @@ -214,9 +214,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyCV25519Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("cv25519"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("cv25519"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "cv25519"); s_info->SetAlgo(algo); @@ -257,9 +257,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyNISTP256Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("nistp256"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("nistp256"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "nistp256"); s_info->SetAlgo(algo); @@ -299,9 +299,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyBRAINPOOLP256R1Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("brainpoolp256r1"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("brainpoolp256r1"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "brainpoolp256r1"); s_info->SetAlgo(algo); @@ -341,9 +341,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyX448Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("x448"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("x448"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "x448"); s_info->SetAlgo(algo); @@ -383,9 +383,9 @@ TEST_F(GpgCoreTest, GenerateSubkeySECP256K1Test) { "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); ASSERT_TRUE(p_key.IsGood()); - auto s_info = QSharedPointer::create(true); + auto s_info = QSharedPointer::create(true); - auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("secp256k1"); + auto [found, algo] = KeyGenerateInfo::SearchSubKeyAlgo("secp256k1"); ASSERT_TRUE(found); ASSERT_EQ(algo.Id(), "secp256k1"); s_info->SetAlgo(algo); diff --git a/src/ui/dialog/Wizard.cpp b/src/ui/dialog/Wizard.cpp index 243fb846..8e77dada 100644 --- a/src/ui/dialog/Wizard.cpp +++ b/src/ui/dialog/Wizard.cpp @@ -195,7 +195,7 @@ KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) { int KeyGenPage::nextId() const { return Wizard::kPAGE_CONCLUSION; } void KeyGenPage::slot_generate_key_dialog() { - (new KeyGenDialog(kGpgFrontendDefaultChannel, this))->show(); + (new KeyGenerateDialog(kGpgFrontendDefaultChannel, this))->show(); wizard()->next(); } diff --git a/src/ui/dialog/key_generate/KeyGenerateDialog.cpp b/src/ui/dialog/key_generate/KeyGenerateDialog.cpp index 49425e5b..27c587a1 100644 --- a/src/ui/dialog/key_generate/KeyGenerateDialog.cpp +++ b/src/ui/dialog/key_generate/KeyGenerateDialog.cpp @@ -95,13 +95,13 @@ void SetKeyLengthComboxBoxByAlgo(QComboBox* combo, combo->addItems(key_lengths); } -KeyGenDialog::KeyGenDialog(int channel, QWidget* parent) - : GeneralDialog(typeid(KeyGenDialog).name(), parent), +KeyGenerateDialog::KeyGenerateDialog(int channel, QWidget* parent) + : GeneralDialog(typeid(KeyGenerateDialog).name(), parent), ui_(QSharedPointer::create()), - gen_key_info_(QSharedPointer::create()), + gen_key_info_(QSharedPointer::create()), gen_subkey_info_(nullptr), - supported_primary_key_algos_(GenKeyInfo::GetSupportedKeyAlgo()), - supported_subkey_algos_(GenKeyInfo::GetSupportedSubkeyAlgo()), + supported_primary_key_algos_(KeyGenerateInfo::GetSupportedKeyAlgo()), + supported_subkey_algos_(KeyGenerateInfo::GetSupportedSubkeyAlgo()), channel_(channel) { ui_->setupUi(this); @@ -128,6 +128,42 @@ KeyGenDialog::KeyGenDialog(int channel, QWidget* parent) tr("Non Expired"), }); + ui_->easyCombinationComboBox->addItems({ + tr("Primary Key Only"), + tr("Primary Key With Subkey"), + }); + + ui_->nameLabel->setText(tr("Name")); + ui_->emailLabel->setText(tr("Email")); + ui_->commentLabel->setText(tr("Comment")); + ui_->keyDBLabel->setText(tr("Key Database")); + ui_->easyAlgoLabel->setText(tr("Algorithm")); + ui_->easyValidPeriodLabel->setText(tr("Validity Period")); + + ui_->pAlgoLabel->setText(tr("Algorithm")); + ui_->pValidPeriodLabel->setText(tr("Validity Period")); + ui_->pKeyLengthLabel->setText(tr("Key Length")); + ui_->pUsageLabel->setText(tr("Usage")); + ui_->pEncrCheckBox->setText(tr("Encrypt")); + ui_->pSignCheckBox->setText(tr("Sign")); + ui_->pAuthCheckBox->setText(tr("Authentication")); + ui_->noPassphraseCheckBox->setText(tr("No Passphrase")); + ui_->pExpireCheckBox->setText(tr("Non Expired")); + + ui_->sAlgoLabel->setText(tr("Algorithm")); + ui_->sValidPeriodLabel->setText(tr("Validity Period")); + ui_->sKeyLengthLabel->setText(tr("Key Length")); + ui_->sUsageLabel->setText(tr("Usage")); + ui_->sEncrCheckBox->setText(tr("Encrypt")); + ui_->sSignCheckBox->setText(tr("Sign")); + ui_->sAuthCheckBox->setText(tr("Authentication")); + ui_->sExpireCheckBox->setText(tr("Non Expired")); + + ui_->tabWidget->setTabText(0, tr("Easy Mode")); + ui_->tabWidget->setTabText(0, tr("Primary Key")); + ui_->tabWidget->setTabText(0, tr("Subkey")); + ui_->generateButton->setText(tr("Generate")); + QSet p_algo_set; for (const auto& algo : supported_primary_key_algos_) { p_algo_set.insert(algo.Name()); @@ -156,21 +192,32 @@ KeyGenDialog::KeyGenDialog(int channel, QWidget* parent) this->setModal(true); } -void KeyGenDialog::slot_key_gen_accept() { +void KeyGenerateDialog::slot_key_gen_accept() { QString buffer; - QTextStream error_stream(&buffer); + QTextStream err_stream(&buffer); if (ui_->nameEdit->text().size() < 5) { - error_stream << " -> " << tr("Name must contain at least five characters.") - << Qt::endl; + err_stream << " -> " << tr("Name must contain at least five characters.") + << Qt::endl; } if (ui_->emailEdit->text().isEmpty() || !check_email_address(ui_->emailEdit->text())) { - error_stream << " -> " << tr("Please give a valid email address.") - << Qt::endl; + err_stream << " -> " << tr("Please give a valid email address.") + << Qt::endl; + } + + if (gen_key_info_->GetAlgo() == KeyGenerateInfo::kNoneAlgo) { + err_stream << " -> " << tr("Please give a valid primary key algorithm.") + << Qt::endl; } - const auto err_string = error_stream.readAll(); + if (gen_subkey_info_ != nullptr && + gen_subkey_info_->GetAlgo() == KeyGenerateInfo::kNoneAlgo) { + err_stream << " -> " << tr("Please give a valid subkey algorithm.") + << Qt::endl; + } + + const auto err_string = err_stream.readAll(); if (!err_string.isEmpty()) { ui_->statusPlainTextEdit->clear(); ui_->statusPlainTextEdit->appendPlainText(err_string); @@ -199,44 +246,13 @@ void KeyGenDialog::slot_key_gen_accept() { } } - if (!GetSettings() - .value("gnupg/use_pinentry_as_password_input_dialog", - QString::fromLocal8Bit(qgetenv("container")) != "flatpak") - .toBool() && - !ui_->noPassphraseCheckBox->isChecked()) { - SetCacheValue("PinentryContext", "NEW_PASSPHRASE"); - } - LOG_D() << "try to generate key at gpg context channel: " << channel_; - GpgOperaHelper::WaitForOpera( - this, tr("Generating"), - [this, gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) { - GpgKeyOpera::GetInstance(channel_).GenerateKeyWithSubkey( - gen_key_info, gen_subkey_info_, - [this, hd](GpgError err, const DataObjectPtr&) { - // stop showing waiting dialog - hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - CommonUtils::RaiseMessageBox( - this->parentWidget() != nullptr ? this->parentWidget() : this, - err); - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { - emit SignalKeyGenerated(); - } - }); - }); - + do_generate(); this->done(0); } -void KeyGenDialog::refresh_widgets_state() { +void KeyGenerateDialog::refresh_widgets_state() { ui_->pAlgoComboBox->blockSignals(true); ui_->pAlgoComboBox->setCurrentText(gen_key_info_->GetAlgo().Name()); ui_->pAlgoComboBox->blockSignals(false); @@ -280,7 +296,7 @@ void KeyGenDialog::refresh_widgets_state() { ui_->pExpireCheckBox->blockSignals(false); if (gen_subkey_info_ == nullptr) { - ui_->tab_3->setDisabled(true); + ui_->sTab->setDisabled(true); ui_->sAlgoComboBox->blockSignals(true); ui_->sAlgoComboBox->setCurrentText(tr("None")); @@ -310,10 +326,14 @@ void KeyGenDialog::refresh_widgets_state() { ui_->sExpireCheckBox->blockSignals(true); ui_->sExpireCheckBox->setCheckState(Qt::Unchecked); ui_->sExpireCheckBox->blockSignals(false); + + ui_->easyCombinationComboBox->blockSignals(true); + ui_->easyCombinationComboBox->setCurrentText(tr("Primary Key Only")); + ui_->easyCombinationComboBox->blockSignals(false); return; } - ui_->tab_3->setDisabled(false); + ui_->sTab->setDisabled(false); ui_->sAlgoComboBox->blockSignals(true); ui_->sAlgoComboBox->setCurrentText(gen_subkey_info_->GetAlgo().Name()); @@ -357,11 +377,15 @@ void KeyGenDialog::refresh_widgets_state() { ui_->sExpireCheckBox->blockSignals(true); ui_->sExpireCheckBox->setChecked(gen_subkey_info_->IsNonExpired()); ui_->sExpireCheckBox->blockSignals(false); + + ui_->easyCombinationComboBox->blockSignals(true); + ui_->easyCombinationComboBox->setCurrentText(tr("Primary Key With Subkey")); + ui_->easyCombinationComboBox->blockSignals(false); } -void KeyGenDialog::set_signal_slot_config() { +void KeyGenerateDialog::set_signal_slot_config() { connect(ui_->generateButton, &QPushButton::clicked, this, - &KeyGenDialog::slot_key_gen_accept); + &KeyGenerateDialog::slot_key_gen_accept); connect(ui_->pExpireCheckBox, &QCheckBox::stateChanged, this, [this](int state) { @@ -425,10 +449,10 @@ void KeyGenDialog::set_signal_slot_config() { }); connect(ui_->easyAlgoComboBox, &QComboBox::currentTextChanged, this, - &KeyGenDialog::slot_easy_mode_changed); + &KeyGenerateDialog::slot_easy_mode_changed); connect(ui_->easyValidityPeriodComboBox, &QComboBox::currentTextChanged, this, - &KeyGenDialog::slot_easy_valid_date_changed); + &KeyGenerateDialog::slot_easy_valid_date_changed); connect(ui_->pValidityPeriodDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this, [=](const QDateTime& dt) { @@ -447,16 +471,19 @@ void KeyGenDialog::set_signal_slot_config() { connect(ui_->keyDBIndexComboBox, &QComboBox::currentIndexChanged, this, [=](int index) { channel_ = index; }); - connect(this, &KeyGenDialog::SignalKeyGenerated, + connect(ui_->easyCombinationComboBox, &QComboBox::currentTextChanged, this, + &KeyGenerateDialog::slot_easy_combination_changed); + + connect(this, &KeyGenerateDialog::SignalKeyGenerated, UISignalStation::GetInstance(), &UISignalStation::SignalKeyDatabaseRefresh); } -auto KeyGenDialog::check_email_address(const QString& str) -> bool { +auto KeyGenerateDialog::check_email_address(const QString& str) -> bool { return re_email_.match(str).hasMatch(); } -void KeyGenDialog::sync_gen_key_info() { +void KeyGenerateDialog::sync_gen_key_info() { auto [found, algo] = GetAlgoByName(ui_->pAlgoComboBox->currentText(), supported_primary_key_algos_); @@ -468,7 +495,7 @@ void KeyGenDialog::sync_gen_key_info() { } } -void KeyGenDialog::sync_gen_subkey_info() { +void KeyGenerateDialog::sync_gen_subkey_info() { if (gen_subkey_info_ != nullptr) { auto [s_found, algo] = GetAlgoByName(ui_->sAlgoComboBox->currentText(), supported_subkey_algos_); @@ -478,54 +505,54 @@ void KeyGenDialog::sync_gen_subkey_info() { } } -void KeyGenDialog::slot_easy_mode_changed(const QString& mode) { +void KeyGenerateDialog::slot_easy_mode_changed(const QString& mode) { if (mode == "RSA") { - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("rsa2048"); if (found) gen_key_info_->SetAlgo(algo); gen_subkey_info_ = nullptr; } else if (mode == "DSA") { - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("dsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("dsa2048"); if (found) gen_key_info_->SetAlgo(algo); if (gen_subkey_info_ == nullptr) { - gen_subkey_info_ = QSharedPointer::create(true); + gen_subkey_info_ = QSharedPointer::create(true); } - auto [s_found, s_algo] = GenKeyInfo::SearchSubKeyAlgo("elg2048"); + auto [s_found, s_algo] = KeyGenerateInfo::SearchSubKeyAlgo("elg2048"); if (s_found) gen_subkey_info_->SetAlgo(s_algo); } else if (mode == "ECC (25519)") { - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("ed25519"); if (found) gen_key_info_->SetAlgo(algo); if (gen_subkey_info_ == nullptr) { - gen_subkey_info_ = QSharedPointer::create(true); + gen_subkey_info_ = QSharedPointer::create(true); } - auto [s_found, s_algo] = GenKeyInfo::SearchSubKeyAlgo("cv25519"); + auto [s_found, s_algo] = KeyGenerateInfo::SearchSubKeyAlgo("cv25519"); if (s_found) gen_subkey_info_->SetAlgo(s_algo); } else { - auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + auto [found, algo] = KeyGenerateInfo::SearchPrimaryKeyAlgo("rsa2048"); if (found) gen_key_info_->SetAlgo(algo); if (gen_subkey_info_ == nullptr) { - gen_subkey_info_ = QSharedPointer::create(true); + gen_subkey_info_ = QSharedPointer::create(true); } - auto [s_found, s_algo] = GenKeyInfo::SearchSubKeyAlgo("rsa2048"); + auto [s_found, s_algo] = KeyGenerateInfo::SearchSubKeyAlgo("rsa2048"); if (s_found) gen_subkey_info_->SetAlgo(s_algo); } refresh_widgets_state(); } -void KeyGenDialog::slot_easy_valid_date_changed(const QString& mode) { +void KeyGenerateDialog::slot_easy_valid_date_changed(const QString& mode) { if (mode == tr("3 Months")) { gen_key_info_->SetNonExpired(false); gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addMonths(3)); @@ -575,15 +602,60 @@ void KeyGenDialog::slot_easy_valid_date_changed(const QString& mode) { refresh_widgets_state(); } -void KeyGenDialog::slot_set_easy_valid_date_2_custom() { +void KeyGenerateDialog::slot_set_easy_valid_date_2_custom() { ui_->easyValidityPeriodComboBox->blockSignals(true); ui_->easyValidityPeriodComboBox->setCurrentText(tr("Custom")); ui_->easyValidityPeriodComboBox->blockSignals(false); } -void KeyGenDialog::slot_set_easy_key_algo_2_custom() { +void KeyGenerateDialog::slot_set_easy_key_algo_2_custom() { ui_->easyAlgoComboBox->blockSignals(true); ui_->easyAlgoComboBox->setCurrentText(tr("Custom")); ui_->easyAlgoComboBox->blockSignals(false); } + +void KeyGenerateDialog::slot_easy_combination_changed(const QString& mode) { + if (mode == tr("Primary Key Only")) { + gen_subkey_info_ = nullptr; + } else { + gen_subkey_info_ = QSharedPointer::create(true); + } + + slot_set_easy_key_algo_2_custom(); + refresh_widgets_state(); +} + +void KeyGenerateDialog::do_generate() { + if (!GetSettings() + .value("gnupg/use_pinentry_as_password_input_dialog", + QString::fromLocal8Bit(qgetenv("container")) != "flatpak") + .toBool() && + !ui_->noPassphraseCheckBox->isChecked()) { + SetCacheValue("PinentryContext", "NEW_PASSPHRASE"); + } + + auto f = [this, + gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) { + GpgKeyOpera::GetInstance(channel_).GenerateKeyWithSubkey( + gen_key_info, gen_subkey_info_, + [this, hd](GpgError err, const DataObjectPtr&) { + // stop showing waiting dialog + hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + CommonUtils::RaiseMessageBox( + this->parentWidget() != nullptr ? this->parentWidget() : this, + err); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + emit SignalKeyGenerated(); + } + }); + }; + GpgOperaHelper::WaitForOpera(this, tr("Generating"), f); +} } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/key_generate/KeyGenerateDialog.h b/src/ui/dialog/key_generate/KeyGenerateDialog.h index 63690831..a4d27900 100644 --- a/src/ui/dialog/key_generate/KeyGenerateDialog.h +++ b/src/ui/dialog/key_generate/KeyGenerateDialog.h @@ -28,7 +28,7 @@ #pragma once -#include "core/model/GpgGenKeyInfo.h" +#include "core/model/GpgKeyGenerateInfo.h" #include "ui/dialog/GeneralDialog.h" class Ui_KeyGenDialog; @@ -39,7 +39,7 @@ namespace GpgFrontend::UI { * @brief * */ -class KeyGenDialog : public GeneralDialog { +class KeyGenerateDialog : public GeneralDialog { Q_OBJECT public: @@ -50,7 +50,7 @@ class KeyGenDialog : public GeneralDialog { * @param key The key to show details of * @param parent The parent of this widget */ - explicit KeyGenDialog(int channel, QWidget* parent = nullptr); + explicit KeyGenerateDialog(int channel, QWidget* parent = nullptr); signals: /** @@ -93,6 +93,13 @@ class KeyGenDialog : public GeneralDialog { */ void slot_set_easy_key_algo_2_custom(); + /** + * @brief + * + * @param mode + */ + void slot_easy_combination_changed(const QString& mode); + private: /** * @brief @@ -109,8 +116,8 @@ class KeyGenDialog : public GeneralDialog { ///< entries of line edits QSharedPointer ui_; - QSharedPointer gen_key_info_; ///< - QSharedPointer gen_subkey_info_; ///< + QSharedPointer gen_key_info_; ///< + QSharedPointer gen_subkey_info_; ///< QContainer supported_primary_key_algos_; QContainer supported_subkey_algos_; @@ -148,6 +155,12 @@ class KeyGenDialog : public GeneralDialog { * */ void sync_gen_subkey_info(); + + /** + * @brief + * + */ + void do_generate(); }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp index b55e4b28..a2f7a4ae 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp @@ -127,10 +127,10 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { key_type_combo_box_ = new QComboBox(this); no_pass_phrase_check_box_ = new QCheckBox(this); - for (const auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) { + for (const auto& algo : KeyGenerateInfo::GetSupportedSubkeyAlgo()) { key_type_combo_box_->addItem(algo.Name()); } - if (!GenKeyInfo::GetSupportedSubkeyAlgo().empty()) { + if (!KeyGenerateInfo::GetSupportedSubkeyAlgo().empty()) { key_type_combo_box_->setCurrentIndex(0); } @@ -189,7 +189,7 @@ void SubkeyGenerateDialog::set_signal_slot() { connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this, [this](int state) -> void { - gen_key_info_->SetNonPassPhrase(state != 0); + gen_subkey_info_->SetNonPassPhrase(state != 0); }); } @@ -202,49 +202,49 @@ void SubkeyGenerateDialog::slot_expire_box_changed() { } void SubkeyGenerateDialog::refresh_widgets_state() { - if (gen_key_info_->IsAllowEncryption()) { + if (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_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_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_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_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_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_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_subkey_info_->IsAllowChangeAuthentication()) { key_usage_check_boxes_[3]->setDisabled(false); } else { key_usage_check_boxes_[3]->setDisabled(true); @@ -252,103 +252,76 @@ void SubkeyGenerateDialog::refresh_widgets_state() { } void SubkeyGenerateDialog::slot_key_gen_accept() { - QString buffer; - QTextStream err_stream(&buffer); - - /** - * primary keys should have a reasonable expiration date (no more than 2 years - * in the future) - */ - if (date_edit_->dateTime() > QDateTime::currentDateTime().addYears(2)) { - err_stream << " " << tr("Expiration time no more than 2 years.") << " "; - } - - auto err_string = err_stream.readAll(); - - if (err_string.isEmpty()) { - if (expire_check_box_->checkState() != 0U) { - gen_key_info_->SetNonExpired(true); - } else { - gen_key_info_->SetExpireTime(date_edit_->dateTime()); - } - - GpgOperaHelper::WaitForOpera( - this, tr("Generating"), - [this, key = this->key_, - gen_key_info = this->gen_key_info_](const OperaWaitingHd& hd) { - GpgKeyOpera::GetInstance(current_gpg_context_channel_) - .GenerateSubkey(key, gen_key_info, - [this, hd](GpgError err, const DataObjectPtr&) { - // stop showing waiting dialog - hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1) { - QMessageBox::critical( - this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - CommonUtils::RaiseMessageBox(this, err); - if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { - emit UISignalStation::GetInstance() - -> SignalKeyDatabaseRefresh(); - } - }); - }); - this->done(0); - + if (expire_check_box_->checkState() != 0U) { + gen_subkey_info_->SetNonExpired(true); } else { - /** - * create error message - */ - error_label_->setAutoFillBackground(true); - QPalette error = error_label_->palette(); - error.setColor(QPalette::Window, "#ff8080"); - error_label_->setPalette(error); - error_label_->setText(err_string); - - this->show(); + gen_subkey_info_->SetExpireTime(date_edit_->dateTime()); } + + GpgOperaHelper::WaitForOpera( + this, tr("Generating"), + [this, key = this->key_, + gen_key_info = this->gen_subkey_info_](const OperaWaitingHd& hd) { + GpgKeyOpera::GetInstance(current_gpg_context_channel_) + .GenerateSubkey(key, gen_key_info, + [this, hd](GpgError err, const DataObjectPtr&) { + // stop showing waiting dialog + hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1) { + QMessageBox::critical( + this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + CommonUtils::RaiseMessageBox(this, err); + if (CheckGpgError(err) == GPG_ERR_NO_ERROR) { + emit UISignalStation::GetInstance() + -> SignalKeyDatabaseRefresh(); + } + }); + }); + this->done(0); } void SubkeyGenerateDialog::slot_encryption_box_changed(int state) { if (state == 0) { - gen_key_info_->SetAllowEncryption(false); + gen_subkey_info_->SetAllowEncryption(false); } else { - gen_key_info_->SetAllowEncryption(true); + gen_subkey_info_->SetAllowEncryption(true); } } void SubkeyGenerateDialog::slot_signing_box_changed(int state) { if (state == 0) { - gen_key_info_->SetAllowSigning(false); + gen_subkey_info_->SetAllowSigning(false); } else { - gen_key_info_->SetAllowSigning(true); + gen_subkey_info_->SetAllowSigning(true); } } void SubkeyGenerateDialog::slot_certification_box_changed(int state) { if (state == 0) { - gen_key_info_->SetAllowCertification(false); + gen_subkey_info_->SetAllowCertification(false); } else { - gen_key_info_->SetAllowCertification(true); + gen_subkey_info_->SetAllowCertification(true); } } void SubkeyGenerateDialog::slot_authentication_box_changed(int state) { if (state == 0) { - gen_key_info_->SetAllowAuthentication(false); + gen_subkey_info_->SetAllowAuthentication(false); } else { - gen_key_info_->SetAllowAuthentication(true); + gen_subkey_info_->SetAllowAuthentication(true); } } void SubkeyGenerateDialog::slot_activated_key_type(int index) { // check - assert(gen_key_info_->GetSupportedSubkeyAlgo().size() > + assert(gen_subkey_info_->GetSupportedSubkeyAlgo().size() > static_cast(index)); - gen_key_info_->SetAlgo(gen_key_info_->GetSupportedSubkeyAlgo()[index]); + gen_subkey_info_->SetAlgo(gen_subkey_info_->GetSupportedSubkeyAlgo()[index]); refresh_widgets_state(); } diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h index b8c525bd..ad47bbf2 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h @@ -31,8 +31,8 @@ #include #include "core/function/gpg/GpgContext.h" -#include "core/model/GpgGenKeyInfo.h" #include "core/model/GpgKey.h" +#include "core/model/GpgKeyGenerateInfo.h" #include "core/typedef/GpgTypedef.h" #include "core/utils/MemoryUtils.h" #include "ui/GpgFrontendUI.h" @@ -60,8 +60,8 @@ class SubkeyGenerateDialog : public GeneralDialog { int current_gpg_context_channel_; ///< GpgKey key_; ///< - QSharedPointer gen_key_info_ = - QSharedPointer::create(true); ///< + QSharedPointer gen_subkey_info_ = + QSharedPointer::create(true); ///< QGroupBox* key_usage_group_box_{}; QDialogButtonBox* button_box_; ///< Box for standard buttons diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp index f83226ed..38a5399c 100644 --- a/src/ui/main_window/KeyMgmt.cpp +++ b/src/ui/main_window/KeyMgmt.cpp @@ -441,7 +441,7 @@ void KeyMgmt::SlotExportKeyToClipboard() { } void KeyMgmt::SlotGenerateKeyDialog() { - (new KeyGenDialog(key_list_->GetCurrentGpgContextChannel(), this))->exec(); + (new KeyGenerateDialog(key_list_->GetCurrentGpgContextChannel(), this))->exec(); this->raise(); } diff --git a/ui/KeyGenDialog.ui b/ui/KeyGenDialog.ui index 254cdb92..8e850f1b 100644 --- a/ui/KeyGenDialog.ui +++ b/ui/KeyGenDialog.ui @@ -32,21 +32,21 @@ 5 - + Comment - + Email - + Name @@ -62,7 +62,7 @@ - + Key Database @@ -86,7 +86,7 @@ true - + Easy Mode @@ -94,7 +94,7 @@ - + Validity Period @@ -107,12 +107,22 @@ - + Algorithm + + + + Combination + + + + + + @@ -130,7 +140,7 @@ - + Primary Key @@ -138,28 +148,28 @@ - + Key Length - + Validity Period - + Algorithm - + Usage @@ -230,7 +240,7 @@ - + Subkey @@ -238,14 +248,14 @@ - + Validity Period - + Usage @@ -255,7 +265,7 @@ - + Key Length @@ -293,7 +303,7 @@ - + Algorithm -- cgit v1.2.3