work on foward secrecy

This commit is contained in:
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:
forwardEncrypted = onionrusers.OnionrUser(self, asymPeer).forwardEncrypt(data)
data = forwardEncrypted[0]
meta['newFSKey'] = forwardEncrypted[1]
meta['forwardEnc'] = True
except onionrexceptions.InvalidPubkey:
onionrusers.OnionrUser(self, asymPeer).generateForwardKey()
fsKey = onionrusers.OnionrUser(self, asymPeer).getGeneratedForwardKeys()[0]
meta['newFSKey'] = fsKey[0]
else:
logger.info(forwardEncrypted)
fsKey = onionrusers.OnionrUser(self, asymPeer).getGeneratedForwardKeys()[0]
meta['newFSKey'] = fsKey[0]
jsonMeta = json.dumps(meta)
if sign:
signature = self._crypto.edSign(jsonMeta.encode() + data, key=self._crypto.privKey, encodeResult=True)

View File

@ -97,12 +97,12 @@ class Block:
pass
else:
try:
self.bcontent = onionrusers.OnionrUser(self.core, self.signer).forwardDecrypt(self.bcontent)
except onionrexceptions.DecryptionError:
self.bcontent = onionrusers.OnionrUser(self.getCore(), self.signer).forwardDecrypt(self.bcontent)
except (onionrexceptions.DecryptionError, nacl.exceptions.CryptoError) as e:
logger.error(str(e))
pass
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:
retData = True
self.decrypted = True

View File

@ -142,7 +142,7 @@ class OnionrCrypto:
retVal = anonBox.encrypt(data, encoder=encoding)
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)'''
retVal = False
if encodedData:
@ -154,7 +154,11 @@ class OnionrCrypto:
ourBox = nacl.public.Box(ownKey, pubkey)
decrypted = ourBox.decrypt(data, encoder=encoding)
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)
return decrypted

View File

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

View File

@ -262,7 +262,7 @@ class OnionrUtils:
'''
myBlock = Block(blockHash, self._core)
if myBlock.isEncrypted:
myBlock.decrypt()
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)
@ -287,6 +287,7 @@ class OnionrUtils:
else:
self._core.updateBlockInfo(blockHash, 'expire', expireTime)
else:
logger.info(myBlock.isEncrypted)
logger.debug('Not processing metadata on encrypted block we cannot decrypt.')
def escapeAnsi(self, line):