forked from p15670423/monkey
Island: Add ILockableEncryptor
This commit is contained in:
parent
54c1eef309
commit
bd2d79fd43
|
@ -7,6 +7,7 @@ from .password_based_bytes_encryptor import (
|
||||||
InvalidCredentialsError,
|
InvalidCredentialsError,
|
||||||
InvalidCiphertextError,
|
InvalidCiphertextError,
|
||||||
)
|
)
|
||||||
|
from .i_lockable_encryptor import ILockableEncryptor
|
||||||
from .data_store_encryptor import (
|
from .data_store_encryptor import (
|
||||||
get_datastore_encryptor,
|
get_datastore_encryptor,
|
||||||
unlock_datastore_encryptor,
|
unlock_datastore_encryptor,
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from . import IEncryptor
|
||||||
|
|
||||||
|
# NOTE: The ILockableEncryptor introduces temporal coupling, that is, you must first unlock the
|
||||||
|
# encryptor before you can use it. This is because the key material used to encrypt repository
|
||||||
|
# contents is encrypted using the user's username and password. This adds extra security by
|
||||||
|
# allowing us to fully encrypt data at rest. Without this, we'd need to store the repository
|
||||||
|
# key in plaintext. Alternative solutions are as follows:
|
||||||
|
# 1. Store the repository key in plaintext
|
||||||
|
# 2. Add an initialization phase to the island's boot sequence. At the moment, this is the
|
||||||
|
# only element of the design that would benefit from adding an additional phase. If
|
||||||
|
# other temporal coupling begins to creep in, we can add the initialization phase at
|
||||||
|
# that time and remove this interface.
|
||||||
|
|
||||||
|
|
||||||
|
class LockedKeyError(Exception):
|
||||||
|
"""
|
||||||
|
Raised when an ILockableEncryptor attemps to encrypt or decrypt data before the
|
||||||
|
ILockableEncryptor has been unlocked.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ILockableEncryptor(IEncryptor):
|
||||||
|
"""
|
||||||
|
An encryptor that can be locked or unlocked.
|
||||||
|
|
||||||
|
ILockableEncryptor's require a secret in order to access their key material. These encryptors
|
||||||
|
must be unlocked before use and can be re-locked at the user's request.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def unlock(self, secret: bytes):
|
||||||
|
"""
|
||||||
|
Unlock the encryptor
|
||||||
|
|
||||||
|
:param secret: A secret that must be used to access the ILockableEncryptor's key material.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def lock(self):
|
||||||
|
"""
|
||||||
|
Lock the encryptor, making it unusable
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def encrypt(self, plaintext: bytes) -> bytes:
|
||||||
|
"""
|
||||||
|
Encrypts data and returns the ciphertext.
|
||||||
|
|
||||||
|
:param plaintext: Data that will be encrypted
|
||||||
|
:return: Ciphertext generated by encrypting the plaintext
|
||||||
|
:raises LockedKeyError: If encrypt() is called while the ILockableEncryptor is locked
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def decrypt(self, ciphertext: bytes) -> bytes:
|
||||||
|
"""
|
||||||
|
Decrypts data and returns the plaintext.
|
||||||
|
|
||||||
|
:param ciphertext: Ciphertext that will be decrypted
|
||||||
|
:return: Plaintext generated by decrypting the ciphertext
|
||||||
|
:raises LockedKeyError: If decrypt() is called while the ILockableEncryptor is locked
|
||||||
|
"""
|
Loading…
Reference in New Issue