Allow to export private keys.
Using a workaround that validates passphrase for a secret key. With GnuPG 2.2.23 and GpgME 1.1.15, a secret key can be exported when the right passphrase is provided. With a bad passphrase, application crashes. See https://dev.gnupg.org/T5151 Application may validate a passphrase before invoking engine. Until it is hopefully fixed in upstream and available in mainstream.
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
#include <gpgme++/keylistresult.h>
|
#include <gpgme++/keylistresult.h>
|
||||||
#include <gpgme++/importresult.h>
|
#include <gpgme++/importresult.h>
|
||||||
#include <gpgme++/keygenerationresult.h>
|
#include <gpgme++/keygenerationresult.h>
|
||||||
|
#include <gpgme++/signingresult.h>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <gpgme++/data.h>
|
#include <gpgme++/data.h>
|
||||||
@@ -346,6 +347,32 @@ const Error GpgMEWorker::CreateSubKey(GpgME::Key& k,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Error GpgMEWorker::CheckPassphrase(const char* fpr,
|
||||||
|
const string& passphrase)
|
||||||
|
{
|
||||||
|
Error e;
|
||||||
|
Context * ctx = Context::createForProtocol(Protocol::OpenPGP);
|
||||||
|
LoopbackPassphraseProvider * ppp = new LoopbackPassphraseProvider(passphrase);
|
||||||
|
ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
|
||||||
|
ctx->setPassphraseProvider(ppp);
|
||||||
|
|
||||||
|
Key k = FindKey(fpr, e, true);
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
e = ctx->addSigningKey(k);
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
Data plain("dummy");
|
||||||
|
Data signature;
|
||||||
|
SigningResult result = ctx->sign(plain, signature, SignatureMode::Detached);
|
||||||
|
e = result.error();
|
||||||
|
|
||||||
|
delete ppp;
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const Error GpgMEWorker::ExportPrivateKey(const char * pattern, string& buffer,
|
const Error GpgMEWorker::ExportPrivateKey(const char * pattern, string& buffer,
|
||||||
const string& passphrase)
|
const string& passphrase)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -181,6 +181,21 @@ public:
|
|||||||
const char * algo,
|
const char * algo,
|
||||||
const string& passphrase,
|
const string& passphrase,
|
||||||
ulong expires = 63072000);
|
ulong expires = 63072000);
|
||||||
|
/**
|
||||||
|
* Checks that passphrase can unlock secret key with fingerprint fpr.
|
||||||
|
* \n This is a workaround when exporting secret keys.
|
||||||
|
* \n To date, with GnuPG 2.2.23 and GpgME 1.1.15, a secret key can be
|
||||||
|
* exported when the right passphrase is provided. With a bad passphrase,
|
||||||
|
* application crashes.
|
||||||
|
* \n See https://dev.gnupg.org/T5151
|
||||||
|
* \n Application may validate a passphrase before invoking engine.
|
||||||
|
* \n Until it is hopefully fixed in upstream and available in mainstream.
|
||||||
|
* @param fpr
|
||||||
|
* @param passphrase
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const Error CheckPassphrase(const char * fpr,
|
||||||
|
const string& passphrase);
|
||||||
/**
|
/**
|
||||||
* Export a secret key.
|
* Export a secret key.
|
||||||
* @param pattern : a key fingerprint
|
* @param pattern : a key fingerprint
|
||||||
|
|||||||
@@ -297,6 +297,18 @@ void KeyringIO::OnPreExportSecretKey(const WString& fpr)
|
|||||||
{
|
{
|
||||||
// On preExport button of popup
|
// On preExport button of popup
|
||||||
WLink link;
|
WLink link;
|
||||||
|
GpgMEWorker gpgw;
|
||||||
|
Error e = gpgw.CheckPassphrase(fpr.toUTF8().c_str(),
|
||||||
|
m_popupExportSecretKey->GetPassphrase());
|
||||||
|
if (e.code() != 0)
|
||||||
|
{
|
||||||
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
m_popupExportSecretKey->GetApplyButton()->setLink(link);
|
||||||
|
m_popupExportSecretKey->GetApplyButton()->disable();
|
||||||
|
LGE(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<ExportKeyStreamResource> shResource =
|
shared_ptr<ExportKeyStreamResource> shResource =
|
||||||
make_shared<ExportKeyStreamResource>
|
make_shared<ExportKeyStreamResource>
|
||||||
(fpr, true, "appliation/pgp-keys", m_tmwMessage);
|
(fpr, true, "appliation/pgp-keys", m_tmwMessage);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
<gdb_interceptlist>
|
<gdb_interceptlist>
|
||||||
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
||||||
</gdb_interceptlist>
|
</gdb_interceptlist>
|
||||||
|
<gdb_signals>
|
||||||
|
</gdb_signals>
|
||||||
<gdb_options>
|
<gdb_options>
|
||||||
<DebugOptions>
|
<DebugOptions>
|
||||||
</DebugOptions>
|
</DebugOptions>
|
||||||
|
|||||||
Reference in New Issue
Block a user