diff --git a/monkey/monkey_island/cc/server_utils/encryption/__init__.py b/monkey/monkey_island/cc/server_utils/encryption/__init__.py index 592d42381..9443fa4ab 100644 --- a/monkey/monkey_island/cc/server_utils/encryption/__init__.py +++ b/monkey/monkey_island/cc/server_utils/encryption/__init__.py @@ -7,7 +7,7 @@ from .password_based_bytes_encryptor import ( InvalidCredentialsError, InvalidCiphertextError, ) -from .i_lockable_encryptor import ILockableEncryptor, LockedKeyError, UnlockError +from .i_lockable_encryptor import ILockableEncryptor, LockedKeyError, UnlockError, ResetKeyError from .repository_encryptor import RepositoryEncryptor from .data_store_encryptor import ( get_datastore_encryptor, diff --git a/monkey/monkey_island/cc/server_utils/encryption/i_lockable_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/i_lockable_encryptor.py index 231af0a16..f31024655 100644 --- a/monkey/monkey_island/cc/server_utils/encryption/i_lockable_encryptor.py +++ b/monkey/monkey_island/cc/server_utils/encryption/i_lockable_encryptor.py @@ -27,6 +27,12 @@ class UnlockError(Exception): """ +class ResetKeyError(Exception): + """ + Raised if an error occurs while attempting to reset an ILockableEncryptor's key + """ + + class ILockableEncryptor(IEncryptor): """ An encryptor that can be locked or unlocked. @@ -54,6 +60,10 @@ class ILockableEncryptor(IEncryptor): def reset_key(self): """ Reset the encryptor's key + + Remove the existing key material so that it can never be used again. + + :raises ResetKeyError: If an error occurred while attemping to reset the key """ @abstractmethod diff --git a/monkey/monkey_island/cc/server_utils/encryption/repository_encryptor.py b/monkey/monkey_island/cc/server_utils/encryption/repository_encryptor.py index d45c760d5..73e054289 100644 --- a/monkey/monkey_island/cc/server_utils/encryption/repository_encryptor.py +++ b/monkey/monkey_island/cc/server_utils/encryption/repository_encryptor.py @@ -3,7 +3,7 @@ from pathlib import Path from monkey_island.cc.server_utils.file_utils import open_new_securely_permissioned_file -from . import ILockableEncryptor, LockedKeyError, UnlockError +from . import ILockableEncryptor, LockedKeyError, ResetKeyError, UnlockError from .key_based_encryptor import KeyBasedEncryptor from .password_based_bytes_encryptor import PasswordBasedBytesEncryptor @@ -49,8 +49,11 @@ class RepositoryEncryptor(ILockableEncryptor): self._key_based_encryptor = None def reset_key(self): - if self._key_file.is_file(): - self._key_file.unlink() + try: + if self._key_file.is_file(): + self._key_file.unlink() + except Exception as err: + raise ResetKeyError(err) self._password_based_encryptor = None self._key_based_encryptor = None diff --git a/monkey/tests/unit_tests/monkey_island/cc/server_utils/encryption/test_repository_encryptor.py b/monkey/tests/unit_tests/monkey_island/cc/server_utils/encryption/test_repository_encryptor.py index ff07efc5f..0dcb7cdcf 100644 --- a/monkey/tests/unit_tests/monkey_island/cc/server_utils/encryption/test_repository_encryptor.py +++ b/monkey/tests/unit_tests/monkey_island/cc/server_utils/encryption/test_repository_encryptor.py @@ -7,6 +7,7 @@ from common.utils.file_utils import get_file_sha256_hash from monkey_island.cc.server_utils.encryption import ( LockedKeyError, RepositoryEncryptor, + ResetKeyError, UnlockError, ) @@ -110,3 +111,16 @@ def test_encrypt_after_reset(encryptor, key_file): def test_reset_before_unlock(encryptor): # Test will fail if an exception is raised encryptor.reset_key() + + +def test_reset_key_error(key_file): + class UnlinkErrorWrapper(key_file.__class__): + def unlink(self): + raise OSError("Can't delete file") + + encryptor = RepositoryEncryptor(UnlinkErrorWrapper(key_file)) + encryptor.unlock(SECRET) + encryptor.lock() + + with pytest.raises(ResetKeyError): + encryptor.reset_key()