e41ae4db9e
* lang/cpp/src/key.cpp (Subkey::publicKeyAlgorithmAsString): New static variant. * lang/cpp/src/key.h: Declare function. Clarify comment about name mismatch.
838 lines
17 KiB
C++
838 lines
17 KiB
C++
/*
|
|
key.cpp - wraps a gpgme key
|
|
Copyright (C) 2003, 2005 Klarälvdalens Datakonsult AB
|
|
|
|
This file is part of GPGME++.
|
|
|
|
GPGME++ is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
GPGME++ is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with GPGME++; see the file COPYING.LIB. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <key.h>
|
|
|
|
#include "util.h"
|
|
|
|
#include <gpgme.h>
|
|
|
|
#include <string.h>
|
|
|
|
const GpgME::Key::Null GpgME::Key::null;
|
|
|
|
namespace GpgME
|
|
{
|
|
|
|
Key::Key() : key() {}
|
|
|
|
Key::Key(const Null &) : key() {}
|
|
|
|
Key::Key(const shared_gpgme_key_t &k) : key(k) {}
|
|
|
|
Key::Key(gpgme_key_t k, bool ref)
|
|
: key(k
|
|
? shared_gpgme_key_t(k, &gpgme_key_unref)
|
|
: shared_gpgme_key_t())
|
|
{
|
|
if (ref && impl()) {
|
|
gpgme_key_ref(impl());
|
|
}
|
|
}
|
|
|
|
UserID Key::userID(unsigned int index) const
|
|
{
|
|
return UserID(key, index);
|
|
}
|
|
|
|
Subkey Key::subkey(unsigned int index) const
|
|
{
|
|
return Subkey(key, index);
|
|
}
|
|
|
|
unsigned int Key::numUserIDs() const
|
|
{
|
|
if (!key) {
|
|
return 0;
|
|
}
|
|
unsigned int count = 0;
|
|
for (gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next) {
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
unsigned int Key::numSubkeys() const
|
|
{
|
|
if (!key) {
|
|
return 0;
|
|
}
|
|
unsigned int count = 0;
|
|
for (gpgme_sub_key_t subkey = key->subkeys ; subkey ; subkey = subkey->next) {
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
std::vector<UserID> Key::userIDs() const
|
|
{
|
|
if (!key) {
|
|
return std::vector<UserID>();
|
|
}
|
|
|
|
std::vector<UserID> v;
|
|
v.reserve(numUserIDs());
|
|
for (gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next) {
|
|
v.push_back(UserID(key, uid));
|
|
}
|
|
return v;
|
|
}
|
|
|
|
std::vector<Subkey> Key::subkeys() const
|
|
{
|
|
if (!key) {
|
|
return std::vector<Subkey>();
|
|
}
|
|
|
|
std::vector<Subkey> v;
|
|
v.reserve(numSubkeys());
|
|
for (gpgme_sub_key_t subkey = key->subkeys ; subkey ; subkey = subkey->next) {
|
|
v.push_back(Subkey(key, subkey));
|
|
}
|
|
return v;
|
|
}
|
|
|
|
Key::OwnerTrust Key::ownerTrust() const
|
|
{
|
|
if (!key) {
|
|
return Unknown;
|
|
}
|
|
switch (key->owner_trust) {
|
|
default:
|
|
case GPGME_VALIDITY_UNKNOWN: return Unknown;
|
|
case GPGME_VALIDITY_UNDEFINED: return Undefined;
|
|
case GPGME_VALIDITY_NEVER: return Never;
|
|
case GPGME_VALIDITY_MARGINAL: return Marginal;
|
|
case GPGME_VALIDITY_FULL: return Full;
|
|
case GPGME_VALIDITY_ULTIMATE: return Ultimate;
|
|
}
|
|
}
|
|
char Key::ownerTrustAsString() const
|
|
{
|
|
if (!key) {
|
|
return '?';
|
|
}
|
|
switch (key->owner_trust) {
|
|
default:
|
|
case GPGME_VALIDITY_UNKNOWN: return '?';
|
|
case GPGME_VALIDITY_UNDEFINED: return 'q';
|
|
case GPGME_VALIDITY_NEVER: return 'n';
|
|
case GPGME_VALIDITY_MARGINAL: return 'm';
|
|
case GPGME_VALIDITY_FULL: return 'f';
|
|
case GPGME_VALIDITY_ULTIMATE: return 'u';
|
|
}
|
|
}
|
|
|
|
Protocol Key::protocol() const
|
|
{
|
|
if (!key) {
|
|
return UnknownProtocol;
|
|
}
|
|
switch (key->protocol) {
|
|
case GPGME_PROTOCOL_CMS: return CMS;
|
|
case GPGME_PROTOCOL_OpenPGP: return OpenPGP;
|
|
default: return UnknownProtocol;
|
|
}
|
|
}
|
|
|
|
const char *Key::protocolAsString() const
|
|
{
|
|
return key ? gpgme_get_protocol_name(key->protocol) : 0 ;
|
|
}
|
|
|
|
bool Key::isRevoked() const
|
|
{
|
|
return key && key->revoked;
|
|
}
|
|
|
|
bool Key::isExpired() const
|
|
{
|
|
return key && key->expired;
|
|
}
|
|
|
|
bool Key::isDisabled() const
|
|
{
|
|
return key && key->disabled;
|
|
}
|
|
|
|
bool Key::isInvalid() const
|
|
{
|
|
return key && key->invalid;
|
|
}
|
|
|
|
bool Key::hasSecret() const
|
|
{
|
|
return key && key->secret;
|
|
}
|
|
|
|
bool Key::isRoot() const
|
|
{
|
|
return key && key->subkeys && key->subkeys->fpr && key->chain_id &&
|
|
strcasecmp(key->subkeys->fpr, key->chain_id) == 0;
|
|
}
|
|
|
|
bool Key::canEncrypt() const
|
|
{
|
|
return key && key->can_encrypt;
|
|
}
|
|
|
|
bool Key::canSign() const
|
|
{
|
|
#ifndef GPGME_CAN_SIGN_ON_SECRET_OPENPGP_KEYLISTING_NOT_BROKEN
|
|
if (key && key->protocol == GPGME_PROTOCOL_OpenPGP) {
|
|
return true;
|
|
}
|
|
#endif
|
|
return canReallySign();
|
|
}
|
|
|
|
bool Key::canReallySign() const
|
|
{
|
|
return key && key->can_sign;
|
|
}
|
|
|
|
bool Key::canCertify() const
|
|
{
|
|
return key && key->can_certify;
|
|
}
|
|
|
|
bool Key::canAuthenticate() const
|
|
{
|
|
return key && key->can_authenticate;
|
|
}
|
|
|
|
bool Key::isQualified() const
|
|
{
|
|
return key && key->is_qualified;
|
|
}
|
|
|
|
const char *Key::issuerSerial() const
|
|
{
|
|
return key ? key->issuer_serial : 0 ;
|
|
}
|
|
const char *Key::issuerName() const
|
|
{
|
|
return key ? key->issuer_name : 0 ;
|
|
}
|
|
const char *Key::chainID() const
|
|
{
|
|
return key ? key->chain_id : 0 ;
|
|
}
|
|
|
|
const char *Key::keyID() const
|
|
{
|
|
return key && key->subkeys ? key->subkeys->keyid : 0 ;
|
|
}
|
|
|
|
const char *Key::shortKeyID() const
|
|
{
|
|
if (!key || !key->subkeys || !key->subkeys->keyid) {
|
|
return 0;
|
|
}
|
|
const int len = strlen(key->subkeys->keyid);
|
|
if (len > 8) {
|
|
return key->subkeys->keyid + len - 8; // return the last 8 bytes (in hex notation)
|
|
} else {
|
|
return key->subkeys->keyid;
|
|
}
|
|
}
|
|
|
|
const char *Key::primaryFingerprint() const
|
|
{
|
|
const char *fpr = key && key->subkeys ? key->subkeys->fpr : 0 ;
|
|
if (fpr) {
|
|
return fpr;
|
|
} else {
|
|
return keyID();
|
|
}
|
|
}
|
|
|
|
unsigned int Key::keyListMode() const
|
|
{
|
|
return key ? convert_from_gpgme_keylist_mode_t(key->keylist_mode) : 0 ;
|
|
}
|
|
|
|
const Key &Key::mergeWith(const Key &other)
|
|
{
|
|
// ### incomplete. Just merges has* and can*, nothing else atm
|
|
// ### detach also missing
|
|
|
|
if (!this->primaryFingerprint() ||
|
|
!other.primaryFingerprint() ||
|
|
strcasecmp(this->primaryFingerprint(), other.primaryFingerprint()) != 0) {
|
|
return *this; // only merge the Key object which describe the same key
|
|
}
|
|
|
|
const gpgme_key_t me = impl();
|
|
const gpgme_key_t him = other.impl();
|
|
|
|
if (!me || !him) {
|
|
return *this;
|
|
}
|
|
|
|
me->revoked |= him->revoked;
|
|
me->expired |= him->expired;
|
|
me->disabled |= him->disabled;
|
|
me->invalid |= him->invalid;
|
|
me->can_encrypt |= him->can_encrypt;
|
|
me->can_sign |= him->can_sign;
|
|
me->can_certify |= him->can_certify;
|
|
me->secret |= him->secret;
|
|
me->can_authenticate |= him->can_authenticate;
|
|
me->is_qualified |= him->is_qualified;
|
|
me->keylist_mode |= him->keylist_mode;
|
|
|
|
// make sure the gpgme_sub_key_t::is_cardkey flag isn't lost:
|
|
for (gpgme_sub_key_t mysk = me->subkeys ; mysk ; mysk = mysk->next) {
|
|
for (gpgme_sub_key_t hissk = him->subkeys ; hissk ; hissk = hissk->next) {
|
|
if (strcmp(mysk->fpr, hissk->fpr) == 0) {
|
|
mysk->is_cardkey |= hissk->is_cardkey;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
//
|
|
//
|
|
// class Subkey
|
|
//
|
|
//
|
|
|
|
gpgme_sub_key_t find_subkey(const shared_gpgme_key_t &key, unsigned int idx)
|
|
{
|
|
if (key) {
|
|
for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next, --idx) {
|
|
if (idx == 0) {
|
|
return s;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
gpgme_sub_key_t verify_subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey)
|
|
{
|
|
if (key) {
|
|
for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next) {
|
|
if (s == subkey) {
|
|
return subkey;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Subkey::Subkey() : key(), subkey(0) {}
|
|
|
|
Subkey::Subkey(const shared_gpgme_key_t &k, unsigned int idx)
|
|
: key(k), subkey(find_subkey(k, idx))
|
|
{
|
|
|
|
}
|
|
|
|
Subkey::Subkey(const shared_gpgme_key_t &k, gpgme_sub_key_t sk)
|
|
: key(k), subkey(verify_subkey(k, sk))
|
|
{
|
|
|
|
}
|
|
|
|
Key Subkey::parent() const
|
|
{
|
|
return Key(key);
|
|
}
|
|
|
|
const char *Subkey::keyID() const
|
|
{
|
|
return subkey ? subkey->keyid : 0 ;
|
|
}
|
|
|
|
const char *Subkey::fingerprint() const
|
|
{
|
|
return subkey ? subkey->fpr : 0 ;
|
|
}
|
|
|
|
Subkey::PubkeyAlgo Subkey::publicKeyAlgorithm() const
|
|
{
|
|
return subkey ? static_cast<PubkeyAlgo>(subkey->pubkey_algo) : AlgoUnknown;
|
|
}
|
|
|
|
const char *Subkey::publicKeyAlgorithmAsString() const
|
|
{
|
|
return gpgme_pubkey_algo_name(subkey ? subkey->pubkey_algo : (gpgme_pubkey_algo_t)0);
|
|
}
|
|
|
|
/* static */
|
|
const char *Subkey::publicKeyAlgorithmAsString(PubkeyAlgo algo)
|
|
{
|
|
if (algo == AlgoUnknown) {
|
|
return NULL;
|
|
}
|
|
return gpgme_pubkey_algo_name(static_cast<gpgme_pubkey_algo_t>(algo));
|
|
}
|
|
|
|
std::string Subkey::algoName() const
|
|
{
|
|
char *gpgmeStr;
|
|
if (subkey && (gpgmeStr = gpgme_pubkey_algo_string(subkey))) {
|
|
std::string ret = std::string(gpgmeStr);
|
|
gpgme_free(gpgmeStr);
|
|
return ret;
|
|
}
|
|
return std::string();
|
|
}
|
|
|
|
bool Subkey::canEncrypt() const
|
|
{
|
|
return subkey && subkey->can_encrypt;
|
|
}
|
|
|
|
bool Subkey::canSign() const
|
|
{
|
|
return subkey && subkey->can_sign;
|
|
}
|
|
|
|
bool Subkey::canCertify() const
|
|
{
|
|
return subkey && subkey->can_certify;
|
|
}
|
|
|
|
bool Subkey::canAuthenticate() const
|
|
{
|
|
return subkey && subkey->can_authenticate;
|
|
}
|
|
|
|
bool Subkey::isQualified() const
|
|
{
|
|
return subkey && subkey->is_qualified;
|
|
}
|
|
|
|
bool Subkey::isCardKey() const
|
|
{
|
|
return subkey && subkey->is_cardkey;
|
|
}
|
|
|
|
const char *Subkey::cardSerialNumber() const
|
|
{
|
|
return subkey ? subkey->card_number : 0 ;
|
|
}
|
|
|
|
bool Subkey::isSecret() const
|
|
{
|
|
return subkey && subkey->secret;
|
|
}
|
|
|
|
unsigned int Subkey::length() const
|
|
{
|
|
return subkey ? subkey->length : 0 ;
|
|
}
|
|
|
|
time_t Subkey::creationTime() const
|
|
{
|
|
return static_cast<time_t>(subkey ? subkey->timestamp : 0);
|
|
}
|
|
|
|
time_t Subkey::expirationTime() const
|
|
{
|
|
return static_cast<time_t>(subkey ? subkey->expires : 0);
|
|
}
|
|
|
|
bool Subkey::neverExpires() const
|
|
{
|
|
return expirationTime() == time_t(0);
|
|
}
|
|
|
|
bool Subkey::isRevoked() const
|
|
{
|
|
return subkey && subkey->revoked;
|
|
}
|
|
|
|
bool Subkey::isInvalid() const
|
|
{
|
|
return subkey && subkey->invalid;
|
|
}
|
|
|
|
bool Subkey::isExpired() const
|
|
{
|
|
return subkey && subkey->expired;
|
|
}
|
|
|
|
bool Subkey::isDisabled() const
|
|
{
|
|
return subkey && subkey->disabled;
|
|
}
|
|
|
|
//
|
|
//
|
|
// class UserID
|
|
//
|
|
//
|
|
|
|
gpgme_user_id_t find_uid(const shared_gpgme_key_t &key, unsigned int idx)
|
|
{
|
|
if (key) {
|
|
for (gpgme_user_id_t u = key->uids ; u ; u = u->next, --idx) {
|
|
if (idx == 0) {
|
|
return u;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
gpgme_user_id_t verify_uid(const shared_gpgme_key_t &key, gpgme_user_id_t uid)
|
|
{
|
|
if (key) {
|
|
for (gpgme_user_id_t u = key->uids ; u ; u = u->next) {
|
|
if (u == uid) {
|
|
return uid;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
UserID::UserID() : key(), uid(0) {}
|
|
|
|
UserID::UserID(const shared_gpgme_key_t &k, gpgme_user_id_t u)
|
|
: key(k), uid(verify_uid(k, u))
|
|
{
|
|
|
|
}
|
|
|
|
UserID::UserID(const shared_gpgme_key_t &k, unsigned int idx)
|
|
: key(k), uid(find_uid(k, idx))
|
|
{
|
|
|
|
}
|
|
|
|
Key UserID::parent() const
|
|
{
|
|
return Key(key);
|
|
}
|
|
|
|
UserID::Signature UserID::signature(unsigned int index) const
|
|
{
|
|
return Signature(key, uid, index);
|
|
}
|
|
|
|
unsigned int UserID::numSignatures() const
|
|
{
|
|
if (!uid) {
|
|
return 0;
|
|
}
|
|
unsigned int count = 0;
|
|
for (gpgme_key_sig_t sig = uid->signatures ; sig ; sig = sig->next) {
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
std::vector<UserID::Signature> UserID::signatures() const
|
|
{
|
|
if (!uid) {
|
|
return std::vector<Signature>();
|
|
}
|
|
|
|
std::vector<Signature> v;
|
|
v.reserve(numSignatures());
|
|
for (gpgme_key_sig_t sig = uid->signatures ; sig ; sig = sig->next) {
|
|
v.push_back(Signature(key, uid, sig));
|
|
}
|
|
return v;
|
|
}
|
|
|
|
const char *UserID::id() const
|
|
{
|
|
return uid ? uid->uid : 0 ;
|
|
}
|
|
|
|
const char *UserID::name() const
|
|
{
|
|
return uid ? uid->name : 0 ;
|
|
}
|
|
|
|
const char *UserID::email() const
|
|
{
|
|
return uid ? uid->email : 0 ;
|
|
}
|
|
|
|
const char *UserID::comment() const
|
|
{
|
|
return uid ? uid->comment : 0 ;
|
|
}
|
|
|
|
UserID::Validity UserID::validity() const
|
|
{
|
|
if (!uid) {
|
|
return Unknown;
|
|
}
|
|
switch (uid->validity) {
|
|
default:
|
|
case GPGME_VALIDITY_UNKNOWN: return Unknown;
|
|
case GPGME_VALIDITY_UNDEFINED: return Undefined;
|
|
case GPGME_VALIDITY_NEVER: return Never;
|
|
case GPGME_VALIDITY_MARGINAL: return Marginal;
|
|
case GPGME_VALIDITY_FULL: return Full;
|
|
case GPGME_VALIDITY_ULTIMATE: return Ultimate;
|
|
}
|
|
}
|
|
|
|
char UserID::validityAsString() const
|
|
{
|
|
if (!uid) {
|
|
return '?';
|
|
}
|
|
switch (uid->validity) {
|
|
default:
|
|
case GPGME_VALIDITY_UNKNOWN: return '?';
|
|
case GPGME_VALIDITY_UNDEFINED: return 'q';
|
|
case GPGME_VALIDITY_NEVER: return 'n';
|
|
case GPGME_VALIDITY_MARGINAL: return 'm';
|
|
case GPGME_VALIDITY_FULL: return 'f';
|
|
case GPGME_VALIDITY_ULTIMATE: return 'u';
|
|
}
|
|
}
|
|
|
|
bool UserID::isRevoked() const
|
|
{
|
|
return uid && uid->revoked;
|
|
}
|
|
|
|
bool UserID::isInvalid() const
|
|
{
|
|
return uid && uid->invalid;
|
|
}
|
|
|
|
//
|
|
//
|
|
// class Signature
|
|
//
|
|
//
|
|
|
|
gpgme_key_sig_t find_signature(gpgme_user_id_t uid, unsigned int idx)
|
|
{
|
|
if (uid) {
|
|
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, --idx) {
|
|
if (idx == 0) {
|
|
return s;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
gpgme_key_sig_t verify_signature(gpgme_user_id_t uid, gpgme_key_sig_t sig)
|
|
{
|
|
if (uid) {
|
|
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) {
|
|
if (s == sig) {
|
|
return sig;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
UserID::Signature::Signature() : key(), uid(0), sig(0) {}
|
|
|
|
UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, unsigned int idx)
|
|
: key(k), uid(verify_uid(k, u)), sig(find_signature(uid, idx))
|
|
{
|
|
|
|
}
|
|
|
|
UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, gpgme_key_sig_t s)
|
|
: key(k), uid(verify_uid(k, u)), sig(verify_signature(uid, s))
|
|
{
|
|
|
|
}
|
|
|
|
UserID UserID::Signature::parent() const
|
|
{
|
|
return UserID(key, uid);
|
|
}
|
|
|
|
const char *UserID::Signature::signerKeyID() const
|
|
{
|
|
return sig ? sig->keyid : 0 ;
|
|
}
|
|
|
|
const char *UserID::Signature::algorithmAsString() const
|
|
{
|
|
return gpgme_pubkey_algo_name(sig ? sig->pubkey_algo : (gpgme_pubkey_algo_t)0);
|
|
}
|
|
|
|
unsigned int UserID::Signature::algorithm() const
|
|
{
|
|
return sig ? sig->pubkey_algo : 0 ;
|
|
}
|
|
|
|
time_t UserID::Signature::creationTime() const
|
|
{
|
|
return static_cast<time_t>(sig ? sig->timestamp : 0);
|
|
}
|
|
|
|
time_t UserID::Signature::expirationTime() const
|
|
{
|
|
return static_cast<time_t>(sig ? sig->expires : 0);
|
|
}
|
|
|
|
bool UserID::Signature::neverExpires() const
|
|
{
|
|
return expirationTime() == time_t(0);
|
|
}
|
|
|
|
bool UserID::Signature::isRevokation() const
|
|
{
|
|
return sig && sig->revoked;
|
|
}
|
|
|
|
bool UserID::Signature::isInvalid() const
|
|
{
|
|
return sig && sig->invalid;
|
|
}
|
|
|
|
bool UserID::Signature::isExpired() const
|
|
{
|
|
return sig && sig->expired;
|
|
}
|
|
|
|
bool UserID::Signature::isExportable() const
|
|
{
|
|
return sig && sig->exportable;
|
|
}
|
|
|
|
const char *UserID::Signature::signerUserID() const
|
|
{
|
|
return sig ? sig->uid : 0 ;
|
|
}
|
|
|
|
const char *UserID::Signature::signerName() const
|
|
{
|
|
return sig ? sig->name : 0 ;
|
|
}
|
|
|
|
const char *UserID::Signature::signerEmail() const
|
|
{
|
|
return sig ? sig->email : 0 ;
|
|
}
|
|
|
|
const char *UserID::Signature::signerComment() const
|
|
{
|
|
return sig ? sig->comment : 0 ;
|
|
}
|
|
|
|
unsigned int UserID::Signature::certClass() const
|
|
{
|
|
return sig ? sig->sig_class : 0 ;
|
|
}
|
|
|
|
UserID::Signature::Status UserID::Signature::status() const
|
|
{
|
|
if (!sig) {
|
|
return GeneralError;
|
|
}
|
|
|
|
switch (gpgme_err_code(sig->status)) {
|
|
case GPG_ERR_NO_ERROR: return NoError;
|
|
case GPG_ERR_SIG_EXPIRED: return SigExpired;
|
|
case GPG_ERR_KEY_EXPIRED: return KeyExpired;
|
|
case GPG_ERR_BAD_SIGNATURE: return BadSignature;
|
|
case GPG_ERR_NO_PUBKEY: return NoPublicKey;
|
|
default:
|
|
case GPG_ERR_GENERAL: return GeneralError;
|
|
}
|
|
}
|
|
|
|
std::string UserID::Signature::statusAsString() const
|
|
{
|
|
if (!sig) {
|
|
return std::string();
|
|
}
|
|
char buf[ 1024 ];
|
|
gpgme_strerror_r(sig->status, buf, sizeof buf);
|
|
buf[ sizeof buf - 1 ] = '\0';
|
|
return std::string(buf);
|
|
}
|
|
|
|
GpgME::Notation UserID::Signature::notation(unsigned int idx) const
|
|
{
|
|
if (!sig) {
|
|
return GpgME::Notation();
|
|
}
|
|
for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
|
|
if (nota->name) {
|
|
if (idx-- == 0) {
|
|
return GpgME::Notation(nota);
|
|
}
|
|
}
|
|
}
|
|
return GpgME::Notation();
|
|
}
|
|
|
|
unsigned int UserID::Signature::numNotations() const
|
|
{
|
|
if (!sig) {
|
|
return 0;
|
|
}
|
|
unsigned int count = 0;
|
|
for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
|
|
if (nota->name) {
|
|
++count; // others are policy URLs...
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
std::vector<Notation> UserID::Signature::notations() const
|
|
{
|
|
if (!sig) {
|
|
return std::vector<GpgME::Notation>();
|
|
}
|
|
std::vector<GpgME::Notation> v;
|
|
v.reserve(numNotations());
|
|
for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
|
|
if (nota->name) {
|
|
v.push_back(GpgME::Notation(nota));
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
|
|
const char *UserID::Signature::policyURL() const
|
|
{
|
|
if (!sig) {
|
|
return 0;
|
|
}
|
|
for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
|
|
if (!nota->name) {
|
|
return nota->value;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
} // namespace GpgME
|