more work on block headers, PMs now signed/verified

This commit is contained in:
Kevin Froman 2018-04-26 14:56:17 -05:00
parent ad56082271
commit c9b7528db4
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
4 changed files with 71 additions and 24 deletions

View File

@ -269,8 +269,8 @@ class Core:
selfInsert = 1 selfInsert = 1
else: else:
selfInsert = 0 selfInsert = 0
data = (newHash, currentTime, 0, '', 0, selfInsert) data = (newHash, currentTime, '', selfInsert)
c.execute('INSERT INTO hashes VALUES(?, ?, ?, ?, ?, ?);', data) c.execute('INSERT INTO hashes (hash, dateReceived, dataType, dataSaved) VALUES(?, ?, ?, ?);', data)
conn.commit() conn.commit()
conn.close() conn.close()
@ -618,7 +618,7 @@ class Core:
retData = '' retData = ''
metadata = {'type': header} metadata = {'type': header}
if sign: if sign:
signature = self._crypto.edSign(data, self._crypto.privKey, encodedResult=True) signature = self._crypto.edSign(data, self._crypto.privKey, encodeResult=True)
ourID = self._crypto.pubKeyHashID() ourID = self._crypto.pubKeyHashID()
metadata['id'] = ourID metadata['id'] = ourID
metadata['sig'] = signature metadata['sig'] = signature

View File

@ -372,7 +372,7 @@ class Onionr:
while True: while True:
messageToAdd = logger.readline('Broadcast message to network: ') messageToAdd = logger.readline('Broadcast message to network: ')
if len(messageToAdd) - 5 >= 1: if len(messageToAdd) >= 1:
break break
#addedHash = self.onionrCore.setData(messageToAdd) #addedHash = self.onionrCore.setData(messageToAdd)

View File

@ -42,24 +42,36 @@ class OnionrCrypto:
keyfile.write(self.pubKey + ',' + self.privKey) keyfile.write(self.pubKey + ',' + self.privKey)
return return
def edVerify(self, data, key): def edVerify(self, data, key, sig, encodedData=True):
'''Verify signed data (combined in nacl) to an ed25519 key''' '''Verify signed data (combined in nacl) to an ed25519 key'''
key = nacl.signing.VerifyKey(key=key, encoder=nacl.encoding.Base32Encoder) key = nacl.signing.VerifyKey(key=key, encoder=nacl.encoding.Base32Encoder)
retData = '' retData = False
if encodeResult: sig = base64.b64decode(sig)
retData = key.verify(data.encode(), encoder=nacl.encoding.Base64Encoder) # .encode() is not the same as nacl.encoding data = data.encode()
if encodedData:
try:
retData = key.verify(data, sig) # .encode() is not the same as nacl.encoding
except nacl.exceptions.BadSignatureError:
pass
else: else:
retData = key.verify(data.encode()) try:
retData = key.verify(data, sig)
except nacl.exceptions.BadSignatureError:
pass
return retData return retData
def edSign(self, data, key, encodeResult=False): def edSign(self, data, key, encodeResult=False):
'''Ed25519 sign data''' '''Ed25519 sign data'''
try:
data = data.encode()
except AttributeError:
pass
key = nacl.signing.SigningKey(seed=key, encoder=nacl.encoding.Base32Encoder) key = nacl.signing.SigningKey(seed=key, encoder=nacl.encoding.Base32Encoder)
retData = '' retData = ''
if encodeResult: if encodeResult:
retData = key.sign(data.encode(), encoder=nacl.encoding.Base64Encoder) # .encode() is not the same as nacl.encoding retData = key.sign(data, encoder=nacl.encoding.Base64Encoder).signature.decode() # .encode() is not the same as nacl.encoding
else: else:
retData = key.sign(data.encode()) retData = key.sign(data).signature
return retData return retData
def pubKeyEncrypt(self, data, pubkey, anonymous=False, encodedData=False): def pubKeyEncrypt(self, data, pubkey, anonymous=False, encodedData=False):
@ -72,7 +84,7 @@ class OnionrCrypto:
encoding = nacl.encoding.RawEncoder encoding = nacl.encoding.RawEncoder
if self.privKey != None and not anonymous: if self.privKey != None and not anonymous:
ownKey = nacl.signing.SigningKey(seed=self.privKey, encoder=nacl.encoding.Base32Encoder()) ownKey = nacl.signing.SigningKey(seed=self.privKey, encoder=nacl.encoding.Base32Encoder)
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()
ourBox = nacl.public.Box(ownKey, key) ourBox = nacl.public.Box(ownKey, key)
retVal = ourBox.encrypt(data.encode(), encoder=encoding) retVal = ourBox.encrypt(data.encode(), encoder=encoding)

