major changes

operator-time
quadrismegistus 4 years ago
parent bc194238b9
commit 234b9b5766

@ -1,739 +0,0 @@
import os
import asyncio
from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair
from pythemis.smessage import SMessage, ssign, sverify
from pythemis.exception import ThemisError
from pythemis.scell import SCellSeal
from base64 import b64decode,b64encode
# from kademlia.network import Server
import os,time,sys,logging
from pathlib import Path
import requests
sys.path.append('../p2p')
BSEP=b'||||||||||'
BSEP2=b'@@@@@@@@@@'
BSEP3=b'##########'
NODE_SLEEP_FOR=1
P2P_PREFIX=b'/persona/'
P2P_PREFIX_POST=b'/msg/'
P2P_PREFIX_INBOX=b'/inbox/'
P2P_PREFIX_OUTBOX=b'/outbox/'
WORLD_PUB_KEY = b'VUVDMgAAAC1z53KeApQY4RICK5k0nXnnS+K17veIFMPlFKo7mqnRhTZDhAmG'
WORLD_PRIV_KEY = b'UkVDMgAAAC26HXeGACxZUoKYKlZ7sDmVoLwffNj3CrdqoPrE94+2ysfhufmP'
KOMRADE_PUB_KEY = b'VUVDMgAAAC09uo+wAgu/V9xyvMkMDbOQEk1ssOrFADaiyTzfwVjE6o8FHoil'
KOMRADE_PRIV_KEY = b'UkVDMgAAAC33fFiaAIpmQewjkYndzMcMkj1mLy/lE4RXJQzIlUN94tyC5g29'
DEBUG = True
UPLOAD_DIR = 'uploads/'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
PORT_LISTEN = 5639
NODE_SLEEP_FOR=1
NODES_PRIME = [("128.232.229.63",8467)]
KEYSERVER_ADDR = 'komrade.app' #'128.232.229.63'
KEYSERVER_PORT = 5566
KEY_PATH = os.path.join(os.path.expanduser('~'),'.komrade')
KEY_PATH_PUB = os.path.join(KEY_PATH,'.locs')
KEY_PATH_PRIV = os.path.join(KEY_PATH,'.keys')
for x in [KEY_PATH,KEY_PATH_PUB,KEY_PATH_PRIV]:
if not os.path.exists(x): os.makedirs(x)
WORLD_PRIV_KEY_FN = os.path.join(KEY_PATH_PRIV,'.world.key')
WORLD_PUB_KEY_FN = os.path.join(KEY_PATH_PUB,'.world.loc')
KOMRADE_PRIV_KEY_FN = os.path.join(KEY_PATH_PRIV,'.komrade.key')
KOMRADE_PUB_KEY_FN = os.path.join(KEY_PATH_PUB,'.komrade.loc')
def check_world_keys():
if not os.path.exists(WORLD_PRIV_KEY_FN):
with open(WORLD_PRIV_KEY_FN,'wb') as of:
of.write(WORLD_PRIV_KEY)
if not os.path.exists(WORLD_PUB_KEY_FN):
with open(WORLD_PUB_KEY_FN,'wb') as of:
of.write(WORLD_PUB_KEY)
if not os.path.exists(KOMRADE_PRIV_KEY_FN):
with open(KOMRADE_PRIV_KEY_FN,'wb') as of:
of.write(KOMRADE_PRIV_KEY)
if not os.path.exists(KOMRADE_PUB_KEY_FN):
with open(KOMRADE_PUB_KEY_FN,'wb') as of:
of.write(KOMRADE_PUB_KEY)
# check_world_keys()
## CONNECTING
## utils
def get_random_id():
import uuid
return uuid.uuid4().hex
def get_random_binary_id():
import base64
idstr = get_random_id()
return base64.b64encode(idstr.encode())
def logger():
import logging
handler = logging.StreamHandler()
formatter = logging.Formatter('[%(asctime)s]\n%(message)s\n')
handler.setFormatter(formatter)
logger = logging.getLogger(__file__)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
return logger
LOG = None
def log(*x):
global LOG
if not LOG: LOG=logger().debug
tolog=' '.join(str(_) for _ in x)
LOG(tolog)
class NetworkStillConnectingError(OSError): pass
class Persona(object):
def __init__(self,name,api=None,node=None,create_if_missing=True):
self.name=name
self.log=log
self.privkey=None
self.pubkey=None
self.api=api
self.can_receive = False
self.can_send = False
# self.can_login = False
self.external_keys_loaded = False
self.pubkey_enc = None
self.pubkey_decr = None
# self._node=node
self.create_if_missing=create_if_missing
# self.log(f'>> Persona.__init__(name={name},create_if_missing={create_if_missing})')
# load at least any local keys (non-async)
self.find_keys_local()
# self.login_or_register()
def __repr__(self):
#pkeystr = '+loc' if self.has_public_key() else ''
#privkeystr = ' +key' if self.has_private_key() else ''
# ptypestr='acccount' if self.has_private_key() else 'contact'
ptypestr='loc' if not self.has_private_key() else 'keyloc'
return f'{self.name} ({ptypestr})'
def get_keyserver_pubkey(self):
Q=f'http://{KEYSERVER_ADDR}:{KEYSERVER_PORT}/pub'
r = self.api.request(Q)
return r.content
# self.log('r =',r,b64encode(r.content))
# pubkey_b64 = b64encode(r.content)
# return pubkey_b64
def get_externally_signed_pubkey(self):
Q=f'http://{KEYSERVER_ADDR}:{KEYSERVER_PORT}/get/{self.name}'
self.log('Q:',Q)
r = self.api.request(Q)
package_b64 = r.content
package = b64decode(package_b64)
self.log('package <--',package)
if not package: return (b'',b'',b'')
return package.split(BSEP)
# pubkey_b64, signed_pubkey_b64, server_signed_pubkey_b64 = package.split(BSEP)
# signed_pubkey = b64encode(r.content)
# return (b64encode(pubkey), b64encode(signed_pubkey))
def set_externally_signed_pubkey(self):
import requests
Q=f'http://{KEYSERVER_ADDR}:{KEYSERVER_PORT}/add/{self.name}' #/{name}/{key}
package = self.pubkey_b64 + BSEP + self.signed_pubkey_b64
self.log('set_externally_signed_pubkey package -->',package)
r = requests.post(Q, data=package) #{'name':self.name,'key':self.pubkey_b64})
return r
def has_private_key(self):
return self.privkey is not None
def has_public_key(self):
return self.pubkey is not None
@property
async def node(self):
node = await self.api.node
return node
def load_keyserver_pubkey(self):
self.keyserver_pubkey_b64 = self.get_keyserver_pubkey()
self.keyserver_pubkey = b64decode(self.keyserver_pubkey_b64)
self.log('keyserver_pubkey =',self.keyserver_pubkey)
return self.keyserver_pubkey
def load_external_keys(self):
if self.external_keys_loaded: return
self.pubkey_ext_b64, self.signed_pubkey_ext_b64, self.server_signed_pubkey_ext_b64 = self.get_externally_signed_pubkey()
self.log('pubkey_ext_b64 =',self.pubkey_ext_b64)
self.log('signed_pubkey_ext_b64 =',self.signed_pubkey_ext_b64)
self.log('server_signed_pubkey_ext_b64 =',self.server_signed_pubkey_ext_b64)
self.external_keys_loaded = True
def keyserver_name_exists(self):
user_missing = (self.pubkey_ext_b64 is b'' or self.signed_pubkey_ext_b64 is b'' or self.server_signed_pubkey_ext_b64 is b'')
return not user_missing
def meet(self,save_loc=True):
pubkey_ext = b64decode(self.pubkey_keyserver_verified)
self.log('pubkey_ext',pubkey_ext)
self.pubkey=pubkey_ext
self.log('setting self.pubkey to external value:',self.pubkey)
self.log('self.pubkey_64',self.pubkey_b64)
self.log('keyserver_verified',self.pubkey_keyserver_verified)
with open(self.key_path_pub,'wb') as of:
of.write(self.pubkey_keyserver_verified)
return {'success':'Met person as acquaintance'}
def register(self):
# register
if self.create_if_missing:
self.gen_keys()
res = self.set_externally_signed_pubkey()
self.log('set_externally_signed_pubkey res =',res)
if res is None:
return {'error':'Could not set externally signed pubkey'}
else:
return {'success':'Created new pubkey'}
else:
return {'error':'No public key externally, but create_if_missing==False'}
# login, meet, or register
def boot(self):
# keyserver active?
keyserver_pubkey = self.keyserver_pubkey = self.load_keyserver_pubkey()
if keyserver_pubkey is None:
return {'error':'Cannot conntact keyserver'}
# load external keys
self.load_external_keys()
# user exists...
if self.keyserver_name_exists():
# if I claim to be this person
if self.privkey and self.pubkey_decr:
attempt = self.login()
self.log('login attempt ->',attempt)
return attempt
# otherwise just meet them
attempt = self.meet()
self.log('meet attempt ->',attempt)
return attempt
# user does not exist
attempt = self.register()
self.log('register attempt -->',attempt)
return attempt
@property
def key_path_pub(self):
return os.path.join(KEY_PATH_PUB,'.'+self.name+'.loc')
@property
def key_path_pub_enc(self):
return os.path.join(KEY_PATH_PUB,'.'+self.name+'.loc.box')
@property
def key_path_priv(self):
return os.path.join(KEY_PATH_PRIV,'.'+self.name+'.key')
@property
def name_b64(self):
return b64encode(self.name.encode())
@property
def privkey_b64(self):
return b64encode(self.privkey)
@property
def pubkey_b64(self):
return b64encode(self.pubkey) if self.pubkey else b''
@property
def signed_pubkey_b64(self):
return self.sign(self.pubkey_b64)
# return self.encrypt(self.pubkey_b64, self.pubkey_b64)
## genearating keys
# def gen_keys1(self):
# self.log('gen_keys()')
# keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC)
# self.privkey = keypair.export_private_key()
# self.pubkey = keypair.export_public_key()
# self.log(f'priv_key saved to {self.key_path_priv}')
# with open(self.key_path_priv, "wb") as private_key_file:
# private_key_file.write(self.privkey_b64)
# with open(self.key_path_pub, "wb") as public_key_file:
# # save SIGNED public key
# public_key_file.write(self.pubkey_b64)
# with open(self.key_path_pub_enc,'wb') as signed_public_key_file:
# # self.log('encrypted_pubkey_b64 -->',self.encrypted_pubkey_b64)
# pubkey_b64 = b64encode(self.pubkey)
# self.log('pubkey',self.pubkey)
# self.log('pubkey_b64',pubkey_b64)
# encrypted_pubkey_b64 = self.encrypt(pubkey_b64, pubkey_b64, KOMRADE_PRIV_KEY)
# self.log('encrypted_pubkey_b64 -->',encrypted_pubkey_b64)
# signed_public_key_file.write(encrypted_pubkey_b64)
def gen_keys(self,passphrase=None):
"""
Generate private/public key pair
Secure that with passphrase
"""
## Generate key pair
self.log('gen_keys()')
keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC)
self.privkey = keypair.export_private_key()
self.pubkey = keypair.export_public_key()
## Secure with passphrase
if passphrase is None: passphrase=input('Please protect account with passphrase:\n')
cell = SCellSeal(passphrase=passphrase)
keypair_b = self.privkey + BSEP + self.pubkey
keypair_b_encr = cell.encrypt(keypair_b)
self.log(f'priv_key saved to {self.key_path_priv}')
with open(self.key_path_priv, "wb") as private_key_file:
private_key_file.write(self.privkey_b64)
with open(self.key_path_pub, "wb") as public_key_file:
# save SIGNED public key
public_key_file.write(self.pubkey_b64)
with open(self.key_path_pub_enc,'wb') as signed_public_key_file:
# self.log('encrypted_pubkey_b64 -->',self.encrypted_pubkey_b64)
pubkey_b64 = b64encode(self.pubkey)
self.log('pubkey',self.pubkey)
self.log('pubkey_b64',pubkey_b64)
encrypted_pubkey_b64 = self.encrypt(pubkey_b64, pubkey_b64, KOMRADE_PRIV_KEY)
self.log('encrypted_pubkey_b64 -->',encrypted_pubkey_b64)
signed_public_key_file.write(encrypted_pubkey_b64)
## loading keys from disk
def find_keys_local(self):
self.log(f'find_keys_local(path_pub={self.key_path_pub}, path_priv={self.key_path_priv})')
if os.path.exists(self.key_path_priv):
with open(self.key_path_priv) as priv_f:
self.privkey=b64decode(priv_f.read())
# Load from encrypted?
if os.path.exists(self.key_path_pub_enc) and self.privkey:
with open(self.key_path_pub_enc) as pub_f:
self.pubkey_enc=pub_f.read()
self.pubkey_decr=self.decrypt(self.pubkey_enc, KOMRADE_PUB_KEY)
# self.pubkey=self.pubkey_decr
self.log('loaded self.pubkey from enc',self.pubkey)
self.can_receive = True
self.can_send = True
# load from nonencrypted pubkey?
if os.path.exists(self.key_path_pub):
with open(self.key_path_pub) as pub_f:
self.pubkey=b64decode(pub_f.read())
self.log('loaded self.pubkey from UNenc',self.pubkey)
self.can_receive = True
@property
def pubkey_keyserver_verified(self):
# test if remote data agrees
if not hasattr(self,'_keyserver_verified'):
self._keyserver_verified = self.verify(self.server_signed_pubkey_ext_b64, self.keyserver_pubkey_b64)
return self._keyserver_verified
def login(self):
# test if local data present
if not self.pubkey or not self.pubkey_decr:
return {'error':'Public keys not present'}
# test if local data agrees
self.log('self.pubkey',self.pubkey_b64)
self.log('self.pubkey_decr',self.pubkey_decr)
if self.pubkey_b64 != self.pubkey_decr:
return {'error':'Public keys do not match'}
# test if remote data agrees
keyserver_verified = self.pubkey_keyserver_verified
if keyserver_verified is None:
return {'error':'Keyserver verification failed'}
# test if pubkey match
enc_match = self.pubkey_decr == keyserver_verified
if enc_match:
return {'success':'Keys matched'}
return {'error':'Keys did not match'}
## E/D/S/V
def encrypt(self,msg_b64,for_pubkey_b64, privkey_b64=None):
self.log('encrypt()',msg_b64,for_pubkey_b64,privkey_b64)
privkey = b64decode(privkey_b64) if privkey_b64 else self.privkey
# handle verification failure
for_pubkey = b64decode(for_pubkey_b64)
encrypted_msg = SMessage(privkey, for_pubkey).wrap(msg_b64)
return b64encode(encrypted_msg)
def decrypt(self,encrypted_msg_b64,from_pubkey_b64, privkey_b64=None):
privkey = b64decode(privkey_b64) if privkey_b64 else self.privkey
# handle verification failure
from_pubkey = b64decode(from_pubkey_b64)
encrypted_msg = b64decode(encrypted_msg_b64)
decrypted_msg = SMessage(privkey, from_pubkey).unwrap(encrypted_msg)
return decrypted_msg
def sign(self,msg_b64, privkey=None):
if not privkey: privkey=self.privkey
signed_msg = b64encode(ssign(privkey, msg_b64))
return signed_msg
def verify(self,signed_msg_b64,pubkey_b64=None):
if pubkey_b64 is None: pubkey_b64=self.pubkey_b64
self.log('verify() signed_msg_b64 =',signed_msg_b64)
self.log('verify() pubkey_b64 =',pubkey_b64)
signed_msg = b64decode(signed_msg_b64)
public_key = b64decode(pubkey_b64)
self.log('verify() signed_msg =',signed_msg)
self.log('verify() public_key =',public_key)
try:
verified_msg = sverify(public_key, signed_msg)
return verified_msg
except ThemisError as e:
print('!!',e)
return None
@property
def uri_inbox(self):
return P2P_PREFIX_INBOX+self.name.encode()
@property
def uri_outbox(self):
return P2P_PREFIX_OUTBOX+self.name.encode()
@property
def app_pubkey_b64(self):
return KOMRADE_PUB_KEY
## POSTING/SENDING MSGS
async def post(self,encrypted_payload_b64,to_person):
# double wrap
double_encrypted_payload = self.encrypt(encrypted_payload_b64, to_person.pubkey_b64, KOMRADE_PRIV_KEY)
self.log('double_encrypted_payload =',double_encrypted_payload)
post_id = get_random_binary_id() #get_random_id().encode()
node = await self.node
uri_post = P2P_PREFIX_POST + post_id
res = await node.set(uri_post, double_encrypted_payload)
self.log('result of post() =',res)
return uri_post
async def send(self,msg_b,to,from_person=None):
"""
1) [Encrypted payload:]
1) Timestamp
2) Public key of sender
3) Public key of recipient
4) AES-encrypted Value
2) [Decryption tools]
1) AES-decryption key
2) AES decryption IV value
5) Signature of value by author
"""
if type(msg_b)==str: msg_b=msg_b.encode()
msg_b64=b64encode(msg_b)
# encrypt and sign
to_person = to
if from_person is None: from_person = self
encrypted_payload = from_person.encrypt(msg_b64, to_person.pubkey_b64)
signed_encrypted_payload = from_person.sign(encrypted_payload)
# package
time_b64 = b64encode(str(time.time()).encode())
WDV_b64 = b64encode(BSEP.join([
signed_encrypted_payload,
from_person.pubkey_b64,
from_person.name_b64,
time_b64]))
self.log('WDV_b64 =',WDV_b64)
# post
post_id = await self.post(WDV_b64, to_person)
self.log('post_id <-',post_id)
# add to inbox
res = await to_person.add_to_inbox(post_id)
self.log('add_to_inbox <-',res)
# add to outbox?
# pass
async def load_inbox(self,decrypt_msg_uri=False,last=None):
node = await self.node
encrypted_inbox_idstr_b64 = await node.get(self.uri_inbox)
self.log('encrypted_inbox_idstr_b64 =',encrypted_inbox_idstr_b64)
if encrypted_inbox_idstr_b64 is None: return []
# inbox_idstr = self.decrypt(encrypted_inbox_idstr_b64, self.app_pubkey_b64)
# self.log('decrypted inbox_idstr =',inbox_idstr)
# decrypt!
encrypted_inbox_idstr = b64decode(encrypted_inbox_idstr_b64)
self.log('encrypted_inbox_idstr =',encrypted_inbox_idstr)
inbox_ids = encrypted_inbox_idstr.split(BSEP) if encrypted_inbox_idstr is not None else []
self.log('inbox_ids =',inbox_ids)
if decrypt_msg_uri:
inbox_ids = [self.decrypt(enc_msg_id_b64,KOMRADE_PUB_KEY) for enc_msg_id_b64 in inbox_ids]
self.log('inbox_ids decrypted =',inbox_ids)
return inbox_ids[:last]
async def add_to_inbox(self,msg_uri,inbox_sofar=None):
# encrypt msg id so only inbox owner can resolve the pointer
self.log('unencrypted msg uri:',msg_uri)
encrypted_msg_uri = self.encrypt(msg_uri, self.pubkey_b64, KOMRADE_PRIV_KEY)
self.log('encrypted msg uri:',encrypted_msg_uri)
# get current inbox
if inbox_sofar is None: inbox_sofar=await self.load_inbox()
self.log('inbox_sofar:',inbox_sofar)
# add new value
new_inbox = inbox_sofar + [encrypted_msg_uri]
new_inbox_b = BSEP.join(new_inbox)
self.log('new_inbox_b:',new_inbox_b)
new_inbox_b64 = b64encode(new_inbox_b)
self.log('new_inbox_b64:',new_inbox_b64)
# set on net
node = await self.node
await node.set(self.uri_inbox,new_inbox_b64)
new_length = len(new_inbox)
return {'success':'Inbox length increased to %s' % new_length}
#return {'error':'Could not append data'}
async def add_to_outbox(self):
"""
Do not store on server!
"""
pass
async def read_inbox(self,uri_inbox=None):
if uri_inbox is None: uri_inbox = P2P_PREFIX_INBOX+self.name.encode()
node = await self.node
inbox_ids = await node.get(uri_inbox)
if inbox_ids is not None:
inbox_ids = inbox_ids.split(BSEP)
self.log('found inbox IDs:',inbox_ids)
msgs_toread = [self.read_msg(msg_id) for msg_id in inbox_ids]
msgs = await asyncio.gather(*msgs_toread)
self.log('read_inbox() msgs = ',msgs)
return msgs
return []
async def read_outbox(self,uri_outbox=None):
if uri_outbox is None: uri_outbox = P2P_PREFIX_OUTBOX+self.name.encode()
return await self.read_inbox(uri_outbox)
async def read_msg(self,msg_id):
self.log(f'Persona.read_msg({msg_id}) ?')
uri_msg=P2P_PREFIX_POST+msg_id
node = await self.node
res = await node.get(uri_msg)
self.log('res = ',res)
if res is not None:
double_encrypted_payload_b64 = res
single_encrypted_payload = self.decrypt(double_encrypted_payload_b64, KOMRADE_PUB_KEY)
self.log('GOT ENRYPTED PAYLOAD:',single_encrypted_payload)
signed_encrypted_payload_b64,from_pubkey_b64,name_b64,time_b64 = single_encrypted_payload.split(BSEP)
self.log('signed_encrypted_payload =',signed_encrypted_payload_b64)
self.log('from_pubkey_b64 =',from_pubkey_b64)
self.log('time_b64 =',time_b64)
from_name = b64decode(name_b64).decode()
self.log('from_name =',from_name)
timestamp = b64decode(time_b64).decode()
tmpP = Persona(from_name)
await tmpP.boot()
from_pubkey_b64_acc_to_name = tmpP.pubkey_b64
assert from_pubkey_b64==from_pubkey_b64_acc_to_name
encrypted_payload_b64 = self.verify(signed_encrypted_payload_b64, from_pubkey_b64)
self.log('encrypted_payload_b64 =',encrypted_payload_b64)
payload = self.decrypt(encrypted_payload_b64, from_pubkey_b64)
self.log('payload =',payload)
return {
'success':True,
'content':payload,
'from_name':from_name,
'from_pubkey_b64':from_pubkey_b64,
'timestamp':timestamp
}
return {'error':'Unknown'}
def run_multiple_tasks(tasks):
async def _go(tasks):
res = await asyncio.gather(*tasks, return_exceptions=True)
return res
return asyncio.get_event_loop().run_until_complete(_go(tasks))
async def main():
# start node
from kademlia.network import Server
#from p2p_api import
PORT_LISTEN = 5969
# NODES_PRIME = [("128.232.229.63",8467), ("68.66.241.111",8467)]
NODES_PRIME = [("128.232.229.63",8467)]
node = Server(log=log)
await node.listen(PORT_LISTEN)
await node.bootstrap(NODES_PRIME)
marx = Persona('marx',node=node)
elon = Persona('elon2',node=node)
world = Persona('world',node=node)
await world.boot()
await marx.boot()
await elon.boot()
# await marx.send(b'Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! Secret message 2! ',to=elon)
# await elon.read_inbox()
await marx.send(b'A specter is haunting the internet',to=world)
await elon.send(b'My rockets explode and so will your mind',to=world)
await elon.send(b'My rockets explode and so will your mind',to=world)
await world.read_inbox()
return True
if __name__=='__main__':
asyncio.run(main())

