LCOV - code coverage report
Current view: top level - lang/cpp/src - key.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 97 435 22.3 %
Date: 2016-09-12 13:07:23 Functions: 24 112 21.4 %

          Line data    Source code
       1             : /*
       2             :   key.cpp - wraps a gpgme key
       3             :   Copyright (C) 2003, 2005 Klarälvdalens Datakonsult AB
       4             : 
       5             :   This file is part of GPGME++.
       6             : 
       7             :   GPGME++ is free software; you can redistribute it and/or
       8             :   modify it under the terms of the GNU Library General Public
       9             :   License as published by the Free Software Foundation; either
      10             :   version 2 of the License, or (at your option) any later version.
      11             : 
      12             :   GPGME++ is distributed in the hope that it will be useful,
      13             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :   GNU Library General Public License for more details.
      16             : 
      17             :   You should have received a copy of the GNU Library General Public License
      18             :   along with GPGME++; see the file COPYING.LIB.  If not, write to the
      19             :   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      20             :   Boston, MA 02110-1301, USA.
      21             : */
      22             : 
      23             : #include <key.h>
      24             : 
      25             : #include "util.h"
      26             : #include "tofuinfo.h"
      27             : #include "context.h"
      28             : 
      29             : #include <gpgme.h>
      30             : 
      31             : #include <string.h>
      32             : #include <istream>
      33             : #include <iterator>
      34             : 
      35           6 : const GpgME::Key::Null GpgME::Key::null;
      36             : 
      37             : namespace GpgME
      38             : {
      39             : 
      40           0 : Key::Key() : key() {}
      41             : 
      42           0 : Key::Key(const Null &) : key() {}
      43             : 
      44           0 : Key::Key(const shared_gpgme_key_t &k) : key(k) {}
      45             : 
      46          36 : Key::Key(gpgme_key_t k, bool ref)
      47             :     : key(k
      48             :           ? shared_gpgme_key_t(k, &gpgme_key_unref)
      49          36 :           : shared_gpgme_key_t())
      50             : {
      51          36 :     if (ref && impl()) {
      52           9 :         gpgme_key_ref(impl());
      53             :     }
      54          36 : }
      55             : 
      56          12 : UserID Key::userID(unsigned int index) const
      57             : {
      58          12 :     return UserID(key, index);
      59             : }
      60             : 
      61           0 : Subkey Key::subkey(unsigned int index) const
      62             : {
      63           0 :     return Subkey(key, index);
      64             : }
      65             : 
      66           8 : unsigned int Key::numUserIDs() const
      67             : {
      68           8 :     if (!key) {
      69           0 :         return 0;
      70             :     }
      71           8 :     unsigned int count = 0;
      72          20 :     for (gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next) {
      73          12 :         ++count;
      74             :     }
      75           8 :     return count;
      76             : }
      77             : 
      78           3 : unsigned int Key::numSubkeys() const
      79             : {
      80           3 :     if (!key) {
      81           0 :         return 0;
      82             :     }
      83           3 :     unsigned int count = 0;
      84           9 :     for (gpgme_sub_key_t subkey = key->subkeys ; subkey ; subkey = subkey->next) {
      85           6 :         ++count;
      86             :     }
      87           3 :     return count;
      88             : }
      89             : 
      90           7 : std::vector<UserID> Key::userIDs() const
      91             : {
      92           7 :     if (!key) {
      93           0 :         return std::vector<UserID>();
      94             :     }
      95             : 
      96           7 :     std::vector<UserID> v;
      97           7 :     v.reserve(numUserIDs());
      98          16 :     for (gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next) {
      99           9 :         v.push_back(UserID(key, uid));
     100             :     }
     101           7 :     return v;
     102             : }
     103             : 
     104           3 : std::vector<Subkey> Key::subkeys() const
     105             : {
     106           3 :     if (!key) {
     107           0 :         return std::vector<Subkey>();
     108             :     }
     109             : 
     110           3 :     std::vector<Subkey> v;
     111           3 :     v.reserve(numSubkeys());
     112           9 :     for (gpgme_sub_key_t subkey = key->subkeys ; subkey ; subkey = subkey->next) {
     113           6 :         v.push_back(Subkey(key, subkey));
     114             :     }
     115           3 :     return v;
     116             : }
     117             : 
     118           3 : Key::OwnerTrust Key::ownerTrust() const
     119             : {
     120           3 :     if (!key) {
     121           0 :         return Unknown;
     122             :     }
     123           3 :     switch (key->owner_trust) {
     124             :     default:
     125           2 :     case GPGME_VALIDITY_UNKNOWN:   return Unknown;
     126           0 :     case GPGME_VALIDITY_UNDEFINED: return Undefined;
     127           0 :     case GPGME_VALIDITY_NEVER:     return Never;
     128           0 :     case GPGME_VALIDITY_MARGINAL:  return Marginal;
     129           0 :     case GPGME_VALIDITY_FULL:     return Full;
     130           1 :     case GPGME_VALIDITY_ULTIMATE: return Ultimate;
     131             :     }
     132             : }
     133           0 : char Key::ownerTrustAsString() const
     134             : {
     135           0 :     if (!key) {
     136           0 :         return '?';
     137             :     }
     138           0 :     switch (key->owner_trust) {
     139             :     default:
     140           0 :     case GPGME_VALIDITY_UNKNOWN:   return '?';
     141           0 :     case GPGME_VALIDITY_UNDEFINED: return 'q';
     142           0 :     case GPGME_VALIDITY_NEVER:     return 'n';
     143           0 :     case GPGME_VALIDITY_MARGINAL:  return 'm';
     144           0 :     case GPGME_VALIDITY_FULL:     return 'f';
     145           0 :     case GPGME_VALIDITY_ULTIMATE: return 'u';
     146             :     }
     147             : }
     148             : 
     149           5 : Protocol Key::protocol() const
     150             : {
     151           5 :     if (!key) {
     152           0 :         return UnknownProtocol;
     153             :     }
     154           5 :     switch (key->protocol) {
     155           0 :     case GPGME_PROTOCOL_CMS:     return CMS;
     156           5 :     case GPGME_PROTOCOL_OpenPGP: return OpenPGP;
     157           0 :     default:                     return UnknownProtocol;
     158             :     }
     159             : }
     160             : 
     161           0 : const char *Key::protocolAsString() const
     162             : {
     163           0 :     return key ? gpgme_get_protocol_name(key->protocol) : 0 ;
     164             : }
     165             : 
     166           0 : bool Key::isRevoked() const
     167             : {
     168           0 :     return key && key->revoked;
     169             : }
     170             : 
     171           0 : bool Key::isExpired() const
     172             : {
     173           0 :     return key && key->expired;
     174             : }
     175             : 
     176           0 : bool Key::isDisabled() const
     177             : {
     178           0 :     return key && key->disabled;
     179             : }
     180             : 
     181           0 : bool Key::isInvalid() const
     182             : {
     183           0 :     return key && key->invalid;
     184             : }
     185             : 
     186           5 : bool Key::hasSecret() const
     187             : {
     188           5 :     return key && key->secret;
     189             : }
     190             : 
     191           0 : bool Key::isRoot() const
     192             : {
     193           0 :     return key && key->subkeys && key->subkeys->fpr && key->chain_id &&
     194           0 :            strcasecmp(key->subkeys->fpr, key->chain_id) == 0;
     195             : }
     196             : 
     197           0 : bool Key::canEncrypt() const
     198             : {
     199           0 :     return key && key->can_encrypt;
     200             : }
     201             : 
     202           0 : bool Key::canSign() const
     203             : {
     204             : #ifndef GPGME_CAN_SIGN_ON_SECRET_OPENPGP_KEYLISTING_NOT_BROKEN
     205           0 :     if (key && key->protocol == GPGME_PROTOCOL_OpenPGP) {
     206           0 :         return true;
     207             :     }
     208             : #endif
     209           0 :     return canReallySign();
     210             : }
     211             : 
     212           0 : bool Key::canReallySign() const
     213             : {
     214           0 :     return key && key->can_sign;
     215             : }
     216             : 
     217           0 : bool Key::canCertify() const
     218             : {
     219           0 :     return key && key->can_certify;
     220             : }
     221             : 
     222           0 : bool Key::canAuthenticate() const
     223             : {
     224           0 :     return key && key->can_authenticate;
     225             : }
     226             : 
     227           0 : bool Key::isQualified() const
     228             : {
     229           0 :     return key && key->is_qualified;
     230             : }
     231             : 
     232           0 : const char *Key::issuerSerial() const
     233             : {
     234           0 :     return key ? key->issuer_serial : 0 ;
     235             : }
     236           0 : const char *Key::issuerName() const
     237             : {
     238           0 :     return key ? key->issuer_name : 0 ;
     239             : }
     240           0 : const char *Key::chainID() const
     241             : {
     242           0 :     return key ? key->chain_id : 0 ;
     243             : }
     244             : 
     245           1 : const char *Key::keyID() const
     246             : {
     247           1 :     return key && key->subkeys ? key->subkeys->keyid : 0 ;
     248             : }
     249             : 
     250           0 : const char *Key::shortKeyID() const
     251             : {
     252           0 :     if (!key || !key->subkeys || !key->subkeys->keyid) {
     253           0 :         return 0;
     254             :     }
     255           0 :     const int len = strlen(key->subkeys->keyid);
     256           0 :     if (len > 8) {
     257           0 :         return key->subkeys->keyid + len - 8; // return the last 8 bytes (in hex notation)
     258             :     } else {
     259           0 :         return key->subkeys->keyid;
     260             :     }
     261             : }
     262             : 
     263          27 : const char *Key::primaryFingerprint() const
     264             : {
     265          27 :     if (!key) {
     266           0 :         return nullptr;
     267             :     }
     268          27 :     if (key->fpr) {
     269             :         /* Return what gpgme thinks is the primary fingerprint */
     270          27 :         return key->fpr;
     271             :     }
     272           0 :     if (key->subkeys) {
     273             :         /* Return the first subkeys fingerprint */
     274           0 :         return key->subkeys->fpr;
     275             :     }
     276           0 : }
     277             : 
     278           0 : unsigned int Key::keyListMode() const
     279             : {
     280           0 :     return key ? convert_from_gpgme_keylist_mode_t(key->keylist_mode) : 0 ;
     281             : }
     282             : 
     283           0 : const Key &Key::mergeWith(const Key &other)
     284             : {
     285             :     // ### incomplete. Just merges has* and can*, nothing else atm
     286             :     // ### detach also missing
     287             : 
     288           0 :     if (!this->primaryFingerprint() ||
     289           0 :             !other.primaryFingerprint() ||
     290           0 :             strcasecmp(this->primaryFingerprint(), other.primaryFingerprint()) != 0) {
     291           0 :         return *this; // only merge the Key object which describe the same key
     292             :     }
     293             : 
     294           0 :     const gpgme_key_t me = impl();
     295           0 :     const gpgme_key_t him = other.impl();
     296             : 
     297           0 :     if (!me || !him) {
     298           0 :         return *this;
     299             :     }
     300             : 
     301           0 :     me->revoked          |= him->revoked;
     302           0 :     me->expired          |= him->expired;
     303           0 :     me->disabled         |= him->disabled;
     304           0 :     me->invalid          |= him->invalid;
     305           0 :     me->can_encrypt      |= him->can_encrypt;
     306           0 :     me->can_sign         |= him->can_sign;
     307           0 :     me->can_certify      |= him->can_certify;
     308           0 :     me->secret           |= him->secret;
     309           0 :     me->can_authenticate |= him->can_authenticate;
     310           0 :     me->is_qualified     |= him->is_qualified;
     311           0 :     me->keylist_mode     |= him->keylist_mode;
     312             : 
     313             :     // make sure the gpgme_sub_key_t::is_cardkey flag isn't lost:
     314           0 :     for (gpgme_sub_key_t mysk = me->subkeys ; mysk ; mysk = mysk->next) {
     315           0 :         for (gpgme_sub_key_t hissk = him->subkeys ; hissk ; hissk = hissk->next) {
     316           0 :             if (strcmp(mysk->fpr, hissk->fpr) == 0) {
     317           0 :                 mysk->is_cardkey |= hissk->is_cardkey;
     318           0 :                 break;
     319             :             }
     320             :         }
     321             :     }
     322             : 
     323           0 :     return *this;
     324             : }
     325             : 
     326           5 : void Key::update()
     327             : {
     328           5 :     auto ctx = Context::createForProtocol(protocol());
     329           5 :     if (!ctx) {
     330           0 :         return;
     331             :     }
     332             :     ctx->setKeyListMode(KeyListMode::Local |
     333             :                         KeyListMode::Signatures |
     334             :                         KeyListMode::SignatureNotations |
     335             :                         KeyListMode::Validate |
     336           5 :                         KeyListMode::WithTofu);
     337           5 :     Error err;
     338          10 :     auto newKey = ctx->key(primaryFingerprint(), err, hasSecret());
     339           5 :     delete ctx;
     340           5 :     if (err) {
     341           0 :         return;
     342             :     }
     343           5 :     swap(newKey);
     344          10 :     return;
     345             : }
     346             : 
     347             : //
     348             : //
     349             : // class Subkey
     350             : //
     351             : //
     352             : 
     353           0 : gpgme_sub_key_t find_subkey(const shared_gpgme_key_t &key, unsigned int idx)
     354             : {
     355           0 :     if (key) {
     356           0 :         for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next, --idx) {
     357           0 :             if (idx == 0) {
     358           0 :                 return s;
     359             :             }
     360             :         }
     361             :     }
     362           0 :     return 0;
     363             : }
     364             : 
     365           6 : gpgme_sub_key_t verify_subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey)
     366             : {
     367           6 :     if (key) {
     368           9 :         for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next) {
     369           9 :             if (s == subkey) {
     370           6 :                 return subkey;
     371             :             }
     372             :         }
     373             :     }
     374           0 :     return 0;
     375             : }
     376             : 
     377           0 : Subkey::Subkey() : key(), subkey(0) {}
     378             : 
     379           0 : Subkey::Subkey(const shared_gpgme_key_t &k, unsigned int idx)
     380           0 :     : key(k), subkey(find_subkey(k, idx))
     381             : {
     382             : 
     383           0 : }
     384             : 
     385           6 : Subkey::Subkey(const shared_gpgme_key_t &k, gpgme_sub_key_t sk)
     386           6 :     : key(k), subkey(verify_subkey(k, sk))
     387             : {
     388             : 
     389           6 : }
     390             : 
     391           0 : Key Subkey::parent() const
     392             : {
     393           0 :     return Key(key);
     394             : }
     395             : 
     396           0 : const char *Subkey::keyID() const
     397             : {
     398           0 :     return subkey ? subkey->keyid : 0 ;
     399             : }
     400             : 
     401           0 : const char *Subkey::fingerprint() const
     402             : {
     403           0 :     return subkey ? subkey->fpr : 0 ;
     404             : }
     405             : 
     406           2 : Subkey::PubkeyAlgo Subkey::publicKeyAlgorithm() const
     407             : {
     408           2 :     return subkey ? static_cast<PubkeyAlgo>(subkey->pubkey_algo) : AlgoUnknown;
     409             : }
     410             : 
     411           0 : const char *Subkey::publicKeyAlgorithmAsString() const
     412             : {
     413           0 :     return gpgme_pubkey_algo_name(subkey ? subkey->pubkey_algo : (gpgme_pubkey_algo_t)0);
     414             : }
     415             : 
     416             : /* static */
     417          11 : const char *Subkey::publicKeyAlgorithmAsString(PubkeyAlgo algo)
     418             : {
     419          11 :     if (algo == AlgoUnknown) {
     420           1 :         return NULL;
     421             :     }
     422          10 :     return gpgme_pubkey_algo_name(static_cast<gpgme_pubkey_algo_t>(algo));
     423             : }
     424             : 
     425           0 : std::string Subkey::algoName() const
     426             : {
     427             :     char *gpgmeStr;
     428           0 :     if (subkey && (gpgmeStr = gpgme_pubkey_algo_string(subkey))) {
     429           0 :         std::string ret = std::string(gpgmeStr);
     430           0 :         gpgme_free(gpgmeStr);
     431           0 :         return ret;
     432             :     }
     433           0 :     return std::string();
     434             : }
     435             : 
     436           0 : bool Subkey::canEncrypt() const
     437             : {
     438           0 :     return subkey && subkey->can_encrypt;
     439             : }
     440             : 
     441           0 : bool Subkey::canSign() const
     442             : {
     443           0 :     return subkey && subkey->can_sign;
     444             : }
     445             : 
     446           0 : bool Subkey::canCertify() const
     447             : {
     448           0 :     return subkey && subkey->can_certify;
     449             : }
     450             : 
     451           0 : bool Subkey::canAuthenticate() const
     452             : {
     453           0 :     return subkey && subkey->can_authenticate;
     454             : }
     455             : 
     456           0 : bool Subkey::isQualified() const
     457             : {
     458           0 :     return subkey && subkey->is_qualified;
     459             : }
     460             : 
     461           0 : bool Subkey::isCardKey() const
     462             : {
     463           0 :     return subkey && subkey->is_cardkey;
     464             : }
     465             : 
     466           0 : const char *Subkey::cardSerialNumber() const
     467             : {
     468           0 :     return subkey ? subkey->card_number : 0 ;
     469             : }
     470             : 
     471           0 : bool Subkey::isSecret() const
     472             : {
     473           0 :     return subkey && subkey->secret;
     474             : }
     475             : 
     476           0 : unsigned int Subkey::length() const
     477             : {
     478           0 :     return subkey ? subkey->length : 0 ;
     479             : }
     480             : 
     481           0 : time_t Subkey::creationTime() const
     482             : {
     483           0 :     return static_cast<time_t>(subkey ? subkey->timestamp : 0);
     484             : }
     485             : 
     486           0 : time_t Subkey::expirationTime() const
     487             : {
     488           0 :     return static_cast<time_t>(subkey ? subkey->expires : 0);
     489             : }
     490             : 
     491           0 : bool Subkey::neverExpires() const
     492             : {
     493           0 :     return expirationTime() == time_t(0);
     494             : }
     495             : 
     496           0 : bool Subkey::isRevoked() const
     497             : {
     498           0 :     return subkey && subkey->revoked;
     499             : }
     500             : 
     501           0 : bool Subkey::isInvalid() const
     502             : {
     503           0 :     return subkey && subkey->invalid;
     504             : }
     505             : 
     506           0 : bool Subkey::isExpired() const
     507             : {
     508           0 :     return subkey && subkey->expired;
     509             : }
     510             : 
     511           0 : bool Subkey::isDisabled() const
     512             : {
     513           0 :     return subkey && subkey->disabled;
     514             : }
     515             : 
     516             : //
     517             : //
     518             : // class UserID
     519             : //
     520             : //
     521             : 
     522          12 : gpgme_user_id_t find_uid(const shared_gpgme_key_t &key, unsigned int idx)
     523             : {
     524          12 :     if (key) {
     525          12 :         for (gpgme_user_id_t u = key->uids ; u ; u = u->next, --idx) {
     526          12 :             if (idx == 0) {
     527          12 :                 return u;
     528             :             }
     529             :         }
     530             :     }
     531           0 :     return 0;
     532             : }
     533             : 
     534           9 : gpgme_user_id_t verify_uid(const shared_gpgme_key_t &key, gpgme_user_id_t uid)
     535             : {
     536           9 :     if (key) {
     537          12 :         for (gpgme_user_id_t u = key->uids ; u ; u = u->next) {
     538          12 :             if (u == uid) {
     539           9 :                 return uid;
     540             :             }
     541             :         }
     542             :     }
     543           0 :     return 0;
     544             : }
     545             : 
     546           0 : UserID::UserID() : key(), uid(0) {}
     547             : 
     548           9 : UserID::UserID(const shared_gpgme_key_t &k, gpgme_user_id_t u)
     549           9 :     : key(k), uid(verify_uid(k, u))
     550             : {
     551             : 
     552           9 : }
     553             : 
     554          12 : UserID::UserID(const shared_gpgme_key_t &k, unsigned int idx)
     555          12 :     : key(k), uid(find_uid(k, idx))
     556             : {
     557             : 
     558          12 : }
     559             : 
     560           0 : Key UserID::parent() const
     561             : {
     562           0 :     return Key(key);
     563             : }
     564             : 
     565           0 : UserID::Signature UserID::signature(unsigned int index) const
     566             : {
     567           0 :     return Signature(key, uid, index);
     568             : }
     569             : 
     570           0 : unsigned int UserID::numSignatures() const
     571             : {
     572           0 :     if (!uid) {
     573           0 :         return 0;
     574             :     }
     575           0 :     unsigned int count = 0;
     576           0 :     for (gpgme_key_sig_t sig = uid->signatures ; sig ; sig = sig->next) {
     577           0 :         ++count;
     578             :     }
     579           0 :     return count;
     580             : }
     581             : 
     582           0 : std::vector<UserID::Signature> UserID::signatures() const
     583             : {
     584           0 :     if (!uid) {
     585           0 :         return std::vector<Signature>();
     586             :     }
     587             : 
     588           0 :     std::vector<Signature> v;
     589           0 :     v.reserve(numSignatures());
     590           0 :     for (gpgme_key_sig_t sig = uid->signatures ; sig ; sig = sig->next) {
     591           0 :         v.push_back(Signature(key, uid, sig));
     592             :     }
     593           0 :     return v;
     594             : }
     595             : 
     596           0 : const char *UserID::id() const
     597             : {
     598           0 :     return uid ? uid->uid : 0 ;
     599             : }
     600             : 
     601           0 : const char *UserID::name() const
     602             : {
     603           0 :     return uid ? uid->name : 0 ;
     604             : }
     605             : 
     606           3 : const char *UserID::email() const
     607             : {
     608           3 :     return uid ? uid->email : 0 ;
     609             : }
     610             : 
     611           0 : const char *UserID::comment() const
     612             : {
     613           0 :     return uid ? uid->comment : 0 ;
     614             : }
     615             : 
     616           0 : UserID::Validity UserID::validity() const
     617             : {
     618           0 :     if (!uid) {
     619           0 :         return Unknown;
     620             :     }
     621           0 :     switch (uid->validity) {
     622             :     default:
     623           0 :     case GPGME_VALIDITY_UNKNOWN:   return Unknown;
     624           0 :     case GPGME_VALIDITY_UNDEFINED: return Undefined;
     625           0 :     case GPGME_VALIDITY_NEVER:     return Never;
     626           0 :     case GPGME_VALIDITY_MARGINAL:  return Marginal;
     627           0 :     case GPGME_VALIDITY_FULL:      return Full;
     628           0 :     case GPGME_VALIDITY_ULTIMATE:  return Ultimate;
     629             :     }
     630             : }
     631             : 
     632           0 : char UserID::validityAsString() const
     633             : {
     634           0 :     if (!uid) {
     635           0 :         return '?';
     636             :     }
     637           0 :     switch (uid->validity) {
     638             :     default:
     639           0 :     case GPGME_VALIDITY_UNKNOWN:   return '?';
     640           0 :     case GPGME_VALIDITY_UNDEFINED: return 'q';
     641           0 :     case GPGME_VALIDITY_NEVER:     return 'n';
     642           0 :     case GPGME_VALIDITY_MARGINAL:  return 'm';
     643           0 :     case GPGME_VALIDITY_FULL:      return 'f';
     644           0 :     case GPGME_VALIDITY_ULTIMATE:  return 'u';
     645             :     }
     646             : }
     647             : 
     648           0 : bool UserID::isRevoked() const
     649             : {
     650           0 :     return uid && uid->revoked;
     651             : }
     652             : 
     653           0 : bool UserID::isInvalid() const
     654             : {
     655           0 :     return uid && uid->invalid;
     656             : }
     657             : 
     658          18 : TofuInfo UserID::tofuInfo() const
     659             : {
     660          18 :     if (!uid) {
     661           0 :         return TofuInfo();
     662             :     }
     663          18 :     return TofuInfo(uid->tofu);
     664             : }
     665             : 
     666             : //
     667             : //
     668             : // class Signature
     669             : //
     670             : //
     671             : 
     672           0 : gpgme_key_sig_t find_signature(gpgme_user_id_t uid, unsigned int idx)
     673             : {
     674           0 :     if (uid) {
     675           0 :         for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, --idx) {
     676           0 :             if (idx == 0) {
     677           0 :                 return s;
     678             :             }
     679             :         }
     680             :     }
     681           0 :     return 0;
     682             : }
     683             : 
     684           0 : gpgme_key_sig_t verify_signature(gpgme_user_id_t uid, gpgme_key_sig_t sig)
     685             : {
     686           0 :     if (uid) {
     687           0 :         for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) {
     688           0 :             if (s == sig) {
     689           0 :                 return sig;
     690             :             }
     691             :         }
     692             :     }
     693           0 :     return 0;
     694             : }
     695             : 
     696           0 : UserID::Signature::Signature() : key(), uid(0), sig(0) {}
     697             : 
     698           0 : UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, unsigned int idx)
     699           0 :     : key(k), uid(verify_uid(k, u)), sig(find_signature(uid, idx))
     700             : {
     701             : 
     702           0 : }
     703             : 
     704           0 : UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, gpgme_key_sig_t s)
     705           0 :     : key(k), uid(verify_uid(k, u)), sig(verify_signature(uid, s))
     706             : {
     707             : 
     708           0 : }
     709             : 
     710           0 : UserID UserID::Signature::parent() const
     711             : {
     712           0 :     return UserID(key, uid);
     713             : }
     714             : 
     715           0 : const char *UserID::Signature::signerKeyID() const
     716             : {
     717           0 :     return sig ? sig->keyid : 0 ;
     718             : }
     719             : 
     720           0 : const char *UserID::Signature::algorithmAsString() const
     721             : {
     722           0 :     return gpgme_pubkey_algo_name(sig ? sig->pubkey_algo : (gpgme_pubkey_algo_t)0);
     723             : }
     724             : 
     725           0 : unsigned int UserID::Signature::algorithm() const
     726             : {
     727           0 :     return sig ? sig->pubkey_algo : 0 ;
     728             : }
     729             : 
     730           0 : time_t UserID::Signature::creationTime() const
     731             : {
     732           0 :     return static_cast<time_t>(sig ? sig->timestamp : 0);
     733             : }
     734             : 
     735           0 : time_t UserID::Signature::expirationTime() const
     736             : {
     737           0 :     return static_cast<time_t>(sig ? sig->expires : 0);
     738             : }
     739             : 
     740           0 : bool UserID::Signature::neverExpires() const
     741             : {
     742           0 :     return expirationTime() == time_t(0);
     743             : }
     744             : 
     745           0 : bool UserID::Signature::isRevokation() const
     746             : {
     747           0 :     return sig && sig->revoked;
     748             : }
     749             : 
     750           0 : bool UserID::Signature::isInvalid() const
     751             : {
     752           0 :     return sig && sig->invalid;
     753             : }
     754             : 
     755           0 : bool UserID::Signature::isExpired() const
     756             : {
     757           0 :     return sig && sig->expired;
     758             : }
     759             : 
     760           0 : bool UserID::Signature::isExportable() const
     761             : {
     762           0 :     return sig && sig->exportable;
     763             : }
     764             : 
     765           0 : const char *UserID::Signature::signerUserID() const
     766             : {
     767           0 :     return sig ? sig->uid : 0 ;
     768             : }
     769             : 
     770           0 : const char *UserID::Signature::signerName() const
     771             : {
     772           0 :     return sig ? sig->name : 0 ;
     773             : }
     774             : 
     775           0 : const char *UserID::Signature::signerEmail() const
     776             : {
     777           0 :     return sig ? sig->email : 0 ;
     778             : }
     779             : 
     780           0 : const char *UserID::Signature::signerComment() const
     781             : {
     782           0 :     return sig ? sig->comment : 0 ;
     783             : }
     784             : 
     785           0 : unsigned int UserID::Signature::certClass() const
     786             : {
     787           0 :     return sig ? sig->sig_class : 0 ;
     788             : }
     789             : 
     790           0 : UserID::Signature::Status UserID::Signature::status() const
     791             : {
     792           0 :     if (!sig) {
     793           0 :         return GeneralError;
     794             :     }
     795             : 
     796           0 :     switch (gpgme_err_code(sig->status)) {
     797           0 :     case GPG_ERR_NO_ERROR:      return NoError;
     798           0 :     case GPG_ERR_SIG_EXPIRED:   return SigExpired;
     799           0 :     case GPG_ERR_KEY_EXPIRED:   return KeyExpired;
     800           0 :     case GPG_ERR_BAD_SIGNATURE: return BadSignature;
     801           0 :     case GPG_ERR_NO_PUBKEY:     return NoPublicKey;
     802             :     default:
     803           0 :     case GPG_ERR_GENERAL:       return GeneralError;
     804             :     }
     805             : }
     806             : 
     807           0 : std::string UserID::Signature::statusAsString() const
     808             : {
     809           0 :     if (!sig) {
     810           0 :         return std::string();
     811             :     }
     812             :     char buf[ 1024 ];
     813           0 :     gpgme_strerror_r(sig->status, buf, sizeof buf);
     814           0 :     buf[ sizeof buf - 1 ] = '\0';
     815           0 :     return std::string(buf);
     816             : }
     817             : 
     818           0 : GpgME::Notation UserID::Signature::notation(unsigned int idx) const
     819             : {
     820           0 :     if (!sig) {
     821           0 :         return GpgME::Notation();
     822             :     }
     823           0 :     for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
     824           0 :         if (nota->name) {
     825           0 :             if (idx-- == 0) {
     826           0 :                 return GpgME::Notation(nota);
     827             :             }
     828             :         }
     829             :     }
     830           0 :     return GpgME::Notation();
     831             : }
     832             : 
     833           0 : unsigned int UserID::Signature::numNotations() const
     834             : {
     835           0 :     if (!sig) {
     836           0 :         return 0;
     837             :     }
     838           0 :     unsigned int count = 0;
     839           0 :     for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
     840           0 :         if (nota->name) {
     841           0 :             ++count; // others are policy URLs...
     842             :         }
     843             :     }
     844           0 :     return count;
     845             : }
     846             : 
     847           0 : std::vector<Notation> UserID::Signature::notations() const
     848             : {
     849           0 :     if (!sig) {
     850           0 :         return std::vector<GpgME::Notation>();
     851             :     }
     852           0 :     std::vector<GpgME::Notation> v;
     853           0 :     v.reserve(numNotations());
     854           0 :     for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
     855           0 :         if (nota->name) {
     856           0 :             v.push_back(GpgME::Notation(nota));
     857             :         }
     858             :     }
     859           0 :     return v;
     860             : }
     861             : 
     862           0 : const char *UserID::Signature::policyURL() const
     863             : {
     864           0 :     if (!sig) {
     865           0 :         return 0;
     866             :     }
     867           0 :     for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
     868           0 :         if (!nota->name) {
     869           0 :             return nota->value;
     870             :         }
     871             :     }
     872           0 :     return 0;
     873             : }
     874             : 
     875           0 : std::ostream &operator<<(std::ostream &os, const UserID &uid)
     876             : {
     877           0 :     os << "GpgME::UserID(";
     878           0 :     if (!uid.isNull()) {
     879           0 :         os << "\n name:      " << protect(uid.name())
     880           0 :            << "\n email:     " << protect(uid.email())
     881           0 :            << "\n comment:   " << protect(uid.comment())
     882           0 :            << "\n validity:  " << uid.validityAsString()
     883           0 :            << "\n revoked:   " << uid.isRevoked()
     884           0 :            << "\n invalid:   " << uid.isInvalid()
     885           0 :            << "\n numsigs:   " << uid.numSignatures()
     886           0 :            << "\n tofuinfo:\n" << uid.tofuInfo();
     887             :     }
     888           0 :     return os << ')';
     889             : }
     890             : 
     891           0 : std::ostream &operator<<(std::ostream &os, const Key &key)
     892             : {
     893           0 :     os << "GpgME::Key(";
     894           0 :     if (!key.isNull()) {
     895           0 :         os << "\n protocol:   " << protect(key.protocolAsString())
     896           0 :            << "\n ownertrust: " << key.ownerTrustAsString()
     897           0 :            << "\n issuer:     " << protect(key.issuerName())
     898           0 :            << "\n fingerprint:" << protect(key.primaryFingerprint())
     899           0 :            << "\n listmode:   " << key.keyListMode()
     900           0 :            << "\n canSign:    " << key.canReallySign()
     901           0 :            << "\n canEncrypt: " << key.canEncrypt()
     902           0 :            << "\n canCertify: " << key.canCertify()
     903           0 :            << "\n canAuth:    " << key.canAuthenticate()
     904           0 :            << "\n uids:\n";
     905           0 :         const std::vector<UserID> uids = key.userIDs();
     906             :         std::copy(uids.begin(), uids.end(),
     907           0 :                   std::ostream_iterator<UserID>(os, "\n"));
     908             :     }
     909           0 :     return os << ')';
     910             : }
     911             : 
     912          18 : } // namespace GpgME

Generated by: LCOV version 1.11