operator-time
quadrismegistus 4 years ago
parent caee9fc35c
commit 285557f5ff

2
.gitignore vendored

@ -7,3 +7,5 @@ dbm.*
lib lib
*.venv *.venv
*.key *.key
*.key.*
.op.*

@ -1,5 +1,11 @@
""" from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair
Code for Caller to interact with Operator from pythemis.smessage import SMessage, ssign, sverify
""" from pythemis.skeygen import GenerateSymmetricKey
from pythemis.scell import SCellSeal
from pythemis.exception import ThemisError
class Caller(object):
def create_keys(self,name):
#
pass pass

@ -0,0 +1,96 @@
"""
Storage for both keys and data
"""
from simplekv.fs import FilesystemStore
from simplekv.memory.redisstore import RedisStore
import redis
import hashlib,os
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 zlib
class Crypt(object):
def log(self,*x): print(*x)
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 hash(self,binary_data):
return hashlib.sha256(binary_data).hexdigest()
# return zlib.adler32(binary_data)
def force_binary(self,k_b):
if type(k_b)==str: k_b=k_b.encode()
if type(k_b)!=bytes: k_b=str(k_b).encode()
return k_b
def package_key(self,k):
k_b = self.force_binary(k)
# k_b = self.cell.encrypt(k_b)
k_b = self.hash(k_b)
return k_b
def package_val(self,k):
k_b = self.force_binary(k)
k_b = self.cell.encrypt(k_b)
return k_b
def unpackage_val(self,k_b):
try:
return self.cell.decrypt(k_b)
except ThemisError:
return None
def set(self,k,v):
self.log('set() k -->',k)
k_b=self.package_key(k)
self.log('set() k_b -->',k_b)
self.log('set() v -->',v)
v_b=self.package_val(v)
self.log('set() v_b -->',v_b)
return self.store.put(k_b,v_b)
def get(self,k):
self.log('get() k -->',k)
k_b=self.package_key(k)
self.log('get() k_b -->',k_b)
v=self.store.get(k_b)
self.log('get() v -->',v)
v_b=self.unpackage_val(v)
self.log('get() v_b -->',v_b)
return v_b
class KeyCrypt(Crypt):
def __init__(self):
return super().__init__(name=PATH_CRYPT_KEYS.replace('.','_'))
class DataCrypt(Crypt):
def __init__(self):
return super().__init__(name=PATH_CRYPT_DATA.replace('.','_'))
if __name__=='__main__':
crypt = Crypt('testt')
print(crypt.set('hellothere',b'ryan'))
# print(crypt.get(b'hello there'))

@ -1,5 +0,0 @@
"""
Storage for both keys and data
"""
pass