@ -1,205 +0,0 @@
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
import getpass,os
from crypt import Crypt
from the_operator import TheOperator
# paths
PATH_KOMRADE = os.path.abspath(os.path.join(os.path.expanduser('~'),'.komrade'))
PATH_CALLER = os.path.join(PATH_KOMRADE,'.caller')
PATH_CALLER_PUBKEY = os.path.join(PATH_CALLER,'.ca.key.pub.encr')
PATH_CALLER_PRIVKEY = os.path.join(PATH_CALLER,'.ca.key.priv.encr')
PATH_CRYPT_KEYS = os.path.join(PATH_CALLER,'.ca.db.keys.crypt')
PATH_CRYPT_DATA = os.path.join(PATH_CALLER,'.ca.db.data.encr')
# class HelloOperator(object):
# def __init__(self,op=None):
# # for now
# self.op = TheOperator()
# def create_keys(self,name):
# return self.op.create_keys(name)
# def exists(self,*x,**y): return self.op.exists(*x,**y)
class Caller(object):
### INIT CODE
def __init__(self,name):
self.name=name
self.op = TheOperator()
def log(self,*x): print(*x)
## CRYPT BASICS
@property
def crypt_cell(self):
pass
@property
def crypt_keys(self):
if not hasattr(self,'_crypt_keys'):
self._crypt_keys = Crypt(fn=PATH_CRYPT_KEYS)
return self._crypt_keys
@property
def crypt_data(self):
if not hasattr(self,'_crypt_data'):
self._crypt_data = Crypt(fn=PATH_CRYPT_DATA)
return self._crypt_data
### CREATION OF KEYS
# Get key de-cryptors
def gen_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)
return (pass_key, pass_cell)
def create_keys(self,pubkey_pass = None, privkey_pass = None, adminkey_pass = None):
# Get keys back from The Operator
res = self.op.create_keys(self.name)
self.log('create_keys() res from Operator? <-',res)
assert type(res)==tuple and len(res)==3
(pubkey_decr, privkey_decr, adminkey_decr) = res
# Get new encryptors
pubkey_passkey,pubkey_passcell = self.gen_pass_keycell(pubkey_pass,q_name='Permission key, to find')
privkey_passkey,privkey_passcell = self.gen_pass_keycell(privkey_pass,q_name='Permission key, to read')
adminkey_passkey,adminkey_passcell = self.gen_pass_keycell(adminkey_pass,q_name='Permission key, to admin')
# double-encrypt what was received
pubkey_decr_encr = pubkey_passcell.encrypt(pubkey_decr)
privkey_decr_encr = privkey_passcell.encrypt(privkey_decr)
adminkey_decr_encr = adminkey_passcell.encrypt(adminkey_decr)
# store double encrypted keys
self.crypt_keys.set(self.name,pubkey_decr_encr,prefix='/pub_decr_encr/')
self.crypt_keys.set(pubkey_decr,privkey_decr_encr,prefix='/priv_decr_encr/')
self.crypt_keys.set(privkey_decr,adminkey_decr_encr,prefix='/admin_decr_encr/')
# store decryption keys if not passworded?
if pubkey_passkey: self.crypt_keys.set(self.name,pubkey_passkey,prefix='/pub_decr_decr/')
if privkey_passkey: self.crypt_keys.set(pubkey_decr,privkey_passkey,prefix='/priv_decr_decr/')
if adminkey_passkey: self.crypt_keys.set(privkey_decr,adminkey_passkey,prefix='/admin_decr_decr/')
# done?
## MAGIC KEY ATTRIBUTES
@property
def pubkey_decr_encr(self):
return self.crypt_keys.get(self.name,prefix='/pub_decr_encr/')
@property
def privkey_decr_encr(self):
return self.crypt_keys.get(self.pubkey_decr,prefix='/priv_decr_encr/')
@property
def pubkey_decr_encr(self):
return self.crypt_keys.get(self.privkey_decr,prefix='/admin_decr_encr/')
# loading keys back
@property
def pubkey_decr_cell(self):
decr_key = self.crypt_keys.get(self.name,prefix='/pub_decr_encr/')
if not decr_key:
if not self.passphrase: return
decr_cell = SCellSeal(passphrase=self.passphrase)
else:
decr_cell = SCellSeal(key=decr_key)
return decr_cell
@property
def privkey_decr_cell(self):
decr_key = self.crypt_keys.get(self.name,prefix='/priv_decr_encr/')
if not decr_key:
if not self.passphrase: return
decr_cell = SCellSeal(passphrase=self.passphrase)
else:
decr_cell = SCellSeal(key=decr_key)
return decr_cell
@property
def adminkey_decr_cell(self):
decr_key = self.crypt_keys.get(self.name,prefix='/admin_decr_encr/')
if not decr_key:
if not self.passphrase: return
decr_cell = SCellSeal(passphrase=self.passphrase)
else:
decr_cell = SCellSeal(key=decr_key)
return decr_cell
@property
def pubkey_decr(self):
return self.pubkey_decr_cell.decrypt(self.pubkey_decr_encr)
@property
def privkey_decr(self):
return self.privkey_decr_cell.decrypt(self.privkey_decr_encr)
@property
def adminkey_decr(self):
return self.adminkey_decr_cell.decrypt(self.adminkey_decr_encr)
### HIGH LEVEL
# Do I exist?
def exists(self):
return self.op.exists(self.name)
def register(self,passphrase = None, as_group=False):
if self.exists():
self.log('ERROR: user already exists')
return
if not passphrase: passphrase = getpass.getpass('Enter password for new account: ')
self.passphrase=passphrase
if as_group:
self.create_keys(adminkey_pass=passphrase)
else:
self.create_keys(privkey_pass=passphrase, adminkey_pass=passphrase)
def login(self,passphrase = None):
if not passphrase: passphrase = getpass.getpass('Enter login password: ')
self.passphrase = passphrase
if not
if __name__ == '__main__':
caller = Caller('elon2')
caller.register()

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 109 KiB

