def from_json_dict(json_obj: dict): """ :param json_obj: A JSON representation of the TimestampResponse object :type json_obj: dict :return: A new TimestampResponse built from the json_obj parameter :rtype: TimestampResponse """ assert 'status_code' in json_obj assert 'x' in json_obj assert 'ID_C' in json_obj assert 'ID_S' in json_obj assert 't' in json_obj assert 'signature' in json_obj status_code = KSIErrorCodes[json_obj['status_code']] x = standard_b64decode(json_obj['x']) ID_C = Identifier(json_obj['ID_C'][len(IDENTIFIER_BASE_NAME):]) ID_S = Identifier(json_obj['ID_S'][len(IDENTIFIER_BASE_NAME):]) t = parse(json_obj['t']) if json_obj['signature'] == "None": signature = None else: signature = bytes(json_obj['signature'], encoding="ascii") res = TimestampResponse(x, ID_S, ID_C, t, status_code) res.signature = signature return res
def get_user_certificate(self, id_client: Identifier) -> Certificate: rec = self.client_certificates.find_one( {'ID_C': str(id_client).replace('.', '#')}) cert = Certificate(Identifier(rec['ID_C'].split('#')[-1]), rec['z_0'], rec['r'], rec['t_0'], Identifier(rec['ID_S'].split('#')[-1]), rec['l']) return cert
def test_5_sign(self): global signed_resp, signed_msg TestSignVerify.signverify.import_private_keys(filename_private_key) x = hash_factory(data=b'ABCD') t_resp = TimestampResponse(x, Identifier("server"), Identifier("client"), datetime.utcnow(), KSIErrorCodes.NO_ERROR) signed_msg, signed_resp = TestSignVerify.signverify.sign(t_resp)
def test_default(self): id_client = Identifier("client") id_server = Identifier("server") seed = b'\xde\xad\xbe\xef' keys = Keys(l=4, seed=seed) z0 = keys.keys[0].hash r = keys.hash_tree_root.hash t0 = datetime.now() cert = Certificate(id_client, z0, r, t0, id_server) print(cert) # There isn't much of testing to be done here as Certificate is a convenience class... assert cert is not None
def test_default(self): # Nothing special, just ensuring complete code coverage normal_ident_str = "herculepoirot" normal_ident = Identifier(normal_ident_str) print("id for \"" + normal_ident_str + "\": \"" + str(normal_ident) + "\"") assert str(normal_ident) == IDENTIFIER_BASE_NAME + normal_ident_str
def from_json(json_obj: dict): """ :param json_obj: JSON representation of a TimestampRequest object :type json_obj: dict :return: A new TimestampRequest from the json parameter :rtype: TimestampRequest """ assert 'x' in json_obj and 'ID_C' in json_obj id = json_obj['ID_C'] # type: str if id.startswith(IDENTIFIER_BASE_NAME): # Removes IDENTIFIER_BASE_NAME from the beginning of the identifier string id = id[len(IDENTIFIER_BASE_NAME):] return TimestampRequest(standard_b64decode(json_obj['x']), Identifier(id))
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 from_json(json_obj: dict): """ :param json_obj: A JSON representation of the Signature object :type json_obj: dict :return: A new Signature built from the json_obj parameter :rtype: Signature """ assert 'ID_C' in json_obj assert 'i' in json_obj assert 'z_i' in json_obj assert 'c_i' in json_obj assert 'msg' in json_obj assert 'S_t' in json_obj ID_C = Identifier(json_obj['ID_C'][len(IDENTIFIER_BASE_NAME):]) i = json_obj['i'] z_i = standard_b64decode(json_obj['z_i']) c_i = pickle.loads(standard_b64decode(json_obj['c_i'])) msg = standard_b64decode(json_obj['msg']) S_t = TimestampResponse.from_json_dict(json_obj['S_t']) return Signature(ID_C, i, z_i, c_i, S_t, msg)
for l in l_nums: 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_DEFAULT_OUTFILE = LOGGER_DIR + LOGGER_NAME + '.log' LOGGER_SAVE_OUTFILE = LOGGER_DIR + 'benchmark-{}-{}-{}.log' if __name__ == '__main__': assert PERFORM_BENCHMARKS is True # This switch need to be enabled! assert BENCHMARK_MOTIF == "ksi.signverify" add_logger() logging.basicConfig(level=logging.INFO) hash = hash_factory(data=b'ABCD') for i in [1024, 2048, 4096]: open(LOGGER_DEFAULT_OUTFILE, 'w+').close() signer = SignVerify() signer.generate_keys(i) resp = TimestampResponse(hash, Identifier('server'), Identifier('client'), datetime.utcnow(), KSIErrorCodes.NO_ERROR) # Benchmark start m, sig = signer.sign(resp) assert signer.verify(m, sig) is True # Benchmark end logger = logging.getLogger(LOGGER_NAME) for h in logger.handlers: h.flush() logger.removeHandler(h) os.rename(LOGGER_DEFAULT_OUTFILE, LOGGER_SAVE_OUTFILE.format('Sign', '', 'key-len_' + str(i)))
def setUp(self): logging.basicConfig(level=logging.DEBUG) self.id_server = Identifier("server")
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')