From a44d84772d6197dfb977b411f6eb7cb29b08471b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Thu, 21 Dec 2023 09:38:52 +0100 Subject: qt: Support writing/reading signed/encrypted files directly to/from file * lang/qt/src/Makefile.am: Add new files. * lang/qt/src/job.cpp (EncryptJob, SignJob, SignEncryptJob): Move definition of constructor and destructor and inclusion of the moc file to the corresponding .cpp files. * lang/qt/src/encryptjob.cpp (EncryptJob): Define constructor. Define destructor as default. Include moc file. * lang/qt/src/encryptjob.cpp, lang/qt/src/encryptjob.h (EncryptJob): Add member functions setRecipients, recipients, setInputFile, inputFile, setOutputFile, outputFile, setEncryptionFlags, encryptionFlags. * lang/qt/src/encryptjob_p.h (EncryptJobPrivate): Add members m_recipients, m_inputFilePath, m_outputFilePath, m_encryptionFlags. * lang/qt/src/qgpgmeencryptjob.cpp (encrypt_to_filename): New. (QGpgMEEncryptJobPrivate::startIt): Start the job with the values from the member variables. * lang/qt/src/qgpgmesignencryptjob.cpp (sign_encrypt_to_filename): New. (QGpgMESignEncryptJobPrivate::startIt): Start the job with the values from the member variables. * lang/qt/src/qgpgmesignjob.cpp (class QGpgMESignJobPrivate): New. (QGpgMESignJob::QGpgMESignJob): Instantiate private job class. (sign_to_filename): New. * lang/qt/src/signencryptjob.cpp (SignEncryptJob): Define constructor. Define destructor as default. Include moc file. * lang/qt/src/signencryptjob.cpp, lang/qt/src/signencryptjob.h (SignEncryptJob): Add member functions setSigners, signers, setRecipients, recipients, setInputFile, inputFile, setOutputFile, outputFile, setEncryptionFlags, encryptionFlags. * lang/qt/src/signencryptjob_p.h (SignEncryptJobPrivate): Add members m_signers, m_recipients, m_inputFilePath, m_outputFilePath, m_encryptionFlags. * lang/qt/src/signjob.cpp: New. * lang/qt/src/signjob.h (SignJob): Add member functions setSigners, signers, setInputFile, inputFile, setOutputFile, outputFile, setSigningFlags, signingFlags. * lang/qt/src/signjob_p.h: New. * lang/qt/tests/Makefile.am: Add new test programs. * lang/qt/tests/run-encryptjob.cpp: New. * lang/qt/tests/run-signjob.cpp: New. -- This makes it possible to tell gpg to read the input and write the output directly to a specified file bypassing GpgME's Data IO when signing and/or encrypting a file. GnuPG-bug-id: 6550 --- lang/qt/src/qgpgmesignencryptjob.cpp | 86 +++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 11 deletions(-) (limited to 'lang/qt/src/qgpgmesignencryptjob.cpp') diff --git a/lang/qt/src/qgpgmesignencryptjob.cpp b/lang/qt/src/qgpgmesignencryptjob.cpp index 0f5642a9..27af7ae9 100644 --- a/lang/qt/src/qgpgmesignencryptjob.cpp +++ b/lang/qt/src/qgpgmesignencryptjob.cpp @@ -40,14 +40,14 @@ #include "qgpgmesignencryptjob.h" -#include "signencryptjob_p.h" - #include "dataprovider.h" +#include "signencryptjob_p.h" +#include "util.h" -#include "context.h" -#include "data.h" -#include "key.h" -#include "exception.h" +#include +#include +#include +#include #include #include @@ -73,11 +73,7 @@ public: ~QGpgMESignEncryptJobPrivate() override = default; private: - GpgME::Error startIt() override - { - Q_ASSERT(!"Not supported by this Job class."); - return Error::fromCode(GPG_ERR_NOT_SUPPORTED); - } + GpgME::Error startIt() override; void startNow() override { @@ -171,6 +167,60 @@ static QGpgMESignEncryptJob::result_type sign_encrypt_qba(Context *ctx, const st return sign_encrypt(ctx, nullptr, signers, recipients, buffer, std::shared_ptr(), eflags, outputIsBsse64Encoded, fileName); } +static QGpgMESignEncryptJob::result_type sign_encrypt_to_filename(Context *ctx, + const std::vector &signers, + const std::vector &recipients, + const QString &inputFilePath, + const QString &outputFilePath, + Context::EncryptionFlags flags) +{ + Data indata; +#ifdef Q_OS_WIN + indata.setFileName(inputFilePath().toUtf8().constData()); +#else + indata.setFileName(QFile::encodeName(inputFilePath).constData()); +#endif + + PartialFileGuard partFileGuard{outputFilePath}; + if (partFileGuard.tempFileName().isEmpty()) { + return std::make_tuple(SigningResult{Error::fromCode(GPG_ERR_EEXIST)}, + EncryptionResult{Error::fromCode(GPG_ERR_EEXIST)}, + QByteArray{}, + QString{}, + Error{}); + } + + Data outdata; +#ifdef Q_OS_WIN + outdata.setFileName(partFileGuard.tempFileName().toUtf8().constData()); +#else + outdata.setFileName(QFile::encodeName(partFileGuard.tempFileName()).constData()); +#endif + + ctx->clearSigningKeys(); + for (const Key &signer : signers) { + if (!signer.isNull()) { + if (const Error err = ctx->addSigningKey(signer)) { + return std::make_tuple(SigningResult{err}, EncryptionResult{}, QByteArray{}, QString{}, Error{}); + } + } + } + + flags = static_cast(flags | Context::EncryptFile); + const auto results = ctx->signAndEncrypt(recipients, indata, outdata, flags); + const auto &signingResult = results.first; + const auto &encryptionResult = results.second; + + if (!signingResult.error().code() && !encryptionResult.error().code()) { + // the operation succeeded -> save the result under the requested file name + partFileGuard.commit(); + } + + Error ae; + const QString log = _detail::audit_log_as_html(ctx, ae); + return std::make_tuple(signingResult, encryptionResult, QByteArray{}, log, ae); +} + Error QGpgMESignEncryptJob::start(const std::vector &signers, const std::vector &recipients, const QByteArray &plainText, bool alwaysTrust) { run(std::bind(&sign_encrypt_qba, std::placeholders::_1, signers, recipients, plainText, alwaysTrust ? Context::AlwaysTrust : Context::None, mOutputIsBase64Encoded, fileName())); @@ -205,4 +255,18 @@ void QGpgMESignEncryptJob::resultHook(const result_type &tuple) { mResult = std::make_pair(std::get<0>(tuple), std::get<1>(tuple)); } + +GpgME::Error QGpgMESignEncryptJobPrivate::startIt() +{ + if (m_inputFilePath.isEmpty() || m_outputFilePath.isEmpty()) { + return Error::fromCode(GPG_ERR_INV_VALUE); + } + + q->run([=](Context *ctx) { + return sign_encrypt_to_filename(ctx, m_signers, m_recipients, m_inputFilePath, m_outputFilePath, m_encryptionFlags); + }); + + return {}; +} + #include "qgpgmesignencryptjob.moc" -- cgit v1.2.3