diff options
author | Saturneric <[email protected]> | 2021-05-29 19:28:40 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-05-29 19:28:40 +0000 |
commit | fe67bfb777a79b25149efa3e045dc043dc144ad0 (patch) | |
tree | 4d75a10f210b86d7e116d188569bc08e4e72adb7 /src/ui/keygen/KeygenDialog.cpp | |
parent | Make eligible keys enter the signature candidate list. (diff) | |
download | GpgFrontend-fe67bfb777a79b25149efa3e045dc043dc144ad0.tar.gz GpgFrontend-fe67bfb777a79b25149efa3e045dc043dc144ad0.zip |
New page and function for generating subkeys.
Define the interface and functions of the subkey management tab.
When there is an item in the UID list, the first item is selected by default.
Compile the API for generating sub-keys and the corresponding calling thread.
Set GpgGenKeyInfo to apply to the subkey
Generate a subkey for the selected key pair of the management key pair interface.
Adjust the project structure and add a new classification key generation category.
Double-click the item in KeyList in the key pair management interface to enter the key details page.
Adjust the title of the key pair management interface.
Optimize part of the code of KeyGenThread.
Signed-off-by: Saturneric <[email protected]>
Diffstat (limited to 'src/ui/keygen/KeygenDialog.cpp')
-rw-r--r-- | src/ui/keygen/KeygenDialog.cpp | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/src/ui/keygen/KeygenDialog.cpp b/src/ui/keygen/KeygenDialog.cpp new file mode 100644 index 00000000..347ebedc --- /dev/null +++ b/src/ui/keygen/KeygenDialog.cpp @@ -0,0 +1,374 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "ui/keygen/KeygenDialog.h" + +KeyGenDialog::KeyGenDialog(GpgME::GpgContext *ctx, QWidget *parent) + : QDialog(parent), mCtx(ctx) { + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + this->setWindowTitle(tr("Generate Key")); + this->setModal(true); + generateKeyDialog(); +} + +void KeyGenDialog::generateKeyDialog() { + + keyUsageGroupBox = create_key_usage_group_box(); + + auto *groupGrid = new QGridLayout(this); + groupGrid->addWidget(create_basic_info_group_box(), 0, 0); + groupGrid->addWidget(keyUsageGroupBox, 1, 0); + + auto *nameList = new QWidget(this); + nameList->setLayout(groupGrid); + + auto *vbox2 = new QVBoxLayout(); + vbox2->addWidget(nameList); + vbox2->addWidget(errorLabel); + vbox2->addWidget(buttonBox); + + this->setLayout(vbox2); + + set_signal_slot(); + + refresh_widgets_state(); + +} + +void KeyGenDialog::slotKeyGenAccept() { + QString errorString = ""; + + /** + * check for errors in keygen dialog input + */ + if ((nameEdit->text()).size() < 5) { + errorString.append(tr(" Name must contain at least five characters. \n")); + } if(emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) { + errorString.append(tr(" Please give a email address. \n")); + } + + /** + * primary keys should have a reasonable expiration date (no more than 2 years in the future) + */ + if(dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) { + + errorString.append(tr(" Expiration time no more than 2 years. ")); + } + + if (errorString.isEmpty()) { + /** + * create the string for key generation + */ + + genKeyInfo.setUserid(QString("%1 (%3) <%2>").arg(nameEdit->text(), emailEdit->text(), commentEdit->text())); + + genKeyInfo.setKeySize(keySizeSpinBox->value()); + + if (expireCheckBox->checkState()) { + genKeyInfo.setNonExpired(true); + } else { + genKeyInfo.setExpired(dateEdit->dateTime()); + } + + kg = new KeyGenThread(&genKeyInfo, mCtx); + connect(kg, SIGNAL(signalKeyGenerated(bool)), this, SLOT(slotKeyGenResult(bool))); + kg->start(); + + this->accept(); + + auto *dialog = new QDialog(this, Qt::CustomizeWindowHint | Qt::WindowTitleHint); + dialog->setModal(true); + dialog->setWindowTitle(tr("Generating Key...")); + + auto *waitMessage = new QLabel( + tr("Collecting random data for key generation.\n This may take a while.\n To speed up the process use your computer\n (e.g. browse the net, listen to music,...)")); + auto *pb = new QProgressBar(); + pb->setRange(0, 0); + + auto *layout = new QVBoxLayout(dialog); + layout->addWidget(waitMessage); + layout->addWidget(pb); + dialog->setLayout(layout); + + dialog->show(); + + while (kg->isRunning()) { + QCoreApplication::processEvents(); + } + + dialog->close(); + + } else { + /** + * create error message + */ + errorLabel->setAutoFillBackground(true); + QPalette error = errorLabel->palette(); + error.setColor(QPalette::Background, "#ff8080"); + errorLabel->setPalette(error); + errorLabel->setText(errorString); + + this->show(); + } +} + +void KeyGenDialog::slotExpireBoxChanged() { + if (expireCheckBox->checkState()) { + dateEdit->setEnabled(false); + } else { + dateEdit->setEnabled(true); + } +} + +QGroupBox *KeyGenDialog::create_key_usage_group_box() { + + auto *groupBox = new QGroupBox(this); + auto *grid = new QGridLayout(this); + + groupBox->setTitle("Key Usage"); + + auto* encrypt = new QCheckBox(tr("Encryption"), groupBox); + encrypt->setTristate(false); + + auto* sign = new QCheckBox(tr("Signing"),groupBox); + sign->setTristate(false); + + auto* cert = new QCheckBox(tr("Certification"),groupBox); + cert->setTristate(false); + + auto* auth = new QCheckBox(tr("Authentication"), groupBox); + auth->setTristate(false); + + keyUsageCheckBoxes.push_back(encrypt); + keyUsageCheckBoxes.push_back(sign); + keyUsageCheckBoxes.push_back(cert); + keyUsageCheckBoxes.push_back(auth); + + grid->addWidget(encrypt, 0, 0); + grid->addWidget(sign, 0, 1); + grid->addWidget(cert, 1, 0); + grid->addWidget(auth, 1, 1); + + groupBox->setLayout(grid); + + return groupBox; +} + +void KeyGenDialog::slotEncryptionBoxChanged(int state) { + if(state == 0) { + genKeyInfo.setAllowEncryption(false); + } else { + genKeyInfo.setAllowEncryption(true); + } +} + +void KeyGenDialog::slotSigningBoxChanged(int state) { + if(state == 0) { + genKeyInfo.setAllowSigning(false); + } else { + genKeyInfo.setAllowSigning(true); + } +} + +void KeyGenDialog::slotCertificationBoxChanged(int state) { + if(state == 0) { + genKeyInfo.setAllowCertification(false); + } else { + genKeyInfo.setAllowCertification(true); + } +} + +void KeyGenDialog::slotAuthenticationBoxChanged(int state) { + if(state == 0) { + genKeyInfo.setAllowAuthentication(false); + } else { + genKeyInfo.setAllowAuthentication(true); + } +} + +void KeyGenDialog::slotActivatedKeyType(int index) { + + qDebug() << "key type index changed " << index; + + genKeyInfo.setAlgo(this->keyTypeComboBox->itemText(index)); + refresh_widgets_state(); +} + +void KeyGenDialog::refresh_widgets_state() { + + qDebug() << "refresh_widgets_state called"; + + if(genKeyInfo.isAllowEncryption()) + keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked); + + if(genKeyInfo.isAllowChangeEncryption()) + keyUsageCheckBoxes[0]->setDisabled(false); + else + keyUsageCheckBoxes[0]->setDisabled(true); + + + if(genKeyInfo.isAllowSigning()) + keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked); + + if(genKeyInfo.isAllowChangeSigning()) + keyUsageCheckBoxes[1]->setDisabled(false); + else + keyUsageCheckBoxes[1]->setDisabled(true); + + + if(genKeyInfo.isAllowCertification()) + keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked); + + if(genKeyInfo.isAllowChangeCertification()) + keyUsageCheckBoxes[2]->setDisabled(false); + else + keyUsageCheckBoxes[2]->setDisabled(true); + + + if(genKeyInfo.isAllowAuthentication()) + keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked); + + if(genKeyInfo.isAllowChangeAuthentication()) + keyUsageCheckBoxes[3]->setDisabled(false); + else + keyUsageCheckBoxes[3]->setDisabled(true); + + + + if(genKeyInfo.isAllowNoPassPhrase()) + noPassPhraseCheckBox->setDisabled(false); + else + noPassPhraseCheckBox->setDisabled(true); + + + keySizeSpinBox->setRange(genKeyInfo.getSuggestMinKeySize(), genKeyInfo.getSuggestMaxKeySize()); + keySizeSpinBox->setValue(genKeyInfo.getKeySize()); + keySizeSpinBox->setSingleStep(genKeyInfo.getSizeChangeStep()); + + +} + +void KeyGenDialog::set_signal_slot() { + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(expireCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotExpireBoxChanged())); + + connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, SLOT(slotEncryptionBoxChanged(int))); + connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, SLOT(slotSigningBoxChanged(int))); + connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, SLOT(slotCertificationBoxChanged(int))); + connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, SLOT(slotAuthenticationBoxChanged(int))); + + connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotActivatedKeyType(int))); + + connect(noPassPhraseCheckBox, &QCheckBox::stateChanged, this, [this](int state) -> void { + if(state == 0) { + genKeyInfo.setNonPassPhrase(false); + } else { + genKeyInfo.setNonPassPhrase(true); + } + + }); + +} + +bool KeyGenDialog::check_email_address(const QString &str) { + return re_email.match(str).hasMatch(); +} + +void KeyGenDialog::slotKeyGenResult(bool success) { + if(success) + QMessageBox::information(nullptr, tr("Success"), tr("The new key pair has been generated.")); + else + QMessageBox::critical(nullptr, tr("Failure"), tr("An error occurred during key generation.")); +} + +QGroupBox *KeyGenDialog::create_basic_info_group_box() { + + errorLabel = new QLabel(tr("")); + nameEdit = new QLineEdit(this); + emailEdit = new QLineEdit(this); + commentEdit = new QLineEdit(this); + keySizeSpinBox = new QSpinBox(this); + keyTypeComboBox = new QComboBox(this); + + for(auto &algo : GenKeyInfo::SupportedKeyAlgo) { + keyTypeComboBox->addItem(algo); + } + if(!GenKeyInfo::SupportedKeyAlgo.isEmpty()) { + keyTypeComboBox->setCurrentIndex(0); + } + + QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); + + dateEdit = new QDateTimeEdit(maxDateTime, this); + dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); + dateEdit->setMaximumDateTime(maxDateTime); + dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); + dateEdit->setCalendarPopup(true); + dateEdit->setEnabled(true); + + expireCheckBox = new QCheckBox(this); + expireCheckBox->setCheckState(Qt::Unchecked); + + noPassPhraseCheckBox = new QCheckBox(this); + noPassPhraseCheckBox->setCheckState(Qt::Unchecked); + + auto *vbox1 = new QGridLayout; + + vbox1->addWidget(new QLabel(tr("Name:")), 0, 0); + vbox1->addWidget(new QLabel(tr("Email Address:")), 1, 0); + vbox1->addWidget(new QLabel(tr("Comment:")), 2, 0); + vbox1->addWidget(new QLabel(tr("Expiration Date:")), 3, 0); + vbox1->addWidget(new QLabel(tr("Never Expire")), 3, 3); + vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 4, 0); + vbox1->addWidget(new QLabel(tr("Key Type:")), 5, 0); + vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 6, 0); + + vbox1->addWidget(nameEdit, 0, 1, 1, 3); + vbox1->addWidget(emailEdit, 1, 1, 1, 3); + vbox1->addWidget(commentEdit, 2, 1, 1, 3); + vbox1->addWidget(dateEdit, 3, 1); + vbox1->addWidget(expireCheckBox, 3, 2); + vbox1->addWidget(keySizeSpinBox, 4, 1); + vbox1->addWidget(keyTypeComboBox, 5, 1); + vbox1->addWidget(noPassPhraseCheckBox, 6, 1); + + auto basicInfoGroupBox = new QGroupBox(); + basicInfoGroupBox->setLayout(vbox1); + basicInfoGroupBox->setTitle(tr("Basic Information")); + + return basicInfoGroupBox; +} |