diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpg/GpgConstants.cpp | 4 | ||||
-rw-r--r-- | src/gpg/GpgConstants.h | 2 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyGetter.cpp | 1 | ||||
-rw-r--r-- | src/gpg/function/GpgKeyImportExporter.cpp | 37 | ||||
-rw-r--r-- | src/gpg/model/GpgKey.h | 7 | ||||
-rwxr-xr-x | src/ui/KeyMgmt.cpp | 89 | ||||
-rwxr-xr-x | src/ui/KeyMgmt.h | 3 | ||||
-rw-r--r-- | src/ui/KeyServerImportDialog.cpp | 2 | ||||
-rw-r--r-- | src/ui/KeyServerImportDialog.h | 2 | ||||
-rw-r--r-- | src/ui/smtp/SendMailDialog.cpp | 7 | ||||
-rw-r--r-- | src/ui/widgets/ExportKeyPackageDialog.cpp | 23 |
11 files changed, 131 insertions, 46 deletions
diff --git a/src/gpg/GpgConstants.cpp b/src/gpg/GpgConstants.cpp index b047ffe3..100bf8f8 100644 --- a/src/gpg/GpgConstants.cpp +++ b/src/gpg/GpgConstants.cpp @@ -42,6 +42,10 @@ const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN = "-----BEGIN PGP SIGNATURE-----"; const char* GpgFrontend::GpgConstants::PGP_SIGNATURE_END = "-----END PGP SIGNATURE-----"; +const char* GpgFrontend::GpgConstants::PGP_PUBLIC_KEY_BEGIN = + "------BEGIN PGP PUBLIC KEY BLOCK-----"; +const char* GpgFrontend::GpgConstants::PGP_PRIVATE_KEY_BEGIN = + "-----BEGIN PGP PRIVATE KEY BLOCK-----"; const char* GpgFrontend::GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD = "GpgF_Scpt://"; diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h index e8b64694..d2f9b0b6 100644 --- a/src/gpg/GpgConstants.h +++ b/src/gpg/GpgConstants.h @@ -99,6 +99,8 @@ class GpgConstants { static const char* PGP_SIGNED_END; static const char* PGP_SIGNATURE_BEGIN; static const char* PGP_SIGNATURE_END; + static const char* PGP_PUBLIC_KEY_BEGIN; + static const char* PGP_PRIVATE_KEY_BEGIN; static const char* GPG_FRONTEND_SHORT_CRYPTO_HEAD; }; diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp index 248e5630..8a26dcd9 100644 --- a/src/gpg/function/GpgKeyGetter.cpp +++ b/src/gpg/function/GpgKeyGetter.cpp @@ -59,7 +59,6 @@ GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { gpgme_key_t key; while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { keys_list->push_back(GetKey(key->fpr)); - auto& _key = keys_list->back(); } assert(check_gpg_error_2_err_code(err, GPG_ERR_EOF) == GPG_ERR_EOF); diff --git a/src/gpg/function/GpgKeyImportExporter.cpp b/src/gpg/function/GpgKeyImportExporter.cpp index 33f865a7..dd027eab 100644 --- a/src/gpg/function/GpgKeyImportExporter.cpp +++ b/src/gpg/function/GpgKeyImportExporter.cpp @@ -25,6 +25,7 @@ #include "gpg/function/GpgKeyImportExporter.h" #include "GpgConstants.h" +#include "gpg/function/GpgKeyGetter.h" /** * Import key pair @@ -65,30 +66,32 @@ bool GpgFrontend::GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list, bool secret) const { if (uid_list->empty()) return false; - std::stringstream ss; - int _mode = 0; - if (secret) _mode |= GPGME_EXPORT_MODE_SECRET; - // Alleviate another crash problem caused by an unknown array out-of-bounds - // access - auto all_success = true; - for (size_t i = 0; i < uid_list->size(); i++) { - GpgData data_out; - auto err = gpgme_op_export(ctx, (*uid_list)[i].c_str(), _mode, data_out); - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) all_success = false; - DLOG(INFO) << "exportKeys read_bytes" - << gpgme_data_seek(data_out, 0, SEEK_END); - - auto temp_out_buffer = data_out.Read2Buffer(); + auto keys = GpgKeyGetter::GetInstance().GetKeys(uid_list); + auto keys_array = new gpgme_key_t[keys->size() + 1]; - ss << *temp_out_buffer << std::endl; + int index = 0; + for (const auto& key : *keys) { + keys_array[index++] = gpgme_key_t(key); } + keys_array[index] = nullptr; + + GpgData data_out; + auto err = gpgme_op_export_keys(ctx, keys_array, _mode, data_out); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false; + + delete[] keys_array; + + DLOG(INFO) << "exportKeys read_bytes" + << gpgme_data_seek(data_out, 0, SEEK_END); + + auto temp_out_buffer = data_out.Read2Buffer(); - out_buffer = std::make_unique<ByteArray>(ss.str()); + swap(temp_out_buffer, out_buffer); - return all_success; + return true; } /** diff --git a/src/gpg/model/GpgKey.h b/src/gpg/model/GpgKey.h index 3336f39e..0ce83372 100644 --- a/src/gpg/model/GpgKey.h +++ b/src/gpg/model/GpgKey.h @@ -110,10 +110,9 @@ class GpgKey { [[nodiscard]] bool HasCardKey() const { auto subkeys = subKeys(); - return std::any_of(subkeys->begin(), subkeys->end(), - [](const GpgSubKey& subkey) -> bool { - if (subkey.is_cardkey()) return true; - }); + return std::any_of( + subkeys->begin(), subkeys->end(), + [](const GpgSubKey& subkey) -> bool { return subkey.is_cardkey(); }); } [[nodiscard]] bool is_private_key() const { return _key_ref->secret; } diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp index bd5c91a9..18a076c7 100755 --- a/src/ui/KeyMgmt.cpp +++ b/src/ui/KeyMgmt.cpp @@ -31,6 +31,7 @@ #include "gpg/function/GpgKeyOpera.h" #include "ui/SignalStation.h" #include "ui/UserInterfaceUtils.h" +#include "ui/aes/qaesencryption.h" #include "ui/keygen/SubkeyGenerateDialog.h" #include "ui/settings/GlobalSettingStation.h" #include "ui/widgets/ExportKeyPackageDialog.h" @@ -143,7 +144,6 @@ KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) { this->resize(size); this->move(pos); - this->setWindowModality(Qt::ApplicationModal); this->statusBar()->show(); setWindowTitle(_("KeyPair Management")); @@ -205,6 +205,13 @@ void KeyMgmt::createActions() { CommonUtils::GetInstance()->slotImportKeyFromKeyServer(this); }); + importKeysFromKeyPackageAct = new QAction(_("Key Package"), this); + importKeysFromKeyPackageAct->setIcon(QIcon(":key_package.png")); + importKeysFromKeyPackageAct->setToolTip( + _("Import Key(s) From a Key Package")); + connect(importKeysFromKeyPackageAct, &QAction::triggered, this, + &KeyMgmt::slotImportKeyPackage); + exportKeyToClipboardAct = new QAction(_("Export To Clipboard"), this); exportKeyToClipboardAct->setIcon(QIcon(":export_key_to_clipboard.png")); exportKeyToClipboardAct->setToolTip(_("Export Selected Key(s) To Clipboard")); @@ -255,6 +262,7 @@ void KeyMgmt::createMenus() { importKeyMenu->addAction(importKeyFromFileAct); importKeyMenu->addAction(importKeyFromClipboardAct); importKeyMenu->addAction(importKeyFromKeyServerAct); + importKeyMenu->addAction(importKeysFromKeyPackageAct); keyMenu->addAction(exportKeyToFileAct); keyMenu->addAction(exportKeyToClipboardAct); @@ -309,8 +317,6 @@ void KeyMgmt::deleteKeysWithWarning(KeyIdArgsListPtr key_ids) { * more than one selected... compare to seahorse "delete-dialog" */ - LOG(INFO) << "KeyMgmt::deleteKeysWithWarning Called"; - if (key_ids->empty()) return; QString keynames; for (const auto& key_id : *key_ids) { @@ -344,7 +350,7 @@ void KeyMgmt::slotShowKeyDetails() { auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front()); if (!key.good()) { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } @@ -355,7 +361,7 @@ void KeyMgmt::slotExportKeyToKeyPackage() { auto keys_checked = key_list_->getChecked(); if (keys_checked->empty()) { QMessageBox::critical( - this, _("Error"), + this, _("Forbidden"), _("Please check some keys before doing this operation.")); return; } @@ -388,17 +394,17 @@ void KeyMgmt::slotGenerateSubKey() { auto keys_selected = key_list_->getSelected(); if (keys_selected->empty()) { QMessageBox::information( - nullptr, _("Invalid Operation"), + this, _("Invalid Operation"), _("Please select one KeyPair before doing this operation.")); return; } const auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front()); if (!key.good()) { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } if (!key.is_private_key()) { - QMessageBox::critical(nullptr, _("Invalid Operation"), + QMessageBox::critical(this, _("Invalid Operation"), _("If a key pair does not have a private key then " "it will not be able to generate sub-keys.")); return; @@ -459,21 +465,23 @@ void KeyMgmt::slotExportAsOpenSSHFormat() { auto keys_checked = key_list_->getChecked(); if (keys_checked->empty()) { - QMessageBox::critical(nullptr, _("Error"), _("No Key Checked.")); + QMessageBox::critical( + this, _("Forbidden"), + _("Please select a key before performing this operation. If you select " + "multiple keys, only the first key will be exported.")); return; } auto key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front()); if (!GpgKeyImportExporter::GetInstance().ExportKeyOpenSSH(key, key_export_data)) { - QMessageBox::critical(nullptr, _("Error"), - _("An error occur in exporting.")); + QMessageBox::critical(this, _("Error"), _("An error occur in exporting.")); return; } if (key_export_data->empty()) { QMessageBox::critical( - nullptr, _("Error"), + this, _("Error"), _("This key may not be able to export as OpenSSH format. Please check " "the key-size of the subkey(s) used to sign.")); return; @@ -481,7 +489,7 @@ void KeyMgmt::slotExportAsOpenSSHFormat() { key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front()); if (!key.good()) { - QMessageBox::critical(nullptr, _("Error"), _("Key Not Found.")); + QMessageBox::critical(this, _("Error"), _("Key Not Found.")); return; } QString fileString = QString::fromStdString(key.name() + " " + key.email() + @@ -497,4 +505,59 @@ void KeyMgmt::slotExportAsOpenSSHFormat() { } } +void KeyMgmt::slotImportKeyPackage() { + auto key_package_file_name = QFileDialog::getOpenFileName( + this, _("Import Key Package"), {}, + QString(_("Key Package")) + " (*.gfepack);;All Files (*)"); + + if (key_package_file_name.isEmpty()) return; + + auto encrypted_data = + read_all_data_in_file(key_package_file_name.toStdString()); + + if (encrypted_data.empty()) { + QMessageBox::critical(this, _("Error"), + _("No data was read from the key package.")); + return; + }; + + auto key_file_name = QFileDialog::getOpenFileName( + this, _("Import Key Package Passphrase File"), {}, + QString(_("Key Package Passphrase File")) + " (*.key);;All Files (*)"); + + auto passphrase = read_all_data_in_file(key_file_name.toStdString()); + + LOG(INFO) << "passphrase size" << passphrase.size(); + if (passphrase.size() != 256) { + QMessageBox::critical( + this, _("Wrong Passphrase"), + _("Please double check the passphrase you entered is correct.")); + return; + } + auto hash_key = QCryptographicHash::hash( + QByteArray::fromStdString(passphrase), QCryptographicHash::Sha256); + auto encoded = QByteArray::fromStdString(encrypted_data); + + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + + auto decoded = encryption.removePadding(encryption.decode(encoded, hash_key)); + auto key_data = QByteArray::fromBase64(decoded); + + if (!key_data.startsWith(GpgConstants::PGP_PUBLIC_KEY_BEGIN) && + !key_data.startsWith(GpgConstants::PGP_PRIVATE_KEY_BEGIN)) { + QMessageBox::critical( + this, _("Wrong Passphrase"), + _("Please double check the passphrase you entered is correct.")); + return; + } + + auto key_data_ptr = std::make_unique<ByteArray>(key_data.toStdString()); + auto info = + GpgKeyImportExporter::GetInstance().ImportKey(std::move(key_data_ptr)); + + auto dialog = new KeyImportDetailDialog(info, false, this); + dialog->exec(); +} + } // namespace GpgFrontend::UI diff --git a/src/ui/KeyMgmt.h b/src/ui/KeyMgmt.h index ae220481..e3f250eb 100755 --- a/src/ui/KeyMgmt.h +++ b/src/ui/KeyMgmt.h @@ -60,6 +60,8 @@ class KeyMgmt : public QMainWindow { void slotSaveWindowState(); + void slotImportKeyPackage(); + signals: void signalStatusBarChanged(QString); @@ -92,6 +94,7 @@ class KeyMgmt : public QMainWindow { QAction* importKeyFromClipboardAct{}; QAction* importKeyFromFileAct{}; QAction* importKeyFromKeyServerAct{}; + QAction* importKeysFromKeyPackageAct{}; QAction* closeAct{}; QAction* showKeyDetailsAct{}; KeyServerImportDialog* importDialog{}; diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp index 5bad29f1..9a118b93 100644 --- a/src/ui/KeyServerImportDialog.cpp +++ b/src/ui/KeyServerImportDialog.cpp @@ -441,7 +441,7 @@ void KeyServerImportDialog::slotImport(const QStringList& keyIds, } } -void KeyServerImportDialog::slotImportFinished(QString keyid) { +void KeyServerImportDialog::slotImportFinished(const QString& keyid) { LOG(INFO) << _("Called"); auto* reply = qobject_cast<QNetworkReply*>(sender()); diff --git a/src/ui/KeyServerImportDialog.h b/src/ui/KeyServerImportDialog.h index 508fb42d..e3761f5c 100644 --- a/src/ui/KeyServerImportDialog.h +++ b/src/ui/KeyServerImportDialog.h @@ -53,7 +53,7 @@ class KeyServerImportDialog : public QDialog { void slotSearchFinished(); - void slotImportFinished(QString keyid); + void slotImportFinished(const QString& keyid); void slotSearch(); diff --git a/src/ui/smtp/SendMailDialog.cpp b/src/ui/smtp/SendMailDialog.cpp index 3bf92283..9db78608 100644 --- a/src/ui/smtp/SendMailDialog.cpp +++ b/src/ui/smtp/SendMailDialog.cpp @@ -130,6 +130,13 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent) ui->attachSenderPublickeyCheckBox->setText(_("Attach sender's public key")); ui->contentEncryptCheckBox->setText(_("Encrypt content")); + auto pos = QPoint(100, 100); + LOG(INFO) << "parent" << parent; + if (parent) pos += parent->pos(); + LOG(INFO) << "pos default" << pos.x() << pos.y(); + + move(pos); + this->setWindowTitle(_("New Message")); this->setAttribute(Qt::WA_DeleteOnClose); } diff --git a/src/ui/widgets/ExportKeyPackageDialog.cpp b/src/ui/widgets/ExportKeyPackageDialog.cpp index b5eea82d..d99e966a 100644 --- a/src/ui/widgets/ExportKeyPackageDialog.cpp +++ b/src/ui/widgets/ExportKeyPackageDialog.cpp @@ -52,7 +52,7 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( }); connect(ui->generatePassphraseButton, &QPushButton::clicked, this, [=]() { - passphrase_ = generate_passphrase(32); + passphrase_ = generate_passphrase(256); auto file_name = QFileDialog::getSaveFileName( this, _("Export Key Package Passphrase"), ui->nameValueLabel->text() + ".key", @@ -64,19 +64,20 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( connect(ui->buttonBox, &QDialogButtonBox::accepted, this, [=]() { if (ui->outputPathLabel->text().isEmpty()) { QMessageBox::critical( - nullptr, _("Forbidden"), + this, _("Forbidden"), _("Please select an output path before exporting.")); return; } if (ui->passphraseValueLabel->text().isEmpty()) { QMessageBox::critical( - nullptr, _("Forbidden"), + this, _("Forbidden"), _("Please generate a password to protect your key before exporting, " "it is very important. Don't forget to back up your password in a " "safe place.")); return; } + auto key_id_exported = std::make_unique<KeyIdArgsList>(); auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids_); for (const auto& key : *keys) { @@ -90,15 +91,19 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( if (!GpgKeyImportExporter::GetInstance().ExportKeys( key_ids_, key_export_data, ui->includeSecretKeyCheckBox->isChecked())) { - QMessageBox::critical(nullptr, _("Error"), _("Export Key(s) Failed.")); + QMessageBox::critical(this, _("Error"), _("Export Key(s) Failed.")); this->close(); return; } - auto key = passphrase_; + auto key = QByteArray::fromStdString(passphrase_), + data = + QString::fromStdString(*key_export_data).toLocal8Bit().toBase64(); - QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB); - auto encoded = encryption.encode(key_export_data->data(), key.data()); + auto hash_key = QCryptographicHash::hash(key, QCryptographicHash::Sha256); + QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB, + QAESEncryption::Padding::ISO); + auto encoded = encryption.encode(data, hash_key); write_buffer_to_file(ui->outputPathLabel->text().toStdString(), encoded.toStdString()); @@ -109,11 +114,11 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( "The Key Package has been successfully generated and has been " "protected by encryption algorithms. You can safely transfer your " "Key Package.")) + - "<b>" + + "<br />" + "<b>" + _("But the key file cannot be leaked under any " "circumstances. Please delete the Key Package and key file as " "soon " - "as possible after completing the transfer operation") + + "as possible after completing the transfer operation.") + "</b>"); }); |