Allow changing subkey expiry time.

Needs GPGME 1.15.0.
Using the same UI for changing expiry time of the primary secret key.
This commit is contained in:
SET
2020-11-21 20:53:01 +01:00
parent bb174075df
commit e9a55a1f69
7 changed files with 100 additions and 12 deletions

View File

@@ -145,6 +145,42 @@ const Error GpgMEWorker::CertifyKey(const char* fprSigningKey,
return e;
}
const Error GpgMEWorker::SetSubkeyExpiryTime(const char* keyFpr,
const char* subkeyFpr,
const string& passphrase,
ulong expires)
{
Error e;
Key k = FindKey(keyFpr, e, true);
if (e.code() != 0)
return e;
e = m_ctx->addSigningKey(k); // +++
if (e.code() != 0)
return e;
vector<GpgME::Subkey> subkey;
for (uint i = 0; i < k.subkeys().size(); i++)
{
GpgME::Subkey sk = k.subkey(i);
if (string(sk.fingerprint()) == string(subkeyFpr))
{
subkey.push_back(sk);
break;
}
}
// There should always be at least one subkey (the key itself).
m_ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
if (m_ppp == NULL)
m_ppp = new LoopbackPassphraseProvider();
m_ppp->SetPassphrase(passphrase);
m_ctx->setPassphraseProvider(m_ppp);
e = m_ctx->setExpire(k, expires, subkey);
return e;
}
const Error GpgMEWorker::SetExpiryTime(const char * keyFpr,
const string& passphrase,
const string& timeString)
@@ -168,7 +204,7 @@ const Error GpgMEWorker::SetExpiryTime(const char * keyFpr,
GpgME::Data d;
e = m_ctx->edit(k, std::unique_ptr<SetExpiryTimeEditInteractor> (interactor), d);
m_ctx->clearSigningKeys();
// NB : with a wrong passphrase, e.code() is 0 !
return e;
}

View File

@@ -77,6 +77,10 @@ public:
const char * fprKeyToSign,
vector<uint>& userIDsToSign, int options,
const string& passphrase);
const Error SetSubkeyExpiryTime(const char * keyFpr,
const char * subkeyFpr,
const string& passphrase,
ulong expires = 63072000);
/**
* Set new expiry time of a secret key.
* @param timeString
@@ -111,8 +115,8 @@ public:
* @return
*/
const Error RevokeUserID(const char * keyFpr, const string& passphrase,
const string& name, const string& email,
const string& comment);
const string& name, const string& email,
const string& comment);
/**
* Creates a pair of secret and public keys with the default engine
* algorithms. Default expiry time is 2 * 365 days.

View File

@@ -428,7 +428,10 @@ void K7Main::DisplaySubKeys(const WString& fullKeyID, bool secret)
if (canEditExpiry)
{
lblExpiry->setToolTip(TR("TTTDoubleCLick"));
lblExpiry->doubleClicked().connect(std::bind(&KeyEdit::OnExpiryClicked, m_keyEdit, skNode, WString(k.primaryFingerprint())));
lblExpiry->doubleClicked().connect(std::bind(&KeyEdit::OnExpiryClicked,
m_keyEdit, skNode,
WString(k.primaryFingerprint()),
WString(sk.fingerprint())));
}
skNode->setColumnWidget(2, unique_ptr<WText> (lblExpiry));
WString usage = sk.canAuthenticate() ? WString("A") : WString::Empty;

View File

@@ -170,7 +170,8 @@ void KeyEdit::CertifyKey()
m_owner->DisplayUids(keyToSign);
}
void KeyEdit::OnExpiryClicked(WTreeTableNode* subkeyNode, const WString& keyFpr)
void KeyEdit::OnExpiryClicked(WTreeTableNode* subkeyNode, const WString& keyFpr,
const WString& subkeyFpr)
{
if (keyFpr != m_expiryEditedKeyFpr)
{
@@ -181,15 +182,29 @@ void KeyEdit::OnExpiryClicked(WTreeTableNode* subkeyNode, const WString& keyFpr)
m_expiryEditedKeyFpr = keyFpr;
m_popupExpiryTime->GetApplyButton()->clicked().connect(this, &KeyEdit::SetExpiryTime);
}
m_popupExpiryTime->SetSubkeyFpr(subkeyFpr);
m_popupExpiryTime->show();
}
void KeyEdit::SetExpiryTime()
{
GpgMEWorker gpgWorker;
GpgME::Error e = gpgWorker.SetExpiryTime(m_expiryEditedKeyFpr.toUTF8().c_str(),
m_popupExpiryTime->GetPassphrase(),
m_popupExpiryTime->GetExpiryTime());
GpgME::Error e;
const WString keyFpr = m_popupExpiryTime->GetKeyFpr();
const WString subkeyFpr = m_popupExpiryTime->GetSubkeyFpr();
if (keyFpr == subkeyFpr)
{
e = gpgWorker.SetExpiryTime(keyFpr.toUTF8().c_str(),
m_popupExpiryTime->GetPassphrase(),
m_popupExpiryTime->GetExpiryTime());
}
else
{
e = gpgWorker.SetSubkeyExpiryTime(keyFpr.toUTF8().c_str(),
subkeyFpr.toUTF8().c_str(),
m_popupExpiryTime->GetPassphrase(),
m_popupExpiryTime->GetExpiry());
}
if (e.code() != 0)
{
m_owner->m_tmwMessage->SetText(TR("SetExpirationTimeFailure"));

View File

@@ -85,7 +85,8 @@ private:
* @param subkeyNode
* @param keyFpr
*/
void OnExpiryClicked(WTreeTableNode * subkeyNode, const WString& keyFpr);
void OnExpiryClicked(WTreeTableNode * subkeyNode, const WString& keyFpr,
const WString& subkeyFpr);
void OnUidEmailClicked(WTreeTableNode * uidNode, const WString& keyFpr);