File diff suppressed because one or more lines are too long

@ -0,0 +1,17 @@
###
# Define some basic things while we're here
class KomradeException(Exception): pass
# make sure komrade is on path
import sys,os
sys.path.append(os.path.dirname(__file__))
import inspect
class Logger(object):
def log(self,*x):
curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe, 2)
mytype = type(self).__name__
caller = calframe[1][3]
print(f'\n[{mytype}.{caller}()]',*x)

@ -0,0 +1,81 @@
# mine imports
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from komrade.backend.caller import Caller
from komrade import KomradeException,Logger
# other imports
import asyncio,os,time,sys,logging,getpass
from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair
from pythemis.smessage import SMessage, ssign, sverify
from pythemis.exception import ThemisError
from pythemis.scell import SCellSeal
from base64 import b64decode,b64encode
from pathlib import Path
class Model(Logger): pass
class UserAlreadyExists(KomradeException): pass
class Persona(Model):
def __init__(self, name, is_group=False):
self.name = name
self.is_group=is_group
@property
def op(self):
return Caller(self.name)
###
# MAJOR OPERATIONS
###
def register(self,passphrase = None):
"""
Register this new persona.
Protect keys according to a passphrase.
If group, only admin key pass-protected;
if individual, all keys pass-protected.
"""
# Does user already exist?
if self.op.exists(): raise UserAlreadyExists('User already exists')
# Get passphrase
if not passphrase: passphrase = getpass.getpass('Enter password for new account: ')
# Create
if self.is_group:
self.op.create_keys(adminkey_pass=passphrase)
else:
self.op.create_keys(privkey_pass=passphrase,adminkey_pass=passphrase)
def login(self,passphrase = None):
# Get passphrase
if not passphrase: passphrase = getpass.getpass('Enter login password: ')
# Get my decryption keys
if self.is_group:
keychain_decr = self.op.keychain_decr(adminkey_pass=passphrase)
else:
keychain_decr = self.op.keychain_decr(privkey_pass=passphrase,adminkey_pass=passphrase)
print(keychain_decr)
if __name__ == '__main__':
import random
idnum = random.choice(list(range(1000)))
persona = Persona('elon'+str(idnum))
print('\n\n\nREGISTERING\n\n\n')
persona.register(passphrase='bb')
print('\n\n\nLOGGING IN\n\n\n')
persona.login(passphrase='bb')

