From c0c5061f1e6c5f03a5cf717e0e42997966f74925 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 9 Nov 2018 13:07:26 -0600 Subject: [PATCH] fixed forward secrecy and delete keys --- onionr/communicator2.py | 7 ++++++- onionr/core.py | 2 +- onionr/dbcreator.py | 4 ++-- onionr/onionrdaemontools.py | 22 +++++++++++++++++++++- onionr/onionrusers.py | 36 +++++++++++++++++++++++++----------- onionr/onionrutils.py | 5 +++++ 6 files changed, 60 insertions(+), 16 deletions(-) diff --git a/onionr/communicator2.py b/onionr/communicator2.py index f29e482e..08806569 100755 --- a/onionr/communicator2.py +++ b/onionr/communicator2.py @@ -99,11 +99,13 @@ class OnionrCommunicatorDaemon: netCheckTimer = OnionrCommunicatorTimers(self, self.daemonTools.netCheck, 600) announceTimer = OnionrCommunicatorTimers(self, self.daemonTools.announceNode, 305, requiresPeer=True, maxThreads=1) cleanupTimer = OnionrCommunicatorTimers(self, self.peerCleanup, 300, requiresPeer=True) + forwardSecrecyTimer = OnionrCommunicatorTimers(self, self.daemonTools.cleanKeys, 15) # set loop to execute instantly to load up peer pool (replaced old pool init wait) peerPoolTimer.count = (peerPoolTimer.frequency - 1) cleanupTimer.count = (cleanupTimer.frequency - 60) announceTimer.count = (cleanupTimer.frequency - 60) + #forwardSecrecyTimer.count = (forwardSecrecyTimer.frequency - 990) self.socketServer = threading.Thread(target=onionrsockets.OnionrSocketServer, args=(self._core,)) self.socketServer.start() @@ -450,7 +452,10 @@ class OnionrCommunicatorDaemon: if cmd[0] == 'shutdown': self.shutdown = True elif cmd[0] == 'announceNode': - self.announce(cmd[1]) + if len(self.onlinePeers) > 0: + self.announce(cmd[1]) + else: + logger.warn("Not introducing, since I have no connected nodes.") elif cmd[0] == 'runCheck': logger.debug('Status check; looks good.') open(self._core.dataDir + '.runcheck', 'w+').close() diff --git a/onionr/core.py b/onionr/core.py index d15d30fb..fab7b04a 100644 --- a/onionr/core.py +++ b/onionr/core.py @@ -670,7 +670,7 @@ class Core: except AttributeError: pass - if encryptType == 'sym': + if encryptType == 'asym': try: forwardEncrypted = onionrusers.OnionrUser(self, asymPeer).forwardEncrypt(data) data = forwardEncrypted[0] diff --git a/onionr/dbcreator.py b/onionr/dbcreator.py index 82816f43..d11aa4fa 100644 --- a/onionr/dbcreator.py +++ b/onionr/dbcreator.py @@ -124,8 +124,8 @@ class DBCreator: c = conn.cursor() c.execute('''CREATE TABLE myForwardKeys( peer text not null, - public key text not null, - private key text not null, + publickey text not null, + privatekey text not null, date int not null, expire int not null ); diff --git a/onionr/onionrdaemontools.py b/onionr/onionrdaemontools.py index 486f4638..cac06f9f 100644 --- a/onionr/onionrdaemontools.py +++ b/onionr/onionrdaemontools.py @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import onionrexceptions, onionrpeers, onionrproofs, base64, logger +import onionrexceptions, onionrpeers, onionrproofs, base64, logger, onionrusers, sqlite3 from dependencies import secrets class DaemonTools: def __init__(self, daemon): @@ -78,6 +78,26 @@ class DaemonTools: self.daemon._core._blacklist.addToDB(bHash) self.daemon._core.removeBlock(bHash) self.daemon.decrementThreadCount('cleanOldBlocks') + + def cleanKeys(self): + '''Delete expired forward secrecy keys''' + conn = sqlite3.connect(self.daemon._core.peerDB, timeout=10) + c = conn.cursor() + time = self.daemon._core._utils.getEpoch() + deleteKeys = [] + for entry in c.execute("SELECT * FROM forwardKeys where expire <= ?", (time,)): + logger.info(entry[1]) + deleteKeys.append(entry[1]) + + for key in deleteKeys: + logger.info('Deleting forward key '+ key) + c.execute("DELETE from forwardKeys where forwardKey = ?", (key,)) + conn.commit() + conn.close() + + onionrusers.deleteExpiredKeys(self.daemon._core) + + self.daemon.decrementThreadCount('cleanKeys') def cooldownPeer(self): '''Randomly add an online peer to cooldown, so we can connect a new one''' diff --git a/onionr/onionrusers.py b/onionr/onionrusers.py index f1ab241c..93ecd6b0 100644 --- a/onionr/onionrusers.py +++ b/onionr/onionrusers.py @@ -19,6 +19,19 @@ ''' import onionrblockapi, logger, onionrexceptions, json, sqlite3 import nacl.exceptions + +def deleteExpiredKeys(coreInst): + # Fetch the keys we generated for the peer, that are still around + conn = sqlite3.connect(coreInst.forwardKeysFile, timeout=10) + c = conn.cursor() + + curTime = coreInst._utils.getEpoch() + c.execute("DELETE from myForwardKeys where expire <= ?", (curTime,)) + conn.commit() + conn.execute("VACUUM") + conn.close() + return + class OnionrUser: def __init__(self, coreInst, publicKey): self.trust = 0 @@ -58,7 +71,7 @@ class OnionrUser: def forwardEncrypt(self, data): retData = '' forwardKey = self._getLatestForwardKey() - logger.info('using ' + forwardKey) + #logger.info('using ' + forwardKey) if self._core._utils.validatePubKey(forwardKey): retData = self._core._crypto.pubKeyEncrypt(data, forwardKey, encodedData=True, anonymous=True) else: @@ -68,9 +81,9 @@ class OnionrUser: def forwardDecrypt(self, encrypted): retData = "" - logger.error(self.publicKey) - logger.error(self.getGeneratedForwardKeys()) - for key in self.getGeneratedForwardKeys(): + #logger.error(self.publicKey) + #logger.error(self.getGeneratedForwardKeys(False)) + for key in self.getGeneratedForwardKeys(False): logger.info(encrypted) try: retData = self._core._crypto.pubKeyDecrypt(encrypted, privkey=key[1], anonymous=True, encodedData=True) @@ -109,7 +122,7 @@ class OnionrUser: return list(keyList) - def generateForwardKey(self, expire=432000): + def generateForwardKey(self, expire=604800): # Generate a forward secrecy key for the peer conn = sqlite3.connect(self._core.forwardKeysFile, timeout=10) @@ -121,7 +134,7 @@ class OnionrUser: newPriv = self._core._utils.bytesToStr(newKeys[1]) time = self._core._utils.getEpoch() - command = (self.publicKey, newPub, newPriv, time, expire) + command = (self.publicKey, newPub, newPriv, time, expire + time) c.execute("INSERT INTO myForwardKeys VALUES(?, ?, ?, ?, ?);", command) @@ -129,7 +142,7 @@ class OnionrUser: conn.close() return newPub - def getGeneratedForwardKeys(self): + def getGeneratedForwardKeys(self, genNew=True): # Fetch the keys we generated for the peer, that are still around conn = sqlite3.connect(self._core.forwardKeysFile, timeout=10) c = conn.cursor() @@ -140,11 +153,12 @@ class OnionrUser: for result in c.execute("SELECT * FROM myForwardKeys where peer=?", command): keyList.append((result[1], result[2])) if len(keyList) == 0: - self.generateForwardKey() - keyList = self.getGeneratedForwardKeys() + if genNew: + self.generateForwardKey() + keyList = self.getGeneratedForwardKeys() return list(keyList) - def addForwardKey(self, newKey, expire=432000): + def addForwardKey(self, newKey, expire=604800): if not self._core._utils.validatePubKey(newKey): raise onionrexceptions.InvalidPubkey # Add a forward secrecy key for the peer @@ -152,7 +166,7 @@ class OnionrUser: c = conn.cursor() # Prepare the insert time = self._core._utils.getEpoch() - command = (self.publicKey, newKey, time, expire) + command = (self.publicKey, newKey, time, time + expire) c.execute("INSERT INTO forwardKeys VALUES(?, ?, ?, ?);", command) diff --git a/onionr/onionrutils.py b/onionr/onionrutils.py index 3bab70b0..558a6b20 100644 --- a/onionr/onionrutils.py +++ b/onionr/onionrutils.py @@ -263,14 +263,19 @@ class OnionrUtils: ''' myBlock = Block(blockHash, self._core) if myBlock.isEncrypted: + #pass logger.warn(myBlock.decrypt()) if (myBlock.isEncrypted and myBlock.decrypted) or (not myBlock.isEncrypted): blockType = myBlock.getMetadata('type') # we would use myBlock.getType() here, but it is bugged with encrypted blocks signer = self.bytesToStr(myBlock.signer) valid = myBlock.verifySig() + logger.info('Checking for fs key') if myBlock.getMetadata('newFSKey') is not None: onionrusers.OnionrUser(self._core, signer).addForwardKey(myBlock.getMetadata('newFSKey')) + else: + logger.warn('FS not used for this encrypted block') + logger.info(myBlock.bmetadata) try: if len(blockType) <= 10: