[git] GPGME - branch, master, updated. gpgme-1.6.0-191-gfbd6ac4

by Andre Heinecke cvs at cvs.gnupg.org
Fri Jul 1 16:57:38 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, master has been updated
       via  fbd6ac4655ebf56d91ebd9a4ff499c8319fcd087 (commit)
       via  93c5d420fcfe275aeff2b3d5ce99629edbe6625d (commit)
       via  948ce7d1edf12ecb5080a4816ca15f495d6393f5 (commit)
      from  570bf2a648f14b34c4c45d3890b7300529a82d37 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fbd6ac4655ebf56d91ebd9a4ff499c8319fcd087
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Jul 1 16:55:14 2016 +0200

    Qt: Add test for TofuInfo
    
    * lang/qt/tests/t-tofuinfo.cpp: New.
    * lang/qt/tests/Makefile.am: Update accordingly.
    
    --
    The test currently contains a workaround for GnuPG-Bug-Id 2405

diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am
index c060c70..204b5a7 100644
--- a/lang/qt/tests/Makefile.am
+++ b/lang/qt/tests/Makefile.am
@@ -24,9 +24,9 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir)
 
 EXTRA_DIST = initial.test
 
-TESTS = initial.test t-keylist t-keylocate t-ownertrust
+TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo
 
-moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc
+moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc
 
 AM_LDFLAGS = -no-install
 
@@ -49,12 +49,13 @@ initial.test : check-local
 t_keylist_SOURCES = t-keylist.cpp
 t_keylocate_SOURCES = t-keylocate.cpp
 t_ownertrust_SOURCES = t-ownertrust.cpp
+t_tofuinfo_SOURCES = t-tofuinfo.cpp
 
 nodist_t_keylist_SOURCES = $(moc_files)
 
 BUILT_SOURCES = $(moc_files)
 
-noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust
+noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo
 
 CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
 	gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp
