reworking PM system before migration to plugin and updating blockapi to encryption format

master
Kevin Froman 2018-07-13 16:02:41 -05:00
parent 4ba1bd3513
commit 40255538da
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
5 changed files with 44 additions and 18 deletions

View File

@ -25,7 +25,6 @@ from defusedxml import minidom
class OnionrCommunicatorDaemon: class OnionrCommunicatorDaemon:
def __init__(self, debug, developmentMode): def __init__(self, debug, developmentMode):
logger.warn('New (unstable) communicator is being used.')
# list of timer instances # list of timer instances
self.timers = [] self.timers = []
@ -57,6 +56,9 @@ class OnionrCommunicatorDaemon:
# list of new blocks to download, added to when new block lists are fetched from peers # list of new blocks to download, added to when new block lists are fetched from peers
self.blockQueue = [] self.blockQueue = []
# list of blocks currently downloading, avoid s
self.currentDownloading = []
# Clear the daemon queue for any dead messages # Clear the daemon queue for any dead messages
if os.path.exists(self._core.queueDB): if os.path.exists(self._core.queueDB):
self._core.clearDaemonQueue() self._core.clearDaemonQueue()
@ -154,6 +156,10 @@ class OnionrCommunicatorDaemon:
def getBlocks(self): def getBlocks(self):
'''download new blocks in queue''' '''download new blocks in queue'''
for blockHash in self.blockQueue: for blockHash in self.blockQueue:
if blockHash in self.currentDownloading:
logger.debug('ALREADY DOWNLOADING ' + blockHash)
continue
self.currentDownloading.append(blockHash)
logger.info("Attempting to download %s..." % blockHash) logger.info("Attempting to download %s..." % blockHash)
content = self.peerAction(self.pickOnlinePeer(), 'getData', data=blockHash) # block content from random peer (includes metadata) content = self.peerAction(self.pickOnlinePeer(), 'getData', data=blockHash) # block content from random peer (includes metadata)
if content != False: if content != False:
@ -171,7 +177,7 @@ class OnionrCommunicatorDaemon:
content = content.decode() # decode here because sha3Hash needs bytes above content = content.decode() # decode here because sha3Hash needs bytes above
metas = self._core._utils.getBlockMetadataFromData(content) # returns tuple(metadata, meta), meta is also in metadata metas = self._core._utils.getBlockMetadataFromData(content) # returns tuple(metadata, meta), meta is also in metadata
metadata = metas[0] metadata = metas[0]
meta = metas[1] #meta = metas[1]
if self._core._utils.validateMetadata(metadata): # check if metadata is valid if self._core._utils.validateMetadata(metadata): # check if metadata is valid
if self._core._crypto.verifyPow(content): # check if POW is enough/correct if self._core._crypto.verifyPow(content): # check if POW is enough/correct
logger.info('Block passed proof, saving.') logger.info('Block passed proof, saving.')
@ -191,6 +197,7 @@ class OnionrCommunicatorDaemon:
pass pass
logger.warn('Block hash validation failed for ' + blockHash + ' got ' + tempHash) logger.warn('Block hash validation failed for ' + blockHash + ' got ' + tempHash)
self.blockQueue.remove(blockHash) # remove from block queue both if success or false self.blockQueue.remove(blockHash) # remove from block queue both if success or false
self.currentDownloading.remove(blockHash)
self.decrementThreadCount('getBlocks') self.decrementThreadCount('getBlocks')
return return

View File

@ -727,15 +727,15 @@ class Core:
if encryptType == 'sym': if encryptType == 'sym':
if len(symKey) < self.requirements.passwordLength: if len(symKey) < self.requirements.passwordLength:
raise onionrexceptions.SecurityError('Weak encryption key') raise onionrexceptions.SecurityError('Weak encryption key')
jsonMeta = self._crypto.symmetricEncrypt(jsonMeta, key=symKey, returnEncoded=True) jsonMeta = self._crypto.symmetricEncrypt(jsonMeta, key=symKey, returnEncoded=True).decode()
data = self._crypto.symmetricEncrypt(data, key=symKey, returnEncoded=True) data = self._crypto.symmetricEncrypt(data, key=symKey, returnEncoded=True).decode()
signature = self._crypto.symmetricEncrypt(signature, key=symKey, returnEncoded=True) signature = self._crypto.symmetricEncrypt(signature, key=symKey, returnEncoded=True).decode()
signer = self._crypto.symmetricEncrypt(signer, key=symKey, returnEncoded=True) signer = self._crypto.symmetricEncrypt(signer, key=symKey, returnEncoded=True).decode()
elif encryptType == 'asym': elif encryptType == 'asym':
if self._utils.validatePubKey(asymPeer): if self._utils.validatePubKey(asymPeer):
jsonMeta = self._crypto.pubKeyEncrypt(jsonMeta, asymPeer, encodedData=True) jsonMeta = self._crypto.pubKeyEncrypt(jsonMeta, asymPeer, encodedData=True).decode()
data = self._crypto.pubKeyEncrypt(data, asymPeer, encodedData=True) data = self._crypto.pubKeyEncrypt(data, asymPeer, encodedData=True).decode()
signature = self._crypto.pubKeyEncrypt(signature, asymPeer, encodedData=True) signature = self._crypto.pubKeyEncrypt(signature, asymPeer, encodedData=True).decode()
else: else:
raise onionrexceptions.InvalidPubkey(asymPeer + ' is not a valid base32 encoded ed25519 key') raise onionrexceptions.InvalidPubkey(asymPeer + ' is not a valid base32 encoded ed25519 key')

