diff options
| author | Ingo Klöcker <[email protected]> | 2024-06-18 14:36:40 +0000 |
|---|---|---|
| committer | Ingo Klöcker <[email protected]> | 2024-06-18 14:36:40 +0000 |
| commit | 7d5df0bf0d86391151911160db24441966b6d938 (patch) | |
| tree | 8bff5499ec7b3492710e525d0ed33844ad9a4c9e /lang/qt/src | |
| parent | qt,build: Install headers for Qt 5 and Qt 6 in different locations (diff) | |
| download | gpgme-7d5df0bf0d86391151911160db24441966b6d938.tar.gz gpgme-7d5df0bf0d86391151911160db24441966b6d938.zip | |
qt: Allow appending a detached signature to an existing file
* lang/qt/src/qgpgmesignjob.cpp (sign_to_filename): Add argument
"appendSignature". Append new detached signature to an existing file if
requested.
* lang/qt/src/signjob.cpp, lang/qt/src/signjob.h (class SignJob): Add
member functions setAppendSignature, appendSignatureEnabled.
* lang/qt/src/signjob_p.h (struct SignJobPrivate): Add member
m_appendSignature.
* lang/qt/tests/run-signjob.cpp (struct CommandLineOptions): Add members
signingFlags, appendSignature. Initialize armor.
(parseCommandLine): Add command line options --detach-sign and --append.
(main): Do not exit if output file exists and append is enabled.
Pass new options to the job.
--
This change simplifies cross-signing a document by appending additional
detached signatures to a file with already existing detached signatures.
GnuPG-bug-id: 6867
Diffstat (limited to 'lang/qt/src')
| -rw-r--r-- | lang/qt/src/qgpgmesignjob.cpp | 42 | ||||
| -rw-r--r-- | lang/qt/src/signjob.cpp | 12 | ||||
| -rw-r--r-- | lang/qt/src/signjob.h | 14 | ||||
| -rw-r--r-- | lang/qt/src/signjob_p.h | 1 |
4 files changed, 62 insertions, 7 deletions
diff --git a/lang/qt/src/qgpgmesignjob.cpp b/lang/qt/src/qgpgmesignjob.cpp index 76e60e72..7ad71767 100644 --- a/lang/qt/src/qgpgmesignjob.cpp +++ b/lang/qt/src/qgpgmesignjob.cpp @@ -170,7 +170,8 @@ static QGpgMESignJob::result_type sign_to_filename(Context *ctx, const std::vector<Key> &signers, const QString &inputFilePath, const QString &outputFilePath, - SignatureMode flags) + SignatureMode flags, + bool appendSignature) { Data indata; #ifdef Q_OS_WIN @@ -206,13 +207,42 @@ static QGpgMESignJob::result_type sign_to_filename(Context *ctx, flags = static_cast<SignatureMode>(flags | SignFile); const auto signingResult = ctx->sign(indata, outdata, flags); + Error ae; + const QString log = _detail::audit_log_as_html(ctx, ae); + if (!signingResult.error().code()) { - // the operation succeeded -> save the result under the requested file name - partFileGuard.commit(); + // the operation succeeded + const bool appendSignatureToExistingFile = appendSignature && (flags & Detached) && QFile::exists(outputFilePath); + if (appendSignatureToExistingFile) { + // append the result to the existing file + QFile newSignatureFile{partFileGuard.tempFileName()}; + if (!newSignatureFile.open(QIODevice::ReadOnly)) { + qCDebug(QGPGME_LOG) << "Failed to open detached signature file" << newSignatureFile.fileName() << "(" << newSignatureFile.errorString() << ")"; + return std::make_tuple(SigningResult{Error::fromCode(GPG_ERR_GENERAL)}, QByteArray{}, log, ae); + } + const QByteArray newSigData = newSignatureFile.readAll(); + if (newSigData.isEmpty()) { + qCDebug(QGPGME_LOG) << "Failed to read detached signature from file" << newSignatureFile.fileName() << "(" << newSignatureFile.errorString() << ")"; + return std::make_tuple(SigningResult{Error::fromCode(GPG_ERR_GENERAL)}, QByteArray{}, log, ae); + } + newSignatureFile.close(); + + QFile existingSignatureFile{outputFilePath}; + if (!existingSignatureFile.open(QIODevice::WriteOnly | QIODevice::Append)) { + qCDebug(QGPGME_LOG) << "Failed to open existing detached signature file for appending" << existingSignatureFile.fileName() << "(" << existingSignatureFile.errorString() << ")"; + return std::make_tuple(SigningResult{Error::fromCode(GPG_ERR_GENERAL)}, QByteArray{}, log, ae); + } + const auto bytesWritten = existingSignatureFile.write(newSigData); + if (bytesWritten != newSigData.size()) { + qCDebug(QGPGME_LOG) << "Failed to write new signature to existing detached signature file" << existingSignatureFile.fileName() << "(" << existingSignatureFile.errorString() << ")"; + return std::make_tuple(SigningResult{Error::fromCode(GPG_ERR_GENERAL)}, QByteArray{}, log, ae); + } + } else { + // 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, QByteArray{}, log, ae); } @@ -241,7 +271,7 @@ GpgME::Error QGpgMESignJobPrivate::startIt() } q->run([=](Context *ctx) { - return sign_to_filename(ctx, m_signers, m_inputFilePath, m_outputFilePath, m_signingFlags); + return sign_to_filename(ctx, m_signers, m_inputFilePath, m_outputFilePath, m_signingFlags, m_appendSignature); }); return {}; diff --git a/lang/qt/src/signjob.cpp b/lang/qt/src/signjob.cpp index 0a9c8651..be15051b 100644 --- a/lang/qt/src/signjob.cpp +++ b/lang/qt/src/signjob.cpp @@ -95,4 +95,16 @@ GpgME::SignatureMode SignJob::signingFlags() const return d->m_signingFlags; } +void SignJob::setAppendSignature(bool append) +{ + auto d = jobPrivate<SignJobPrivate>(this); + d->m_appendSignature = append; +} + +bool SignJob::appendSignatureEnabled() const +{ + auto d = jobPrivate<SignJobPrivate>(this); + return d->m_appendSignature; +} + #include "signjob.moc" diff --git a/lang/qt/src/signjob.h b/lang/qt/src/signjob.h index 273277b5..085f8498 100644 --- a/lang/qt/src/signjob.h +++ b/lang/qt/src/signjob.h @@ -113,7 +113,8 @@ public: * * \note If a file with this path exists, then the job will fail, i.e. you * need to delete an existing file that shall be overwritten before you - * start the job. + * start the job. If you create a detached signature then you can tell + * the job to append the new detached signature to an existing file. */ void setOutputFile(const QString &path); QString outputFile() const; @@ -130,6 +131,17 @@ public: GpgME::SignatureMode signingFlags() const; /** + * If @c true then a new detached signature is appended to an already + * existing detached signature. + * + * Defaults to \c false. + * + * Used if the job is started with startIt(). + */ + void setAppendSignature(bool append); + bool appendSignatureEnabled() const; + + /** Starts the signing operation. \a signers is the list of keys to sign \a plainText with. Empty (null) keys are ignored. */ diff --git a/lang/qt/src/signjob_p.h b/lang/qt/src/signjob_p.h index 75309782..e1eae6b8 100644 --- a/lang/qt/src/signjob_p.h +++ b/lang/qt/src/signjob_p.h @@ -48,6 +48,7 @@ struct SignJobPrivate : public JobPrivate QString m_inputFilePath; QString m_outputFilePath; GpgME::SignatureMode m_signingFlags = GpgME::SignFile; + bool m_appendSignature = false; }; } |