new file mode 100644
index 0000000..0257359
--- /dev/null
+++ b/lang/qt/tests/t-tofuinfo.cpp
@@ -0,0 +1,163 @@
+/* t-tofuinfo.cpp
+
+    This file is part of qgpgme, the Qt API binding for gpgme
+    Copyright (c) 2016 Intevation GmbH
+
+    QGpgME is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.
+
+    QGpgME is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+    In addition, as a special exception, the copyright holders give
+    permission to link the code of this program with any edition of
+    the Qt library by Trolltech AS, Norway (or with modified versions
+    of Qt that use the same license as Qt), and distribute linked
+    combinations including the two.  You must obey the GNU General
+    Public License in all respects for all of the code used other than
+    Qt.  If you modify this file, you may extend this exception to
+    your version of the file, but you are not obligated to do so.  If
+    you do not wish to do so, delete this exception statement from
+    your version.
+*/
+#include <QDebug>
+#include <QTest>
+#include <QTemporaryDir>
+#include "protocol.h"
+#include "tofuinfo.h"
+#include "verifyopaquejob.h"
+#include "verificationresult.h"
+#include <iostream>
+
+using namespace QGpgME;
+using namespace GpgME;
+
+static const char testMsg1[] =
+"-----BEGIN PGP MESSAGE-----\n"
+"\n"
+"owGbwMvMwCSoW1RzPCOz3IRxjXQSR0lqcYleSUWJTZOvjVdpcYmCu1+oQmaJIleH\n"
+"GwuDIBMDGysTSIqBi1MApi+nlGGuwDeHao53HBr+FoVGP3xX+kvuu9fCMJvl6IOf\n"
+"y1kvP4y+8D5a11ang0udywsA\n"
+"=Crq6\n"
+"-----END PGP MESSAGE-----\n";
+
+class TofuInfoTest: public QObject
+{
+    Q_OBJECT
+
+    void testTofuCopy(TofuInfo other, const TofuInfo &orig)
+    {
+        Q_ASSERT(!orig.isNull());
+        Q_ASSERT(!other.isNull());
+        Q_ASSERT(!strcmp(orig.fingerprint(), other.fingerprint()));
+        Q_ASSERT(orig.lastSeen() == other.lastSeen());
+        Q_ASSERT(orig.signCount() == other.signCount());
+        Q_ASSERT(orig.validity() == other.validity());
+        Q_ASSERT(orig.policy() == other.policy());
+    }
+
+private:
+    QTemporaryDir mDir;
+
+private Q_SLOTS:
+    void testTofuNull()
+    {
+        TofuInfo tofu;
+        Q_ASSERT(tofu.isNull());
+        Q_ASSERT(!tofu.fingerprint());
+        Q_ASSERT(!tofu.address());
+        Q_ASSERT(!tofu.description());
+        Q_ASSERT(!tofu.signCount());
+        Q_ASSERT(!tofu.lastSeen());
+        Q_ASSERT(!tofu.firstSeen());
+        Q_ASSERT(tofu.validity() == TofuInfo::ValidityUnknown);
+        Q_ASSERT(tofu.policy() == TofuInfo::PolicyUnknown);
+    }
+
+    void testTofuInfo()
+    {
+        auto *job = openpgp()->verifyOpaqueJob(true);
+        const QByteArray data1(testMsg1);
+        QByteArray plaintext;
+
+        auto result = job->exec(data1, plaintext);
+
+        Q_ASSERT(!strcmp(plaintext.constData(), "Just GNU it!\n"));
+        Q_ASSERT(!result.isNull());
+        Q_ASSERT(!result.error());
+
+        Q_ASSERT(result.numSignatures() == 1);
+        Signature sig = result.signatures()[0];
+        /* TOFU is always marginal */
+        Q_ASSERT(sig.validity() == Signature::Marginal);
+
+        Q_ASSERT(!sig.tofuInfo().empty());
+        Q_FOREACH(const TofuInfo stats, sig.tofuInfo()) {
+            Q_ASSERT(!stats.isNull());
+            Q_ASSERT(!strcmp(stats.fingerprint(), sig.fingerprint()));
+            Q_ASSERT(stats.firstSeen() == stats.lastSeen());
+            Q_ASSERT(!stats.signCount());
+            Q_ASSERT(stats.address());
+          /* See issue2405 Comment back in when resolved
+            Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto); */
+            Q_ASSERT(stats.validity() == TofuInfo::NoHistory);
+        }
+
+        const TofuInfo first = sig.tofuInfo()[0];
+        testTofuCopy(first, first);
+
+        /* Another verify */
+
+        /* FIXME: GnuPG-Bug-Id 2405 makes the wait necessary. */
+        QTest::qWait(1000);
+        job = openpgp()->verifyOpaqueJob(true);
+        result = job->exec(data1, plaintext);
+
+        Q_ASSERT(!result.isNull());
+        Q_ASSERT(!result.error());
+
+        Q_ASSERT(result.numSignatures() == 1);
+        sig = result.signatures()[0];
+        /* TOFU is always marginal */
+        Q_ASSERT(sig.validity() == Signature::Marginal);
+
+        Q_ASSERT(!sig.tofuInfo().empty());
+        Q_FOREACH(const TofuInfo stats, sig.tofuInfo()) {
+            Q_ASSERT(!stats.isNull());
+            Q_ASSERT(!strcmp(stats.fingerprint(), sig.fingerprint()));
+            Q_ASSERT(stats.signCount() == 1);
+            Q_ASSERT(stats.address());
+            Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto);
+            Q_ASSERT(stats.validity() == TofuInfo::LittleHistory);
+        }
+    }
+
+    void initTestCase()
+    {
+        const QString gpgHome = qgetenv("GNUPGHOME");
+        QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set.");
+        qputenv("GNUPGHOME", mDir.path().toUtf8());
+        Q_ASSERT(mDir.isValid());
+        QFile conf(mDir.path() + QStringLiteral("/gpg.conf"));
+        Q_ASSERT(conf.open(QIODevice::WriteOnly));
+        conf.write("trust-model tofu+pgp");
+        conf.close();
+        Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/pubring.gpg"),
+                 mDir.path() + QStringLiteral("/pubring.gpg")));
+        Q_ASSERT(QFile::copy(gpgHome + QStringLiteral("/secring.gpg"),
+                 mDir.path() + QStringLiteral("/secring.gpg")));
+
+    }
+};
+
+QTEST_MAIN(TofuInfoTest)
+
+#include "t-tofuinfo.moc"

