diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 85f6fa6b..90f29781 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -25,10 +25,10 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) EXTRA_DIST = initial.test TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo \ - t-encrypt + t-encrypt t-wkspublish moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ - t-encrypt.moc t-support.hmoc + t-encrypt.moc t-support.hmoc t-wkspublish.moc AM_LDFLAGS = -no-install @@ -55,6 +55,7 @@ t_keylocate_SOURCES = t-keylocate.cpp $(support_src) t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src) t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src) t_encrypt_SOURCES = t-encrypt.cpp $(support_src) +t_wkspublish_SOURCES = t-wkspublish.cpp $(support_src) run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp nodist_t_keylist_SOURCES = $(moc_files) @@ -62,7 +63,7 @@ nodist_t_keylist_SOURCES = $(moc_files) BUILT_SOURCES = $(moc_files) noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ - run-keyformailboxjob + run-keyformailboxjob t-wkspublish 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-wkspublish.cpp b/lang/qt/tests/t-wkspublish.cpp new file mode 100644 index 00000000..7039f3c9 --- /dev/null +++ b/lang/qt/tests/t-wkspublish.cpp @@ -0,0 +1,280 @@ +/* t-wkspublish.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 +#include +#include +#include +#include "wkspublishjob.h" +#include "keygenerationjob.h" +#include "keygenerationresult.h" +#include "importjob.h" +#include "importresult.h" +#include "protocol.h" +#include "engineinfo.h" +#include "context.h" + +#include "t-support.h" + +using namespace QGpgME; +using namespace GpgME; + +//#define DO_ONLINE_TESTS + +#define TEST_ADDRESS "testuser2@test.gnupg.org" + +static const char *testSecKey = +"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +"\n" +"lHgEV77hVhMJKyQDAwIIAQEHAgMEN3qKqBr9EecnfUnpw8RS8DHAjJqhwm2HAoEE\n" +"3yfQQ9w8uB/bKm5dqW4HML3JWRH8YoJaKSVrJY2D1FZUY+vHlgABAKDwEAB0HND8\n" +"5kbxiJmqKIuuNqCJ2jHgs9G0xk4GdKvZEdq0JlRlc3QgVXNlciAyIDx0ZXN0dXNl\n" +"cjJAdGVzdC5nbnVwZy5vcmc+iHkEExMIACEFAle+4VYCGwMFCwkIBwIGFQgJCgsC\n" +"BBYCAwECHgECF4AACgkQRVRoUEJO+6zgFQD7BF3pnS3w3A7J9y+Y3kyGfmscXFWJ\n" +"Kme1PAsAlVSm1y4A+weReMvWFYHJH257v94yhStmV8egGoybsNDttNAW53cbnHwE\n" +"V77hVhIJKyQDAwIIAQEHAgMEX+6cF0HEn4g3ztFvwHyr7uwXMVYUGL3lE3mjhnV3\n" +"SbY6Dmy3OeFVnEVkawHqSv+HobpQTeEqNoQHAoIiXFCRlgMBCAcAAP9FykiyDspm\n" +"T33XWRPD+LAOmaIU7CIhfv9+lVkeExlU1w+qiGEEGBMIAAkFAle+4VYCGwwACgkQ\n" +"RVRoUEJO+6xjhgD/ZJ/MwYZJPk/xPYhTP8+wF+tErVNA8w3pP9D69dgUPdcA/izZ\n" +"Pji6YetVhgsyaHc4PrKynsk5G6nM3KkAOehUQsX8\n" +"=S/Wa\n" +"-----END PGP PRIVATE KEY BLOCK-----\n"; + +static const char *testResponse = +"From key-submission@test.gnupg.org Thu Aug 25 12:15:54 2016\n" +"Return-Path: \n" +"From: key-submission@test.gnupg.org\n" +"To: testuser2@test.gnupg.org\n" +"Subject: Confirm your key publication\n" +"X-Wks-Loop: webkey.g10code.com\n" +"MIME-Version: 1.0\n" +"Content-Type: multipart/encrypted; protocol=\"application/pgp-encrypted\";\n" +" boundary=\"=-=01-wbu5fr9nu6fix5tcojjo=-=\"\n" +"Date: Thu, 25 Aug 2016 12:15:54 +0000\n" +"Message-Id: \n" +"Sender: \n" +"X-Kolab-Scheduling-Message: FALSE\n" +"\n" +" \n" +"\n" +"--=-=01-wbu5fr9nu6fix5tcojjo=-=\n" +"Content-Type: application/pgp-encrypted\n" +"\n" +"Version: 1\n" +"\n" +"--=-=01-wbu5fr9nu6fix5tcojjo=-=\n" +"Content-Type: application/octet-stream\n" +"\n" +"-----BEGIN PGP MESSAGE-----\n" +"Version: GnuPG v2\n" +"\n" +"hH4D8pSp7hUsFUASAgMEg0w39E6d0TkFYxLbT6n3YcoKTT+Ur/c7Sn1ECyL7Rnuk\n" +"cmPO0adt3JxueK7Oz5COlk32SECFODdF3cQuDhkGxzC6Sfc4SfisdILmNhaT/MeW\n" +"8a+yE4skSK70absif4kw5XkvxXNxHeIHfAteP50jPJLSwEsBTEceb9cRMoP7s8w0\n" +"lYyi+RWQ7UKlKKywtcRCL4ow2H7spjx+a+3FzNOAoy7K0/thhLVRk8z+iuPi0/4n\n" +"Z2Ql60USLLUlfV2ZIpXdCd+5GjTJsnGhDos1pas5TZcOOAxO12Cg5TcqHISOaqa8\n" +"6BqxcKCU3NypIynOKHj375KArSs0WsEH8HWHyBBHB+NYtNpnTAuHNKxM+JtNxf+U\n" +"NfD2zptS6kyiHLw+4zjL5pEV7RHS2PBwWBDS6vhnyybNwckleya96U04iYiGRYGE\n" +"lUUR6Fl8H6x04dItFH1/jJA6Ppcu4FoYou04HADWCqJXPTgztjiW1/9QoCeXl5lm\n" +"CcOCcuw7lXp+qTejuns=\n" +"=SsWX\n" +"-----END PGP MESSAGE-----\n" +"\n" +"--=-=01-wbu5fr9nu6fix5tcojjo=-=--\n"; + + +class WKSPublishTest : public QGpgMETest +{ + Q_OBJECT + +Q_SIGNALS: + void asyncDone(); + +private Q_SLOTS: + void testUnsupported() + { + // First check if it is supported + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(err); + Q_EMIT asyncDone(); + }); + job->startCheck ("testuser1@localhost"); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } +#ifdef DO_ONLINE_TESTS +private Q_SLOTS: +#else +private: +#endif + void testWSKPublishSupport() + { + // First check if it is supported + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + std::cout << err; + Q_ASSERT(err); + } else { + Q_ASSERT(!err); + } + Q_EMIT asyncDone(); + }); + job->startCheck ("testuser1@test.gnupg.org"); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } + + void testWKSPublishErrors() { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + /* Not supported */ + return; + } + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(err); + Q_EMIT asyncDone(); + }); + job->startCreate("AB874F24E98EBB8487EE7B170F8E3D97FE7011B7", + QStringLiteral("Foo@bar.baz")); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + } + + void testWKSPublishCreate() { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + /* Not supported */ + return; + } + auto ctx = Context::createForProtocol(OpenPGP); + /* First generate a test key */ + const QString args = QStringLiteral("\n" + "%no-protection\n" + "%transient-key\n" + "key-type: ECDSA\n" + "key-curve: brainpoolP256r1\n" + "key-usage: sign\n" + "subkey-type: ECDH\n" + "subkey-curve: brainpoolP256r1\n" + "subkey-usage: encrypt\n" + "name-email: %1\n" + "name-real: Test User\n" + "").arg(TEST_ADDRESS); + + auto keygenjob = openpgp()->keyGenerationJob(); + QByteArray fpr; + connect(keygenjob, &KeyGenerationJob::result, this, + [this, &fpr](KeyGenerationResult result, QByteArray pubkeyData, QString, Error) + { + Q_ASSERT(!result.error()); + fpr = QByteArray(result.fingerprint()); + Q_ASSERT(!fpr.isEmpty()); + Q_EMIT asyncDone(); + }); + keygenjob->start(args); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + + /* Then try to create a request. */ + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(!err); + Q_EMIT asyncDone(); + const QString outstr = QString(out); + Q_ASSERT(outstr.contains( + QStringLiteral("-----BEGIN PGP PUBLIC KEY BLOCK-----"))); + Q_ASSERT(outstr.contains( + QStringLiteral("Content-Type: application/pgp-keys"))); + Q_ASSERT(outstr.contains( + QStringLiteral("From: " TEST_ADDRESS))); + }); + job->startCreate(fpr.constData(), QLatin1String(TEST_ADDRESS)); + Q_ASSERT(spy.wait()); + } + + void testWKSPublishRecieve() { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") { + /* Not supported */ + return; + } + auto importjob = openpgp()->importJob(); + connect(importjob, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + Q_ASSERT(!result.error()); + Q_ASSERT(!result.imports().empty()); + Q_ASSERT(result.numSecretKeysImported()); + Q_EMIT asyncDone(); + }); + importjob->start(QByteArray(testSecKey)); + QSignalSpy spy (this, SIGNAL(asyncDone())); + Q_ASSERT(spy.wait()); + + /* Get a response. */ + auto job = openpgp()->wksPublishJob(); + connect(job, &WKSPublishJob::result, this, + [this] (Error err, QByteArray out, QByteArray errout, QString, Error) { + Q_ASSERT(!err); + Q_EMIT asyncDone(); + const QString outstr = QString(out); + Q_ASSERT(outstr.contains( + QStringLiteral("-----BEGIN PGP MESSAGE-----"))); + Q_ASSERT(outstr.contains( + QStringLiteral("Content-Type: multipart/encrypted;"))); + Q_ASSERT(outstr.contains( + QStringLiteral("From: " TEST_ADDRESS))); + }); + job->startRecieve(QByteArray(testResponse)); + Q_ASSERT(spy.wait()); + } + + void initTestCase() + { + QGpgMETest::initTestCase(); + const QString gpgHome = qgetenv("GNUPGHOME"); + qputenv("GNUPGHOME", mDir.path().toUtf8()); + Q_ASSERT(mDir.isValid()); + QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf")); + Q_ASSERT(agentConf.open(QIODevice::WriteOnly)); + agentConf.write("allow-loopback-pinentry"); + agentConf.close(); + } +private: + QTemporaryDir mDir; +}; + +QTEST_MAIN(WKSPublishTest) + +#include "t-wkspublish.moc"