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'],