def test_2_key_import(self): dao_factory = factory(DAOMemoryFactory) server = KSIServer(self.id_server, dao_factory.get_server()) assert server.signer.key.has_private() and server.signer.key.can_sign() server.signer.import_public_keys("output/public_key." + SIGN_KEY_FORMAT) assert server.signer.key.publickey()
def test_1_key_generation(self): dao_factory = factory(DAOMemoryFactory) dao_memory_server = dao_factory.get_server() # type: DAOMemoryServer server = KSIServer(self.id_server, dao_memory_server) assert len(dao_memory_server.client_certificates) == 0 assert len(dao_memory_server.signed) == 0 assert server.signer.key and server.signer.key.has_private( ) and server.signer.key.publickey()
def test_3_missing_client_certificate(self): # This test works because the DAO memory share certificates among the client and server DAO dao_factory = factory(DAOMemoryFactory) server = KSIServer(self.id_server, dao_factory.get_server()) l = 8 keys = Keys(l=l, seed=b'SEED') client = KSIClient(server, dao_factory.get_client(), keys=keys) client.sign(b'AAAA') assert len(dao_factory.get_client().signatures) == 1 and len( dao_factory.get_server().signed) == 1
def test_all(self): dao_factory = factory(DAOMongoFactory) server = KSIServer(Identifier('server'), dao_factory.get_server()) keys = Keys(l=256, seed=b'SEED') client = KSIClient(server, dao_factory.get_client(), keys=keys) ref_cert = client.certificate mongo_cert = server.dao.get_user_certificate( client.certificate.id_client) self.assertTrue(ref_cert == mongo_cert) ref_msg = hash_factory(data=b'DATA').digest() sig = client.sign(ref_msg) client.verify(sig, client.certificate, ref_msg)
def test_verify(self): dao_factory = factory(DAOMemoryFactory) l = 512 keys = Keys(l=l, seed=b'SEED') client = KSIClient(KSIServer(Identifier("server"), dao_factory.get_server()), dao_factory.get_client(), keys=keys) message = b'DDDD' sig = client.sign(message) self.assertTrue(client.verify(sig, client.certificate, sig.message)) # Tampering with the hash chain sig.c_i.right_child.hash = b'1234567890' # This is an arbitrary value, any other than the original one would do self.assertFalse(client.verify(sig, client.certificate, sig.message))
def test_4_client_certificate_too_early(self): dao_factory = factory(DAOMemoryFactory) dao_memory_server = dao_factory.get_server() # type: DAOMemoryServer server = KSIServer(self.id_server, dao_factory.get_server()) l = 8 keys = Keys(l=l, seed=b'SEED2') client2 = KSIClient(server, dao_factory.get_client(), keys=keys, ID_C_str='client2') dao_memory_server.client_certificates[str( client2.certificate.id_client)].t_0 += timedelta(seconds=100) with self.assertRaises(ValueError): client2.sign(b'AAAA') assert len(dao_factory.get_client().signatures) == 1 and len( dao_memory_server.signed) == 1
keys = None # Importing saved keys from Keys benchmark with shelve.open(KEY_SHELVE_INPUT_FILE.format("Keys", HASH_ALGO, "l_" + str(l)), flag='r') as save: keys = save['keys'] # type: Keys assert keys is not None open(LOGGER_DEFAULT_OUTFILE, 'w+').close() print("l: \t{} / {}".format(l, _max_l)) dao_factory = factory(DAOMemoryFactory) server = KSIServer(Identifier("server"), dao_factory.get_server(), filename_private_key="/tmp/private.pem") client = KSIClient(server, dao_factory.get_client(), keys=keys, public_key_filename="/tmp/public.pem") # Benchmark Start client.sign(msg_to_sign) # Benchmark End logger = logging.getLogger(LOGGER_NAME) for h in logger.handlers: h.flush() logger.removeHandler(h)
logging.basicConfig(level=logging.INFO) # Filter messages to come only from the server's logger # for handler in logging.root.handlers: # handler.addFilter(logging.Filter("ksi.ksi_server.KSIServer")) app = Flask(__name__) auth = HTTPBasicAuth() SALT = b'KSI_IS_MAGIC' dao_factory = factory(DAOMongoFactory) dao = dao_factory.get_server() # type: DAOMongoServer ksi_server = KSIServer(Identifier("server"), dao, filename_private_key="/tmp/private_key." + SIGN_KEY_FORMAT) def hash_salt(s: str) -> bytes: return hash_factory(data=bytes(s, encoding='ascii') + SALT).digest() # The list of authorized users and their hash/salted passwords (this ought to move to a DB in the future...) user_dict = { 'client': hash_salt('password'), 'client2': hash_salt('password2') } def callback_log(x: TimestampResponse):
def test_sign_coverage(self): dao_factory = factory(DAOMemoryFactory) KSIClient(KSIServer(Identifier("server"), dao_factory.get_server()), dao_factory.get_client())
def test_sign(self): dao_factory = factory(DAOMemoryFactory) dao_memory_client = dao_factory.get_client() # type: DAOMemoryClient logging.basicConfig(level=logging.DEBUG) server_id = Identifier("server") server = KSIServer(server_id, dao_factory.get_server()) l = 8 keys = Keys(l=l, seed=b'SEED') client = KSIClient(server, dao_memory_client, keys=keys) # dao_memory_server.client_certificates[str(client.certificate.id_client)] = client.certificate sleep_counter = 2 sleep(sleep_counter) client.sign(b'AAAA') # Compute graphviz on the whole merkle graph g1 = graphviz.Digraph(name="after sign", directory="./output", format="dot", node_attr={"shape": "box"}) g1 = keys.hash_tree_root.to_graphviz(g1) g1.render() # Compute graphviz only the hash chain print("Signatures: ") for k, v in client.dao.signatures.items( ): # type: _sha3.SHA3, Signature print("[{k}] = {v}".format(k=k.hex(), v=v)) assert v.S_t.status_code == KSIErrorCodes.NO_ERROR g2 = graphviz.Digraph(name="hash chain", directory="./output", format="dot", node_attr={"shape": "box"}) g2 = v.c_i.to_graphviz(g2) g2.render() # +1 for "the sleep before publishing the signature" mechanism sleep_counter += 2 + 1 client.signatures = {} sleep(2) client.sign(b'BBBB') # Compute graphviz on the whole merkle graph g3 = graphviz.Digraph(name="after sign 2", directory="./output", format="dot", node_attr={"shape": "box"}) g3 = keys.hash_tree_root.to_graphviz(g3) g3.render() # Compute graphviz only the hash chain print("Signatures: ") for k, v in client.dao.signatures.items( ): # type: _sha3.SHA3, Signature print("[{k}] = {v}".format(k=k.hex(), v=v)) g4 = graphviz.Digraph(name="hash chain 2", directory="./output", format="dot", node_attr={"shape": "box"}) g4 = v.c_i.to_graphviz(g4) g4.render() sleep(l - sleep_counter - 1) with self.assertRaises(ValueError): client.sign(b'CCCC')