commit 93c5d420fcfe275aeff2b3d5ce99629edbe6625d
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Jul 1 16:49:06 2016 +0200

    Cpp: Add TofuInfo to signatures
    
    * lang/cpp/src/tofuinfo.cpp, lang/cpp/src/tofuinfo.h: New class.
    * lang/cpp/src/verificationresult.cpp (Signature::tofuInfo): New.
    (VerificationResult::Private): Handle tofu info.
    (GpgME::operator<<(std::ostream &os, const Signature &sig)): Include
    TofuInfo in dump.
    * lang/cpp/src/verificationresult.h (Signature::tofuInfo): New.
    * lang/cpp/src/Makefile.am (main_sources, gpgmepp_headers): Add
    new files.
    * configure.ac (LIBGPGMEPP_LT_REVISION): Bump for new API.

diff --git a/configure.ac b/configure.ac
index 4269540..335a33a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,7 +63,7 @@ LIBGPGME_LT_REVISION=0
 
 LIBGPGMEPP_LT_CURRENT=6
 LIBGPGMEPP_LT_AGE=0
-LIBGPGMEPP_LT_REVISION=0
+LIBGPGMEPP_LT_REVISION=1
 
 LIBQGPGME_LT_CURRENT=6
 LIBQGPGME_LT_AGE=0
diff --git a/lang/cpp/src/Makefile.am b/lang/cpp/src/Makefile.am
index d3d28ce..364d2ca 100644
--- a/lang/cpp/src/Makefile.am
+++ b/lang/cpp/src/Makefile.am
@@ -32,7 +32,7 @@ main_sources = \
     gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \
     gpgadduserideditinteractor.cpp defaultassuantransaction.cpp \
     scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \
-    vfsmountresult.cpp configuration.cpp
+    vfsmountresult.cpp configuration.cpp tofuinfo.cpp
 
 gpgmepp_headers = \
     assuanresult.h configuration.h context.h data.h decryptionresult.h \
@@ -43,7 +43,8 @@ gpgmepp_headers = \
     gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \
     importresult.h keygenerationresult.h key.h keylistresult.h \
     notation.h result.h scdgetinfoassuantransaction.h signingresult.h \
-    trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h
+    trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h \
+    tofuinfo.h
 
 private_gpgmepp_headers = \
     result_p.h context_p.h util.h callbacks.h data_p.h