@ -0,0 +1,93 @@
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from komrade.backend.crypt import Crypt
from komrade.backend.the_operator import TheOperator
from komrade.backend.keymaker import Keymaker
from komrade import KomradeException,Logger
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
import getpass,os
# paths
PATH_KOMRADE = os.path.abspath(os.path.join(os.path.expanduser('~'),'.komrade'))
PATH_CALLER = os.path.join(PATH_KOMRADE,'.caller')
PATH_CALLER_PUBKEY = os.path.join(PATH_CALLER,'.ca.key.pub.encr')
PATH_CALLER_PRIVKEY = os.path.join(PATH_CALLER,'.ca.key.priv.encr')
PATH_CRYPT_KEYS = os.path.join(PATH_CALLER,'.ca.db.keys.crypt')
PATH_CRYPT_DATA = os.path.join(PATH_CALLER,'.ca.db.data.encr')
# class HelloOperator(object):
# def __init__(self,op=None):
# # for now
# self.op = TheOperator()
# def create_keys(self,name):
# return self.op.create_keys(name)
# def exists(self,*x,**y): return self.op.exists(*x,**y)
class Caller(Keymaker):
### INIT CODE
def __init__(self,name):
self.name=name
self.op = TheOperator()
## CRYPT BASICS
@property
def crypt_cell(self):
pass
### CREATION OF KEYS
def exists(self):
return self.op.exists(self.name)
def create_keys(self,pubkey_pass = None, privkey_pass = None, adminkey_pass = None):
# Get keys back from The Operator
res = self.op.create_keys(self.name)
self.log('create_keys() res from Operator? <-',res)
assert type(res)==tuple and len(res)==3
(pubkey_decr, privkey_decr, adminkey_decr) = res
# double-encrypt what was received
pubkey_decr_decr_key,pubkey_decr_decr_cell = self.pubkey_decr_decr_keycell(passphrase=pubkey_pass)
self.log('pubkey_decr_decr_key <--',pubkey_decr_decr_key)
self.log('pubkey_decr_decr_cell <--',pubkey_decr_decr_cell)
self.log('pubkey_decr <--',pubkey_decr)
pubkey_decr_encr = pubkey_decr_decr_cell.encrypt(pubkey_decr)
self.log('pubkey_decr_encr <--',pubkey_decr_encr)
# privkey_decr_encr = privkey_passcell.encrypt(privkey_decr)
# self.log('pubkey_decr_encr <--',pubkey_decr_encr)
# adminkey_decr_encr = adminkey_passcell.encrypt(adminkey_decr)
# self.log('pubkey_decr_encr <--',pubkey_decr_encr)
# store double encrypted keys
self.crypt_keys.set(self.name,pubkey_decr_encr,prefix='/pub_decr_encr/')
# self.crypt_keys.set(pubkey_decr,privkey_decr_encr,prefix='/priv_decr_encr/')
# self.crypt_keys.set(privkey_decr,adminkey_decr_encr,prefix='/admin_decr_encr/')
# store decryption keys if not passworded?
if pubkey_decr_decr_key: self.crypt_keys.set(self.name,pubkey_decr_decr_key,prefix='/pub_decr_decr_key/')
# if privkey_passkey: self.crypt_keys.set(pubkey_decr,privkey_passkey,prefix='/priv_decr_decr_key/')
# if adminkey_passkey: self.crypt_keys.set(privkey_decr,adminkey_passkey,prefix='/admin_decr_decr_key/')
# done?
if __name__ == '__main__':
caller = Caller('elon2')
# caller.register()

