work on foward secrecy

master
Kevin Froman 2018-10-09 18:36:52 -05:00
parent c823eecfe3
commit fbd82d38fe
5 changed files with 35 additions and 19 deletions

View File

@ -727,12 +727,13 @@ class Core:
try: try:
forwardEncrypted = onionrusers.OnionrUser(self, asymPeer).forwardEncrypt(data) forwardEncrypted = onionrusers.OnionrUser(self, asymPeer).forwardEncrypt(data)
data = forwardEncrypted[0] data = forwardEncrypted[0]
meta['newFSKey'] = forwardEncrypted[1]
meta['forwardEnc'] = True meta['forwardEnc'] = True
except onionrexceptions.InvalidPubkey: except onionrexceptions.InvalidPubkey:
onionrusers.OnionrUser(self, asymPeer).generateForwardKey() onionrusers.OnionrUser(self, asymPeer).generateForwardKey()
fsKey = onionrusers.OnionrUser(self, asymPeer).getGeneratedForwardKeys()[0] else:
meta['newFSKey'] = fsKey[0] logger.info(forwardEncrypted)
fsKey = onionrusers.OnionrUser(self, asymPeer).getGeneratedForwardKeys()[0]
meta['newFSKey'] = fsKey[0]
jsonMeta = json.dumps(meta) jsonMeta = json.dumps(meta)
if sign: if sign:
signature = self._crypto.edSign(jsonMeta.encode() + data, key=self._crypto.privKey, encodeResult=True) signature = self._crypto.edSign(jsonMeta.encode() + data, key=self._crypto.privKey, encodeResult=True)

View File

@ -97,12 +97,12 @@ class Block:
pass pass
else: else:
try: try:
self.bcontent = onionrusers.OnionrUser(self.core, self.signer).forwardDecrypt(self.bcontent) self.bcontent = onionrusers.OnionrUser(self.getCore(), self.signer).forwardDecrypt(self.bcontent)
except onionrexceptions.DecryptionError: except (onionrexceptions.DecryptionError, nacl.exceptions.CryptoError) as e:
logger.error(str(e))
pass pass
except nacl.exceptions.CryptoError: except nacl.exceptions.CryptoError:
pass logger.debug('Could not decrypt block. Either invalid key or corrupted data')
#logger.debug('Could not decrypt block. Either invalid key or corrupted data')
else: else:
retData = True retData = True
self.decrypted = True self.decrypted = True

View File

