def test_create_entry(db_manager): key = get_random_value_hex(16) value = get_random_value_hex(32) # Adding a value with no prefix should work db_manager.create_entry(key, value) assert db_manager.db.get(key.encode("utf-8")).decode("utf-8") == value # Prefixing the key would require the prefix to load key = get_random_value_hex(16) prefix = "w" db_manager.create_entry(key, value, prefix=prefix) assert db_manager.db.get( (prefix + key).encode("utf-8")).decode("utf-8") == value assert db_manager.db.get(key.encode("utf-8")) is None # Keys, prefixes, and values of wrong format should fail with pytest.raises(TypeError): db_manager.create_entry(key=None) with pytest.raises(TypeError): db_manager.create_entry(key=key, value=None) with pytest.raises(TypeError): db_manager.create_entry(key=key, value=value, prefix=1)
def test_decrypt_wrong_key_size(): random_key = get_random_value_hex(31) random_encrypted_data_odd = get_random_value_hex(64) random_encrypted_blob_odd = random_encrypted_data_odd with pytest.raises(InvalidParameter, match="32-byte hex value"): Cryptographer.decrypt(random_encrypted_blob_odd, random_key)
def test_is_compressed_pk(): wrong_values = [ None, 3, 15.23, "", {}, (), object, str, get_random_value_hex(32), get_random_value_hex(34), "06" + get_random_value_hex(32), ] # check_user_pk must only accept values that is not a 33-byte hex string for i in range(100): if i % 2: prefix = "02" else: prefix = "03" assert is_compressed_pk(prefix + get_random_value_hex(32)) # check_user_pk must only accept values that is not a 33-byte hex string for value in wrong_values: assert not is_compressed_pk(value)
def test_delete_entry(db_manager): # Let's get the key all the things we've wrote so far in the db and empty the db. data = [k.decode("utf-8") for k, v in db_manager.db.iterator()] for key in data: db_manager.delete_entry(key) assert len([k for k, v in db_manager.db.iterator()]) == 0 # The same works if a prefix is provided. prefix = "r" key = get_random_value_hex(16) value = get_random_value_hex(32) db_manager.create_entry(key, value, prefix) # Checks it's there assert db_manager.db.get( (prefix + key).encode("utf-8")).decode("utf-8") == value # And now it's gone db_manager.delete_entry(key, prefix) assert db_manager.db.get((prefix + key).encode("utf-8")) is None # Deleting a non-existing key should be fine db_manager.delete_entry(key, prefix) # Trying to delete a non str key or prefix should fail with pytest.raises(TypeError): db_manager.delete_entry(None) with pytest.raises(TypeError): db_manager.delete_entry(get_random_value_hex(16), prefix=1)
def test_decrypt_odd_length_data(): random_key = get_random_value_hex(32) random_encrypted_data_odd = get_random_value_hex(64)[:-1] random_encrypted_blob_odd = random_encrypted_data_odd with pytest.raises(InvalidParameter, match="Odd-length"): Cryptographer.decrypt(random_encrypted_blob_odd, random_key)
def test_check_sha256_hex_format(): # Only 32-byte hex encoded strings should pass the test wrong_inputs = [None, str(), 213, 46.67, dict(), "A" * 63, "C" * 65, bytes(), get_random_value_hex(31)] for wtype in wrong_inputs: assert check_sha256_hex_format(wtype) is False for v in range(100): assert check_sha256_hex_format(get_random_value_hex(32)) is True
def test_compute_locator(): # The best way of checking that compute locator is correct is by using check_locator_format for _ in range(100): assert check_locator_format(compute_locator(get_random_value_hex(LOCATOR_LEN_BYTES))) is True # String of length smaller than LOCATOR_LEN_BYTES bytes must fail for i in range(1, LOCATOR_LEN_BYTES): assert check_locator_format(compute_locator(get_random_value_hex(i))) is False
def test_decrypt_invalid_tag(): random_key = get_random_value_hex(32) random_encrypted_data = get_random_value_hex(64) random_encrypted_blob = EncryptedBlob(random_encrypted_data) # Trying to decrypt random data should result in an InvalidTag exception. Our decrypt function # returns None hex_tx = Cryptographer.decrypt(random_encrypted_blob, random_key) assert hex_tx is None
def test_decrypt_invalid_tag(): random_key = get_random_value_hex(32) random_encrypted_data = get_random_value_hex(64) random_encrypted_blob = random_encrypted_data # Trying to decrypt random data should result in an EncryptionError with pytest.raises(EncryptionError, match="Cannot decrypt blob with the provided key"): Cryptographer.decrypt(random_encrypted_blob, random_key)
def test_encrypt_odd_length_data(): blob = Blob(get_random_value_hex(64)[-1]) key = get_random_value_hex(32) try: Cryptographer.encrypt(blob, key) assert False except ValueError: assert True
def test_check_data_key_format_wrong_data(): data = get_random_value_hex(64)[:-1] key = get_random_value_hex(32) try: Cryptographer.check_data_key_format(data, key) assert False except ValueError as e: assert "Odd-length" in str(e)
def test_encrypt_wrong_key_size(): blob = Blob(get_random_value_hex(64)) key = get_random_value_hex(31) try: Cryptographer.encrypt(blob, key) assert False except ValueError: assert True
def test_check_data_key_format_wrong_key(): data = get_random_value_hex(64) key = get_random_value_hex(33) try: Cryptographer.check_data_key_format(data, key) assert False except ValueError as e: assert "32-byte hex" in str(e)
def test_decrypt_odd_length_data(): random_key = get_random_value_hex(32) random_encrypted_data_odd = get_random_value_hex(64)[:-1] random_encrypted_blob_odd = EncryptedBlob(random_encrypted_data_odd) try: Cryptographer.decrypt(random_encrypted_blob_odd, random_key) assert False except ValueError: assert True
def test_decrypt_wrong_key_size(): random_key = get_random_value_hex(31) random_encrypted_data_odd = get_random_value_hex(64) random_encrypted_blob_odd = EncryptedBlob(random_encrypted_data_odd) try: Cryptographer.decrypt(random_encrypted_blob_odd, random_key) assert False except ValueError: assert True
def test_init_blob(): data = get_random_value_hex(64) blob = Blob(data) assert isinstance(blob, Blob) # Wrong data try: Blob(unhexlify(get_random_value_hex(64))) assert False, "Able to create blob with wrong data" except ValueError: assert True
def appointment_data(): locator = get_random_value_hex(LOCATOR_LEN_BYTES) to_self_delay = 20 user_id = get_random_value_hex(16) encrypted_blob_data = get_random_value_hex(100) return { "locator": locator, "to_self_delay": to_self_delay, "encrypted_blob": encrypted_blob_data, "user_id": user_id, }
def appointment_data(): locator = get_random_value_hex(LOCATOR_LEN_BYTES) start_time = 100 end_time = 120 to_self_delay = 20 encrypted_blob_data = get_random_value_hex(100) return { "locator": locator, "start_time": start_time, "end_time": end_time, "to_self_delay": to_self_delay, "encrypted_blob": encrypted_blob_data, }
def test_check_locator_format(): # Check that only LOCATOR_LEN_BYTES long string pass the test wrong_inputs = [ None, str(), 213, 46.67, dict(), "A" * (2 * LOCATOR_LEN_BYTES - 1), "C" * (2 * LOCATOR_LEN_BYTES + 1), bytes(), get_random_value_hex(LOCATOR_LEN_BYTES - 1), ] for wtype in wrong_inputs: assert check_locator_format(wtype) is False for _ in range(100): assert check_locator_format(get_random_value_hex(LOCATOR_LEN_BYTES)) is True
def test_create_appointment_receipt(appointment_data): # Not much to test here, basically making sure the fields are in the correct order # The receipt format is user_signature | start_block sk = PrivateKey.from_int(42) data = get_random_value_hex(120) signature = Cryptographer.sign(data.encode("utf-8"), sk) start_block = 200 receipt = receipts.create_appointment_receipt(signature, start_block) assert pyzbase32.encode_bytes(receipt[:-4]).decode() == signature assert struct.unpack(">I", receipt[-4:])[0] == start_block
def test_create_registration_receipt_wrong_inputs(): user_id = "02" + get_random_value_hex(32) available_slots = 100 subscription_expiry = 4320 wrong_user_ids = [ "01" + get_random_value_hex(32), "04" + get_random_value_hex(31), "06" + get_random_value_hex(33) ] no_int = [{}, object, "", [], 3.4, None] overflow_iu4nt = pow(2, 32) for wrong_param in wrong_user_ids + no_int: with pytest.raises(InvalidParameter, match="public key does not match expected format"): receipts.create_registration_receipt(wrong_param, available_slots, subscription_expiry) with pytest.raises( InvalidParameter, match="available_slots must be a 4-byte unsigned integer"): receipts.create_registration_receipt(user_id, wrong_param, subscription_expiry) with pytest.raises( InvalidParameter, match="subscription_expiry must be a 4-byte unsigned integer"): receipts.create_registration_receipt(user_id, available_slots, wrong_param) # Same for overflow u4int with pytest.raises( InvalidParameter, match="available_slots must be a 4-byte unsigned integer"): receipts.create_registration_receipt(user_id, overflow_iu4nt, subscription_expiry) with pytest.raises( InvalidParameter, match="subscription_expiry must be a 4-byte unsigned integer"): receipts.create_registration_receipt(user_id, available_slots, overflow_iu4nt)
def test_load_entry(db_manager): key = get_random_value_hex(16) value = get_random_value_hex(32) # Loading an existing key should work db_manager.db.put(key.encode("utf-8"), value.encode("utf-8")) assert db_manager.load_entry(key) == value.encode("utf-8") # Adding an existing prefix should work assert db_manager.load_entry(key[2:], prefix=key[:2]) == value.encode("utf-8") # Adding a non-existing prefix should return None assert db_manager.load_entry(key, prefix=get_random_value_hex(2)) is None # Loading a non-existing entry should return None assert db_manager.load_entry(get_random_value_hex(16)) is None # Trying to load a non str key or prefix should fail with pytest.raises(TypeError): db_manager.load_entry(None) with pytest.raises(TypeError): db_manager.load_entry(get_random_value_hex(16), prefix=1)
def test_create_registration_receipt(): # Not much to test here, basically making sure the fields are in the correct order # The receipt format is user_id | available_slots | subscription_expiry user_id = "02" + get_random_value_hex(32) available_slots = 100 subscription_expiry = 4320 registration_receipt = receipts.create_registration_receipt( user_id, available_slots, subscription_expiry) assert registration_receipt[:33].hex() == user_id assert int.from_bytes(registration_receipt[33:37], "big") == available_slots assert int.from_bytes(registration_receipt[37:], "big") == subscription_expiry
def test_is_u4int(): out_of_range = [-1, pow(2, 32)] in_range = [0, pow(2, 32) // 2, pow(2, 32) - 1] wrong_inputs = [ None, str(), 46.67, dict(), "A", bytes(), get_random_value_hex(31) ] # Test ints out of the range return false for x in out_of_range: assert not is_u4int(x) # Same for wrong inputs for x in wrong_inputs: assert not is_u4int(x) # True is returned for values in range for x in in_range: assert is_u4int(x)
def test_create_appointment_receipt_wrong_inputs(): sk = PrivateKey.from_int(42) data = get_random_value_hex(120) signature = Cryptographer.sign(data.encode("utf-8"), sk) start_block = 200 overflow_iu4nt = pow(2, 32) no_str = [{}, [], None, 15, 4.5, dict(), object, True] no_int = [{}, [], None, "", 4.5, dict(), object] for wrong_param in no_str: with pytest.raises(InvalidParameter, match="user_signature is invalid"): receipts.create_appointment_receipt(wrong_param, start_block) for wrong_param in no_int: with pytest.raises(InvalidParameter, match="must be a 4-byte unsigned integer"): receipts.create_appointment_receipt(signature, wrong_param) # Same for overflow u4int with pytest.raises(InvalidParameter, match="start_block must be a 4-byte unsigned integer"): receipts.create_appointment_receipt(signature, overflow_iu4nt)
def test_check_data_key_format_wrong_data(): data = get_random_value_hex(64)[:-1] key = get_random_value_hex(32) with pytest.raises(InvalidParameter, match="Odd-length"): Cryptographer.check_data_key_format(data, key)
def test_check_data_key_format_wrong_key(): data = get_random_value_hex(64) key = get_random_value_hex(33) with pytest.raises(InvalidParameter, match="32-byte hex value"): Cryptographer.check_data_key_format(data, key)
def test_check_data_key_format(): data = get_random_value_hex(64) key = get_random_value_hex(32) # Correct format does not raise anything Cryptographer.check_data_key_format(data, key)
def test_encrypt_wrong_key_size(): blob = get_random_value_hex(64) key = get_random_value_hex(31) with pytest.raises(InvalidParameter, match="32-byte hex value"): Cryptographer.encrypt(blob, key)
def test_encrypt_odd_length_data(): blob = get_random_value_hex(64)[-1] key = get_random_value_hex(32) with pytest.raises(InvalidParameter, match="Odd-length"): Cryptographer.encrypt(blob, key)