def test_ephid(): """ test the generating epemeral id's. (positive test) """ user_id = b'\x81\x87S\x06\x04\xc6.I\xf3\x84\xb9\x189\xe8K\xd3' master_key = b'\x84&,\xd3C\xb1\xee\x86\xbb\xbe\xb4\x03\xdabM\xf9' # day = 18374 time = 1587592647 geohash = b'\xb4\xf2\xd5\x1d\x7f' target_time = int(time + 60*60*26.5) expected_ephid = b'\xc8>A\xc5\x1a\x95\xb3\xeaN\x83\x96\xab\xb4/6A' user = User(user_id, master_key, time) user.update_key_databases(time, target_time) assert user.generate_ephemeral_id(target_time, geohash) == expected_ephid
def test_contact_then_verify(): """ default test for two user's that were in contact. (positive test) """ first_user_id = b'carolefuknbaskin' first_user_key = b'0\xe7\x9f\x91\xaa$\x1eB\x94\xe7fX\x82\xf0\xff\xe7' # day = 18374 first_user_init_time = 1587592647 second_user_id = b'___joe_exotic___' second_user_key = b'\xd9\x1d\x1eP\x8a\xb8\\:\x8d\xc8^\x02\xa7|\xb1=' second_user_init_time = int(first_user_init_time + 60*60*24*3.5) first_user_contact_time = int(second_user_init_time + 60*60*24*1.5) second_user_contact_time = first_user_contact_time + 100 first_user_geohash = b'\x81\xd5\x8d\x1f\xf5' second_user_geohash = b'9\x19\x04\xa1\x93' rssi = None expected_proof = b'\xc7x6\x97' first_user = User(first_user_id, first_user_key, first_user_init_time) second_user = User(second_user_id, second_user_key, second_user_init_time) server = Server() first_user.update_key_databases(first_user_init_time, first_user_contact_time) eph_id = first_user.generate_ephemeral_id(first_user_contact_time, first_user_geohash) assert second_user.store_contact(eph_id, rssi, second_user_contact_time, second_user_geohash) server_keys_a = first_user.get_keys_for_server() server.receive_user_key(server_keys_a) server_msg = server.send_keys() matches = second_user.find_crypto_matches(server_msg) assert len(matches) == 1, "Expected one match, found {}".format(len(matches)) m = matches[0] assert m.proof == expected_proof assert m.infected_geohash == first_user_geohash t1 = Time(first_user_contact_time) t2 = Time(m.infected_time) assert t1.day == t2.day and t1.epoch == t2.epoch and t1.get_units() == t2.get_units() # Make sure the server validates the match assert server.verify_contact(t2.day, t2.epoch, m.proof)
def duplicate_message_test(): """ A test to check that the server only accepts one set of keys from infected user. (negative test) """ # TODO the code doesn't support this test. there is no way to check the same user again right know. id_a = bytes([1] + [0] * 15) key_a = bytes(i + 2 for i in range(16)) install_time_a = day_to_second(100) + 50 user_a = User(id_a, key_a, install_time_a) server = Server() first_contact = day_to_second(102) second_contact = day_to_second(104) _ = user_a.generate_ephemeral_id(first_contact, bytes([0] * 5)) # sending first user keys to server first_keys = user_a.get_keys_for_server() server.receive_user_key(first_keys) _ = server.send_keys() _ = user_a.generate_ephemeral_id(second_contact, bytes([0] * 5)) # sending second user keys to server(duplicate send) second_keys = user_a.get_keys_for_server() server.receive_user_key(second_keys) _ = server.send_keys()
def test_updating_database(): """ unit test for the update_database function. checking the update_key_database delete past time. """ id_a = bytes([1] + [0] * 15) key_a = bytes(i + 2 for i in range(16)) install_time = day_to_second(100) user_a = User(id_a, key_a, install_time) user_a.update_key_databases(day_to_second(99), day_to_second(113)) user_a.update_key_databases(day_to_second(110), day_to_second(115)) assert min(user_a.epoch_keys.keys()) == Time(day_to_second(110))
def test_key_derivation(): """ General test for the key derivation. (positive test) """ user_id = b'n\xb3\x1aqy\x8bF\xe3\x98\xee\x01X\x1b\x8cp\xc6' master_key = b'3>\xa5\xce\xd8\xf42\xdc\x83\xb7)\xcd\xc6\xa8\x91D' # day = 18374 time = 1587592647 target_day = 18401 exp_master_com = b'\x15a\xaf\xac\t\xfbdl\x1dF\xc5\xdaj\x96\x8e\xa4' exp_day_master = b'\x8d\x99E\x92\xa0\x95J\x1fa\xed\x85\xeaZ\xc8\x99f' exp_k_day = b'\x80{\x14j\xc4?.\xb9\xa2<+\x9a\x85\x8f\xd9\xd2' exp_verification_key = b'\x93zWF\xb6Ko\xb9x-"\xe5g\xf2,<' exp_k_id = b'\xa0Bv\xd9Q\x08*\x7f\xea\xc7\xb1\xfe?\x02D\x0b' exp_k_master_ver = b'\x12J-l\x02V\xefu\x93k\xf3\t*k\xa6e' user = User(user_id, master_key, time) assert user.K_master_com == exp_master_com assert user.K_id == exp_k_id assert user.K_master_ver == exp_k_master_ver
def dos_test(): """ Test 1 in section 6(spam prevention). sending many BLE in short time. user should only accept 1000. """ id_a = bytes([1] + [0] * 15) id_b = bytes([2] + [0] * 15) id_c = bytes([3] + [0] * 15) id_d = bytes([4] + [0] * 15) id_e = bytes([5] + [0] * 15) key_a = bytes(i + 2 for i in range(16)) key_b = bytes(i + 3 for i in range(16)) key_c = bytes(i + 4 for i in range(16)) key_d = bytes(i + 5 for i in range(16)) key_e = bytes(i + 6 for i in range(16)) install_time = day_to_second(100) rssi = None geo_hash = bytes([0] * 5) user_a = User(id_a, key_a, install_time) user_b = User(id_b, key_b, install_time) user_c = User(id_c, key_c, install_time) user_d = User(id_d, key_d, install_time) user_e = User(id_e, key_e, install_time) counter = 0 for i in range(T_UNIT): time = install_time + i eph_b = user_b.generate_ephemeral_id(time, geo_hash) eph_c = user_c.generate_ephemeral_id(time, geo_hash) eph_d = user_d.generate_ephemeral_id(time, geo_hash) eph_e = user_e.generate_ephemeral_id(time, geo_hash) if counter < 1000: assert user_a.store_contact(eph_b, rssi, time, geo_hash) assert user_a.store_contact(eph_c, rssi, time, geo_hash) assert user_a.store_contact(eph_d, rssi, time, geo_hash) assert user_a.store_contact(eph_e, rssi, time, geo_hash) else: assert not user_a.store_contact(eph_b, rssi, time, geo_hash) assert not user_a.store_contact(eph_c, rssi, time, geo_hash) assert not user_a.store_contact(eph_d, rssi, time, geo_hash) assert not user_a.store_contact(eph_e, rssi, time, geo_hash) counter += 4 assert len(user_a.contacts) == 1000 user_b.update_key_databases(install_time, install_time + day_to_second(3)) eph_b = user_b.generate_ephemeral_id(install_time + day_to_second(3), geo_hash) assert user_a.store_contact(eph_b, rssi, install_time + day_to_second(3), geo_hash) assert len(user_a.contacts) == 1001
def test_delete_contact(): """ A test to check that the user can delete meeting a contact. (positive test) """ id_a = bytes([1] + [0] * 15) id_b = bytes([2] + [0] * 15) id_c = bytes([3] + [0] * 15) key_a = bytes(i + 2 for i in range(16)) key_b = bytes(i + 4 for i in range(16)) key_c = bytes(i + 5 for i in range(16)) install_time_a = day_to_second(100) install_time_b = install_time_a + 60 install_time_c = install_time_a + 120 contact_ab = day_to_second(110) contact_ba = day_to_second(110) + 5 contact_ac = day_to_second(115) contact_ca = day_to_second(115) + 5 rssi = None user_a = User(id_a, key_a, install_time_a) user_b = User(id_b, key_b, install_time_b) user_c = User(id_c, key_c, install_time_c) server = Server() # first contact. user_a.update_key_databases(install_time_a, contact_ab) eph_id_ab = user_a.generate_ephemeral_id(contact_ab, bytes([0] * 5)) assert user_b.store_contact(eph_id_ab, rssi, contact_ba, bytes([0] * 5)) # second contact. user_a.update_key_databases(install_time_a, contact_ac) eph_id_ac = user_a.generate_ephemeral_id(contact_ac, bytes([0] * 5)) assert user_c.store_contact(eph_id_ac, rssi, contact_ca, bytes([0] * 5)) # user b delete's his contact with user a contact = Contact(eph_id_ab, rssi, contact_ba, bytes([0] * 5)) user_b.delete_contact(contact) # sending first user keys to server result_keys = user_a.get_keys_for_server() server.receive_user_key(result_keys) server_msg = server.send_keys() second_user_matches = user_b.find_crypto_matches(server_msg) third_user_matches = user_c.find_crypto_matches(server_msg) assert len(second_user_matches) == 0 assert len(third_user_matches) == 1 assert third_user_matches[0].contact.EphID == eph_id_ac assert third_user_matches[0].contact.time == contact_ca assert third_user_matches[0].contact.location == bytes([0] * 5) assert third_user_matches[0].contact.RSSI is None assert third_user_matches[0].infected_geohash == bytes([0] * 5) assert third_user_matches[0].proof == user_a.epoch_keys[Time( contact_ac)].epochVER[:4] assert third_user_matches[0].infected_time == contact_ac
def test_delete_time(): """ A test to check that the user can delete data from specific periods. Scenario: - A, B, C are all created on day 100 - A contacts B on day 110 (with some gitter in times) - A contacts C on day 115 (with some gitter in times) - A deletes days 114-116 - A is diagnosed as infected; sends his keys to the server. - The server distributes A's keys to B and C. Expected result: - B is notified (one contact). - C is not notified (zero contacts). (positive test) """ id_a = b'\x11j1w\xeao\xb8b\x85\xf8\xfd\x99@^e8' id_b = b'\xfaz\xde\x99\x95\xb2\x9c\r\xe0|1g\x9b\xeb\x07/' id_c = b'\xba\xea~\x98\r\xd6X\x9c\xf3\xf0\xcdRk5\xe80' key_a = b'\xf4\xa4\xec\x1b:\xe6Q\xb4\xbb\xbf\n\xac:\xb8\xc9\xaf' key_b = b',_\xb7\xf0\xfa\x9e\xa5\x1f\xd8\xef\xbb&\xe7\xb2\xe0;' key_c = b'\x95\t\xec\xce\xae\xbai\x11\x08\x8e\x9b\x94R^1F' geohash_ab = b'\xb1\xfd\x88\x84s' geohash_ba = b'`z\xb0;H' geohash_ac = b'\x8c\xff\x8b\x93\xa2' geohash_ca = b'7got%' install_time = day_to_second(100) contact_ab = day_to_second(110) contact_ba = contact_ab + 30 contact_ac = day_to_second(115) contact_ca = contact_ac - 30 a_delete_from = day_to_second(114) a_delete_to = day_to_second(116) rssi = None user_a = User(id_a, key_a, install_time) user_b = User(id_b, key_b, install_time) user_c = User(id_c, key_c, install_time) server = Server() user_a.update_key_databases(install_time, contact_ab) ephid_ab = user_a.generate_ephemeral_id(contact_ab, geohash_ab) assert user_b.store_contact(ephid_ab, rssi, contact_ba, geohash_ba) user_a.update_key_databases(contact_ab, contact_ac) ephid_ac = user_a.generate_ephemeral_id(contact_ac, geohash_ac) assert user_c.store_contact(ephid_ac, rssi, contact_ca, geohash_ca) user_a.delete_my_keys(a_delete_from, a_delete_to) # a is infected and sends his keys to the server keys_for_distribution = user_a.get_keys_for_server() server.receive_user_key(keys_for_distribution) server_msg = server.send_keys() matches_b = user_b.find_crypto_matches(server_msg) matches_c = user_c.find_crypto_matches(server_msg) assert len(matches_b) == 1 assert len(matches_c) == 0 match = matches_b[0] assert match.contact.EphID == ephid_ab assert match.contact.time == contact_ba assert match.contact.location == geohash_ba assert match.contact.RSSI == rssi assert match.infected_geohash == geohash_ab assert abs(match.infected_time - contact_ab) <= JITTER_THRESHOLD assert match.proof == user_a.epoch_keys[Time(contact_ab)].epochVER[:4]
def test_user_delete_past_data(): """ A test to check that the user deletes ephemeral data from more then 14 days ago. (positive test) """ id_a = bytes([1] + [0] * 15) id_b = bytes([2] + [0] * 15) key_a = bytes(i + 2 for i in range(16)) key_b = bytes(i + 4 for i in range(16)) install_time_a = day_to_second(100) install_time_b = day_to_second(101) contact_ab = day_to_second(110) contact_ba = day_to_second(110) + 5 rssi = None user_a = User(id_a, key_a, install_time_a) user_b = User(id_b, key_b, install_time_b) server = Server() # contact between user a and user b. user_a.update_key_databases(install_time_a, contact_ab) eph_id_ab = user_a.generate_ephemeral_id(contact_ab, bytes([0] * 5)) assert user_b.store_contact(eph_id_ab, rssi, contact_ba, bytes([0] * 5)) # update both users to day 124 update_time = day_to_second(124) user_a.update_key_databases(install_time_a, update_time) user_b.update_key_databases(install_time_b, update_time) _ = user_a.generate_ephemeral_id(update_time, bytes([0] * 5)) _ = user_b.generate_ephemeral_id(update_time, bytes([0] * 5)) # this test is pretty stupid. but the test inside the real application is better. # the application will need to call delete history for the past 14 days every time. history_time = day_to_second(110) + 6 user_a.delete_history(history_time) user_b.delete_history(history_time) # sending first user keys to server result_keys = user_a.get_keys_for_server() server.receive_user_key(result_keys) server_msg = server.send_keys() second_user_matches = user_b.find_crypto_matches(server_msg) assert len(second_user_matches) == 0