diff --git a/docs/onionr-draft.md b/docs/onionr-draft.md
index 6fb79cbe..5ab91cb0 100644
--- a/docs/onionr-draft.md
+++ b/docs/onionr-draft.md
@@ -24,6 +24,8 @@ All traffic is over Tor/I2P, connecting only to Tor onion and I2P hidden service
Onionr nodes use HTTP (over Tor/I2P) to exchange keys, metadata, and blocks. Blocks are identified by their sha3_256 hash. Nodes sync a table of blocks hashes and attempt to download blocks they do not yet have from random peers.
+Blocks may be encrypted using Curve25519.
+
## Connections
When a node first comes online, it attempts to bootstrap using a default list provided by a client.
diff --git a/onionr/api.py b/onionr/api.py
index 73c65b48..666b7783 100755
--- a/onionr/api.py
+++ b/onionr/api.py
@@ -47,7 +47,7 @@ class API:
if os.path.exists('dev-enabled'):
self._developmentMode = True
logger.set_level(logger.LEVEL_DEBUG)
- logger.warn('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
+ #logger.warn('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
else:
self._developmentMode = False
logger.set_level(logger.LEVEL_INFO)
@@ -172,9 +172,9 @@ class API:
resp = Response("Invalid request")
return resp
-
- logger.info('Starting client on ' + self.host + ':' + str(bindPort) + '...')
- logger.debug('Client token: ' + logger.colors.underline + self.clientToken)
+ if not os.environ.get("WERKZEUG_RUN_MAIN") == "true":
+ logger.info('Starting client on ' + self.host + ':' + str(bindPort) + '...')
+ logger.debug('Client token: ' + logger.colors.underline + self.clientToken)
app.run(host=self.host, port=bindPort, debug=True, threaded=True)
diff --git a/onionr/communicator.py b/onionr/communicator.py
index 7fe5ecd1..4b6e49a8 100755
--- a/onionr/communicator.py
+++ b/onionr/communicator.py
@@ -20,7 +20,7 @@ and code to operate as a daemon, getting commands from the command queue databas
along with this program. If not, see .
'''
import sqlite3, requests, hmac, hashlib, time, sys, os, math, logger, urllib.parse
-import core, onionrutils
+import core, onionrutils, onionrcrypto
class OnionrCommunicate:
def __init__(self, debug, developmentMode):
@@ -31,6 +31,7 @@ class OnionrCommunicate:
'''
self._core = core.Core()
self._utils = onionrutils.OnionrUtils(self._core)
+ self._crypto = onionrcrypto.OnionrCrypto(self._core)
blockProcessTimer = 0
blockProcessAmount = 5
heartBeatTimer = 0
diff --git a/onionr/core.py b/onionr/core.py
index d1a03b31..29d84a55 100644
--- a/onionr/core.py
+++ b/onionr/core.py
@@ -41,13 +41,14 @@ class Core:
self.blockDB = 'data/blocks.db'
self.blockDataLocation = 'data/blocks/'
self._utils = onionrutils.OnionrUtils(self)
+
+ # Initialize the crypto object
self._crypto = onionrcrypto.OnionrCrypto(self)
if not os.path.exists('data/'):
os.mkdir('data/')
if not os.path.exists('data/blocks/'):
os.mkdir('data/blocks/')
-
if not os.path.exists(self.blockDB):
self.createBlockDB()
diff --git a/onionr/netcontroller.py b/onionr/netcontroller.py
index dcb3c3a5..058d8e4a 100644
--- a/onionr/netcontroller.py
+++ b/onionr/netcontroller.py
@@ -103,7 +103,12 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
int(pidN)
except:
return
- os.kill(int(pidN), signal.SIGTERM)
- os.remove('data/torPid.txt')
+ try:
+ os.kill(int(pidN), signal.SIGTERM)
+ os.remove('data/torPid.txt')
+ except ProcessLookupError:
+ pass
+ except FileNotFoundError:
+ pass
return
diff --git a/onionr/onionr.py b/onionr/onionr.py
index 87b02442..d3c51a4f 100755
--- a/onionr/onionr.py
+++ b/onionr/onionr.py
@@ -47,7 +47,6 @@ class Onionr:
if os.path.exists('dev-enabled'):
self._developmentMode = True
logger.set_level(logger.LEVEL_DEBUG)
- logger.warn('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
else:
self._developmentMode = False
logger.set_level(logger.LEVEL_INFO)
@@ -211,11 +210,14 @@ class Onionr:
def daemon(self):
''' Start the Onionr communication daemon '''
if not os.environ.get("WERKZEUG_RUN_MAIN") == "true":
+ if self._developmentMode:
+ logger.warn('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
net = NetController(self.config['CLIENT']['PORT'])
logger.info('Tor is starting...')
if not net.startTor():
sys.exit(1)
logger.info('Started Tor .onion service: ' + logger.colors.underline + net.myID)
+ logger.info('Our Public key: ' + self.onionrCore._crypto.pubKey)
time.sleep(1)
subprocess.Popen(["./communicator.py", "run", str(net.socksPort)])
logger.debug('Started communicator')
diff --git a/onionr/onionrcrypto.py b/onionr/onionrcrypto.py
index e9f89c7c..6b282341 100644
--- a/onionr/onionrcrypto.py
+++ b/onionr/onionrcrypto.py
@@ -17,21 +17,51 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
'''
-import nacl
+import nacl.signing, nacl.encoding, nacl.public, os
class OnionrCrypto:
def __init__(self, coreInstance):
self._core = coreInstance
+ self._keyFile = 'data/keys.txt'
+ self.pubKey = None
+ self.privKey = None
+
+ # Load our own pub/priv Ed25519 keys, gen & save them if they don't exist
+ if os.path.exists(self._keyFile):
+ with open('data/keys.txt', 'r') as keys:
+ keys = keys.read().split(',')
+ self.pubKey = keys[0]
+ self.privKey = keys[1]
+ else:
+ keys = self.generatePubKey()
+ self.pubKey = keys[0]
+ self.privKey = keys[1]
+ with open(self._keyFile, 'w') as keyfile:
+ keyfile.write(self.pubKey + ',' + self.privKey)
return
- def symmetricPeerEncrypt(self, data, key):
+ def pubKeyEncrypt(self, data, peer):
+ '''Encrypt to a peers public key (Curve25519, taken from Ed25519 pubkey)'''
return
- def symmetricPeerDecrypt(self, data, key):
+ def pubKeyEncrypt(self, data, peer):
+ '''pubkey decrypt (Curve25519, taken from Ed25519 pubkey)'''
+ return
+
+ def symmetricPeerEncrypt(self, data):
+ '''Salsa20 encrypt data to peer (with mac)'''
+ return
+
+ def symmetricPeerDecrypt(self, data, peer):
+ '''Salsa20 decrypt data from peer (with mac)'''
return
- def generateSymmetric():
+ def generateSymmetric(self, data, peer):
+ '''Generate symmetric key'''
return
- def generateHMAC():
- return
\ No newline at end of file
+ def generatePubKey(self):
+ '''Generate a Ed25519 public key pair, return tuple of base64encoded pubkey, privkey'''
+ private_key = nacl.signing.SigningKey.generate()
+ public_key = private_key.verify_key.encode(encoder=nacl.encoding.Base32Encoder())
+ return (public_key.decode(), private_key.encode(encoder=nacl.encoding.Base32Encoder()).decode())
\ No newline at end of file
diff --git a/reset.sh b/reset.sh
new file mode 100755
index 00000000..eaf6641b
--- /dev/null
+++ b/reset.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+echo "RESETING ONIONR"
+rm onionr/data/blocks/*.dat
+rm onionr/data/peers.db
+rm onionr/data/blocks.db