lot of work on OnionrCrypto

updated logo
fixed broken peerinfo functions in core
removed gnupg from travis installation
master
Kevin Froman 2018-04-01 19:33:09 -05:00
parent e3ebe5c2e4
commit 8022781a8f
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
6 changed files with 108 additions and 21 deletions

View File

@ -3,6 +3,6 @@ python:
- "3.6.4"
# install dependencies
install:
- sudo apt install gnupg tor
- sudo apt install tor
- pip install -r requirements.txt
script: make test

View File

@ -18,7 +18,7 @@ uninstall:
test:
@rm -rf onionr/data-backup
@mv onionr/data onionr/data-backup | true > /dev/null 2>&1
-@cd onionr; ./tests.py
-@cd onionr; ./tests.py; ./cryptotests.py;
@rm -rf onionr/data
@mv onionr/data-backup onionr/data | true > /dev/null 2>&1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -33,6 +33,8 @@ class OnionrCommunicate:
self._core = core.Core()
self._utils = onionrutils.OnionrUtils(self._core)
self._crypto = onionrcrypto.OnionrCrypto(self._core)
self.highFailureAmount = 7
'''
logger.info('Starting Bitcoin Node... with Tor socks port:' + str(sys.argv[2]))
try:
@ -47,6 +49,8 @@ class OnionrCommunicate:
blockProcessTimer = 0
blockProcessAmount = 5
highFailureTimer = 0
highFailureRate = 10
heartBeatTimer = 0
heartBeatRate = 5
pexTimer = 5 # How often we should check for new peers
@ -68,6 +72,11 @@ class OnionrCommunicate:
blockProcessTimer += 1
heartBeatTimer += 1
pexCount += 1
if highFailureTimer == highFailureRate:
highFailureTimer = 0
for i in self.peerData:
if self.peerData[i]['failCount'] == self.highFailureAmount:
self.peerData[i]['failCount'] -= 1
if pexTimer == pexCount:
self.getNewPeers()
pexCount = 0
@ -236,7 +245,7 @@ class OnionrCommunicate:
if data != None:
url = url + '&data=' + self.urlencode(data)
try:
if skipHighFailureAddress and self.peerData[peer]['failCount'] > 10:
if skipHighFailureAddress and self.peerData[peer]['failCount'] > self.highFailureAmount:
retData = False
logger.debug('Skipping ' + peer + ' because of high failure rate')
else:
@ -251,6 +260,7 @@ class OnionrCommunicate:
self.peerData[peer]['failCount'] += 1
else:
self.peerData[peer]['connectCount'] += 1
self.peerData[peer]['failCount'] -= 1
self.peerData[peer]['lastConnectTime'] = math.floor(time.time())
return retData

View File

@ -369,16 +369,17 @@ class Core:
id text 0
name text, 1
adders text, 2
forwardKey text, 3
dateSeen not null, 4
bytesStored int, 5
trust int 6
pubkey text, 2
adders text, 3
forwardKey text, 4
dateSeen not null, 5
bytesStored int, 6
trust int 7
'''
conn = sqlite3.connect(self.peerDB)
c = conn.cursor()
command = (peer,)
infoNumbers = {'id': 0, 'name': 1, 'adders': 2, 'forwardKey': 3, 'dateSeen': 4, 'bytesStored': 5, 'trust': 6}
infoNumbers = {'id': 0, 'name': 1, 'pubkey': 2, 'adders': 3, 'forwardKey': 4, 'dateSeen': 5, 'bytesStored': 6, 'trust': 7}
info = infoNumbers[info]
iterCount = 0
retVal = ''

View File

