diff libervia/backend/plugins/plugin_xep_0373.py @ 4332:71c939e34ca6

XEP-0373 (OX): Adjust to gpgme updates: generate with explicit algorithm and subkeys
author Syndace <me@syndace.dev>
date Sat, 13 Jul 2024 18:28:28 +0200
parents 0d7bb4df2343
children 111dce64dcb5
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_xep_0373.py	Wed Nov 20 15:29:47 2024 +0100
+++ b/libervia/backend/plugins/plugin_xep_0373.py	Sat Jul 13 18:28:28 2024 +0200
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 # Libervia plugin for OpenPGP for XMPP
-# Copyright (C) 2022-2022 Tim Henkes (me@syndace.dev)
+# Copyright (C) 2022-2024 Tim Henkes (me@syndace.dev)
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -444,6 +444,8 @@
     GPG provider implementation based on GnuPG Made Easy (GPGME).
     """
 
+    ALGORITHM = "ed25519/cert,sign+cv25519/encr"
+
     def __init__(self, home_dir: Optional[str] = None) -> None:
         """
         @param home_dir: Optional GPG home directory path to use for all operations.
@@ -777,23 +779,38 @@
     def create_key(self, user_id: str) -> GPGSecretKey:
         with gpg.Context(home_dir=self.__home_dir) as c:
             try:
-                result = c.create_key(
+                # A single ECC (primary) key with signing and encryption capabilities is not supported, a
+                # subkey is required for encryption.
+                # Create a primary key only capable of certifying subkeys
+                primary_create_result = c.create_key(
                     user_id,
+                    algorithm=self.ALGORITHM,
                     expires=False,
-                    sign=True,
-                    encrypt=True,
-                    certify=False,
-                    authenticate=False,
-                    force=True,
+                    certify=True,
+                    force=True
                 )
 
-                key_obj = c.get_key(result.fpr, secret=True)
+                primary_key_obj = c.get_key(primary_create_result.fpr, secret=True)
+
+                c.create_subkey(
+                    primary_key_obj,
+                    algorithm=self.ALGORITHM,
+                    expires=False,
+                    sign=True
+                )
+
+                c.create_subkey(
+                    primary_key_obj,
+                    algorithm=self.ALGORITHM,
+                    expires=False,
+                    encrypt=True
+                )
             except gpg.errors.GPGMEError as e:
                 raise GPGProviderError("Internal GPGME error") from e
-            except gpg.errors.KeyError as e:
+            except gpg.errors.KeyNotFound as e:
                 raise GPGProviderError("Newly created key not found") from e
 
-            return GPGME_GPGSecretKey(GPGME_GPGPublicKey(key_obj))
+            return GPGME_GPGSecretKey(GPGME_GPGPublicKey(primary_key_obj))
 
 
 class PublicKeyMetadata(NamedTuple):