Page MenuHome GnuPG

GpgOL: Sign requested without signing key shows error
Closed, ResolvedPublic

Description

When sign is selected but no signing key exists, pinentry should prompt the user to generate a key for this identity.

Instead an error message about unusable secret key is shown.

I noticed that the resolver.exe from gpg4win-tools also does not handle this case.

Event Timeline

aheinecke created this task.
aheinecke added a subscriber: ikloecker.

@ikloecker
If I test the resolver code from libkleo with gpg4win-tools keyresolver binary:

GNUPGHOME=$(mktemp -d) resolver --sign --debug --sender aheinecke@gnupg.com

It does not show me the approval dialog but thinks that "AllResolved" because it could resolve all encryption recipients even though it could not resolve the signers.

I am not sure how to fix this, to avoid changing every place where the result is returned I would fix it somewhat like this:

diff --git a/src/kleo/keyresolver.cpp b/src/kleo/keyresolver.cpp
index 3c62554..73127b0 100644
--- a/src/kleo/keyresolver.cpp
+++ b/src/kleo/keyresolver.cpp
@@ -103,7 +103,7 @@ void KeyResolver::start(bool showApproval, QWidget *parentWidget)
     }
     const auto result = d->mCore.resolve();
     const bool success = (result.flags & KeyResolverCore::AllResolved);
-    if (success && !showApproval) {
+    if (success && !showApproval && (!d->mSign || !result.solution.signingKeys.empty())) {
         d->mResult = std::move(result.solution);
         Q_EMIT keysResolved(true, false);
         return;

But I don't think that this really is the API idea of the keyresolvercore.

Sounds familiar, that the signing keys are not considered. I think when I worked on this, I thought that is was a bad idea to mix resolving signing and encryption keys. Do the unit tests still pass with your change?

Yes, unit tests still pass. So its ok with you to commit this?

I'm not sure. In KeyResolverCore::Private::resolve() line 668 reads

const bool pgpOnly = (!mEncrypt || !hasUnresolvedRecipients(mEncKeys, OpenPGP)) && (!mSign || mSigKeys.contains(OpenPGP));

I'd say this is supposed to check if there is an OpenPGP signing key, but I guess mSigKeys[OpenPGP] is an empty list. This may be a regression introduced by the resultion of key groups because in KeyResolverCore::Private::resolveSigningGroups() the entry mSigKeys[OpenPGP] is always set (unless we are in CMS-only mode).

So, the correct fix would be in KeyResolverCore.

ikloecker moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.
ikloecker changed the task status from Open to Testing.Mar 3 2022, 12:03 PM
ikloecker removed ikloecker as the assignee of this task.
ikloecker moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.

Fixed.

ebo claimed this task.
ebo moved this task from Restricted Project Column to Restricted Project Column on the Restricted Project board.
ebo added a subscriber: ebo.

This works, when sign is selected and no standard OpenPGP key for the mail address exists.

It does not work when a sign only key exists. Then the error message occurs, see T6569 for that.