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 * from komrade.backend.crypt import * from abc import ABC, abstractmethod # common external imports from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair from pythemis.smessage import SMessage, ssign, sverify from pythemis.skeygen import GenerateSymmetricKey from pythemis.scell import SCellSeal from pythemis.exception import ThemisError class KomradeKey(ABC,Logger): @abstractmethod def encrypt(self,msg,**kwargs): pass @abstractmethod def decrypt(self,msg,**kwargs): pass @abstractmethod def data(self): pass @property def data_b64(self):return b64encode(self.data) if type(self.data)==bytes else self.data.data_b64 @property def data_b64_s(self): return self.data_b64.decode() @property def discreet(self): return make_key_discreet(self.data) def __str__(self): return repr(self) class KomradeSymmetricKey(KomradeKey): def encrypt(self,msg,**kwargs): if hasattr(msg,'data'): msg=msg.data # print('??? dec',msg,kwargs) return self.cell.encrypt(msg,**kwargs) def decrypt(self,msg,**kwargs): if hasattr(msg,'data'): msg=msg.data # print('??? dec',msg,kwargs) try: return self.cell.decrypt(msg,**kwargs) except TypeError: return self.cell.decrypt(msg.data,**kwargs) def getpass_status(passphrase=None): while not passphrase: passphrase1 = getpass(f'@Keymaker: What is a *memorable* pass word or phrase? Do not write it down.\n@{name}: ') passphrase2 = getpass(f'@Keymaker: Could you repeat that?') if passphrase1!=passphrase2: self.status('@Keymaker: Those passwords didn\'t match. Please try again.',clear=False,pause=False) else: return passphrase1 # get_pass_func = getpass_status if SHOW_STATUS else getpass from getpass import getpass class KomradeSymmetricKeyWithPassphrase(KomradeSymmetricKey): def hash(self,x): return self.crypt_keys.hash(x) @property def passhash(self): if not self._passhash: self._passhash = hasher(getpass(WHY_MSG)) return self._passhash def __init__(self,passphrase=None,passhash=None): if passhash: self._passhash = passhash elif passphrase: self._passhash = hasher(passphrase) else: self._passhash = None @property def data(self): return KEY_TYPE_SYMMETRIC_WITH_PASSPHRASE.encode('utf-8') def __repr__(self): return f'[Symmetric Key] (generated by password)' @property def cell(self): if not hasattr(self,'_cell'): from getpass import getpass self._cell = SCellSeal(passphrase=self.passhash) return self._cell class KomradeSymmetricKeyWithoutPassphrase(KomradeSymmetricKey): def __init__(self,key=None): self.key = GenerateSymmetricKey() if not key else key @property def data(self): return self.key def __repr__(self): return f'[Symmetric Key]\n ({self.discreet})' @property def cell(self): if not hasattr(self,'_cell'): self._cell = SCellSeal(key=self.key) return self._cell class KomradeAsymmetricKey(KomradeKey): def __init__(self,pubkey=None,privkey=None): if not pubkey or not privkey: keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC) privkey = keypair.export_private_key() pubkey = keypair.export_public_key() self.pubkey=pubkey self.privkey=privkey self.privkey_obj = KomradeAsymmetricPrivateKey(privkey,pubkey) self.pubkey_obj = KomradeAsymmetricPublicKey(pubkey,privkey) def encrypt(self,msg,pubkey=None,privkey=None): if issubclass(type(msg), KomradeKey) or issubclass(type(msg), KomradeEncryptedKey): 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): if issubclass(type(msg), KomradeKey) or issubclass(type(msg), KomradeEncryptedKey): msg=msg.data pubkey=pubkey if pubkey else self.pubkey privkey=privkey if privkey else self.privkey return SMessage(privkey.data,pubkey.data).unwrap(msg) @property def data(self): return self.key class KomradeAsymmetricPublicKey(KomradeAsymmetricKey): def __init__(self,pubkey,privkey=None): self.pubkey=pubkey self.privkey=privkey @property def key(self): return self.pubkey @property def data(self): return self.pubkey def __repr__(self): return f'''[Asymmetric Public Key]\n ({self.data_b64.decode()})''' class KomradeAsymmetricPrivateKey(KomradeAsymmetricKey): def __init__(self,privkey,pubkey=None): self.pubkey=pubkey self.privkey=privkey @property def data(self): return self.privkey @property def key(self): return self.privkey def __repr__(self): return f'''[Asymmetric Private Key]\n ({self.discreet})''' def make_key_discreet(data,chance_unredacted=0.25): import random if not data: return '?' if not isBase64(data): data=b64encode(data) key=data.decode() return ''.join((k if random.random()