lot of work on OnionrCrypto
updated logo fixed broken peerinfo functions in core removed gnupg from travis installationmaster
parent
e3ebe5c2e4
commit
8022781a8f
|
@ -3,6 +3,6 @@ python:
|
||||||
- "3.6.4"
|
- "3.6.4"
|
||||||
# install dependencies
|
# install dependencies
|
||||||
install:
|
install:
|
||||||
- sudo apt install gnupg tor
|
- sudo apt install tor
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
script: make test
|
script: make test
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -18,7 +18,7 @@ uninstall:
|
||||||
test:
|
test:
|
||||||
@rm -rf onionr/data-backup
|
@rm -rf onionr/data-backup
|
||||||
@mv onionr/data onionr/data-backup | true > /dev/null 2>&1
|
@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
|
@rm -rf onionr/data
|
||||||
@mv onionr/data-backup onionr/data | true > /dev/null 2>&1
|
@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 |
|
@ -33,6 +33,8 @@ class OnionrCommunicate:
|
||||||
self._core = core.Core()
|
self._core = core.Core()
|
||||||
self._utils = onionrutils.OnionrUtils(self._core)
|
self._utils = onionrutils.OnionrUtils(self._core)
|
||||||
self._crypto = onionrcrypto.OnionrCrypto(self._core)
|
self._crypto = onionrcrypto.OnionrCrypto(self._core)
|
||||||
|
|
||||||
|
self.highFailureAmount = 7
|
||||||
'''
|
'''
|
||||||
logger.info('Starting Bitcoin Node... with Tor socks port:' + str(sys.argv[2]))
|
logger.info('Starting Bitcoin Node... with Tor socks port:' + str(sys.argv[2]))
|
||||||
try:
|
try:
|
||||||
|
@ -47,6 +49,8 @@ class OnionrCommunicate:
|
||||||
|
|
||||||
blockProcessTimer = 0
|
blockProcessTimer = 0
|
||||||
blockProcessAmount = 5
|
blockProcessAmount = 5
|
||||||
|
highFailureTimer = 0
|
||||||
|
highFailureRate = 10
|
||||||
heartBeatTimer = 0
|
heartBeatTimer = 0
|
||||||
heartBeatRate = 5
|
heartBeatRate = 5
|
||||||
pexTimer = 5 # How often we should check for new peers
|
pexTimer = 5 # How often we should check for new peers
|
||||||
|
@ -68,6 +72,11 @@ class OnionrCommunicate:
|
||||||
blockProcessTimer += 1
|
blockProcessTimer += 1
|
||||||
heartBeatTimer += 1
|
heartBeatTimer += 1
|
||||||
pexCount += 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:
|
if pexTimer == pexCount:
|
||||||
self.getNewPeers()
|
self.getNewPeers()
|
||||||
pexCount = 0
|
pexCount = 0
|
||||||
|
@ -236,7 +245,7 @@ class OnionrCommunicate:
|
||||||
if data != None:
|
if data != None:
|
||||||
url = url + '&data=' + self.urlencode(data)
|
url = url + '&data=' + self.urlencode(data)
|
||||||
try:
|
try:
|
||||||
if skipHighFailureAddress and self.peerData[peer]['failCount'] > 10:
|
if skipHighFailureAddress and self.peerData[peer]['failCount'] > self.highFailureAmount:
|
||||||
retData = False
|
retData = False
|
||||||
logger.debug('Skipping ' + peer + ' because of high failure rate')
|
logger.debug('Skipping ' + peer + ' because of high failure rate')
|
||||||
else:
|
else:
|
||||||
|
@ -251,6 +260,7 @@ class OnionrCommunicate:
|
||||||
self.peerData[peer]['failCount'] += 1
|
self.peerData[peer]['failCount'] += 1
|
||||||
else:
|
else:
|
||||||
self.peerData[peer]['connectCount'] += 1
|
self.peerData[peer]['connectCount'] += 1
|
||||||
|
self.peerData[peer]['failCount'] -= 1
|
||||||
self.peerData[peer]['lastConnectTime'] = math.floor(time.time())
|
self.peerData[peer]['lastConnectTime'] = math.floor(time.time())
|
||||||
return retData
|
return retData
|
||||||
|
|
||||||
|
|
|
@ -369,16 +369,17 @@ class Core:
|
||||||
|
|
||||||
id text 0
|
id text 0
|
||||||
name text, 1
|
name text, 1
|
||||||
adders text, 2
|
pubkey text, 2
|
||||||
forwardKey text, 3
|
adders text, 3
|
||||||
dateSeen not null, 4
|
forwardKey text, 4
|
||||||
bytesStored int, 5
|
dateSeen not null, 5
|
||||||
trust int 6
|
bytesStored int, 6
|
||||||
|
trust int 7
|
||||||
'''
|
'''
|
||||||
conn = sqlite3.connect(self.peerDB)
|
conn = sqlite3.connect(self.peerDB)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
command = (peer,)
|
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]
|
info = infoNumbers[info]
|
||||||
iterCount = 0
|
iterCount = 0
|
||||||
retVal = ''
|
retVal = ''
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
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 nacl.signing, nacl.encoding, nacl.public, os
|
import nacl.signing, nacl.encoding, nacl.public, nacl.secret, os, binascii, base64
|
||||||
|
|
||||||
class OnionrCrypto:
|
class OnionrCrypto:
|
||||||
def __init__(self, coreInstance):
|
def __init__(self, coreInstance):
|
||||||
|
@ -60,36 +60,112 @@ class OnionrCrypto:
|
||||||
retData = key.sign(data.encode())
|
retData = key.sign(data.encode())
|
||||||
return retData
|
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)'''
|
'''Encrypt to a public key (Curve25519, taken from base32 Ed25519 pubkey)'''
|
||||||
retVal = ''
|
retVal = ''
|
||||||
|
|
||||||
|
if encodedData:
|
||||||
|
encoding = nacl.encoding.Base64Encoder
|
||||||
|
else:
|
||||||
|
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=nacl.encoding.RawEncoder)
|
retVal = ourBox.encrypt(data.encode(), encoder=encoding)
|
||||||
elif anonymous:
|
elif anonymous:
|
||||||
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()
|
||||||
anonBox = nacl.public.SealedBox(key)
|
anonBox = nacl.public.SealedBox(key)
|
||||||
retVal = anonBox.encrypt(data.encode(), encoder=nacl.encoding.RawEncoder)
|
retVal = anonBox.encrypt(data.encode(), encoder=encoding)
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def pubKeyDecrypt(self, data, peer):
|
def pubKeyDecrypt(self, data, pubkey, anonymous=False, encodedData=False):
|
||||||
'''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
|
'''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):
|
def symmetricPeerEncrypt(self, data, peer):
|
||||||
'''Salsa20 encrypt data to peer (with mac)'''
|
'''Salsa20 encrypt data to peer (with mac)
|
||||||
return
|
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):
|
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
|
return
|
||||||
|
|
||||||
def generateSymmetric(self, data, peer):
|
def symmetricEncrypt(self, data, key, encodedKey=False, returnEncoded=True):
|
||||||
'''Generate symmetric key'''
|
'''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 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
|
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):
|
def generatePubKey(self):
|
||||||
'''Generate a Ed25519 public key pair, return tuple of base64encoded pubkey, privkey'''
|
'''Generate a Ed25519 public key pair, return tuple of base64encoded pubkey, privkey'''
|
||||||
private_key = nacl.signing.SigningKey.generate()
|
private_key = nacl.signing.SigningKey.generate()
|
||||||
|
|
Loading…
Reference in New Issue