diff options
author | saturneric <[email protected]> | 2024-07-28 15:08:48 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-07-28 15:08:56 +0000 |
commit | 4e0db9ef4bf329d5698b31bd93601004305f71dc (patch) | |
tree | 94a22cfab394456ff89392831d3e146a76413118 /src/ui/dialog/keypair_details/KeyPairOperaTab.cpp | |
parent | fix: remove invalid parameters from the SDK (diff) | |
download | GpgFrontend-4e0db9ef4bf329d5698b31bd93601004305f71dc.tar.gz GpgFrontend-4e0db9ef4bf329d5698b31bd93601004305f71dc.zip |
feat: add paper key module support
Diffstat (limited to 'src/ui/dialog/keypair_details/KeyPairOperaTab.cpp')
-rw-r--r-- | src/ui/dialog/keypair_details/KeyPairOperaTab.cpp | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp index 10a1ac00..34b03cd9 100644 --- a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp @@ -34,6 +34,7 @@ #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/function/gpg/GpgKeyOpera.h" #include "core/model/GpgKey.h" +#include "core/module/ModuleManager.h" #include "core/typedef/GpgTypedef.h" #include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" @@ -96,6 +97,16 @@ KeyPairOperaTab::KeyPairOperaTab(const QString& key_id, QWidget* parent) key_server_opera_button->setDisabled(forbid_all_gnupg_connection); advance_h_box_layout->addWidget(key_server_opera_button); + if (!Module::IsModuleActivate(kPaperKeyModuleID)) { + if (!m_key_.IsPrivateKey() || !m_key_.IsHasMasterKey()) { + auto* import_paper_key_button = new QPushButton(tr("Import A Paper Key")); + import_paper_key_button->setStyleSheet("text-align:center;"); + connect(import_paper_key_button, &QPushButton::clicked, this, + &KeyPairOperaTab::slot_import_paper_key); + vbox_p_k->addWidget(import_paper_key_button); + } + } + if (m_key_.IsPrivateKey() && m_key_.IsHasMasterKey()) { auto* revoke_cert_opera_button = new QPushButton(tr("Revoke Certificate Operation")); @@ -168,6 +179,17 @@ void KeyPairOperaTab::CreateOperaMenu() { connect(export_shortest_secret_key, &QAction::triggered, this, &KeyPairOperaTab::slot_export_short_private_key); + if (!Module::IsModuleActivate(kPaperKeyModuleID)) { + auto* export_secret_key_as_paper_key = + new QAction(tr("Export Secret Key As A Paper Key"), this); + connect(export_secret_key_as_paper_key, &QAction::triggered, this, + &KeyPairOperaTab::slot_export_paper_key); + if (!m_key_.IsPrivateKey()) { + export_secret_key_as_paper_key->setDisabled(true); + } + secret_key_export_opera_menu_->addAction(export_secret_key_as_paper_key); + } + secret_key_export_opera_menu_->addAction(export_full_secret_key); secret_key_export_opera_menu_->addAction(export_shortest_secret_key); @@ -447,4 +469,148 @@ void KeyPairOperaTab::slot_import_revoke_cert() { emit UISignalStation::GetInstance() -> SignalKeyRevoked(m_key_.GetId()); CommonUtils::GetInstance()->SlotImportKeys(nullptr, rev_file.readAll()); } + +void KeyPairOperaTab::slot_export_paper_key() { + if (!Module::IsModuleActivate(kPaperKeyModuleID)) return; + + int ret = QMessageBox::information( + this, tr("Exporting private key as a Paper key"), + "<h3>" + tr("You are about to export your") + "<font color=\"red\">" + + tr(" PRIVATE KEY ") + "</font>!</h3>\n" + + tr("This is NOT your Public Key, so DON'T give it away.") + "<br />" + + tr("A PaperKey is a human-readable printout of your private key, " + "which can be used to recover your key if you lose access to " + "your " + "digital copy. ") + + "<br />" + tr("Keep it in a safe place.") + "<br />" + + tr("Do you REALLY want to export your PRIVATE KEY?"), + QMessageBox::Cancel | QMessageBox::Ok); + + // export key, if ok was clicked + if (ret == QMessageBox::Ok) { + auto [err, gf_buffer] = GpgKeyImportExporter::GetInstance().ExportKey( + m_key_, true, false, true); + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + CommonUtils::RaiseMessageBox(this, err); + return; + } + + // generate a file name +#ifndef WINDOWS + auto file_string = m_key_.GetName() + "<" + m_key_.GetEmail() + ">(" + + m_key_.GetId() + ")_paper_key.txt"; +#else + auto file_string = m_key_.GetName() + "[" + m_key_.GetEmail() + "](" + + m_key_.GetId() + ")_paper_key.txt"; +#endif + std::replace(file_string.begin(), file_string.end(), ' ', '_'); + + auto file_name = QFileDialog::getSaveFileName( + this, tr("Export Key To File"), file_string, + tr("Key Files") + " (*.txt);;All Files (*)"); + + if (file_name.isEmpty()) return; + + Module::TriggerEvent( + "REQUEST_TRANS_KEY_2_PAPER_KEY", + { + {"secret_key", QString(gf_buffer.ConvertToQByteArray().toBase64())}, + }, + [this, file_name](Module::EventIdentifier i, + Module::Event::ListenerIdentifier ei, + Module::Event::Params p) { + qCDebug(ui) << "REQUEST_TRANS_KEY_2_PAPER_KEY callback: " << i << ei; + + if (p["ret"] != "0" || p["paper_key"].isEmpty()) { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred trying to recover the " + "Paper Key back to the private key.")); + return; + } + + if (!WriteFile(file_name, p["paper_key"].toLatin1())) { + QMessageBox::critical( + this, tr("Export Error"), + tr("Couldn't open %1 for writing").arg(file_name)); + return; + } + }); + } +} + +void KeyPairOperaTab::slot_import_paper_key() { + if (!Module::IsModuleActivate(kPaperKeyModuleID)) return; + + auto [err, gf_buffer] = + GpgKeyImportExporter::GetInstance().ExportKey(m_key_, false, false, true); + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + CommonUtils::RaiseMessageBox(this, err); + return; + } + + // generate a file name +#ifndef WINDOWS + auto file_string = m_key_.GetName() + "<" + m_key_.GetEmail() + ">(" + + m_key_.GetId() + ")_paper_key.txt"; +#else + auto file_string = m_key_.GetName() + "[" + m_key_.GetEmail() + "](" + + m_key_.GetId() + ")_paper_key.txt"; +#endif + std::replace(file_string.begin(), file_string.end(), ' ', '_'); + + auto file_name = QFileDialog::getOpenFileName( + this, tr("Import A Paper Key"), file_string, + tr("Paper Key File") + " (*.txt);;All Files (*)"); + + if (file_name.isEmpty()) return; + + QFileInfo file_info(file_name); + + if (!file_info.isFile() || !file_info.isReadable()) { + QMessageBox::critical( + this, tr("Error"), + tr("Cannot open this file. Please make sure that this " + "is a regular file and it's readable.")); + return; + } + + if (file_info.size() > static_cast<qint64>(1024 * 1024)) { + QMessageBox::critical( + this, tr("Error"), + tr("The target file is too large for a paper key keyring.")); + return; + } + + auto [succ, gf_in_buff] = ReadFileGFBuffer(file_name); + if (!succ) { + QMessageBox::critical( + this, tr("Error"), + tr("Cannot open this file. Please make sure that this " + "is a regular file and it's readable.")); + return; + } + + Module::TriggerEvent( + "REQUEST_TRANS_PAPER_KEY_2_KEY", + { + {"public_key", QString(gf_buffer.ConvertToQByteArray().toBase64())}, + {"paper_key_secrets", + QString(gf_in_buff.ConvertToQByteArray().toBase64())}, + }, + [this](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei, + Module::Event::Params p) { + qCDebug(ui) << "REQUEST_TRANS_PAPER_KEY_2_KEY callback: " << i << ei; + + if (p["ret"] != "0" || p["secret_key"].isEmpty()) { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred trying to recover the " + "Paper Key back to the private key.")); + return; + } + + CommonUtils::GetInstance()->SlotImportKeys( + this, QByteArray::fromBase64(p["secret_key"].toLatin1())); + }); +} + } // namespace GpgFrontend::UI |