LCOV - code coverage report
Current view: top level - lang/cpp/src - verificationresult.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 77 307 25.1 %
Date: 2018-11-15 08:49:49 Functions: 16 58 27.6 %

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

Generated by: LCOV version 1.13