diff options
Diffstat (limited to 'src/mailman_pgp/pgp/keygen.py')
| -rw-r--r-- | src/mailman_pgp/pgp/keygen.py | 119 |
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)) |