View File

@ -51,6 +51,7 @@ class Block:
self.parent = None self.parent = None
self.bheader = {} self.bheader = {}
self.bmetadata = {} self.bmetadata = {}
self.isEncrypted = False
# handle arguments # handle arguments
if self.getCore() is None: if self.getCore() is None:
@ -118,6 +119,10 @@ class Block:
self.raw = str(blockdata) self.raw = str(blockdata)
self.bheader = json.loads(self.getRaw()[:self.getRaw().index('\n')]) self.bheader = json.loads(self.getRaw()[:self.getRaw().index('\n')])
self.bcontent = self.getRaw()[self.getRaw().index('\n') + 1:] self.bcontent = self.getRaw()[self.getRaw().index('\n') + 1:]
if self.bheader['encryptType'] in ('asym', 'sym'):
self.bmetadata = self.getHeader('meta', None)
self.isEncrypted = True
else:
self.bmetadata = json.loads(self.getHeader('meta', None)) self.bmetadata = json.loads(self.getHeader('meta', None))
self.parent = self.getMetadata('parent', None) self.parent = self.getMetadata('parent', None)
self.btype = self.getMetadata('type', None) self.btype = self.getMetadata('type', None)

View File

@ -114,6 +114,11 @@ class OnionrCrypto:
'''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)''' '''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
retVal = '' retVal = ''
try:
pubkey = pubkey.encode()
except AttributeError:
pass
if encodedData: if encodedData:
encoding = nacl.encoding.Base64Encoder encoding = nacl.encoding.Base64Encoder
else: else:
@ -127,7 +132,11 @@ class OnionrCrypto:
elif anonymous: elif anonymous:
key = nacl.signing.VerifyKey(key=pubkey, encoder=nacl.encoding.Base32Encoder).to_curve25519_public_key() key = nacl.signing.VerifyKey(key=pubkey, encoder=nacl.encoding.Base32Encoder).to_curve25519_public_key()
anonBox = nacl.public.SealedBox(key) anonBox = nacl.public.SealedBox(key)
retVal = anonBox.encrypt(data.encode(), encoder=encoding) try:
data = data.encode()
except AttributeError:
pass
retVal = anonBox.encrypt(data, encoder=encoding)
return retVal return retVal
def pubKeyDecrypt(self, data, pubkey='', anonymous=False, encodedData=False): def pubKeyDecrypt(self, data, pubkey='', anonymous=False, encodedData=False):

View File

@ -59,7 +59,7 @@ class OnionrUtils:
High level function to encrypt a message to a peer and insert it as a block High level function to encrypt a message to a peer and insert it as a block
''' '''
self._core.insertBlock(message, header='pm', sign=True, encryptType='sym', symKey=pubkey) self._core.insertBlock(message, header='pm', sign=True, encryptType='asym', asymPeer=pubkey)
return return
@ -117,7 +117,7 @@ class OnionrUtils:
else: else:
logger.warn("Failed to add key") logger.warn("Failed to add key")
else: else:
logger.warn('%s pow failed' % key[0]) logger.debug('%s pow failed' % key[0])
return retVal return retVal
except Exception as error: except Exception as error:
logger.error('Failed to merge keys.', error=error) logger.error('Failed to merge keys.', error=error)
@ -204,18 +204,23 @@ class OnionrUtils:
def getBlockMetadataFromData(self, blockData): def getBlockMetadataFromData(self, blockData):
''' '''
accepts block contents as string and returns a tuple of metadata, meta (meta being internal metadata) accepts block contents as string, returns a tuple of metadata, meta (meta being internal metadata, which will be returned as an encrypted base64 string if it is encrypted, dict if not).
''' '''
meta = {}
try: try:
blockData = blockData.encode() blockData = blockData.encode()
except AttributeError: except AttributeError:
pass pass
metadata = json.loads(blockData[:blockData.find(b'\n')].decode()) metadata = json.loads(blockData[:blockData.find(b'\n')].decode())
data = blockData[blockData.find(b'\n'):].decode() data = blockData[blockData.find(b'\n'):].decode()
if not metadata['encryptType'] in ('asym', 'sym'):
try: try:
meta = json.loads(metadata['meta']) meta = json.loads(metadata['meta'])
except KeyError: except KeyError:
meta = {} pass
meta = metadata['meta']
return (metadata, meta, data) return (metadata, meta, data)
def checkPort(self, port, host=''): def checkPort(self, port, host=''):