From e1e585776d8ba3d411e42bd7ebc85ce919a8e291 Mon Sep 17 00:00:00 2001 From: nolash Date: Sat, 9 Jan 2021 20:25:47 +0100 Subject: [PATCH] Use keyapi for address generation in import key in dictkeystore --- CHANGELOG | 9 ++- crypto_dev_signer/eth/signer/defaultsigner.py | 2 +- crypto_dev_signer/eth/web3ext/middleware.py | 2 +- crypto_dev_signer/keystore/__init__.py | 1 + crypto_dev_signer/keystore/interface.py | 12 +++- crypto_dev_signer/runnable/signer.py | 3 +- setup.py | 2 +- test/test_keystore_dict.py | 67 +++++++++++++++++++ ...keystore.py => test_keystore_reference.py} | 0 test/test_sign.py | 1 + ...--00a329c0648769a73afac7f9381e08fb43dbea72 | 1 + 11 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 test/test_keystore_dict.py rename test/{test_keystore.py => test_keystore_reference.py} (100%) create mode 100644 test/testdata/UTC--2021-01-08T18-37-01.187235289Z--00a329c0648769a73afac7f9381e08fb43dbea72 diff --git a/CHANGELOG b/CHANGELOG index 9959c74..7daaddc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,11 @@ -- 0.4.10 +* 0.4.13-unreleased + - Implement DictKeystore + - Remove unused insert_key method in keystore interface +* 0.4.12 + - Enforce hex strings in signer backend for sign message +* 0.4.11 + - Add missing middleware param for eth_sign method +* 0.4.10 - Add bytes and string handling in inner signer backend * 0.4.9 - Accept string message format for message signing diff --git a/crypto_dev_signer/eth/signer/defaultsigner.py b/crypto_dev_signer/eth/signer/defaultsigner.py index 9c2a7d6..eacfcda 100644 --- a/crypto_dev_signer/eth/signer/defaultsigner.py +++ b/crypto_dev_signer/eth/signer/defaultsigner.py @@ -47,7 +47,7 @@ class ReferenceSigner(Signer): z = None if type(message).__name__ == 'str': logg.debug('signing message in "str" format: {}'.format(message)) - z = k.sign_msg(message.encode('utf-8')) + z = k.sign_msg(bytes.fromhex(message)) elif type(message).__name__ == 'bytes': logg.debug('signing message in "bytes" format: {}'.format(message.hex())) z = k.sign_msg(message) diff --git a/crypto_dev_signer/eth/web3ext/middleware.py b/crypto_dev_signer/eth/web3ext/middleware.py index ab0df1b..5f72ba9 100644 --- a/crypto_dev_signer/eth/web3ext/middleware.py +++ b/crypto_dev_signer/eth/web3ext/middleware.py @@ -99,7 +99,7 @@ class PlatformMiddleware: s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0) ipc_provider_workaround = s.connect(self.ipcaddr) logg.info('redirecting method {} params {} original paramsĀ {}'.format(method, params, suspect_params)) - o = jsonrpc_request(method, params[0], params[1]) + o = jsonrpc_request(method, params) j = json.dumps(o) logg.debug('send {}'.format(j)) s.send(j.encode('utf-8')) diff --git a/crypto_dev_signer/keystore/__init__.py b/crypto_dev_signer/keystore/__init__.py index 44f35f0..15332dd 100644 --- a/crypto_dev_signer/keystore/__init__.py +++ b/crypto_dev_signer/keystore/__init__.py @@ -5,3 +5,4 @@ from eth_keys.backends import NativeECCBackend keyapi = KeyAPI(NativeECCBackend) from .postgres import ReferenceKeystore +from .dict import DictKeystore diff --git a/crypto_dev_signer/keystore/interface.py b/crypto_dev_signer/keystore/interface.py index c349347..6754ecf 100644 --- a/crypto_dev_signer/keystore/interface.py +++ b/crypto_dev_signer/keystore/interface.py @@ -1,6 +1,9 @@ # standard imports import os +# third-party imports +import eth_keyfile + # local imports from . import keyapi @@ -25,6 +28,11 @@ class Keystore: raise NotImplementedError - def insert_key(self, pk, password=None): - raise NotImplementedError + def import_keystore_data(self, keystore_content, password=''): + #private_key = w3.eth.account.decrypt(keystore_content, password) + private_key = eth_keyfile.decode_keyfile_json(keystore_content, password.encode('utf-8')) + return self.import_raw_key(private_key, password) + def import_keystore_file(self, keystore_file, password=''): + keystore_content = eth_keyfile.load_keyfile(keystore_file) + return self.import_keystore_data(keystore_content, password) diff --git a/crypto_dev_signer/runnable/signer.py b/crypto_dev_signer/runnable/signer.py index 59c46db..67d9c46 100755 --- a/crypto_dev_signer/runnable/signer.py +++ b/crypto_dev_signer/runnable/signer.py @@ -120,7 +120,8 @@ def eth_sign(p): message_type = type(p[1]).__name__ if message_type != 'str': raise ValueError('invalid message format, must be {}, not {}'.format(message_type)) - return signer.signEthereumMessage(p[0], p[1].encode('utf-8')) + z = signer.signEthereumMessage(p[0], p[1][2:]) + return str(z) methods = { diff --git a/setup.py b/setup.py index eace084..0f6ccbb 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ f.close() setup( name="crypto-dev-signer", - version="0.4.10", + version="0.4.13a2", description="A signer and keystore daemon and library for cryptocurrency software development", author="Louis Holbrook", author_email="dev@holbrook.no", diff --git a/test/test_keystore_dict.py b/test/test_keystore_dict.py new file mode 100644 index 0000000..1f1effb --- /dev/null +++ b/test/test_keystore_dict.py @@ -0,0 +1,67 @@ +#!/usr/bin/python + +# standard imports +import unittest +import logging +import base64 +import os + +# third-party imports +import psycopg2 +from psycopg2 import sql +from cryptography.fernet import Fernet, InvalidToken + +# local imports +from crypto_dev_signer.keystore import DictKeystore +from crypto_dev_signer.error import UnknownAccountError + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +script_dir = os.path.realpath(os.path.dirname(__file__)) + + +class TestDatabase(unittest.TestCase): + + conn = None + cur = None + symkey = None + address_hex = None + db = None + + def setUp(self): + logg.debug('setup') + # arbitrary value + #symkey_hex = 'E92431CAEE69313A7BE9E443C4ABEED9BF8157E9A13553B4D5D6E7D51B5021D9' + #self.symkey = bytes.fromhex(symkey_hex) + + #kw = { + # 'symmetric_key': self.symkey, + # } + self.db = DictKeystore() + + keystore_filepath = os.path.join(script_dir, 'testdata', 'UTC--2021-01-08T18-37-01.187235289Z--00a329c0648769a73afac7f9381e08fb43dbea72') + #f = open( + #s = f.read() + #f.close() + + self.address_hex = self.db.import_keystore_file(keystore_filepath, '')[2:] + + + def tearDown(self): + pass + + + def test_get_key(self): + logg.debug('getting {}'.format(self.address_hex)) + pk = self.db.get(self.address_hex, '') + + self.assertEqual(pk.public_key.to_checksum_address()[2:], self.address_hex) + + bogus_account = os.urandom(20).hex() + with self.assertRaises(UnknownAccountError): + self.db.get(bogus_account, '') + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_keystore.py b/test/test_keystore_reference.py similarity index 100% rename from test/test_keystore.py rename to test/test_keystore_reference.py diff --git a/test/test_sign.py b/test/test_sign.py index 5ce5c23..4d0676b 100644 --- a/test/test_sign.py +++ b/test/test_sign.py @@ -91,6 +91,7 @@ class TestSign(unittest.TestCase): s = ReferenceSigner(self.pk_getter) z = s.signEthereumMessage(tx_ints['from'], 'foo') z = s.signEthereumMessage(tx_ints['from'], b'foo') + logg.debug('zzz {}'.format(str(z))) if __name__ == '__main__': diff --git a/test/testdata/UTC--2021-01-08T18-37-01.187235289Z--00a329c0648769a73afac7f9381e08fb43dbea72 b/test/testdata/UTC--2021-01-08T18-37-01.187235289Z--00a329c0648769a73afac7f9381e08fb43dbea72 new file mode 100644 index 0000000..f5166b0 --- /dev/null +++ b/test/testdata/UTC--2021-01-08T18-37-01.187235289Z--00a329c0648769a73afac7f9381e08fb43dbea72 @@ -0,0 +1 @@ +{"address":"00a329c0648769a73afac7f9381e08fb43dbea72","crypto":{"cipher":"aes-128-ctr","ciphertext":"e06ab0b0c96e9b4b1f04259ec49d6c8c865bf6363b38b030ab4852fa471269b4","cipherparams":{"iv":"36d3d7781750d12d3802cfe74aed4434"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"94e82d24c10e2af9987b926b5e1a36ce8d03595535a96359ca6648485872d5ba"},"mac":"6cac102b8d4c25203ea52505fea7e0d0b1a70929a1561e2143df88a6b45784da"},"id":"0225f31c-36da-4dd7-95d8-c463bba04387","version":3} \ No newline at end of file