progress in removing core

master
Kevin Froman 2019-07-25 11:14:13 -05:00
parent 3d50dbcaac
commit 19fa128710
14 changed files with 114 additions and 449 deletions

View File

@ -17,8 +17,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
from coredb import dbfiles
import sqlite3, os
from coredb import dbfiles
import filepaths
def createAddressDB():
'''
@ -116,6 +117,9 @@ def createBlockDB():
def createBlockDataDB():
if os.path.exists(dbfiles.block_data_db):
raise FileExistsError("Block data database already exists")
else:
if not os.path.exists(filepaths.block_data_location):
os.mkdir(filepaths.block_data_location)
conn = sqlite3.connect(dbfiles.block_data_db)
c = conn.cursor()
c.execute('''CREATE TABLE blockData(

View File

@ -4,6 +4,7 @@ if not home.endswith('/'): home += '/'
usage_file = home + 'disk-usage.txt'
block_data_location = home + 'blocks/'
contacts_location = home + 'contacts/'
public_API_host_file = home + 'public-host.txt'
private_API_host_file = home + 'private-host.txt'
bootstrap_file_location = 'static-data/bootstrap-nodes.txt'

View File

@ -32,7 +32,7 @@ if sys.version_info[0] == 2 or sys.version_info[1] < MIN_PY_VERSION:
from utils import detectoptimization
if detectoptimization.detect_optimization():
sys.stderr.write('Error, Onionr cannot be run in optimized mode\n')
sys.stderr.write('Error, Onionr cannot be run with an optimized Python interpreter\n')
sys.exit(1)
from utils import createdirs
createdirs.create_dirs()

View File

@ -18,7 +18,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
from . import generate, hashers, getourkeypair, signing, encryption
from . import generate, hashers, getourkeypair, signing, encryption, cryptoutils
generate_deterministic = generate.generate_deterministic
generate = generate.generate_pub_key
keypair = getourkeypair.get_keypair()

View File

@ -1,6 +1,26 @@
import nacl.signing, nacl.encoding
import nacl.signing, nacl.encoding, nacl.pwhash
import onionrexceptions
from onionrutils import bytesconverter
def generate_pub_key():
'''Generate a Ed25519 public key pair, return tuple of base32encoded 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())
def generate_deterministic(passphrase, bypassCheck=False):
'''Generate a Ed25519 public key pair from a password'''
passStrength = 25
passphrase = bytesconverter.str_to_bytes(passphrase) # Convert to bytes if not already
# Validate passphrase length
if not bypassCheck:
if len(passphrase) < passStrength:
raise onionrexceptions.PasswordStrengthError("Passphase must be at least %s characters" % (passStrength,))
# KDF values
kdf = nacl.pwhash.argon2id.kdf
salt = b"U81Q7llrQcdTP0Ux" # Does not need to be unique or secret, but must be 16 bytes
ops = nacl.pwhash.argon2id.OPSLIMIT_SENSITIVE
mem = nacl.pwhash.argon2id.MEMLIMIT_SENSITIVE
key = kdf(32, passphrase, salt, opslimit=ops, memlimit=mem) # Generate seed for ed25519 key
key = nacl.signing.SigningKey(key)
return (key.verify_key.encode(nacl.encoding.Base32Encoder).decode(), key.encode(nacl.encoding.Base32Encoder).decode())

View File

@ -34,264 +34,6 @@ PLUGIN_VERSION = '0.0.1'
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
import sentboxdb, mailapi, loadinbox # import after path insert
flask_blueprint = mailapi.flask_blueprint
"""
def draw_border(text):
# This function taken from https://stackoverflow.com/a/20757491 by https://stackoverflow.com/users/816449/bunyk, under https://creativecommons.org/licenses/by-sa/3.0/
lines = text.splitlines()
width = max(len(s) for s in lines)
res = ['' + '' * width + '']
for s in lines:
res.append('' + (s + ' ' * width)[:width] + '')
res.append('' + '' * width + '')
return '\n'.join(res)
class MailStrings:
def __init__(self, mailInstance):
self.mailInstance = mailInstance
self.programTag = 'OnionrMail v%s' % (PLUGIN_VERSION)
choices = ['view inbox', 'view sentbox', 'send message', 'toggle pseudonymity', 'quit']
self.mainMenuChoices = choices
self.mainMenu = '''-----------------
1. %s
2. %s
3. %s
4. %s
5. %s''' % (choices[0], choices[1], choices[2], choices[3], choices[4])
class OnionrMail:
def __init__(self, pluginapi):
self.strings = MailStrings(self)
self.sentboxTools = sentboxdb.SentBox()
self.sentboxList = []
self.sentMessages = {}
self.doSigs = True
return
def inbox(self):
blockCount = 0
pmBlockMap = {}
pmBlocks = {}
logger.info('Decrypting messages...', terminal=True)
choice = ''
displayList = []
subject = ''
# this could use a lot of memory if someone has received a lot of messages
for blockHash in blockmetadb.get_blocks_by_type('pm'):
pmBlocks[blockHash] = Block(blockHash, core=self.myCore)
pmBlocks[blockHash].decrypt()
blockCount = 0
for blockHash in pmBlocks:
if not pmBlocks[blockHash].decrypted:
continue
blockCount += 1
pmBlockMap[blockCount] = blockHash
block = pmBlocks[blockHash]
senderKey = block.signer
try:
senderKey = senderKey.decode()
except AttributeError:
pass
senderDisplay = onionrusers.OnionrUser(self.myCore, senderKey).getName()
if senderDisplay == 'anonymous':
senderDisplay = senderKey
blockDate = pmBlocks[blockHash].getDate().strftime("%m/%d %H:%M")
try:
subject = pmBlocks[blockHash].bmetadata['subject']
except KeyError:
subject = ''
displayList.append('%s. %s - %s - <%s>: %s' % (blockCount, blockDate, senderDisplay[:12], subject[:10], blockHash))
while choice not in ('-q', 'q', 'quit'):
for i in displayList:
logger.info(i, terminal=True)
try:
choice = logger.readline('Enter a block number, -r to refresh, or -q to stop: ').strip().lower()
except (EOFError, KeyboardInterrupt):
choice = '-q'
if choice in ('-q', 'q', 'quit'):
continue
if choice in ('-r', 'r', 'refresh'):
# dirty hack
self.inbox()
return
try:
choice = int(choice)
except ValueError:
pass
else:
try:
pmBlockMap[choice]
readBlock = pmBlocks[pmBlockMap[choice]]
except KeyError:
pass
else:
cancel = ''
readBlock.verifySig()
senderDisplay = bytesconverter.bytes_to_str(readBlock.signer)
if len(senderDisplay.strip()) == 0:
senderDisplay = 'Anonymous'
logger.info('Message received from %s' % (senderDisplay,), terminal=True)
logger.info('Valid signature: %s' % readBlock.validSig, terminal=True)
if not readBlock.validSig:
logger.warn('This message has an INVALID/NO signature. ANYONE could have sent this message.', terminal=True)
cancel = logger.readline('Press enter to continue to message, or -q to not open the message (recommended).')
print('')
if cancel != '-q':
try:
print(draw_border(escapeansi.escape_ANSI(readBlock.bcontent.decode().strip())))
except ValueError:
logger.warn('Error presenting message. This is usually due to a malformed or blank message.', terminal=True)
pass
if readBlock.validSig:
reply = logger.readline("Press enter to continue, or enter %s to reply" % ("-r",))
print('')
if reply == "-r":
self.draft_message(bytesconverter.bytes_to_str(readBlock.signer,))
else:
logger.readline("Press enter to continue")
print('')
return
def sentbox(self):
'''
Display sent mail messages
'''
entering = True
while entering:
self.get_sent_list()
logger.info('Enter a block number or -q to return', terminal=True)
try:
choice = input('>')
except (EOFError, KeyboardInterrupt) as e:
entering = False
else:
try:
choice = int(choice) - 1
except ValueError:
pass
else:
try:
self.sentboxList[int(choice)]
except (IndexError, ValueError) as e:
logger.warn('Invalid block.', terminal=True)
else:
logger.info('Sent to: ' + self.sentMessages[self.sentboxList[int(choice)]][1], terminal=True)
# Print ansi escaped sent message
logger.info(escapeansi.escape_ANSI(self.sentMessages[self.sentboxList[int(choice)]][0]), terminal=True)
input('Press enter to continue...')
finally:
if choice == '-q':
entering = False
return
def get_sent_list(self, display=True):
count = 1
self.sentboxList = []
self.sentMessages = {}
for i in self.sentboxTools.listSent():
self.sentboxList.append(i['hash'])
self.sentMessages[i['hash']] = (bytesconverter.bytes_to_str(i['message']), i['peer'], i['subject'])
if display:
logger.info('%s. %s - %s - (%s) - %s' % (count, i['hash'], i['peer'][:12], i['subject'], i['date']), terminal=True)
count += 1
return json.dumps(self.sentMessages)
def draft_message(self, recip=''):
message = ''
newLine = ''
subject = ''
entering = False
if len(recip) == 0:
entering = True
while entering:
try:
recip = logger.readline('Enter peer address, or -q to stop:').strip()
if recip in ('-q', 'q'):
raise EOFError
if not stringvalidators.validate_pub_key(recip):
raise onionrexceptions.InvalidPubkey('Must be a valid ed25519 base32 encoded public key')
except onionrexceptions.InvalidPubkey:
logger.warn('Invalid public key', terminal=True)
except (KeyboardInterrupt, EOFError):
entering = False
else:
break
else:
# if -q or ctrl-c/d, exit function here, otherwise we successfully got the public key
return
try:
subject = logger.readline('Message subject: ')
except (KeyboardInterrupt, EOFError):
pass
cancelEnter = False
logger.info('Enter your message, stop by entering -q on a new line. -c to cancel', terminal=True)
while newLine != '-q':
try:
newLine = input()
except (KeyboardInterrupt, EOFError):
cancelEnter = True
if newLine == '-c':
cancelEnter = True
break
if newLine == '-q':
continue
newLine += '\n'
message += newLine
if not cancelEnter:
logger.info('Inserting encrypted message as Onionr block....', terminal=True)
blockID = self.myCore.insertBlock(message, header='pm', encryptType='asym', asymPeer=recip, sign=self.doSigs, meta={'subject': subject})
def toggle_signing(self):
self.doSigs = not self.doSigs
def menu(self):
choice = ''
while True:
sigMsg = 'Message Signing: %s'
logger.info(self.strings.programTag + '\n\nUser ID: ' + self.myCore._crypto.pubKey, terminal=True)
if self.doSigs:
sigMsg = sigMsg % ('enabled',)
else:
sigMsg = sigMsg % ('disabled (Your messages cannot be trusted)',)
if self.doSigs:
logger.info(sigMsg, terminal=True)
else:
logger.warn(sigMsg, terminal=True)
logger.info(self.strings.mainMenu.title(), terminal=True) # print out main menu
try:
choice = logger.readline('Enter 1-%s:\n' % (len(self.strings.mainMenuChoices))).lower().strip()
except (KeyboardInterrupt, EOFError):
choice = '5'
if choice in (self.strings.mainMenuChoices[0], '1'):
self.inbox()
elif choice in (self.strings.mainMenuChoices[1], '2'):
self.sentbox()
elif choice in (self.strings.mainMenuChoices[2], '3'):
self.draft_message()
elif choice in (self.strings.mainMenuChoices[3], '4'):
self.toggle_signing()
elif choice in (self.strings.mainMenuChoices[4], '5'):
logger.info('Goodbye.', terminal=True)
break
elif choice == '':
pass
else:
logger.warn('Invalid choice.', terminal=True)
return """
def add_deleted(keyStore, bHash):
existing = keyStore.get('deleted_mail')

View File

@ -7,13 +7,12 @@ import nacl.signing, nacl.hash, nacl.encoding
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
print("Test directory:", TEST_DIR)
os.environ["ONIONR_HOME"] = TEST_DIR
import core, onionr
c = core.Core()
import onionrblocks
from utils import createdirs
createdirs.create_dirs()
class OnionrBlockTests(unittest.TestCase):
def test_plaintext_insert(self):
message = 'hello world'
c.insertBlock(message)
onionrblocks.insert(message)
unittest.main()

View File

@ -6,35 +6,34 @@ TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
print("Test directory:", TEST_DIR)
os.environ["ONIONR_HOME"] = TEST_DIR
from urllib.request import pathname2url
import core, onionr
c = core.Core()
from coredb import keydb
from utils import createdirs
createdirs.create_dirs()
class OnionrTests(unittest.TestCase):
def test_address_add(self):
testAddresses = ['facebookcorewwwi.onion', '56kmnycrvepfarolhnx6t2dvmldfeyg7jdymwgjb7jjzg47u2lqw2sad.onion', '5bvb5ncnfr4dlsfriwczpzcvo65kn7fnnlnt2ln7qvhzna2xaldq.b32.i2p']
for address in testAddresses:
c.addAddress(address)
dbAddresses = c.listAdders()
keydb.addkeys.add_address(address)
dbAddresses = keydb.listkeys.list_adders()
for address in testAddresses:
self.assertIn(address, dbAddresses)
invalidAddresses = [None, '', ' ', '\t', '\n', ' test ', 24, 'fake.onion', 'fake.b32.i2p']
for address in invalidAddresses:
try:
c.addAddress(address)
keydb.addkeys.add_address(address)
except TypeError:
pass
dbAddresses = c.listAdders()
dbAddresses = keydb.listkeys.list_adders()
for address in invalidAddresses:
self.assertNotIn(address, dbAddresses)
def test_address_info(self):
adder = 'nytimes3xbfgragh.onion'
c.addAddress(adder)
self.assertNotEqual(c.getAddressInfo(adder, 'success'), 1000)
c.setAddressInfo(adder, 'success', 1000)
self.assertEqual(c.getAddressInfo(adder, 'success'), 1000)
keydb.addkeys.add_address(adder)
self.assertNotEqual(keydb.transportinfo.get_address_info(adder, 'success'), 1000)
keydb.transportinfo.set_address_info(adder, 'success', 1000)
self.assertEqual(keydb.transportinfo.get_address_info(adder, 'success'), 1000)
unittest.main()

View File

@ -1,70 +0,0 @@
#!/usr/bin/env python3
import sys, os
sys.path.append(".")
import unittest, uuid, sqlite3
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
print("Test directory:", TEST_DIR)
os.environ["ONIONR_HOME"] = TEST_DIR
from urllib.request import pathname2url
import core, onionr
core.Core()
class OnionrTests(unittest.TestCase):
def test_peer_db_creation(self):
try:
dburi = 'file:{}?mode=rw'.format(pathname2url(TEST_DIR + 'peers.db'))
conn = sqlite3.connect(dburi, uri=True, timeout=30)
cursor = conn.cursor()
conn.close()
except sqlite3.OperationalError:
self.assertTrue(False)
else:
self.assertTrue(True)
def test_block_db_creation(self):
try:
dburi = 'file:{}?mode=rw'.format(pathname2url(TEST_DIR + 'blocks.db'))
conn = sqlite3.connect(dburi, uri=True, timeout=30)
cursor = conn.cursor()
conn.close()
except sqlite3.OperationalError:
self.assertTrue(False)
else:
self.assertTrue(True)
def test_forward_keys_db_creation(self):
try:
dburi = 'file:{}?mode=rw'.format(pathname2url(TEST_DIR + 'forward-keys.db'))
conn = sqlite3.connect(dburi, uri=True, timeout=30)
cursor = conn.cursor()
conn.close()
except sqlite3.OperationalError:
self.assertTrue(False)
else:
self.assertTrue(True)
def test_address_db_creation(self):
try:
dburi = 'file:{}?mode=rw'.format(pathname2url(TEST_DIR + 'address.db'))
conn = sqlite3.connect(dburi, uri=True, timeout=30)
cursor = conn.cursor()
conn.close()
except sqlite3.OperationalError:
self.assertTrue(False)
else:
self.assertTrue(True)
def blacklist_db_creation(self):
try:
dburi = 'file:{}?mode=rw'.format(pathname2url(TEST_DIR + 'blacklist.db'))
conn = sqlite3.connect(dburi, uri=True, timeout=30)
cursor = conn.cursor()
conn.close()
except sqlite3.OperationalError:
self.assertTrue(False)
else:
self.assertTrue(True)
unittest.main()

View File

@ -4,11 +4,12 @@ sys.path.append(".")
import unittest, uuid
TEST_DIR_1 = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
TEST_DIR_2 = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
import core, onionr, time
import onionr, time
import onionrexceptions
import onionrexceptions, onionrcrypto as crypto
from onionrusers import onionrusers
from onionrusers import contactmanager
from utils import createdirs
class OnionrForwardSecrecyTests(unittest.TestCase):
'''
@ -17,23 +18,23 @@ class OnionrForwardSecrecyTests(unittest.TestCase):
def test_forward_encrypt(self):
os.environ["ONIONR_HOME"] = TEST_DIR_1
o = onionr.Onionr()
createdirs.create_dirs()
friend = o.onionrCore._crypto.generatePubKey()
friend = crypto.generate()
friendUser = onionrusers.OnionrUser(o.onionrCore, friend[0], saveUser=True)
friendUser = onionrusers.OnionrUser(friend[0], saveUser=True)
for x in range(5):
message = 'hello world %s' % (random.randint(1, 1000))
forwardKey = friendUser.generateForwardKey()
fakeForwardPair = o.onionrCore._crypto.generatePubKey()
fakeForwardPair = crypto.generate()
self.assertTrue(friendUser.addForwardKey(fakeForwardPair[0]))
encrypted = friendUser.forwardEncrypt(message)
decrypted = o.onionrCore._crypto.pubKeyDecrypt(encrypted[0], privkey=fakeForwardPair[1], encodedData=True)
decrypted = crypto.encryption.pub_key_decrypt(encrypted[0], privkey=fakeForwardPair[1], encodedData=True)
self.assertEqual(decrypted, message.encode())
return

View File

@ -8,34 +8,32 @@ from onionrutils import stringvalidators, mnemonickeys
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
print("Test directory:", TEST_DIR)
os.environ["ONIONR_HOME"] = TEST_DIR
import core, onionr, onionrexceptions
import onionrcrypto as crypto, onionrexceptions
c = core.Core()
crypto = c._crypto
class OnionrCryptoTests(unittest.TestCase):
def test_blake2b(self):
self.assertEqual(crypto.blake2bHash('test'), crypto.blake2bHash(b'test'))
self.assertEqual(crypto.blake2bHash(b'test'), crypto.blake2bHash(b'test'))
self.assertEqual(crypto.hashers.blake2b_hash('test'), crypto.hashers.blake2b_hash(b'test'))
self.assertEqual(crypto.hashers.blake2b_hash(b'test'), crypto.hashers.blake2b_hash(b'test'))
self.assertNotEqual(crypto.blake2bHash(''), crypto.blake2bHash(b'test'))
self.assertNotEqual(crypto.hashers.blake2b_hash(''), crypto.hashers.blake2b_hash(b'test'))
try:
crypto.blake2bHash(None)
crypto.hashers.blake2b_hash(None)
except nacl.exceptions.TypeError:
pass
else:
self.assertTrue(False)
self.assertEqual(nacl.hash.blake2b(b'test'), crypto.blake2bHash(b'test'))
self.assertEqual(nacl.hash.blake2b(b'test'), crypto.hashers.blake2b_hash(b'test'))
def test_sha3256(self):
hasher = hashlib.sha3_256()
self.assertEqual(crypto.sha3Hash('test'), crypto.sha3Hash(b'test'))
self.assertEqual(crypto.sha3Hash(b'test'), crypto.sha3Hash(b'test'))
self.assertEqual(crypto.hashers.sha3_hash('test'), crypto.hashers.sha3_hash(b'test'))
self.assertEqual(crypto.hashers.sha3_hash(b'test'), crypto.hashers.sha3_hash(b'test'))
self.assertNotEqual(crypto.sha3Hash(''), crypto.sha3Hash(b'test'))
self.assertNotEqual(crypto.hashers.sha3_hash(''), crypto.hashers.sha3_hash(b'test'))
try:
crypto.sha3Hash(None)
crypto.hashers.sha3_hash(None)
except TypeError:
pass
else:
@ -43,21 +41,21 @@ class OnionrCryptoTests(unittest.TestCase):
hasher.update(b'test')
normal = hasher.hexdigest()
self.assertEqual(crypto.sha3Hash(b'test'), normal)
self.assertEqual(crypto.hashers.sha3_hash(b'test'), normal)
def valid_default_id(self):
self.assertTrue(stringvalidators.validate_pub_key(crypto.pubKey))
self.assertTrue(stringvalidators.validate_pub_key(crypto.pub_key))
def test_human_readable_length(self):
human = mnemonickeys.get_human_readable_ID(c)
human = mnemonickeys.get_human_readable_ID()
self.assertTrue(len(human.split(' ')) == 32)
def test_safe_compare(self):
self.assertTrue(crypto.safeCompare('test', 'test'))
self.assertTrue(crypto.safeCompare('test', b'test'))
self.assertFalse(crypto.safeCompare('test', 'test2'))
self.assertTrue(crypto.cryptoutils.safe_compare('test', 'test'))
self.assertTrue(crypto.cryptoutils.safe_compare('test', b'test'))
self.assertFalse(crypto.cryptoutils.safe_compare('test', 'test2'))
try:
crypto.safeCompare('test', None)
crypto.cryptoutils.safe_compare('test', None)
except TypeError:
pass
else:
@ -67,82 +65,53 @@ class OnionrCryptoTests(unittest.TestCase):
# Small chance that the randomized list will be same. Rerun test a couple times if it fails
startList = ['cat', 'dog', 'moose', 'rabbit', 'monkey', 'crab', 'human', 'dolphin', 'whale', 'etc'] * 10
self.assertNotEqual(startList, list(crypto.randomShuffle(startList)))
self.assertTrue(len(list(crypto.randomShuffle(startList))) == len(startList))
self.assertNotEqual(startList, list(crypto.cryptoutils.random_shuffle(startList)))
self.assertTrue(len(list(crypto.cryptoutils.random_shuffle(startList))) == len(startList))
def test_asymmetric(self):
keyPair = crypto.generatePubKey()
keyPair2 = crypto.generatePubKey()
keyPair = crypto.generate()
keyPair2 = crypto.generate()
message = "hello world"
self.assertTrue(len(crypto.pubKeyEncrypt(message, keyPair2[0], encodedData=True)) > 0)
encrypted = crypto.pubKeyEncrypt(message, keyPair2[0], encodedData=False)
decrypted = crypto.pubKeyDecrypt(encrypted, privkey=keyPair2[1], encodedData=False)
self.assertTrue(len(crypto.encryption.pub_key_encrypt(message, keyPair2[0], encodedData=True)) > 0)
encrypted = crypto.encryption.pub_key_encrypt(message, keyPair2[0], encodedData=False)
decrypted = crypto.encryption.pub_key_decrypt(encrypted, privkey=keyPair2[1], encodedData=False)
self.assertTrue(decrypted.decode() == message)
try:
crypto.pubKeyEncrypt(None, keyPair2[0])
crypto.encryption.pub_key_encrypt(None, keyPair2[0])
except TypeError:
pass
else:
self.assertTrue(False)
blankMessage = crypto.pubKeyEncrypt('', keyPair2[0])
self.assertTrue('' == crypto.pubKeyDecrypt(blankMessage, privkey=keyPair2[1], encodedData=False).decode())
blankMessage = crypto.encryption.pub_key_encrypt('', keyPair2[0])
self.assertTrue('' == crypto.encryption.pub_key_decrypt(blankMessage, privkey=keyPair2[1], encodedData=False).decode())
# Try to encrypt arbitrary bytes
crypto.pubKeyEncrypt(os.urandom(32), keyPair2[0])
def test_symmetric(self):
dataString = "this is a secret message"
dataBytes = dataString.encode()
key = b"tttttttttttttttttttttttttttttttt"
invalidKey = b'tttttttttttttttttttttttttttttttb'
encrypted = crypto.symmetricEncrypt(dataString, key, returnEncoded=True)
decrypted = crypto.symmetricDecrypt(encrypted, key, encodedMessage=True)
self.assertTrue(dataString == decrypted.decode())
try:
crypto.symmetricDecrypt(encrypted, invalidKey, encodedMessage=True)
except nacl.exceptions.CryptoError:
pass
else:
self.assertFalse(True)
try:
crypto.symmetricEncrypt(None, key, returnEncoded=True)
except AttributeError:
pass
else:
self.assertFalse(True)
crypto.symmetricEncrypt("string", key, returnEncoded=True)
try:
crypto.symmetricEncrypt("string", None, returnEncoded=True)
except nacl.exceptions.TypeError:
pass
else:
self.assertFalse(True)
crypto.encryption.pub_key_encrypt(os.urandom(32), keyPair2[0])
def test_deterministic(self):
password = os.urandom(32)
gen = crypto.generateDeterministic(password)
gen = crypto.generate_deterministic(password)
self.assertTrue(stringvalidators.validate_pub_key(gen[0]))
try:
crypto.generateDeterministic('weakpassword')
crypto.generate_deterministic('weakpassword')
except onionrexceptions.PasswordStrengthError:
pass
else:
self.assertFalse(True)
try:
crypto.generateDeterministic(None)
crypto.generate_deterministic(None)
except TypeError:
pass
else:
self.assertFalse(True)
gen = crypto.generateDeterministic('weakpassword', bypassCheck=True)
gen = crypto.generate_deterministic('weakpassword', bypassCheck=True)
password = base64.b64encode(os.urandom(32))
gen1 = crypto.generateDeterministic(password)
gen2 = crypto.generateDeterministic(password)
gen1 = crypto.generate_deterministic(password)
gen2 = crypto.generate_deterministic(password)
self.assertFalse(gen == gen1)
self.assertTrue(gen1 == gen2)
self.assertTrue(stringvalidators.validate_pub_key(gen1[0]))

View File

@ -6,37 +6,38 @@ import json
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
print("Test directory:", TEST_DIR)
os.environ["ONIONR_HOME"] = TEST_DIR
import core, onionr
c = core.Core()
import onionrexceptions
from onionrusers import onionrusers
from onionrusers import contactmanager
import onionrcrypto as crypto
from coredb import keydb
from utils import identifyhome, createdirs
createdirs.create_dirs()
class OnionrUserTests(unittest.TestCase):
'''
Tests both the onionrusers class and the contactmanager (which inherits it)
'''
def test_users(self):
keypair = c._crypto.generatePubKey()
onionrusers.OnionrUser(c, keypair[0])
keypair = crypto.generate()
onionrusers.OnionrUser(keypair[0])
return
def test_contact_init_no_save(self):
contact = c._crypto.generatePubKey()[0]
contact = contactmanager.ContactManager(c, contact)
self.assertFalse(contact.publicKey in c.listPeers())
contact = crypto.generate()[0]
contact = contactmanager.ContactManager(contact)
self.assertFalse(contact.publicKey in keydb.listkeys.list_peers())
def test_contact_create(self):
contact = c._crypto.generatePubKey()[0]
contact = contactmanager.ContactManager(c, contact, saveUser=True)
self.assertTrue(contact.publicKey in c.listPeers())
contact = crypto.generate()[0]
contact = contactmanager.ContactManager(contact, saveUser=True)
self.assertTrue(contact.publicKey in keydb.listkeys.list_peers())
def test_contact_set_info(self):
contact = c._crypto.generatePubKey()[0]
contact = contactmanager.ContactManager(c, contact, saveUser=True)
fileLocation = '%s/contacts/%s.json' % (c.dataDir, contact.publicKey)
contact = crypto.generate()[0]
contact = contactmanager.ContactManager(contact, saveUser=True)
fileLocation = '%s/contacts/%s.json' % (identifyhome.identify_home(), contact.publicKey)
contact.set_info('alias', 'bob')
self.assertTrue(os.path.exists(fileLocation))
@ -47,9 +48,9 @@ class OnionrUserTests(unittest.TestCase):
self.assertEqual(data['alias'], 'bob')
def test_contact_get_info(self):
contact = c._crypto.generatePubKey()[0]
contact = contactmanager.ContactManager(c, contact, saveUser=True)
fileLocation = '%s/contacts/%s.json' % (c.dataDir, contact.publicKey)
contact = crypto.generate()[0]
contact = contactmanager.ContactManager(contact, saveUser=True)
fileLocation = '%s/contacts/%s.json' % (identifyhome.identify_home(), contact.publicKey)
with open(fileLocation, 'w') as contactFile:
contactFile.write('{"alias": "bob"}')
@ -59,16 +60,16 @@ class OnionrUserTests(unittest.TestCase):
self.assertEqual(contact.get_info('fail'), None)
def test_encrypt(self):
contactPair = c._crypto.generatePubKey()
contact = contactmanager.ContactManager(c, contactPair[0], saveUser=True)
contactPair = crypto.generate()
contact = contactmanager.ContactManager(contactPair[0], saveUser=True)
encrypted = contact.encrypt('test')
decrypted = c._crypto.pubKeyDecrypt(encrypted, privkey=contactPair[1], encodedData=True).decode()
decrypted = crypto.encryption.pub_key_decrypt(encrypted, privkey=contactPair[1], encodedData=True).decode()
self.assertEqual('test', decrypted)
def test_delete_contact(self):
contact = c._crypto.generatePubKey()[0]
contact = contactmanager.ContactManager(c, contact, saveUser=True)
fileLocation = '%s/contacts/%s.json' % (c.dataDir, contact.publicKey)
contact = crypto.generate()[0]
contact = contactmanager.ContactManager(contact, saveUser=True)
fileLocation = '%s/contacts/%s.json' % (identifyhome.identify_home(), contact.publicKey)
self.assertFalse(os.path.exists(fileLocation))
with open(fileLocation, 'w') as contactFile:
contactFile.write('{"alias": "test"}')

View File

@ -5,11 +5,8 @@ import unittest, uuid
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
print("Test directory:", TEST_DIR)
os.environ["ONIONR_HOME"] = TEST_DIR
import core, onionr
from onionrutils import stringvalidators
core.Core()
class OnionrValidations(unittest.TestCase):
def test_peer_validator(self):
@ -50,7 +47,6 @@ class OnionrValidations(unittest.TestCase):
# Test ed25519 public key validity
valids = ['JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ====', 'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIRRQ']
invalid = [None, '', ' ', 'dfsg', '\n', 'JZ5VE72GUS3C7BOHDRIYZX4B5U5EJMCMLKHLYCVBQQF3UKHYIR$Q====']
c = core.Core()
for valid in valids:
print('testing', valid)

View File

@ -8,6 +8,8 @@ def create_dirs():
os.mkdir(home)
if not os.path.exists(filepaths.block_data_location):
os.mkdir(filepaths.block_data_location)
if not os.path.exists(filepaths.contacts_location):
os.mkdir(filepaths.contacts_location)
for db in dbcreator.create_funcs:
try: