Add key creation functions.

- create a pair of keys with default engine algorithms
 - create a secret key
 - create a subkey (public) and add it to a secret key.
This commit is contained in:
SET
2020-11-11 14:47:05 +01:00
parent 15abc8b810
commit 9cce0febdb
2 changed files with 141 additions and 3 deletions

View File

@@ -10,10 +10,19 @@
#include "GpgMEWorker.h" #include "GpgMEWorker.h"
#include <gpgme++/keylistresult.h> #include <gpgme++/keylistresult.h>
#include <gpgme++/importresult.h> #include <gpgme++/importresult.h>
#include <gpgme++/keygenerationresult.h>
#include <locale> #include <locale>
#include <iostream> #include <iostream>
#include <gpgme++/data.h> #include <gpgme++/data.h>
using namespace std;
#define SPACE " "
#define LESSTHAN "<"
#define MORETHAN ">"
// From gpgme.h (C API), don't want to include it here for one const.
#define _CREATE_NOEXPIRE (1 << 13)
GpgMEWorker::GpgMEWorker() GpgMEWorker::GpgMEWorker()
{ {
m_ctx = Context::createForProtocol(Protocol::OpenPGP); m_ctx = Context::createForProtocol(Protocol::OpenPGP);
@@ -145,18 +154,98 @@ const Error GpgMEWorker::SetExpiryTime(const char * keyFpr,
e = m_ctx->addSigningKey(k); // +++ e = m_ctx->addSigningKey(k); // +++
if (e.code() != 0) if (e.code() != 0)
return e; return e;
m_ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback); m_ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
if (m_ppp == NULL) if (m_ppp == NULL)
m_ppp = new LoopbackPassphraseProvider(); m_ppp = new LoopbackPassphraseProvider();
m_ppp->SetPassphrase(passphrase); m_ppp->SetPassphrase(passphrase);
m_ctx->setPassphraseProvider(m_ppp); m_ctx->setPassphraseProvider(m_ppp);
SetExpiryTimeEditInteractor * interactor SetExpiryTimeEditInteractor * interactor
= new SetExpiryTimeEditInteractor(timeString); = new SetExpiryTimeEditInteractor(timeString);
GpgME::Data d; GpgME::Data d;
e = m_ctx->edit(k, std::unique_ptr<SetExpiryTimeEditInteractor> (interactor), d); e = m_ctx->edit(k, std::unique_ptr<SetExpiryTimeEditInteractor> (interactor), d);
m_ctx->clearSigningKeys(); m_ctx->clearSigningKeys();
return e;
}
/*
* Using a temporary context for key creation. It is altered after secret key
* creation, and subkey creation fails thereafter. This is observational.
*/
const Error GpgMEWorker::CreateKeyWithEngineDefaultAlgo(GpgME::Key& k,
const string& name,
const string& email,
const string& comment,
const string& passphrase,
ulong expires)
{
Error e;
Context * ctx = Context::createForProtocol(Protocol::OpenPGP);
LoopbackPassphraseProvider * ppp = new LoopbackPassphraseProvider(passphrase);
ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
ctx->setPassphraseProvider(ppp);
string uid = name + SPACE
+ LESSTHAN + email + MORETHAN;
if (!comment.empty())
uid += SPACE + comment;
uint flags = expires
? 0 : _CREATE_NOEXPIRE;
KeyGenerationResult kgr = ctx->createKeyEx(uid.c_str(), "default",
0, 0, k, flags);
return kgr.error();
}
const Error GpgMEWorker::CreateKey(GpgME::Key& k,
const string& name,
const string& email,
const string& comment,
const char* algo,
const string& passphrase,
ulong expires)
{
Error e;
Context * ctx = Context::createForProtocol(Protocol::OpenPGP);
LoopbackPassphraseProvider * ppp = new LoopbackPassphraseProvider(passphrase);
ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
ctx->setPassphraseProvider(ppp);
string uid = name + SPACE
+ LESSTHAN + email + MORETHAN;
if (!comment.empty())
uid += SPACE + comment;
uint flags = expires
? 0 : _CREATE_NOEXPIRE;
KeyGenerationResult kgr = ctx->createKeyEx(uid.c_str(), algo,
0, expires, k, flags);
// Why is k not assigned the newly created key ?!
k = FindKey(kgr.fingerprint(), e, true);
delete ppp;
delete ctx;
return kgr.error();
}
const Error GpgMEWorker::CreateSubKey(GpgME::Key& k,
const char* algo,
const string& passphrase,
ulong expires)
{
Error e;
Context * ctx = Context::createForProtocol(Protocol::OpenPGP);
LoopbackPassphraseProvider * ppp = new LoopbackPassphraseProvider(passphrase);
ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
ctx->setPassphraseProvider(ppp);
uint flags = expires
? 0 : _CREATE_NOEXPIRE;
e = ctx->createSubkey(k, algo, 0, expires, flags);
k.update();
delete ppp;
delete ctx;
return e; return e;
} }

View File

@@ -84,6 +84,55 @@ public:
const Error SetExpiryTime(const char * keyFpr, const Error SetExpiryTime(const char * keyFpr,
const string& passphrase, const string& passphrase,
const string& timeString = "0"); const string& timeString = "0");
/**
* Creates a pair of secret and public keys with the default engine
* algorithms. Default expiry time is 2 * 365 days.
* @param k : must be a null key
* @param name
* @param email
* @param comment
* @param passphrase
* @param expires : seconds ahead of creation time. Use 0 for no expiry.
* @return
*/
const Error CreateKeyWithEngineDefaultAlgo(GpgME::Key& k,
const string& name,
const string& email,
const string& comment,
const string& passphrase,
ulong expires = 63072000);
/**
* Creates a secret key with passed in algorithm name. Default expiry time
* is 2 * 365 days.
* @param k : must be a null key
* @param name
* @param email
* @param comment
* @param algo : a valid algorithm name for a secret key
* @param passphrase
* @param expires : seconds ahead of creation time. Use 0 for no expiry.
* @return
*/
const Error CreateKey(GpgME::Key& k,
const string& name,
const string& email,
const string& comment,
const char * algo,
const string& passphrase,
ulong expires = 63072000);
/**
* Creates a public key with passed in algorithm name and adds it to secret
* key k. Default expiry time is 2 * 365 days.
* @param k : must be a secret key
* @param algo : : a valid algorithm name for a public key
* @param passphrase
* @param expires : seconds ahead of creation time. Use 0 for no expiry.
* @return
*/
const Error CreateSubKey(GpgME::Key& k,
const char * algo,
const string& passphrase,
ulong expires = 63072000);
private: private:
Context * m_ctx; Context * m_ctx;