1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
"""List key generator runs in a separate process to not block for the
potentially long key generation operation."""
import multiprocessing as mp
from os.path import exists, isfile
from flufl.lock import Lock
from pgpy import PGPKey, PGPUID
from pgpy.constants import (
CompressionAlgorithm, HashAlgorithm, KeyFlags, SymmetricKeyAlgorithm)
class ListKeyGenerator(mp.Process):
""""""
def __init__(self, keypair_config, display_name, posting_address,
request_address, key_path):
super().__init__(
target=self.generate,
args=(
keypair_config, display_name, posting_address, request_address,
key_path),
daemon=True)
def generate(self, keypair_config, display_name, posting_address,
request_address, key_path):
"""
Generates the list keypair and saves it to key_path, if it does not
exist.
:param keypair_config:
:param display_name:
:param posting_address:
:param request_address:
:param key_path:
"""
with Lock(key_path + '.lock'):
if exists(key_path) and isfile(key_path):
return
key = self._create(keypair_config, display_name, posting_address,
request_address)
self._save(key, key_path)
def _create(self, config, display_name, posting_address, request_address):
"""
Generates the list `PGPKey` keypair, with posting and request UIDs.
Uses a Sign+Certify main key and Encrypt subkey.
:param config:
:param display_name:
:param posting_address:
:param request_address:
:return: `PGPKey`
"""
# Generate the Sign + Certify primary key.
key_type = config['key_type']
key_length = config['key_length']
key = PGPKey.new(key_type, key_length)
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)
# Generate the posting + request uids.
main_uid = PGPUID.new(display_name, email=posting_address)
request_uid = PGPUID.new(display_name,
email=request_address)
# Generate the Encrypt subkey.
subkey_type = config['subkey_type']
subkey_length = config['subkey_length']
subkey = PGPKey.new(subkey_type, subkey_length)
subkey_params = dict(
usage={KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage},
primary=False
)
# Put it all together.
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, key_path):
"""
Save the generated key.
:param key:
:param key_path:
"""
with open(key_path, 'w') as key_file:
key_file.write(str(key))
|