work on foward secrecy
parent
c823eecfe3
commit
fbd82d38fe
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue