aboutsummaryrefslogtreecommitdiff
path: root/src/mailman_pgp/pgp/keygen.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman_pgp/pgp/keygen.py')
-rw-r--r--src/mailman_pgp/pgp/keygen.py119
1 files changed, 96 insertions, 23 deletions
diff --git a/src/mailman_pgp/pgp/keygen.py b/src/mailman_pgp/pgp/keygen.py
index b15dbf6..e1fa6b0 100644
--- a/src/mailman_pgp/pgp/keygen.py
+++ b/src/mailman_pgp/pgp/keygen.py
@@ -1,29 +1,102 @@
-""""""
+"""List key generator runs in a separate process to not block for the
+potentially long key generation operation."""
-import threading
+import multiprocessing as mp
+from os.path import exists, isfile
-from mailman_pgp.config import config
+from flufl.lock import Lock
+from pgpy import PGPKey, PGPUID
+from pgpy.constants import (
+ CompressionAlgorithm, HashAlgorithm, KeyFlags, SymmetricKeyAlgorithm)
-class KeyGenerator(threading.Thread):
- def __init__(self, name, email, comment=None):
- super().__init__(daemon=True)
- self._name = name
- self._comment = comment
- self._email = email
- self.key_fingerprint = None
+class ListKeyGenerator(mp.Process):
+ """"""
- def run(self):
- default_config = config.gpg.keypair_config
- key_config = dict(default_config)
- key_config.update(dict(name_real=self._name,
- name_email=self._email))
- if self._comment is not None:
- key_config['name_comment'] = self._comment
- key_input = config.gpg.gen_key_input(**key_config)
- key = config.gpg.gen_key(key_input)
- self.key_fingerprint = key.fingerprint
+ def __init__(self, keypair_config, display_name, posting_address,
+ request_address, queue, key_path):
+ super().__init__(
+ target=self.generate,
+ args=(
+ keypair_config, display_name, posting_address, request_address,
+ queue, key_path),
+ daemon=True)
- @property
- def has_key(self):
- return self.key_fingerprint is not None
+ def generate(self, keypair_config, display_name, posting_address,
+ request_address, queue, key_path):
+ """
+
+ :param keypair_config:
+ :param display_name:
+ :param posting_address:
+ :param request_address:
+ :param queue:
+ :param key_path:
+ :return:
+ """
+ if exists(key_path) and isfile(key_path):
+ queue.put(PGPKey.from_file(key_path))
+ return
+ key = self._create(keypair_config, display_name, posting_address,
+ request_address)
+ self._save(key, queue, key_path)
+
+ def _create(self, config, display_name, posting_address, request_address):
+ """
+
+ :param config:
+ :param display_name:
+ :param posting_address:
+ :param request_address:
+ :return:
+ """
+ # Generate the Sign + Certify primary key.
+ key_type = config['key_type']
+ key_size = config['key_size']
+ key = PGPKey.new(key_type, key_size)
+ key_params = dict(usage={KeyFlags.Sign, KeyFlags.Certify},
+ hashes=[HashAlgorithm.SHA256,
+ HashAlgorithm.SHA384,
+ HashAlgorithm.SHA512,
+ HashAlgorithm.SHA224],
+ ciphers=[SymmetricKeyAlgorithm.AES256,
+ SymmetricKeyAlgorithm.AES192,
+ SymmetricKeyAlgorithm.AES128],
+ compression=[CompressionAlgorithm.ZLIB,
+ CompressionAlgorithm.BZ2,
+ CompressionAlgorithm.ZIP,
+ CompressionAlgorithm.Uncompressed],
+ primary=True)
+
+ main_uid = PGPUID.new(display_name, email=posting_address)
+ request_uid = PGPUID.new(display_name,
+ email=request_address)
+
+ subkey_type = config['subkey_type']
+ subkey_size = config['subkey_size']
+ subkey = PGPKey.new(subkey_type, subkey_size)
+
+ subkey_params = dict(
+ usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage},
+ primary=False
+ )
+
+ key.add_uid(main_uid, **key_params)
+ key.add_uid(request_uid, **key_params)
+ key.add_subkey(subkey, **subkey_params)
+ return key
+
+ def _save(self, key, queue, key_path):
+ """
+
+ :param key:
+ :param queue:
+ :param key_path:
+ :return:
+ """
+ queue.put(key)
+
+ lock = Lock(key_path)
+ with lock:
+ with open(key_path, 'w') as key_file:
+ key_file.write(str(key))