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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
23
KeyEdit.cpp
23
KeyEdit.cpp
@@ -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"));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -54,7 +76,7 @@ public:
|
||||
{
|
||||
return m_btnApply;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
TransientMessageWidget * m_tmwMessage;
|
||||
WContainerWidget * m_cwMain;
|
||||
@@ -63,6 +85,7 @@ private:
|
||||
WPushButton * m_btnApply;
|
||||
WText * m_lblPassphrase;
|
||||
WString m_keyFpr;
|
||||
WString m_subkeyFpr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user