View File

@@ -22,6 +22,7 @@ PopupExpiryTime::PopupExpiryTime(WWidget * anchorWidget, TransientMessageWidget
m_tmwMessage = txtMessage;
m_cwMain = NULL;
m_keyFpr = WString::Empty;
m_subkeyFpr = WString::Empty;
/*
* Trade-off.
* When the calendar of WDateEdit is clicked, this popup gets hidden,
@@ -82,6 +83,11 @@ const string PopupExpiryTime::GetExpiryTime() const
return m_deExpiry->text().toUTF8();
}
const ulong PopupExpiryTime::GetExpiry() const
{
return ((WDate::currentDate().daysTo(m_deExpiry->date())) * 24 * 3600);
}
void PopupExpiryTime::ShowPassphrase(bool show)
{
// See comments in PopupCertifyUserId::ShowPassphrase

View File

@@ -23,9 +23,24 @@ class PopupExpiryTime : public WPopupWidget
{
public:
PopupExpiryTime(WWidget * anchorWidget, TransientMessageWidget * txtMessage,
const WLength& width = 300);
const WLength& width = 300);
virtual ~PopupExpiryTime();
void Create(const WString& keyFpr);
const WString GetKeyFpr()
{
return m_keyFpr;
}
void SetSubkeyFpr(const WString& subkeyFpr)
{
m_subkeyFpr = subkeyFpr;
}
const WString GetSubkeyFpr()
{
return m_subkeyFpr;
}
/**
* Controls visibility of passphrase widgets.
* \n Need not be always visible as the passphrase is cached by gpg-agent.
@@ -34,6 +49,7 @@ public:
* @param show
*/
void ShowPassphrase(bool show = true);
/**
* Used to forward the passphrase to the loopback passphrase provider.
* @return
@@ -43,9 +59,15 @@ public:
return m_lePassphrase->text().toUTF8();
}
/**
* Returns the new expiry date.
* Returns the new expiry date, or 0 if date is invalid.
*/
const std::string GetExpiryTime() const;
/**
* Number of seconds from now.
* @return
*/
const ulong GetExpiry() const;
/**
* Caller binds its function here.
* @return
@@ -63,6 +85,7 @@ private:
WPushButton * m_btnApply;
WText * m_lblPassphrase;
WString m_keyFpr;
WString m_subkeyFpr;
};