diff options
author | saturneric <[email protected]> | 2025-02-01 23:21:59 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2025-02-01 23:21:59 +0000 |
commit | d06c31abe7e2540518c4d3471acd381edfababa3 (patch) | |
tree | 7efec63216119a6a3b77208328ba59419acd905f | |
parent | fix: issues found on unit test mode (diff) | |
download | GpgFrontend-d06c31abe7e2540518c4d3471acd381edfababa3.tar.gz GpgFrontend-d06c31abe7e2540518c4d3471acd381edfababa3.zip |
feat: upgrade KeyGenDialog to meet easy and advanced requirements
-rw-r--r-- | src/core/GpgCoreInit.cpp | 2 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyOpera.cpp | 411 | ||||
-rw-r--r-- | src/core/function/gpg/GpgKeyOpera.h | 21 | ||||
-rw-r--r-- | src/core/model/GpgGenKeyInfo.cpp | 423 | ||||
-rw-r--r-- | src/core/model/GpgGenKeyInfo.h | 142 | ||||
-rw-r--r-- | src/core/typedef/GpgTypedef.h | 2 | ||||
-rw-r--r-- | src/test/core/GpgCoreTestBasicOpera.cpp | 4 | ||||
-rw-r--r-- | src/test/core/GpgCoreTestKeygen.cpp | 316 | ||||
-rw-r--r-- | src/test/core/GpgCoreTestSubkeygen.cpp | 166 | ||||
-rw-r--r-- | src/ui/dialog/Wizard.cpp | 16 | ||||
-rw-r--r-- | src/ui/dialog/Wizard.h | 13 | ||||
-rw-r--r-- | src/ui/dialog/key_generate/KeygenDialog.cpp | 807 | ||||
-rw-r--r-- | src/ui/dialog/key_generate/KeygenDialog.h | 106 | ||||
-rw-r--r-- | src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp | 21 | ||||
-rw-r--r-- | src/ui/dialog/key_generate/SubkeyGenerateDialog.h | 8 | ||||
-rw-r--r-- | src/ui/main_window/KeyMgmt.cpp | 2 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotUI.cpp | 2 | ||||
-rw-r--r-- | ui/KeyGenDialog.ui | 355 |
18 files changed, 1547 insertions, 1270 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index b564307a..5018b8e4 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -637,7 +637,7 @@ void StartMonitorCoreInitializationStatus() { "core", "env.state.basic", 0); LOG_D() << "monitor: core env is still initializing, waiting..."; - QThread::msleep(15); + QThread::msleep(100); } if (core_init_state < 0) return -1; diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 800a6708..cf4d1e3b 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -163,337 +163,168 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key, }}); } +auto GenerateKeyImpl(GpgContext& ctx, const QSharedPointer<GenKeyInfo>& params, + const DataObjectPtr& data_object) -> GpgError { + const auto userid = params->GetUserid(); + const auto algo = params->GetAlgo().Id(); + + 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; + + LOG_D() << "key generation args: " << userid << algo << expires << flags; + LOG_D() << "key generation flags" << params->IsAllowEncryption() + << params->IsAllowSigning() << params->IsAllowAuthentication() + << !params->IsSubKey(); + + 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); +} + /** * Generate a new key pair * @param params key generation args * @return error information */ -void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params, +void GpgKeyOpera::GenerateKey(const QSharedPointer<GenKeyInfo>& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( - [&ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { - auto userid = params->GetUserid(); - auto algo = params->GetAlgo() + params->GetKeySizeStr(); - - LOG_D() << "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; - - LOG_D() << "key generation args: " << userid << algo << expires - << flags; - - err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(), - algo.toUtf8(), 0, expires, nullptr, flags); - assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); - - 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); + [=](const DataObjectPtr& data_object) -> GpgError { + return GenerateKeyImpl(ctx_, params, data_object); }, callback, "gpgme_op_createkey", "2.1.0"); } -auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params) +auto GpgKeyOpera::GenerateKeySync(const QSharedPointer<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(); - - LOG_D() << "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; - - LOG_D() << "key generation args: " << userid << algo << expires - << flags; - - err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(), - algo.toUtf8(), 0, expires, nullptr, flags); - assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); - - 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); + [=](const DataObjectPtr& data_object) -> GpgError { + return GenerateKeyImpl(ctx_, params, data_object); }, "gpgme_op_createkey", "2.1.0"); } +auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKey& key, + const QSharedPointer<GenKeyInfo>& 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(); + + auto algo = params->GetAlgo().Id(); + 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; + + LOG_D() << "subkey generation args: " << key.GetId() << algo << expires + << flags; + + auto err = + gpgme_op_createsubkey(ctx.DefaultContext(), static_cast<gpgme_key_t>(key), + algo.toLatin1(), 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); +} + void GpgKeyOpera::GenerateSubkey(const GpgKey& key, - const std::shared_ptr<GenKeyInfo>& params, + const QSharedPointer<GenKeyInfo>& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( - [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { - if (!params->IsSubKey()) return GPG_ERR_CANCELED; - - LOG_D() << "generate subkey algo: " << params->GetAlgo() - << "key size: " << 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; - - LOG_D() << "subkey generation args: " << key.GetId() << algo << expires - << flags; - - auto err = gpgme_op_createsubkey(ctx.DefaultContext(), - static_cast<gpgme_key_t>(key), - algo.toLatin1(), 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); + [=](const DataObjectPtr& data_object) -> GpgError { + return GenerateSubKeyImpl(ctx_, key, params, data_object); }, callback, "gpgme_op_createsubkey", "2.1.13"); } auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key, - const std::shared_ptr<GenKeyInfo>& params) + const QSharedPointer<GenKeyInfo>& params) -> std::tuple<GpgError, DataObjectPtr> { return RunGpgOperaSync( - [key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError { - if (!params->IsSubKey()) return GPG_ERR_CANCELED; - - LOG_D() << "generate subkey algo: " << params->GetAlgo() - << " key size: " << 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; - - LOG_D() << " args: " << key.GetId() << algo << expires << flags; - - auto err = gpgme_op_createsubkey(ctx.DefaultContext(), - static_cast<gpgme_key_t>(key), - algo.toLatin1(), 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); + [=](const DataObjectPtr& data_object) -> GpgError { + return GenerateSubKeyImpl(ctx_, key, params, data_object); }, "gpgme_op_createsubkey", "2.1.13"); } +auto GenerateKeyWithSubkeyImpl(GpgContext& ctx, GpgKeyGetter& key_getter, + const QSharedPointer<GenKeyInfo>& p_params, + const QSharedPointer<GenKeyInfo>& s_params, + const DataObjectPtr& data_object) -> GpgError { + auto err = GenerateKeyImpl(ctx, p_params, data_object); + + if (err != GPG_ERR_NO_ERROR) return err; + if (!data_object->Check<GpgGenerateKeyResult>()) return GPG_ERR_CANCELED; + + auto result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + auto key = key_getter.GetKey(result.GetFingerprint()); + if (!key.IsGood()) { + LOG_W() << "cannot get key which has been generated, fpr: " + << result.GetFingerprint(); + return GPG_ERR_CANCELED; + } + + if (s_params == nullptr) return err; + + data_object->Swap({}); + err = GenerateSubKeyImpl(ctx, key, s_params, data_object); + auto s_result = ExtractParams<GpgGenerateKeyResult>(data_object, 0); + + data_object->Swap({result, s_result}); + return err; +} + void GpgKeyOpera::GenerateKeyWithSubkey( - const std::shared_ptr<GenKeyInfo>& params, - const std::shared_ptr<GenKeyInfo>& subkey_params, + const QSharedPointer<GenKeyInfo>& p_params, + const QSharedPointer<GenKeyInfo>& s_params, const GpgOperationCallback& callback) { RunGpgOperaAsync( - [&ctx = ctx_, params, subkey_params, - channel = GetChannel()](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; - - LOG_D() << "key generation args: " << userid << algo << expires - << flags; - - err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires, - nullptr, flags); - assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); - - 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(channel).GetKey( - genkey_result.GetFingerprint()); - if (!key.IsGood()) { - LOG_W() << "cannot get key which has been generate, fpr: " - << genkey_result.GetFingerprint(); - return err; - } - - 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; - - LOG_D() << "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); + [=](const DataObjectPtr& data_object) -> GpgError { + return GenerateKeyWithSubkeyImpl(ctx_, key_getter_, p_params, s_params, + data_object); }, 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) + const QSharedPointer<GenKeyInfo>& p_params, + const QSharedPointer<GenKeyInfo>& s_params) -> std::tuple<GpgError, DataObjectPtr> { return RunGpgOperaSync( - [&ctx = ctx_, params, subkey_params, - channel = GetChannel()](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; - - LOG_D() << "key generation args: " << userid << algo << expires - << flags; - - err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires, - nullptr, flags); - assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); - - 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(channel).GetKey( - genkey_result.GetFingerprint()); - if (!key.IsGood()) { - LOG_W() << "cannot get key which has been generate, fpr: " - << genkey_result.GetFingerprint(); - return err; - } - - LOG_D() << "try to generate subkey of key: " << key.GetId() - << ", algo :" << subkey_params->GetAlgo() - << ", key size: " << 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; - - LOG_D() << "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); + [=](const DataObjectPtr& data_object) -> GpgError { + return GenerateKeyWithSubkeyImpl(ctx_, key_getter_, p_params, s_params, + data_object); }, "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0"); } diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h index 0084d473..d724f5f8 100644 --- a/src/core/function/gpg/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -31,6 +31,7 @@ #include <functional> #include "core/function/gpg/GpgContext.h" +#include "core/function/gpg/GpgKeyGetter.h" #include "core/typedef/GpgTypedef.h" namespace GpgFrontend { @@ -114,7 +115,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param result * @return GpgFrontend::GpgError */ - void GenerateKey(const std::shared_ptr<GenKeyInfo>&, + void GenerateKey(const QSharedPointer<GenKeyInfo>&, const GpgOperationCallback&); /** @@ -122,7 +123,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * * @param params */ - auto GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params) + auto GenerateKeySync(const QSharedPointer<GenKeyInfo>& params) -> std::tuple<GpgError, DataObjectPtr>; /** @@ -133,7 +134,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @return GpgFrontend::GpgError */ void GenerateSubkey(const GpgKey& key, - const std::shared_ptr<GenKeyInfo>& params, + const QSharedPointer<GenKeyInfo>& params, const GpgOperationCallback&); /** @@ -143,7 +144,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param params */ auto GenerateSubkeySync(const GpgKey& key, - const std::shared_ptr<GenKeyInfo>& params) + const QSharedPointer<GenKeyInfo>& params) -> std::tuple<GpgError, DataObjectPtr>; /** @@ -153,8 +154,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param subkey_params * @param callback */ - void GenerateKeyWithSubkey(const std::shared_ptr<GenKeyInfo>& params, - const std::shared_ptr<GenKeyInfo>& subkey_params, + void GenerateKeyWithSubkey(const QSharedPointer<GenKeyInfo>& p_params, + const QSharedPointer<GenKeyInfo>& s_params, const GpgOperationCallback& callback); /** @@ -164,13 +165,15 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param subkey_params * @param callback */ - auto GenerateKeyWithSubkeySync( - const std::shared_ptr<GenKeyInfo>& params, - const std::shared_ptr<GenKeyInfo>& subkey_params) + auto GenerateKeyWithSubkeySync(const QSharedPointer<GenKeyInfo>& p_params, + const QSharedPointer<GenKeyInfo>& s_params) -> std::tuple<GpgError, DataObjectPtr>; private: GpgContext& ctx_ = GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); ///< + + GpgKeyGetter& key_getter_ = + GpgKeyGetter::GetInstance(SingletonFunctionObject::GetChannel()); ///< }; } // namespace GpgFrontend diff --git a/src/core/model/GpgGenKeyInfo.cpp b/src/core/model/GpgGenKeyInfo.cpp index 180a7fab..2b8a3dbc 100644 --- a/src/core/model/GpgGenKeyInfo.cpp +++ b/src/core/model/GpgGenKeyInfo.cpp @@ -35,125 +35,141 @@ namespace GpgFrontend { -void GenKeyInfo::SetAlgo(const QString &t_algo_args) { - auto algo_args = t_algo_args.toLower(); - - // reset all options - reset_options(); - - if (!this->subkey_) { - this->SetAllowCertification(true); - - } else { - this->SetAllowCertification(false); - } - - this->allow_change_certification_ = false; - - if (algo_args == "rsa") { - /** - * RSA is the world’s premier asymmetric cryptographic algorithm, - * and is built on the difficulty of factoring extremely large composites. - * GnuPG supports RSA with key sizes of between 1024 and 4096 bits. - */ - suggest_min_key_size_ = 1024; - suggest_max_key_size_ = 4096; - suggest_size_addition_step_ = 1024; - SetKeyLength(2048); - - } else if (algo_args == "dsa") { +const QContainer<KeyAlgo> 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. */ - - SetAllowEncryption(false); - allow_change_encryption_ = false; - - suggest_min_key_size_ = 1024; - suggest_max_key_size_ = 3072; - suggest_size_addition_step_ = 1024; - SetKeyLength(2048); - } else if (algo_args == "elg") { + {"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<KeyAlgo> 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<KeyAlgo> { + const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - SetAllowEncryption(true); - - SetAllowAuthentication(false); - allow_change_authentication_ = false; - - SetAllowSigning(false); - allow_change_signing_ = false; - - suggest_min_key_size_ = 1024; - suggest_max_key_size_ = 4096; - suggest_size_addition_step_ = 1024; - SetKeyLength(3072); - - } else if (algo_args == "ed25519") { - SetAllowEncryption(false); - allow_change_encryption_ = false; - - suggest_min_key_size_ = -1; - suggest_max_key_size_ = -1; - suggest_size_addition_step_ = -1; - SetKeyLength(-1); - } else if (algo_args == "cv25519" || algo_args == "x448") { - SetAllowAuthentication(false); - allow_change_authentication_ = false; - - SetAllowSigning(false); - allow_change_signing_ = false; - - suggest_min_key_size_ = -1; - suggest_max_key_size_ = -1; - suggest_size_addition_step_ = -1; - SetKeyLength(-1); - } else if (algo_args == "ed448") { - SetAllowEncryption(false); - allow_change_encryption_ = false; - - // it should allow signing or it's bug - SetAllowSigning(true); - allow_change_signing_ = true; - - suggest_min_key_size_ = -1; - suggest_max_key_size_ = -1; - suggest_size_addition_step_ = -1; - SetKeyLength(-1); - } else if (algo_args == "nistp256" || algo_args == "nistp384" || - algo_args == "nistp521" || algo_args == "brainpoolp256r1" || - algo_args == "brainpoolp384r1" || algo_args == "brainpoolp512r1" || - algo_args == "secp256k1") { - if (!subkey_) { // for primary key is always ecdsa - - SetAllowEncryption(false); - allow_change_encryption_ = false; - - } else { // for subkey key is always ecdh - - SetAllowAuthentication(false); - allow_change_authentication_ = false; - - SetAllowSigning(false); - allow_change_signing_ = false; - } - - suggest_min_key_size_ = -1; - suggest_max_key_size_ = -1; - suggest_size_addition_step_ = -1; - SetKeyLength(-1); - } else { - LOG_W() << "unsupported genkey algo arguments: " << algo_args; - return; + QContainer<KeyAlgo> algos; + + for (const auto &algo : kPrimaryKeyAlgos) { + if (!algo.IsSupported(gnupg_version)) continue; + algos.append(algo); } - this->algo_ = algo_args; + 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<KeyAlgo> { + const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); + + QContainer<KeyAlgo> 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<bool, KeyAlgo> { + 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<bool, KeyAlgo> { + 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() { @@ -168,29 +184,10 @@ void GenKeyInfo::reset_options() { allow_change_authentication_ = true; SetAllowAuthentication(true); - - passphrase_.clear(); -} - -auto GenKeyInfo::GetKeySizeStr() const -> QString { - if (key_size_ > 0) { - return QString::number(key_size_); - } - return {}; -} - -void GenKeyInfo::SetKeyLength(int m_key_size) { - if (m_key_size < suggest_min_key_size_ || - m_key_size > suggest_max_key_size_) { - return; - } - GenKeyInfo::key_size_ = m_key_size; } void GenKeyInfo::SetExpireTime(const QDateTime &m_expired) { - if (!IsNonExpired()) { - GenKeyInfo::expired_ = m_expired; - } + GenKeyInfo::expired_ = m_expired; } void GenKeyInfo::SetNonExpired(bool m_non_expired) { @@ -210,103 +207,9 @@ void GenKeyInfo::SetAllowCertification(bool m_allow_certification) { } } -GenKeyInfo::GenKeyInfo(bool m_is_sub_key) : subkey_(m_is_sub_key) { +GenKeyInfo::GenKeyInfo(bool is_subkey) : subkey_(is_subkey) { assert(!GetSupportedKeyAlgo().empty()); - SetAlgo(std::get<0>(GetSupportedKeyAlgo()[0])); -} - -auto GenKeyInfo::GetSupportedKeyAlgo() - -> const QContainer<GenKeyInfo::KeyGenAlgo> & { - static QContainer<GenKeyInfo::KeyGenAlgo> k_support_key_algo = { - {"RSA", "RSA", ""}, - {"DSA", "DSA", ""}, - }; - static bool initialized = false; - - if (!initialized) { - const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - if (GFCompareSoftwareVersion(gnupg_version, "2.0.0") < 0) { - // do nothing - } else if (GFCompareSoftwareVersion(gnupg_version, "2.3.0") < 0) { - k_support_key_algo = { - {"RSA", "RSA", ""}, - {"DSA", "DSA", ""}, - {"EdDSA (ED25519)", "ED25519", ""}, - {"ECDSA (NIST P-256)", "NISTP256", ""}, - {"ECDSA (NIST P-384)", "NISTP384", ""}, - {"ECDSA (NIST P-521)", "NISTP521", ""}, - }; - } else { - k_support_key_algo = { - {"RSA", "RSA", ""}, - {"DSA", "DSA", ""}, - {"EdDSA (ED448)", "ED448", ""}, - {"EdDSA (ED25519)", "ED25519", ""}, - {"ECDSA (SECP256K1)", "SECP256K1", ""}, - {"ECDSA (NIST P-256)", "NISTP256", ""}, - {"ECDSA (NIST P-384)", "NISTP384", ""}, - {"ECDSA (NIST P-521)", "NISTP521", ""}, - {"ECDSA (BrainPooL P-256)", "BRAINPOOLP256R1", ""}, - {"ECDSA (BrainPooL P-384)", "BRAINPOOLP384R1", ""}, - {"ECDSA (BrainPooL P-512)", "BRAINPOOLP512R1", ""}, - }; - } - - initialized = true; - } - - return k_support_key_algo; -} - -auto GenKeyInfo::GetSupportedSubkeyAlgo() - -> const QContainer<GenKeyInfo::KeyGenAlgo> & { - static QContainer<GenKeyInfo::KeyGenAlgo> k_support_subkey_algo = { - {"RSA", "", "RSA"}, - {"DSA", "", "DSA"}, - {"ELG-E", "", "ELG"}, - }; - static bool initialized = false; - - if (!initialized) { - const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - if (GFCompareSoftwareVersion(gnupg_version, "2.0.0") < 0) { - // do nothing - } else if (GFCompareSoftwareVersion(gnupg_version, "2.3.0") < 0) { - k_support_subkey_algo = { - {"RSA", "", "RSA"}, - {"DSA", "", "DSA"}, - {"ELG-E", "", "ELG"}, - {"EdDSA (ED25519)", "", "ED25519"}, - {"ECDH (CV25519)", "", "CV25519"}, - {"ECDH (NIST P-256)", "", "NISTP256"}, - {"ECDH (NIST P-384)", "", "NISTP384"}, - {"ECDH (NIST P-521)", "", "NISTP521"}, - }; - } else { - k_support_subkey_algo = { - {"RSA", "", "RSA"}, - {"DSA", "", "DSA"}, - {"ELG-E", "", "ELG"}, - {"EdDSA (ED25519)", "", "ED25519"}, - {"ECDH (CV25519)", "", "CV25519"}, - {"ECDH (SECP256K1)", "", "SECP256K1"}, - {"EdDSA (ED448)", "", "ED448"}, - {"ECDH (X448)", "", "X448"}, - {"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"}, - }; - } - - initialized = true; - } - - return k_support_subkey_algo; + SetAlgo(GetSupportedKeyAlgo().front()); } /** @@ -386,7 +289,7 @@ void GenKeyInfo::SetComment(const QString &m_comment) { * * @return const QString& */ -[[nodiscard]] auto GenKeyInfo::GetAlgo() const -> const QString & { +[[nodiscard]] auto GenKeyInfo::GetAlgo() const -> const KeyAlgo & { return algo_; } @@ -395,7 +298,9 @@ void GenKeyInfo::SetComment(const QString &m_comment) { * * @return int */ -[[nodiscard]] auto GenKeyInfo::GetKeyLength() const -> int { return key_size_; } +[[nodiscard]] auto GenKeyInfo::GetKeyLength() const -> int { + return algo_.KeyLength(); +} /** * @brief Get the Expired object @@ -506,24 +411,6 @@ void GenKeyInfo::SetAllowAuthentication(bool m_allow_authentication) { } /** - * @brief Get the Pass Phrase object - * - * @return const QString& - */ -[[nodiscard]] auto GenKeyInfo::GetPassPhrase() const -> const QString & { - return passphrase_; -} - -/** - * @brief Set the Pass Phrase object - * - * @param m_pass_phrase - */ -void GenKeyInfo::SetPassPhrase(const QString &m_pass_phrase) { - GenKeyInfo::passphrase_ = m_pass_phrase; -} - -/** * @brief * * @return true @@ -563,31 +450,37 @@ void GenKeyInfo::SetPassPhrase(const QString &m_pass_phrase) { return allow_change_authentication_; } -/** - * @brief Get the Suggest Max Key Size object - * - * @return int - */ -[[nodiscard]] auto GenKeyInfo::GetSuggestMaxKeySize() const -> int { - return suggest_max_key_size_; -} +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); +}; -/** - * @brief Get the Suggest Min Key Size object - * - * @return int - */ -[[nodiscard]] auto GenKeyInfo::GetSuggestMinKeySize() const -> int { - return suggest_min_key_size_; -} +auto KeyAlgo::Id() const -> QString { return id_; } -/** - * @brief Get the Size Change Step object - * - * @return int - */ -[[nodiscard]] auto GenKeyInfo::GetSizeChangeStep() const -> int { - return suggest_size_addition_step_; +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 index 460dffc6..a6dd03b0 100644 --- a/src/core/model/GpgGenKeyInfo.h +++ b/src/core/model/GpgGenKeyInfo.h @@ -28,14 +28,60 @@ #pragma once +#include <utility> + #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: - using KeyGenAlgo = std::tuple<QString, QString, QString>; + static const QContainer<KeyAlgo> kPrimaryKeyAlgos; + + static const QContainer<KeyAlgo> kSubKeyAlgos; /** * @brief Construct a new Gen Key Info object @@ -43,21 +89,39 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { * @param m_is_sub_key * @param m_standalone */ - explicit GenKeyInfo(bool m_is_sub_key = false); + explicit GenKeyInfo(bool is_subkey = false); /** * @brief Get the Supported Key Algo object * * @return const QContainer<KeyGenAlgo>& */ - static auto GetSupportedKeyAlgo() -> const QContainer<KeyGenAlgo> &; + static auto GetSupportedKeyAlgo() -> QContainer<KeyAlgo>; /** * @brief Get the Supported Subkey Algo object * * @return const QContainer<KeyGenAlgo>& */ - static auto GetSupportedSubkeyAlgo() -> const QContainer<KeyGenAlgo> &; + static auto GetSupportedSubkeyAlgo() -> QContainer<KeyAlgo>; + + /** + * @brief + * + * @param algo_id + * @return std::tuple<bool, KeyAlgo> + */ + static auto SearchPrimaryKeyAlgo(const QString &algo_id) + -> std::tuple<bool, KeyAlgo>; + + /** + * @brief + * + * @param algo_id + * @return std::tuple<bool, KeyAlgo> + */ + static auto SearchSubKeyAlgo(const QString &algo_id) + -> std::tuple<bool, KeyAlgo>; /** * @brief @@ -72,7 +136,7 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { * * @param m_sub_key */ - void SetIsSubKey(bool m_sub_key); + void SetIsSubKey(bool); /** * @brief Get the Userid object @@ -86,21 +150,21 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { * * @param m_name */ - void SetName(const QString &m_name); + void SetName(const QString &name); /** * @brief Set the Email object * * @param m_email */ - void SetEmail(const QString &m_email); + void SetEmail(const QString &email); /** * @brief Set the Comment object * * @param m_comment */ - void SetComment(const QString &m_comment); + void SetComment(const QString &comment); /** * @brief Get the Name object @@ -128,21 +192,14 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { * * @return const QString& */ - [[nodiscard]] auto GetAlgo() const -> const QString &; + [[nodiscard]] auto GetAlgo() const -> const KeyAlgo &; /** * @brief Set the Algo object * * @param m_algo */ - void SetAlgo(const QString &); - - /** - * @brief Get the Key Size Str object - * - * @return QString - */ - [[nodiscard]] auto GetKeySizeStr() const -> QString; + void SetAlgo(const KeyAlgo &); /** * @brief Get the Key Size object @@ -152,13 +209,6 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { [[nodiscard]] auto GetKeyLength() const -> int; /** - * @brief Set the Key Size object - * - * @param m_key_size - */ - void SetKeyLength(int m_key_size); - - /** * @brief Get the Expired object * * @return const QDateTime& @@ -271,20 +321,6 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { void SetAllowAuthentication(bool m_allow_authentication); /** - * @brief Get the Pass Phrase object - * - * @return const QString& - */ - [[nodiscard]] auto GetPassPhrase() const -> const QString &; - - /** - * @brief Set the Pass Phrase object - * - * @param m_pass_phrase - */ - void SetPassPhrase(const QString &m_pass_phrase); - - /** * @brief * * @return true @@ -316,47 +352,19 @@ class GPGFRONTEND_CORE_EXPORT GenKeyInfo { */ [[nodiscard]] auto IsAllowChangeAuthentication() const -> bool; - /** - * @brief Get the Suggest Max Key Size object - * - * @return int - */ - [[nodiscard]] auto GetSuggestMaxKeySize() const -> int; - - /** - * @brief Get the Suggest Min Key Size object - * - * @return int - */ - [[nodiscard]] auto GetSuggestMinKeySize() const -> int; - - /** - * @brief Get the Size Change Step object - * - * @return int - */ - [[nodiscard]] auto GetSizeChangeStep() const -> int; - private: bool subkey_ = false; ///< QString name_; ///< QString email_; ///< QString comment_; ///< - QString algo_; ///< - int key_size_ = 2048; + KeyAlgo algo_; ///< QDateTime expired_ = QDateTime::currentDateTime().addYears(2); bool non_expired_ = false; ///< bool no_passphrase_ = false; ///< bool allow_no_pass_phrase_ = true; ///< - int suggest_max_key_size_ = 4096; ///< - int suggest_size_addition_step_ = 1024; ///< - int suggest_min_key_size_ = 1024; ///< - - QString passphrase_; ///< - bool allow_encryption_ = true; ///< bool allow_change_encryption_ = true; ///< bool allow_certification_ = true; ///< diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h index fffc5cf4..8d9fbf5f 100644 --- a/src/core/typedef/GpgTypedef.h +++ b/src/core/typedef/GpgTypedef.h @@ -69,5 +69,7 @@ enum GpgOperation { kVERIFY = 1 << 3, kENCRYPT_SIGN = 1 << 4, kDECRYPT_VERIFY = 1 << 5, + kAUTH = 1 << 6, + kCERT = 1 << 7, }; } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/test/core/GpgCoreTestBasicOpera.cpp b/src/test/core/GpgCoreTestBasicOpera.cpp index 2e675766..4a593532 100644 --- a/src/test/core/GpgCoreTestBasicOpera.cpp +++ b/src/test/core/GpgCoreTestBasicOpera.cpp @@ -171,7 +171,7 @@ TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) { GpgBasicOperator::GetInstance().VerifySync(sign_out_buffer, GFBuffer()); ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); - ASSERT_TRUE((data_object_0->Check<GpgVerifyResult>())); + ASSERT_TRUE((data_object_0->Check<GpgVerifyResult, GFBuffer>())); auto verify_result = ExtractParams<GpgVerifyResult>(data_object_0, 0); ASSERT_FALSE(verify_result.GetSignature().empty()); ASSERT_EQ(verify_result.GetSignature().at(0).GetFingerprint(), @@ -198,7 +198,7 @@ TEST_F(GpgCoreTest, CoreSignVerifyDetachTest) { GpgBasicOperator::GetInstance().VerifySync(sign_text, sign_out_buffer); ASSERT_EQ(CheckGpgError(err_0), GPG_ERR_NO_ERROR); - ASSERT_TRUE((data_object_0->Check<GpgVerifyResult>())); + ASSERT_TRUE((data_object_0->Check<GpgVerifyResult, GFBuffer>())); auto verify_result = ExtractParams<GpgVerifyResult>(data_object_0, 0); ASSERT_FALSE(verify_result.GetSignature().empty()); ASSERT_EQ(verify_result.GetSignature().at(0).GetFingerprint(), diff --git a/src/test/core/GpgCoreTestKeygen.cpp b/src/test/core/GpgCoreTestKeygen.cpp index 9197e18e..aa4de244 100644 --- a/src/test/core/GpgCoreTestKeygen.cpp +++ b/src/test/core/GpgCoreTestKeygen.cpp @@ -37,18 +37,41 @@ namespace GpgFrontend::Test { +TEST_F(GpgCoreTest, SearchPrimaryKeyAlgoTest) { + auto [find, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + ASSERT_TRUE(find); + ASSERT_EQ(algo.Id(), "rsa2048"); + ASSERT_EQ(algo.Id(), "rsa2048"); + ASSERT_EQ(algo.Name(), "RSA"); + ASSERT_EQ(algo.Type(), "RSA"); + ASSERT_EQ(algo.KeyLength(), 2048); +} + +TEST_F(GpgCoreTest, SearchSubKeyAlgoTest) { + auto [find, algo] = GenKeyInfo::SearchSubKeyAlgo("rsa2048"); + ASSERT_TRUE(find); + ASSERT_EQ(algo.Id(), "rsa2048"); + ASSERT_EQ(algo.Name(), "RSA"); + ASSERT_EQ(algo.Type(), "RSA"); + ASSERT_EQ(algo.KeyLength(), 2048); +} + TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { - auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_0"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("foobar"); - keygen_info->SetAlgo("rsa"); - keygen_info->SetKeyLength(2048); - keygen_info->SetNonExpired(true); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_0"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("foobar"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "rsa2048"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(true); + p_info->SetNonPassPhrase(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -84,22 +107,26 @@ TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { } 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("rsa"); - keygen_info->SetKeyLength(4096); - keygen_info->SetNonExpired(false); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_1"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("hello gpgfrontend"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa4096"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "rsa4096"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(false); + p_info->SetNonPassPhrase(true); auto expire_time = QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); - keygen_info->SetExpireTime(expire_time); - keygen_info->SetNonPassPhrase(false); + p_info->SetExpireTime(expire_time); + p_info->SetNonPassPhrase(false); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -119,22 +146,26 @@ TEST_F(GpgCoreTest, GenerateKeyRSA4096Test) { } TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { - auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_1"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("hello gpgfrontend"); - keygen_info->SetAlgo("dsa"); - keygen_info->SetKeyLength(2048); - keygen_info->SetNonExpired(false); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_1"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("hello gpgfrontend"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("dsa2048"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "dsa2048"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(false); + p_info->SetNonPassPhrase(true); auto expire_time = QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); - keygen_info->SetExpireTime(expire_time); - keygen_info->SetNonPassPhrase(false); + p_info->SetExpireTime(expire_time); + p_info->SetNonPassPhrase(false); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); @@ -169,21 +200,26 @@ TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { } TEST_F(GpgCoreTest, GenerateKeyED25519Test) { - auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_4"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("hello gpgfrontend"); - keygen_info->SetAlgo("ed25519"); - keygen_info->SetNonExpired(false); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_4"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("hello gpgfrontend"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "ed25519"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(false); + p_info->SetNonPassPhrase(true); auto expire_time = QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); - keygen_info->SetExpireTime(expire_time); - keygen_info->SetNonPassPhrase(false); + p_info->SetExpireTime(expire_time); + p_info->SetNonPassPhrase(false); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); @@ -218,22 +254,31 @@ TEST_F(GpgCoreTest, GenerateKeyED25519Test) { } 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("ed25519"); - keygen_info->SetNonExpired(true); - keygen_info->SetNonPassPhrase(true); - - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("cv25519"); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); - - auto [err, data_object] = - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeyWithSubkeySync(keygen_info, subkeygen_info); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_ec"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("ecccc"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "ed25519"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(true); + p_info->SetNonPassPhrase(true); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + std::tie(found, algo) = GenKeyInfo::SearchSubKeyAlgo("cv25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "cv25519"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeyWithSubkeySync(p_info, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_TRUE( @@ -284,22 +329,31 @@ TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { } 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("ed25519"); - keygen_info->SetNonExpired(true); - keygen_info->SetNonPassPhrase(true); - - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("nistp256"); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); - - auto [err, data_object] = - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeyWithSubkeySync(keygen_info, subkeygen_info); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_ec2"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("ecccc"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "ed25519"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(true); + p_info->SetNonPassPhrase(true); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + std::tie(found, algo) = GenKeyInfo::SearchSubKeyAlgo("nistp256"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "nistp256"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeyWithSubkeySync(p_info, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_TRUE( @@ -350,22 +404,31 @@ TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { } 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("ed25519"); - keygen_info->SetNonExpired(true); - keygen_info->SetNonPassPhrase(true); - - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("brainpoolp256r1"); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); - - auto [err, data_object] = - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeyWithSubkeySync(keygen_info, subkeygen_info); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_ec3"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("ecccc3"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "ed25519"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(true); + p_info->SetNonPassPhrase(true); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + std::tie(found, algo) = GenKeyInfo::SearchSubKeyAlgo("brainpoolp256r1"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "brainpoolp256r1"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); + + auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) + .GenerateKeyWithSubkeySync(p_info, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_TRUE( @@ -416,21 +479,26 @@ TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { } TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { - auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_4"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("hello gpgfrontend"); - keygen_info->SetAlgo("nistp256"); - keygen_info->SetNonExpired(false); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_4"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("hello gpgfrontend"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("nistp256"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "nistp256"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(false); + p_info->SetNonPassPhrase(true); auto expire_time = QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); - keygen_info->SetExpireTime(expire_time); - keygen_info->SetNonPassPhrase(false); + p_info->SetExpireTime(expire_time); + p_info->SetNonPassPhrase(false); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); @@ -466,21 +534,26 @@ TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { } TEST_F(GpgCoreTest, GenerateKeyED448Test) { - auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_4"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("hello gpgfrontend"); - keygen_info->SetAlgo("ed448"); - keygen_info->SetNonExpired(false); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_4"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("hello gpgfrontend"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed448"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "ed448"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(false); + p_info->SetNonPassPhrase(true); auto expire_time = QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); - keygen_info->SetExpireTime(expire_time); - keygen_info->SetNonPassPhrase(false); + p_info->SetExpireTime(expire_time); + p_info->SetNonPassPhrase(false); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); @@ -516,21 +589,26 @@ TEST_F(GpgCoreTest, GenerateKeyED448Test) { } TEST_F(GpgCoreTest, GenerateKeySECP256K1Test) { - auto keygen_info = SecureCreateSharedObject<GenKeyInfo>(); - keygen_info->SetName("foo_4"); - keygen_info->SetEmail("[email protected]"); - keygen_info->SetComment("hello gpgfrontend"); - keygen_info->SetAlgo("secp256k1"); - keygen_info->SetNonExpired(false); - keygen_info->SetNonPassPhrase(true); + auto p_info = QSharedPointer<GenKeyInfo>::create(); + p_info->SetName("foo_4"); + p_info->SetEmail("[email protected]"); + p_info->SetComment("hello gpgfrontend"); + + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("secp256k1"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "secp256k1"); + p_info->SetAlgo(algo); + + p_info->SetNonExpired(false); + p_info->SetNonPassPhrase(true); auto expire_time = QDateTime::currentDateTime().addSecs(static_cast<qint64>(24 * 3600)); - keygen_info->SetExpireTime(expire_time); - keygen_info->SetNonPassPhrase(false); + p_info->SetExpireTime(expire_time); + p_info->SetNonPassPhrase(false); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateKeySync(keygen_info); + .GenerateKeySync(p_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); ASSERT_TRUE(data_object->Check<GpgGenerateKeyResult>()); diff --git a/src/test/core/GpgCoreTestSubkeygen.cpp b/src/test/core/GpgCoreTestSubkeygen.cpp index c4fe92b0..886a6f04 100644 --- a/src/test/core/GpgCoreTestSubkeygen.cpp +++ b/src/test/core/GpgCoreTestSubkeygen.cpp @@ -38,18 +38,22 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, GenerateSubkeyRSA2048Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("rsa"); - subkeygen_info->SetKeyLength(2048); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("rsa2048"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "rsa2048"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -77,18 +81,22 @@ TEST_F(GpgCoreTest, GenerateSubkeyRSA2048Test) { } TEST_F(GpgCoreTest, GenerateSubkeyDSA2048Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("dsa"); - subkeygen_info->SetKeyLength(2048); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("dsa2048"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "dsa2048"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -116,18 +124,22 @@ TEST_F(GpgCoreTest, GenerateSubkeyDSA2048Test) { } TEST_F(GpgCoreTest, GenerateSubkeyELG2048Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("elg"); - subkeygen_info->SetKeyLength(2048); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("elg2048"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "elg2048"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -155,17 +167,22 @@ TEST_F(GpgCoreTest, GenerateSubkeyELG2048Test) { } TEST_F(GpgCoreTest, GenerateSubkeyED25519Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("ed25519"); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("ed25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "ed25519"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -193,17 +210,22 @@ TEST_F(GpgCoreTest, GenerateSubkeyED25519Test) { } TEST_F(GpgCoreTest, GenerateSubkeyCV25519Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("cv25519"); - subkeygen_info->SetNonExpired(true); - subkeygen_info->SetNonPassPhrase(true); + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("cv25519"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "cv25519"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); + s_info->SetNonPassPhrase(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -231,16 +253,21 @@ TEST_F(GpgCoreTest, GenerateSubkeyCV25519Test) { } TEST_F(GpgCoreTest, GenerateSubkeyNISTP256Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("nistp256"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "nistp256"); + s_info->SetAlgo(algo); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("nistp256"); - subkeygen_info->SetNonExpired(true); + s_info->SetNonExpired(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -268,16 +295,21 @@ TEST_F(GpgCoreTest, GenerateSubkeyNISTP256Test) { } TEST_F(GpgCoreTest, GenerateSubkeyBRAINPOOLP256R1Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("brainpoolp256r1"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "brainpoolp256r1"); + s_info->SetAlgo(algo); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("brainpoolp256r1"); - subkeygen_info->SetNonExpired(true); + s_info->SetNonExpired(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -305,16 +337,21 @@ TEST_F(GpgCoreTest, GenerateSubkeyBRAINPOOLP256R1Test) { } TEST_F(GpgCoreTest, GenerateSubkeyX448Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("x448"); - subkeygen_info->SetNonExpired(true); + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("x448"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "x448"); + s_info->SetAlgo(algo); + + s_info->SetNonExpired(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); @@ -342,16 +379,21 @@ TEST_F(GpgCoreTest, GenerateSubkeyX448Test) { } TEST_F(GpgCoreTest, GenerateSubkeySECP256K1Test) { - auto main_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKey( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(main_key.IsGood()); + ASSERT_TRUE(p_key.IsGood()); + + auto s_info = QSharedPointer<GenKeyInfo>::create(true); + + auto [found, algo] = GenKeyInfo::SearchSubKeyAlgo("secp256k1"); + ASSERT_TRUE(found); + ASSERT_EQ(algo.Id(), "secp256k1"); + s_info->SetAlgo(algo); - auto subkeygen_info = SecureCreateSharedObject<GenKeyInfo>(true); - subkeygen_info->SetAlgo("secp256k1"); - subkeygen_info->SetNonExpired(true); + s_info->SetNonExpired(true); auto [err, data_object] = GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .GenerateSubkeySync(main_key, subkeygen_info); + .GenerateSubkeySync(p_key, s_info); ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR); ASSERT_EQ(data_object->GetObjectSize(), 1); diff --git a/src/ui/dialog/Wizard.cpp b/src/ui/dialog/Wizard.cpp index ee70239a..32d88b31 100644 --- a/src/ui/dialog/Wizard.cpp +++ b/src/ui/dialog/Wizard.cpp @@ -29,14 +29,16 @@ #include "Wizard.h" #include "core/function/GlobalSettingStation.h" +#include "ui/GpgFrontendUI.h" +#include "ui/dialog/key_generate/KeyGenDialog.h" namespace GpgFrontend::UI { Wizard::Wizard(QWidget* parent) : QWizard(parent) { - setPage(Page_Intro, new IntroPage(this)); - setPage(Page_Choose, new ChoosePage(this)); - setPage(Page_GenKey, new KeyGenPage(this)); - setPage(Page_Conclusion, new ConclusionPage(this)); + setPage(kPAGE_INTRO, new IntroPage(this)); + setPage(kPAGE_CHOOSE, new ChoosePage(this)); + setPage(kPAGE_GEN_KEY, new KeyGenPage(this)); + setPage(kPAGE_CONCLUSION, new ConclusionPage(this)); #ifndef Q_WS_MAC setWizardStyle(ModernStyle); #endif @@ -98,7 +100,7 @@ IntroPage::IntroPage(QWidget* parent) : QWizardPage(parent) { setLayout(layout); } -int IntroPage::nextId() const { return Wizard::Page_Choose; } +int IntroPage::nextId() const { return Wizard::kPAGE_CHOOSE; } ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) { setTitle(tr("Choose your action...")); @@ -143,7 +145,7 @@ ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) { layout->addWidget(encr_decy_text_label); layout->addWidget(sign_verify_text_label); setLayout(layout); - next_page_ = Wizard::Page_Conclusion; + next_page_ = Wizard::kPAGE_CONCLUSION; } int ChoosePage::nextId() const { return next_page_; } @@ -190,7 +192,7 @@ KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) { setLayout(layout); } -int KeyGenPage::nextId() const { return Wizard::Page_Conclusion; } +int KeyGenPage::nextId() const { return Wizard::kPAGE_CONCLUSION; } void KeyGenPage::slot_generate_key_dialog() { (new KeyGenDialog(kGpgFrontendDefaultChannel, this))->show(); diff --git a/src/ui/dialog/Wizard.h b/src/ui/dialog/Wizard.h index eae1d73d..91a5f846 100644 --- a/src/ui/dialog/Wizard.h +++ b/src/ui/dialog/Wizard.h @@ -29,10 +29,6 @@ #pragma once #include "core/GpgConstants.h" -#include "main_window/KeyMgmt.h" -#include "ui/GpgFrontendUI.h" -#include "ui/dialog/key_generate/KeygenDialog.h" -#include "ui/dialog/settings/SettingsDialog.h" namespace GpgFrontend::UI { @@ -45,7 +41,12 @@ class Wizard : public QWizard { Q_ENUMS(WizardPages) public: - enum WizardPages { Page_Intro, Page_Choose, Page_GenKey, Page_Conclusion }; + enum WizardPages { + kPAGE_INTRO, + kPAGE_CHOOSE, + kPAGE_GEN_KEY, + kPAGE_CONCLUSION, + }; /** * @brief Construct a new Wizard object @@ -176,7 +177,7 @@ class ConclusionPage : public QWizardPage { * * @return int */ - [[nodiscard]] int nextId() const override; + [[nodiscard]] auto nextId() const -> int override; private: QCheckBox* dont_show_wizard_checkbox_; ///< diff --git a/src/ui/dialog/key_generate/KeygenDialog.cpp b/src/ui/dialog/key_generate/KeygenDialog.cpp index 0bf235ac..a5ba98d1 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.cpp +++ b/src/ui/dialog/key_generate/KeygenDialog.cpp @@ -26,12 +26,11 @@ * */ -#include "KeygenDialog.h" +#include "KeyGenDialog.h" #include "core/GpgModel.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyOpera.h" -#include "core/module/ModuleManager.h" #include "core/typedef/GpgTypedef.h" #include "core/utils/CacheUtils.h" #include "core/utils/GpgUtils.h" @@ -39,440 +38,552 @@ #include "ui/UserInterfaceUtils.h" #include "ui/function/GpgOperaHelper.h" +// +#include "ui_KeyGenDialog.h" + namespace GpgFrontend::UI { -KeyGenDialog::KeyGenDialog(int channel, QWidget* parent) - : GeneralDialog(typeid(KeyGenDialog).name(), parent), - default_gpg_context_channel_(channel) { - button_box_ = - new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); +auto SearchAlgoByName(const QString& name, + const QContainer<KeyAlgo>& algos) -> QContainer<KeyAlgo> { + QContainer<KeyAlgo> res; - bool const longer_expiration_date = - GetSettings().value("basic/longer_expiration_date", false).toBool(); + for (const auto& algo : algos) { + if (algo.Name() != name) continue; + res.append(algo); + } - max_date_time_ = longer_expiration_date - ? QDateTime::currentDateTime().toLocalTime().addYears(30) - : QDateTime::currentDateTime().toLocalTime().addYears(2); + return res; +} - connect(this, &KeyGenDialog::SignalKeyGenerated, - UISignalStation::GetInstance(), - &UISignalStation::SignalKeyDatabaseRefresh); +auto GetAlgoByNameAndKeyLength(const QString& name, int key_length, + const QContainer<KeyAlgo>& algos) + -> std::tuple<bool, KeyAlgo> { + for (const auto& algo : algos) { + if (algo.Name() != name) continue; + if (algo.KeyLength() != key_length) continue; + return {true, algo}; + } - generate_key_dialog(); + return {}; +} - this->setWindowTitle(tr("Generate Key")); - this->setAttribute(Qt::WA_DeleteOnClose); - this->setModal(true); +auto GetAlgoByName(const QString& name, const QContainer<KeyAlgo>& algos) + -> std::tuple<bool, KeyAlgo> { + for (const auto& algo : algos) { + if (algo.Name() != name) continue; + return {true, algo}; + } + + return {}; +} + +void SetKeyLengthComboxBoxByAlgo(QComboBox* combo, + const QContainer<KeyAlgo>& algos) { + combo->clear(); + + QContainer<KeyAlgo> sorted_algos(algos.begin(), algos.end()); + std::sort(sorted_algos.begin(), sorted_algos.end(), + [](const KeyAlgo& a, const KeyAlgo& b) { + return a.KeyLength() < b.KeyLength(); + }); + + QStringList key_lengths; + for (const auto& algo : sorted_algos) { + key_lengths.append(QString::number(algo.KeyLength())); + } + + combo->addItems(key_lengths); } -void KeyGenDialog::generate_key_dialog() { - key_usage_group_box_ = create_key_usage_group_box(); +KeyGenDialog::KeyGenDialog(int channel, QWidget* parent) + : GeneralDialog(typeid(KeyGenDialog).name(), parent), + ui_(QSharedPointer<Ui_KeyGenDialog>::create()), + gen_key_info_(QSharedPointer<GenKeyInfo>::create()), + gen_subkey_info_(nullptr), + supported_primary_key_algos_(GenKeyInfo::GetSupportedKeyAlgo()), + supported_subkey_algos_(GenKeyInfo::GetSupportedSubkeyAlgo()), + channel_(channel) { + ui_->setupUi(this); + + for (const auto& key_db : GetGpgKeyDatabaseInfos()) { + ui_->keyDBIndexComboBox->insertItem( + key_db.channel, QString("%1: %2").arg(key_db.channel).arg(key_db.name)); + } - auto* group_grid = new QGridLayout(this); - group_grid->addWidget(create_basic_info_group_box(), 0, 0); - group_grid->addWidget(key_usage_group_box_, 1, 0); + ui_->easyAlgoComboBox->addItems({ + tr("Custom"), + "RSA", + "DSA", + "ECC (25519)", + }); - auto* name_list = new QWidget(this); - name_list->setLayout(group_grid); + ui_->easyValidityPeriodComboBox->addItems({ + tr("Custom"), + tr("3 Months"), + tr("6 Months"), + tr("1 Year"), + tr("2 Years"), + tr("5 Years"), + tr("10 Years"), + tr("Non Expired"), + }); - auto* vbox2 = new QVBoxLayout(); - vbox2->addWidget(name_list); - vbox2->addWidget(error_label_); - vbox2->addWidget(button_box_); + QSet<QString> p_algo_set; + for (const auto& algo : supported_primary_key_algos_) { + p_algo_set.insert(algo.Name()); + } + ui_->pAlgoComboBox->addItems( + QStringList(p_algo_set.cbegin(), p_algo_set.cend())); + + QSet<QString> s_algo_set; + for (const auto& algo : supported_subkey_algos_) { + s_algo_set.insert(algo.Name()); + } + ui_->sAlgoComboBox->addItem(tr("None")); + ui_->sAlgoComboBox->addItems( + QStringList(s_algo_set.cbegin(), s_algo_set.cend())); - this->setLayout(vbox2); + ui_->easyAlgoComboBox->setCurrentText("RSA"); + ui_->easyValidityPeriodComboBox->setCurrentText(tr("2 Years")); - set_signal_slot(); - refresh_widgets_state(); + set_signal_slot_config(); + + slot_easy_mode_changed("RSA"); + slot_easy_valid_date_changed(tr("2 Years")); + + this->setWindowTitle(tr("Generate Key")); + this->setAttribute(Qt::WA_DeleteOnClose); + this->setModal(true); } void KeyGenDialog::slot_key_gen_accept() { QString buffer; QTextStream error_stream(&buffer); - /** - * check for errors in keygen dialog input - */ - if ((name_edit_->text()).size() < 5) { - error_stream << " " << tr("Name must contain at least five characters.") - << '\n'; + if (ui_->nameEdit->text().size() < 5) { + error_stream << " -> " << tr("Name must contain at least five characters.") + << Qt::endl; } - if (email_edit_->text().isEmpty() || - !check_email_address(email_edit_->text())) { - error_stream << " " << tr("Please give a email address.") << '\n'; + if (ui_->emailEdit->text().isEmpty() || + !check_email_address(ui_->emailEdit->text())) { + error_stream << " -> " << tr("Please give a valid email address.") + << Qt::endl; } - /** - * primary keys should have a reasonable expiration date (no more than 2 years - * in the future) - */ - if (date_edit_->dateTime() > max_date_time_) { - error_stream << " " << tr("Expiration time too long.") << '\n'; + const auto err_string = error_stream.readAll(); + if (!err_string.isEmpty()) { + ui_->statusPlainTextEdit->clear(); + ui_->statusPlainTextEdit->appendPlainText(err_string); + return; } - auto err_string = error_stream.readAll(); - if (err_string.isEmpty()) { - /** - * create the string for key generation - */ - gen_key_info_->SetName(name_edit_->text()); - gen_key_info_->SetEmail(email_edit_->text()); - gen_key_info_->SetComment(comment_edit_->text()); - - gen_key_info_->SetKeyLength(key_size_spin_box_->value()); - - if (no_pass_phrase_check_box_->checkState() != 0U) { - gen_key_info_->SetNonPassPhrase(true); - if (gen_subkey_info_ != nullptr) { - gen_subkey_info_->SetNonPassPhrase(true); - } - } + gen_key_info_->SetName(ui_->nameEdit->text()); + gen_key_info_->SetEmail(ui_->emailEdit->text()); + gen_key_info_->SetComment(ui_->commentEdit->text()); - if (expire_check_box_->checkState() != 0U) { - gen_key_info_->SetNonExpired(true); - if (gen_subkey_info_ != nullptr) gen_subkey_info_->SetNonExpired(true); - } else { - gen_key_info_->SetExpireTime(date_edit_->dateTime()); - if (gen_subkey_info_ != nullptr) { - gen_subkey_info_->SetExpireTime(date_edit_->dateTime()); - } + if (ui_->noPassphraseCheckBox->checkState() != 0U) { + gen_key_info_->SetNonPassPhrase(true); + if (gen_subkey_info_ != nullptr) { + gen_subkey_info_->SetNonPassPhrase(true); } + } - if (!GetSettings() - .value("gnupg/use_pinentry_as_password_input_dialog", - QString::fromLocal8Bit(qgetenv("container")) != "flatpak") - .toBool() && - !no_pass_phrase_check_box_->isChecked()) { - SetCacheValue("PinentryContext", "NEW_PASSPHRASE"); + if (ui_->pExpireCheckBox->checkState() != 0U) { + gen_key_info_->SetNonExpired(true); + if (gen_subkey_info_ != nullptr) gen_subkey_info_->SetNonExpired(true); + } else { + gen_key_info_->SetExpireTime(ui_->pValidityPeriodDateTimeEdit->dateTime()); + if (gen_subkey_info_ != nullptr) { + gen_subkey_info_->SetExpireTime( + ui_->sValidityPeriodDateTimeEdit->dateTime()); } + } - auto selected_gpg_context_channel = gpg_contexts_combo_box_->currentIndex(); - LOG_D() << "try to generate key at gpg context channel: " - << selected_gpg_context_channel; - - GpgOperaHelper::WaitForOpera( - this, tr("Generating"), - [this, gen_key_info = this->gen_key_info_, - selected_gpg_context_channel](const OperaWaitingHd& hd) { - GpgKeyOpera::GetInstance(selected_gpg_context_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(); - } - }); - }); - - this->done(0); + if (!GetSettings() + .value("gnupg/use_pinentry_as_password_input_dialog", + QString::fromLocal8Bit(qgetenv("container")) != "flatpak") + .toBool() && + !ui_->noPassphraseCheckBox->isChecked()) { + SetCacheValue("PinentryContext", "NEW_PASSPHRASE"); + } - } 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(); + 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(); + } + }); + }); + + this->done(0); +} + +void KeyGenDialog::refresh_widgets_state() { + ui_->pAlgoComboBox->blockSignals(true); + ui_->pAlgoComboBox->setCurrentText(gen_key_info_->GetAlgo().Name()); + ui_->pAlgoComboBox->blockSignals(false); + + ui_->pKeyLengthComboBox->blockSignals(true); + SetKeyLengthComboxBoxByAlgo( + ui_->pKeyLengthComboBox, + SearchAlgoByName(ui_->pAlgoComboBox->currentText(), + supported_primary_key_algos_)); + ui_->pKeyLengthComboBox->setCurrentText( + QString::number(gen_key_info_->GetKeyLength())); + ui_->pKeyLengthComboBox->blockSignals(false); + + ui_->pEncrCheckBox->blockSignals(true); + ui_->pEncrCheckBox->setCheckState( + gen_key_info_->IsAllowEncryption() ? Qt::Checked : Qt::Unchecked); + ui_->pEncrCheckBox->setEnabled(gen_key_info_->IsAllowChangeEncryption()); + ui_->pEncrCheckBox->blockSignals(false); + + ui_->pSignCheckBox->blockSignals(true); + ui_->pSignCheckBox->setCheckState( + gen_key_info_->IsAllowSigning() ? Qt::Checked : Qt::Unchecked); + ui_->pSignCheckBox->setEnabled(gen_key_info_->IsAllowChangeSigning()); + ui_->pSignCheckBox->blockSignals(false); + + ui_->pAuthCheckBox->blockSignals(true); + ui_->pAuthCheckBox->setCheckState( + gen_key_info_->IsAllowAuthentication() ? Qt::Checked : Qt::Unchecked); + ui_->pAuthCheckBox->setEnabled(gen_key_info_->IsAllowChangeAuthentication()); + ui_->pAuthCheckBox->blockSignals(false); + + ui_->noPassphraseCheckBox->setEnabled(gen_key_info_->IsAllowNoPassPhrase()); + + ui_->pValidityPeriodDateTimeEdit->blockSignals(true); + ui_->pValidityPeriodDateTimeEdit->setDateTime(gen_key_info_->GetExpireTime()); + ui_->pValidityPeriodDateTimeEdit->setDisabled(gen_key_info_->IsNonExpired()); + ui_->pValidityPeriodDateTimeEdit->blockSignals(false); + + ui_->pExpireCheckBox->blockSignals(true); + ui_->pExpireCheckBox->setChecked(gen_key_info_->IsNonExpired()); + ui_->pExpireCheckBox->blockSignals(false); + + if (gen_subkey_info_ == nullptr) { + ui_->tab_3->setDisabled(true); + + ui_->sAlgoComboBox->blockSignals(true); + ui_->sAlgoComboBox->setCurrentText(tr("None")); + ui_->sAlgoComboBox->blockSignals(false); + + ui_->sKeyLengthComboBox->blockSignals(true); + ui_->sKeyLengthComboBox->clear(); + ui_->sKeyLengthComboBox->blockSignals(false); + + ui_->sEncrCheckBox->blockSignals(true); + ui_->sEncrCheckBox->setCheckState(Qt::Unchecked); + ui_->sEncrCheckBox->blockSignals(false); + + ui_->sSignCheckBox->blockSignals(true); + ui_->sSignCheckBox->setCheckState(Qt::Unchecked); + ui_->sSignCheckBox->blockSignals(false); + + ui_->sAuthCheckBox->blockSignals(true); + ui_->sAuthCheckBox->setCheckState(Qt::Unchecked); + ui_->sAuthCheckBox->blockSignals(false); + + ui_->sValidityPeriodDateTimeEdit->blockSignals(true); + ui_->sValidityPeriodDateTimeEdit->setDateTime(QDateTime::currentDateTime()); + ui_->sValidityPeriodDateTimeEdit->setDisabled(true); + ui_->sValidityPeriodDateTimeEdit->blockSignals(false); + + ui_->sExpireCheckBox->blockSignals(true); + ui_->sExpireCheckBox->setCheckState(Qt::Unchecked); + ui_->sExpireCheckBox->blockSignals(false); + return; } + + ui_->tab_3->setDisabled(false); + + ui_->sAlgoComboBox->blockSignals(true); + ui_->sAlgoComboBox->setCurrentText(gen_subkey_info_->GetAlgo().Name()); + ui_->sAlgoComboBox->blockSignals(false); + + ui_->sKeyLengthComboBox->blockSignals(true); + SetKeyLengthComboxBoxByAlgo( + ui_->sKeyLengthComboBox, + SearchAlgoByName(ui_->sAlgoComboBox->currentText(), + supported_subkey_algos_)); + ui_->sKeyLengthComboBox->setCurrentText( + QString::number(gen_subkey_info_->GetKeyLength())); + ui_->sKeyLengthComboBox->blockSignals(false); + + ui_->sEncrCheckBox->blockSignals(true); + ui_->sEncrCheckBox->setCheckState( + gen_subkey_info_->IsAllowEncryption() ? Qt::Checked : Qt::Unchecked); + ui_->sEncrCheckBox->setEnabled(gen_subkey_info_->IsAllowChangeEncryption()); + ui_->sEncrCheckBox->blockSignals(false); + + ui_->sSignCheckBox->blockSignals(true); + ui_->sSignCheckBox->setCheckState( + gen_subkey_info_->IsAllowSigning() ? Qt::Checked : Qt::Unchecked); + ui_->sSignCheckBox->setEnabled(gen_subkey_info_->IsAllowChangeSigning()); + ui_->sSignCheckBox->blockSignals(false); + + ui_->sAuthCheckBox->blockSignals(true); + ui_->sAuthCheckBox->setCheckState( + gen_subkey_info_->IsAllowAuthentication() ? Qt::Checked : Qt::Unchecked); + ui_->sAuthCheckBox->setEnabled( + gen_subkey_info_->IsAllowChangeAuthentication()); + ui_->sAuthCheckBox->blockSignals(false); + + ui_->sValidityPeriodDateTimeEdit->blockSignals(true); + ui_->sValidityPeriodDateTimeEdit->setDateTime( + gen_subkey_info_->GetExpireTime()); + ui_->sValidityPeriodDateTimeEdit->setDisabled( + gen_subkey_info_->IsNonExpired()); + ui_->sValidityPeriodDateTimeEdit->blockSignals(false); + + ui_->sExpireCheckBox->blockSignals(true); + ui_->sExpireCheckBox->setChecked(gen_subkey_info_->IsNonExpired()); + ui_->sExpireCheckBox->blockSignals(false); } -void KeyGenDialog::slot_expire_box_changed() {} +void KeyGenDialog::set_signal_slot_config() { + connect(ui_->generateButton, &QPushButton::clicked, this, + &KeyGenDialog::slot_key_gen_accept); + + connect(ui_->pExpireCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + ui_->pValidityPeriodDateTimeEdit->setDisabled(state == Qt::Checked); + + slot_set_easy_valid_date_2_custom(); + }); + connect(ui_->sExpireCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + ui_->sValidityPeriodDateTimeEdit->setDisabled(state == Qt::Checked); + + slot_set_easy_valid_date_2_custom(); + }); + + connect(ui_->pEncrCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + gen_key_info_->SetAllowEncryption(state == Qt::Checked); + }); + connect(ui_->pSignCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + gen_key_info_->SetAllowSigning(state == Qt::Checked); + }); + connect(ui_->pAuthCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + gen_key_info_->SetAllowAuthentication(state == Qt::Checked); + }); + + connect(ui_->sEncrCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + gen_subkey_info_->SetAllowEncryption(state == Qt::Checked); + }); + connect(ui_->sSignCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + gen_subkey_info_->SetAllowSigning(state == Qt::Checked); + }); + connect(ui_->sAuthCheckBox, &QCheckBox::stateChanged, this, + [this](int state) { + gen_subkey_info_->SetAllowAuthentication(state == Qt::Checked); + }); + + connect(ui_->noPassphraseCheckBox, &QCheckBox::stateChanged, this, + [this](int state) -> void { + gen_key_info_->SetNonPassPhrase(state != 0); + if (gen_subkey_info_ != nullptr) { + gen_subkey_info_->SetNonPassPhrase(state != 0); + } + }); + + connect(ui_->pAlgoComboBox, &QComboBox::currentTextChanged, this, + [=](const QString&) { + sync_gen_key_info(); + slot_set_easy_key_algo_2_custom(); + refresh_widgets_state(); + }); -auto KeyGenDialog::create_key_usage_group_box() -> QGroupBox* { - auto* group_box = new QGroupBox(this); - auto* grid = new QGridLayout(this); + connect(ui_->sAlgoComboBox, &QComboBox::currentTextChanged, this, + [=](const QString&) { + sync_gen_subkey_info(); + slot_set_easy_key_algo_2_custom(); + refresh_widgets_state(); + }); - group_box->setTitle(tr("Key Usage")); + connect(ui_->easyAlgoComboBox, &QComboBox::currentTextChanged, this, + &KeyGenDialog::slot_easy_mode_changed); - auto* encrypt = new QCheckBox(tr("Encryption"), group_box); - encrypt->setTristate(false); + connect(ui_->easyValidityPeriodComboBox, &QComboBox::currentTextChanged, this, + &KeyGenDialog::slot_easy_valid_date_changed); - auto* sign = new QCheckBox(tr("Signing"), group_box); - sign->setTristate(false); + connect(ui_->pValidityPeriodDateTimeEdit, &QDateTimeEdit::dateTimeChanged, + this, [=](const QDateTime& dt) { + gen_key_info_->SetExpireTime(dt); - auto* cert = new QCheckBox(tr("Certification"), group_box); - cert->setTristate(false); + slot_set_easy_valid_date_2_custom(); + }); - auto* auth = new QCheckBox(tr("Authentication"), group_box); - auth->setTristate(false); + connect(ui_->sValidityPeriodDateTimeEdit, &QDateTimeEdit::dateTimeChanged, + this, [=](const QDateTime& dt) { + gen_subkey_info_->SetExpireTime(dt); - key_usage_check_boxes_.push_back(encrypt); - key_usage_check_boxes_.push_back(sign); - key_usage_check_boxes_.push_back(cert); - key_usage_check_boxes_.push_back(auth); + slot_set_easy_valid_date_2_custom(); + }); - grid->addWidget(encrypt, 0, 0); - grid->addWidget(sign, 0, 1); - grid->addWidget(cert, 1, 0); - grid->addWidget(auth, 1, 1); + connect(ui_->keyDBIndexComboBox, &QComboBox::currentIndexChanged, this, + [=](int index) { channel_ = index; }); - group_box->setLayout(grid); + connect(this, &KeyGenDialog::SignalKeyGenerated, + UISignalStation::GetInstance(), + &UISignalStation::SignalKeyDatabaseRefresh); +} - return group_box; +auto KeyGenDialog::check_email_address(const QString& str) -> bool { + return re_email_.match(str).hasMatch(); } -void KeyGenDialog::slot_encryption_box_changed(int state) { - if (state == 0) { - gen_key_info_->SetAllowEncryption(false); - } else { - gen_key_info_->SetAllowEncryption(true); +void KeyGenDialog::sync_gen_key_info() { + auto [found, algo] = GetAlgoByName(ui_->pAlgoComboBox->currentText(), + + supported_primary_key_algos_); + + ui_->generateButton->setDisabled(!found); + + if (found) { + gen_key_info_->SetAlgo(algo); } } -void KeyGenDialog::slot_signing_box_changed(int state) { - if (state == 0) { - gen_key_info_->SetAllowSigning(false); - } else { - gen_key_info_->SetAllowSigning(true); +void KeyGenDialog::sync_gen_subkey_info() { + if (gen_subkey_info_ != nullptr) { + auto [s_found, algo] = GetAlgoByName(ui_->sAlgoComboBox->currentText(), + supported_subkey_algos_); + + ui_->generateButton->setDisabled(!s_found); + if (s_found) gen_subkey_info_->SetAlgo(algo); } } -void KeyGenDialog::slot_certification_box_changed(int state) { - if (state == 0) { - gen_key_info_->SetAllowCertification(false); - } else { - gen_key_info_->SetAllowCertification(true); +void KeyGenDialog::slot_easy_mode_changed(const QString& mode) { + if (mode == "RSA") { + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + if (found) gen_key_info_->SetAlgo(algo); + + gen_subkey_info_ = nullptr; } -} -void KeyGenDialog::slot_authentication_box_changed(int state) { - if (state == 0) { - gen_key_info_->SetAllowAuthentication(false); - } else { - gen_key_info_->SetAllowAuthentication(true); + else if (mode == "DSA") { + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("dsa2048"); + if (found) gen_key_info_->SetAlgo(algo); + + if (gen_subkey_info_ == nullptr) { + gen_subkey_info_ = QSharedPointer<GenKeyInfo>::create(true); + } + + auto [s_found, s_algo] = GenKeyInfo::SearchSubKeyAlgo("elg2048"); + if (s_found) gen_subkey_info_->SetAlgo(s_algo); } -} -void KeyGenDialog::slot_activated_key_type(int index) { - // check - assert(gen_key_info_->GetSupportedKeyAlgo().size() > - static_cast<size_t>(index)); + else if (mode == "ECC (25519)") { + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("ed25519"); + if (found) gen_key_info_->SetAlgo(algo); - const auto [name, key_algo, subkey_algo] = - gen_key_info_->GetSupportedKeyAlgo()[index]; + if (gen_subkey_info_ == nullptr) { + gen_subkey_info_ = QSharedPointer<GenKeyInfo>::create(true); + } + + auto [s_found, s_algo] = GenKeyInfo::SearchSubKeyAlgo("cv25519"); + if (s_found) gen_subkey_info_->SetAlgo(s_algo); + } - assert(!key_algo.isEmpty()); - gen_key_info_->SetAlgo(key_algo); + else { + auto [found, algo] = GenKeyInfo::SearchPrimaryKeyAlgo("rsa2048"); + if (found) gen_key_info_->SetAlgo(algo); - if (!subkey_algo.isEmpty()) { if (gen_subkey_info_ == nullptr) { - gen_subkey_info_ = SecureCreateSharedObject<GenKeyInfo>(true); + gen_subkey_info_ = QSharedPointer<GenKeyInfo>::create(true); } - gen_subkey_info_->SetAlgo(subkey_algo); - } else { - gen_subkey_info_ = nullptr; + + auto [s_found, s_algo] = GenKeyInfo::SearchSubKeyAlgo("rsa2048"); + if (s_found) gen_subkey_info_->SetAlgo(s_algo); } refresh_widgets_state(); } -void KeyGenDialog::refresh_widgets_state() { - 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); +void KeyGenDialog::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)); } - 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); + else if (mode == tr("6 Months")) { + gen_key_info_->SetNonExpired(false); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addMonths(6)); } - 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); + else if (mode == tr("1 Year")) { + gen_key_info_->SetNonExpired(false); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addYears(1)); } - 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); + else if (mode == tr("2 Years")) { + gen_key_info_->SetNonExpired(false); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addYears(2)); } - 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); + else if (mode == tr("5 Years")) { + gen_key_info_->SetNonExpired(false); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addYears(5)); } - 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); - } + else if (mode == tr("10 Years")) { + gen_key_info_->SetNonExpired(false); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addYears(10)); - 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() || - (gen_subkey_info_ != nullptr && - gen_subkey_info_->IsAllowChangeAuthentication())) { - key_usage_check_boxes_[3]->setDisabled(false); - } else { - key_usage_check_boxes_[3]->setDisabled(true); + else if (mode == tr("Non Expired")) { + gen_key_info_->SetNonExpired(true); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime()); } - if (gen_key_info_->IsAllowNoPassPhrase()) { - no_pass_phrase_check_box_->setDisabled(false); - } else { - no_pass_phrase_check_box_->setDisabled(true); + else { + gen_key_info_->SetNonExpired(false); + gen_key_info_->SetExpireTime(QDateTime::currentDateTime().addYears(2)); } - if (gen_key_info_->GetSuggestMinKeySize() == -1 || - gen_key_info_->GetSuggestMaxKeySize() == -1) { - key_size_spin_box_->setDisabled(true); - key_size_spin_box_->setRange(0, 0); - key_size_spin_box_->setValue(0); - key_size_spin_box_->setSingleStep(0); - } else { - key_size_spin_box_->setDisabled(false); - key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(), - gen_key_info_->GetSuggestMaxKeySize()); - key_size_spin_box_->setValue(gen_key_info_->GetKeyLength()); - key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep()); + if (gen_subkey_info_ != nullptr) { + gen_subkey_info_->SetExpireTime(gen_key_info_->GetExpireTime()); + gen_subkey_info_->SetNonExpired(gen_key_info_->IsNonExpired()); } -} - -void KeyGenDialog::set_signal_slot() { - connect(button_box_, &QDialogButtonBox::accepted, this, - &KeyGenDialog::slot_key_gen_accept); - connect(button_box_, &QDialogButtonBox::rejected, this, - &KeyGenDialog::reject); - - connect(expire_check_box_, &QCheckBox::stateChanged, this, [this]() { - date_edit_->setDisabled(expire_check_box_->checkState() != 0U); - }); - - connect(key_usage_check_boxes_[0], &QCheckBox::stateChanged, this, - &KeyGenDialog::slot_encryption_box_changed); - connect(key_usage_check_boxes_[1], &QCheckBox::stateChanged, this, - &KeyGenDialog::slot_signing_box_changed); - connect(key_usage_check_boxes_[2], &QCheckBox::stateChanged, this, - &KeyGenDialog::slot_certification_box_changed); - connect(key_usage_check_boxes_[3], &QCheckBox::stateChanged, this, - &KeyGenDialog::slot_authentication_box_changed); - connect(key_type_combo_box_, qOverload<int>(&QComboBox::currentIndexChanged), - this, &KeyGenDialog::slot_activated_key_type); - - connect(no_pass_phrase_check_box_, &QCheckBox::stateChanged, this, - [this](int state) -> void { - gen_key_info_->SetNonPassPhrase(state != 0); - if (gen_subkey_info_ != nullptr) { - gen_subkey_info_->SetNonPassPhrase(state != 0); - } - }); + refresh_widgets_state(); } -auto KeyGenDialog::check_email_address(const QString& str) -> bool { - return re_email_.match(str).hasMatch(); +void KeyGenDialog::slot_set_easy_valid_date_2_custom() { + ui_->easyValidityPeriodComboBox->blockSignals(true); + ui_->easyValidityPeriodComboBox->setCurrentText(tr("Custom")); + ui_->easyValidityPeriodComboBox->blockSignals(false); } -auto KeyGenDialog::create_basic_info_group_box() -> QGroupBox* { - error_label_ = new QLabel(); - name_edit_ = new QLineEdit(this); - email_edit_ = new QLineEdit(this); - comment_edit_ = new QLineEdit(this); - key_size_spin_box_ = new QSpinBox(this); - key_type_combo_box_ = new QComboBox(this); - gpg_contexts_combo_box_ = new QComboBox(this); - - auto gpg_context_index_list = - Module::ListRTChildKeys("core", "gpgme.ctx.list"); - - for (auto& context_index : gpg_context_index_list) { - const auto grt_key_prefix = QString("gpgme.ctx.list.%1").arg(context_index); - auto channel = Module::RetrieveRTValueTypedOrDefault( - "core", grt_key_prefix + ".channel", -1); - auto database_name = Module::RetrieveRTValueTypedOrDefault( - "core", grt_key_prefix + ".database_name", QString{}); - gpg_contexts_combo_box_->addItem( - QString("%1: %2").arg(channel).arg(database_name)); - } - gpg_contexts_combo_box_->setCurrentIndex(default_gpg_context_channel_); - - for (const auto& algo : GenKeyInfo::GetSupportedKeyAlgo()) { - key_type_combo_box_->addItem(std::get<0>(algo)); - } - if (!GenKeyInfo::GetSupportedKeyAlgo().empty()) { - key_type_combo_box_->setCurrentIndex(0); - } - - date_edit_ = - new QDateTimeEdit(QDateTime::currentDateTime().addYears(2), this); - date_edit_->setMinimumDateTime(QDateTime::currentDateTime()); - date_edit_->setMaximumDateTime(max_date_time_); - date_edit_->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); - date_edit_->setCalendarPopup(true); - date_edit_->setEnabled(true); - - expire_check_box_ = new QCheckBox(this); - expire_check_box_->setCheckState(Qt::Unchecked); - - no_pass_phrase_check_box_ = new QCheckBox(this); - no_pass_phrase_check_box_->setCheckState(Qt::Unchecked); - - auto* vbox1 = new QGridLayout; - - vbox1->addWidget(new QLabel(tr("Key Database") + ": "), 0, 0); - vbox1->addWidget(new QLabel(tr("Name") + ": "), 1, 0); - vbox1->addWidget(new QLabel(tr("Email Address") + ": "), 2, 0); - vbox1->addWidget(new QLabel(tr("Comment") + ": "), 3, 0); - vbox1->addWidget(new QLabel(tr("Expiration Date") + ": "), 4, 0); - vbox1->addWidget(new QLabel(tr("Never Expire") + ": "), 4, 3); - vbox1->addWidget(new QLabel(tr("KeySize (in Bit)") + ": "), 5, 0); - vbox1->addWidget(new QLabel(tr("Key Type") + ": "), 6, 0); - vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 7, 0); - - vbox1->addWidget(gpg_contexts_combo_box_, 0, 1, 1, 3); - vbox1->addWidget(name_edit_, 1, 1, 1, 3); - vbox1->addWidget(email_edit_, 2, 1, 1, 3); - vbox1->addWidget(comment_edit_, 3, 1, 1, 3); - vbox1->addWidget(date_edit_, 4, 1); - vbox1->addWidget(expire_check_box_, 4, 2); - vbox1->addWidget(key_size_spin_box_, 5, 1); - vbox1->addWidget(key_type_combo_box_, 6, 1); - vbox1->addWidget(no_pass_phrase_check_box_, 7, 1); - - auto* basic_info_group_box = new QGroupBox(); - basic_info_group_box->setLayout(vbox1); - basic_info_group_box->setTitle(tr("Basic Information")); - - return basic_info_group_box; +void KeyGenDialog::slot_set_easy_key_algo_2_custom() { + ui_->easyAlgoComboBox->blockSignals(true); + ui_->easyAlgoComboBox->setCurrentText(tr("Custom")); + ui_->easyAlgoComboBox->blockSignals(false); } - } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/key_generate/KeygenDialog.h b/src/ui/dialog/key_generate/KeygenDialog.h index dbb5048e..fd827ecd 100644 --- a/src/ui/dialog/key_generate/KeygenDialog.h +++ b/src/ui/dialog/key_generate/KeygenDialog.h @@ -35,6 +35,8 @@ #include "ui/GpgFrontendUI.h" #include "ui/dialog/GeneralDialog.h" +class Ui_KeyGenDialog; + namespace GpgFrontend::UI { /** @@ -61,131 +63,95 @@ class KeyGenDialog : public GeneralDialog { */ void SignalKeyGenerated(); - private: - /** - * @brief Create a key usage group box object - * - * @return QGroupBox* - */ - QGroupBox* create_key_usage_group_box(); + private slots: /** - * @brief Create a basic info group box object - * - * @return QGroupBox* + * @details check all lineedits for false entries. Show error, when there + * is one, otherwise generate the key */ - QGroupBox* create_basic_info_group_box(); + void slot_key_gen_accept(); /** * @brief * + * @param mode */ - QRegularExpression re_email_{ - R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + void slot_easy_mode_changed(const QString& mode); /** * @brief * + * @param mode */ - QStringList error_messages_; ///< List of errors occurring when checking - ///< entries of line edits - - std::shared_ptr<GenKeyInfo> gen_key_info_ = - SecureCreateSharedObject<GenKeyInfo>(); ///< - std::shared_ptr<GenKeyInfo> gen_subkey_info_ = nullptr; ///< - - QDialogButtonBox* button_box_; ///< Box for standard buttons - QLabel* error_label_{}; ///< Label containing error message - QLineEdit* name_edit_{}; ///< Line edit for the keys name - QLineEdit* email_edit_{}; ///< Line edit for the keys email - QLineEdit* comment_edit_{}; ///< Line edit for the keys comment - QSpinBox* key_size_spin_box_{}; ///< Spinbox for the keys size (in bit) - QComboBox* key_type_combo_box_{}; ///< Combobox for Key type - QDateTimeEdit* date_edit_{}; ///< Date edit for expiration date - QCheckBox* expire_check_box_{}; ///< Checkbox, if key should expire - QCheckBox* no_pass_phrase_check_box_{}; - QGroupBox* key_usage_group_box_{}; ///< Group of Widgets detecting the usage - ///< of the Key - QDateTime max_date_time_; ///< - QContainer<QCheckBox*> key_usage_check_boxes_; ///< ENCR, SIGN, CERT, AUTH - QComboBox* gpg_contexts_combo_box_{}; - - int default_gpg_context_channel_; + void slot_easy_valid_date_changed(const QString& mode); /** * @brief * */ - void generate_key_dialog(); + void slot_set_easy_valid_date_2_custom(); /** - * @details Refresh widgets state by GenKeyInfo + * @brief + * */ - void refresh_widgets_state(); + void slot_set_easy_key_algo_2_custom(); + private: /** - * @brief Set the signal slot object + * @brief * */ - void set_signal_slot(); + QRegularExpression re_email_{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; /** * @brief * - * @param str - * @return true - * @return false */ - bool check_email_address(const QString& str); + QStringList error_messages_; ///< List of errors occurring when checking + ///< entries of line edits - private slots: + QSharedPointer<Ui_KeyGenDialog> ui_; + QSharedPointer<GenKeyInfo> gen_key_info_; ///< + QSharedPointer<GenKeyInfo> gen_subkey_info_; ///< - /** - * @details when expirebox was checked/unchecked, enable/disable the - * expiration date box - */ - void slot_expire_box_changed(); + QContainer<KeyAlgo> supported_primary_key_algos_; + QContainer<KeyAlgo> supported_subkey_algos_; - /** - * @details check all lineedits for false entries. Show error, when there is - * one, otherwise generate the key - */ - void slot_key_gen_accept(); + int channel_; /** - * @brief - * - * @param state + * @details Refresh widgets state by GenKeyInfo */ - void slot_encryption_box_changed(int state); + void refresh_widgets_state(); /** - * @brief + * @brief Set the signal slot object * - * @param state */ - void slot_signing_box_changed(int state); + void set_signal_slot_config(); /** * @brief * - * @param state + * @param str + * @return true + * @return false */ - void slot_certification_box_changed(int state); + auto check_email_address(const QString& str) -> bool; /** * @brief * - * @param state */ - void slot_authentication_box_changed(int state); + void sync_gen_key_info(); /** * @brief * - * @param index */ - void slot_activated_key_type(int index); + void sync_gen_subkey_info(); }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp index 527d335b..b55e4b28 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp @@ -128,7 +128,7 @@ QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { no_pass_phrase_check_box_ = new QCheckBox(this); for (const auto& algo : GenKeyInfo::GetSupportedSubkeyAlgo()) { - key_type_combo_box_->addItem(std::get<0>(algo)); + key_type_combo_box_->addItem(algo.Name()); } if (!GenKeyInfo::GetSupportedSubkeyAlgo().empty()) { key_type_combo_box_->setCurrentIndex(0); @@ -249,20 +249,6 @@ void SubkeyGenerateDialog::refresh_widgets_state() { } else { key_usage_check_boxes_[3]->setDisabled(true); } - - if (gen_key_info_->GetSuggestMinKeySize() == -1 || - gen_key_info_->GetSuggestMaxKeySize() == -1) { - key_size_spin_box_->setDisabled(true); - key_size_spin_box_->setRange(0, 0); - key_size_spin_box_->setValue(0); - key_size_spin_box_->setSingleStep(0); - } else { - key_size_spin_box_->setDisabled(false); - key_size_spin_box_->setRange(gen_key_info_->GetSuggestMinKeySize(), - gen_key_info_->GetSuggestMaxKeySize()); - key_size_spin_box_->setValue(gen_key_info_->GetKeyLength()); - key_size_spin_box_->setSingleStep(gen_key_info_->GetSizeChangeStep()); - } } void SubkeyGenerateDialog::slot_key_gen_accept() { @@ -280,8 +266,6 @@ void SubkeyGenerateDialog::slot_key_gen_accept() { auto err_string = err_stream.readAll(); if (err_string.isEmpty()) { - gen_key_info_->SetKeyLength(key_size_spin_box_->value()); - if (expire_check_box_->checkState() != 0U) { gen_key_info_->SetNonExpired(true); } else { @@ -364,8 +348,7 @@ void SubkeyGenerateDialog::slot_activated_key_type(int index) { // check assert(gen_key_info_->GetSupportedSubkeyAlgo().size() > static_cast<size_t>(index)); - gen_key_info_->SetAlgo( - std::get<2>(gen_key_info_->GetSupportedSubkeyAlgo()[index])); + gen_key_info_->SetAlgo(gen_key_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 fc3c51c9..b8c525bd 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h @@ -60,8 +60,8 @@ class SubkeyGenerateDialog : public GeneralDialog { int current_gpg_context_channel_; ///< GpgKey key_; ///< - std::shared_ptr<GenKeyInfo> gen_key_info_ = - SecureCreateSharedObject<GenKeyInfo>(true); ///< + QSharedPointer<GenKeyInfo> gen_key_info_ = + QSharedPointer<GenKeyInfo>::create(true); ///< QGroupBox* key_usage_group_box_{}; QDialogButtonBox* button_box_; ///< Box for standard buttons @@ -80,14 +80,14 @@ class SubkeyGenerateDialog : public GeneralDialog { * * @return QGroupBox* */ - QGroupBox* create_key_usage_group_box(); + auto create_key_usage_group_box() -> QGroupBox*; /** * @brief Create a basic info group box object * * @return QGroupBox* */ - QGroupBox* create_basic_info_group_box(); + auto create_basic_info_group_box() -> QGroupBox*; /** * @brief Set the signal slot object * diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp index 2a027bfd..f4b06f86 100644 --- a/src/ui/main_window/KeyMgmt.cpp +++ b/src/ui/main_window/KeyMgmt.cpp @@ -41,7 +41,7 @@ #include "ui/UserInterfaceUtils.h" #include "ui/dialog/import_export/ExportKeyPackageDialog.h" #include "ui/dialog/import_export/KeyImportDetailDialog.h" -#include "ui/dialog/key_generate/KeygenDialog.h" +#include "ui/dialog/key_generate/KeyGenDialog.h" #include "ui/dialog/key_generate/SubkeyGenerateDialog.h" #include "ui/dialog/keypair_details/KeyDetailsDialog.h" #include "ui/function/GpgOperaHelper.h" diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index c8c68aef..acc8f5a8 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -33,9 +33,11 @@ #include "core/model/SettingsObject.h" #include "ui/UserInterfaceUtils.h" #include "ui/dialog/Wizard.h" +#include "ui/dialog/settings/SettingsDialog.h" #include "ui/main_window/KeyMgmt.h" #include "ui/struct/settings_object/AppearanceSO.h" #include "ui/widgets/TextEdit.h" + namespace GpgFrontend::UI { void MainWindow::SlotSetStatusBarText(const QString& text) { diff --git a/ui/KeyGenDialog.ui b/ui/KeyGenDialog.ui new file mode 100644 index 00000000..254cdb92 --- /dev/null +++ b/ui/KeyGenDialog.ui @@ -0,0 +1,355 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>KeyGenDialog</class> + <widget class="QDialog" name="KeyGenDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>475</width> + <height>568</height> + </rect> + </property> + <property name="windowTitle"> + <string>Key Generation</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="leftMargin"> + <number>5</number> + </property> + <property name="topMargin"> + <number>5</number> + </property> + <property name="rightMargin"> + <number>5</number> + </property> + <property name="bottomMargin"> + <number>5</number> + </property> + <item> + <layout class="QGridLayout" name="gridLayout_3"> + <property name="topMargin"> + <number>5</number> + </property> + <item row="4" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Comment</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Email</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Name</string> + </property> + </widget> + </item> + <item row="2" column="1" colspan="2"> + <widget class="QLineEdit" name="nameEdit"/> + </item> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="commentEdit"/> + </item> + <item row="3" column="1" colspan="2"> + <widget class="QLineEdit" name="emailEdit"/> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Key Database</string> + </property> + </widget> + </item> + <item row="5" column="1" colspan="2"> + <widget class="QComboBox" name="keyDBIndexComboBox"/> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="tabPosition"> + <enum>QTabWidget::TabPosition::North</enum> + </property> + <property name="currentIndex"> + <number>0</number> + </property> + <property name="documentMode"> + <bool>true</bool> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Easy Mode</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="4" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Validity Period</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="easyAlgoComboBox"/> + </item> + <item row="4" column="1" colspan="2"> + <widget class="QComboBox" name="easyValidityPeriodComboBox"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Algorithm</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Orientation::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Primary Key</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="3" column="0"> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>Key Length</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Validity Period</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Algorithm</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Usage</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="pAlgoComboBox"/> + </item> + <item row="4" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QCheckBox" name="pEncrCheckBox"> + <property name="text"> + <string>Encrypt</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="pSignCheckBox"> + <property name="text"> + <string>Sign</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="pAuthCheckBox"> + <property name="text"> + <string>Authentication</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="3" column="1" colspan="2"> + <widget class="QComboBox" name="pKeyLengthComboBox"/> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QDateTimeEdit" name="pValidityPeriodDateTimeEdit"/> + </item> + <item row="5" column="0" colspan="3"> + <widget class="QCheckBox" name="noPassphraseCheckBox"> + <property name="text"> + <string>No Passphrase</string> + </property> + </widget> + </item> + <item row="6" column="0" colspan="3"> + <widget class="QCheckBox" name="pExpireCheckBox"> + <property name="text"> + <string>Non Expired</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Orientation::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_3"> + <attribute name="title"> + <string>Subkey</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="1" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Validity Period</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>Usage</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QDateTimeEdit" name="sValidityPeriodDateTimeEdit"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>Key Length</string> + </property> + </widget> + </item> + <item row="3" column="1" colspan="2"> + <widget class="QComboBox" name="sKeyLengthComboBox"/> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="sAlgoComboBox"/> + </item> + <item row="4" column="1" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QCheckBox" name="sEncrCheckBox"> + <property name="text"> + <string>Encrypt</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="sSignCheckBox"> + <property name="text"> + <string>Sign</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="sAuthCheckBox"> + <property name="text"> + <string>Authentication</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Algorithm</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="3"> + <widget class="QCheckBox" name="sExpireCheckBox"> + <property name="text"> + <string>Non Expired</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Orientation::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QPlainTextEdit" name="statusPlainTextEdit"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="generateButton"> + <property name="text"> + <string>Generate</string> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> |