LCOV - code coverage report
Current view: top level - lang/qt/tests - t-encrypt.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 91 100.0 %
Date: 2016-09-12 13:07:23 Functions: 14 21 66.7 %

          Line data    Source code
       1             : /* t-encrypt.cpp
       2             : 
       3             :     This file is part of qgpgme, the Qt API binding for gpgme
       4             :     Copyright (c) 2016 Intevation GmbH
       5             : 
       6             :     QGpgME is free software; you can redistribute it and/or
       7             :     modify it under the terms of the GNU General Public License as
       8             :     published by the Free Software Foundation; either version 2 of the
       9             :     License, or (at your option) any later version.
      10             : 
      11             :     QGpgME is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :     General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU General Public License
      17             :     along with this program; if not, write to the Free Software
      18             :     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      19             : 
      20             :     In addition, as a special exception, the copyright holders give
      21             :     permission to link the code of this program with any edition of
      22             :     the Qt library by Trolltech AS, Norway (or with modified versions
      23             :     of Qt that use the same license as Qt), and distribute linked
      24             :     combinations including the two.  You must obey the GNU General
      25             :     Public License in all respects for all of the code used other than
      26             :     Qt.  If you modify this file, you may extend this exception to
      27             :     your version of the file, but you are not obligated to do so.  If
      28             :     you do not wish to do so, delete this exception statement from
      29             :     your version.
      30             : */
      31             : #include <QDebug>
      32             : #include <QTest>
      33             : #include <QTemporaryDir>
      34             : #include <QSignalSpy>
      35             : #include <QBuffer>
      36             : #include "keylistjob.h"
      37             : #include "encryptjob.h"
      38             : #include "qgpgmeencryptjob.h"
      39             : #include "encryptionresult.h"
      40             : #include "decryptionresult.h"
      41             : #include "qgpgmedecryptjob.h"
      42             : #include "qgpgmebackend.h"
      43             : #include "keylistresult.h"
      44             : #include "engineinfo.h"
      45             : #include "t-support.h"
      46             : 
      47             : #define PROGRESS_TEST_SIZE 1 * 1024 * 1024
      48             : 
      49             : using namespace QGpgME;
      50             : using namespace GpgME;
      51             : 
      52           2 : class EncryptionTest : public QGpgMETest
      53             : {
      54             :     Q_OBJECT
      55             : 
      56             : Q_SIGNALS:
      57             :     void asyncDone();
      58             : 
      59             : private Q_SLOTS:
      60             : 
      61           1 :     void testSimpleEncryptDecrypt()
      62             :     {
      63           1 :         auto listjob = openpgp()->keyListJob(false, false, false);
      64           1 :         std::vector<Key> keys;
      65           3 :         auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
      66           3 :                                           false, keys);
      67           1 :         Q_ASSERT(!keylistresult.error());
      68           1 :         Q_ASSERT(keys.size() == 1);
      69           1 :         delete listjob;
      70             : 
      71           1 :         auto job = openpgp()->encryptJob(/*ASCII Armor */true, /* Textmode */ true);
      72           1 :         Q_ASSERT(job);
      73           2 :         QByteArray cipherText;
      74           3 :         auto result = job->exec(keys, QStringLiteral("Hello World").toUtf8(), Context::AlwaysTrust, cipherText);
      75           1 :         delete job;
      76           1 :         Q_ASSERT(!result.error());
      77           2 :         const auto cipherString = QString::fromUtf8(cipherText);
      78           1 :         Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
      79             : 
      80             :         /* Now decrypt */
      81           1 :         auto ctx = Context::createForProtocol(OpenPGP);
      82           2 :         TestPassphraseProvider provider;
      83           1 :         ctx->setPassphraseProvider(&provider);
      84           1 :         ctx->setPinentryMode(Context::PinentryLoopback);
      85           1 :         auto decJob = new QGpgMEDecryptJob(ctx);
      86           2 :         QByteArray plainText;
      87           2 :         auto decResult = decJob->exec(cipherText, plainText);
      88           1 :         Q_ASSERT(!result.error());
      89           2 :         Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello World"));
      90           2 :         delete decJob;
      91           1 :     }
      92             : 
      93           1 :     void testProgress()
      94             :     {
      95           1 :         if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.15") {
      96             :             // We can only test the progress with 2.1.15 as this started to
      97             :             // have total progress for memory callbacks
      98           1 :             return;
      99             :         }
     100           1 :         auto listjob = openpgp()->keyListJob(false, false, false);
     101           1 :         std::vector<Key> keys;
     102           3 :         auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
     103           3 :                                           false, keys);
     104           1 :         Q_ASSERT(!keylistresult.error());
     105           1 :         Q_ASSERT(keys.size() == 1);
     106           1 :         delete listjob;
     107             : 
     108           1 :         auto job = openpgp()->encryptJob(/*ASCII Armor */false, /* Textmode */ false);
     109           1 :         Q_ASSERT(job);
     110           2 :         QByteArray plainBa;
     111           1 :         plainBa.fill('X', PROGRESS_TEST_SIZE);
     112           2 :         QByteArray cipherText;
     113             : 
     114           1 :         bool initSeen = false;
     115           1 :         bool finishSeen = false;
     116           2 :         connect(job, &Job::progress, this, [this, &initSeen, &finishSeen] (const QString& what, int current, int total) {
     117             :                 // We only check for progress 0 and max progress as the other progress
     118             :                 // lines depend on the system speed and are as such unreliable to test.
     119           2 :                 Q_ASSERT(total == PROGRESS_TEST_SIZE);
     120           2 :                 if (current == 0) {
     121           1 :                     initSeen = true;
     122             :                 }
     123           2 :                 if (current == total) {
     124           1 :                     finishSeen = true;
     125             :                 }
     126           2 :                 Q_ASSERT(current >= 0 && current <= total);
     127           3 :             });
     128             :         connect(job, &EncryptJob::result, this, [this, &initSeen, &finishSeen] (const GpgME::EncryptionResult &result,
     129             :                                                                                 const QByteArray &cipherText,
     130             :                                                                                 const QString,
     131           1 :                                                                                 const GpgME::Error) {
     132           1 :                 Q_ASSERT(initSeen);
     133           1 :                 Q_ASSERT(finishSeen);
     134           1 :                 Q_EMIT asyncDone();
     135           2 :             });
     136             : 
     137           2 :         auto inptr  = std::shared_ptr<QIODevice>(new QBuffer(&plainBa));
     138           1 :         inptr->open(QIODevice::ReadOnly);
     139           2 :         auto outptr = std::shared_ptr<QIODevice>(new QBuffer(&cipherText));
     140           1 :         outptr->open(QIODevice::WriteOnly);
     141             : 
     142           1 :         job->start(keys, inptr, outptr, Context::AlwaysTrust);
     143           2 :         QSignalSpy spy (this, SIGNAL(asyncDone()));
     144           2 :         Q_ASSERT(spy.wait());
     145             :     }
     146             : 
     147           1 :     void testSymmetricEncryptDecrypt()
     148             :     {
     149           1 :         auto ctx = Context::createForProtocol(OpenPGP);
     150           1 :         TestPassphraseProvider provider;
     151           1 :         ctx->setPassphraseProvider(&provider);
     152           1 :         ctx->setPinentryMode(Context::PinentryLoopback);
     153           1 :         ctx->setArmor(true);
     154           1 :         ctx->setTextMode(true);
     155           1 :         auto job = new QGpgMEEncryptJob(ctx);
     156           2 :         QByteArray cipherText;
     157           3 :         auto result = job->exec(std::vector<Key>(), QStringLiteral("Hello symmetric World").toUtf8(), Context::AlwaysTrust, cipherText);
     158           1 :         delete job;
     159           1 :         Q_ASSERT(!result.error());
     160           2 :         const auto cipherString = QString::fromUtf8(cipherText);
     161           1 :         Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
     162             : 
     163           1 :         killAgent(mDir.path());
     164             : 
     165           1 :         auto ctx2 = Context::createForProtocol(OpenPGP);
     166           1 :         ctx2->setPassphraseProvider(&provider);
     167           1 :         ctx2->setPinentryMode(Context::PinentryLoopback);
     168           1 :         auto decJob = new QGpgMEDecryptJob(ctx2);
     169           2 :         QByteArray plainText;
     170           2 :         auto decResult = decJob->exec(cipherText, plainText);
     171           1 :         Q_ASSERT(!result.error());
     172           2 :         Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World"));
     173           2 :         delete decJob;
     174           1 :     }
     175             : 
     176             : private:
     177             :     /* Loopback and passphrase provider don't work for mixed encryption.
     178             :      * So this test is disabled until gnupg(?) is fixed for this. */
     179             :     void testMixedEncryptDecrypt()
     180             :     {
     181             :         auto listjob = openpgp()->keyListJob(false, false, false);
     182             :         std::vector<Key> keys;
     183             :         auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
     184             :                                           false, keys);
     185             :         Q_ASSERT(!keylistresult.error());
     186             :         Q_ASSERT(keys.size() == 1);
     187             :         delete listjob;
     188             : 
     189             :         auto ctx = Context::createForProtocol(OpenPGP);
     190             :         ctx->setPassphraseProvider(new TestPassphraseProvider);
     191             :         ctx->setPinentryMode(Context::PinentryLoopback);
     192             :         ctx->setArmor(true);
     193             :         ctx->setTextMode(true);
     194             :         auto job = new QGpgMEEncryptJob(ctx);
     195             :         QByteArray cipherText;
     196             :         printf("Before exec, flags: %x\n", Context::Symmetric | Context::AlwaysTrust);
     197             :         auto result = job->exec(keys, QStringLiteral("Hello symmetric World").toUtf8(),
     198             :                                 static_cast<Context::EncryptionFlags>(Context::Symmetric | Context::AlwaysTrust),
     199             :                                 cipherText);
     200             :         printf("After exec\n");
     201             :         delete job;
     202             :         Q_ASSERT(!result.error());
     203             :         printf("Cipher:\n%s\n", cipherText.constData());
     204             :         const auto cipherString = QString::fromUtf8(cipherText);
     205             :         Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
     206             : 
     207             :         killAgent(mDir.path());
     208             : 
     209             :         /* Now create a new homedir which with we test symetric decrypt. */
     210             :         QTemporaryDir tmp;
     211             :         qputenv("GNUPGHOME", tmp.path().toUtf8());
     212             :         QFile agentConf(tmp.path() + QStringLiteral("/gpg-agent.conf"));
     213             :         Q_ASSERT(agentConf.open(QIODevice::WriteOnly));
     214             :         agentConf.write("allow-loopback-pinentry");
     215             :         agentConf.close();
     216             : 
     217             :         auto ctx2 = Context::createForProtocol(OpenPGP);
     218             :         ctx2->setPassphraseProvider(new TestPassphraseProvider);
     219             :         ctx2->setPinentryMode(Context::PinentryLoopback);
     220             :         ctx2->setTextMode(true);
     221             :         auto decJob = new QGpgMEDecryptJob(ctx2);
     222             :         QByteArray plainText;
     223             :         auto decResult = decJob->exec(cipherText, plainText);
     224             :         Q_ASSERT(!decResult.error());
     225             :         qDebug() << "Plain: " << plainText;
     226             :         Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World"));
     227             :         delete decJob;
     228             : 
     229             :         killAgent(tmp.path());
     230             :         qputenv("GNUPGHOME", mDir.path().toUtf8());
     231             :     }
     232             : 
     233             : public Q_SLOT:
     234             : 
     235             :     void initTestCase()
     236             :     {
     237             :         QGpgMETest::initTestCase();
     238             :         const QString gpgHome = qgetenv("GNUPGHOME");
     239             :         qputenv("GNUPGHOME", mDir.path().toUtf8());
     240             :         Q_ASSERT(mDir.isValid());
     241             :         QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf"));
     242             :         Q_ASSERT(agentConf.open(QIODevice::WriteOnly));
     243             :         agentConf.write("allow-loopback-pinentry");
     244             :         agentConf.close();
     245             :         Q_ASSERT(copyKeyrings(gpgHome, mDir.path()));
     246             :     }
     247             : 
     248             : private:
     249             :     QTemporaryDir mDir;
     250             : };
     251             : 
     252           1 : QTEST_MAIN(EncryptionTest)
     253             : 
     254             : #include "t-encrypt.moc"

Generated by: LCOV version 1.11