diff --git a/lang/cpp/src/tofuinfo.cpp b/lang/cpp/src/tofuinfo.cpp
new file mode 100644
index 0000000..c27a59e
--- /dev/null
+++ b/lang/cpp/src/tofuinfo.cpp
@@ -0,0 +1,177 @@
+/* tofuinfo.cpp - wraps gpgme tofu info
+  Copyright (C) 2016 Intevation GmbH
+
+  This file is part of GPGME++.
+
+  GPGME++ is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  GPGME++ is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public License
+  along with GPGME++; see the file COPYING.LIB.  If not, write to the
+  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+*/
+
+#include "tofuinfo.h"
+
+#include <istream>
+#include "util.h"
+
+class GpgME::TofuInfo::Private
+{
+public:
+    Private() {}
+    Private(gpgme_tofu_info_t info)
+        : mInfo(info ? new _gpgme_tofu_info(*info) : nullptr)
+    {
+        if (mInfo && mInfo->fpr) {
+            mInfo->fpr = strdup(mInfo->fpr);
+        }
+        if (mInfo && mInfo->address) {
+            mInfo->address = strdup(mInfo->address);
+        }
+        if (mInfo && mInfo->description) {
+            mInfo->description = strdup(mInfo->description);
+        }
+    }
+
+    Private(const Private &other)
+        : mInfo(other.mInfo)
+    {
+        if (mInfo && mInfo->fpr) {
+            mInfo->fpr = strdup(mInfo->fpr);
+        }
+        if (mInfo && mInfo->address) {
+            mInfo->address = strdup(mInfo->address);
+        }
+        if (mInfo && mInfo->description) {
+            mInfo->description = strdup(mInfo->description);
+        }
+    }
+
+    ~Private()
+    {
+        if (mInfo) {
+            std::free(mInfo->fpr);
+            mInfo->fpr = nullptr;
+            std::free(mInfo->address);
+            mInfo->address = nullptr;
+            std::free(mInfo->description);
+            mInfo->description = nullptr;
+
+            delete mInfo;
+        }
+    }
+
+    gpgme_tofu_info_t mInfo;
+};
+
+GpgME::TofuInfo::TofuInfo(gpgme_tofu_info_t info)
+    : d(new Private(info))
+{
+}
+
+GpgME::TofuInfo::TofuInfo() : d()
+{
+}
+
+bool GpgME::TofuInfo::isNull() const
+{
+    return !d || !d->mInfo;
+}
+
+GpgME::TofuInfo::Validity GpgME::TofuInfo::validity() const
+{
+    if (isNull()) {
+        return ValidityUnknown;
+    }
+    switch (d->mInfo->validity) {
+        case 0:
+            return Conflict;
+        case 1:
+            return NoHistory;
+        case 2:
+            return LittleHistory;
+        case 3:
+            return BasicHistory;
+        case 4:
+            return LargeHistory;
+        default:
+            return ValidityUnknown;
+    }
+}
+
+GpgME::TofuInfo::Policy GpgME::TofuInfo::policy() const
+{
+    if (isNull()) {
+        return PolicyUnknown;
+    }
+    switch (d->mInfo->policy) {
+        case GPGME_TOFU_POLICY_NONE:
+            return PolicyNone;
+        case GPGME_TOFU_POLICY_AUTO:
+            return PolicyAuto;
+        case GPGME_TOFU_POLICY_GOOD:
+            return PolicyGood;
+        case GPGME_TOFU_POLICY_BAD:
+            return PolicyBad;
+        case GPGME_TOFU_POLICY_ASK:
+            return PolicyAsk;
+        case GPGME_TOFU_POLICY_UNKNOWN:
+            return PolicyUnknown;
+    }
+}
+
+const char *GpgME::TofuInfo::fingerprint() const
+{
+    return isNull() ? nullptr : d->mInfo->fpr;
+}
+
+const char *GpgME::TofuInfo::address() const
+{
+    return isNull() ? nullptr : d->mInfo->address;
+}
+
+const char *GpgME::TofuInfo::description() const
+{
+    return isNull() ? nullptr : d->mInfo->description;
+}
+
+unsigned short GpgME::TofuInfo::signCount() const
+{
+    return isNull() ? 0 : d->mInfo->signcount;
+}
+
+unsigned int GpgME::TofuInfo::firstSeen() const
+{
+    return isNull() ? 0 : d->mInfo->firstseen;
+}
+
+unsigned int GpgME::TofuInfo::lastSeen() const
+{
+    return isNull() ? 0 : d->mInfo->lastseen;
+}
+
+std::ostream &GpgME::operator<<(std::ostream &os, const GpgME::TofuInfo &info)
+{
+    os << "GpgME::Signature::TofuInfo(";
+    if (!info.isNull()) {
+        os << "\n address:  " << protect(info.address())
+           << "\n fpr: "      << protect(info.fingerprint())
+           << "\n desc: "     << protect(info.description())
+           << "\n validity: " << info.validity()
+           << "\n policy: "   << info.policy()
+           << "\n signcount: "<< info.signCount()
+           << "\n firstseen: "<< info.firstSeen()
+           << "\n lastseen: " << info.lastSeen()
+           << '\n';
+    }
+    return os << ")";
+}
diff --git a/lang/cpp/src/tofuinfo.h b/lang/cpp/src/tofuinfo.h
new file mode 100644
index 0000000..c698360
--- /dev/null
+++ b/lang/cpp/src/tofuinfo.h
@@ -0,0 +1,126 @@
+/*
+  tofuinfo.h - wraps gpgme tofu info
+  Copyright (C) 2016 Intevation GmbH
+
+  This file is part of GPGME++.
+
+  GPGME++ is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  GPGME++ is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public License
+  along with GPGME++; see the file COPYING.LIB.  If not, write to the
+  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GPGMEPP_TOFUINFO_H__
+#define __GPGMEPP_TOFUINFO_H__
+
+#include "gpgmepp_export.h"
+
+#include "gpgme.h"
+
+#include "global.h"
+
+#include <memory>
+
+namespace GpgME
+{
+
+class GPGMEPP_EXPORT TofuInfo
+{
+public:
+    TofuInfo();
+    explicit TofuInfo(gpgme_tofu_info_t info);
+
+    const TofuInfo &operator=(TofuInfo other)
+    {
+        swap(other);
+        return *this;
+    }
+
+    void swap(TofuInfo &other)
+    {
+        using std::swap;
+        swap(this->d, other.d);
+    }
+
+    bool isNull() const;
+
+    /* @enum Validity
+     * @brief The TOFU Validity. */
+    enum Validity {
+        /*! Unknown (uninitialized).*/
+        ValidityUnknown,
+        /*! TOFU Conflict.*/
+        Conflict,
+        /*! Key without history.*/
+        NoHistory,
+        /*! Key with too little history.*/
+        LittleHistory,
+        /*! Key with enough history for basic trust.*/
+        BasicHistory,
+        /*! Key with a lot of history.*/
+        LargeHistory,
+    };
+    Validity validity() const;
+
+    /* @enum Policy
+     * @brief The TOFU Validity. */
+    enum Policy {
+        /*! GPGME_TOFU_POLICY_NONE */
+        PolicyNone,
+        /*! GPGME_TOFU_POLICY_AUTO */
+        PolicyAuto,
+        /*! GPGME_TOFU_POLICY_GOOD */
+        PolicyGood,
+        /*! GPGME_TOFU_POLICY_UNKNOWN */
+        PolicyUnknown,
+        /*! GPGME_TOFU_POLICY_BAD */
+        PolicyBad,
+        /*! GPGME_TOFU_POLICY_ASK */
+        PolicyAsk,
+    };
+    Policy policy() const;
+
+    /* Number of signatures seen for this binding.  Capped at USHRT_MAX.  */
+    unsigned short signCount() const;
+
+    /* Number of seconds since the first message was verified. */
+    unsigned int firstSeen() const;
+
+    /* Number of seconds since the last message was verified. */
+    unsigned int lastSeen() const;
+
+    /* Finterprint of the key for this entry. */
+    const char *fingerprint() const;
+
+    /* If non-NULL a human readable string summarizing the TOFU data. */
+    const char *description() const;
+
+    /* The address of the tofu binding.
+     *
+     * If no mail address is set for a User ID this is the name used
+     * for the user ID. Can be ambiguous when the same mail address or
+     * name is used in multiple user ids.
+     */
+    const char *address() const;
+
+private:
+    class Private;
+    std::shared_ptr<Private> d;
+};
+
+GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const TofuInfo &info);
+
+} // namespace GpgME
+
+GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(TofuInfo)
+#endif // __GPGMEPP_TOFUINFO_H__
diff --git a/lang/cpp/src/verificationresult.cpp b/lang/cpp/src/verificationresult.cpp
index b6fde7d..4bd1a7b 100644
--- a/lang/cpp/src/verificationresult.cpp
+++ b/lang/cpp/src/verificationresult.cpp
@@ -24,6 +24,7 @@
 #include <notation.h>
 #include "result_p.h"
 #include "util.h"
