From 1698eec2ae3ec1a97c739e892d9cf288c0ec4ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Thu, 2 Feb 2023 11:59:55 +0100 Subject: [PATCH] cpp: Return successful verification for signed but not encrypted data * lang/cpp/src/context.cpp (Context::decrypt): Use decryptionResult(). (Context::verifyDetachedSignature, Context::verifyOpaqueSignature): Use verificationResult(). (Context::verificationResult): Ignore "no data" error for signed but not encrypted data. (Context::decryptAndVerify): Use decryptionResult() and verificationResult(). -- gpgme's decrypt operations set the error to GPG_ERR_NO_DATA if no encrypted data was found. It makes sense to use this error for the encryption result, but it doesn't make sense to use it also for the verfication result if signed data was found. This way using the combined decrypt-verify operations on data that may be encrypted and/or signed doesn't produce confusing results. GnuPG-bug-id: 6342 --- lang/cpp/src/context.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp index afe32299..7667eb30 100644 --- a/lang/cpp/src/context.cpp +++ b/lang/cpp/src/context.cpp @@ -1070,7 +1070,7 @@ DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText, const const Data::Private *const cdp = cipherText.impl(); Data::Private *const pdp = plainText.impl(); d->lasterr = gpgme_op_decrypt_ext(d->ctx, static_cast (d->decryptFlags | flags), cdp ? cdp->data : nullptr, pdp ? pdp->data : nullptr); - return DecryptionResult(d->ctx, Error(d->lasterr)); + return decryptionResult(); } DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText) @@ -1107,7 +1107,7 @@ VerificationResult Context::verifyDetachedSignature(const Data &signature, const const Data::Private *const sdp = signature.impl(); const Data::Private *const tdp = signedText.impl(); d->lasterr = gpgme_op_verify(d->ctx, sdp ? sdp->data : nullptr, tdp ? tdp->data : nullptr, nullptr); - return VerificationResult(d->ctx, Error(d->lasterr)); + return verificationResult(); } VerificationResult Context::verifyOpaqueSignature(const Data &signedData, Data &plainText) @@ -1116,7 +1116,7 @@ VerificationResult Context::verifyOpaqueSignature(const Data &signedData, Data & const Data::Private *const sdp = signedData.impl(); Data::Private *const pdp = plainText.impl(); d->lasterr = gpgme_op_verify(d->ctx, sdp ? sdp->data : nullptr, nullptr, pdp ? pdp->data : nullptr); - return VerificationResult(d->ctx, Error(d->lasterr)); + return verificationResult(); } Error Context::startDetachedSignatureVerification(const Data &signature, const Data &signedText) @@ -1138,9 +1138,18 @@ Error Context::startOpaqueSignatureVerification(const Data &signedData, Data &pl VerificationResult Context::verificationResult() const { if (d->lastop & Private::Verify) { - return VerificationResult(d->ctx, Error(d->lasterr)); + const auto res = VerificationResult{d->ctx, Error(d->lasterr)}; + if ((d->lastop == Private::DecryptAndVerify) + && (res.error().code() == GPG_ERR_NO_DATA) + && (res.numSignatures() > 0)) { + // ignore "no data" error for verification if there are signatures and + // the operation was a combined (tentative) decryption and verification + // because then "no data" just indicates that there was nothing to decrypt + return VerificationResult{d->ctx, Error{}}; + } + return res; } else { - return VerificationResult(); + return {}; } } @@ -1151,8 +1160,7 @@ std::pair Context::decryptAndVerify(const Data::Private *const pdp = plainText.impl(); d->lasterr = gpgme_op_decrypt_ext(d->ctx, static_cast (d->decryptFlags | flags | DecryptVerify), cdp ? cdp->data : nullptr, pdp ? pdp->data : nullptr); - return std::make_pair(DecryptionResult(d->ctx, Error(d->lasterr)), - VerificationResult(d->ctx, Error(d->lasterr))); + return std::make_pair(decryptionResult(), verificationResult()); } std::pair Context::decryptAndVerify(const Data &cipherText, Data &plainText)