[PATCH 5/5] Throw a NoKeyError when no matching PGP key

Konstantin Ryabitsev <[email protected]> Thu, 3 Jun 2021 13:18:15 -0400
Newsgroups org.kernel.lore.signatures
Message-ID <d37d358c9ddd4d0972fbcd392ce26df852767948.1622740672.git.konstantin.ryabitsev@linux.dev>
Fix a problem where we incorrectly reported a missing public key for a
failing signature for the cases when the public key is in the default
keyring.

Signed-off-by: Konstantin Ryabitsev <[email protected]>
---
 patatt/__init__.py | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/patatt/__init__.py b/patatt/__init__.py
index b4018ab..f5e0fd9 100644
--- a/patatt/__init__.py
+++ b/patatt/__init__.py
@@ -47,7 +47,7 @@ OPT_HDRS = [b'message-id']
 KEYCACHE = dict()
 
 # My version
-__VERSION__ = '0.4.4'
+__VERSION__ = '0.4.5-dev'
 MAX_SUPPORTED_FORMAT_VERSION = 1
 
 
@@ -69,6 +69,12 @@ class ValidationError(Exception):
         self.errors = errors
 
 
+class NoKeyError(ValidationError):
+    def __init__(self, message: str, errors: Optional[list] = None):
+        super().__init__(message)
+        self.errors = errors
+
+
 class BodyValidationError(ValidationError):
     def __init__(self, message: str, errors: Optional[list] = None):
         super().__init__(message, errors)
@@ -346,6 +352,8 @@ class DevsigHeader:
             ecode, out, err = gpg_run_command(vrfyargs, stdin=bsigdata)
 
         if ecode > 0:
+            if err.find(b'[GNUPG:] NO_PUBKEY '):
+                raise NoKeyError('No matching key found')
             raise ValidationError('Failed to validate PGP signature')
 
         good, valid, trusted, signkey, signtime = DevsigHeader._check_gpg_status(err)
@@ -952,12 +960,14 @@ def validate_message(msgdata: bytes, sources: list, trim_body: bool = False) ->
             attestations.append((RES_VALID, i, signtime, keysrc, algo, errors))
         except ValidationError:
             if keysrc is None:
-                # Not in default keyring
-                errors.append('%s/%s no matching openpgp key found' % (i, s))
-                attestations.append((RES_NOKEY, i, t, None, algo, errors))
-                continue
-            errors.append('failed to validate using %s' % keysrc)
+                errors.append('failed to validate using default keyring')
+            else:
+                errors.append('failed to validate using %s' % keysrc)
             attestations.append((RES_BADSIG, i, t, keysrc, algo, errors))
+        except NoKeyError:
+            # Not in default keyring
+            errors.append('%s/%s no matching openpgp key found' % (i, s))
+            attestations.append((RES_NOKEY, i, t, None, algo, errors))
 
     return attestations
 
-- 
2.31.1