2
0
mirror of https://github.com/ComradCollective/Comrad synced 2024-11-19 15:25:34 +00:00
Comrad/komrade/backend/keymaker.py

628 lines
26 KiB
Python
Raw Normal View History

2020-09-05 16:26:37 +00:00
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from komrade import *
2020-09-05 21:11:42 +00:00
from komrade.backend.crypt import *
2020-09-06 14:45:40 +00:00
from abc import ABC, abstractmethod
class KomradeKey(ABC):
@abstractmethod
def encrypt(self,msg,**kwargs): pass
@abstractmethod
def decrypt(self,msg,**kwargs): pass
2020-09-04 12:46:22 +00:00
2020-09-06 14:45:40 +00:00
@abstractmethod
def data(self): pass
2020-09-06 13:07:27 +00:00
2020-09-06 14:45:40 +00:00
class KomradeSymmetricKey(KomradeKey):
2020-09-06 13:07:27 +00:00
@property
def cell(self):
if not hasattr(self,'_cell'):
if hasattr(self,'passphrase') and self.passphrase:
2020-09-06 14:45:40 +00:00
self._cell = SCellSeal(passphrase=self.passphrase)
2020-09-06 13:07:27 +00:00
elif hasattr(self,'key') and self.key:
2020-09-06 14:45:40 +00:00
self._cell = SCellSeal(key=self.key)
return self._cell
def encrypt(self,msg,**kwargs):
if issubclass(type(msg), KomradeKey): msg=msg.data
return self.cell.encrypt(msg,**kwargs)
def decrypt(self,msg,**kwargs):
return self.cell.decrypt(msg,**kwargs)
2020-09-06 13:07:27 +00:00
2020-09-06 14:45:40 +00:00
class KomradeSymmetricKeyWithPassphrase(KomradeSymmetricKey):
2020-09-06 13:07:27 +00:00
def __init__(self,passphrase=None, why=WHY_MSG):
self.passphrase=passphrase
if not self.passphrase:
self.passphrase=getpass.getpass(why)
2020-09-06 14:45:40 +00:00
#return self.passphrase
@property
def data(self): return KEY_TYPE_SYMMETRIC_WITH_PASSPHRASE.encode('utf-8')
2020-09-06 13:07:27 +00:00
2020-09-06 14:45:40 +00:00
class KomradeSymmetricKeyWithoutPassphrase(KomradeSymmetricKey):
2020-09-06 13:07:27 +00:00
def __init__(self):
self.key = GenerateSymmetricKey()
2020-09-06 14:45:40 +00:00
@property
def data(self): return self.key
class KomradeAsymmetricKey(KomradeKey):
def __init__(self,pubkey,privkey):
self.pubkey=pubkey
self.privkey=privkey
def encrypt(self,msg,pubkey=None,privkey=None):
if issubclass(type(msg), KomradeKey): msg=msg.data
pubkey=pubkey if pubkey else self.pubkey
privkey=privkey if privkey else self.privkey
return SMessage(privkey,pubkey).wrap(msg)
def decrypt(self,msg,pubkey=None,privkey=None):
pubkey=pubkey if pubkey else self.pubkey
privkey=privkey if privkey else self.privkey
return SMessage(privkey,pubkey).unwrap(msg)
@property
def data(self): return self.key
class KomradeAsymmetricPublicKey(KomradeAsymmetricKey):
@property
def key(self): return self.pubkey
class KomradeAsymmetricPrivateKey(KomradeAsymmetricKey):
@property
def key(self): return self.privkey
2020-09-06 13:07:27 +00:00
class Keymaker(Logger):
def __init__(self,name=None,passphrase=None, path_crypt_keys=None, path_crypt_data=None, allow_builtin=True):
2020-09-05 14:09:31 +00:00
self.name=name
self._keychain={}
2020-09-05 14:09:31 +00:00
self.passphrase=passphrase
2020-09-06 09:48:01 +00:00
self.path_crypt_keys=path_crypt_keys
self.path_crypt_data=path_crypt_data
self.allow_builtin=allow_builtin
2020-09-05 14:09:31 +00:00
2020-09-04 12:46:22 +00:00
### BASE STORAGE
@property
def crypt_keys(self):
if not hasattr(self,'_crypt_keys'):
2020-09-06 09:48:01 +00:00
self._crypt_keys = Crypt(fn=self.path_crypt_keys)
2020-09-04 12:46:22 +00:00
return self._crypt_keys
2020-09-06 16:29:27 +00:00
@property
def crypt_keys_mem(self):
if not hasattr(self,'_crypt_keys_mem'):
self._crypt_keys_mem = CryptMemory()
return self._crypt_keys_mem
2020-09-04 12:46:22 +00:00
@property
def crypt_data(self):
if not hasattr(self,'_crypt_data'):
2020-09-06 09:48:01 +00:00
self._crypt_data = Crypt(fn=self.path_crypt_data)
2020-09-04 12:46:22 +00:00
return self._crypt_data
### STARTING WITH MOST ABSTRACT
2020-09-06 17:25:03 +00:00
def findkey(self, keyname, keychain={}, uri=None):
# self.log(f'looking for key {keyname}, in keychain {keychain.keys()} or under crypt uri {uri}')
2020-09-04 14:07:17 +00:00
# look in keychain, then in crypt, for this key
given_key = keychain.get(keyname)
2020-09-05 14:09:31 +00:00
if given_key:
# self.log(f'{keyname} found in keychain: {given_key}')
2020-09-05 14:09:31 +00:00
return given_key
2020-09-04 14:07:17 +00:00
found_key = self.crypt_keys.get(uri,prefix=f'/{keyname}/')
2020-09-05 14:09:31 +00:00
if found_key:
# self.log(f'{keyname} found in crypt: {given_key}')
2020-09-05 14:09:31 +00:00
return found_key
# self.log(f'{keyname} not found!!')
2020-09-05 14:09:31 +00:00
2020-09-04 14:07:17 +00:00
2020-09-06 17:25:03 +00:00
def getkey(self, keyname, keychain={}, uri=None):
# self.log(f'keyname={keyname}, keychain={keychain.keys()}, uri={uri}')
2020-09-05 14:09:31 +00:00
2020-09-04 14:07:17 +00:00
# 1) I already have this key stored in either the keychain or the crypt; return straight away
key = self.findkey(keyname, keychain, uri)
2020-09-05 14:09:31 +00:00
if key:
# self.log(f'>> I have {key} already, returning')
2020-09-05 14:09:31 +00:00
return key
2020-09-04 14:07:17 +00:00
## 2) I can assemble the key
# self.log(f'assembling key: {keyname}_encr + {keyname}_decr')
2020-09-04 14:07:17 +00:00
key_encr = self.findkey(keyname+'_encr', keychain,uri)
key_decr = self.findkey(keyname+'_decr', keychain, uri)
key = self.assemble_key(key_encr, key_decr)
2020-09-04 14:07:17 +00:00
return key
def get_cell(self, str_or_key_or_cell):
# self.log('getting decr cell for',str_or_key_or_cell)
2020-09-05 14:09:31 +00:00
if type(str_or_key_or_cell)==SCellSeal:
return str_or_key_or_cell
elif type(str_or_key_or_cell)==str:
return SCellSeal(passphrase=str_or_key_or_cell)
elif type(str_or_key_or_cell)==bytes:
2020-09-05 14:09:31 +00:00
return SCellSeal(key=str_or_key_or_cell)
def assemble_key(self, key_encr, key_decr):
# self.log(f'assembling key: {key_decr} decrypting {key_encr}')
2020-09-05 14:09:31 +00:00
2020-09-04 14:07:17 +00:00
# need the encrypted half
if not key_encr:
# self.log('!! encrypted half not given')
2020-09-04 14:07:17 +00:00
return
if not key_decr:
2020-09-05 14:09:31 +00:00
if self.passphrase:
key_decr = self.passphrase
else:
# self.log('!! decryptor half not given')
2020-09-05 14:09:31 +00:00
return
2020-09-04 14:07:17 +00:00
# need some way to regenerate the decryptor
decr_cell = self.get_cell(key_decr)
2020-09-04 14:07:17 +00:00
# need the decryptor half
if not decr_cell:
# self.log('!! decryptor cell not regenerable')
2020-09-04 14:07:17 +00:00
return
2020-09-04 12:46:22 +00:00
2020-09-04 14:07:17 +00:00
# decrypt!
try:
2020-09-05 14:09:31 +00:00
self.log(f'>> decrypting {key_encr} with cell {decr_cell}')
key = decr_cell.decrypt(key_encr)
# self.log('assembled_key built:',key)
2020-09-04 14:07:17 +00:00
return key
except ThemisError as e:
self.log('!! decryption failed:',e)
return
2020-09-04 14:07:17 +00:00
2020-09-04 14:22:16 +00:00
# Concrete keys
## (1) Final keys
2020-09-06 21:35:21 +00:00
def pubkey(self, force=False, **kwargs):
if force or not hasattr(self,'_pubkey') or not self._pubkey:
2020-09-06 20:23:58 +00:00
self._pubkey = self.getkey(keyname='pubkey',uri=self.name,**kwargs)
return self._pubkey
2020-09-06 21:35:21 +00:00
def privkey(self, force=False, **kwargs):
if force or not hasattr(self,'_privkey') or not self._privkey:
2020-09-06 20:23:58 +00:00
self._privkey=self.getkey(keyname='privkey',uri=self.pubkey(**kwargs),**kwargs)
return self._privkey
2020-09-06 21:35:21 +00:00
def adminkey(self, force=False, **kwargs):
if force or not hasattr(self,'_adminkey') or not self._adminkey:
2020-09-06 20:23:58 +00:00
self._adminkey=self.getkey(keyname='adminkey',uri=self.privkey(**kwargs),**kwargs)
return self._adminkey
2020-09-04 14:22:16 +00:00
## (1-X) Encrypted halves
2020-09-04 12:46:22 +00:00
def pubkey_encr(self, **kwargs):
2020-09-04 14:22:16 +00:00
return self.getkey(uri=self.name,keyname='pubkey_encr',**kwargs)
2020-09-04 12:46:22 +00:00
def privkey_encr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.pubkey(**kwargs),keyname='privkey_encr',**kwargs)
2020-09-04 12:46:22 +00:00
def adminkey_encr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.privkey(**kwargs),keyname='adminkey_encr',**kwargs)
2020-09-04 12:46:22 +00:00
2020-09-04 14:22:16 +00:00
## (1-Y) Decrpytor halves
2020-09-04 12:46:22 +00:00
def pubkey_decr(self, **kwargs):
2020-09-04 14:22:16 +00:00
return self.getkey(uri=self.name,keyname='pubkey_decr',**kwargs)
2020-09-04 12:46:22 +00:00
def privkey_decr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.pubkey(**kwargs),keyname='privkey_decr',**kwargs)
2020-09-04 12:46:22 +00:00
def adminkey_decr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.privkey(**kwargs),keyname='adminkey_decr',**kwargs)
2020-09-04 14:22:16 +00:00
## Second halving!
## (1-X-X)
def pubkey_encr_encr(self, **kwargs):
return self.getkey(uri=self.name,keyname='pubkey_encr_encr',**kwargs)
def privkey_encr_encr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.pubkey_encr(**kwargs),keyname='privkey_encr_encr',**kwargs)
2020-09-04 14:22:16 +00:00
def adminkey_encr_encr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.privkey_encr(**kwargs),keyname='adminkey_encr_encr',**kwargs)
2020-09-04 14:22:16 +00:00
## (1-X-Y)
def pubkey_encr_decr(self, **kwargs):
return self.getkey(uri=self.name,keyname='pubkey_encr_decr',**kwargs)
def privkey_encr_decr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.pubkey_encr(**kwargs),keyname='privkey_encr_decr',**kwargs)
2020-09-04 14:22:16 +00:00
def adminkey_encr_decr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.privkey_encr(**kwargs),keyname='adminkey_encr_decr',**kwargs)
2020-09-04 14:22:16 +00:00
## (1-Y-X)
def pubkey_decr_encr(self, **kwargs):
return self.getkey(uri=self.name,keyname='pubkey_decr_encr',**kwargs)
def privkey_decr_encr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.pubkey_decr(**kwargs),keyname='privkey_decr_encr',**kwargs)
2020-09-04 14:22:16 +00:00
def adminkey_decr_encr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.privkey_decr(**kwargs),keyname='adminkey_decr_encr',**kwargs)
2020-09-04 14:22:16 +00:00
## (1-Y-Y)
def pubkey_decr_decr(self, **kwargs):
return self.getkey(uri=self.name,keyname='pubkey_decr_decr',**kwargs)
def privkey_decr_decr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.pubkey_decr(**kwargs),keyname='privkey_decr_decr',**kwargs)
2020-09-04 14:22:16 +00:00
def adminkey_decr_decr(self, **kwargs):
2020-09-05 14:09:31 +00:00
return self.getkey(uri=self.privkey_decr(**kwargs),keyname='adminkey_decr_decr',**kwargs)
2020-09-04 14:07:17 +00:00
2020-09-05 16:26:37 +00:00
# convenience functions
# Concrete keys
@property
2020-09-06 09:40:10 +00:00
def pubkey_(self): return self.keychain().get('pubkey')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_(self, **kwargs): return self.keychain().get('privkey')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_(self, **kwargs): return self.keychain().get('adminkey')
2020-09-04 14:07:17 +00:00
2020-09-05 16:26:37 +00:00
## (1-X) Encrypted halves
@property
2020-09-06 09:40:10 +00:00
def pubkey_encr_(self, **kwargs):return self.keychain().get('pubkey_encr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_encr_(self, **kwargs): return self.keychain().get('privkey_encr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_encr_(self, **kwargs): return self.keychain().get('adminkey_encr')
2020-09-05 16:26:37 +00:00
## (1-Y) Decrpytor halves
@property
2020-09-06 09:40:10 +00:00
def pubkey_decr_(self, **kwargs): return self.keychain().get('pubkey_decr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_decr_(self, **kwargs): return self.keychain().get('privkey_decr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_decr_(self, **kwargs): return self.keychain().get('adminkey_decr')
2020-09-05 16:26:37 +00:00
## Second halving!
## (1-X-X)
@property
2020-09-06 09:40:10 +00:00
def pubkey_encr_encr_(self, **kwargs): return self.keychain().get('pubkey_encr_encr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_encr_encr_(self, **kwargs): return self.keychain().get('privkey_encr_encr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_encr_encr_(self, **kwargs): return self.keychain().get('adminkey_encr_encr')
2020-09-05 16:26:37 +00:00
## (1-X-Y)
@property
2020-09-06 09:40:10 +00:00
def pubkey_encr_decr_(self, **kwargs): return self.keychain().get('pubkey_encr_decr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_encr_decr_(self, **kwargs): return self.keychain().get('privkey_encr_decr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_encr_decr_(self, **kwargs): return self.keychain().get('adminkey_encr_decr')
2020-09-05 16:26:37 +00:00
## (1-Y-X)
@property
2020-09-06 09:40:10 +00:00
def pubkey_decr_encr_(self, **kwargs): return self.keychain().get('pubkey_decr_encr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_decr_encr_(self, **kwargs): return self.keychain().get('privkey_decr_encr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_decr_encr_(self, **kwargs): return self.keychain().get('adminkey_decr_encr')
2020-09-05 16:26:37 +00:00
## (1-Y-Y)
@property
2020-09-06 09:40:10 +00:00
def pubkey_decr_decr_(self, **kwargs): return self.keychain().get('pubkey_decr_decr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def privkey_decr_decr_(self, **kwargs): return self.keychain().get('privkey_decr_decr')
2020-09-05 16:26:37 +00:00
@property
2020-09-06 09:40:10 +00:00
def adminkey_decr_decr_(self, **kwargs): return self.keychain().get('adminkey_decr_decr')
2020-09-05 16:26:37 +00:00
2020-09-04 14:07:17 +00:00
2020-09-04 12:46:22 +00:00
# Get key de-cryptors
def genkey_pass_keycell(self,pass_phrase,q_name='Read permissions?'):
if pass_phrase is None:
pass_key = GenerateSymmetricKey()
pass_cell = SCellSeal(key=pass_key)
else:
if pass_phrase is True: pass_phrase=getpass.getpass(f'Enter pass phrase [{q_name}]: ')
pass_key = None
pass_cell = SCellSeal(passphrase=pass_phrase)
self.log(f'pass_key [{q_name}] <--',pass_key)
self.log(f'pass_cell [{q_name}] <--',pass_cell)
return (pass_key, pass_cell)
2020-09-04 15:50:08 +00:00
def exists(self):
return self.crypt_keys.exists(self.name,prefix='/pubkey_encr/') or self.crypt_keys.exists(self.name,prefix='/pubkey_decr/') or self.crypt_keys.exists(self.name,prefix='/pubkey/')
### CREATING KEYS
2020-09-06 13:07:27 +00:00
def get_new_keys(self):
raise KomradeException('Every keymaker must make their own get_new_keys() !')
def gen_keys_from_types(self,key_types,passphrase=None):
asymmetric_pubkey=None
asymmetric_privkey=None
2020-09-06 17:25:03 +00:00
keychain = {}
2020-09-06 14:45:40 +00:00
for key_name,key_type_desc in key_types.items():
if key_type_desc in {KEY_TYPE_ASYMMETRIC_PUBKEY,KEY_TYPE_ASYMMETRIC_PRIVKEY}:
2020-09-06 13:07:27 +00:00
if not asymmetric_privkey or not asymmetric_pubkey:
keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC)
asymmetric_privkey = keypair.export_private_key()
asymmetric_pubkey = keypair.export_public_key()
2020-09-06 14:45:40 +00:00
if key_type_desc==KEY_TYPE_ASYMMETRIC_PRIVKEY:
keychain[key_name] = KomradeAsymmetricPrivateKey(asymmetric_pubkey,asymmetric_privkey)
elif key_type_desc==KEY_TYPE_ASYMMETRIC_PUBKEY:
keychain[key_name] = KomradeAsymmetricPublicKey(asymmetric_pubkey,asymmetric_privkey)
2020-09-06 13:07:27 +00:00
elif key_type_desc==KEY_TYPE_SYMMETRIC_WITHOUT_PASSPHRASE:
2020-09-06 14:45:40 +00:00
keychain[key_name]=KomradeSymmetricKeyWithoutPassphrase()
2020-09-06 13:07:27 +00:00
elif key_type_desc==KEY_TYPE_SYMMETRIC_WITH_PASSPHRASE:
2020-09-06 14:45:40 +00:00
if not passphrase and not self.passphrase: self.passphrase=getpass.getpass(WHY_MSG)
passphrase=passphrase if passphrase else self.passphrase
keychain[key_name]=KomradeSymmetricKeyWithPassphrase(passphrase=passphrase)
return keychain
2020-09-06 13:07:27 +00:00
def forge_new_keys(self,
2020-09-06 14:45:40 +00:00
name=None,
2020-09-06 13:07:27 +00:00
keys_to_save = KEYMAKER_DEFAULT_KEYS_TO_SAVE,
keys_to_return = KEYMAKER_DEFAULT_KEYS_TO_RETURN,
2020-09-06 14:45:40 +00:00
keys_to_gen = KEYMAKER_DEFAULT_KEYS_TO_GEN,
2020-09-06 13:07:27 +00:00
key_types = KEYMAKER_DEFAULT_KEY_TYPES):
2020-09-06 21:12:49 +00:00
# self.log('forging new keys...',name,self.name)
# self.log('keys_to_save:',keys_to_save)
# self.log('keys_to_return',keys_to_return)
2020-09-06 17:53:51 +00:00
# stop
2020-09-06 17:52:25 +00:00
2020-09-06 14:45:40 +00:00
if not name: name=self.name
keys_to_gen = set(keys_to_gen) | set(keys_to_save) | set(keys_to_return)
keys_to_gen = sorted(list(keys_to_gen),key=lambda x: x.count('_'))
2020-09-06 21:12:49 +00:00
# self.log('keys_to_gen =',keys_to_gen)
2020-09-06 14:45:40 +00:00
key_types = dict([(k,key_types[k]) for k in keys_to_gen])
2020-09-06 21:12:49 +00:00
# self.log('key_types =',key_types)
2020-09-06 14:45:40 +00:00
keychain = self.gen_keys_from_types(key_types)
2020-09-06 21:12:49 +00:00
# self.log('keychain =',keychain)
2020-09-06 14:45:40 +00:00
2020-09-06 21:12:49 +00:00
# self.log('!!!!',keychain)
2020-09-06 14:45:40 +00:00
# stop
2020-09-06 17:25:03 +00:00
#keychain_tosave = {}
#keychain_toreturn = {}
2020-09-06 21:12:49 +00:00
# self.log('keys_to_save =',keys_to_save)
# self.log('keys_to_return =',keys_to_return)
2020-09-06 14:45:40 +00:00
for key_name in keys_to_gen:
if key_name.endswith('_encr') and key_name not in keychain:
# encrypt it with the associated decr
name_of_what_to_encrypt = key_name[:-len('_encr')]
the_key_to_encrypt_it_with = name_of_what_to_encrypt + '_decr'
if the_key_to_encrypt_it_with in keychain and name_of_what_to_encrypt in keychain:
_key_decr = keychain[the_key_to_encrypt_it_with]
_key = keychain[name_of_what_to_encrypt]
self.log(f'about to encrypt key {name_of_what_to_encrypt}, using {the_key_to_encrypt_it_with}, which is a type {key_types[the_key_to_encrypt_it_with]} and has value {keychain[the_key_to_encrypt_it_with]}')
_key_encr = _key_decr.encrypt(_key)
self.log(f'{_key}\n-- encrypting ----->\n{_key_encr}')
keychain[key_name]=_key_encr
2020-09-06 18:08:14 +00:00
2020-09-06 14:45:40 +00:00
# filter for transfer
for k,v in keychain.items():
if issubclass(type(v),KomradeKey):
v=v.data
2020-09-06 18:54:38 +00:00
# v=b64encode(v)
2020-09-06 14:45:40 +00:00
keychain[k]=v
2020-09-06 18:08:14 +00:00
# self.log('-->',v)
2020-09-06 14:45:40 +00:00
# stop
2020-09-06 21:12:49 +00:00
# self.log('once more, with encryption!',keychain)
2020-09-06 18:19:57 +00:00
2020-09-06 14:45:40 +00:00
# keychain_tosave = dict([(k,keychain[k]) for k in keys_to_save if k in keychain])
2020-09-04 15:50:08 +00:00
2020-09-06 14:45:40 +00:00
# for k,v in keychain_tosave.items():
2020-09-06 19:13:16 +00:00
2020-09-06 14:45:40 +00:00
if 'pubkey' in keys_to_save or 'privkey' in keys_to_save or 'adminkey' in keys_to_save:
2020-09-06 19:13:16 +00:00
# unless we're the operator or the telephone
if not self.name in {OPERATOR_NAME,TELEPHONE_NAME}:
raise KomradeException('there is no private property in a socialist network! all keys must be split between komrades')
else:
if 'pubkey' in keys_to_save and 'pubkey' in keychain:
self.crypt_keys.set(name,keychain['pubkey'],prefix='/pubkey/')
if 'privkey' in keys_to_save and 'privkey' in keychain:
self.crypt_keys.set(keychain['pubkey'],keychain['privkey'],prefix='/privkey/')
if 'adminkey' in keys_to_save and 'adminkey' in keychain:
self.crypt_keys.set(keychain['privkey'],keychain['adminkey'],prefix='/adminkey/')
2020-09-06 18:02:18 +00:00
2020-09-06 17:46:09 +00:00
### SAVE ENCRYPTED KEYS?
2020-09-06 18:19:57 +00:00
self.log('KEYCHAIN AS OF NOW:',keychain)
2020-09-06 18:21:10 +00:00
self.log('keys_to_save')
2020-09-06 18:29:49 +00:00
if 'pubkey_encr' in keys_to_save and 'pubkey_encr' in keychain:
2020-09-06 18:24:51 +00:00
self.crypt_keys.set(name,keychain['pubkey_encr'],prefix='/pubkey_encr/')
2020-09-06 18:29:49 +00:00
if 'privkey_encr' in keys_to_save and 'privkey_encr' in keychain:
2020-09-06 18:24:51 +00:00
self.crypt_keys.set(keychain['pubkey'],keychain['privkey_encr'],prefix='/privkey_encr/')
2020-09-06 18:29:49 +00:00
if 'adminkey_encr' in keys_to_save and 'adminkey_encr' in keychain:
2020-09-06 18:24:51 +00:00
self.crypt_keys.set(keychain['privkey'],keychain['adminkey_encr'],prefix='/adminkey_encr/')
2020-09-06 18:29:49 +00:00
# stop
2020-09-06 17:46:09 +00:00
# save decrypted keys?
2020-09-06 18:29:49 +00:00
if 'pubkey_decr' in keys_to_save and 'pubkey_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(name,keychain['pubkey_decr'],prefix='/pubkey_decr/')
2020-09-06 18:29:49 +00:00
if 'privkey_decr' in keys_to_save and 'privkey_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['pubkey'],keychain['privkey_decr'],prefix='/privkey_decr/')
2020-09-06 18:29:49 +00:00
if 'adminkey_decr' in keys_to_save and 'adminkey_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['privkey'],keychain['adminkey_decr'],prefix='/adminkey_decr/')
2020-09-06 18:29:49 +00:00
if 'pubkey_encr_encr' in keys_to_save and 'pubkey_encr_encr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(name,keychain['pubkey_decr_encr'],prefix='/pubkey_decr_encr/')
2020-09-06 18:29:49 +00:00
if 'privkey_encr_encr' in keys_to_save and 'privkey_encr_encr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['pubkey_decr'],keychain['privkey_decr_encr'],prefix='/privkey_decr_encr/')
2020-09-06 18:29:49 +00:00
if 'adminkey_encr_encr' in keys_to_save and 'adminkey_encr_encr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['privkey_decr'],keychain['adminkey_decr_encr'],prefix='/adminkey_decr_encr/')
2020-09-06 18:29:49 +00:00
if 'pubkey_decr_encr' in keys_to_save and 'pubkey_decr_encr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(name,keychain['pubkey_decr_encr'],prefix='/pubkey_decr_encr/')
2020-09-06 18:29:49 +00:00
if 'privkey_decr_encr' in keys_to_save and 'privkey_decr_encr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['pubkey_decr'],keychain['privkey_decr_encr'],prefix='/privkey_decr_encr/')
2020-09-06 18:29:49 +00:00
if 'adminkey_decr_encr' in keys_to_save and 'adminkey_decr_encr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['privkey_decr'],keychain['adminkey_decr_encr'],prefix='/adminkey_decr_encr/')
2020-09-04 15:50:08 +00:00
2020-09-06 18:29:49 +00:00
if 'pubkey_decr_decr' in keys_to_save and 'pubkey_decr_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(name,keychain['pubkey_decr_decr'],prefix='/pubkey_decr_decr/')
2020-09-06 18:29:49 +00:00
if 'privkey_decr_decr' in keys_to_save and 'privkey_decr_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['pubkey_decr'],keychain['privkey_decr_decr'],prefix='/privkey_decr_decr/')
2020-09-06 18:29:49 +00:00
if 'adminkey_decr_decr' in keys_to_save and 'adminkey_decr_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['privkey_decr'],keychain['adminkey_decr_decr'],prefix='/adminkey_decr_decr/')
2020-09-06 18:29:49 +00:00
if 'pubkey_decr_decr' in keys_to_save and 'pubkey_decr_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(name,keychain['pubkey_decr_decr'],prefix='/pubkey_decr_decr/')
2020-09-06 18:29:49 +00:00
if 'privkey_decr_decr' in keys_to_save and 'privkey_decr_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['pubkey_decr'],keychain['privkey_decr_decr'],prefix='/privkey_decr_decr/')
2020-09-06 18:29:49 +00:00
if 'adminkey_decr_decr' in keys_to_save and 'adminkey_decr_decr' in keychain:
2020-09-06 17:46:09 +00:00
self.crypt_keys.set(keychain['privkey_decr'],keychain['adminkey_decr_decr'],prefix='/adminkey_decr_decr/')
2020-09-06 18:02:18 +00:00
keychain_toreturn = {}
for key in keys_to_return:
if key in keychain:
2020-09-06 21:12:49 +00:00
# print('adding',key,'to returned keychain')
2020-09-06 18:02:18 +00:00
keychain_toreturn[key]=keychain[key]
return keychain_toreturn
2020-09-06 17:46:09 +00:00
2020-09-06 21:26:36 +00:00
def valid_keychain(self,keychain_b64_d):
valid_kc = {}
for k,v in keychain_b64_d.items():
self.log('incoming <--',k,v)
if type(v)==bytes:
data = v
elif type(v)==str:
if not isBase64(v):
self.log('not valid input!')
continue
# first try to get from string to bytes
try:
data = v.encode()
2020-09-06 21:28:29 +00:00
self.log('data',data)
2020-09-06 21:26:36 +00:00
except UnicodeEncodeError:
self.log('not valid unicode?')
continue
# then try to get from b64 bytes to raw bytes
2020-09-06 21:28:29 +00:00
if isBase64(data):
valid_kc[k]=b64decode(data)
2020-09-06 21:26:36 +00:00
else:
2020-09-06 21:28:29 +00:00
valid_kc[k]=data
2020-09-06 21:26:36 +00:00
return valid_kc
2020-09-04 15:50:08 +00:00
2020-09-06 13:07:27 +00:00
@property
def cell_dblencr(self):
if not hasattr(self,'_cell_dblencr'):
self._dbl_encr = get_cell_dblencr()
return self._dbl_encr
def get_cell_dblencr(self,passphrase=None):
2020-09-05 14:09:31 +00:00
if not passphrase:
if self.passphrase:
passphrase=self.passphrase
else:
self.passphrase=passphrase=getpass.getpass('Forge the password of memory: ')
2020-09-04 15:50:08 +00:00
cell = SCellSeal(passphrase=passphrase)
2020-09-06 13:07:27 +00:00
return cell
def lock_new_keys(self,
keychain,
passphrase=None,
save_encrypted = True, return_encrypted = False,
save_decrypted = False, return_decrypted = True):
# we're not going to store the decryptor keys directly though
2020-09-05 14:09:31 +00:00
2020-09-04 15:50:08 +00:00
# encrypt the decryptor keys
pubkey_decr_encr = cell.encrypt(keychain['pubkey_decr'])
privkey_decr_encr = cell.encrypt(keychain['privkey_decr'])
adminkey_decr_encr = cell.encrypt(keychain['adminkey_decr'])
2020-09-05 14:09:31 +00:00
# set to crypt and keychain
2020-09-06 13:07:27 +00:00
if save_decrypted:
self.crypt_keys.set(self.name,pubkey_decr_encr,prefix='/pubkey_decr_encr/')
self.crypt_keys.set(keychain['pubkey_decr'],privkey_decr_encr,prefix='/privkey_decr_encr/')
#keychain['privkey_decr_encr']=privkey_decr_encr
2020-09-05 14:09:31 +00:00
2020-09-06 13:07:27 +00:00
self.crypt_keys.set(keychain['privkey_decr'],adminkey_decr_encr,prefix='/adminkey_decr_encr/')
#keychain['adminkey_decr_encr']=adminkey_decr_encr
2020-09-04 15:50:08 +00:00
# store decryption keys if not passworded?
2020-09-05 14:09:31 +00:00
pub_ddk,priv_ddk,admin_ddk=[x+'key_decr_decr_key' for x in ['pub','priv','admin']]
if pub_ddk in keychain:
self.crypt_keys.set(self.name, keychain[pub_ddk], prefix=f'/{pub_ddk}/')
if priv_ddk in keychain:
self.crypt_keys.set(self.name, keychain[priv_ddk], prefix=f'/{priv_ddk}/')
if admin_ddk in keychain:
self.crypt_keys.set(self.name, keychain[admin_ddk], prefix=f'/{admin_ddk}/')
2020-09-04 15:50:08 +00:00
2020-09-05 14:09:31 +00:00
# # return protected keychain
# todel = ['pubkey_decr','privkey_decr','adminkey_decr']
# for x in todel:
# if x in keychain:
# del keychain[x]
# # add encr versions
# keychain
# del keychain['pubkey_decr']
# del keychain['privkey_decr']
# del keychain['adminkey_decr']
# return ()
return passphrase
# def load_concrete_keychain():
# keychain = {}
# for keyname in KEYNAMES:
# keychain=self.findkey(keyname, keychain, uri)
def keychain(self,passphrase=None,force=False,allow_builtin=True,extra_keys={},keys_to_gen=KEYMAKER_DEFAULT_KEYS_TO_GEN,**kwargs):
2020-09-05 14:09:31 +00:00
# assemble as many keys as we can!
if not force and hasattr(self,'_keychain') and self._keychain: return self._keychain
if passphrase: self.passphrase=passphrase
self._keychain = _keychain = {**extra_keys}
# self.log('_keychain at start of keychain() =',_keychain)
2020-09-06 17:34:03 +00:00
2020-09-07 06:03:41 +00:00
# # am I a builtin one?
# # self.log('hello///',self.name,self.name in BUILTIN_KEYCHAIN)
# if hasattr(self,'allow_builtin'):
# allow_builtin = allow_builtin and self.allow_builtin
2020-09-06 22:09:36 +00:00
2020-09-07 06:03:41 +00:00
# if self.name in BUILTIN_KEYCHAIN and allow_builtin:
# self.log('??',_keychain)
2020-09-06 18:47:29 +00:00
2020-09-07 06:03:41 +00:00
# # if self.name!=OPERATOR_NAME:
# for k,v in BUILTIN_KEYCHAIN[self.name].items():
# _keychain[k]=v
# self.log('??',_keychain)
# # stop
2020-09-06 17:34:03 +00:00
# self.log('_keychain',_keychain)
2020-09-06 17:38:10 +00:00
# stop
2020-09-06 17:35:05 +00:00
2020-09-06 22:09:36 +00:00
for keyname in keys_to_gen:
# self.log('??',keyname,'...')
2020-09-05 14:09:31 +00:00
if hasattr(self,keyname):
method=getattr(self,keyname)
res=method(keychain=_keychain, **kwargs)
# self.log('res <--',res)
2020-09-05 14:09:31 +00:00
if res:
_keychain[keyname]=res
return _keychain
2020-09-06 14:45:40 +00:00
if __name__ == '__main__':
keymaker = Keymaker('marx69')
keychain = keymaker.forge_new_keys()
print(keychain)