@ -11,19 +11,24 @@ from pythemis.skeygen import GenerateSymmetricKey
from pythemis.scell import SCellSeal
from pythemis.exception import ThemisError
import zlib
from komrade import KomradeException,Logger
LOG_GET_SET = False
class Crypt(object):
def log(self,*x): print(*x)
class Crypt(Logger):
def __init__(self,name=None,fn=None,cell=None):
if not name and fn: name=os.path.basename(fn).replace('.','_')
self.name,self.fn,self.cell = name,fn,cell
self.store = FilesystemStore(self.fn)
def log(self,*x):
if LOG_GET_SET:
super().log(*x)
def hash(self,binary_data):
return hashlib.sha256(binary_data).hexdigest()

@ -0,0 +1,205 @@
class Keymaker(Logger):
### BASE STORAGE
@property
def crypt_keys(self):
if not hasattr(self,'_crypt_keys'):
self._crypt_keys = Crypt(fn=PATH_CRYPT_KEYS)
return self._crypt_keys
@property
def crypt_data(self):
if not hasattr(self,'_crypt_data'):
self._crypt_data = Crypt(fn=PATH_CRYPT_DATA)
return self._crypt_data
### STARTING WITH MOST ABSTRACT
### (1) Final keys
def getkey(self, uri, passphrases={}, keychain_encr={}, keychain_decr={}, keyname=''):
if not keyname: return
key = None
# if the decryption keys have been provided to me
if keychain_decr:
# get the relevant decryption key
key_decr = keychain_encr.get(f'{keyname}key_decr'):
# see if I have the right encrypted key
key_encr = self.getkey_encr(uri, passphrases=passphrases, keychain_decr=keychain_decr, keyname=keyname)
# conversely, if the encryption keys have been provided to me
elif keychain_encr:
# get the relevant encryption key
key_encr = keychain_encr.get(f'{keyname}key_decr'):
# see if I have the right encrypted key
key_decr = self.getkey_decr(uri, passphrases=passphrases, keychain_decr=keychain_decr, keyname=keyname)
# then, once I have both:
if not keychain_decr and not keychain_encr: return
try:
key = SCellSeal(key=key_decr).decrypt(key_encr)
except ThemisError as e:
self.log('key recovery failed',e)
return key
def pubkey(self, **kwargs):
return self.getkey(uri=self.name,keyname='pub',**kwargs)
def privkey(self, **kwargs):
return self.getkey(uri=self.pubkey(**kwargs),keyname='priv',**kwargs)
def adminkey(self, **kwargs):
return self.getkey(uri=self.privkey(**kwargs),keyname='admin',**kwargs)
## (2A) ENCRYPTED KEYS
def getkey_encr(self, uri, passphrases={}, keychain_decr={}, keyname=''):
return self.crypt_keys.get(uri,prefix=f'/{keyname}_encr/')
def pubkey_encr(self, **kwargs):
return self.getkey_encr(uri=self.name,keyname='pub',**kwargs)
def privkey_encr(self, **kwargs):
return self.getkey(uri=self.pubkey_encr(**kargs),keyname='priv',**kwargs)
def adminkey_encr(self, **kwargs):
return self.getkey(uri=self.privkey_encr(**kargs),keyname='admin',**kwargs)
### (2B) DECRYPTED KEYS
def getkey_decr(self, uri, passphrases={}, keychain_encr={}, keyname=''):
key_loaded = self.crypt_keys.get(uri,prefix=f'/{keyname}_decr/')
if key_loaded: return key_loaded
# otherwise, get it by decrypting its components?
return self.buildkey
def pubkey_decr(self, **kwargs):
return self.getkey_decr(uri=self.name,keyname='pub',**kwargs)
def privkey_decr(self, **kwargs):
return self.getkey(uri=self.pubkey_decr(**kargs),keyname='priv',**kwargs)
def adminkey_decr(self, **kwargs):
return self.getkey(uri=self.privkey_decr(**kargs),keyname='admin',**kwargs)
def buildkey_decr(self, passphrases={}, keyname='pub'):
# need two pieces: its encrypted part and its decrypted part
key_decr_encr = self.getkey_decr_encr(keyname=keyname)
key_decr_decr_key,pubkey_decr_decr_cell = self.getkey_decr_decr_keycell(passphrase,keyname=keyname)
self.log(f'about to decrypt {pubkey_decr_encr} with cell {pubkey_decr_decr_cell}')
try:
pubkey_decr = pubkey_decr_decr_cell.decrypt(pubkey_decr_encr)
except ThemisError as e:
self.log('!!',e)
exit()
self.log('pubkey_decr <--',pubkey_decr)
return pubkey_decr
def pubkey_decr(self, passphrases={}):
pubkey_decr_encr = self.pubkey_decr_encr()
pubkey_decr_decr_key,pubkey_decr_decr_cell = self.pubkey_decr_decr_keycell(passphrase)
self.log(f'about to decrypt {pubkey_decr_encr} with cell {pubkey_decr_decr_cell}')
try:
pubkey_decr = pubkey_decr_decr_cell.decrypt(pubkey_decr_encr)
except ThemisError as e:
self.log('!!',e)
exit()
self.log('pubkey_decr <--',pubkey_decr)
return pubkey_decr
def privkey_decr(self, passphrases={}):
privkey_decr_encr = self.privkey_decr_encr()
privkey_decr_decr_cell = self.privkey_decr_decr_cell(passphrase)
privkey_decr = privkey_decr_decr_cell.decrypt(privkey_decr_encr)
return privkey_decr
def adminkey_decr(self, passphrases={}):
adminkey_decr_encr = self.adminkey_decr_encr()
adminkey_decr_decr_cell = self.adminkey_decr_decr_cell(passphrase)
adminkey_decr = adminkey_decr_decr_cell.decrypt(adminkey_decr_encr)
return adminkey_decr
def keychain_decr(self, pubkey_pass = None, privkey_pass = None, adminkey_pass = None):
return {
'pubkey_decr':self.pubkey_decr(pubkey_pass),
'privkey_decr':self.privkey_decr(privkey_pass),
'adminkey_decr':self.adminkey_decr(adminkey_pass)
}
## MAGIC KEY ATTRIBUTES
# loading keys back
### DECR DECR KEYCELL
# 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)
def getkey_decr_decr_keycell(self, passphrases={}, keyname='pub'):
# get or make
decr_key = None
decr_cell = None
if passphrase:
decr_key=None
decr_cell = SCellSeal(passphrase=passphrase)
return (decr_key,decr_cell)
# if I have one stored?
decr_key = self.crypt_keys.get(self.name,prefix=f'/{keyname}_decr_decr_key/')
if decr_key:
decr_cell = SCellSeal(key=decr_key)
return (decr_key,decr_cell)
# if I need to generate one
if not decr_cell:
return self.genkey_pass_keycell()
return (decr_key,decr_cell)
def pubkey_decr_decr_keycell(self,passphrases={}):
return self.getkey_decr_decr_keycell(passphrase=passphrase, keyname='pub')
def privkey_decr_decr_keycell(self,passphrases={}):
return self.getkey_decr_decr_keycell(passphrase=passphrase, keyname='priv')
def adminkey_decr_decr_keycell(self,passphrases={}):
return self.getkey_decr_decr_keycell(passphrase=passphrase, keyname='admin')
### DECR ENCR KEYS
def getkey_decr_encr(self,crypt_key = None,keyname='pub'):
if not crypt_key: crypt_key = self.name
key_decr_encr = self.crypt_keys.get(self.name,prefix=f'/{keyname}_decr_encr/')
self.log(f'{keyname}key_decr_encr <--',key_decr_encr)
return key_decr_encr
def pubkey_decr_encr(self,passphrases={}):
return self.getkey_decr_encr(crypt_key=self.name, keyname='pub')
def privkey_decr_encr(self,passphrases={}):
pubkey_decr = self.pubkey_decr(passphrase=passphrase)
return self.getkey_decr_encr(crypt_key=pubkey_decr, keyname='priv')
def adminkey_decr_encr(self,passphrases={}):
privkey_decr=self.privkey_decr(passphrase=passphrase)
return self.getkey_decr_encr(crypt_key=privkey_decr, keyname='admin')
### DECR KEYS

