-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpkg.py
executable file
·131 lines (108 loc) · 4.24 KB
/
pkg.py
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/python3.6
"""Usage:
`python pkg.py register <name> <email>` - register client
`python pkg.py get_pubkey <name> <email>` - get public key assigned to client
`python pkg.py get_privkey <name> <email>` - get private key assigned to client (should be made by owner!)
`python pkg.py clean clients content` - clean the whole content related with clients
E.g. `python register Bob [email protected]`"""
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA3_256
import os
import re
import sys
import database
import config
import identity
import json
class PrivateKeyGenerator:
def __init__(self, db, k_folder, key_len):
self._db = db
self._key_folder = k_folder
self._key_len = key_len
def register(self, identifier):
identifier_hash = self._hash(str(identifier))
private_key_file = '{}/.{}'.format(self._key_folder, identifier_hash)
public_key_file = '{}/{}.pub'.format(self._key_folder, identifier_hash)
if os.path.exists(private_key_file) or os.path.exists(public_key_file):
return
print('Registering {}'.format(identifier))
key = RSA.generate(self._key_len)
private_key = key.export_key()
with open(private_key_file, 'wb') as f:
f.write(private_key)
public_key = key.publickey().export_key()
with open(public_key_file, 'wb') as f:
f.write(public_key)
self._db.insert_client(identifier, identifier_hash)
def get_public_key(self, identifier):
if identifier is None:
raise ValueError
self.register(identifier)
pubkey_file = self._get_public_key_file(identifier)
with open('{}/{}'.format(self._key_folder, pubkey_file)) as f:
return f.read()
"""Caution: It should be implemented in other (local) way to provide secure operations.
Right now get_private_key reveals the whole secret of user without authenticating
(but it's not a part of IBE)!"""
def _get_private_key(self, identifier):
if identifier is None:
raise ValueError
self.register(identifier)
privkey_file = self._get_private_key_file(identifier)
with open('{}/{}'.format(self._key_folder, privkey_file)) as f:
return f.read()
def clean_keys(self):
for f in os.listdir(self._key_folder):
# private keys
if re.search('^.[0-9a-fA-F]{64}$', f):
os.remove(os.path.join(self._key_folder, f))
# public keys
if re.search('^[0-9a-fA-F]{64}.pub$', f):
os.remove(os.path.join(self._key_folder, f))
def _get_public_key_file(self, identifier):
client_content = self._db.select_client(str(identifier))[0]
return json.loads(client_content)['pubkey_file']
def _get_private_key_file(self, identifier):
client_content = self._db.select_client(str(identifier))[0]
return json.loads(client_content)['privkey_file']
@staticmethod
def _hash(text):
h = SHA3_256.new()
h.update(text.encode())
return h.hexdigest()
@staticmethod
def create():
conf = config.load()
folder = conf['database']['folder']
key_len = conf['client']['key_len']
ndb = database.Database.create()
return PrivateKeyGenerator(ndb, folder, key_len)
if __name__ == "__main__":
if len(sys.argv) is not 4:
print(__doc__)
sys.exit(1)
def register_client(pkg, i):
pkg.register(i)
def get_public_key_user(pkg, i):
print(pkg.get_public_key(i))
def get_private_key_user(pkg, i):
print(pkg._get_private_key(i))
def clean_clients_content(pkg, _):
pkg.clean_keys()
pkg._db.clean_clients()
commands = {
'register': register_client,
'get_pubkey': get_public_key_user,
'get_privkey': get_private_key_user,
'clean': clean_clients_content
}
command = sys.argv[1]
if command not in commands:
print(__doc__)
sys.exit(1)
if command == 'clean' and (sys.argv[2] != 'clients' or sys.argv[3] != 'content'):
print(__doc__)
sys.exit(1)
identity = identity.Identity(sys.argv[2], sys.argv[3])
keygen = PrivateKeyGenerator.create()
commands[command](keygen, identity)