Allow revoking key certifications.
Certified user identities in keys can be revoked using the same popup for certification. Requires GnuPG 2.2.24 (not available in distro's repository, not fully tested to date).
This commit is contained in:
@@ -145,6 +145,34 @@ const Error GpgMEWorker::CertifyKey(const char* fprSigningKey,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Error GpgMEWorker::RevokeKeyCertifications(const char* fprSigningKey,
|
||||||
|
const char* fprKeyToSign,
|
||||||
|
vector<GpgME::UserID>& userIDsToRevoke,
|
||||||
|
const string& passphrase)
|
||||||
|
{
|
||||||
|
Error e;
|
||||||
|
Key signingKey = FindKey(fprSigningKey, e, true);
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
e = m_ctx->addSigningKey(signingKey); // +++
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
Key keyToSign = FindKey(fprKeyToSign, e, false);
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
|
||||||
|
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->revokeSignature(keyToSign, signingKey, userIDsToRevoke);
|
||||||
|
m_ctx->clearSigningKeys();
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const Error GpgMEWorker::SetSubkeyExpiryTime(const char* keyFpr,
|
const Error GpgMEWorker::SetSubkeyExpiryTime(const char* keyFpr,
|
||||||
const char* subkeyFpr,
|
const char* subkeyFpr,
|
||||||
const string& passphrase,
|
const string& passphrase,
|
||||||
|
|||||||
@@ -77,6 +77,19 @@ public:
|
|||||||
const char * fprKeyToSign,
|
const char * fprKeyToSign,
|
||||||
vector<uint>& userIDsToSign, int options,
|
vector<uint>& userIDsToSign, int options,
|
||||||
const string& passphrase);
|
const string& passphrase);
|
||||||
|
/**
|
||||||
|
* Revoke UserID certifications.
|
||||||
|
* \n Requires GnuPG >= 2.2.24
|
||||||
|
* @param fprSigningKey
|
||||||
|
* @param fprKeyToSign
|
||||||
|
* @param userIDsToRevoke : vector of ::UserID
|
||||||
|
* @param passphrase
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const Error RevokeKeyCertifications(const char * fprSigningKey,
|
||||||
|
const char * fprKeyToSign,
|
||||||
|
vector<GpgME::UserID>& userIDsToRevoke,
|
||||||
|
const string& passphrase);
|
||||||
/**
|
/**
|
||||||
* Sets the expiry time of a single subkey. Requires GPGME >= 1.15.0.
|
* Sets the expiry time of a single subkey. Requires GPGME >= 1.15.0.
|
||||||
* \n If no subkey is found (wrong fpr), the expiry time of key is set
|
* \n If no subkey is found (wrong fpr), the expiry time of key is set
|
||||||
|
|||||||
42
KeyEdit.cpp
42
KeyEdit.cpp
@@ -153,19 +153,43 @@ void KeyEdit::CertifyKey()
|
|||||||
}
|
}
|
||||||
const WString signingKey = m_popupUid->GetSelectedKey();
|
const WString signingKey = m_popupUid->GetSelectedKey();
|
||||||
const WString keyToSign = m_popupUid->GetKeyToSign();
|
const WString keyToSign = m_popupUid->GetKeyToSign();
|
||||||
int options = m_popupUid->GetCertifyOptions();
|
|
||||||
GpgMEWorker gpgWorker;
|
GpgMEWorker gpgWorker;
|
||||||
GpgME::Error e = gpgWorker.CertifyKey(signingKey.toUTF8().c_str(),
|
GpgME::Error e;
|
||||||
keyToSign.toUTF8().c_str(),
|
if (m_popupUid->WhatToDo() == PopupCertifyUserId::CertifyUid)
|
||||||
uidsToSign, options,
|
{
|
||||||
m_popupUid->GetPassphrase());
|
int options = m_popupUid->GetCertifyOptions();
|
||||||
|
e = gpgWorker.CertifyKey(signingKey.toUTF8().c_str(),
|
||||||
|
keyToSign.toUTF8().c_str(),
|
||||||
|
uidsToSign, options,
|
||||||
|
m_popupUid->GetPassphrase());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector<GpgME::UserID> uidsToRevoke
|
||||||
|
= m_popupUid->GetUidsToRevokeCertification();
|
||||||
|
e = gpgWorker.RevokeKeyCertifications(signingKey.toUTF8().c_str(),
|
||||||
|
keyToSign.toUTF8().c_str(),
|
||||||
|
uidsToRevoke,
|
||||||
|
m_popupUid->GetPassphrase());
|
||||||
|
}
|
||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_owner->m_tmwMessage->SetText(TR("CertificationFailure"));
|
if (m_popupUid->WhatToDo() == PopupCertifyUserId::CertifyUid)
|
||||||
m_popupUid->ShowPassphrase(true);
|
{
|
||||||
return;
|
m_owner->m_tmwMessage->SetText(e.asString());
|
||||||
|
m_popupUid->ShowPassphrase(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_owner->m_tmwMessage->SetText(e.asString());
|
||||||
|
m_popupUid->ShowPassphrase(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_owner->m_tmwMessage->SetText(TR("CertificationSuccess"));
|
if (m_popupUid->WhatToDo() == PopupCertifyUserId::CertifyUid)
|
||||||
|
m_owner->m_tmwMessage->SetText(TR("CertificationSuccess"));
|
||||||
|
else
|
||||||
|
m_owner->m_tmwMessage->SetText(TR("RevocationSuccess"));
|
||||||
m_popupUid->ShowPassphrase(false);
|
m_popupUid->ShowPassphrase(false);
|
||||||
m_owner->DisplayUids(keyToSign);
|
m_owner->DisplayUids(keyToSign);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
#include <Wt/WStandardItem.h>
|
#include <Wt/WStandardItem.h>
|
||||||
#include <Wt/WStandardItemModel.h>
|
#include <Wt/WStandardItemModel.h>
|
||||||
|
#include <Wt/WRadioButton.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -63,10 +65,10 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
m_hblPreferences->addLayout(unique_ptr<WVBoxLayout> (m_vblEmail));
|
m_hblPreferences->addLayout(unique_ptr<WVBoxLayout> (m_vblEmail));
|
||||||
PresentEmail();
|
PresentEmail();
|
||||||
// Column 1
|
// Column 1
|
||||||
|
m_gbOptions = new WGroupBox(TR("Options"));
|
||||||
WVBoxLayout * vblOptions = new WVBoxLayout();
|
WVBoxLayout * vblOptions = new WVBoxLayout();
|
||||||
m_hblPreferences->addLayout(unique_ptr<WVBoxLayout> (vblOptions));
|
m_gbOptions->setLayout(unique_ptr<WVBoxLayout> (vblOptions));
|
||||||
WText * lblOptions = new WText(TR("Options"));
|
m_hblPreferences->addWidget(unique_ptr<WGroupBox> (m_gbOptions));
|
||||||
vblOptions->addWidget(unique_ptr<WText> (lblOptions));
|
|
||||||
m_cbOptionExportable = new WCheckBox(TR("ExportableCertification"));
|
m_cbOptionExportable = new WCheckBox(TR("ExportableCertification"));
|
||||||
m_cbOptionExportable->setToolTip(TR("OneWayHint"));
|
m_cbOptionExportable->setToolTip(TR("OneWayHint"));
|
||||||
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionExportable));
|
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionExportable));
|
||||||
@@ -74,7 +76,7 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
m_cbOptionNonRevocable->setToolTip(TR("OneWayHint"));
|
m_cbOptionNonRevocable->setToolTip(TR("OneWayHint"));
|
||||||
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionNonRevocable));
|
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionNonRevocable));
|
||||||
/*m_cbOptionTrust = new WCheckBox(TR("TrustCertification"));
|
/*m_cbOptionTrust = new WCheckBox(TR("TrustCertification"));
|
||||||
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionTrust));*/
|
gbOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionTrust));*/
|
||||||
|
|
||||||
WHBoxLayout * hblPassphrase = new WHBoxLayout();
|
WHBoxLayout * hblPassphrase = new WHBoxLayout();
|
||||||
m_lblPassphrase = new WText(TR("Passphrase"));
|
m_lblPassphrase = new WText(TR("Passphrase"));
|
||||||
@@ -84,6 +86,18 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
hblPassphrase->addWidget(unique_ptr<WLineEdit> (m_lePassphrase), 1);
|
hblPassphrase->addWidget(unique_ptr<WLineEdit> (m_lePassphrase), 1);
|
||||||
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblPassphrase));
|
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblPassphrase));
|
||||||
|
|
||||||
|
WHBoxLayout * hblWhat = new WHBoxLayout();
|
||||||
|
WRadioButton * rbCertifyUid = new WRadioButton(TR("CertifyUid"));
|
||||||
|
hblWhat->addWidget(unique_ptr<WRadioButton> (rbCertifyUid));
|
||||||
|
WRadioButton * rbRevokeCertification =
|
||||||
|
new WRadioButton(TR("RevokeUidCertification"));
|
||||||
|
hblWhat->addWidget(unique_ptr<WRadioButton> (rbRevokeCertification));
|
||||||
|
m_bgWhat = make_shared<WButtonGroup>();
|
||||||
|
m_bgWhat->addButton(rbCertifyUid, What::CertifyUid);
|
||||||
|
m_bgWhat->addButton(rbRevokeCertification, What::RevokeUidCertification);
|
||||||
|
m_bgWhat->setCheckedButton(rbCertifyUid);
|
||||||
|
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblWhat));
|
||||||
|
|
||||||
WHBoxLayout * hblButtons = new WHBoxLayout();
|
WHBoxLayout * hblButtons = new WHBoxLayout();
|
||||||
WPushButton * btnClose = new WPushButton(TR("Close"));
|
WPushButton * btnClose = new WPushButton(TR("Close"));
|
||||||
hblButtons->addWidget(unique_ptr<WPushButton> (btnClose));
|
hblButtons->addWidget(unique_ptr<WPushButton> (btnClose));
|
||||||
@@ -99,6 +113,7 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
m_cbOptionNonRevocable->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 2));
|
m_cbOptionNonRevocable->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 2));
|
||||||
// m_cbOptionTrust->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 4));
|
// m_cbOptionTrust->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 4));
|
||||||
btnClose->clicked().connect(this, &WPopupWidget::hide);
|
btnClose->clicked().connect(this, &WPopupWidget::hide);
|
||||||
|
m_bgWhat->checkedChanged().connect(this, &PopupCertifyUserId::OnButtonGroupWhat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::FillPrivateKeyComboBox(vector<WString>& privateKeys)
|
void PopupCertifyUserId::FillPrivateKeyComboBox(vector<WString>& privateKeys)
|
||||||
@@ -175,8 +190,8 @@ void PopupCertifyUserId::PresentEmail()
|
|||||||
WCheckBox * cbEmail = new WCheckBox(it->email());
|
WCheckBox * cbEmail = new WCheckBox(it->email());
|
||||||
m_vblEmail->addWidget(unique_ptr<WCheckBox> (cbEmail));
|
m_vblEmail->addWidget(unique_ptr<WCheckBox> (cbEmail));
|
||||||
cbEmail->setId(std::to_string(id));
|
cbEmail->setId(std::to_string(id));
|
||||||
cbEmail->checked().connect(std::bind(&PopupCertifyUserId::OnEmailChecked, this, cbEmail));
|
cbEmail->checked().connect(std::bind(&PopupCertifyUserId::OnEmailChecked, this, cbEmail, (*it)));
|
||||||
cbEmail->unChecked().connect(std::bind(&PopupCertifyUserId::OnEmailUnChecked, this, cbEmail));
|
cbEmail->unChecked().connect(std::bind(&PopupCertifyUserId::OnEmailUnChecked, this, cbEmail, (*it)));
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,25 +235,32 @@ void PopupCertifyUserId::ShowPassphrase(bool show)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::OnEmailChecked(WCheckBox* cb)
|
void PopupCertifyUserId::OnEmailChecked(WCheckBox* cb, GpgME::UserID& uid)
|
||||||
{
|
{
|
||||||
int id = Tools::ToInt(cb->id());
|
int id = Tools::ToInt(cb->id());
|
||||||
m_uidsToSign.push_back(id);
|
m_uidsToSign.push_back(id);
|
||||||
|
m_uidsToRevokeCertification.push_back(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::OnEmailUnChecked(WCheckBox* cb)
|
void PopupCertifyUserId::OnEmailUnChecked(WCheckBox* cb, GpgME::UserID& uid)
|
||||||
{
|
{
|
||||||
// Any tip to locate a known value in a vector without iterating over?
|
|
||||||
const uint id = Tools::ToInt(cb->id());
|
const uint id = Tools::ToInt(cb->id());
|
||||||
vector<uint>::iterator it;
|
vector<uint>::iterator it =
|
||||||
for (it = m_uidsToSign.begin(); it != m_uidsToSign.end(); it++)
|
std::find(m_uidsToSign.begin(), m_uidsToSign.end(), id);
|
||||||
|
if (it != m_uidsToSign.end())
|
||||||
|
m_uidsToSign.erase(it);
|
||||||
|
|
||||||
|
vector<GpgME::UserID>::iterator uit;
|
||||||
|
for (uit = m_uidsToRevokeCertification.begin();
|
||||||
|
uit != m_uidsToRevokeCertification.end(); uit++)
|
||||||
{
|
{
|
||||||
if ((*it) == id)
|
if ((*uit).uidhash() == uid.uidhash())
|
||||||
{
|
{
|
||||||
m_uidsToSign.erase(it);
|
m_uidsToRevokeCertification.erase(uit);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::OnCertifyOptionChecked(int id)
|
void PopupCertifyUserId::OnCertifyOptionChecked(int id)
|
||||||
@@ -250,3 +272,10 @@ void PopupCertifyUserId::OnCertifyOptionUnChecked(int id)
|
|||||||
{
|
{
|
||||||
m_certifyOptions -= id;
|
m_certifyOptions -= id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PopupCertifyUserId::OnButtonGroupWhat(WRadioButton* btn)
|
||||||
|
{
|
||||||
|
m_gbOptions->setDisabled(m_bgWhat->checkedId()
|
||||||
|
== What::RevokeUidCertification);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,28 +19,32 @@
|
|||||||
#include <Wt/WLineEdit.h>
|
#include <Wt/WLineEdit.h>
|
||||||
#include <Wt/WVBoxLayout.h>
|
#include <Wt/WVBoxLayout.h>
|
||||||
#include <Wt/WHBoxLayout.h>
|
#include <Wt/WHBoxLayout.h>
|
||||||
|
#include <Wt/WGroupBox.h>
|
||||||
|
#include <Wt/WButtonGroup.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <gpgme++/key.h>
|
||||||
#include "TransientMessageWidget.h"
|
#include "TransientMessageWidget.h"
|
||||||
|
|
||||||
using namespace Wt;
|
using namespace Wt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A popup with required parameters to certify a key :
|
* A popup with required parameters to certify or revoke a key uid :
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Signer's private keys</li>
|
* <li>Signer's private keys</li>
|
||||||
* <li>Target key user identities (email)</li>
|
* <li>Target key user identities (email)</li>
|
||||||
* <li>Signing options : Exportable and non-revocable</li>
|
* <li>Signing options : Exportable and non-revocable</li>
|
||||||
* <li>Passphrase for selected private key</li>
|
* <li>Passphrase for selected private key</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* The passphrase is cached by gpg-agent for default 10 mins.
|
* \n For revocation, GnuPG >= 2.2.24 is required.
|
||||||
* \n The popup hides the passphrase widget until a certify op fails.
|
|
||||||
* \n UserID::Validity:: lists many validity levels. How to selectively apply
|
|
||||||
* an arbitrary level ? Before signing, it's 'Unknown'. After signing, it's
|
|
||||||
* always 'Full'.
|
|
||||||
*/
|
*/
|
||||||
class PopupCertifyUserId : public WPopupWidget
|
class PopupCertifyUserId : public WPopupWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum What
|
||||||
|
{
|
||||||
|
RevokeUidCertification = 0, CertifyUid
|
||||||
|
};
|
||||||
PopupCertifyUserId(WWidget * anchorWidget, TransientMessageWidget * txtMessage,
|
PopupCertifyUserId(WWidget * anchorWidget, TransientMessageWidget * txtMessage,
|
||||||
const WLength& width = 500);
|
const WLength& width = 500);
|
||||||
virtual ~PopupCertifyUserId();
|
virtual ~PopupCertifyUserId();
|
||||||
@@ -102,6 +106,27 @@ public:
|
|||||||
return m_uidsToSign;
|
return m_uidsToSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the certifications to revoke.
|
||||||
|
* \n GPGME >= 1.15.0 is required. It expects
|
||||||
|
* it as a vector of GpgME::UserID, instead of a vector of indices used in
|
||||||
|
* GetUidsToSign().
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
vector<GpgME::UserID>& GetUidsToRevokeCertification()
|
||||||
|
{
|
||||||
|
return m_uidsToRevokeCertification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Certify selected user identities or revoke certifications.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const What WhatToDo() const
|
||||||
|
{
|
||||||
|
return (What) m_bgWhat->checkedId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sum of option values
|
* Sum of option values
|
||||||
* <ul>
|
* <ul>
|
||||||
@@ -141,7 +166,10 @@ private:
|
|||||||
WPushButton * m_btnApply;
|
WPushButton * m_btnApply;
|
||||||
|
|
||||||
vector<uint> m_uidsToSign;
|
vector<uint> m_uidsToSign;
|
||||||
|
vector<GpgME::UserID> m_uidsToRevokeCertification;
|
||||||
int m_certifyOptions;
|
int m_certifyOptions;
|
||||||
|
WGroupBox * m_gbOptions;
|
||||||
|
shared_ptr<WButtonGroup> m_bgWhat;
|
||||||
/**
|
/**
|
||||||
* Available private fingerprints in a combobox. The selected item is the
|
* Available private fingerprints in a combobox. The selected item is the
|
||||||
* signing key.
|
* signing key.
|
||||||
@@ -154,15 +182,17 @@ private:
|
|||||||
*/
|
*/
|
||||||
void PresentEmail();
|
void PresentEmail();
|
||||||
/**
|
/**
|
||||||
* Add the identity index in a vector.
|
* Add the identity index in a vector for certification.
|
||||||
|
* \n Add the ::UserID in a vector for signature revocation.
|
||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
void OnEmailChecked(WCheckBox * cb);
|
void OnEmailChecked(WCheckBox * cb, GpgME::UserID& uid);
|
||||||
/**
|
/**
|
||||||
* Removes the identity index in a vector.
|
* Removes the identity index from a vector for certification.
|
||||||
|
* \n Removes the ::UserID from a vector for signature revocation.
|
||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
void OnEmailUnChecked(WCheckBox * cb);
|
void OnEmailUnChecked(WCheckBox * cb, GpgME::UserID& uid);
|
||||||
/**
|
/**
|
||||||
* Adds the option value in m_certifyOptions.
|
* Adds the option value in m_certifyOptions.
|
||||||
* @param id
|
* @param id
|
||||||
@@ -173,6 +203,11 @@ private:
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
void OnCertifyOptionUnChecked(int id);
|
void OnCertifyOptionUnChecked(int id);
|
||||||
|
/**
|
||||||
|
* Show certification options if certifying, else hide them.
|
||||||
|
* @param btn
|
||||||
|
*/
|
||||||
|
void OnButtonGroupWhat(WRadioButton * btn);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* POPUPCERTIFYUSERID_H */
|
#endif /* POPUPCERTIFYUSERID_H */
|
||||||
|
|||||||
@@ -83,8 +83,10 @@
|
|||||||
<message id='NoUidSelected'>No email address is selected</message>
|
<message id='NoUidSelected'>No email address is selected</message>
|
||||||
<message id='Apply'>Apply</message>
|
<message id='Apply'>Apply</message>
|
||||||
<message id='CertificationSuccess'>Key succesfully certified</message>
|
<message id='CertificationSuccess'>Key succesfully certified</message>
|
||||||
<message id='CertificationFailure'>Key certification failed</message>
|
<message id='RevocationSuccess'>Identity certification succesfully revoked</message>
|
||||||
<message id='OneWayHint'>Once set, this option cannot be removed. Use gpg cli for further edit.</message>
|
<message id='OneWayHint'>Once set, this option cannot be removed. Use gpg cli for further edit.</message>
|
||||||
|
<message id='CertifyUid'>Certify identities</message>
|
||||||
|
<message id='RevokeUidCertification'>Revoke certifications</message>
|
||||||
|
|
||||||
<message id='PrepareCopy'>Click to be able to copy next</message>
|
<message id='PrepareCopy'>Click to be able to copy next</message>
|
||||||
|
|
||||||
|
|||||||
@@ -83,8 +83,10 @@
|
|||||||
<message id='NoUidSelected'>Aucun courriel n'est sélectionné</message>
|
<message id='NoUidSelected'>Aucun courriel n'est sélectionné</message>
|
||||||
<message id='Apply'>Appliquer</message>
|
<message id='Apply'>Appliquer</message>
|
||||||
<message id='CertificationSuccess'>Succès de certification de la clé</message>
|
<message id='CertificationSuccess'>Succès de certification de la clé</message>
|
||||||
<message id='CertificationFailure'>Échec de certification de la clé</message>
|
<message id='RevocationSuccess'>Succès de révocation de l'identité</message>
|
||||||
<message id='OneWayHint'>Une fois appliquée, cette option ne pourra plus être enlevée. Utilisez gpg en ligne de commande pour édition ultérieure.</message>
|
<message id='OneWayHint'>Une fois appliquée, cette option ne pourra plus être enlevée. Utilisez gpg en ligne de commande pour édition ultérieure.</message>
|
||||||
|
<message id='CertifyUid'>Certifier les identités</message>
|
||||||
|
<message id='RevokeUidCertification'>Revoquer les certifications</message>
|
||||||
|
|
||||||
<message id='PrepareCopy'>Cliquez pour pouvoir ensuite copier</message>
|
<message id='PrepareCopy'>Cliquez pour pouvoir ensuite copier</message>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user