* work on new block system, working on encryption
* added onionrvalues file for onionr requirements * added invalidmetadata exceptionmaster
parent
7864677498
commit
10ebdddb24
|
@ -28,7 +28,7 @@ class OnionrCommunicatorDaemon:
|
||||||
logger.warn('New (unstable) communicator is being used.')
|
logger.warn('New (unstable) communicator is being used.')
|
||||||
|
|
||||||
self.timers = []
|
self.timers = []
|
||||||
self._core = core.Core()
|
self._core = core.Core(torPort=sys.argv[2])
|
||||||
self.nistSaltTimestamp = 0
|
self.nistSaltTimestamp = 0
|
||||||
self.powSalt = 0
|
self.powSalt = 0
|
||||||
self.delay = 1
|
self.delay = 1
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
import sqlite3, os, sys, time, math, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger, json, netcontroller, math, config
|
import sqlite3, os, sys, time, math, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger, json, netcontroller, math, config
|
||||||
from onionrblockapi import Block
|
from onionrblockapi import Block
|
||||||
|
|
||||||
import onionrutils, onionrcrypto, onionrproofs, onionrevents as events
|
import onionrutils, onionrcrypto, onionrproofs, onionrevents as events, onionrexceptions, onionrvalues
|
||||||
|
|
||||||
if sys.version_info < (3, 6):
|
if sys.version_info < (3, 6):
|
||||||
try:
|
try:
|
||||||
|
@ -30,7 +30,7 @@ if sys.version_info < (3, 6):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
def __init__(self):
|
def __init__(self, torPort=0):
|
||||||
'''
|
'''
|
||||||
Initialize Core Onionr library
|
Initialize Core Onionr library
|
||||||
'''
|
'''
|
||||||
|
@ -44,6 +44,7 @@ class Core:
|
||||||
|
|
||||||
self.bootstrapFileLocation = 'static-data/bootstrap-nodes.txt'
|
self.bootstrapFileLocation = 'static-data/bootstrap-nodes.txt'
|
||||||
self.bootstrapList = []
|
self.bootstrapList = []
|
||||||
|
self.requirements = onionrvalues.OnionrValues()
|
||||||
|
|
||||||
if not os.path.exists('data/'):
|
if not os.path.exists('data/'):
|
||||||
os.mkdir('data/')
|
os.mkdir('data/')
|
||||||
|
@ -659,11 +660,49 @@ class Core:
|
||||||
conn.close()
|
conn.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def insertBlock(self, data, header='txt', sign=False, metadata = {}):
|
def insertBlock(self, data, header='txt', sign=False, encryptType='', symKey='', asymPeer='', meta = {}):
|
||||||
'''
|
'''
|
||||||
Inserts a block into the network
|
Inserts a block into the network
|
||||||
|
encryptType must be specified to encrypt a block
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
data.decode()
|
||||||
|
except AttributeError:
|
||||||
|
data = data.encode()
|
||||||
|
|
||||||
|
retData = ''
|
||||||
|
signature = ''
|
||||||
|
signer = ''
|
||||||
|
|
||||||
|
# only use header if not set in provided meta
|
||||||
|
try:
|
||||||
|
meta['type']
|
||||||
|
except KeyError:
|
||||||
|
meta['type'] = header # block type
|
||||||
|
|
||||||
|
jsonMeta = json.dumps(meta)
|
||||||
|
|
||||||
|
if encryptType in ('asym', 'sym'):
|
||||||
|
metadata['encryptType'] = encryptType
|
||||||
|
else:
|
||||||
|
raise onionrexceptions.InvalidMetadata('encryptType must be asym or sym')
|
||||||
|
|
||||||
|
# sign before encrypt, as unauthenticated crypto should not be a problem here
|
||||||
|
if sign:
|
||||||
|
signature = self._crypto.edSign(jsonMeta + data, key=self._crypto.privKey, encodeResult=True)
|
||||||
|
signer = self._crypto.pubKeyHashID()
|
||||||
|
|
||||||
|
if len(jsonMeta) > 1000:
|
||||||
|
raise onionrexceptions.InvalidMetadata('meta in json encoded form must not exceed 1000 bytes')
|
||||||
|
|
||||||
|
if encryptType == 'sym':
|
||||||
|
if len(symKey) < self.requirements.passwordLength:
|
||||||
|
raise onionrexceptions.SecurityError('Weak encryption key')
|
||||||
|
jsonMeta = self._crypto.symmetricEncrypt(jsonMeta, key=symKey, returnEncoded=True)
|
||||||
|
|
||||||
|
metadata['meta'] = jsonMeta
|
||||||
|
|
||||||
powProof = onionrproofs.POW(data)
|
powProof = onionrproofs.POW(data)
|
||||||
powToken = ''
|
powToken = ''
|
||||||
# wait for proof to complete
|
# wait for proof to complete
|
||||||
|
@ -685,41 +724,7 @@ class Core:
|
||||||
powProof.shutdown()
|
powProof.shutdown()
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
try:
|
|
||||||
data.decode()
|
|
||||||
except AttributeError:
|
|
||||||
data = data.encode()
|
|
||||||
|
|
||||||
retData = ''
|
|
||||||
|
|
||||||
metadata['type'] = header
|
|
||||||
metadata['powRandomToken'] = powToken
|
|
||||||
|
|
||||||
sig = {}
|
|
||||||
|
|
||||||
metadata = json.dumps(metadata)
|
|
||||||
metadata = metadata.encode()
|
|
||||||
signature = ''
|
|
||||||
|
|
||||||
if sign:
|
|
||||||
signature = self._crypto.edSign(metadata + b'\n' + data, self._crypto.privKey, encodeResult=True)
|
|
||||||
ourID = self._crypto.pubKeyHashID()
|
|
||||||
# Convert from bytes on some py versions?
|
|
||||||
try:
|
|
||||||
ourID = ourID.decode()
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
metadata = {'sig': signature, 'meta': metadata.decode()}
|
|
||||||
metadata = json.dumps(metadata)
|
|
||||||
metadata = metadata.encode()
|
|
||||||
|
|
||||||
if len(data) == 0:
|
|
||||||
logger.error('Will not insert empty block')
|
|
||||||
else:
|
|
||||||
addedHash = self.setData(metadata + b'\n' + data)
|
|
||||||
self.addToBlockDB(addedHash, selfInsert=True)
|
|
||||||
self.setBlockType(addedHash, header)
|
|
||||||
retData = addedHash
|
|
||||||
return retData
|
return retData
|
||||||
|
|
||||||
def introduceNode(self):
|
def introduceNode(self):
|
||||||
|
|
|
@ -26,6 +26,10 @@ class Unknown(Exception):
|
||||||
class Invalid(Exception):
|
class Invalid(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# block exceptions
|
||||||
|
class InvalidMetadata(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
# network level exceptions
|
# network level exceptions
|
||||||
class MissingPort(Exception):
|
class MissingPort(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
'''
|
||||||
|
Onionr - P2P Microblogging Platform & Social network
|
||||||
|
|
||||||
|
This file defines values and requirements used by Onionr
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
class OnionrValues:
|
||||||
|
def __init__(self):
|
||||||
|
self.passwordLength = 20
|
||||||
|
self.blockMetadataLengths = {'meta': 1000, 'sig': 88, 'signer': 64, 'time': 10, 'powRandomToken': '1000'}
|
Loading…
Reference in New Issue