mirror of
https://github.com/borgbackup/borg.git
synced 2026-06-11 09:59:19 -04:00
cosmetics: comments, rename crypt... -> key...
This commit is contained in:
parent
f042845762
commit
c1c94a8682
1 changed files with 36 additions and 26 deletions
62
attic/key.py
62
attic/key.py
|
|
@ -23,7 +23,7 @@ from attic.helpers import IntegrityError, get_keys_dir, Error
|
|||
# zero anyway as the full IV is a 128bit counter. PREFIX are the upper 8 bytes,
|
||||
# stored_iv are the lower 8 Bytes.
|
||||
PREFIX = b'\0' * 8
|
||||
Meta = namedtuple('Meta', 'compr_type, crypt_type, mac_type, cipher_type, hmac, stored_iv')
|
||||
Meta = namedtuple('Meta', 'compr_type, key_type, mac_type, cipher_type, hmac, stored_iv')
|
||||
|
||||
|
||||
class UnsupportedPayloadError(Error):
|
||||
|
|
@ -63,6 +63,9 @@ class HMAC(hmac.HMAC):
|
|||
self.inner.update(msg)
|
||||
|
||||
|
||||
# HASH / MAC stuff below all has a mac-like interface, so it can be used in the same way.
|
||||
# special case: hashes do not use keys (and thus, do not sign/authenticate)
|
||||
|
||||
class SHA256(object): # note: can't subclass sha256
|
||||
TYPE = 0
|
||||
|
||||
|
|
@ -93,9 +96,6 @@ class SHA512_256(sha512_256):
|
|||
super().__init__(data)
|
||||
|
||||
|
||||
HASH_DEFAULT = SHA256.TYPE
|
||||
|
||||
|
||||
class HMAC_SHA256(HMAC):
|
||||
TYPE = 10
|
||||
|
||||
|
|
@ -131,9 +131,13 @@ class GMAC:
|
|||
return tag
|
||||
|
||||
|
||||
HASH_DEFAULT = SHA256.TYPE
|
||||
MAC_DEFAULT = GMAC.TYPE
|
||||
|
||||
|
||||
# compressor classes, all same interface
|
||||
# special case: zlib level 0 is "no compression"
|
||||
|
||||
class ZlibCompressor(object): # uses 0..9 in the mapping
|
||||
TYPE = 0
|
||||
LEVELS = range(10)
|
||||
|
|
@ -165,6 +169,9 @@ class LzmaCompressor(object): # uses 10..19 in the mapping
|
|||
COMPR_DEFAULT = ZlibCompressor.TYPE + 6 # zlib level 6
|
||||
|
||||
|
||||
# ciphers - AEAD (authenticated encryption with assoc. data) style interface
|
||||
# special case: PLAIN dummy does not encrypt / authenticate
|
||||
|
||||
class PLAIN:
|
||||
TYPE = 0
|
||||
|
||||
|
|
@ -217,6 +224,9 @@ PLAIN_DEFAULT = PLAIN.TYPE
|
|||
CIPHER_DEFAULT = AES_GCM.TYPE
|
||||
|
||||
|
||||
# misc. types of keys
|
||||
# special case: no keys (thus: no encryption, no signing/authentication)
|
||||
|
||||
class KeyBase(object):
|
||||
TYPE = 0x00 # override in derived classes
|
||||
|
||||
|
|
@ -243,14 +253,14 @@ class KeyBase(object):
|
|||
def encrypt(self, data):
|
||||
data = self.compressor.compress(data)
|
||||
tag, iv_last8, data = self.cipher.compute_tag_and_encrypt(data)
|
||||
meta = Meta(compr_type=self.compressor.TYPE, crypt_type=self.TYPE,
|
||||
meta = Meta(compr_type=self.compressor.TYPE, key_type=self.TYPE,
|
||||
mac_type=self.maccer_cls.TYPE, cipher_type=self.cipher.TYPE,
|
||||
hmac=tag, stored_iv=iv_last8)
|
||||
return generate(meta, data)
|
||||
|
||||
def decrypt(self, id, data):
|
||||
meta, data, compressor, crypter, maccer, cipher = parser(data)
|
||||
assert isinstance(self, crypter)
|
||||
meta, data, compressor, keyer, maccer, cipher = parser(data)
|
||||
assert isinstance(self, keyer)
|
||||
assert self.maccer_cls is maccer
|
||||
assert self.cipher_cls is cipher
|
||||
data = self.cipher.check_tag_and_decrypt(meta.hmac, meta.stored_iv, data)
|
||||
|
|
@ -275,7 +285,7 @@ class PlaintextKey(KeyBase):
|
|||
|
||||
@classmethod
|
||||
def detect(cls, repository, manifest_data):
|
||||
meta, data, compressor, crypter, maccer, cipher = parser(manifest_data)
|
||||
meta, data, compressor, keyer, maccer, cipher = parser(manifest_data)
|
||||
return cls(compressor, maccer, cipher)
|
||||
|
||||
|
||||
|
|
@ -292,8 +302,8 @@ class AESKeyBase(KeyBase):
|
|||
only 295 exabytes!
|
||||
"""
|
||||
def extract_nonce(self, payload):
|
||||
meta, data, compressor, crypter, maccer, cipher = parser(payload)
|
||||
assert isinstance(self, crypter)
|
||||
meta, data, compressor, keyer, maccer, cipher = parser(payload)
|
||||
assert isinstance(self, keyer)
|
||||
nonce = bytes_to_long(meta.stored_iv)
|
||||
return nonce
|
||||
|
||||
|
|
@ -346,7 +356,7 @@ class PassphraseKey(AESKeyBase):
|
|||
@classmethod
|
||||
def detect(cls, repository, manifest_data):
|
||||
prompt = 'Enter passphrase for %s: ' % repository._location.orig
|
||||
meta, data, compressor, crypter, maccer, cipher = parser(manifest_data)
|
||||
meta, data, compressor, keyer, maccer, cipher = parser(manifest_data)
|
||||
key = cls(compressor, maccer, cipher)
|
||||
passphrase = os.environ.get('ATTIC_PASSPHRASE')
|
||||
if passphrase is None:
|
||||
|
|
@ -378,7 +388,7 @@ class KeyfileKey(AESKeyBase):
|
|||
|
||||
@classmethod
|
||||
def detect(cls, repository, manifest_data):
|
||||
meta, data, compressor, crypter, maccer, cipher = parser(manifest_data)
|
||||
meta, data, compressor, keyer, maccer, cipher = parser(manifest_data)
|
||||
key = cls(compressor, maccer, cipher)
|
||||
path = cls.find_key_file(repository)
|
||||
prompt = 'Enter passphrase for key file %s: ' % path
|
||||
|
|
@ -510,7 +520,7 @@ for preset in LzmaCompressor.PRESETS:
|
|||
type('LzmaCompressorPreset%d' % preset, (LzmaCompressor, ), dict(TYPE=LzmaCompressor.TYPE + preset))
|
||||
|
||||
|
||||
crypter_mapping = {
|
||||
keyer_mapping = {
|
||||
KeyfileKey.TYPE: KeyfileKey,
|
||||
PassphraseKey.TYPE: PassphraseKey,
|
||||
PlaintextKey.TYPE: PlaintextKey,
|
||||
|
|
@ -540,16 +550,16 @@ cipher_mapping = {
|
|||
def get_implementations(meta):
|
||||
try:
|
||||
compressor = compressor_mapping[meta.compr_type]
|
||||
crypter = crypter_mapping[meta.crypt_type]
|
||||
keyer = keyer_mapping[meta.key_type]
|
||||
maccer = maccer_mapping[meta.mac_type]
|
||||
cipher = cipher_mapping[meta.cipher_type]
|
||||
except KeyError:
|
||||
raise UnsupportedPayloadError("compr_type %x crypt_type %x mac_type %x" % (
|
||||
meta.compr_type, meta.crypt_type, meta.mac_type, meta.cipher_type))
|
||||
return compressor, crypter, maccer, cipher
|
||||
raise UnsupportedPayloadError("compr_type %x key_type %x mac_type %x" % (
|
||||
meta.compr_type, meta.key_type, meta.mac_type, meta.cipher_type))
|
||||
return compressor, keyer, maccer, cipher
|
||||
|
||||
|
||||
def legacy_parser(all_data, crypt_type): # all rather hardcoded
|
||||
def legacy_parser(all_data, key_type): # all rather hardcoded
|
||||
"""
|
||||
Payload layout:
|
||||
no encryption: TYPE(1) + data
|
||||
|
|
@ -562,7 +572,7 @@ def legacy_parser(all_data, crypt_type): # all rather hardcoded
|
|||
only 295 exabytes!
|
||||
"""
|
||||
offset = 1
|
||||
if crypt_type == PlaintextKey.TYPE:
|
||||
if key_type == PlaintextKey.TYPE:
|
||||
hmac = None
|
||||
iv = stored_iv = None
|
||||
data = all_data[offset:]
|
||||
|
|
@ -570,11 +580,11 @@ def legacy_parser(all_data, crypt_type): # all rather hardcoded
|
|||
hmac = all_data[offset:offset+32]
|
||||
stored_iv = all_data[offset+32:offset+40]
|
||||
data = all_data[offset+40:]
|
||||
meta = Meta(compr_type=6, crypt_type=crypt_type,
|
||||
meta = Meta(compr_type=6, key_type=key_type,
|
||||
mac_type=HMAC_SHA256.TYPE, cipher_type=AES_CTR_HMAC.TYPE,
|
||||
hmac=hmac, stored_iv=stored_iv)
|
||||
compressor, crypter, maccer, cipher = get_implementations(meta)
|
||||
return meta, data, compressor, crypter, maccer, cipher
|
||||
compressor, keyer, maccer, cipher = get_implementations(meta)
|
||||
return meta, data, compressor, keyer, maccer, cipher
|
||||
|
||||
def parser00(all_data):
|
||||
return legacy_parser(all_data, KeyfileKey.TYPE)
|
||||
|
|
@ -601,8 +611,8 @@ def parser03(all_data): # new & flexible
|
|||
# more recent ones, not by 0.4.2. So, fix here when 0.4.6 is out. :-(
|
||||
meta_tuple, data = msgpack.unpackb(all_data[1:])
|
||||
meta = Meta(*meta_tuple)
|
||||
compressor, crypter, maccer, cipher = get_implementations(meta)
|
||||
return meta, data, compressor, crypter, maccer, cipher
|
||||
compressor, keyer, maccer, cipher = get_implementations(meta)
|
||||
return meta, data, compressor, keyer, maccer, cipher
|
||||
|
||||
|
||||
def parser(data):
|
||||
|
|
@ -618,8 +628,8 @@ def parser(data):
|
|||
|
||||
|
||||
def key_factory(repository, manifest_data):
|
||||
meta, data, compressor, crypter, maccer, cipher = parser(manifest_data)
|
||||
return crypter.detect(repository, manifest_data)
|
||||
meta, data, compressor, keyer, maccer, cipher = parser(manifest_data)
|
||||
return keyer.detect(repository, manifest_data)
|
||||
|
||||
|
||||
def generate(meta, data):
|
||||
|
|
|
|||
Loading…
Reference in a new issue