+#include "tofuinfo.h"
 
 #include <gpgme.h>
 
@@ -81,6 +82,11 @@ public:
                 }
                 nota.back().push_back(n);
             }
+            // copy tofu info:
+            tinfos.push_back(std::vector<TofuInfo>());
+            for (gpgme_tofu_info_t in = is->tofu; in ; in = in->next) {
+                tinfos.back().push_back(TofuInfo(in));
+            }
         }
     }
     ~Private()
@@ -107,6 +113,7 @@ public:
 
     std::vector<gpgme_signature_t> sigs;
     std::vector< std::vector<Nota> > nota;
+    std::vector< std::vector<TofuInfo> > tinfos;
     std::vector<char *> purls;
     std::string file_name;
 };
@@ -363,6 +370,15 @@ std::vector<GpgME::Notation> GpgME::Signature::notations() const
     return result;
 }
 
+std::vector<GpgME::TofuInfo> GpgME::Signature::tofuInfo() const
+{
+    if (isNull()) {
+        return std::vector<GpgME::TofuInfo>();
+    }
+
+    return d->tinfos[idx];
+}
+
 class GpgME::Notation::Private
 {
 public:
@@ -530,6 +546,9 @@ std::ostream &GpgME::operator<<(std::ostream &os, const Signature &sig)
         const std::vector<Notation> nota = sig.notations();
         std::copy(nota.begin(), nota.end(),
                   std::ostream_iterator<Notation>(os, "\n"));
+        const std::vector<TofuInfo> tinfos = sig.tofuInfo();
+        std::copy(tinfos.begin(), tinfos.end(),
+                  std::ostream_iterator<TofuInfo>(os, "\n"));
     }
     return os << ')';
 }
