Browse Source

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 years ago
parent
commit
fcea641e26
2 changed files with 8 additions and 23 deletions
  1. 4 21
      attic/key.py
  2. 4 2
      attic/testsuite/archiver.py

+ 4 - 21
attic/key.py

@@ -504,19 +504,8 @@ def parser02(all_data):
 
 
 
 
 def parser03(all_data):  # new & flexible
 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)
     compressor, crypter, maccer = get_implementations(meta)
     return meta, data, compressor, crypter, maccer
     return meta, data, compressor, crypter, maccer
 
 
@@ -540,14 +529,8 @@ def key_factory(repository, manifest_data):
 
 
 def generate(meta, data):
 def generate(meta, data):
     # always create new-style 0x03 format
     # 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):
 def compressor_creator(args):
     # args == None is used by unit tests
     # 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.archiver import Archiver
 from attic.crypto import bytes_to_long, num_aes_blocks
 from attic.crypto import bytes_to_long, num_aes_blocks
 from attic.helpers import Manifest
 from attic.helpers import Manifest
+from attic.key import parser
 from attic.remote import RemoteRepository, PathNotAllowed
 from attic.remote import RemoteRepository, PathNotAllowed
 from attic.repository import Repository
 from attic.repository import Repository
 from attic.testsuite import AtticTestCase
 from attic.testsuite import AtticTestCase
@@ -359,8 +360,9 @@ class ArchiverTestCase(ArchiverTestCaseBase):
                 hash = sha256(data).digest()
                 hash = sha256(data).digest()
                 if not hash in seen:
                 if not hash in seen:
                     seen.add(hash)
                     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):
                     for counter in range(nonce, nonce + num_blocks):
                         self.assert_not_in(counter, used)
                         self.assert_not_in(counter, used)
                         used.add(counter)
                         used.add(counter)