commit:     17c9c9c8b96f60115d1ad12232ac89f80b2e38b3
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 21 11:59:31 2025 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Tue Oct 21 11:59:31 2025 +0000
URL:        https://gitweb.gentoo.org/proj/gemato.git/commit/?id=17c9c9c8

openpgp: Explicitly reject keys with no valid self-sigs

Explicitly detect keys that have no self-signatures (via missing UID
creation date) and reject them while importing.  This is necessary
to match GnuPG behavior in FreePG, where importing keys without (valid)
self-signatures is acceptable.

Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 gemato/openpgp.py | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/gemato/openpgp.py b/gemato/openpgp.py
index f148765..cb42a83 100644
--- a/gemato/openpgp.py
+++ b/gemato/openpgp.py
@@ -155,6 +155,7 @@ class SystemGPGEnvironment:
         prev_pub = None
         fpr = None
         ret = {}
+        invalid = set()
 
         for line in out.splitlines():
             # were we expecting a fingerprint?
@@ -181,7 +182,15 @@ class SystemGPGEnvironment:
                 if fpr is None:
                     raise OpenPGPKeyListingError(
                         f'UID without key in GPG output: {line}')
-                uid = line.split(b':')[9]
+                uid_split = line.split(b":", 10)
+                uid = uid_split[9]
+                # no creation date means missing/broken self-sig
+                if not uid_split[5]:
+                    LOGGER.debug(
+                        f"list_keys(): rejecting key with missing self-sig: "
+                        f"{fpr=}, {uid=!r}")
+                    invalid.add(fpr)
+                    continue
                 _, addr = email.utils.parseaddr(
                     uid.decode('utf8', errors='replace'))
                 if '@' in addr:
@@ -192,6 +201,11 @@ class SystemGPGEnvironment:
                         f'list_keys(): ignoring UID without mail: '
                         f'{uid!r}')
 
+        # reject keys that have invalid/missing self-sigs
+        # to make FreePG match GnuPG behavior
+        for fpr in invalid:
+            del ret[fpr]
+
         return ret
 
     def refresh_keys(self, allow_wkd=True, keyserver=None):
@@ -545,13 +559,21 @@ debug-level guru
             keyfile.read(),
             raise_on_error=OpenPGPKeyImportError)
 
+        fprs = set()
+        for line in out.splitlines():
+            if line.startswith(b"[GNUPG:] IMPORT_OK"):
+                fprs.add(line.split(b" ")[3].decode("ASCII"))
+
+        imported = self.list_keys(list(fprs))
+        missing = fprs - set(imported)
+        if missing:
+            raise OpenPGPKeyImportError(
+                "Import succeeded but no valid key for fingerprints: "
+                f"{missing}"
+            )
+
         if trust:
-            fprs = set()
-            for line in out.splitlines():
-                if line.startswith(b'[GNUPG:] IMPORT_OK'):
-                    fprs.add(line.split(b' ')[3].decode('ASCII'))
             self._trusted_keys.update(fprs)
-
             ownertrust = ''.join(f'{fpr}:6:\n' for fpr in fprs).encode('utf8')
             exitst, out, err = self._spawn_gpg(
                 [GNUPG, '--batch', '--import-ownertrust'],

Reply via email to