diff --git a/lang/cpp/src/verificationresult.h b/lang/cpp/src/verificationresult.h
index 17f0568..5a2927f 100644
--- a/lang/cpp/src/verificationresult.h
+++ b/lang/cpp/src/verificationresult.h
@@ -40,6 +40,7 @@ namespace GpgME
 class Error;
 class Signature;
 class Notation;
+class TofuInfo;
 
 class GPGMEPP_EXPORT VerificationResult : public Result
 {
@@ -156,6 +157,18 @@ public:
     GpgME::Notation notation(unsigned int index) const;
     std::vector<GpgME::Notation> notations() const;
 
+    /** List of TOFU stats for this signature.
+     *
+     * For each UserID of the key used to create this
+     * signature a tofu entry is returned.
+     *
+     * Warning: Addresses can be ambigous if there are multiple UserID's
+     * with the same mailbox in a key.
+     *
+     * @returns The list of TOFU stats.
+     */
+    std::vector<GpgME::TofuInfo> tofuInfo() const;
+
 private:
     std::shared_ptr<VerificationResult::Private> d;
     unsigned int idx;

commit 948ce7d1edf12ecb5080a4816ca15f495d6393f5
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Jul 1 16:47:04 2016 +0200

    core: Clarify documentation of tofu_stats address
    
    * src/gpgme.h.in: Mention that Address is not always in addr-spec.
    
    --
    The old comment made it look like you could always expect the
    address to be parsable as a mailbox address.

diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 790485d..cdb7037 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1559,7 +1559,12 @@ struct _gpgme_tofu_info
 {
   struct _gpgme_tofu_info *next;
 
-  /* The mail address (addr-spec from RFC5322) of the tofu binding.  */
+  /* The mail address (addr-spec from RFC5322) of the tofu binding.
+   *
+   * If no mail address is set for a User ID this is the name used
+   * for the user ID. Can be ambiguous when the same mail address or
+   * name is used in multiple user ids.
+   */
   char *address;
 
   /* The fingerprint of the primary key.  */

-----------------------------------------------------------------------

Summary of changes:
 configure.ac                        |   2 +-
 lang/cpp/src/Makefile.am            |   5 +-
 lang/cpp/src/tofuinfo.cpp           | 177 ++++++++++++++++++++++++++++++++++++
 lang/cpp/src/tofuinfo.h             | 126 +++++++++++++++++++++++++
 lang/cpp/src/verificationresult.cpp |  19 ++++
 lang/cpp/src/verificationresult.h   |  13 +++
 lang/qt/tests/Makefile.am           |   7 +-
 lang/qt/tests/t-tofuinfo.cpp        | 163 +++++++++++++++++++++++++++++++++
 src/gpgme.h.in                      |   7 +-
 9 files changed, 512 insertions(+), 7 deletions(-)
 create mode 100644 lang/cpp/src/tofuinfo.cpp
 create mode 100644 lang/cpp/src/tofuinfo.h
 create mode 100644 lang/qt/tests/t-tofuinfo.cpp


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list