From 8c4436e73af369f79f125f56d020d01b184cafc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Tue, 31 Jan 2023 11:20:47 +0100 Subject: [PATCH] qt: Add job for creating encrypted signed archives * lang/qt/src/signencryptarchivejob.cpp, lang/qt/src/signencryptarchivejob.h, lang/qt/src/signencryptarchivejob_p.h, lang/qt/src/qgpgmesignencryptarchivejob.cpp, lang/qt/src/qgpgmesignencryptarchivejob.h: New. * lang/qt/src/protocol.h (class Protocol): Add pure virtual member function signEncryptArchiveJob * lang/qt/src/protocol_p.h (Protocol::signEncryptArchiveJob): ... and implement it. * lang/qt/src/Makefile.am: Update accordingly. * lang/qt/tests/run-encryptarchivejob.cpp (displayName): Remove. (CommandLineOptions): Initialize member armor. Add member sign. (parseCommandLine): Update application description. Add and parse option -s/--sign. (main): Use SignEncryptArchiveJob if sign option is set. -- GnuPG-bug-id: 6342 --- lang/qt/src/Makefile.am | 8 ++ lang/qt/src/protocol.h | 2 + lang/qt/src/protocol_p.h | 13 ++ lang/qt/src/qgpgmesignencryptarchivejob.cpp | 150 ++++++++++++++++++++ lang/qt/src/qgpgmesignencryptarchivejob.h | 72 ++++++++++ lang/qt/src/signencryptarchivejob.cpp | 62 ++++++++ lang/qt/src/signencryptarchivejob.h | 95 +++++++++++++ lang/qt/src/signencryptarchivejob_p.h | 49 +++++++ lang/qt/tests/run-encryptarchivejob.cpp | 73 ++++++---- 9 files changed, 494 insertions(+), 30 deletions(-) create mode 100644 lang/qt/src/qgpgmesignencryptarchivejob.cpp create mode 100644 lang/qt/src/qgpgmesignencryptarchivejob.h create mode 100644 lang/qt/src/signencryptarchivejob.cpp create mode 100644 lang/qt/src/signencryptarchivejob.h create mode 100644 lang/qt/src/signencryptarchivejob_p.h diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 928b6913..8775531e 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -51,6 +51,7 @@ qgpgme_sources = \ qgpgmesetprimaryuseridjob.cpp \ qgpgmesignarchivejob.cpp \ qgpgmesignencryptjob.cpp \ + qgpgmesignencryptarchivejob.cpp \ qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \ qgpgmeverifyopaquejob.cpp qgpgmewkdlookupjob.cpp threadedjobmixin.cpp \ qgpgmekeyformailboxjob.cpp qgpgme_debug.cpp \ @@ -59,6 +60,7 @@ qgpgme_sources = \ qgpgmegpgcardjob.cpp changeexpiryjob.cpp encryptjob.cpp importjob.cpp \ signarchivejob.cpp \ signencryptjob.cpp \ + signencryptarchivejob.cpp \ dn.cpp cryptoconfig.cpp wkdlookupresult.cpp \ util.cpp @@ -95,6 +97,7 @@ qgpgme_headers= \ signjob.h \ signkeyjob.h \ signencryptjob.h \ + signencryptarchivejob.h \ verifyopaquejob.h \ refreshkeysjob.h \ cryptoconfig.h \ @@ -143,6 +146,7 @@ camelcase_headers= \ SignArchiveJob \ SignJob \ SignKeyJob \ + SignEncryptArchiveJob \ SignEncryptJob \ VerifyOpaqueJob \ RefreshKeysJob \ @@ -195,6 +199,7 @@ private_qgpgme_headers = \ qgpgmesetprimaryuseridjob.h \ qgpgmesignarchivejob.h \ qgpgmesignencryptjob.h \ + qgpgmesignencryptarchivejob.h \ qgpgmesignjob.h \ qgpgmesignkeyjob.h \ qgpgmeverifydetachedjob.h \ @@ -207,6 +212,7 @@ private_qgpgme_headers = \ qgpgmequickjob.h \ signarchivejob_p.h \ signencryptjob_p.h \ + signencryptarchivejob_p.h \ threadedjobmixin.h \ util.h @@ -255,6 +261,7 @@ qgpgme_moc_sources = \ qgpgmesetprimaryuseridjob.moc \ qgpgmesignarchivejob.moc \ qgpgmesignencryptjob.moc \ + qgpgmesignencryptarchivejob.moc \ qgpgmesignjob.moc \ qgpgmesignkeyjob.moc \ qgpgmeverifydetachedjob.moc \ @@ -269,6 +276,7 @@ qgpgme_moc_sources = \ setprimaryuseridjob.moc \ signarchivejob.moc \ signencryptjob.moc \ + signencryptarchivejob.moc \ signjob.moc \ signkeyjob.moc \ specialjob.moc \ diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index 0f3e5b28..e689ba66 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -54,6 +54,7 @@ class EncryptArchiveJob; class EncryptJob; class DecryptJob; class SignArchiveJob; +class SignEncryptArchiveJob; class SignJob; class SignKeyJob; class VerifyDetachedJob; @@ -194,6 +195,7 @@ public: virtual EncryptArchiveJob *encryptArchiveJob(bool armor = false) const = 0; virtual SignArchiveJob *signArchiveJob(bool armor = false) const = 0; + virtual SignEncryptArchiveJob *signEncryptArchiveJob(bool armor = false) const = 0; }; /** Obtain a reference to the OpenPGP Protocol. diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index 73405c6d..a4a33acb 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -49,6 +49,7 @@ #include "qgpgmeencryptarchivejob.h" #include "qgpgmeencryptjob.h" #include "qgpgmesignarchivejob.h" +#include "qgpgmesignencryptarchivejob.h" #include "qgpgmesignjob.h" #include "qgpgmesignkeyjob.h" #include "qgpgmeexportjob.h" @@ -532,6 +533,18 @@ public: } return nullptr; } + + QGpgME::SignEncryptArchiveJob *signEncryptArchiveJob(bool armor) const override + { + if (mProtocol != GpgME::OpenPGP) { + return nullptr; + } + if (auto context = GpgME::Context::createForProtocol(mProtocol)) { + context->setArmor(armor); + return new QGpgME::QGpgMESignEncryptArchiveJob{context}; + } + return nullptr; + } }; } diff --git a/lang/qt/src/qgpgmesignencryptarchivejob.cpp b/lang/qt/src/qgpgmesignencryptarchivejob.cpp new file mode 100644 index 00000000..b75c4d0f --- /dev/null +++ b/lang/qt/src/qgpgmesignencryptarchivejob.cpp @@ -0,0 +1,150 @@ +/* + qgpgmesignencryptarchivejob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2004,2007,2008 Klarälvdalens Datakonsult AB + Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik + Software engineering by Intevation GmbH + Copyright (c) 2022,2023 g10 Code GmbH + Software engineering by Ingo Klöcker + + 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. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "qgpgmesignencryptarchivejob.h" + +#include "dataprovider.h" +#include "signencryptarchivejob_p.h" +#include "filelistdataprovider.h" + +// #include +#include +// #include +// +// #include +// #include +// +// #include + +using namespace QGpgME; +using namespace GpgME; + +namespace +{ + +class QGpgMESignEncryptArchiveJobPrivate : public SignEncryptArchiveJobPrivate +{ + QGpgMESignEncryptArchiveJob *q = nullptr; + +public: + QGpgMESignEncryptArchiveJobPrivate(QGpgMESignEncryptArchiveJob *qq) + : q{qq} + { + } + + ~QGpgMESignEncryptArchiveJobPrivate() override = default; + +private: + void start() override + { + q->run(); + } +}; + +} + +QGpgMESignEncryptArchiveJob::QGpgMESignEncryptArchiveJob(Context *context) + : mixin_type{context} +{ + setJobPrivate(this, std::unique_ptr{new QGpgMESignEncryptArchiveJobPrivate{this}}); + lateInitialization(); +} + +static QGpgMESignEncryptArchiveJob::result_type sign_encrypt(Context *ctx, + QThread *thread, + const std::vector &signers, + const std::vector &recipients, + const std::vector &paths, + const std::weak_ptr &cipherText_, + Context::EncryptionFlags encryptionFlags, + const QString &baseDirectory) +{ + const std::shared_ptr cipherText = cipherText_.lock(); + const _detail::ToThreadMover ctMover(cipherText, thread); + + QGpgME::FileListDataProvider in{paths}; + Data indata(&in); + if (!baseDirectory.isEmpty()) { + indata.setFileName(baseDirectory.toStdString()); + } + + QGpgME::QIODeviceDataProvider out{cipherText}; + Data outdata(&out); + + ctx->clearSigningKeys(); + for (const Key &signer : signers) { + if (!signer.isNull()) { + if (const Error err = ctx->addSigningKey(signer)) { + return std::make_tuple(SigningResult{err}, EncryptionResult{}, QString{}, Error{}); + } + } + } + + encryptionFlags = static_cast(encryptionFlags | Context::EncryptArchive); + const auto res = ctx->signAndEncrypt(recipients, indata, outdata, encryptionFlags); + Error ae; + const QString log = _detail::audit_log_as_html(ctx, ae); + return std::make_tuple(res.first, res.second, log, ae); +} + +GpgME::Error QGpgMESignEncryptArchiveJob::start(const std::vector &signers, + const std::vector &recipients, + const std::vector &paths, + const std::shared_ptr &cipherText, + const GpgME::Context::EncryptionFlags encryptionFlags) +{ + if (!cipherText) { + return Error::fromCode(GPG_ERR_INV_VALUE); + } + + run(std::bind(&sign_encrypt, + std::placeholders::_1, + std::placeholders::_2, + signers, + recipients, + paths, + std::placeholders::_3, + encryptionFlags, + baseDirectory()), + cipherText); + return {}; +} + +#include "qgpgmesignencryptarchivejob.moc" diff --git a/lang/qt/src/qgpgmesignencryptarchivejob.h b/lang/qt/src/qgpgmesignencryptarchivejob.h new file mode 100644 index 00000000..80e6da4f --- /dev/null +++ b/lang/qt/src/qgpgmesignencryptarchivejob.h @@ -0,0 +1,72 @@ +/* + qgpgmesignencryptarchivejob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 g10 Code GmbH + Software engineering by Ingo Klöcker + + 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. +*/ + +#ifndef __QGPGME_QGPGMESIGNENCRYPTARCHIVEJOB_H__ +#define __QGPGME_QGPGMESIGNENCRYPTARCHIVEJOB_H__ + +#include "signencryptarchivejob.h" + +#include "threadedjobmixin.h" + +#include +#include + +namespace QGpgME +{ + +class QGpgMESignEncryptArchiveJob +#ifdef Q_MOC_RUN + : public SignEncryptArchiveJob +#else + : public _detail::ThreadedJobMixin> +#endif +{ + Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: + void slotFinished(); +#endif +public: + explicit QGpgMESignEncryptArchiveJob(GpgME::Context *context); + ~QGpgMESignEncryptArchiveJob() = default; + + GpgME::Error start(const std::vector &signers, + const std::vector &recipients, + const std::vector &paths, + const std::shared_ptr &cipherText, + const GpgME::Context::EncryptionFlags flags) override; +}; + +} + +#endif // __QGPGME_QGPGMESIGNENCRYPTARCHIVEJOB_H__ diff --git a/lang/qt/src/signencryptarchivejob.cpp b/lang/qt/src/signencryptarchivejob.cpp new file mode 100644 index 00000000..6a9a5abe --- /dev/null +++ b/lang/qt/src/signencryptarchivejob.cpp @@ -0,0 +1,62 @@ +/* + signencryptarchivejob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 g10 Code GmbH + Software engineering by Ingo Klöcker + + 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. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "signencryptarchivejob.h" +#include "signencryptarchivejob_p.h" + +using namespace QGpgME; + +SignEncryptArchiveJob::SignEncryptArchiveJob(QObject *parent) + : Job{parent} +{ +} + +SignEncryptArchiveJob::~SignEncryptArchiveJob() = default; + +void SignEncryptArchiveJob::setBaseDirectory(const QString &baseDirectory) +{ + auto d = jobPrivate(this); + d->m_baseDirectory = baseDirectory; +} + +QString SignEncryptArchiveJob::baseDirectory() const +{ + auto d = jobPrivate(this); + return d->m_baseDirectory; +} + +#include "signencryptarchivejob.moc" diff --git a/lang/qt/src/signencryptarchivejob.h b/lang/qt/src/signencryptarchivejob.h new file mode 100644 index 00000000..67b2fcbb --- /dev/null +++ b/lang/qt/src/signencryptarchivejob.h @@ -0,0 +1,95 @@ +/* + signencryptarchivejob.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 g10 Code GmbH + Software engineering by Ingo Klöcker + + 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. +*/ + +#ifndef __QGPGME_SIGNENCRYPTARCHIVEJOB_H__ +#define __QGPGME_SIGNENCRYPTARCHIVEJOB_H__ + +#include "job.h" + +#ifdef BUILDING_QGPGME +# include "context.h" +#else +# include +#endif + +namespace GpgME +{ +class Key; +} + +namespace QGpgME +{ + +/** + * Abstract base class for job for creating encrypted signed archives + */ +class QGPGME_EXPORT SignEncryptArchiveJob : public Job +{ + Q_OBJECT +protected: + explicit SignEncryptArchiveJob(QObject *parent); +public: + ~SignEncryptArchiveJob() override; + + void setBaseDirectory(const QString &baseDirectory); + QString baseDirectory() const; + + /** + * Starts the creation of an encrypted signed archive. + * + * Creates an encrypted signed archive with the files and directories in + * \a paths. + * The archive is signed with the keys in \a signers or with the default + * key, if \a signers is empty. Then the archive is encrypted for the + * keys in \a recipients. If \a recipients is empty, then symmetric + * encryption is performed. The encrypted signed archive is written to + * \a cipherText. + * + * Emits result() when the job has finished. + */ + virtual GpgME::Error start(const std::vector &signers, + const std::vector &recipients, + const std::vector &paths, + const std::shared_ptr &cipherText, + const GpgME::Context::EncryptionFlags flags) = 0; + +Q_SIGNALS: + void result(const GpgME::SigningResult &signingResult, + const GpgME::EncryptionResult &encryptionResult, + const QString &auditLogAsHtml = {}, + const GpgME::Error &auditLogError = {}); +}; + +} + +#endif // __QGPGME_SIGNENCRYPTARCHIVEJOB_H__ diff --git a/lang/qt/src/signencryptarchivejob_p.h b/lang/qt/src/signencryptarchivejob_p.h new file mode 100644 index 00000000..2732fd0a --- /dev/null +++ b/lang/qt/src/signencryptarchivejob_p.h @@ -0,0 +1,49 @@ +/* + signencryptarchivejob_p.h + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2023 g10 Code GmbH + Software engineering by Ingo Klöcker + + 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. +*/ + +#ifndef __QGPGME_SIGNENCRYPTARCHIVEJOB_P_H__ +#define __QGPGME_SIGNENCRYPTARCHIVEJOB_P_H__ + +#include "job_p.h" + +namespace QGpgME +{ + +struct SignEncryptArchiveJobPrivate : public JobPrivate +{ + QString m_baseDirectory; +}; + +} + +#endif // __QGPGME_SIGNENCRYPTARCHIVEJOB_P_H__ diff --git a/lang/qt/tests/run-encryptarchivejob.cpp b/lang/qt/tests/run-encryptarchivejob.cpp index e48af9f8..cdcfa17d 100644 --- a/lang/qt/tests/run-encryptarchivejob.cpp +++ b/lang/qt/tests/run-encryptarchivejob.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -44,8 +45,8 @@ #include #include +#include -#include #include using namespace GpgME; @@ -55,20 +56,9 @@ std::ostream &operator<<(std::ostream &os, const QString &s) return os << s.toLocal8Bit().constData(); } -const char *displayName(Protocol protocol) -{ - switch (protocol) { - case GpgME::OpenPGP: - return "OpenPGP"; - case GpgME::CMS: - return "S/MIME"; - default: - return "Unknown protocol"; - } -} - struct CommandLineOptions { - bool armor; + bool armor = false; + bool sign = false; QString archiveName; QString baseDirectory; std::vector filesAndDirectories; @@ -79,9 +69,10 @@ CommandLineOptions parseCommandLine(const QStringList &arguments) CommandLineOptions options; QCommandLineParser parser; - parser.setApplicationDescription("Test program for EncryptArchiveJob"); + parser.setApplicationDescription("Test program for EncryptArchiveJob and SignEncryptArchiveJob"); parser.addHelpOption(); parser.addOptions({ + {{"s", "sign"}, "Sign archive before encryption."}, {{"o", "output"}, "Write output to FILE.", "FILE"}, {{"a", "armor"}, "Create ASCII armored output."}, {{"C", "directory"}, "Change to DIRECTORY before creating the archive.", "DIRECTORY"}, @@ -96,6 +87,7 @@ CommandLineOptions parseCommandLine(const QStringList &arguments) } options.armor = parser.isSet("armor"); + options.sign = parser.isSet("sign"); options.archiveName = parser.value("output"); options.baseDirectory = parser.value("directory"); std::copy(args.begin(), args.end(), std::back_inserter(options.filesAndDirectories)); @@ -136,22 +128,43 @@ int main(int argc, char **argv) return 1; } - auto job = QGpgME::openpgp()->encryptArchiveJob(options.armor); - if (!job) { - std::cerr << "Error: Could not create job" << std::endl; - return 1; - } - job->setBaseDirectory(options.baseDirectory); - QObject::connect(job, &QGpgME::EncryptArchiveJob::result, &app, [](const GpgME::EncryptionResult &result, const QString &auditLog, const GpgME::Error &) { - std::cerr << "Diagnostics: " << auditLog << std::endl; - std::cerr << "Result: " << result << std::endl; - qApp->quit(); - }); + if (options.sign) { + auto job = QGpgME::openpgp()->signEncryptArchiveJob(options.armor); + if (!job) { + std::cerr << "Error: Could not create job" << std::endl; + return 1; + } + job->setBaseDirectory(options.baseDirectory); + QObject::connect(job, &QGpgME::SignEncryptArchiveJob::result, &app, [](const GpgME::SigningResult &signingResult, const GpgME::EncryptionResult &encryptionResult, const QString &auditLog, const GpgME::Error &) { + std::cerr << "Diagnostics: " << auditLog << std::endl; + std::cerr << "Signing Result: " << signingResult << std::endl; + std::cerr << "Encryption Result: " << encryptionResult << std::endl; + qApp->quit(); + }); - const auto err = job->start({}, options.filesAndDirectories, output, GpgME::Context::None); - if (err) { - std::cerr << "Error: Starting the job failed: " << err.asString() << std::endl; - return 1; + const auto err = job->start({}, {}, options.filesAndDirectories, output, GpgME::Context::None); + if (err) { + std::cerr << "Error: Starting the job failed: " << err.asString() << std::endl; + return 1; + } + } else { + auto job = QGpgME::openpgp()->encryptArchiveJob(options.armor); + if (!job) { + std::cerr << "Error: Could not create job" << std::endl; + return 1; + } + job->setBaseDirectory(options.baseDirectory); + QObject::connect(job, &QGpgME::EncryptArchiveJob::result, &app, [](const GpgME::EncryptionResult &result, const QString &auditLog, const GpgME::Error &) { + std::cerr << "Diagnostics: " << auditLog << std::endl; + std::cerr << "Result: " << result << std::endl; + qApp->quit(); + }); + + const auto err = job->start({}, options.filesAndDirectories, output, GpgME::Context::None); + if (err) { + std::cerr << "Error: Starting the job failed: " << err.asString() << std::endl; + return 1; + } } return app.exec();