|
@@ -145,6 +145,8 @@ def tam_required(repository):
|
|
|
class KeyBase:
|
|
|
# Numeric key type ID, must fit in one byte.
|
|
|
TYPE = None # override in subclasses
|
|
|
+ # set of key type IDs the class can handle as input
|
|
|
+ TYPES_ACCEPTABLE = None # override in subclasses
|
|
|
|
|
|
# Human-readable name
|
|
|
NAME = 'UNDEFINED'
|
|
@@ -259,6 +261,7 @@ class KeyBase:
|
|
|
|
|
|
class PlaintextKey(KeyBase):
|
|
|
TYPE = 0x02
|
|
|
+ TYPES_ACCEPTABLE = {TYPE}
|
|
|
NAME = 'plaintext'
|
|
|
ARG_NAME = 'none'
|
|
|
STORAGE = KeyBlobStorage.NO_STORAGE
|
|
@@ -287,7 +290,7 @@ class PlaintextKey(KeyBase):
|
|
|
return b''.join([self.TYPE_STR, data])
|
|
|
|
|
|
def decrypt(self, id, data, decompress=True):
|
|
|
- if data[0] != self.TYPE:
|
|
|
+ if data[0] not in self.TYPES_ACCEPTABLE:
|
|
|
id_str = bin_to_hex(id) if id is not None else '(unknown)'
|
|
|
raise IntegrityError('Chunk %s: Invalid encryption envelope' % id_str)
|
|
|
payload = memoryview(data)[1:]
|
|
@@ -367,8 +370,7 @@ class AESKeyBase(KeyBase):
|
|
|
return self.cipher.encrypt(data, header=self.TYPE_STR, iv=next_iv)
|
|
|
|
|
|
def decrypt(self, id, data, decompress=True):
|
|
|
- if not (data[0] == self.TYPE or
|
|
|
- data[0] == PassphraseKey.TYPE and isinstance(self, RepoKey)):
|
|
|
+ if data[0] not in self.TYPES_ACCEPTABLE:
|
|
|
id_str = bin_to_hex(id) if id is not None else '(unknown)'
|
|
|
raise IntegrityError('Chunk %s: Invalid encryption envelope' % id_str)
|
|
|
try:
|
|
@@ -396,8 +398,7 @@ class AESKeyBase(KeyBase):
|
|
|
if manifest_data is None:
|
|
|
nonce = 0
|
|
|
else:
|
|
|
- if not (manifest_data[0] == self.TYPE or
|
|
|
- manifest_data[0] == PassphraseKey.TYPE and isinstance(self, RepoKey)):
|
|
|
+ if manifest_data[0] not in self.TYPES_ACCEPTABLE:
|
|
|
raise IntegrityError('Manifest: Invalid encryption envelope')
|
|
|
# manifest_blocks is a safe upper bound on the amount of cipher blocks needed
|
|
|
# to encrypt the manifest. depending on the ciphersuite and overhead, it might
|
|
@@ -641,6 +642,7 @@ class KeyfileKeyBase(AESKeyBase):
|
|
|
|
|
|
class KeyfileKey(ID_HMAC_SHA_256, KeyfileKeyBase):
|
|
|
TYPE = 0x00
|
|
|
+ TYPES_ACCEPTABLE = {TYPE}
|
|
|
NAME = 'key file'
|
|
|
ARG_NAME = 'keyfile'
|
|
|
STORAGE = KeyBlobStorage.KEYFILE
|
|
@@ -731,6 +733,7 @@ class KeyfileKey(ID_HMAC_SHA_256, KeyfileKeyBase):
|
|
|
|
|
|
class RepoKey(ID_HMAC_SHA_256, KeyfileKeyBase):
|
|
|
TYPE = 0x03
|
|
|
+ TYPES_ACCEPTABLE = {TYPE, PassphraseKey.TYPE}
|
|
|
NAME = 'repokey'
|
|
|
ARG_NAME = 'repokey'
|
|
|
STORAGE = KeyBlobStorage.REPO
|
|
@@ -770,6 +773,7 @@ class RepoKey(ID_HMAC_SHA_256, KeyfileKeyBase):
|
|
|
|
|
|
class Blake2KeyfileKey(ID_BLAKE2b_256, KeyfileKey):
|
|
|
TYPE = 0x04
|
|
|
+ TYPES_ACCEPTABLE = {0x04}
|
|
|
NAME = 'key file BLAKE2b'
|
|
|
ARG_NAME = 'keyfile-blake2'
|
|
|
STORAGE = KeyBlobStorage.KEYFILE
|
|
@@ -780,6 +784,7 @@ class Blake2KeyfileKey(ID_BLAKE2b_256, KeyfileKey):
|
|
|
|
|
|
class Blake2RepoKey(ID_BLAKE2b_256, RepoKey):
|
|
|
TYPE = 0x05
|
|
|
+ TYPES_ACCEPTABLE = {TYPE}
|
|
|
NAME = 'repokey BLAKE2b'
|
|
|
ARG_NAME = 'repokey-blake2'
|
|
|
STORAGE = KeyBlobStorage.REPO
|
|
@@ -824,12 +829,14 @@ class AuthenticatedKeyBase(RepoKey):
|
|
|
|
|
|
class AuthenticatedKey(AuthenticatedKeyBase):
|
|
|
TYPE = 0x07
|
|
|
+ TYPES_ACCEPTABLE = {TYPE}
|
|
|
NAME = 'authenticated'
|
|
|
ARG_NAME = 'authenticated'
|
|
|
|
|
|
|
|
|
class Blake2AuthenticatedKey(ID_BLAKE2b_256, AuthenticatedKeyBase):
|
|
|
TYPE = 0x06
|
|
|
+ TYPES_ACCEPTABLE = {TYPE}
|
|
|
NAME = 'authenticated BLAKE2b'
|
|
|
ARG_NAME = 'authenticated-blake2'
|
|
|
|