File indexing completed on 2025-03-09 04:53:53

0001 /*
0002   SPDX-FileCopyrightText: 2020 Sandro Knauß <knauss@kde.org>
0003 
0004   SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "autocryptheadersjobtest.h"
0008 
0009 #include "cryptofunctions.h"
0010 #include "qtest_messagecomposer.h"
0011 #include "setupenv.h"
0012 
0013 #include <KMime/Content>
0014 
0015 #include <Libkleo/Enum>
0016 
0017 #include <MessageComposer/AutocryptHeadersJob>
0018 #include <MessageComposer/Composer>
0019 #include <MessageComposer/Util>
0020 
0021 #include <QGpgME/KeyListJob>
0022 #include <QGpgME/Protocol>
0023 
0024 #include <gpgme++/decryptionresult.h>
0025 #include <gpgme++/keylistresult.h>
0026 #include <gpgme++/verificationresult.h>
0027 
0028 #include <cstdlib>
0029 
0030 #include <MessageComposer/TransparentJob>
0031 #include <QTest>
0032 
0033 QTEST_MAIN(AutocryptHeadersJobTest)
0034 
0035 using namespace MessageComposer;
0036 
0037 void AutocryptHeadersJobTest::initTestCase()
0038 {
0039     Test::setupEnv();
0040 }
0041 
0042 void AutocryptHeadersJobTest::testAutocryptHeader()
0043 {
0044     Composer composer;
0045 
0046     KMime::Message skeletonMessage;
0047     skeletonMessage.from(true)->from7BitString("Alice <alice@autocrypt.example>");
0048     skeletonMessage.to(true)->from7BitString("Bob <bob@autocrypt.example>");
0049     skeletonMessage.subject(true)->from7BitString("an Autocrypt header example using Ed25519+Cv25519 key");
0050     skeletonMessage.date(true)->from7BitString("Tue, 22 Jan 2019 12:56:25 +0100");
0051     skeletonMessage.messageID(true)->from7BitString("<abe640bb-018d-4f9d-b4d8-1636d6164e22@autocrypt.example>");
0052 
0053     KMime::Content content;
0054     content.contentType(true)->from7BitString("text/plain");
0055     content.setBody("This is an example e-mail with Autocrypt header and Ed25519+Cv25519 key (key\nfingerprint: ) as defined in Level 1 revision 1.1.\n");
0056 
0057     auto job = QGpgME::openpgp()->keyListJob(false);
0058     std::vector<GpgME::Key> ownKeys;
0059     auto res = job->exec(QStringList(QString::fromLatin1(skeletonMessage.from()[0].addresses()[0])), false, ownKeys);
0060 
0061     auto aJob = new AutocryptHeadersJob(&composer);
0062 
0063     QVERIFY(aJob);
0064 
0065     aJob->setContent(&content);
0066     aJob->setSkeletonMessage(&skeletonMessage);
0067     aJob->setSenderKey(ownKeys[0]);
0068     aJob->setPreferEncrypted(true);
0069     VERIFYEXEC(aJob);
0070 
0071     skeletonMessage.assemble();
0072     content.assemble();
0073 
0074     auto referenceFile = QStringLiteral("autcryptheader.mbox");
0075     QFile f(referenceFile);
0076     QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
0077     f.write(skeletonMessage.head());
0078     f.write(content.encodedContent());
0079     f.close();
0080 
0081     Test::compareFile(referenceFile, QStringLiteral(MAIL_DATA_DIR "/") + referenceFile);
0082 }
0083 
0084 void AutocryptHeadersJobTest::testContentChained()
0085 {
0086     Composer composer;
0087 
0088     KMime::Message skeletonMessage;
0089     skeletonMessage.from(true)->from7BitString("Alice <alice@autocrypt.example>");
0090     skeletonMessage.to(true)->from7BitString("Bob <bob@autocrypt.example>");
0091     skeletonMessage.subject(true)->from7BitString("an Autocrypt header example using Ed25519+Cv25519 key");
0092     skeletonMessage.date(true)->from7BitString("Tue, 22 Jan 2019 12:56:25 +0100");
0093     skeletonMessage.messageID(true)->from7BitString("<abe640bb-018d-4f9d-b4d8-1636d6164e22@autocrypt.example>");
0094 
0095     KMime::Content content;
0096     content.contentType(true)->from7BitString("text/plain");
0097     content.setBody("This is an example e-mail with Autocrypt header and Ed25519+Cv25519 key (key\nfingerprint: ) as defined in Level 1 revision 1.1.\n");
0098 
0099     auto job = QGpgME::openpgp()->keyListJob(false);
0100     std::vector<GpgME::Key> ownKeys;
0101     auto res = job->exec(QStringList(QString::fromLatin1(skeletonMessage.from()[0].addresses()[0])), false, ownKeys);
0102 
0103     auto aJob = new AutocryptHeadersJob(&composer);
0104     QVERIFY(aJob);
0105 
0106     auto tJob = new TransparentJob;
0107     tJob->setContent(&content);
0108 
0109     aJob->setSkeletonMessage(&skeletonMessage);
0110     aJob->setSenderKey(ownKeys[0]);
0111     aJob->setPreferEncrypted(true);
0112     QVERIFY(aJob->appendSubjob(tJob));
0113     VERIFYEXEC(aJob);
0114 
0115     skeletonMessage.assemble();
0116     content.assemble();
0117 
0118     auto referenceFile = QStringLiteral("autcryptheader.mbox");
0119     QFile f(referenceFile);
0120     QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
0121     f.write(skeletonMessage.head());
0122     f.write(content.encodedContent());
0123     f.close();
0124 
0125     Test::compareFile(referenceFile, QStringLiteral(MAIL_DATA_DIR "/") + referenceFile);
0126 }
0127 
0128 void AutocryptHeadersJobTest::testAutocryptGossipHeader()
0129 {
0130     Composer composer;
0131 
0132     KMime::Message skeletonMessage;
0133     skeletonMessage.from(true)->from7BitString("Alice <alice@autocrypt.example>");
0134 
0135     KMime::Content content;
0136     content.setBody(
0137         "Hi Bob and Carol,\n"
0138         "\n"
0139         "I wanted to introduce the two of you to each other.\n"
0140         "\n"
0141         "I hope you are both doing well!  You can now both \"reply all\" here,\n"
0142         "and the thread will remain encrypted.\n");
0143 
0144     auto job = QGpgME::openpgp()->keyListJob(false);
0145     std::vector<GpgME::Key> ownKeys;
0146     job->exec(QStringList(QString::fromLatin1(skeletonMessage.from()[0].addresses()[0])), false, ownKeys);
0147     std::vector<GpgME::Key> keys;
0148     job->exec(QStringList({QStringLiteral("bob@autocrypt.example"), QStringLiteral("carol@autocrypt.example")}), false, keys);
0149 
0150     auto aJob = new AutocryptHeadersJob(&composer);
0151 
0152     QVERIFY(aJob);
0153 
0154     aJob->setContent(&content);
0155     aJob->setSkeletonMessage(&skeletonMessage);
0156     aJob->setSenderKey(ownKeys[0]);
0157     aJob->setPreferEncrypted(true);
0158     aJob->setGossipKeys(keys);
0159     VERIFYEXEC(aJob);
0160 
0161     content.contentType(true)->from7BitString("text/plain");
0162     content.assemble();
0163 
0164     auto referenceFile = QStringLiteral("autocryptgossipheader.mbox");
0165     Test::compareFile(&content, QStringLiteral(MAIL_DATA_DIR "/") + referenceFile);
0166 }
0167 
0168 void AutocryptHeadersJobTest::testSetGnupgHome()
0169 {
0170     Composer composer;
0171 
0172     KMime::Message skeletonMessage;
0173     skeletonMessage.from(true)->from7BitString("Alice <alice@autocrypt.example>");
0174 
0175     KMime::Content content;
0176     content.setBody(
0177         "Hi Bob and Carol,\n"
0178         "\n"
0179         "I wanted to introduce the two of you to each other.\n"
0180         "\n"
0181         "I hope you are both doing well!  You can now both \"reply all\" here,\n"
0182         "and the thread will remain encrypted.\n");
0183 
0184     auto exportJob = QGpgME::openpgp()->keyListJob(false);
0185     std::vector<GpgME::Key> ownKeys;
0186     exportJob->exec(QStringList(QString::fromLatin1(skeletonMessage.from()[0].addresses()[0])), false, ownKeys);
0187     std::vector<GpgME::Key> keys;
0188     exportJob->exec(QStringList({QStringLiteral("bob@autocrypt.example"), QStringLiteral("carol@autocrypt.example")}), false, keys);
0189 
0190     QTemporaryDir dir;
0191     { // test with an empty gnupg Home
0192         auto aJob = new AutocryptHeadersJob(&composer);
0193         QVERIFY(aJob);
0194 
0195         aJob->setContent(&content);
0196         aJob->setSkeletonMessage(&skeletonMessage);
0197         aJob->setSenderKey(ownKeys[0]);
0198         aJob->setPreferEncrypted(true);
0199         aJob->setGossipKeys(keys);
0200         aJob->setGnupgHome(dir.path());
0201         QCOMPARE(aJob->exec(), false);
0202     }
0203 
0204     // Populate Keyring with needed keys.
0205     Test::populateKeyring(dir.path(), ownKeys[0]);
0206     for (const auto &key : keys) {
0207         Test::populateKeyring(dir.path(), key);
0208     }
0209     auto aJob = new AutocryptHeadersJob(&composer);
0210     QVERIFY(aJob);
0211 
0212     aJob->setContent(&content);
0213     aJob->setSkeletonMessage(&skeletonMessage);
0214     aJob->setSenderKey(ownKeys[0]);
0215     aJob->setPreferEncrypted(true);
0216     aJob->setGossipKeys(keys);
0217     aJob->setGnupgHome(dir.path());
0218 
0219     VERIFYEXEC(aJob);
0220 
0221     content.contentType(true)->from7BitString("text/plain");
0222     content.assemble();
0223 
0224     auto referenceFile = QStringLiteral("autocryptgossipheader.mbox");
0225     Test::compareFile(&content, QStringLiteral(MAIL_DATA_DIR "/") + referenceFile);
0226 }
0227 
0228 void AutocryptHeadersJobTest::testStripSenderKey()
0229 {
0230     Composer composer;
0231 
0232     KMime::Message skeletonMessage;
0233     skeletonMessage.from(true)->from7BitString("Alice <alice@autocrypt.example>");
0234 
0235     KMime::Content content;
0236     content.setBody(
0237         "Hi Bob and Carol,\n"
0238         "\n"
0239         "I wanted to introduce the two of you to each other.\n"
0240         "\n"
0241         "I hope you are both doing well!  You can now both \"reply all\" here,\n"
0242         "and the thread will remain encrypted.\n");
0243 
0244     auto job = QGpgME::openpgp()->keyListJob(false);
0245     std::vector<GpgME::Key> ownKeys;
0246     job->exec(QStringList(QString::fromLatin1(skeletonMessage.from()[0].addresses()[0])), false, ownKeys);
0247     std::vector<GpgME::Key> keys;
0248     job->exec(QStringList({QStringLiteral("bob@autocrypt.example"), QStringLiteral("carol@autocrypt.example")}), false, keys);
0249     keys.push_back(ownKeys[0]);
0250 
0251     auto aJob = new AutocryptHeadersJob(&composer);
0252 
0253     QVERIFY(aJob);
0254 
0255     aJob->setContent(&content);
0256     aJob->setSkeletonMessage(&skeletonMessage);
0257     aJob->setSenderKey(ownKeys[0]);
0258     aJob->setPreferEncrypted(true);
0259     aJob->setGossipKeys(keys);
0260     VERIFYEXEC(aJob);
0261 
0262     content.contentType(true)->from7BitString("text/plain");
0263     content.assemble();
0264 
0265     auto referenceFile = QStringLiteral("autocryptgossipheader.mbox");
0266     Test::compareFile(&content, QStringLiteral(MAIL_DATA_DIR "/") + referenceFile);
0267 }
0268 
0269 #include "moc_autocryptheadersjobtest.cpp"