def test_get_configuration_key(mock_set_configuration_key, mock_keyring_get_password, config): """ Test whether calling get_configuration_key gets and sets a configuration key properly. """ # A previous key is stored within the keychain. key = helpers.get_configuration_key(config, auto_create=False) assert mock_keyring_get_password.called_with( service=config.APP_NAME, name=config.KEYCHAIN_CONFIGURATION_KEY_NAME) assert not mock_set_configuration_key.called assert key == b'stored_key' # No previous key found. mock_keyring_get_password.return_value = None key = helpers.get_configuration_key(config, auto_create=False) assert mock_keyring_get_password.called assert not mock_set_configuration_key.called assert key is None # No previous key found _and_ auto_create=True mock_keyring_get_password.return_value = None key = helpers.get_configuration_key(config, auto_create=True) assert mock_keyring_get_password.called assert mock_set_configuration_key.called_with( service=config.APP_NAME, name=config.KEYCHAIN_CONFIGURATION_KEY_NAME, password=base64.b64encode(key)) assert key == b'new_key'
def test_store_read_configuration_key(no_configuration_key): """Test that storing and retrieving a given key works.""" config, key = no_configuration_key assert key == helpers.get_configuration_key(config, auto_create=False) key = os.urandom(config.KEYCHAIN_CONFIGURATION_KEY_SIZE) kb64 = base64.b64encode(key).decode('ascii') keyring.set_password(config.APP_NAME, config.KEYCHAIN_CONFIGURATION_KEY_NAME, kb64) stored_key = keyring.get_password(config.APP_NAME, config.KEYCHAIN_CONFIGURATION_KEY_NAME) assert stored_key == kb64 assert key == helpers.get_configuration_key(config, auto_create=True)
def no_configuration_key(config): """ Ensures that there is no configuration key is stored in the keychain. """ if keyring.get_password(config.APP_NAME, config.KEYCHAIN_CONFIGURATION_KEY_NAME): keyring.delete_password(config.APP_NAME, config.KEYCHAIN_CONFIGURATION_KEY_NAME) key = helpers.get_configuration_key(config, auto_create=False) assert not key return config, key
def test_encryption_should_work_with_auto_create_while_write( no_configuration_key): """ Ensure that a key is auto created per default if not present when calling write operation. """ config, no_configuration_key = no_configuration_key config = reset_config(config) assert not no_configuration_key helpers.write_config(config, config.config_file) # Ensure that a key has been written to the keychain. assert helpers.get_configuration_key(config, auto_create=False)
def test_read_write_encryption(config): """Ensure basic encrypt/decrypt works and that invalid keys or tags throw exceptions. """ # Expected location of the configuration file. okey = helpers.get_configuration_key(config, auto_create=True) # Writing the configuration once should use the existing key and store the current tag. helpers.write_config(config) old_tag = helpers.get_configuration_tag(config) assert old_tag assert okey == helpers.get_configuration_key(config, auto_create=False) assert okey == helpers.get_configuration_key(config, auto_create=True) helpers.write_config(config) assert os.path.exists(config.config_file) # The tags should be different. new_tag = helpers.get_configuration_tag(config) assert old_tag != new_tag # The keys should stay the same. new_key = helpers.get_configuration_key(config, auto_create=True) assert new_key == okey # Decrypting it with the proper key and tag should work. assert helpers.read_encrypted_configuration(config, config.config_file, new_key, new_tag) # Decrypting with the old tag should still return the configuration. read_config = helpers.read_encrypted_configuration(config, config.config_file, new_key, old_tag) assert 'metadata' in read_config # Decrypting with an invalid tag should still return the configuration. invalid_tag = b'X' * config.KEYCHAIN_CONFIGURATION_TAG_SIZE read_config = helpers.read_encrypted_configuration(config, config.config_file, new_key, invalid_tag) assert 'metadata' in read_config # Decrypting with an invalid key should also fail. tag = helpers.get_configuration_tag(config) with pytest.raises(helpers.ConfigurationError): helpers.read_encrypted_configuration( config, config.config_file, os.urandom(config.KEYCHAIN_CONFIGURATION_KEY_SIZE), tag)