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 /src/ui/dialog/key_generate/KeygenDialog.cpp | |
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
Diffstat (limited to 'src/ui/dialog/key_generate/KeygenDialog.cpp')
-rw-r--r-- | src/ui/dialog/key_generate/KeygenDialog.cpp | 807 |
1 files changed, 459 insertions, 348 deletions
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 |