channnggessss

nothing-unencr
quadrismegistus 4 years ago
parent d814689883
commit 95ac8bb0ba

@ -11,8 +11,33 @@ class Caller(Operator):
Variant of an Operator which handles local keys and keymaking.
"""
def ring_ring(self,msg_encr_caller2caller):
# ring 1: encrypt caller2phone
msg_encr_caller2caller_caller2phone = self.package_msg_to(
msg_encr_caller2caller,
self.op
)
self.log('msg_encr_caller2caller_caller2phone',msg_encr_caller2caller_caller2phone)
# ring 2: dial and get response
resp_msg_encr_caller2caller_caller2phone = self.phone.ring_ring(
msg_encr_caller2caller_caller2phone
)
self.log('resp_msg_encr_caller2caller_caller2phone',resp_msg_encr_caller2caller_caller2phone)
# ring 3: decrypt and send back
resp_msg_encr_caller2caller = self.unpackage_msg_from(
resp_msg_encr_caller2caller_caller2phone
)
self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller)
return resp_msg_encr_caller2caller
def get_new_keys(self, name = None, passphrase = DEBUG_DEFAULT_PASSPHRASE, is_group=None):
# get needed metadata
if not name: name=self.name
if name is None:
name = input('\nWhat is the name for this account? ')
@ -22,14 +47,13 @@ class Caller(Operator):
# is_group = input('\nIs this a group account? [y/N]').strip().lower() == 'y'
# form request
req_json = {
'_route':'forge_new_keys',
msg_to_op = {
'_please':'forge_new_keys',
'name':name,
'passphrase':hashish(passphrase.encode())
}
# ask operator
phone_res = self.phone.ring_ring(json_phone2phone=req_json)
phone_res = self.phone.ring_ring(msg_to_op)
# URI id
uri_id = phone_res.get('uri_id')

@ -85,24 +85,61 @@ class Keymaker(Logger):
# set defaults
self.name=name
self._uri_id=uri_id
self._pubkey=None
self._keychain=keychain
self.passphrase=passphrase
self.path_crypt_keys=path_crypt_keys
self.path_crypt_data=path_crypt_data
@property
def pubkey(self):
if not self._pubkey: self._pubkey = self.crypt_keys.get(self.name, prefix='/pubkey/')
if not self._pubkey: self._pubkey = b64decode(self.load_qr.get(self.name, prefix='/pubkey/').encode())
return self._pubkey
def keychain(self,look_for=KEYMAKER_DEFAULT_ALL_KEY_NAMES):
keys = {'pubkey':self.pubkey}
uri = self.uri_id
# get from cache
for keyname in look_for:
key = self.crypt_keys.get(uri,prefix=f'/{keyname}/')
if key:
keys[keyname]=key
# try to assemble
keys = self.assemble(self.assemble(keys))
return keys
@property
def pubkey(self):
if not self._pubkey: self._pubkey = self.crypt_keys.get(self.name, prefix='/pubkey/')
if not self._pubkey: self._pubkey = b64decode(self.load_qr.get(self.name, prefix='/pubkey/').encode())
return self._pubkey
@property
def privkey(self): return self.keychain()['privkey']
@property
def adminkey(self): return self.keychain()['adminkey']
def load_qr(self,name):
# try to load?
contact_fnfn = os.path.join(PATH_QRCODES,name+'.png')
print(contact_fnfn,os.path.exists(contact_fnfn))
if not os.path.exists(contact_fnfn): return
# with open(contact_fnfn,'rb') as f: dat=f.read()
from pyzbar.pyzbar import decode
from PIL import Image
return decode(Image.open(contact_fnfn))[0].data
@property
def uri_id(self):
if not hasattr(self,'_uri_id') or not self._uri_id:
# try to load?
contact_fnfn = os.path.join(PATH_QRCODES,self.name+'.png')
print(contact_fnfn,os.path.exists(contact_fnfn))
if not os.path.exists(contact_fnfn): return
# with open(contact_fnfn,'rb') as f: dat=f.read()
from pyzbar.pyzbar import decode
from PIL import Image
self._uri_id = uri_id = decode(Image.open(contact_fnfn))[0].data
self._uri_id = b64encode(self.pubkey)
return self._uri_id
@ -343,45 +380,45 @@ class Keymaker(Logger):
return SCellSeal(key=str_or_key_or_cell)
def keychain(self,
passphrase=DEBUG_DEFAULT_PASSPHRASE,
extra_keys={},
keys_to_gen=KEYMAKER_DEFAULT_KEYS_TO_GEN,
uri_id=None,
**kwargs):
# assemble as many keys as we can!
self.log(f'''keychain(
passphrase={passphrase},
extra_keys={extra_keys},
keys_to_gen={keys_to_gen},
uri_id={uri_id},
**kwargs = {kwargs}
)''')
if not uri_id: uri_id = self.uri_id
if not uri_id and not self.uri_id:
raise KomradeException('Need URI id to complete finding of keys!')
self.log('getting keychain for uri ID:',uri_id)
# if not force and hasattr(self,'_keychain') and self._keychain: return self._keychain
if passphrase: self.passphrase=passphrase
# start off keychain
_keychain = {**extra_keys, **self._keychain}
self.log('_keychain at start of keychain() =',_keychain)
# def keychain(self,
# passphrase=DEBUG_DEFAULT_PASSPHRASE,
# extra_keys={},
# keys_to_gen=KEYMAKER_DEFAULT_KEYS_TO_GEN,
# uri_id=None,
# **kwargs):
# # assemble as many keys as we can!
# self.log(f'''keychain(
# passphrase={passphrase},
# extra_keys={extra_keys},
# keys_to_gen={keys_to_gen},
# uri_id={uri_id},
# **kwargs = {kwargs}
# )''')
# if not uri_id: uri_id = self.uri_id
# if not uri_id and not self.uri_id:
# raise KomradeException('Need URI id to complete finding of keys!')
# self.log('getting keychain for uri ID:',uri_id)
# # if not force and hasattr(self,'_keychain') and self._keychain: return self._keychain
# if passphrase: self.passphrase=passphrase
# # start off keychain
# _keychain = {**extra_keys, **self._keychain}
# self.log('_keychain at start of keychain() =',_keychain)
# find
for keyname in keys_to_gen:
if keyname in _keychain and _keychain[keyname]: continue
# self.log('??',keyname,keyname in self._keychain,'...')
newkey = self.crypt_keys.get(uri_id,prefix=f'/{keyname}/')
if newkey: _keychain[keyname] = newkey
# # find
# for keyname in keys_to_gen:
# if keyname in _keychain and _keychain[keyname]: continue
# # self.log('??',keyname,keyname in self._keychain,'...')
# newkey = self.crypt_keys.get(uri_id,prefix=f'/{keyname}/')
# if newkey: _keychain[keyname] = newkey
# return
_keychain = self.assemble(_keychain)
self._keychain = _keychain
return _keychain
# # return
# _keychain = self.assemble(_keychain)
# self._keychain = _keychain
# return _keychain

@ -99,475 +99,16 @@ class Operator(Keymaker):
def write_to(self,another):
pass
def package_msg_to(self,msg,another):
msg = {
'_from_pub':self.pubkey,
'_from_name':self.name,
'_to_pub':another.pubkey,
'_to_name':another.name
'_msg':msg,
}
return self.encrypt_to_send(msg, self.privkey, another.pubkey)
# async def req(self,json_phone={},json_caller={},caller=None):
def ring_ring(self,
from_phone=None,
to_phone=None,
from_caller=None,
to_caller=None,
json_phone2phone={},
json_caller2phone={}, # (person) -> operator or operator -> (person)
json_caller2caller={}):
self.log(f"""
RING RING!
from_phone={from_phone}, to_phone={to_phone},
from_caller={from_caller}, to_caller={to_caller},
json_phone2phone={json_phone2phone},
json_caller2phone={json_caller2phone},
json_caller2caller={json_caller2caller},
""")
## defaults
unencr_header=b''
encrypted_message_from_telephone_to_op = b''
encrypted_message_from_caller_to_op = b''
encrypted_message_from_caller_to_caller = b''
print('uri phone',from_phone.uri_id)
from_phone_keychain = from_phone.keychain()
from_phone_pubkey_encr=from_phone_keychain.get('pubkey_encr')
from_phone_privkey=from_phone_keychain.get('privkey')
to_phone_keychain = to_phone.keychain()
to_phone_pubkey_decr=to_phone_keychain.get('pubkey_decr')
to_phone_pubkey=to_phone_keychain.get('pubkey')
self.log('from_phone',type(from_phone),'to_phone',type(to_phone))
self.log('from_phone_keychain',from_phone_keychain)
self.log('to_phone_keychain',to_phone_keychain)
### LAYERS OF ENCRYPTION:
# 1) unencr header
# Telephone sends half its and the operator's public keys
self.log('Layer 1: from_phone_pubkey_encr header:',from_phone_pubkey_encr)
self.log('Layer 1: to_phone_pubkey_decr header:',to_phone_pubkey_decr)
unencr_header = from_phone_pubkey_encr + BSEP2 + to_phone_pubkey_decr
self.log('Layer 1: Unencrypted header:',unencr_header)
## Encrypt level 1: from Phone to Op
if json_phone2phone:
encrypted_message_from_telephone_to_op = self.encrypt_to_send(
msg_json = json_phone2phone,
from_privkey = from_phone_privkey,
to_pubkey = to_phone_pubkey
)
self.log('Layer 2: Phone 2 op:',encrypted_message_from_telephone_to_op)
## Level 2: from Caller to Op
if json_caller2phone and from_caller:
encrypted_message_from_caller_to_op = self.encrypt_to_send(
msg_json = json_caller2phone,
from_privkey = from_caller.keychain().get('privkey'),
to_pubkey = to_phone_pubkey
)
self.log('Layer 3: Caller 2 op:',encrypted_message_from_telephone_to_op)
# 2) Level 3: from Caller to Caller
if json_caller2caller and from_caller and to_caller:
encrypted_message_from_caller_to_caller = self.encrypt_to_send(
msg_json = json_caller2caller,
from_privkey = from_caller.keychain().get('privkey'),
to_pubkey = to_caller.keychain().get('pubkey')
)
self.log('Layer 3: Caller 2 Caller:',encrypted_message_from_telephone_to_op)
MSG_PIECES = [
unencr_header,
encrypted_message_from_telephone_to_op,
encrypted_message_from_caller_to_op,
encrypted_message_from_caller_to_caller
]
self.log(b'\n ~~~ \n'.join(MSG_PIECES))
MSG = BSEP.join(MSG_PIECES)
self.log('MSG',MSG)
MSG_b64 = b64encode(MSG)
self.log(b' ~~~ ring ring ~~~ rriing ~~~',MSG_b64)
msg_b64_str = MSG_b64.decode()
self.log(b' ~~~ rirrrrng ring ~~~~ ring ~~ rrrrriing ~~~',msg_b64_str)
## escape slashes
msg_b64_str_esc=msg_b64_str.replace('/','_')
return msg_b64_str_esc
def answer_phone(self,data_b64_str_esc, from_phone=None,to_phone=None):
## escape slashes
data_b64_s=data_b64_str_esc.replace('_','/')
self.log('Pronto!\n ... '+data_b64_s+' ...?')
# if not isBase64(data_b64_s):
# self.log('incoming data not b64')
# return OPERATOR_INTERCEPT_MESSAGE
# string -> b64 bytes
data_b64_b = data_b64_s.encode()
self.log('data_b64_b',data_b64_b)
# b64 -> raw bytes
data = b64decode(data_b64_b)
self.log('data',data)
# split
self.log('BSEP count',data.count(BSEP))
self.log(data.split(BSEP))
assert data.count(BSEP) == 3
(
unencr_header, # Tele.pubkey_encr|Op.pubkey_decr
data_encr_phone2phone,
data_encr_caller2phone,
data_encr_caller2caller
) = data.split(BSEP)
self.log('unencr_header',unencr_header)
self.log('data_encr_phone2phone',data_encr_phone2phone)
self.log('data_encr_caller2phone',data_encr_caller2phone)
self.log('data_encr_caller2caller',data_encr_caller2caller)
# set up
DATA = {}
# layer 1: unencr
# get other keys from halfkeys
# from_phone_pubkey,to_phone_pubkey = self.reassemble_nec_keys_using_header(unencr_header)
if not from_phone or not to_phone:
from_phone,to_phone = self.discover_which_phones_from_header(unencr_header)
self.log(f'I am {to_phone} and I am answering the phone! from {from_phone}')
# layer 2: I know I (either Telephone or Operator) am the recipient of this msg
from_phone_keychain = from_phone.keychain()
from_phone_pubkey=from_phone_keychain.get('pubkey')
to_phone_keychain = to_phone.keychain()
to_phone_privkey=to_phone_keychain.get('privkey')
self.log('data_encr_phone2phone',data_encr_phone2phone)
self.log('from_phone_pubkey',from_phone_pubkey,from_phone)
self.log('to_phone_privkey',to_phone_privkey,to_phone)
# 2) decrypt from phone
data_phone2phone = self.decrypt_from_send(
msg_encr=data_encr_phone2phone,
from_pubkey=from_phone_pubkey,
to_privkey=to_phone_privkey
)
self.log('data_phone2phone',data_phone2phone)
# 3) decrypt from caller
from_caller_pubkey = self.reassemble_necessary_keys_using_decr_phone_data(data_phone2phone)
data_caller2phone = self.decrypt_from_send(
msg_encr=data_encr_caller2phone,
from_pubkey=from_caller_pubkey,
to_privkey=to_phone_privkey
)
self.log('data_caller2phone',data_caller2phone)
# @TODO: 4) Caller 2 Caller
#to_caller_pubkey = self.reassemble_necessary_keys_using_decr_caller_data(data_caller2phone)
# send this to caller...
DATA = {}
dict_merge(DATA,data_phone2phone)
dict_merge(DATA,data_caller2phone)
# dict_merge(DATA,data_caller2caller)
# dict_merge(DATA,data_by_caller)
self.log('DATA!!!!!',DATA)
return DATA
# def encrypt_outgoing(self,
# data_from_sender1={},
# data_from_sender2={},
# privkey_from_sender1=None,
# privkey_from_sender2=None,
# to_pubkey=None,
# unencr_header=b''):
# # 2) encrypt to phone
# json_phone_encr = self.encrypt_to_send(data_from_sender1,from_phone_privkey,to_pubkey)
# self.log('json_phone_encr',json_phone_encr)
# # 3) to caller
# json_caller_encr = self.encrypt_to_send(json_caller,from_caller_privkey,to_pubkey)
# self.log()
# # return
# req_data_encr = unencr_header + BSEP + json_phone_encr + BSEP + json_caller_encr
# return req_data_encr
def reassemble_nec_keys_using_header(self,unencr_header):
assert unencr_header.count(BSEP2)==1
phone_pubkey_encr,op_pubkey_decr = unencr_header.split(BSEP2)
# get phone pubkey
new_phone_keychain = self.phone.keychain(extra_keys={'pubkey_encr':phone_pubkey_encr},force=True)
new_op_keychain = self.keychain(extra_keys={'pubkey_decr':op_pubkey_decr},force=True)
phone_pubkey = new_phone_keychain.get('pubkey')
op_pubkey = new_op_keychain.get('pubkey')
self.log('reassembled phone/op pubkeys:',phone_pubkey,op_pubkey)
return (phone_pubkey,op_pubkey)
def discover_which_phones_from_header(self,unencr_header):
assert unencr_header.count(BSEP2)==1
from_phone_pubkey_encr,to_phone_pubkey_decr = unencr_header.split(BSEP2)
phone_keychain = self.phone.keychain()
op_keychain = self.op.keychain()
op_pubkey_encr = op_keychain.get('pubkey_encr')
op_pubkey_decr = op_keychain.get('pubkey_decr')
phone_pubkey_encr = phone_keychain.get('pubkey_encr')
phone_pubkey_decr = phone_keychain.get('pubkey_encr')
self.log('phone_keychain',phone_keychain)
self.log('op_keychain',op_keychain)
self.log('op_pubkey_encr',op_pubkey_encr)
self.log('op_pubkey_decr',op_pubkey_decr)
self.log('phone_pubkey_encr',phone_pubkey_encr)
self.log('phone_pubkey_decr',phone_pubkey_decr)
# was this sent from Phone -> Op?
to_phone=None
from_phone=None
op_fits_as_to_phone=False
tele_fits_as_to_phone=False
op_fits_as_from_phone=False
tele_fits_as_from_phone=False
if op_pubkey_encr:
op_fits_as_to_phone = self.assemble_key(op_pubkey_encr,to_phone_pubkey_decr)
self.log('op_fits_as_to_phone',op_fits_as_to_phone)
return (self.phone,self.op)
if phone_pubkey_encr:
tele_fits_as_to_phone = self.assemble_key(phone_pubkey_encr,to_phone_pubkey_decr)
self.log('tele_fits_as_to_phone',tele_fits_as_to_phone)
return (self.op,self.phone)
if op_pubkey_decr:
op_fits_as_from_phone = self.assemble_key(from_phone_pubkey_encr, op_pubkey_decr)
self.log('op_fits_as_from_phone',op_fits_as_from_phone)
return (self.op,self.phone)
if phone_pubkey_decr:
tele_fits_as_from_phone = self.assemble_key(from_phone_pubkey_encr,phone_pubkey_decr)
self.log('tele_fits_as_from_phone',tele_fits_as_from_phone)
return (self.phone,self.op)
# # get phone pubkey
# new_phone_keychain = self.phone.keychain(extra_keys={'pubkey_encr':phone_pubkey_encr},force=True)
# new_op_keychain = self.keychain(extra_keys={'pubkey_decr':op_pubkey_decr},force=True)
# phone_pubkey = new_phone_keychain.get('pubkey')
# op_pubkey = new_op_keychain.get('pubkey')
# self.log('reassembled phone/op pubkeys:',phone_pubkey,op_pubkey)
# return (phone_pubkey,op_pubkey)
def reassemble_necessary_keys_using_decr_phone_data(self,decr_phone_data):
name=decr_phone_data.get('name')
if not name: return None
try:
caller = Caller(name)
self.log('got caller on phone',name,caller)
return caller.pubkey_
except:
return
### CREATE PRIME ENTITIES
def create_phonelines():
## CREATE OPERATOR
op = Operator(name=OPERATOR_NAME)
op_keys_to_keep_on_client = ['pubkey'] # kept on app, stored under name
op_keys_to_keep_on_3rdparty = ['privkey_decr'] # kept on .onion site
op_keys_to_keep_on_server = ['pubkey', # stored under name
'privkey_encr',
'adminkey_encr',
'adminkey_decr_encr',
'adminkey_decr_decr'] # kept on op server
## create phone
phone = Operator(name=TELEPHONE_NAME)
phone_keys_to_keep_on_client = ['pubkey','privkey_encr'] # kept on app; need both to init connection
phone_keys_to_keep_on_3rdparty = ['privkey_decr'] # dl by phone
phone_keys_to_keep_on_server = ['pubkey'] # kept on op server
# create keys for Op
op_res = op.forge_new_keys(
keys_to_save=op_keys_to_keep_on_server,
keys_to_return=op_keys_to_keep_on_client + op_keys_to_keep_on_3rdparty # on clients only
)
op_uri = op_res['uri_id']
op_decr_keys = op_res['_keychain']
print('op_uri',op_uri)
print('op_decr_keys',op_decr_keys)
# create keys for phone
phone_res = phone.forge_new_keys(
name=TELEPHONE_NAME,
keys_to_save=phone_keys_to_keep_on_server, # on server only
keys_to_return=phone_keys_to_keep_on_client + phone_keys_to_keep_on_3rdparty # on clients only
)
phone_uri = phone_res['uri_id']
phone_decr_keys = phone_res['_keychain']
print('phone_uri',phone_uri)
print('phone_decr_keys',phone_decr_keys)
# store URIs
# op.save_uri_as_qrcode(odir=PATH_OPERATOR_WEB_CONTACTS_DIR)
# op.save_uri_as_qrcode()
# phone.save_uri_as_qrcode(odir=PATH_OPERATOR_WEB_CONTACTS_DIR)
# phone.save_uri_as_qrcode()
## store remote keys
THIRD_PARTY_DICT = {OPERATOR_NAME:{}, TELEPHONE_NAME:{}}
for key in op_keys_to_keep_on_3rdparty:
if key in op_decr_keys:
THIRD_PARTY_DICT[OPERATOR_NAME][key]=op_decr_keys[key]
for key in phone_keys_to_keep_on_3rdparty:
if key in phone_decr_keys:
THIRD_PARTY_DICT[TELEPHONE_NAME][key]=phone_decr_keys[key]
print('THIRD_PARTY_DICT',THIRD_PARTY_DICT)
# store local keys
STORE_IN_APP = {OPERATOR_NAME:{}, TELEPHONE_NAME:{}}
for key in op_keys_to_keep_on_client:
if key in op_decr_keys:
STORE_IN_APP[OPERATOR_NAME][key]=op_decr_keys[key]
for key in phone_keys_to_keep_on_client:
if key in phone_decr_keys:
STORE_IN_APP[TELEPHONE_NAME][key]=phone_decr_keys[key]
print('STORE_IN_APP',STORE_IN_APP)
# package
STORE_IN_APP_pkg = package_for_transmission(STORE_IN_APP) #package_for_transmission(STORE_IN_APP[TELEPHONE_NAME]) + BSEP + package_for_transmission(STORE_IN_APP[OPERATOR_NAME])
THIRD_PARTY_DICT_pkg = package_for_transmission(THIRD_PARTY_DICT) #package_for_transmission(THIRD_PARTY_DICT[TELEPHONE_NAME]) + BSEP + package_for_transmission(THIRD_PARTY_DICT[OPERATOR_NAME])
print('THIRD_PARTY_DICT_pkg',THIRD_PARTY_DICT_pkg)
print('THIRD_PARTY_DICT_pkg',THIRD_PARTY_DICT_pkg)
# encrypt
omega_key = KomradeSymmetricKeyWithoutPassphrase()
STORE_IN_APP_encr = b64encode(omega_key.encrypt(STORE_IN_APP_pkg))
print('STORE_IN_APP_encr',STORE_IN_APP_encr)
THIRD_PARTY_totalpkg = b64encode(omega_key.data + BSEP + omega_key.encrypt(THIRD_PARTY_DICT_pkg))
print('THIRD_PARTY_totalpkg',THIRD_PARTY_totalpkg)
# save
with open(PATH_BUILTIN_KEYCHAIN,'wb') as of:
of.write(STORE_IN_APP_encr)
print('STORE_IN_APP_encr',STORE_IN_APP_encr)
with open(PATH_OPERATOR_WEB_KEYS_FILE,'wb') as of:
of.write(THIRD_PARTY_totalpkg)
print('THIRD_PARTY_DICT_encr',THIRD_PARTY_totalpkg)
def connect_phonelines():
# globals
global OMEGA_KEY,OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN
if OMEGA_KEY and OPERATOR_KEYCHAIN and TELEPHONE_KEYCHAIN:
return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN)
print('\n\n\n\nCONNECTING PHONELINES!\n\n\n\n')
# import
from komrade.backend.mazes import tor_request
from komrade.backend import PATH_OPERATOR_WEB_KEYS_URL
# load local keys
if not os.path.exists(PATH_BUILTIN_KEYCHAIN):
print('builtin keys not present??')
return
with open(PATH_BUILTIN_KEYCHAIN,'rb') as f:
local_builtin_keychain_encr = b64decode(f.read())
# load remote keys
print('??',PATH_OPERATOR_WEB_KEYS_URL)
r = komrade_request(PATH_OPERATOR_WEB_KEYS_URL)
if r.status_code!=200:
print('cannot authenticate the keymakers')
return
# unpack remote pkg
pkg = r.text
print('got from onion:',pkg)
pkg = b64decode(pkg)
print('got from onion:',pkg)
OMEGA_KEY_b,remote_builtin_keychain_encr = pkg.split(BSEP)
print('OMEGA_KEY_b',OMEGA_KEY_b)
print('remote_builtin_keychain_encr',remote_builtin_keychain_encr)
OMEGA_KEY = KomradeSymmetricKeyWithoutPassphrase(key=OMEGA_KEY_b)
print('loaded Omega',OMEGA_KEY)
# from komrade.utils import unpackage_from_transmission
remote_builtin_keychain = unpackage_from_transmission(OMEGA_KEY.decrypt(remote_builtin_keychain_encr))
print('remote_builtin_keychain',remote_builtin_keychain)
remote_builtin_keychain_phone_json,remote_builtin_keychain_op_json = remote_builtin_keychain[TELEPHONE_NAME],remote_builtin_keychain[OPERATOR_NAME]
print('remote_builtin_keychain_phone_json',remote_builtin_keychain_phone_json)
print('remote_builtin_keychain_op_json',remote_builtin_keychain_op_json)
# unpack local pkg
local_builtin_keychain = unpackage_from_transmission(OMEGA_KEY.decrypt(local_builtin_keychain_encr))
print('local_builtin_keychain',local_builtin_keychain)
local_builtin_keychain_phone_json,local_builtin_keychain_op_json = local_builtin_keychain[TELEPHONE_NAME],local_builtin_keychain[OPERATOR_NAME]
print('local_builtin_keychain_phone_json',local_builtin_keychain_phone_json)
print('local_builtin_keychain_op_json',local_builtin_keychain_op_json)
# set builtin keychains
TELEPHONE_KEYCHAIN={}
OPERATOR_KEYCHAIN={}
dict_merge(TELEPHONE_KEYCHAIN,local_builtin_keychain_phone_json)
dict_merge(OPERATOR_KEYCHAIN,local_builtin_keychain_op_json)
dict_merge(TELEPHONE_KEYCHAIN,remote_builtin_keychain_phone_json)
dict_merge(OPERATOR_KEYCHAIN,remote_builtin_keychain_op_json)
print('>>>> loaded OPERATOR_KEYCHAIN',OPERATOR_KEYCHAIN)
print('>>>> loaded TELEPHONE_KEYCHAIN',TELEPHONE_KEYCHAIN)
return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN)
def unpackage_msg_from(self,msg_encr_b,another):
return self.decrypt_from_send(msg_encr_b,anonther.pubkey,self.privkey)

@ -0,0 +1,90 @@
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 import *
class Person(Caller):
def call_person(self,person):
pass
def ring_ring(self,msg_unencr,whom_to_call):
# ring 1: encrypt caller2phone
msg_encr_caller2caller = self.package_msg_to(
msg_unencr,
whom_to_call
)
self.log('msg_encr_caller2caller',msg_encr_caller2caller)
# ring 2: use 'Caller' class to dial and get response
resp_msg_encr_caller2caller = super().ring_ring(
msg_encr_caller2caller
)
self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller)
# ring 3: decrypt and send back
resp_msg_unencr = self.unpackage_msg_from(
msg_encr_caller2caller,
whom_to_call
)
self.log('resp_msg_unencr',resp_msg_encr_caller2caller)
return resp_msg_unencr
def register(self):
# get needed metadata
if not name: name=self.name
if name is None:
name = input('\nWhat is the name for this account? ')
if passphrase is None:
passphrase = getpass.getpass('\nEnter a memborable password: ')
# if is_group is None:
# is_group = input('\nIs this a group account? [y/N]').strip().lower() == 'y'
# form request to operator
msg_to_op = {'_please':'forge_new_keys'}
# call and ask operator to register us
resp = self.ring_ring(
whom=self.op,
msg_unencr=msg_to_op
)
def get_new_keys(self, name = None, passphrase = DEBUG_DEFAULT_PASSPHRASE, is_group=None):
# get needed metadata
if not name: name=self.name
if name is None:
name = input('\nWhat is the name for this account? ')
if passphrase is None:
passphrase = getpass.getpass('\nEnter a memborable password: ')
# if is_group is None:
# is_group = input('\nIs this a group account? [y/N]').strip().lower() == 'y'
phone_res = self.phone.ring_ring(msg_to_op)
# URI id
uri_id = phone_res.get('uri_id')
returned_keys = phone_res.get('_keychain')
self.log('got URI from Op:',uri_id)
self.log('got returnd keys from Op:',returned_keys)
stop
# better have the right keys
assert set(KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_CLIENT) == set(returned_keys.keys())
# now save these keys!
saved_keys = self.save_keychain(name,returned_keys,uri_id=uri_id)
self.log('saved keys!',saved_keys)
# better have the right keys
# assert set(KEYMAKER_DEFAULT_KEYS_TO_SAVE) == set(saved_keys.keys())
# success!
self.log('yay!!!!')
return saved_keys

@ -0,0 +1,173 @@
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 komrade.backend.keymaker import *
from komrade.backend.mazes import *
from komrade.backend.switchboard import *
### CREATE PRIME ENTITIES
def create_phonelines():
## CREATE OPERATOR
op = Operator(name=OPERATOR_NAME)
op_keys_to_keep_on_client = ['pubkey'] # kept on app, stored under name
op_keys_to_keep_on_3rdparty = ['privkey_decr'] # kept on .onion site
op_keys_to_keep_on_server = ['pubkey', # stored under name
'privkey_encr',
'adminkey_encr',
'adminkey_decr_encr',
'adminkey_decr_decr'] # kept on op server
## create phone
phone = Operator(name=TELEPHONE_NAME)
phone_keys_to_keep_on_client = ['pubkey','privkey_encr'] # kept on app; need both to init connection
phone_keys_to_keep_on_3rdparty = ['privkey_decr'] # dl by phone
phone_keys_to_keep_on_server = ['pubkey'] # kept on op server
# create keys for Op
op_res = op.forge_new_keys(
keys_to_save=op_keys_to_keep_on_server,
keys_to_return=op_keys_to_keep_on_client + op_keys_to_keep_on_3rdparty # on clients only
)
op_uri = op_res['uri_id']
op_decr_keys = op_res['_keychain']
print('op_uri',op_uri)
print('op_decr_keys',op_decr_keys)
# create keys for phone
phone_res = phone.forge_new_keys(
name=TELEPHONE_NAME,
keys_to_save=phone_keys_to_keep_on_server, # on server only
keys_to_return=phone_keys_to_keep_on_client + phone_keys_to_keep_on_3rdparty # on clients only
)
phone_uri = phone_res['uri_id']
phone_decr_keys = phone_res['_keychain']
print('phone_uri',phone_uri)
print('phone_decr_keys',phone_decr_keys)
# store URIs
# op.save_uri_as_qrcode(odir=PATH_OPERATOR_WEB_CONTACTS_DIR)
# op.save_uri_as_qrcode()
# phone.save_uri_as_qrcode(odir=PATH_OPERATOR_WEB_CONTACTS_DIR)
# phone.save_uri_as_qrcode()
## store remote keys
THIRD_PARTY_DICT = {OPERATOR_NAME:{}, TELEPHONE_NAME:{}}
for key in op_keys_to_keep_on_3rdparty:
if key in op_decr_keys:
THIRD_PARTY_DICT[OPERATOR_NAME][key]=op_decr_keys[key]
for key in phone_keys_to_keep_on_3rdparty:
if key in phone_decr_keys:
THIRD_PARTY_DICT[TELEPHONE_NAME][key]=phone_decr_keys[key]
print('THIRD_PARTY_DICT',THIRD_PARTY_DICT)
# store local keys
STORE_IN_APP = {OPERATOR_NAME:{}, TELEPHONE_NAME:{}}
for key in op_keys_to_keep_on_client:
if key in op_decr_keys:
STORE_IN_APP[OPERATOR_NAME][key]=op_decr_keys[key]
for key in phone_keys_to_keep_on_client:
if key in phone_decr_keys:
STORE_IN_APP[TELEPHONE_NAME][key]=phone_decr_keys[key]
print('STORE_IN_APP',STORE_IN_APP)
# package
STORE_IN_APP_pkg = package_for_transmission(STORE_IN_APP) #package_for_transmission(STORE_IN_APP[TELEPHONE_NAME]) + BSEP + package_for_transmission(STORE_IN_APP[OPERATOR_NAME])
THIRD_PARTY_DICT_pkg = package_for_transmission(THIRD_PARTY_DICT) #package_for_transmission(THIRD_PARTY_DICT[TELEPHONE_NAME]) + BSEP + package_for_transmission(THIRD_PARTY_DICT[OPERATOR_NAME])
print('THIRD_PARTY_DICT_pkg',THIRD_PARTY_DICT_pkg)
print('THIRD_PARTY_DICT_pkg',THIRD_PARTY_DICT_pkg)
# encrypt
omega_key = KomradeSymmetricKeyWithoutPassphrase()
STORE_IN_APP_encr = b64encode(omega_key.encrypt(STORE_IN_APP_pkg))
print('STORE_IN_APP_encr',STORE_IN_APP_encr)
THIRD_PARTY_totalpkg = b64encode(omega_key.data + BSEP + omega_key.encrypt(THIRD_PARTY_DICT_pkg))
print('THIRD_PARTY_totalpkg',THIRD_PARTY_totalpkg)
# save
with open(PATH_BUILTIN_KEYCHAIN,'wb') as of:
of.write(STORE_IN_APP_encr)
print('STORE_IN_APP_encr',STORE_IN_APP_encr)
with open(PATH_OPERATOR_WEB_KEYS_FILE,'wb') as of:
of.write(THIRD_PARTY_totalpkg)
print('THIRD_PARTY_DICT_encr',THIRD_PARTY_totalpkg)
def connect_phonelines():
# globals
global OMEGA_KEY,OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN
if OMEGA_KEY and OPERATOR_KEYCHAIN and TELEPHONE_KEYCHAIN:
return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN)
print('\n\n\n\nCONNECTING PHONELINES!\n\n\n\n')
# import
from komrade.backend.mazes import tor_request
from komrade.backend import PATH_OPERATOR_WEB_KEYS_URL
# load local keys
if not os.path.exists(PATH_BUILTIN_KEYCHAIN):
print('builtin keys not present??')
return
with open(PATH_BUILTIN_KEYCHAIN,'rb') as f:
local_builtin_keychain_encr = b64decode(f.read())
# load remote keys
print('??',PATH_OPERATOR_WEB_KEYS_URL)
r = komrade_request(PATH_OPERATOR_WEB_KEYS_URL)
if r.status_code!=200:
print('cannot authenticate the keymakers')
return
# unpack remote pkg
pkg = r.text
print('got from onion:',pkg)
pkg = b64decode(pkg)
print('got from onion:',pkg)
OMEGA_KEY_b,remote_builtin_keychain_encr = pkg.split(BSEP)
print('OMEGA_KEY_b',OMEGA_KEY_b)
print('remote_builtin_keychain_encr',remote_builtin_keychain_encr)
OMEGA_KEY = KomradeSymmetricKeyWithoutPassphrase(key=OMEGA_KEY_b)
print('loaded Omega',OMEGA_KEY)
# from komrade.utils import unpackage_from_transmission
remote_builtin_keychain = unpackage_from_transmission(OMEGA_KEY.decrypt(remote_builtin_keychain_encr))
print('remote_builtin_keychain',remote_builtin_keychain)
remote_builtin_keychain_phone_json,remote_builtin_keychain_op_json = remote_builtin_keychain[TELEPHONE_NAME],remote_builtin_keychain[OPERATOR_NAME]
print('remote_builtin_keychain_phone_json',remote_builtin_keychain_phone_json)
print('remote_builtin_keychain_op_json',remote_builtin_keychain_op_json)
# unpack local pkg
local_builtin_keychain = unpackage_from_transmission(OMEGA_KEY.decrypt(local_builtin_keychain_encr))
print('local_builtin_keychain',local_builtin_keychain)
local_builtin_keychain_phone_json,local_builtin_keychain_op_json = local_builtin_keychain[TELEPHONE_NAME],local_builtin_keychain[OPERATOR_NAME]
print('local_builtin_keychain_phone_json',local_builtin_keychain_phone_json)
print('local_builtin_keychain_op_json',local_builtin_keychain_op_json)
# set builtin keychains
TELEPHONE_KEYCHAIN={}
OPERATOR_KEYCHAIN={}
dict_merge(TELEPHONE_KEYCHAIN,local_builtin_keychain_phone_json)
dict_merge(OPERATOR_KEYCHAIN,local_builtin_keychain_op_json)
dict_merge(TELEPHONE_KEYCHAIN,remote_builtin_keychain_phone_json)
dict_merge(OPERATOR_KEYCHAIN,remote_builtin_keychain_op_json)
print('>>>> loaded OPERATOR_KEYCHAIN',OPERATOR_KEYCHAIN)
print('>>>> loaded TELEPHONE_KEYCHAIN',TELEPHONE_KEYCHAIN)
return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN)

@ -7,56 +7,9 @@ from komrade.backend import *
from flask import Flask, request, jsonify
from flask_classful import FlaskView
# PATH_OPERATOR_WEB_KEYS_URI = hashish(b'keys')
# PATH_OPERATOR_WEB_KEYS_FILE = f'/home/ryan/www/website-komrade/.builtin.keys'
# PATH_OPERATOR_WEB_KEYS_URL = f'http://{KOMRADE_ONION}/.builtin.keys'
# print(PATH_OPERATOR_WEB_KEYS_URL)
OPERATOR = None
TELEPHONE = None
from flask_classful import FlaskView, route
class TheSwitchboard(FlaskView, Logger):
default_methods = ['GET']
excluded_methods = ['phone','op','send']
@route('/.builtin.keys/')
def keys(self):
if not os.path.exists(PATH_OPERATOR_WEB_KEYS_FILE):
self.log('no keys file exists!',PATH_OPERATOR_WEB_KEYS_FILE)
return OPERATOR_INTERCEPT_MESSAGE
with open(PATH_OPERATOR_WEB_KEYS_FILE,'rb') as f:
return f.read()
@property
def phone(self):
global TELEPHONE
from komrade.backend.the_telephone import TheTelephone
if not TELEPHONE: TELEPHONE=TheTelephone()
return TELEPHONE
@property
def op(self):
global OPERATOR
from komrade.backend.the_operator import TheOperator
if not OPERATOR: OPERATOR=TheOperator()
return OPERATOR
def send(self,res):
return res
def route(self,msg):
# give to The Operator
# try:
self.log('Success! your message was: '+str(msg))
res = self.op.recv(msg)
self.log('Your return result should be:',res)
return self.send(res)
# except AssertionError as e:
# self.log('got exception!!',e)
return OPERATOR_INTERCEPT_MESSAGE
def get(self,msg):
self.log('Incoming call!:',msg)
@ -65,7 +18,10 @@ class TheSwitchboard(FlaskView, Logger):
return OPERATOR_INTERCEPT_MESSAGE
# unenescape
msg = msg.replace('_','/')
return self.route(msg)
str_msg_from_op = self.op.route(msg)
str_msg_from_op = msg.replace('_','/')
self.log('Switchboard got msg back from Operator:',str_msg_from_op)
return str_msg_from_op
def run_forever(port='8080'):
global OPERATOR,TELEPHONE,TELEPHONE_KEYCHAIN,OPERATOR_KEYCHAIN

@ -59,32 +59,19 @@ class TheOperator(Operator):
return self.send(encr_msg_to_send)
def recv(self,data):
# decrypt
self.log('recv 1: got',data)
# answer the phone!
data_in = self.answer_phone(data, from_phone=self.phone, to_phone=self)
self.log('recv 2: answer_phone gave me',data_in)
# route
return self.route(data_in)
# self.log('recv 3: route gave me',encr_result)
# # send
# return self.send(encr_result)
def send(self,encr_data_b):
self.log(type(encr_data_b),encr_data_b,'sending!')
return encr_data_b
def route(self, data):
# route incoming call from the switchboard
res=None
route = data.get('_route')
route = data.get('_please')
if not route: return OPERATOR_INTERCEPT_MESSAGE
del data['_route']
del data['_please']
if route == 'forge_new_keys':
return self.forge_new_keys(**data)

@ -36,40 +36,44 @@ class TheTelephone(Operator):
self.log("DIALING THE OPERATOR:",URL)
ringring=komrade_request(URL)
if ringring.status_code==200:
um_yes_hello = ringring.text
return self.answer_phone(um_yes_hello,
from_phone=self.op,
to_phone=self
)
# response back from Operator!
encr_str_response_from_op = ringring.text
self.log('encr_str_response_from_op',encr_str_response_from_op)
return encr_str_response_from_op.encode()
else:
self.log('!! error in request',ringring.status_code,ringring.text)
return None
def ring_ring(self,
from_caller=None,
to_caller=None,
json_phone2phone={},
json_caller2phone={}, # (person) -> operator or operator -> (person)
json_caller2caller={}):
encr_msg_to_send = super().ring_ring(
from_phone=self,
to_phone=self.op,
from_caller=from_caller,
to_caller=to_caller,
json_phone2phone=json_phone2phone,
json_caller2phone=json_caller2phone, # (person) -> operator
json_caller2caller=json_caller2caller)
def ring_ring(self,msg_encr_caller2caller_caller2phone):
# ring 1: encrypt
msg_encr_caller2caller_caller2phone_phone2phone = self.package_msg_to(
msg_encr_caller2caller,
self.op
)
self.log('final form of encr msg!',msg_encr_caller2caller_caller2phone_phone2phone)
# ring 2: dial and get response
msg_encr_caller2caller_caller2phone_phone2phone = self.send_and_receive(msg_encr_caller2caller_phone2phone)
msg_encr_caller2caller_caller2phone_phone2phone: return
# ring 3: decrypt
msg_encr_caller2caller_caller2phone = self.unpackage_msg_from(
msg_encr_caller2caller_caller2phone_phone2phone,
self.op
)
return msg_encr_caller2caller_caller2phone
return self.send_and_receive(encr_msg_to_send)
def test_call():
caller = Caller('marx33') #Caller('marx')
# caller.boot(create=True)
# print(caller.keychain())
# phone = TheTelephone()
# req_json = {'_route':'forge_new_keys','name':name, 'pubkey_is_public':pubkey_is_public}}
# req_json = {'_please':'forge_new_keys','name':name, 'pubkey_is_public':pubkey_is_public}}
# req_json_s = jsonify(req_json)
# res = phone.req({'forge_new_keys':{'name':'marx', 'pubkey_is_public':True}})
# print(res)

@ -122,6 +122,9 @@ KEYMAKER_DEFAULT_KEY_TYPES = {
'privkey_decr_encr':ENCRYPTED_KEY,
'adminkey_decr_encr':ENCRYPTED_KEY
}
KEYMAKER_DEFAULT_ALL_KEY_NAMES = sorted(list(KEYMAKER_DEFAULT_KEY_TYPES.keys()), key=lambda x: x.count('_'))
WHY_MSG = 'Forge the password of memory: '

Loading…
Cancel
Save