aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/gpg/GpgContext.h2
-rw-r--r--include/gpg/GpgGenKeyInfo.h253
-rw-r--r--include/ui/KeygenDialog.h50
-rw-r--r--include/ui/KeygenThread.h6
-rw-r--r--src/gpg/GpgContext.cpp56
-rw-r--r--src/ui/KeygenDialog.cpp274
-rw-r--r--src/ui/KeygenThread.cpp13
7 files changed, 570 insertions, 84 deletions
diff --git a/include/gpg/GpgContext.h b/include/gpg/GpgContext.h
index 71c857ad..95b61f93 100644
--- a/include/gpg/GpgContext.h
+++ b/include/gpg/GpgContext.h
@@ -99,7 +99,7 @@ namespace GpgME {
bool exportKeys(QStringList *uidList, QByteArray *outBuffer);
- void generateKey(GenKeyInfo *params);
+ bool generateKey(GenKeyInfo *params);
GpgKeyList listKeys();
diff --git a/include/gpg/GpgGenKeyInfo.h b/include/gpg/GpgGenKeyInfo.h
index 397123d9..ab416b81 100644
--- a/include/gpg/GpgGenKeyInfo.h
+++ b/include/gpg/GpgGenKeyInfo.h
@@ -8,16 +8,257 @@
#include <QString>
#include <QTime>
-struct GenKeyInfo {
- bool isSubKey = false;
+class GenKeyInfo {
+
+ bool subKey = true;
QString userid;
QString algo;
- int keySize;
- QDateTime expired;
+ int keySize = 2048;
+ QDateTime expired = QDateTime::currentDateTime().addYears(2);
bool nonExpired = false;
- bool allowSigning = true;
- bool allowEncryption = true;
+
+ bool noPassPhrase = false;
+ bool allowNoPassPhrase = true;
+
+ int suggestMaxKeySize = 1024;
+ int suggestSizeAdditionStep = 1024;
+ int suggestMinKeySize = 4096;
+
QString passPhrase;
+
+public:
+
+ static const QVector<QString> SupportedAlgo;
+
+ [[nodiscard]] bool isSubKey() const {
+ return subKey;
+ }
+
+ void setIsSubKey(bool m_sub_key) {
+ GenKeyInfo::subKey = m_sub_key;
+ }
+
+ [[nodiscard]] const QString &getUserid() const {
+ return userid;
+ }
+
+ void setUserid(const QString &m_userid) {
+ GenKeyInfo::userid = m_userid;
+ }
+
+ [[nodiscard]] const QString &getAlgo() const {
+ return algo;
+ }
+
+ void setAlgo(const QString &m_algo) {
+
+ qDebug() << "set algo " << m_algo;
+
+ reset_options();
+
+ if (!this->subKey) {
+ this->setAllowCertification(true);
+ this->allowChangeCertification = false;
+ }
+
+ auto lower_algo = m_algo.toLower();
+
+ if(lower_algo == "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.
+ */
+ suggestMinKeySize = 1024;
+ suggestMaxKeySize = 4096;
+ suggestSizeAdditionStep = 1024;
+ setKeySize(2048);
+
+ } else if (lower_algo == "dsa") {
+ /**
+ * 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);
+ allowChangeEncryption = false;
+ setAllowAuthentication(false);
+ allowChangeAuthentication = false;
+
+ suggestMinKeySize = 1024;
+ suggestMaxKeySize = 3072;
+ suggestSizeAdditionStep = 1024;
+ setKeySize(2048);
+
+ } else if (lower_algo == "elg") {
+ /**
+ * GnuPG supports the Elgamal asymmetric encryption algorithm in key lengths ranging from 1024 to 4096 bits.
+ */
+ suggestMinKeySize = 1024;
+ suggestMaxKeySize = 4096;
+ suggestSizeAdditionStep = 1024;
+ setKeySize(2048);
+ }
+ GenKeyInfo::algo = lower_algo;
+ }
+
+ [[nodiscard]] int getKeySize() const {
+ return keySize;
+ }
+
+ void setKeySize(int m_key_size) {
+ if (m_key_size < 0 || m_key_size > 8192) {
+ return;
+ }
+ GenKeyInfo::keySize = m_key_size;
+ }
+
+ [[nodiscard]] const QDateTime &getExpired() const {
+ return expired;
+ }
+
+ void setExpired(const QDateTime &m_expired) {
+ auto current = QDateTime::currentDateTime();
+ if (isNonExpired() && m_expired < current.addYears(2)) {
+ GenKeyInfo::expired = m_expired;
+ }
+ }
+
+ [[nodiscard]] bool isNonExpired() const {
+ return nonExpired;
+ }
+
+ void setNonExpired(bool m_non_expired) {
+ if (!m_non_expired) {
+ this->expired = QDateTime(QDateTime::fromTime_t(0));
+ }
+ GenKeyInfo::nonExpired = m_non_expired;
+ }
+
+ [[nodiscard]] bool isNoPassPhrase() const {
+ return this->noPassPhrase;
+ }
+
+ void setNonPassPhrase(bool m_non_pass_phrase) {
+ GenKeyInfo::noPassPhrase = true;
+ }
+
+ [[nodiscard]] bool isAllowSigning() const {
+ return allowSigning;
+ }
+
+ [[nodiscard]] bool isAllowNoPassPhrase() const {
+ return allowNoPassPhrase;
+ }
+
+ void setAllowSigning(bool m_allow_signing) {
+ if(allowChangeSigning)
+ GenKeyInfo::allowSigning = m_allow_signing;
+ }
+
+ [[nodiscard]] bool isAllowEncryption() const {
+ return allowEncryption;
+ }
+
+ void setAllowEncryption(bool m_allow_encryption) {
+ if(allowChangeEncryption)
+ GenKeyInfo::allowEncryption = m_allow_encryption;
+ }
+
+ [[nodiscard]] bool isAllowCertification() const {
+ return allowCertification;
+ }
+
+ void setAllowCertification(bool m_allow_certification) {
+ if(allowChangeCertification)
+ GenKeyInfo::allowCertification = m_allow_certification;
+ }
+
+ [[nodiscard]] bool isAllowAuthentication() const {
+ return allowAuthentication;
+ }
+
+ void setAllowAuthentication(bool m_allow_authentication) {
+ if(allowChangeAuthentication)
+ GenKeyInfo::allowAuthentication = m_allow_authentication;
+ }
+
+ [[nodiscard]] const QString &getPassPhrase() const {
+ return passPhrase;
+ }
+
+ void setPassPhrase(const QString &m_pass_phrase) {
+ GenKeyInfo::passPhrase = m_pass_phrase;
+ }
+
+ [[nodiscard]] bool isAllowChangeSigning() const {
+ return allowChangeSigning;
+ }
+ [[nodiscard]] bool isAllowChangeEncryption() const {
+ return allowChangeEncryption;
+ }
+
+ [[nodiscard]] bool isAllowChangeCertification() const {
+ return allowChangeCertification;
+ }
+
+ [[nodiscard]] bool isAllowChangeAuthentication() const {
+ return allowChangeAuthentication;
+ }
+
+ [[nodiscard]] int getSuggestMaxKeySize() const {
+ return suggestMaxKeySize;
+ }
+
+ [[nodiscard]] int getSuggestMinKeySize() const {
+ return suggestMinKeySize;
+ }
+
+ [[nodiscard]] int getSizeChangeStep() const {
+ return suggestSizeAdditionStep;
+ }
+
+
+private:
+ bool allowEncryption = true;
+ bool allowChangeEncryption = true;
+
+ bool allowCertification = true;
+ bool allowChangeCertification = true;
+
+ bool allowAuthentication = true;
+ bool allowChangeAuthentication = true;
+
+ bool allowSigning = true;
+ bool allowChangeSigning = true;
+
+ void reset_options() {
+
+ allowChangeEncryption = true;
+ setAllowEncryption(true);
+
+ allowChangeCertification = true;
+ setAllowCertification(true);
+
+ allowChangeSigning = true;
+ setAllowSigning(true);
+
+ allowChangeAuthentication = true;
+ setAllowAuthentication(true);
+
+
+ passPhrase.clear();
+
+ }
+
+public:
+
+ explicit GenKeyInfo(bool m_is_sub_key = false) : subKey(m_is_sub_key) {
+ setAlgo("rsa");
+ }
+
+
};
#endif //GPG4USB_GPGGENKEYINFO_H
diff --git a/include/ui/KeygenDialog.h b/include/ui/KeygenDialog.h
index cca92830..933f8bbe 100644
--- a/include/ui/KeygenDialog.h
+++ b/include/ui/KeygenDialog.h
@@ -42,18 +42,17 @@ public:
explicit KeyGenDialog(GpgME::GpgContext *ctx, QWidget *parent = nullptr);
private:
- void generateKeyDialog();
- /**
- * @details Check the password strength of the text in the passwordEdit member
- *
- * @return digit between 0 and 6, the higher the more secure is the password
- */
- int checkPassWordStrength();
+ QGroupBox *create_key_usage_group_box();
+
+ 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])+)\]))"};
GpgME::GpgContext *mCtx; /** The current gpg context */
__attribute__((unused)) KeyGenThread *keyGenThread{}; /** Thread for key generation */
__attribute__((unused)) QStringList errorMessages; /** List of errors occuring when checking entries of lineedits */
+ GenKeyInfo genKeyInfo{};
+
QDialogButtonBox *buttonBox; /** Box for standardbuttons */
QLabel *errorLabel{}; /** Label containing error message */
QLineEdit *nameEdit{}; /** Lineedit for the keys name */
@@ -65,8 +64,35 @@ private:
QComboBox *keyTypeComboBox{}; /** Combobox for Keytpe */
QDateTimeEdit *dateEdit{}; /** Dateedit for expiration date */
QCheckBox *expireCheckBox{}; /** Checkbox, if key should expire */
+ QCheckBox *noPassPhraseCheckBox{};
QSlider *pwStrengthSlider{}; /** Slider showing the password strength */
+ QGroupBox *keyUsageGroupBox{}; /** Group of Widgets detecting the usage of the Key **/
+
+// ENCR, SIGN, CERT, AUTH
+ std::vector<QCheckBox *> keyUsageCheckBoxes;
+
+ KeyGenThread *kg = nullptr;
+
+ void generateKeyDialog();
+
+ /**
+ * @details Check the password strength of the text in the passwordEdit member
+ *
+ * @return digit between 0 and 6, the higher the more secure is the password
+ */
+ int checkPassWordStrength();
+
+
+ /**
+ * @details Refresh widgets state by GenKeyInfo
+ */
+ void refresh_widgets_state();
+
+ void set_signal_slot();
+
+ bool check_email_address(const QString &str);
+
private slots:
/**
@@ -84,6 +110,16 @@ private slots:
*/
void slotKeyGenAccept();
+ void slotEncryptionBoxChanged(int state);
+
+ void slotSigningBoxChanged(int state);
+
+ void slotCertificationBoxChanged(int state);
+
+ void slotAuthenticationBoxChanged(int state);
+
+ void slotActivatedKeyType(int index);
+
};
#endif // __KEYGENDIALOG_H__
diff --git a/include/ui/KeygenThread.h b/include/ui/KeygenThread.h
index 467d8338..5f73efdb 100644
--- a/include/ui/KeygenThread.h
+++ b/include/ui/KeygenThread.h
@@ -34,14 +34,14 @@ class KeyGenThread : public QThread {
Q_OBJECT
public:
- KeyGenThread(GenKeyInfo keyGenParams, GpgME::GpgContext *ctx);
+ KeyGenThread(GenKeyInfo *keyGenParams, GpgME::GpgContext *ctx);
signals:
- void signalKeyGenerated();
+ void signalKeyGenerated(bool success);
private:
- GenKeyInfo keyGenParams;
+ GenKeyInfo *keyGenParams;
GpgME::GpgContext *mCtx;
[[maybe_unused]] bool abort;
QMutex mutex;
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
index a42861a6..08cafe0c 100644
--- a/src/gpg/GpgContext.cpp
+++ b/src/gpg/GpgContext.cpp
@@ -20,11 +20,20 @@
*/
#include "gpg/GpgContext.h"
+#include "ui/KeygenThread.h"
+
#include <unistd.h> /* contains read/write */
#ifdef _WIN32
#include <windows.h>
#endif
+
+const QVector<QString> GenKeyInfo::SupportedAlgo = {
+ "RSA",
+ "DSA",
+ "ELG"
+};
+
namespace GpgME {
/** Constructor
@@ -74,7 +83,7 @@ namespace GpgME {
if (accKeydbPath != "") {
if (!QDir(qGpgKeys).exists()) {
- QMessageBox::critical(0, tr("keydb path"),
+ QMessageBox::critical(nullptr, tr("keydb path"),
tr("Didn't find keydb directory. Switching to gpg4usb's default keydb directory for this session."));
qGpgKeys = appPath + "/keydb";
}
@@ -122,7 +131,7 @@ namespace GpgME {
*/
GpgContext::~GpgContext() {
if (mCtx) gpgme_release(mCtx);
- mCtx = 0;
+ mCtx = nullptr;
}
/** Import Key from QByteArray
@@ -195,35 +204,48 @@ namespace GpgME {
/** Generate New Key with values params
*
*/
- void GpgContext::generateKey(GenKeyInfo *params) {
- auto userid_utf8 = params->userid.toUtf8();
+ bool GpgContext::generateKey(GenKeyInfo *params) {
+
+ auto userid_utf8 = params->getUserid().toUtf8();
const char *userid = userid_utf8.constData();
- auto algo_utf8 = (params->algo + QString::number(params->keySize)).toUtf8();
+ auto algo_utf8 = (params->getAlgo() + QString::number(params->getKeySize())).toUtf8();
const char *algo = algo_utf8.constData();
- unsigned long expires = params->expired.toTime_t();
+ unsigned long expires = params->getExpired().toTime_t();
unsigned int flags = 0;
- if(!params->isSubKey) {
+ if(!params->isSubKey()) {
flags |= GPGME_CREATE_CERT;
+ }
+
+ if(params->isAllowEncryption()) {
flags |= GPGME_CREATE_ENCR;
- } else {
- if(params->allowEncryption) {
- flags |= GPGME_CREATE_ENCR;
- }
}
- if(params->allowSigning) {
+ if(params->isAllowSigning()) {
flags |= GPGME_CREATE_SIGN;
}
- if(params->nonExpired) {
+ if(params->isAllowAuthentication()) {
+ flags |= GPGME_CREATE_AUTH;
+ }
+
+ if(params->isNonExpired()) {
flags |= GPGME_CREATE_NOEXPIRE;
}
+ if(params->isNoPassPhrase()) {
+ flags |= GPGME_CREATE_NOPASSWD;
+ }
+
err = gpgme_op_createkey(mCtx, userid, algo, 0, expires, nullptr, flags);
- checkErr(err);
- emit signalKeyDBChanged();
+ if(err != GPG_ERR_NO_ERROR) {
+ checkErr(err);
+ return false;
+ } else {
+ emit signalKeyDBChanged();
+ return true;
+ }
}
/** Export Key to QByteArray
@@ -564,8 +586,8 @@ namespace GpgME {
void GpgContext::checkErr(gpgme_error_t gpgmeError, const QString& comment) {
//if (gpgmeError != GPG_ERR_NO_ERROR && gpgmeError != GPG_ERR_CANCELED) {
if (gpgmeError != GPG_ERR_NO_ERROR) {
- qDebug() << "[Error " << comment << "] Source: " << gpgme_strsource(gpgmeError) << " String: "
- << gpgErrString(gpgmeError);
+ qDebug() << "[Error "<< gpg_err_code(gpgmeError)
+ <<"] Source: " << gpgme_strsource(gpgmeError) << " Description: " << gpgErrString(gpgmeError);
}
}
diff --git a/src/ui/KeygenDialog.cpp b/src/ui/KeygenDialog.cpp
index 5f29836f..a9a960b3 100644
--- a/src/ui/KeygenDialog.cpp
+++ b/src/ui/KeygenDialog.cpp
@@ -23,8 +23,7 @@
#include "ui/KeygenDialog.h"
KeyGenDialog::KeyGenDialog(GpgME::GpgContext *ctx, QWidget *parent)
- : QDialog(parent) {
- mCtx = ctx;
+ : QDialog(parent), mCtx(ctx) {
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
this->setWindowTitle(tr("Generate Key"));
@@ -33,27 +32,29 @@ KeyGenDialog::KeyGenDialog(GpgME::GpgContext *ctx, QWidget *parent)
}
void KeyGenDialog::generateKeyDialog() {
+
+ keyUsageGroupBox = create_key_usage_group_box();
+
errorLabel = new QLabel(tr(""));
nameEdit = new QLineEdit(this);
emailEdit = new QLineEdit(this);
commentEdit = new QLineEdit(this);
-
keySizeSpinBox = new QSpinBox(this);
- keySizeSpinBox->setRange(1024, 4096);
- keySizeSpinBox->setValue(3072);
+ keyTypeComboBox = new QComboBox(this);
- keySizeSpinBox->setSingleStep(1024);
+ for(auto &algo : GenKeyInfo::SupportedAlgo) {
+ keyTypeComboBox->addItem(algo);
+ }
+ if(!GenKeyInfo::SupportedAlgo.isEmpty()) {
+ keyTypeComboBox->setCurrentIndex(0);
+ }
- keyTypeComboBox = new QComboBox(this);
- keyTypeComboBox->addItem("RSA");
- keyTypeComboBox->addItem("DSA");
- keyTypeComboBox->addItem("ELG");
- keyTypeComboBox->addItem("ED25519");
- keyTypeComboBox->addItem("CV25519");
- keyTypeComboBox->setCurrentIndex(0);
- dateEdit = new QDateEdit(QDate::currentDate().addYears(5), this);
- dateEdit->setMinimumDate(QDate::currentDate());
- dateEdit->setDisplayFormat("dd/MM/yyyy");
+ 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);
@@ -66,6 +67,9 @@ void KeyGenDialog::generateKeyDialog() {
passwordEdit->setEchoMode(QLineEdit::Password);
repeatpwEdit->setEchoMode(QLineEdit::Password);
+ noPassPhraseCheckBox = new QCheckBox(this);
+ noPassPhraseCheckBox->setCheckState(Qt::Unchecked);
+
pwStrengthSlider = new QSlider(this);
pwStrengthSlider->setOrientation(Qt::Horizontal);
pwStrengthSlider->setMaximum(6);
@@ -82,77 +86,85 @@ void KeyGenDialog::generateKeyDialog() {
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("Password:")), 6, 0);
- vbox1->addWidget(new QLabel(tr("Password: Strength\nWeak -> Strong")), 6, 3);
- vbox1->addWidget(new QLabel(tr("Repeat Password:")), 7, 0);
-
- vbox1->addWidget(nameEdit, 0, 1);
- vbox1->addWidget(emailEdit, 1, 1);
- vbox1->addWidget(commentEdit, 2, 1);
+ vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 6, 3);
+ vbox1->addWidget(new QLabel(tr("Pass Phrase:")), 6, 0);
+ vbox1->addWidget(new QLabel(tr("Pass Phrase: Strength\nWeak -> Strong")), 7, 3);
+ vbox1->addWidget(new QLabel(tr("Repeat Pass Phrase:")), 7, 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, 2);
vbox1->addWidget(passwordEdit, 6, 1);
vbox1->addWidget(repeatpwEdit, 7, 1);
- vbox1->addWidget(pwStrengthSlider, 7, 3);
+ vbox1->addWidget(pwStrengthSlider, 8, 3);
+
+ auto *groupGrid = new QGridLayout(this);
+ groupGrid->addLayout(vbox1, 0, 0);
+ groupGrid->addWidget(keyUsageGroupBox, 1, 0);
auto *nameList = new QWidget(this);
- nameList->setLayout(vbox1);
+ nameList->setLayout(groupGrid);
auto *vbox2 = new QVBoxLayout();
vbox2->addWidget(nameList);
vbox2->addWidget(errorLabel);
vbox2->addWidget(buttonBox);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
- connect(expireCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotExpireBoxChanged()));
- connect(passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(slotPasswordEditChanged()));
-// connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotKeyTypeChanged()));
-// connect(keySizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(slotKeySizeChanged()));
this->setLayout(vbox2);
+
+ set_signal_slot();
+
+ refresh_widgets_state();
+
}
void KeyGenDialog::slotKeyGenAccept() {
QString errorString = "";
- GenKeyInfo genKeyInfo;
-
/**
* 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()) {
+ } if(emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) {
errorString.append(tr(" Please give a email address. \n"));
}
if (passwordEdit->text() != repeatpwEdit->text()) {
errorString.append(tr(" Password and Repeat don't match. "));
}
+ /**
+ * 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.userid = QString("%1 <%2>").arg(nameEdit->text(), emailEdit->text());
+ genKeyInfo.setUserid(QString("%1 <%2>").arg(nameEdit->text(), emailEdit->text()));
- genKeyInfo.algo = keyTypeComboBox->currentText().toLower();
+ genKeyInfo.setKeySize(keySizeSpinBox->value());
- genKeyInfo.keySize = keySizeSpinBox->value();
-
- genKeyInfo.passPhrase = passwordEdit->text();
+ genKeyInfo.setPassPhrase(passwordEdit->text());
if (expireCheckBox->checkState()) {
- genKeyInfo.nonExpired = true;
- genKeyInfo.expired = QDateTime(QDateTime::fromTime_t(0));
+ genKeyInfo.setNonExpired(true);
} else {
- genKeyInfo.expired = dateEdit->dateTime();
+ genKeyInfo.setExpired(dateEdit->dateTime());
}
- auto *kg = new KeyGenThread(genKeyInfo, mCtx);
+ kg = new KeyGenThread(&genKeyInfo, mCtx);
+
kg->start();
this->accept();
@@ -177,8 +189,10 @@ void KeyGenDialog::slotKeyGenAccept() {
QCoreApplication::processEvents();
}
+ destroy(kg, true);
+
dialog->close();
- QMessageBox::information(nullptr, tr("Success"), tr("New key created"));
+
} else {
/**
* create error message
@@ -237,3 +251,173 @@ int KeyGenDialog::checkPassWordStrength() {
return strength;
}
+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(passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(slotPasswordEditChanged()));
+
+ 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);
+ passwordEdit->setDisabled(false);
+ repeatpwEdit->setDisabled(false);
+ } else {
+ genKeyInfo.setNonPassPhrase(true);
+ passwordEdit->setDisabled(true);
+ repeatpwEdit->setDisabled(true);
+ }
+
+ });
+
+}
+
+bool KeyGenDialog::check_email_address(const QString &str) {
+ return re_email.match(str).hasMatch();
+}
+
diff --git a/src/ui/KeygenThread.cpp b/src/ui/KeygenThread.cpp
index cd564c42..2f0a629c 100644
--- a/src/ui/KeygenThread.cpp
+++ b/src/ui/KeygenThread.cpp
@@ -21,14 +21,17 @@
#include "ui/KeygenThread.h"
-#include <utility>
-
-KeyGenThread::KeyGenThread(GenKeyInfo keyGenParams, GpgME::GpgContext *ctx) {
- this->keyGenParams = std::move(keyGenParams);
+KeyGenThread::KeyGenThread(GenKeyInfo* keyGenParams, GpgME::GpgContext *ctx) {
+ this->keyGenParams = keyGenParams;
this->mCtx = ctx;
abort = false;
}
void KeyGenThread::run() {
- mCtx->generateKey(&keyGenParams);
+ bool success = mCtx->generateKey(keyGenParams);
+ if(success)
+ QMessageBox::information(nullptr, tr("Success"), tr("New key created"));
+ else
+ QMessageBox::critical(nullptr, tr("Failure"), tr("Key generation failed"));
+
}