@ -142,7 +142,7 @@ class OnionrCrypto:
retVal = anonBox.encrypt(data, encoder=encoding) retVal = anonBox.encrypt(data, encoder=encoding)
return retVal return retVal
def pubKeyDecrypt(self, data, pubkey='', anonymous=False, encodedData=False): def pubKeyDecrypt(self, data, pubkey='', privkey='', anonymous=False, encodedData=False):
'''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)''' '''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
retVal = False retVal = False
if encodedData: if encodedData:
@ -154,7 +154,11 @@ class OnionrCrypto:
ourBox = nacl.public.Box(ownKey, pubkey) ourBox = nacl.public.Box(ownKey, pubkey)
decrypted = ourBox.decrypt(data, encoder=encoding) decrypted = ourBox.decrypt(data, encoder=encoding)
elif anonymous: elif anonymous:
anonBox = nacl.public.SealedBox(ownKey) if self._core._utils.validatePubKey(privkey):
privkey = nacl.signing.SigningKey(seed=privkey, encoder=nacl.encoding.Base32Encoder()).to_curve25519_private_key()
anonBox = nacl.public.SealedBox(privkey)
else:
anonBox = nacl.public.SealedBox(ownKey)
decrypted = anonBox.decrypt(data, encoder=encoding) decrypted = anonBox.decrypt(data, encoder=encoding)
return decrypted return decrypted

View File

@ -18,6 +18,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import onionrblockapi, logger, onionrexceptions, json, sqlite3 import onionrblockapi, logger, onionrexceptions, json, sqlite3
import nacl.exceptions
class OnionrUser: class OnionrUser:
def __init__(self, coreInst, publicKey): def __init__(self, coreInst, publicKey):
self.trust = 0 self.trust = 0
@ -61,15 +62,20 @@ class OnionrUser:
retData = self._core._crypto.pubKeyEncrypt(data, forwardKey, encodedData=True, anonymous=True) retData = self._core._crypto.pubKeyEncrypt(data, forwardKey, encodedData=True, anonymous=True)
else: else:
raise onionrexceptions.InvalidPubkey("No valid forward key available for this user") raise onionrexceptions.InvalidPubkey("No valid forward key available for this user")
self.generateForwardKey() #self.generateForwardKey()
return (retData, forwardKey) return (retData, forwardKey)
def forwardDecrypt(self, encrypted): def forwardDecrypt(self, encrypted):
retData = "" retData = ""
logger.error(self.publicKey)
logger.error(self.getGeneratedForwardKeys())
for key in self.getGeneratedForwardKeys(): for key in self.getGeneratedForwardKeys():
retData = self._core._crypto.pubKeyDecrypt(encrypted, pubkey=key[1], anonymous=True) logger.info(encrypted)
logger('decrypting ' + key + ' got ' + retData) try:
if retData != False: retData = self._core._crypto.pubKeyDecrypt(encrypted, privkey=key[1], anonymous=True, encodedData=True)
except nacl.exceptions.CryptoError:
retData = False
else:
break break
else: else:
raise onionrexceptions.DecryptionError("Could not decrypt forward secrecy content") raise onionrexceptions.DecryptionError("Could not decrypt forward secrecy content")
@ -110,8 +116,8 @@ class OnionrUser:
# Prepare the insert # Prepare the insert
time = self._core._utils.getEpoch() time = self._core._utils.getEpoch()
newKeys = self._core._crypto.generatePubKey() newKeys = self._core._crypto.generatePubKey()
newPub = newKeys[0] newPub = self._core._utils.bytesToStr(newKeys[0])
newPriv = newKeys[1] newPriv = self._core._utils.bytesToStr(newKeys[1])
time = self._core._utils.getEpoch() time = self._core._utils.getEpoch()
command = (self.publicKey, newPub, newPriv, time, expire) command = (self.publicKey, newPub, newPriv, time, expire)
@ -126,14 +132,18 @@ class OnionrUser:
# Fetch the keys we generated for the peer, that are still around # Fetch the keys we generated for the peer, that are still around
conn = sqlite3.connect(self._core.forwardKeysFile, timeout=10) conn = sqlite3.connect(self._core.forwardKeysFile, timeout=10)
c = conn.cursor() c = conn.cursor()
command = (self.publicKey,) pubkey = self.publicKey
pubkey = self._core._utils.bytesToStr(pubkey)
command = (pubkey,)
keyList = [] # list of tuples containing pub, private for peer keyList = [] # list of tuples containing pub, private for peer
for result in c.execute("SELECT * FROM myForwardKeys where peer=?", command): for result in c.execute("SELECT * FROM myForwardKeys where peer=?", command):
keyList.append((result[1], result[2])) keyList.append((result[1], result[2]))
return keyList if len(keyList) == 0:
self.generateForwardKey()
keyList = self.getGeneratedForwardKeys()
return list(keyList)
def addForwardKey(self, newKey, expire=432000): def addForwardKey(self, newKey, expire=432000):
logger.info(newKey)
if not self._core._utils.validatePubKey(newKey): if not self._core._utils.validatePubKey(newKey):
raise onionrexceptions.InvalidPubkey raise onionrexceptions.InvalidPubkey
# Add a forward secrecy key for the peer # Add a forward secrecy key for the peer

View File

@ -262,7 +262,7 @@ class OnionrUtils:
''' '''
myBlock = Block(blockHash, self._core) myBlock = Block(blockHash, self._core)
if myBlock.isEncrypted: if myBlock.isEncrypted:
myBlock.decrypt() logger.warn(myBlock.decrypt())
if (myBlock.isEncrypted and myBlock.decrypted) or (not myBlock.isEncrypted): 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 blockType = myBlock.getMetadata('type') # we would use myBlock.getType() here, but it is bugged with encrypted blocks
signer = self.bytesToStr(myBlock.signer) signer = self.bytesToStr(myBlock.signer)
@ -287,6 +287,7 @@ class OnionrUtils:
else: else:
self._core.updateBlockInfo(blockHash, 'expire', expireTime) self._core.updateBlockInfo(blockHash, 'expire', expireTime)
else: else:
logger.info(myBlock.isEncrypted)
logger.debug('Not processing metadata on encrypted block we cannot decrypt.') logger.debug('Not processing metadata on encrypted block we cannot decrypt.')
def escapeAnsi(self, line): def escapeAnsi(self, line):