@ -2,7 +2,9 @@
There is only one operator!
Running on node prime.
"""
import os,sys
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from komrade.backend.crypt import Crypt
from komrade.backend.keymaker import Keymaker
from flask import Flask
from flask_classful import FlaskView
from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair
@ -11,6 +13,7 @@ from pythemis.skeygen import GenerateSymmetricKey
from pythemis.scell import SCellSeal
from pythemis.exception import ThemisError
from base64 import b64encode,b64decode
from komrade import KomradeException,Logger
import getpass
PATH_HERE = os.path.dirname(__file__)
sys.path.append(PATH_HERE)
@ -35,22 +38,18 @@ if not os.path.exists(PATH_OPERATOR): os.makedirs(PATH_OPERATOR)
class TheOperator(object):
class TheOperator(Keymaker):
"""
The operator.
"""
def __init__(self):
def __init__(self, passphrase = None):
"""
Boot up the operator. Requires knowing or setting a password of memory.
"""
# Establish encryption/decryption cell
self.cell = SCellSeal(passphrase=getpass.getpass('What is the password of memory? '))
# Do I have my keys?
have_keys = self.check_keys()
# If not, forge them -- only once!
if not have_keys: self.forge_keys()
@ -61,31 +60,25 @@ class TheOperator(object):
# That's it!
@property
def crypt_keys(self):
if not hasattr(self,'_crypt_keys'):
self._crypt_keys = Crypt(fn=PATH_CRYPT_KEYS, cell=self.cell)
return self._crypt_keys
@property
def crypt_data(self):
if not hasattr(self,'_crypt_data'):
self._crypt_data = Crypt(fn=PATH_CRYPT_DATA, cell=self.cell)
return self._crypt_data
def log(self,*x):
print(*x)
def get_encypted_keys(self):
def op_keychain_encr(self):
self.log('loading encrypted keys from disk')
with open(PATH_OPERATOR_PUBKEY,'rb') as f_pub, open(PATH_OPERATOR_PRIVKEY,'rb') as f_priv:
pubkey_encr = f_pub.read()
privkey_encr = f_priv.read()
#self.log('loaded encrypted pubkey is:',pubkey_encr)
#self.log('loaded encrypted privkey is:',privkey_encr)
self.log('Operator pubkey_encr <--',pubkey_encr)
self.log('Operator privkey <--',privkey_encr)
return (pubkey_encr,privkey_encr)
def get_keys(self):
def get_op_keys(self):
# Get passphrase
passphrase = 'aa' #@ HACK!!!
self.crypt_key,self. = self.get_k
# Do I have my keys?
have_keys = self.check_keys()
pubkey_encr,privkey_encr = self.get_encypted_keys()
# decrypt according to password of memory
@ -170,11 +163,40 @@ class TheOperator(object):
return (pubkey_decr, privkey_decr, adminkey_decr)
# Magic key attributes
## DECRYPTED REAL FINAL KEYS
def pubkey(self, name, keychain_decr):
pubkey_decr = keychain_decr.get('pubkey_decr')
pubkey_encr = self.pubkey_encr(name)
if not pubkey_decr or not pubkey_encr: return None
pubkey = SCellSeal(key=pubkey_decr).decrypt(pubkey_encr)
return pubkey
def privkey(self, name, keychain_decr):
privkey_decr = keychain_decr.get('privkey_decr')
privkey_encr = self.privkey_encr(name, keychain_decr)
if not privkey_decr or not privkey_encr: return None
privkey = SCellSeal(key=privkey_decr).decrypt(privkey_encr)
return privkey
def adminkey(self, name, keychain_decr):
adminkey_decr = keychain_decr.get('adminkey_decr')
adminkey_encr = self.adminkey_encr(name, keychain_decr)
if not adminkey_decr or not adminkey_encr: return None
adminkey = SCellSeal(key=adminkey_decr).decrypt(adminkey_encr)
return adminkey
def exists(self,name):
return self.crypt_keys.get(name,prefix='/pub_encr/') is not None
def login(self, name, keychain_encr):
pass

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Before

Width:  |  Height:  |  Size: 333 KiB

After

Width:  |  Height:  |  Size: 333 KiB

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 276 KiB

Before

Width:  |  Height:  |  Size: 568 KiB

After

Width:  |  Height:  |  Size: 568 KiB

Before

Width:  |  Height:  |  Size: 9.7 MiB

After

Width:  |  Height:  |  Size: 9.7 MiB

Before

Width:  |  Height:  |  Size: 9.7 MiB

After

Width:  |  Height:  |  Size: 9.7 MiB

Before

Width:  |  Height:  |  Size: 398 KiB

After

Width:  |  Height:  |  Size: 398 KiB

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 384 KiB

Before

Width:  |  Height:  |  Size: 9.7 MiB

After

Width:  |  Height:  |  Size: 9.7 MiB

Before

Width:  |  Height:  |  Size: 9.7 MiB

After

Width:  |  Height:  |  Size: 9.7 MiB

Before

Width:  |  Height:  |  Size: 9.7 MiB

After

Width:  |  Height:  |  Size: 9.7 MiB

Before

Width:  |  Height:  |  Size: 491 KiB

After

Width:  |  Height:  |  Size: 491 KiB

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Before

Width:  |  Height:  |  Size: 7.1 MiB

After

Width:  |  Height:  |  Size: 7.1 MiB

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

Before

Width:  |  Height:  |  Size: 923 KiB

After

Width:  |  Height:  |  Size: 923 KiB

Before

Width:  |  Height:  |  Size: 491 KiB

After

Width:  |  Height:  |  Size: 491 KiB

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 202 KiB

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Loading…
Cancel
Save