@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import nacl.signing, nacl.encoding, nacl.public, os
import nacl.signing, nacl.encoding, nacl.public, nacl.secret, os, binascii, base64
class OnionrCrypto:
def __init__(self, coreInstance):
@ -60,36 +60,112 @@ class OnionrCrypto:
retData = key.sign(data.encode())
return retData
def pubKeyEncrypt(self, data, pubkey, anonymous=False):
def pubKeyEncrypt(self, data, pubkey, anonymous=False, encodedData=False):
'''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
retVal = ''
if encodedData:
encoding = nacl.encoding.Base64Encoder
else:
encoding = nacl.encoding.RawEncoder
if self.privKey != None and not anonymous:
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()
ourBox = nacl.public.Box(ownKey, key)
retVal = ourBox.encrypt(data.encode(), encoder=nacl.encoding.RawEncoder)
retVal = ourBox.encrypt(data.encode(), encoder=encoding)
elif anonymous:
key = nacl.signing.VerifyKey(key=pubkey, encoder=nacl.encoding.Base32Encoder).to_curve25519_public_key()
anonBox = nacl.public.SealedBox(key)
retVal = anonBox.encrypt(data.encode(), encoder=nacl.encoding.RawEncoder)
retVal = anonBox.encrypt(data.encode(), encoder=encoding)
return retVal
def pubKeyDecrypt(self, data, peer):
def pubKeyDecrypt(self, data, pubkey, anonymous=False, encodedData=False):
'''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
return
retVal = ''
if encodedData:
encoding = nacl.encoding.Base64Encoder
else:
encoding = nacl.encoding.RawEncoder
ownKey = nacl.signing.SigningKey(seed=self.privKey, encoder=nacl.encoding.Base32Encoder())
if self.privKey != None and not anoymous:
ourBox = nacl.public.Box(ownKey, pubkey)
decrypted = ourBox.decrypt(data, encoder=encoding)
elif anonymous:
anonBox = nacl.public.SealedBox(ownKey)
decrypted = anonBox.decrypt(data.encode(), encoder=encoding)
return decrypted
def symmetricPeerEncrypt(self, data):
'''Salsa20 encrypt data to peer (with mac)'''
return
def symmetricPeerEncrypt(self, data, peer):
'''Salsa20 encrypt data to peer (with mac)
this function does not accept a key, it is a wrapper for encryption with a peer
'''
key = self._core.getPeerInfo(4)
if type(key) != bytes:
key = self._core.getPeerInfo(2)
encrypted = self.symmetricEncrypt(data, key, encodedKey=True)
return encrypted
def symmetricPeerDecrypt(self, data, peer):
'''Salsa20 decrypt data from peer (with mac)'''
'''Salsa20 decrypt data from peer (with mac)
this function does not accept a key, it is a wrapper for encryption with a peer
'''
key = self._core.getPeerInfo(4)
if type(key) != bytes:
key = self._core.getPeerInfo(2)
decrypted = self.symmetricDecrypt(data, key, encodedKey=True)
return decrypted
return
def symmetricEncrypt(self, data, key, encodedKey=False, returnEncoded=True):
'''Encrypt data to a 32-byte key (Salsa20-Poly1305 MAC)'''
if encodedKey:
encoding = nacl.encoding.Base64Encoder
else:
encoding = nacl.encoding.RawEncoder
# Make sure data is bytes
if type(data) != bytes:
data = data.encode()
box = nacl.secret.SecretBox(key, encoder=encoding)
if returnEncoded:
encoding = nacl.encoding.Base64Encoder
else:
encoding = nacl.encoding.RawEncoder
encrypted = box.encrypt(data, encoder=encoding)
return encrypted
def symmetricDecrypt(self, data, key, encodedKey=False, encodedMessage=False, returnEncoded=False):
'''Decrypt data to a 32-byte key (Salsa20-Poly1305 MAC)'''
if encodedKey:
encoding = nacl.encoding.Base64Encoder
else:
encoding = nacl.encoding.RawEncoder
box = nacl.secret.SecretBox(key, encoder=encoding)
if encodedMessage:
encoding = nacl.encoding.Base64Encoder
else:
encoding = nacl.encoding.RawEncoder
decrypted = box.decrypt(data, encoder=encoding)
if returnEncoded:
decrypted = base64.b64encode(decrypted)
return decrypted
def generateSymmetric(self, data, peer):
'''Generate symmetric key'''
def generateSymmetricPeer(self, peer):
'''Generate symmetric key for a peer and save it to the peer database'''
key = self.generateSymmetric()
self._core.setPeerInfo(peer, 'forwardKey', key)
return
def generateSymmetric(self):
'''Generate a symmetric key (bytes) and return it'''
return binascii.hexlify(nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE))
def generatePubKey(self):
'''Generate a Ed25519 public key pair, return tuple of base64encoded pubkey, privkey'''
private_key = nacl.signing.SigningKey.generate()