aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpg/GpgConstants.cpp4
-rw-r--r--src/gpg/GpgConstants.h2
-rw-r--r--src/gpg/function/GpgKeyGetter.cpp1
-rw-r--r--src/gpg/function/GpgKeyImportExporter.cpp37
-rw-r--r--src/gpg/model/GpgKey.h7
-rwxr-xr-xsrc/ui/KeyMgmt.cpp89
-rwxr-xr-xsrc/ui/KeyMgmt.h3
-rw-r--r--src/ui/KeyServerImportDialog.cpp2
-rw-r--r--src/ui/KeyServerImportDialog.h2
-rw-r--r--src/ui/smtp/SendMailDialog.cpp7
-rw-r--r--src/ui/widgets/ExportKeyPackageDialog.cpp23
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>");
});