View File

@ -18,7 +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/>.
''' '''
# Misc functions that do not fit in the main api, but are useful # Misc functions that do not fit in the main api, but are useful
import getpass, sys, requests, os, socket, hashlib, logger, sqlite3, config, binascii, time, base64 import getpass, sys, requests, os, socket, hashlib, logger, sqlite3, config, binascii, time, base64, json
import nacl.signing, nacl.encoding import nacl.signing, nacl.encoding
if sys.version_info < (3, 6): if sys.version_info < (3, 6):
@ -55,7 +55,7 @@ class OnionrUtils:
try: try:
encrypted = self._core._crypto.pubKeyEncrypt(message, pubkey, anonymous=True, encodedData=True).decode() encrypted = self._core._crypto.pubKeyEncrypt(message, pubkey, anonymous=True, encodedData=True).decode()
block = self._core.insertBlock(encrypted, header='pm') block = self._core.insertBlock(encrypted, header='pm', sign=True)
if block == '': if block == '':
logger.error('Could not send PM') logger.error('Could not send PM')
@ -316,7 +316,8 @@ class OnionrUtils:
''' '''
Find, decrypt, and return array of PMs (array of dictionary, {from, text}) Find, decrypt, and return array of PMs (array of dictionary, {from, text})
''' '''
blocks = self._core.getBlockList().split('\n') #blocks = self._core.getBlockList().split('\n')
blocks = self._core.getBlocksByType('pm')
message = '' message = ''
sender = '' sender = ''
for i in blocks: for i in blocks:
@ -324,15 +325,37 @@ class OnionrUtils:
continue continue
try: try:
with open('data/blocks/' + i + '.dat', 'r') as potentialMessage: with open('data/blocks/' + i + '.dat', 'r') as potentialMessage:
message = potentialMessage.read() data = potentialMessage.read().split('}')
if message.startswith('-pm-'): message = data[1]
try: sigResult = ''
message = self._core._crypto.pubKeyDecrypt(message.replace('-pm-', ''), encodedData=True, anonymous=True) signer = ''
except nacl.exceptions.CryptoError as e:
logger.error('Unable to decrypt ' + i, error=e) try:
pass metadata = json.loads(data[0] + '}')
except json.decoder.JSONDecodeError:
metadata = {}
try:
sig = json.loads(data[0].strip() + '}')['sig']
signer = self._core._utils.getPeerByHashId(metadata['id'])
print('signer',signer)
print('signature', metadata['sig'])
except KeyError:
pass
else:
sigResult = self._core._crypto.edVerify(message, signer, sig, encodedData=True)
#sigResult = False
if sigResult != False:
sigResult = 'Valid signature by ' + signer
else: else:
logger.info('Recieved message: ' + message.decode()) sigResult = 'Invalid signature by ' + signer
try:
message = self._core._crypto.pubKeyDecrypt(message, encodedData=True, anonymous=True)
except nacl.exceptions.CryptoError as e:
logger.error('Unable to decrypt ' + i, error=e)
else:
logger.info('Recieved message: ' + message.decode())
logger.info(sigResult)
except FileNotFoundError: except FileNotFoundError:
pass pass
except Exception as error: except Exception as error:
@ -342,4 +365,16 @@ class OnionrUtils:
def getPeerByHashId(self, hash): def getPeerByHashId(self, hash):
''' '''
Return the pubkey of the user if known from the hash Return the pubkey of the user if known from the hash
''' '''
if self._core._crypto.pubKeyHashID() == hash:
retData = self._core._crypto.pubKey
return retData
conn = sqlite3.connect(self._core.peerDB)
c = conn.cursor()
command = (hash,)
retData = ''
print('finding', hash)
for row in c.execute('SELECT ID FROM peers where hashID=?', command):
if row[0] != '':
retData = row[0]
return retData