LCOV - code coverage report
Current view: top level - lang/qt/tests - t-tofuinfo.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 268 295 90.8 %
Date: 2018-11-14 16:53:58 Functions: 30 46 65.2 %

          Line data    Source code
       1             : /* t-tofuinfo.cpp
       2             : 
       3             :     This file is part of qgpgme, the Qt API binding for gpgme
       4             :     Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
       5             :     Software engineering by Intevation GmbH
       6             : 
       7             :     QGpgME is free software; you can redistribute it and/or
       8             :     modify it under the terms of the GNU General Public License as
       9             :     published by the Free Software Foundation; either version 2 of the
      10             :     License, or (at your option) any later version.
      11             : 
      12             :     QGpgME 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 GNU
      15             :     General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program; if not, write to the Free Software
      19             :     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      20             : 
      21             :     In addition, as a special exception, the copyright holders give
      22             :     permission to link the code of this program with any edition of
      23             :     the Qt library by Trolltech AS, Norway (or with modified versions
      24             :     of Qt that use the same license as Qt), and distribute linked
      25             :     combinations including the two.  You must obey the GNU General
      26             :     Public License in all respects for all of the code used other than
      27             :     Qt.  If you modify this file, you may extend this exception to
      28             :     your version of the file, but you are not obligated to do so.  If
      29             :     you do not wish to do so, delete this exception statement from
      30             :     your version.
      31             : */
      32             : #ifdef HAVE_CONFIG_H
      33             :  #include "config.h"
      34             : #endif
      35             : 
      36             : #include <QDebug>
      37             : #include <QTest>
      38             : #include <QTemporaryDir>
      39             : #include <QSignalSpy>
      40             : 
      41             : #include "protocol.h"
      42             : #include "tofuinfo.h"
      43             : #include "tofupolicyjob.h"
      44             : #include "verifyopaquejob.h"
      45             : #include "verificationresult.h"
      46             : #include "signingresult.h"
      47             : #include "importjob.h"
      48             : #include "importresult.h"
      49             : #include "keylistjob.h"
      50             : #include "keylistresult.h"
      51             : #include "signjob.h"
      52             : #include "key.h"
      53             : #include "t-support.h"
      54             : #include "engineinfo.h"
      55             : #include "context.h"
      56             : #include <iostream>
      57             : 
      58             : using namespace QGpgME;
      59             : using namespace GpgME;
      60             : 
      61             : static const char testMsg1[] =
      62             : "-----BEGIN PGP MESSAGE-----\n"
      63             : "\n"
      64             : "owGbwMvMwCSoW1RzPCOz3IRxjXQSR0lqcYleSUWJTZOvjVdpcYmCu1+oQmaJIleH\n"
      65             : "GwuDIBMDGysTSIqBi1MApi+nlGGuwDeHao53HBr+FoVGP3xX+kvuu9fCMJvl6IOf\n"
      66             : "y1kvP4y+8D5a11ang0udywsA\n"
      67             : "=Crq6\n"
      68             : "-----END PGP MESSAGE-----\n";
      69             : 
      70             : static const char conflictKey1[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
      71             : "\n"
      72             : "mDMEWG+w/hYJKwYBBAHaRw8BAQdAiq1oStvDYg8ZfFs5DgisYJo8dJxD+C/AA21O\n"
      73             : "K/aif0O0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBHoJBLaV\n"
      74             : "DamYAgoa1L5BwMOl/x88BQJYb7D+AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n"
      75             : "Ah4BAheAAAoJEL5BwMOl/x88GvwA/0SxkbLyAcshGm2PRrPsFQsSVAfwaSYFVmS2\n"
      76             : "cMVIw1PfAQDclRH1Z4MpufK07ju4qI33o4s0UFpVRBuSxt7A4P2ZD7g4BFhvsP4S\n"
      77             : "CisGAQQBl1UBBQEBB0AmVrgaDNJ7K2BSalsRo2EkRJjHGqnp5bBB0tapnF81CQMB\n"
      78             : "CAeIeAQYFggAIBYhBHoJBLaVDamYAgoa1L5BwMOl/x88BQJYb7D+AhsMAAoJEL5B\n"
      79             : "wMOl/x88OR0BAMq4/vmJUORRTmzjHcv/DDrQB030DSq666rlckGIKTShAPoDXM9N\n"
      80             : "0gZK+YzvrinSKZXHmn0aSwmC1/hyPybJPEljBw==\n"
      81             : "=p2Oj\n"
      82             : "-----END PGP PUBLIC KEY BLOCK-----\n";
      83             : 
      84             : static const char conflictKey2[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
      85             : "\n"
      86             : "mDMEWG+xShYJKwYBBAHaRw8BAQdA567gPEPJRpqKnZjlFJMRNUqruRviYMyygfF6\n"
      87             : "6Ok+ygu0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBJ5kRh7E\n"
      88             : "I98w8kgUcmkAfYFvqqHsBQJYb7FKAhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n"
      89             : "Ah4BAheAAAoJEGkAfYFvqqHsYR0BAOz8JjYB4VvGkt6noLS3F5TLfsedGwQkBCw5\n"
      90             : "znw/vGZsAQD9DSX+ekwdrN56mNO8ISt5uVS7B1ZQtouNBF+nzcwbDbg4BFhvsUoS\n"
      91             : "CisGAQQBl1UBBQEBB0BFupW8+Xc1ikab8TJqANjQhvFVh6uLsgcK4g9lZgbGXAMB\n"
      92             : "CAeIeAQYFggAIBYhBJ5kRh7EI98w8kgUcmkAfYFvqqHsBQJYb7FKAhsMAAoJEGkA\n"
      93             : "fYFvqqHs15ABALdN3uiV/07cJ3RkNb3WPcijGsto+lECDS11dKEwTMFeAQDx+V36\n"
      94             : "ocbYC/xEuwi3w45oNqGieazzcD/GBbt8OBk3BA==\n"
      95             : "=45IR\n"
      96             : "-----END PGP PUBLIC KEY BLOCK-----\n";
      97             : 
      98             : static const char conflictMsg1[] = "-----BEGIN PGP MESSAGE-----\n"
      99             : "\n"
     100             : "owGbwMvMwCG2z/HA4aX/5W0YT3MlMUTkb2xPSizi6ihlYRDjYJAVU2Sp4mTZNpV3\n"
     101             : "5QwmLqkrMLWsTCCFDFycAjCR1vcMf4U0Qrs6qzqfHJ9puGOFduLN2nVmhsumxjBE\n"
     102             : "mdw4lr1ehIWR4QdLuNBpe86PGx1PtNXfVAzm/hu+vfjCp5BVNjPTM9L0eAA=\n"
     103             : "=MfBD\n"
     104             : "-----END PGP MESSAGE-----\n";
     105             : 
     106             : static const char conflictMsg2[] = "-----BEGIN PGP MESSAGE-----\n"
     107             : "\n"
     108             : "owGbwMvMwCGWyVDbmL9q4RvG01xJDBH5GyvS8vO5OkpZGMQ4GGTFFFnmpbjJHVG+\n"
     109             : "b/DJQ6QIppaVCaSQgYtTACaySZHhr/SOPrdFJ89KrcwKY5i1XnflXYf2PK76SafK\n"
     110             : "tkxXuXzvJAvDX4kCybuqFk3HXCexz2+IrnZ+5X5EqOnuo3ens2cte+uzlhMA\n"
     111             : "=BIAi\n"
     112             : "-----END PGP MESSAGE-----\n";
     113             : 
     114           2 : class TofuInfoTest: public QGpgMETest
     115             : {
     116             :     Q_OBJECT
     117             : Q_SIGNALS:
     118             :     void asyncDone();
     119             : 
     120             : private:
     121           6 :     bool testSupported()
     122             :     {
     123             :         static bool initialized, supported;
     124           6 :         if (initialized) {
     125           5 :             return supported;
     126             :         }
     127           1 :         initialized = true;
     128           1 :         if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.16") {
     129           0 :             return false;
     130             :         }
     131             :         // If the keylist fails here this means that gnupg does not
     132             :         // support tofu at all. It can be disabled at compile time. So no
     133             :         // tests.
     134           1 :         auto *job = openpgp()->keyListJob(false, false, false);
     135           1 :         job->addMode(GpgME::WithTofu);
     136           2 :         std::vector<GpgME::Key> keys;
     137           2 :         job->exec(QStringList() << QStringLiteral("zulu@example.net"), true, keys);
     138           1 :         delete job;
     139           1 :         supported = !keys.empty();
     140           1 :         return supported;
     141             :     }
     142             : 
     143           1 :     void testTofuCopy(TofuInfo other, const TofuInfo &orig)
     144             :     {
     145           1 :         QVERIFY(!orig.isNull());
     146           1 :         QVERIFY(!other.isNull());
     147           1 :         QVERIFY(orig.signLast() == other.signLast());
     148           1 :         QVERIFY(orig.signCount() == other.signCount());
     149           1 :         QVERIFY(orig.validity() == other.validity());
     150           1 :         QVERIFY(orig.policy() == other.policy());
     151             :     }
     152             : 
     153           6 :     void signAndVerify(const QString &what, const GpgME::Key &key, int expected)
     154             :     {
     155           6 :         auto job = openpgp()->signJob();
     156           6 :         auto ctx = Job::context(job);
     157          12 :         TestPassphraseProvider provider;
     158           6 :         ctx->setPassphraseProvider(&provider);
     159           6 :         ctx->setPinentryMode(Context::PinentryLoopback);
     160             : 
     161          12 :         std::vector<Key> keys;
     162           6 :         keys.push_back(key);
     163          12 :         QByteArray signedData;
     164          12 :         auto sigResult = job->exec(keys, what.toUtf8(), NormalSignatureMode, signedData);
     165           6 :         delete job;
     166             : 
     167           6 :         QVERIFY(!sigResult.error());
     168          12 :         foreach (const auto uid, keys[0].userIDs()) {
     169          12 :             auto info = uid.tofuInfo();
     170           6 :             QVERIFY(info.signCount() == expected - 1);
     171             :         }
     172             : 
     173           6 :         auto verifyJob = openpgp()->verifyOpaqueJob();
     174          12 :         QByteArray verified;
     175             : 
     176          12 :         auto result = verifyJob->exec(signedData, verified);
     177           6 :         delete verifyJob;
     178             : 
     179           6 :         QVERIFY(!result.error());
     180           6 :         QVERIFY(verified == what.toUtf8());
     181             : 
     182           6 :         QVERIFY(result.numSignatures() == 1);
     183          12 :         auto sig = result.signatures()[0];
     184             : 
     185          12 :         auto key2 = sig.key();
     186           6 :         QVERIFY(!key.isNull());
     187           6 :         QVERIFY(!strcmp (key2.primaryFingerprint(), key.primaryFingerprint()));
     188           6 :         QVERIFY(!strcmp (key.primaryFingerprint(), sig.fingerprint()));
     189          12 :         auto stats = key2.userID(0).tofuInfo();
     190           6 :         QVERIFY(!stats.isNull());
     191           6 :         if (stats.signCount() != expected) {
     192           0 :             std::cout << "################ Key before verify: "
     193           0 :                       << key
     194           0 :                       << "################ Key after verify: "
     195           0 :                       << key2;
     196             :         }
     197           6 :         QVERIFY(stats.signCount() == expected);
     198             :     }
     199             : 
     200             : private Q_SLOTS:
     201           1 :     void testTofuNull()
     202             :     {
     203           1 :         if (!testSupported()) {
     204           0 :             return;
     205             :         }
     206           2 :         TofuInfo tofu;
     207           1 :         QVERIFY(tofu.isNull());
     208           1 :         QVERIFY(!tofu.description());
     209           1 :         QVERIFY(!tofu.signCount());
     210           1 :         QVERIFY(!tofu.signLast());
     211           1 :         QVERIFY(!tofu.signFirst());
     212           1 :         QVERIFY(tofu.validity() == TofuInfo::ValidityUnknown);
     213           1 :         QVERIFY(tofu.policy() == TofuInfo::PolicyUnknown);
     214             :     }
     215             : 
     216           1 :     void testTofuInfo()
     217             :     {
     218           1 :         if (!testSupported()) {
     219           0 :             return;
     220             :         }
     221           1 :         auto *job = openpgp()->verifyOpaqueJob(true);
     222           2 :         const QByteArray data1(testMsg1);
     223           2 :         QByteArray plaintext;
     224             : 
     225           1 :         auto ctx = Job::context(job);
     226           1 :         QVERIFY(ctx);
     227           1 :         ctx->setSender("alfa@example.net");
     228             : 
     229           2 :         auto result = job->exec(data1, plaintext);
     230           1 :         delete job;
     231             : 
     232           1 :         QVERIFY(!result.isNull());
     233           1 :         QVERIFY(!result.error());
     234           1 :         QVERIFY(!strcmp(plaintext.constData(), "Just GNU it!\n"));
     235             : 
     236           1 :         QVERIFY(result.numSignatures() == 1);
     237           2 :         Signature sig = result.signatures()[0];
     238             :         /* TOFU is always marginal */
     239           1 :         QVERIFY(sig.validity() == Signature::Marginal);
     240             : 
     241           2 :         auto stats = sig.key().userID(0).tofuInfo();
     242           1 :         QVERIFY(!stats.isNull());
     243           1 :         QVERIFY(sig.key().primaryFingerprint());
     244           1 :         QVERIFY(sig.fingerprint());
     245           1 :         QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
     246           1 :         QVERIFY(stats.signFirst() == stats.signLast());
     247           1 :         QVERIFY(stats.signCount() == 1);
     248           1 :         QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
     249           1 :         QVERIFY(stats.validity() == TofuInfo::LittleHistory);
     250             : 
     251           1 :         testTofuCopy(stats, stats);
     252             : 
     253             :         /* Another verify */
     254             : 
     255           1 :         job = openpgp()->verifyOpaqueJob(true);
     256           1 :         result = job->exec(data1, plaintext);
     257           1 :         delete job;
     258             : 
     259           1 :         QVERIFY(!result.isNull());
     260           1 :         QVERIFY(!result.error());
     261             : 
     262           1 :         QVERIFY(result.numSignatures() == 1);
     263           1 :         sig = result.signatures()[0];
     264             :         /* TOFU is always marginal */
     265           1 :         QVERIFY(sig.validity() == Signature::Marginal);
     266             : 
     267           1 :         stats = sig.key().userID(0).tofuInfo();
     268           1 :         QVERIFY(!stats.isNull());
     269           1 :         QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
     270           1 :         QVERIFY(stats.signFirst() == stats.signLast());
     271           1 :         QVERIFY(stats.signCount() == 1);
     272           1 :         QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
     273           1 :         QVERIFY(stats.validity() == TofuInfo::LittleHistory);
     274             : 
     275             :         /* Verify that another call yields the same result */
     276           1 :         job = openpgp()->verifyOpaqueJob(true);
     277           1 :         result = job->exec(data1, plaintext);
     278           1 :         delete job;
     279             : 
     280           1 :         QVERIFY(!result.isNull());
     281           1 :         QVERIFY(!result.error());
     282             : 
     283           1 :         QVERIFY(result.numSignatures() == 1);
     284           1 :         sig = result.signatures()[0];
     285             :         /* TOFU is always marginal */
     286           1 :         QVERIFY(sig.validity() == Signature::Marginal);
     287             : 
     288           1 :         stats = sig.key().userID(0).tofuInfo();
     289           1 :         QVERIFY(!stats.isNull());
     290           1 :         QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
     291           1 :         QVERIFY(stats.signFirst() == stats.signLast());
     292           1 :         QVERIFY(stats.signCount() == 1);
     293           1 :         QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
     294           1 :         QVERIFY(stats.validity() == TofuInfo::LittleHistory);
     295             :     }
     296             : 
     297           1 :     void testTofuSignCount()
     298             :     {
     299           1 :         if (!testSupported()) {
     300           0 :             return;
     301             :         }
     302           1 :         auto *job = openpgp()->keyListJob(false, false, false);
     303           1 :         job->addMode(GpgME::WithTofu);
     304           2 :         std::vector<GpgME::Key> keys;
     305           3 :         GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("zulu@example.net"),
     306           3 :                                                 true, keys);
     307           1 :         delete job;
     308           1 :         QVERIFY(!keys.empty());
     309           2 :         Key key = keys[0];
     310           1 :         QVERIFY(!key.isNull());
     311             : 
     312             :         /* As we sign & verify quickly here we need different
     313             :          * messages to avoid having them treated as the same
     314             :          * message if they were created within the same second.
     315             :          * Alternatively we could use the same message and wait
     316             :          * a second between each call. But this would slow down
     317             :          * the testsuite. */
     318           2 :         signAndVerify(QStringLiteral("Hello"), key, 1);
     319           1 :         key.update();
     320           2 :         signAndVerify(QStringLiteral("Hello2"), key, 2);
     321           1 :         key.update();
     322           2 :         signAndVerify(QStringLiteral("Hello3"), key, 3);
     323           1 :         key.update();
     324           2 :         signAndVerify(QStringLiteral("Hello4"), key, 4);
     325             :     }
     326             : 
     327           1 :     void testTofuKeyList()
     328             :     {
     329           1 :         if (!testSupported()) {
     330           0 :             return;
     331             :         }
     332             : 
     333             :         /* First check that the key has no tofu info. */
     334           1 :         auto *job = openpgp()->keyListJob(false, false, false);
     335           2 :         std::vector<GpgME::Key> keys;
     336           3 :         auto result = job->exec(QStringList() << QStringLiteral("zulu@example.net"),
     337           3 :                                                  true, keys);
     338           1 :         delete job;
     339           1 :         QVERIFY(!keys.empty());
     340           2 :         auto key = keys[0];
     341           1 :         QVERIFY(!key.isNull());
     342           1 :         QVERIFY(key.userID(0).tofuInfo().isNull());
     343           2 :         auto keyCopy = key;
     344           1 :         keyCopy.update();
     345           1 :         auto sigCnt = keyCopy.userID(0).tofuInfo().signCount();
     346           3 :         signAndVerify(QStringLiteral("Hello5"), keyCopy,
     347           1 :                       sigCnt + 1);
     348           1 :         keyCopy.update();
     349           3 :         signAndVerify(QStringLiteral("Hello6"), keyCopy,
     350           1 :                       sigCnt + 2);
     351             : 
     352             :         /* Now another one but with tofu */
     353           1 :         job = openpgp()->keyListJob(false, false, false);
     354           1 :         job->addMode(GpgME::WithTofu);
     355           3 :         result = job->exec(QStringList() << QStringLiteral("zulu@example.net"),
     356           2 :                            true, keys);
     357           1 :         delete job;
     358           1 :         QVERIFY(!result.error());
     359           1 :         QVERIFY(!keys.empty());
     360           2 :         auto key2 = keys[0];
     361           1 :         QVERIFY(!key2.isNull());
     362           2 :         auto info = key2.userID(0).tofuInfo();
     363           1 :         QVERIFY(!info.isNull());
     364           1 :         QVERIFY(info.signCount());
     365             :     }
     366             : 
     367           1 :     void testTofuPolicy()
     368             :     {
     369           1 :         if (!testSupported()) {
     370           0 :             return;
     371             :         }
     372             : 
     373             :         /* First check that the key has no tofu info. */
     374           1 :         auto *job = openpgp()->keyListJob(false, false, false);
     375           2 :         std::vector<GpgME::Key> keys;
     376           1 :         job->addMode(GpgME::WithTofu);
     377           3 :         auto result = job->exec(QStringList() << QStringLiteral("bravo@example.net"),
     378           3 :                                                  false, keys);
     379             : 
     380           1 :         if (keys.empty()) {
     381           0 :             qDebug() << "bravo@example.net not found";
     382           0 :             qDebug() << "Error: " << result.error().asString();
     383           0 :             const auto homedir = QString::fromLocal8Bit(qgetenv("GNUPGHOME"));
     384           0 :             qDebug() << "Homedir is: " << homedir;
     385           0 :             QFileInfo fi(homedir + "/pubring.gpg");
     386           0 :             qDebug () << "pubring exists: " << fi.exists() << " readable? "
     387           0 :                       << fi.isReadable() << " size: " << fi.size();
     388           0 :             QFileInfo fi2(homedir + "/pubring.kbx");
     389           0 :             qDebug () << "keybox exists: " << fi2.exists() << " readable? "
     390           0 :                       << fi2.isReadable() << " size: " << fi2.size();
     391             : 
     392           0 :             result = job->exec(QStringList(), false, keys);
     393           0 :             foreach (const auto key, keys) {
     394           0 :                 qDebug() << "Key: " << key.userID(0).name() << " <"
     395           0 :                          << key.userID(0).email()
     396           0 :                          << ">\n fpr: " << key.primaryFingerprint();
     397             :             }
     398             :         }
     399           1 :         QVERIFY(!result.error());
     400           1 :         QVERIFY(!keys.empty());
     401           2 :         auto key = keys[0];
     402           1 :         QVERIFY(!key.isNull());
     403           1 :         QVERIFY(key.userID(0).tofuInfo().policy() != TofuInfo::PolicyBad);
     404           1 :         auto *tofuJob = openpgp()->tofuPolicyJob();
     405           2 :         auto err = tofuJob->exec(key, TofuInfo::PolicyBad);
     406           1 :         QVERIFY(!err);
     407           3 :         result = job->exec(QStringList() << QStringLiteral("bravo@example.net"),
     408           2 :                                             false, keys);
     409           1 :         QVERIFY(!keys.empty());
     410           1 :         key = keys[0];
     411           1 :         QVERIFY(key.userID(0).tofuInfo().policy() == TofuInfo::PolicyBad);
     412           1 :         err = tofuJob->exec(key, TofuInfo::PolicyGood);
     413             : 
     414           3 :         result = job->exec(QStringList() << QStringLiteral("bravo@example.net"),
     415           2 :                                             false, keys);
     416           1 :         key = keys[0];
     417           1 :         QVERIFY(key.userID(0).tofuInfo().policy() == TofuInfo::PolicyGood);
     418           1 :         delete tofuJob;
     419           1 :         delete job;
     420             :     }
     421             : 
     422           1 :     void testTofuConflict()
     423             :     {
     424           1 :         if (!testSupported()) {
     425           0 :             return;
     426             :         }
     427             : 
     428           1 :         if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.19") {
     429           0 :             return;
     430             :         }
     431             : 
     432             :         // Import key 1
     433           1 :         auto importjob = openpgp()->importJob();
     434             :         connect(importjob, &ImportJob::result, this,
     435           1 :                 [this](ImportResult result, QString, Error)
     436           1 :         {
     437           1 :             QVERIFY(!result.error());
     438           1 :             QVERIFY(!result.imports().empty());
     439           1 :             QVERIFY(result.numImported());
     440           1 :             Q_EMIT asyncDone();
     441           1 :         });
     442           1 :         importjob->start(QByteArray(conflictKey1));
     443           2 :         QSignalSpy spy (this, SIGNAL(asyncDone()));
     444           1 :         QVERIFY(spy.wait());
     445             : 
     446             :         // Verify Message 1
     447           2 :         const QByteArray signedData(conflictMsg1);
     448           1 :         auto verifyJob = openpgp()->verifyOpaqueJob(true);
     449           2 :         QByteArray verified;
     450           2 :         auto result = verifyJob->exec(signedData, verified);
     451           1 :         delete verifyJob;
     452             : 
     453           1 :         QVERIFY(!result.isNull());
     454           1 :         QVERIFY(!result.error());
     455             : 
     456           1 :         QVERIFY(result.numSignatures() == 1);
     457           2 :         auto sig = result.signatures()[0];
     458           1 :         QVERIFY(sig.validity() == Signature::Marginal);
     459             : 
     460           2 :         auto stats = sig.key().userID(0).tofuInfo();
     461           1 :         QVERIFY(!stats.isNull());
     462           1 :         QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
     463           1 :         QVERIFY(stats.signFirst() == stats.signLast());
     464           1 :         QVERIFY(stats.signCount() == 1);
     465           1 :         QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
     466           1 :         QVERIFY(stats.validity() == TofuInfo::LittleHistory);
     467             : 
     468             :         // Import key 2
     469           1 :         importjob = openpgp()->importJob();
     470             :         connect(importjob, &ImportJob::result, this,
     471           1 :                 [this](ImportResult result, QString, Error)
     472           1 :         {
     473           1 :             QVERIFY(!result.error());
     474           1 :             QVERIFY(!result.imports().empty());
     475           1 :             QVERIFY(result.numImported());
     476           1 :             Q_EMIT asyncDone();
     477           1 :         });
     478           1 :         importjob->start(QByteArray(conflictKey2));
     479           2 :         QSignalSpy spy2 (this, SIGNAL(asyncDone()));
     480           1 :         QVERIFY(spy2.wait());
     481             : 
     482             :         // Verify Message 2
     483           2 :         const QByteArray signedData2(conflictMsg2);
     484           2 :         QByteArray verified2;
     485           1 :         verifyJob = openpgp()->verifyOpaqueJob(true);
     486           1 :         result = verifyJob->exec(signedData2, verified2);
     487           1 :         delete verifyJob;
     488             : 
     489           1 :         QVERIFY(!result.isNull());
     490           1 :         QVERIFY(!result.error());
     491             : 
     492           1 :         QVERIFY(result.numSignatures() == 1);
     493           1 :         sig = result.signatures()[0];
     494           1 :         QVERIFY(sig.validity() == Signature::Unknown);
     495             :         // TODO activate when implemented
     496             :         // QVERIFY(sig.summary() == Signature::TofuConflict);
     497             : 
     498           1 :         stats = sig.key().userID(0).tofuInfo();
     499           1 :         QVERIFY(!stats.isNull());
     500           1 :         QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
     501           1 :         QVERIFY(stats.signFirst() == stats.signLast());
     502           1 :         QVERIFY(stats.signCount() == 1);
     503           1 :         QVERIFY(stats.policy() == TofuInfo::PolicyAsk);
     504           1 :         QVERIFY(stats.validity() == TofuInfo::Conflict);
     505             :     }
     506             : 
     507             : 
     508           1 :     void initTestCase()
     509             :     {
     510           1 :         QGpgMETest::initTestCase();
     511           2 :         const QString gpgHome = qgetenv("GNUPGHOME");
     512           1 :         qputenv("GNUPGHOME", mDir.path().toUtf8());
     513           1 :         QVERIFY(mDir.isValid());
     514           3 :         QFile conf(mDir.path() + QStringLiteral("/gpg.conf"));
     515           1 :         QVERIFY(conf.open(QIODevice::WriteOnly));
     516           1 :         conf.write("trust-model tofu+pgp");
     517           1 :         conf.close();
     518           3 :         QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf"));
     519           1 :         QVERIFY(agentConf.open(QIODevice::WriteOnly));
     520           1 :         agentConf.write("allow-loopback-pinentry");
     521           1 :         agentConf.close();
     522           1 :         QVERIFY(copyKeyrings(gpgHome, mDir.path()));
     523             :     }
     524             : private:
     525             :     QTemporaryDir mDir;
     526             : 
     527             : };
     528             : 
     529           1 : QTEST_MAIN(TofuInfoTest)
     530             : 
     531             : #include "t-tofuinfo.moc"

Generated by: LCOV version 1.13