LCOV - code coverage report
Current view: top level - lang/cpp/src - verificationresult.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 78 310 25.2 %
Date: 2016-11-29 15:07:43 Functions: 16 57 28.1 %

          Line data    Source code
       1             : /*
       2             :   verificationresult.cpp - wraps a gpgme verify result
       3             :   Copyright (C) 2004 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             : #ifdef HAVE_CONFIG_H
      24             :  #include "config.h"
      25             : #endif
      26             : 
      27             : #include <verificationresult.h>
      28             : #include <notation.h>
      29             : #include "result_p.h"
      30             : #include "util.h"
      31             : #include "key.h"
      32             : #include "context.h"
      33             : 
      34             : #include <gpgme.h>
      35             : 
      36             : #include <istream>
      37             : #include <algorithm>
      38             : #include <iterator>
      39             : #include <string>
      40             : #include <cstring>
      41             : #include <cstdlib>
      42             : 
      43             : #include <string.h>
      44             : 
      45             : class GpgME::VerificationResult::Private
      46             : {
      47             : public:
      48          10 :     explicit Private(const gpgme_verify_result_t r)
      49          10 :     {
      50          10 :         if (!r) {
      51          10 :             return;
      52             :         }
      53          10 :         if (r->file_name) {
      54           4 :             file_name = r->file_name;
      55             :         }
      56             :         // copy recursively, using compiler-generated copy ctor.
      57             :         // We just need to handle the pointers in the structs:
      58          20 :         for (gpgme_signature_t is = r->signatures ; is ; is = is->next) {
      59          10 :             gpgme_signature_t scopy = new _gpgme_signature(*is);
      60          10 :             if (is->fpr) {
      61          10 :                 scopy->fpr = strdup(is->fpr);
      62             :             }
      63             : // PENDING(marc) why does this crash on Windows in strdup()?
      64             : # ifndef _WIN32
      65          10 :             if (is->pka_address) {
      66           0 :                 scopy->pka_address = strdup(is->pka_address);
      67             :             }
      68             : # else
      69             :             scopy->pka_address = 0;
      70             : # endif
      71          10 :             scopy->next = 0;
      72          10 :             sigs.push_back(scopy);
      73             :             // copy keys
      74          10 :             if (scopy->key) {
      75           9 :                 keys.push_back(Key(scopy->key, true));
      76             :             } else {
      77           1 :                 keys.push_back(Key());
      78             :             }
      79             :             // copy notations:
      80          10 :             nota.push_back(std::vector<Nota>());
      81          10 :             purls.push_back(0);
      82          10 :             for (gpgme_sig_notation_t in = is->notations ; in ; in = in->next) {
      83           0 :                 if (!in->name) {
      84           0 :                     if (in->value) {
      85           0 :                         purls.back() = strdup(in->value);   // policy url
      86             :                     }
      87           0 :                     continue;
      88             :                 }
      89           0 :                 Nota n = { 0, 0, in->flags };
      90           0 :                 n.name = strdup(in->name);
      91           0 :                 if (in->value) {
      92           0 :                     n.value = strdup(in->value);
      93             :                 }
      94           0 :                 nota.back().push_back(n);
      95             :             }
      96             :         }
      97             :     }
      98          10 :     ~Private()
      99          10 :     {
     100          20 :         for (std::vector<gpgme_signature_t>::iterator it = sigs.begin() ; it != sigs.end() ; ++it) {
     101          10 :             std::free((*it)->fpr);
     102          10 :             std::free((*it)->pka_address);
     103          10 :             delete *it; *it = 0;
     104             :         }
     105          20 :         for (std::vector< std::vector<Nota> >::iterator it = nota.begin() ; it != nota.end() ; ++it) {
     106          10 :             for (std::vector<Nota>::iterator jt = it->begin() ; jt != it->end() ; ++jt) {
     107           0 :                 std::free(jt->name);  jt->name = 0;
     108           0 :                 std::free(jt->value); jt->value = 0;
     109             :             }
     110             :         }
     111          10 :         std::for_each(purls.begin(), purls.end(), &std::free);
     112          10 :     }
     113             : 
     114             :     struct Nota {
     115             :         char *name;
     116             :         char *value;
     117             :         gpgme_sig_notation_flags_t flags;
     118             :     };
     119             : 
     120             :     std::vector<gpgme_signature_t> sigs;
     121             :     std::vector< std::vector<Nota> > nota;
     122             :     std::vector<GpgME::Key> keys;
     123             :     std::vector<char *> purls;
     124             :     std::string file_name;
     125             :     Protocol proto;
     126             : };
     127             : 
     128           0 : GpgME::VerificationResult::VerificationResult(gpgme_ctx_t ctx, int error)
     129           0 :     : GpgME::Result(error), d()
     130             : {
     131           0 :     init(ctx);
     132           0 : }
     133             : 
     134          10 : GpgME::VerificationResult::VerificationResult(gpgme_ctx_t ctx, const Error &error)
     135          10 :     : GpgME::Result(error), d()
     136             : {
     137          10 :     init(ctx);
     138          10 : }
     139             : 
     140          10 : void GpgME::VerificationResult::init(gpgme_ctx_t ctx)
     141             : {
     142          10 :     if (!ctx) {
     143           0 :         return;
     144             :     }
     145          10 :     gpgme_verify_result_t res = gpgme_op_verify_result(ctx);
     146          10 :     if (!res) {
     147           0 :         return;
     148             :     }
     149          10 :     d.reset(new Private(res));
     150          10 :     gpgme_protocol_t proto = gpgme_get_protocol(ctx);
     151          10 :     d->proto = proto == GPGME_PROTOCOL_OpenPGP ? OpenPGP :
     152             :                proto == GPGME_PROTOCOL_CMS ? CMS :
     153          10 :                UnknownProtocol;
     154             : }
     155             : 
     156          23 : make_standard_stuff(VerificationResult)
     157             : 
     158           0 : const char *GpgME::VerificationResult::fileName() const
     159             : {
     160           0 :     return d ? d->file_name.c_str() : 0 ;
     161             : }
     162             : 
     163          10 : unsigned int GpgME::VerificationResult::numSignatures() const
     164             : {
     165          10 :     return d ? d->sigs.size() : 0 ;
     166             : }
     167             : 
     168           0 : GpgME::Signature GpgME::VerificationResult::signature(unsigned int idx) const
     169             : {
     170           0 :     return Signature(d, idx);
     171             : }
     172             : 
     173          10 : std::vector<GpgME::Signature> GpgME::VerificationResult::signatures() const
     174             : {
     175          10 :     if (!d) {
     176           0 :         return std::vector<Signature>();
     177             :     }
     178          10 :     std::vector<Signature> result;
     179          10 :     result.reserve(d->sigs.size());
     180          20 :     for (unsigned int i = 0 ; i < d->sigs.size() ; ++i) {
     181          10 :         result.push_back(Signature(d, i));
     182             :     }
     183          10 :     return result;
     184             : }
     185             : 
     186          10 : GpgME::Signature::Signature(const std::shared_ptr<VerificationResult::Private> &parent, unsigned int i)
     187          10 :     : d(parent), idx(i)
     188             : {
     189          10 : }
     190             : 
     191           0 : GpgME::Signature::Signature() : d(), idx(0) {}
     192             : 
     193          31 : bool GpgME::Signature::isNull() const
     194             : {
     195          31 :     return !d || idx >= d->sigs.size() ;
     196             : }
     197             : 
     198           0 : GpgME::Signature::Summary GpgME::Signature::summary() const
     199             : {
     200           0 :     if (isNull()) {
     201           0 :         return None;
     202             :     }
     203           0 :     gpgme_sigsum_t sigsum = d->sigs[idx]->summary;
     204           0 :     unsigned int result = 0;
     205           0 :     if (sigsum & GPGME_SIGSUM_VALID) {
     206           0 :         result |= Valid;
     207             :     }
     208           0 :     if (sigsum & GPGME_SIGSUM_GREEN) {
     209           0 :         result |= Green;
     210             :     }
     211           0 :     if (sigsum & GPGME_SIGSUM_RED) {
     212           0 :         result |= Red;
     213             :     }
     214           0 :     if (sigsum & GPGME_SIGSUM_KEY_REVOKED) {
     215           0 :         result |= KeyRevoked;
     216             :     }
     217           0 :     if (sigsum & GPGME_SIGSUM_KEY_EXPIRED) {
     218           0 :         result |= KeyExpired;
     219             :     }
     220           0 :     if (sigsum & GPGME_SIGSUM_SIG_EXPIRED) {
     221           0 :         result |= SigExpired;
     222             :     }
     223           0 :     if (sigsum & GPGME_SIGSUM_KEY_MISSING) {
     224           0 :         result |= KeyMissing;
     225             :     }
     226           0 :     if (sigsum & GPGME_SIGSUM_CRL_MISSING) {
     227           0 :         result |= CrlMissing;
     228             :     }
     229           0 :     if (sigsum & GPGME_SIGSUM_CRL_TOO_OLD) {
     230           0 :         result |= CrlTooOld;
     231             :     }
     232           0 :     if (sigsum & GPGME_SIGSUM_BAD_POLICY) {
     233           0 :         result |= BadPolicy;
     234             :     }
     235           0 :     if (sigsum & GPGME_SIGSUM_SYS_ERROR) {
     236           0 :         result |= SysError;
     237             :     }
     238           0 :     if (sigsum & GPGME_SIGSUM_TOFU_CONFLICT) {
     239           0 :         result |= TofuConflict;
     240             :     }
     241           0 :     return static_cast<Summary>(result);
     242             : }
     243             : 
     244          13 : const char *GpgME::Signature::fingerprint() const
     245             : {
     246          13 :     return isNull() ? 0 : d->sigs[idx]->fpr ;
     247             : }
     248             : 
     249           0 : GpgME::Error GpgME::Signature::status() const
     250             : {
     251           0 :     return Error(isNull() ? 0 : d->sigs[idx]->status);
     252             : }
     253             : 
     254           0 : time_t GpgME::Signature::creationTime() const
     255             : {
     256           0 :     return static_cast<time_t>(isNull() ? 0 : d->sigs[idx]->timestamp);
     257             : }
     258             : 
     259           0 : time_t GpgME::Signature::expirationTime() const
     260             : {
     261           0 :     return static_cast<time_t>(isNull() ? 0 : d->sigs[idx]->exp_timestamp);
     262             : }
     263             : 
     264           0 : bool GpgME::Signature::neverExpires() const
     265             : {
     266           0 :     return expirationTime() == (time_t)0;
     267             : }
     268             : 
     269           0 : bool GpgME::Signature::isWrongKeyUsage() const
     270             : {
     271           0 :     return !isNull() && d->sigs[idx]->wrong_key_usage;
     272             : }
     273             : 
     274           0 : bool GpgME::Signature::isVerifiedUsingChainModel() const
     275             : {
     276           0 :     return !isNull() && d->sigs[idx]->chain_model;
     277             : }
     278             : 
     279           0 : GpgME::Signature::PKAStatus GpgME::Signature::pkaStatus() const
     280             : {
     281           0 :     if (!isNull()) {
     282           0 :         return static_cast<PKAStatus>(d->sigs[idx]->pka_trust);
     283             :     }
     284           0 :     return UnknownPKAStatus;
     285             : }
     286             : 
     287           0 : const char *GpgME::Signature::pkaAddress() const
     288             : {
     289           0 :     if (!isNull()) {
     290           0 :         return d->sigs[idx]->pka_address;
     291             :     }
     292           0 :     return 0;
     293             : }
     294             : 
     295           3 : GpgME::Signature::Validity GpgME::Signature::validity() const
     296             : {
     297           3 :     if (isNull()) {
     298           0 :         return Unknown;
     299             :     }
     300           3 :     switch (d->sigs[idx]->validity) {
     301             :     default:
     302           0 :     case GPGME_VALIDITY_UNKNOWN:   return Unknown;
     303           0 :     case GPGME_VALIDITY_UNDEFINED: return Undefined;
     304           0 :     case GPGME_VALIDITY_NEVER:     return Never;
     305           3 :     case GPGME_VALIDITY_MARGINAL:  return Marginal;
     306           0 :     case GPGME_VALIDITY_FULL:      return Full;
     307           0 :     case GPGME_VALIDITY_ULTIMATE:  return Ultimate;
     308             :     }
     309             : }
     310             : 
     311           0 : char GpgME::Signature::validityAsString() const
     312             : {
     313           0 :     if (isNull()) {
     314           0 :         return '?';
     315             :     }
     316           0 :     switch (d->sigs[idx]->validity) {
     317             :     default:
     318           0 :     case GPGME_VALIDITY_UNKNOWN:   return '?';
     319           0 :     case GPGME_VALIDITY_UNDEFINED: return 'q';
     320           0 :     case GPGME_VALIDITY_NEVER:     return 'n';
     321           0 :     case GPGME_VALIDITY_MARGINAL:  return 'm';
     322           0 :     case GPGME_VALIDITY_FULL:      return 'f';
     323           0 :     case GPGME_VALIDITY_ULTIMATE:  return 'u';
     324             :     }
     325             : }
     326             : 
     327           0 : GpgME::Error GpgME::Signature::nonValidityReason() const
     328             : {
     329           0 :     return Error(isNull() ? 0 : d->sigs[idx]->validity_reason);
     330             : }
     331             : 
     332           0 : unsigned int GpgME::Signature::publicKeyAlgorithm() const
     333             : {
     334           0 :     if (!isNull()) {
     335           0 :         return d->sigs[idx]->pubkey_algo;
     336             :     }
     337           0 :     return 0;
     338             : }
     339             : 
     340           0 : const char *GpgME::Signature::publicKeyAlgorithmAsString() const
     341             : {
     342           0 :     if (!isNull()) {
     343           0 :         return gpgme_pubkey_algo_name(d->sigs[idx]->pubkey_algo);
     344             :     }
     345           0 :     return 0;
     346             : }
     347             : 
     348           0 : unsigned int GpgME::Signature::hashAlgorithm() const
     349             : {
     350           0 :     if (!isNull()) {
     351           0 :         return d->sigs[idx]->hash_algo;
     352             :     }
     353           0 :     return 0;
     354             : }
     355             : 
     356           0 : const char *GpgME::Signature::hashAlgorithmAsString() const
     357             : {
     358           0 :     if (!isNull()) {
     359           0 :         return gpgme_hash_algo_name(d->sigs[idx]->hash_algo);
     360             :     }
     361           0 :     return 0;
     362             : }
     363             : 
     364           0 : const char *GpgME::Signature::policyURL() const
     365             : {
     366           0 :     return isNull() ? 0 : d->purls[idx] ;
     367             : }
     368             : 
     369           0 : GpgME::Notation GpgME::Signature::notation(unsigned int nidx) const
     370             : {
     371           0 :     return GpgME::Notation(d, idx, nidx);
     372             : }
     373             : 
     374           0 : std::vector<GpgME::Notation> GpgME::Signature::notations() const
     375             : {
     376           0 :     if (isNull()) {
     377           0 :         return std::vector<GpgME::Notation>();
     378             :     }
     379           0 :     std::vector<GpgME::Notation> result;
     380           0 :     result.reserve(d->nota[idx].size());
     381           0 :     for (unsigned int i = 0 ; i < d->nota[idx].size() ; ++i) {
     382           0 :         result.push_back(GpgME::Notation(d, idx, i));
     383             :     }
     384           0 :     return result;
     385             : }
     386             : 
     387          14 : GpgME::Key GpgME::Signature::key() const
     388             : {
     389          14 :     if (isNull()) {
     390           0 :         return Key();
     391             :     }
     392          14 :     return d->keys[idx];
     393             : }
     394             : 
     395           1 : GpgME::Key GpgME::Signature::key(bool search, bool update) const
     396             : {
     397           1 :     if (isNull()) {
     398           0 :         return Key();
     399             :     }
     400             : 
     401           1 :     GpgME::Key ret = key();
     402           1 :     if (ret.isNull() && search) {
     403           1 :         auto ctx = Context::createForProtocol (d->proto);
     404           1 :         if (ctx) {
     405             :             ctx->setKeyListMode(KeyListMode::Local |
     406             :                         KeyListMode::Signatures |
     407             :                         KeyListMode::SignatureNotations |
     408             :                         KeyListMode::Validate |
     409           1 :                         KeyListMode::WithTofu);
     410           1 :             Error e;
     411           1 :             ret = d->keys[idx] = ctx->key(fingerprint(), e, false);
     412           1 :             delete ctx;
     413             :         }
     414             :     }
     415           1 :     if (update) {
     416           0 :         ret.update();
     417             :     }
     418           1 :     return ret;
     419             : }
     420             : 
     421             : class GpgME::Notation::Private
     422             : {
     423             : public:
     424             :     Private() : d(), sidx(0), nidx(0), nota(0) {}
     425           0 :     Private(const std::shared_ptr<VerificationResult::Private> &priv, unsigned int sindex, unsigned int nindex)
     426           0 :         : d(priv), sidx(sindex), nidx(nindex), nota(0)
     427             :     {
     428             : 
     429           0 :     }
     430           0 :     Private(gpgme_sig_notation_t n)
     431           0 :         : d(), sidx(0), nidx(0), nota(n ? new _gpgme_sig_notation(*n) : 0)
     432             :     {
     433           0 :         if (nota && nota->name) {
     434           0 :             nota->name = strdup(nota->name);
     435             :         }
     436           0 :         if (nota && nota->value) {
     437           0 :             nota->value = strdup(nota->value);
     438             :         }
     439           0 :     }
     440             :     Private(const Private &other)
     441             :         : d(other.d), sidx(other.sidx), nidx(other.nidx), nota(other.nota)
     442             :     {
     443             :         if (nota) {
     444             :             nota->name = strdup(nota->name);
     445             :             nota->value = strdup(nota->value);
     446             :         }
     447             :     }
     448           0 :     ~Private()
     449           0 :     {
     450           0 :         if (nota) {
     451           0 :             std::free(nota->name);  nota->name = 0;
     452           0 :             std::free(nota->value); nota->value = 0;
     453           0 :             delete nota;
     454             :         }
     455           0 :     }
     456             : 
     457             :     std::shared_ptr<VerificationResult::Private> d;
     458             :     unsigned int sidx, nidx;
     459             :     gpgme_sig_notation_t nota;
     460             : };
     461             : 
     462           0 : GpgME::Notation::Notation(const std::shared_ptr<VerificationResult::Private> &parent, unsigned int sindex, unsigned int nindex)
     463           0 :     : d(new Private(parent, sindex, nindex))
     464             : {
     465             : 
     466           0 : }
     467             : 
     468           0 : GpgME::Notation::Notation(gpgme_sig_notation_t nota)
     469           0 :     : d(new Private(nota))
     470             : {
     471             : 
     472           0 : }
     473             : 
     474           0 : GpgME::Notation::Notation() : d() {}
     475             : 
     476           0 : bool GpgME::Notation::isNull() const
     477             : {
     478           0 :     if (!d) {
     479           0 :         return true;
     480             :     }
     481           0 :     if (d->d) {
     482           0 :         return d->sidx >= d->d->nota.size() || d->nidx >= d->d->nota[d->sidx].size() ;
     483             :     }
     484           0 :     return !d->nota;
     485             : }
     486             : 
     487           0 : const char *GpgME::Notation::name() const
     488             : {
     489             :     return
     490           0 :         isNull() ? 0 :
     491           0 :         d->d ? d->d->nota[d->sidx][d->nidx].name :
     492           0 :         d->nota ? d->nota->name : 0 ;
     493             : }
     494             : 
     495           0 : const char *GpgME::Notation::value() const
     496             : {
     497             :     return
     498           0 :         isNull() ? 0 :
     499           0 :         d->d ? d->d->nota[d->sidx][d->nidx].value :
     500           0 :         d->nota ? d->nota->value : 0 ;
     501             : }
     502             : 
     503           0 : GpgME::Notation::Flags GpgME::Notation::flags() const
     504             : {
     505             :     return
     506             :         convert_from_gpgme_sig_notation_flags_t(
     507           0 :             isNull() ? 0 :
     508           0 :             d->d ? d->d->nota[d->sidx][d->nidx].flags :
     509           0 :             d->nota ? d->nota->flags : 0);
     510             : }
     511             : 
     512           0 : bool GpgME::Notation::isHumanReadable() const
     513             : {
     514           0 :     return flags() & HumanReadable;
     515             : }
     516             : 
     517           0 : bool GpgME::Notation::isCritical() const
     518             : {
     519           0 :     return flags() & Critical;
     520             : }
     521             : 
     522           0 : std::ostream &GpgME::operator<<(std::ostream &os, const VerificationResult &result)
     523             : {
     524           0 :     os << "GpgME::VerificationResult(";
     525           0 :     if (!result.isNull()) {
     526           0 :         os << "\n error:      " << result.error()
     527           0 :            << "\n fileName:   " << protect(result.fileName())
     528           0 :            << "\n signatures:\n";
     529           0 :         const std::vector<Signature> sigs = result.signatures();
     530             :         std::copy(sigs.begin(), sigs.end(),
     531           0 :                   std::ostream_iterator<Signature>(os, "\n"));
     532             :     }
     533           0 :     return os << ')';
     534             : }
     535             : 
     536           0 : std::ostream &GpgME::operator<<(std::ostream &os, Signature::PKAStatus pkaStatus)
     537             : {
     538             : #define OUTPUT( x ) if ( !(pkaStatus & (GpgME::Signature:: x)) ) {} else do { os << #x " "; } while(0)
     539           0 :     os << "GpgME::Signature::PKAStatus(";
     540             :     OUTPUT(UnknownPKAStatus);
     541           0 :     OUTPUT(PKAVerificationFailed);
     542           0 :     OUTPUT(PKAVerificationSucceeded);
     543             : #undef OUTPUT
     544           0 :     return os << ')';
     545             : }
     546             : 
     547           0 : std::ostream &GpgME::operator<<(std::ostream &os, Signature::Summary summary)
     548             : {
     549             : #define OUTPUT( x ) if ( !(summary & (GpgME::Signature:: x)) ) {} else do { os << #x " "; } while(0)
     550           0 :     os << "GpgME::Signature::Summary(";
     551           0 :     OUTPUT(Valid);
     552           0 :     OUTPUT(Green);
     553           0 :     OUTPUT(Red);
     554           0 :     OUTPUT(KeyRevoked);
     555           0 :     OUTPUT(KeyExpired);
     556           0 :     OUTPUT(SigExpired);
     557           0 :     OUTPUT(KeyMissing);
     558           0 :     OUTPUT(CrlMissing);
     559           0 :     OUTPUT(CrlTooOld);
     560           0 :     OUTPUT(BadPolicy);
     561           0 :     OUTPUT(SysError);
     562           0 :     OUTPUT(TofuConflict);
     563             : #undef OUTPUT
     564           0 :     return os << ')';
     565             : }
     566             : 
     567           0 : std::ostream &GpgME::operator<<(std::ostream &os, const Signature &sig)
     568             : {
     569           0 :     os << "GpgME::Signature(";
     570           0 :     if (!sig.isNull()) {
     571           0 :         os << "\n Summary:                   " << sig.summary()
     572           0 :            << "\n Fingerprint:               " << protect(sig.fingerprint())
     573           0 :            << "\n Status:                    " << sig.status()
     574           0 :            << "\n creationTime:              " << sig.creationTime()
     575           0 :            << "\n expirationTime:            " << sig.expirationTime()
     576           0 :            << "\n isWrongKeyUsage:           " << sig.isWrongKeyUsage()
     577           0 :            << "\n isVerifiedUsingChainModel: " << sig.isVerifiedUsingChainModel()
     578           0 :            << "\n pkaStatus:                 " << sig.pkaStatus()
     579           0 :            << "\n pkaAddress:                " << protect(sig.pkaAddress())
     580           0 :            << "\n validity:                  " << sig.validityAsString()
     581           0 :            << "\n nonValidityReason:         " << sig.nonValidityReason()
     582           0 :            << "\n publicKeyAlgorithm:        " << protect(sig.publicKeyAlgorithmAsString())
     583           0 :            << "\n hashAlgorithm:             " << protect(sig.hashAlgorithmAsString())
     584           0 :            << "\n policyURL:                 " << protect(sig.policyURL())
     585           0 :            << "\n notations:\n";
     586           0 :         const std::vector<Notation> nota = sig.notations();
     587             :         std::copy(nota.begin(), nota.end(),
     588           0 :                   std::ostream_iterator<Notation>(os, "\n"));
     589             :     }
     590           0 :     return os << ')';
     591             : }
     592             : 
     593           0 : std::ostream &GpgME::operator<<(std::ostream &os, Notation::Flags flags)
     594             : {
     595           0 :     os << "GpgME::Notation::Flags(";
     596             : #define OUTPUT( x ) if ( !(flags & (GpgME::Notation:: x)) ) {} else do { os << #x " "; } while(0)
     597           0 :     OUTPUT(HumanReadable);
     598           0 :     OUTPUT(Critical);
     599             : #undef OUTPUT
     600           0 :     return os << ')';
     601             : }
     602             : 
     603           0 : std::ostream &GpgME::operator<<(std::ostream &os, const Notation &nota)
     604             : {
     605           0 :     os << "GpgME::Signature::Notation(";
     606           0 :     if (!nota.isNull()) {
     607           0 :         os << "\n name:  " << protect(nota.name())
     608           0 :            << "\n value: " << protect(nota.value())
     609           0 :            << "\n flags: " << nota.flags()
     610           0 :            << '\n';
     611             :     }
     612           0 :     return os << ")";
     613          18 : }

Generated by: LCOV version 1.11