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
2020-09-04 15:37:12 +00:00
class Keymaker ( Logger ) :
2020-09-06 22:40:53 +00:00
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
2020-09-06 22:16:33 +00:00
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
2020-09-06 22:40:53 +00:00
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 ) :
2020-09-07 06:13:05 +00:00
# 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 :
2020-09-07 06:13:05 +00:00
# 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 :
2020-09-07 06:13:05 +00:00
# self.log(f'{keyname} found in crypt: {given_key}')
2020-09-05 14:09:31 +00:00
return found_key
2020-09-07 06:13:05 +00:00
# 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 ) :
2020-09-07 06:13:05 +00:00
# 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 :
2020-09-07 06:13:05 +00:00
# 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
2020-09-07 06:13:05 +00:00
# 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 )
2020-09-04 15:37:12 +00:00
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
2020-09-04 15:37:12 +00:00
def get_cell ( self , str_or_key_or_cell ) :
2020-09-07 06:13:05 +00:00
# self.log('getting decr cell for',str_or_key_or_cell)
2020-09-05 14:09:31 +00:00
2020-09-04 15:37:12 +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 )
2020-09-04 15:37:12 +00:00
def assemble_key ( self , key_encr , key_decr ) :
2020-09-07 06:13:05 +00:00
# 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 :
2020-09-07 06:13:05 +00:00
# self.log('!! encrypted half not given')
2020-09-04 14:07:17 +00:00
return
2020-09-04 15:37:12 +00:00
if not key_decr :
2020-09-05 14:09:31 +00:00
if self . passphrase :
key_decr = self . passphrase
else :
2020-09-07 06:13:05 +00:00
# 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
2020-09-04 15:37:12 +00:00
decr_cell = self . get_cell ( key_decr )
2020-09-04 14:07:17 +00:00
# need the decryptor half
2020-09-04 15:37:12 +00:00
if not decr_cell :
2020-09-07 06:13:05 +00:00
# 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 } ' )
2020-09-04 15:37:12 +00:00
key = decr_cell . decrypt ( key_encr )
2020-09-07 06:13:05 +00:00
# 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 )
2020-09-07 06:13:05 +00:00
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)
2020-09-06 22:16:33 +00:00
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
2020-09-06 22:16:33 +00:00
self . _keychain = _keychain = { * * extra_keys }
2020-09-07 06:13:05 +00:00
# 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
2020-09-07 06:13:05 +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 :
2020-09-07 06:13:05 +00:00
# self.log('??',keyname,'...')
2020-09-05 14:09:31 +00:00
if hasattr ( self , keyname ) :
method = getattr ( self , keyname )
res = method ( keychain = _keychain , * * kwargs )
2020-09-07 06:13:05 +00:00
# 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 )