2
0
Эх сурвалжийг харах

reimplement new 0x03 format using msgpack

this is much easier to maintain (and change, if needed) than all those hardcoded offsets.

note:

when using packb to store a namedtuple's data, just the tuple's elements get stored, in order (not the names).
thus, the overhead is rather small. but we can just recreate the namedtuple from the tuple returned by unpackb.

namedtuples are very efficient and prettier to deal with than tuples. alternatively, a dictionary could be used,
but packb would create more overhead for it as key names and values would be stored.
Thomas Waldmann 10 жил өмнө
parent
commit
fcea641e26

+ 4 - 21
attic/key.py

@@ -504,19 +504,8 @@ def parser02(all_data):
 
 
 def parser03(all_data):  # new & flexible
-    offset = 4
-    compr_type, crypt_type, mac_type = all_data[1:offset]
-    if crypt_type == PlaintextKey.TYPE:
-        hmac = None
-        iv = stored_iv = None
-        data = all_data[offset:]
-    else:
-        hmac = all_data[offset:offset+32]
-        stored_iv = all_data[offset+32:offset+40]
-        iv = PREFIX + stored_iv
-        data = all_data[offset+40:]
-    meta = Meta(compr_type=compr_type, crypt_type=crypt_type, mac_type=mac_type,
-                hmac=hmac, iv=iv, stored_iv=stored_iv)
+    meta_tuple, data = msgpack.unpackb(all_data[1:])
+    meta = Meta(*meta_tuple)
     compressor, crypter, maccer = get_implementations(meta)
     return meta, data, compressor, crypter, maccer
 
@@ -540,14 +529,8 @@ def key_factory(repository, manifest_data):
 
 def generate(meta, data):
     # always create new-style 0x03 format
-    start = bytes([0x03, meta.compr_type, meta.crypt_type, meta.mac_type])
-    if meta.crypt_type == PlaintextKey.TYPE:
-        result = start + data
-    else:
-        assert len(meta.hmac) == 32
-        assert len(meta.stored_iv) == 8
-        result = start + meta.hmac + meta.stored_iv + data
-    return result
+    return b'\x03' + msgpack.packb((meta, data))
+
 
 def compressor_creator(args):
     # args == None is used by unit tests

+ 4 - 2
attic/testsuite/archiver.py

@@ -13,6 +13,7 @@ from attic.archive import Archive, ChunkBuffer
 from attic.archiver import Archiver
 from attic.crypto import bytes_to_long, num_aes_blocks
 from attic.helpers import Manifest
+from attic.key import parser
 from attic.remote import RemoteRepository, PathNotAllowed
 from attic.repository import Repository
 from attic.testsuite import AtticTestCase
@@ -359,8 +360,9 @@ class ArchiverTestCase(ArchiverTestCaseBase):
                 hash = sha256(data).digest()
                 if not hash in seen:
                     seen.add(hash)
-                    num_blocks = num_aes_blocks(len(data) - 4 - 40)
-                    nonce = bytes_to_long(data[4+32:4+40])
+                    meta, data, _, _, _ = parser(data)
+                    num_blocks = num_aes_blocks(len(data))
+                    nonce = bytes_to_long(meta.stored_iv)
                     for counter in range(nonce, nonce + num_blocks):
                         self.assert_not_in(counter, used)
                         used.add(counter)