@ -2,84 +2,230 @@
There is only one operator! There is only one operator!
Running on node prime. Running on node prime.
""" """
import os import os,sys
from flask import Flask from flask import Flask
from flask import request from flask_classful import FlaskView
import asyncio
from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair
from pythemis.smessage import SMessage, ssign, sverify from pythemis.smessage import SMessage, ssign, sverify
from pythemis.skeygen import GenerateSymmetricKey
from pythemis.scell import SCellSeal
from pythemis.exception import ThemisError from pythemis.exception import ThemisError
from base64 import b64encode,b64decode from base64 import b64encode,b64decode
BSEP=b'||||||||||' import getpass
BSEP2=b'@@@@@@@@@@' PATH_HERE = os.path.dirname(__file__)
BSEP3=b'##########' sys.path.append(PATH_HERE)
from crypt import *
HOME_OPERATOR = os.path.abspath(__file__) # paths
PATH_DB_KEYS = os.path.join(HOME_OPERATOR, '.keydb') PATH_KOMRADE = os.path.abspath(os.path.join(os.path.expanduser('~'),'.komrade'))
PATH_OPERATOR = os.path.join(PATH_KOMRADE,'.operator')
PATH_OPERATOR_PUBKEY = os.path.join(PATH_OPERATOR,'.op.key.pub.encr')
PATH_OPERATOR_PRIVKEY = os.path.join(PATH_OPERATOR,'.op.key.priv.encr')
PATH_CRYPT_KEYS = os.path.join(PATH_OPERATOR,'.op.db.keys.crypt')
PATH_CRYPT_DATA = os.path.join(PATH_OPERATOR,'.op.db.data.encr')
# init req paths
if not os.path.exists(PATH_OPERATOR): os.makedirs(PATH_OPERATOR)
keyhome = os.path.join(os.path.expanduser('~'),'.komrade','.keyserver')
if not os.path.exists(keyhome): os.makedirs(keyhome)
keyserver = 'komrade.app'
keyserver_port = 5566
app = Flask(__name__)
async def init(): class TheOperator(object):
from api import Api """
api = Api() The operator.
# keyserver = await api.personate('keyserver') """
def __init__(self):
"""
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()
# load keys
self.pubkey,self.privkey = self.get_keys()
# 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):
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)
return (pubkey_encr,privkey_encr)
def get_keys(self):
pubkey_encr,privkey_encr = self.get_encypted_keys()
# decrypt according to password of memory
try:
pubkey = self.cell.decrypt(pubkey_encr)
privkey = self.cell.decrypt(privkey_encr)
except ThemisError:
self.log('\nERROR: Incorrect password of memory! Shutting down.')
exit()
# self.log(f'decrypted keys to:\npubkey={pubkey}\nprivkey={privkey}')
return (pubkey,privkey)
def check_keys(self):
self.log('checking for keys...')
have_keys = (os.path.exists(PATH_OPERATOR_PUBKEY) and os.path.exists(PATH_OPERATOR_PRIVKEY))
self.log('have_keys =',have_keys)
return have_keys
def forge_keys(self):
self.log('forging keys...')
# Initialize asymmetric keys
keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC)
privkey = keypair.export_private_key()
pubkey = keypair.export_public_key()
# Also create a symmetric passworded key!
## It is up to you, forger of the keys, to remember this:
## otherwise the whole system topples!
# Encrypt private public keys
privkey = self.cell.encrypt(privkey)
pubkey = self.cell.encrypt(pubkey)
# Save
with open(PATH_OPERATOR_PUBKEY,'wb') as of: of.write(pubkey)
with open(PATH_OPERATOR_PRIVKEY,'wb') as of: of.write(privkey)
self.log('Keys forged!')
####
# Key CRUD
####
def create_keys(self,name):
# Create public and private keys
keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC) keypair = GenerateKeyPair(KEY_PAIR_TYPE.EC)
privkey = keypair.export_private_key() privkey = keypair.export_private_key()
pubkey = keypair.export_public_key() pubkey = keypair.export_public_key()
print('pubkey:',pubkey) # Create permission keys
with open('.keyserver.loc','wb') as of: of.write(b64encode(pubkey)) permkey_find = GenerateSymmetricKey()
with open(os.path.join(keyhome,'.keyserver.key'),'wb') as of: of.write(b64encode(privkey)) permkey_read = GenerateSymmetricKey()
permkey_admin = GenerateSymmetricKey()
## load pubkey permkey_adminX = GenerateSymmetricKey()
PATH_PUBKEY = os.path.join(os.path.dirname(__file__),'.keyserver.loc')
PATH_PRIVKEY = os.path.join(keyhome,'.keyserver.key') # (1) Encrypted pubkey
if not os.path.exists(PATH_PRIVKEY) or not os.path.exists(PATH_PUBKEY): pubkey_decr = permkey_find
asyncio.run(init()) pubkey_encr = SCellSeal(key=pubkey_decr).encrypt(pubkey)
with open(PATH_PUBKEY) as f: # (2) Encnrypted priv key
PUBKEY_b64 = f.read() privkey_decr = permkey_read
PUBKEY = b64decode(PUBKEY_b64) privkey_encr = SCellSeal(key=privkey_decr).encrypt(privkey)
with open(PATH_PRIVKEY) as f:
PRIVKEY_b64 = f.read() # (3) Encrypted admin key?
PRIVKEY = b64decode(PRIVKEY_b64) adminkey_decr = permkey_adminX
adminkey_encr = SCellSeal(key=adminkey_decr).encrypt(permkey_admin)
@app.route('/pub')
def pubkey():
return PUBKEY_b64
@app.route('/add/<name>',methods=['POST'])
def add(name): self.log(f'priv_key saved to {self.key_path_priv}')
key_fn = os.path.join(keyhome,name+'.loc') with open(self.key_path_priv, "wb") as private_key_file:
if not os.path.exists(key_fn): private_key_file.write(self.privkey_b64)
with open(key_fn,'wb') as of:
pubkey,signed_pubkey=request.data.split(BSEP) with open(self.key_path_pub, "wb") as public_key_file:
server_signed_pubkey = b64encode(ssign(PRIVKEY,pubkey)) # save SIGNED public key
package = pubkey + BSEP + signed_pubkey + BSEP + server_signed_pubkey public_key_file.write(self.pubkey_b64)
package_b64 = b64encode(package)
print('add package -->',package) with open(self.key_path_pub_enc,'wb') as signed_public_key_file:
print('add package_b64 -->',package_b64) # self.log('encrypted_pubkey_b64 -->',self.encrypted_pubkey_b64)
of.write(package_b64) pubkey_b64 = b64encode(self.pubkey)
return package_b64 self.log('pubkey',self.pubkey)
return None self.log('pubkey_b64',pubkey_b64)
@app.route('/get/<name>') encrypted_pubkey_b64 = self.encrypt(pubkey_b64, pubkey_b64, KOMRADE_PRIV_KEY)
def get(name): self.log('encrypted_pubkey_b64 -->',encrypted_pubkey_b64)
key_fn = os.path.join(keyhome,name+'.loc')
if os.path.exists(key_fn): signed_public_key_file.write(encrypted_pubkey_b64)
with open(key_fn,'rb') as f:
signed_key=f.read()
return signed_key
return b'' def create_permissions_file(self):
pass
class TheOperatorView(FlaskView):
route_prefix = '/'
def index(self):
print('hello')
return "<br>".join(quotes)
def something(self):
return 'something'
## Main
def run_forever():
app = Flask(__name__)
TheOperator.register(app, route_base='/op/', route_prefix=None)
app.run(debug=True)
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='0.0.0.0',port=keyserver_port) #run_forever()
# asyncio.run(init())
op = TheOperator()
print(op.crypt_keys.set('aaaa','1111'))
print(op.crypt_keys.get('aaaa'))

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save