redo transition between objects in crypto layer
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Thu, 16 Mar 2017 16:06:28 +0000 (17:06 +0100)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 2 Apr 2018 11:34:08 +0000 (13:34 +0200)
When encrypting, the ciphertext size isn’t known beforehand.
Likewise, the file name isn’t available when initializing the
decryption of a file.

deltatar/crypto.py

index 2ac588b..2d84ccc 100755 (executable)
@@ -93,6 +93,7 @@ HDR_OFF_PARAMVERSION = HDR_OFF_VERSION      + I2N_HDR_SIZE_VERSION
 HDR_OFF_NACL         = HDR_OFF_PARAMVERSION + I2N_HDR_SIZE_PARAMVERSION
 HDR_OFF_IV           = HDR_OFF_NACL         + I2N_HDR_SIZE_NACL
 HDR_OFF_CTSIZE       = HDR_OFF_IV           + I2N_HDR_SIZE_IV
+HDR_CTSIZE_DUMMY     = 0xffffFFFFffffFFFF
 
 FMT_UINT16_LE = "<H"
 FMT_UINT64_LE = "<Q"
@@ -168,7 +169,7 @@ def hdr_read_stream (instr):
 
 def hdr_from_params (version, paramversion, nacl, iv, ctsize=None):
     if ctsize is None:
-        ctsize = 0xffffFFFFffffFFFF # dummy, overwritten later
+        ctsize = HDR_CTSIZE_DUMMY # dummy, overwritten later
     buf  = bytearray (I2N_HDR_SIZE)
     bufv = memoryview (buf)
 
@@ -312,10 +313,6 @@ class Crypto (object):
         self.pfx          = pfx
 
 
-    def next (self, aad=None, iv=None):
-        self.aes.authenticate_additional_data (aad)
-
-
     def process (self, buf):
         self.aes.update (buf)
 
@@ -333,17 +330,17 @@ class Encrypt (Crypto):
         return struct.pack("<8sL", self.pfx, self.cnt % 0xffFFffFF)
 
 
-    def next (self, filename, ctsize):
+    def next (self, filename):
         self.cnt += 1
-        aad = "%.20x|%s" % (ctsize, filename)
-        iv = iv_make()
+        aad = "%s" % filename
+        iv = self.iv_make()
         self.aes = Cipher \
                         ( algorithms.AES (self.key)
                         , modes.GCM (iv)
                         , backend = default_backend ()) \
                         .encryptor ()
 
-        return super().next(aad)
+        return self.aes.authenticate_additional_data (aad)
 
 
     def done (self):
@@ -358,16 +355,14 @@ class Decrypt (Crypto):
         super().__init__ (password, paramversion, nacl)
 
 
-    def next (self, filename, hdr):
+    def next (self, hdr):
         self.cnt += 1
-        aad = "%0.20x|%s" % (hdr["ctsize"], filename)
         print("I2N: got header “%s”" % crypto.hdr_fmt (hdr))
         self.aes = Cipher \
                         ( algorithms.AES (key)
                         , modes.GCM (hdr["iv"])
                         , backend = default_backend ()) \
                         . decryptor ()
-        return super().next(aad)
 
 
     def next_in_source (self, tarinfo, source):
@@ -375,10 +370,12 @@ class Decrypt (Crypto):
         if ok is False:
             raise DecryptionError("Irrecoverable error reading header from "
                                   "%r" % source)
-        return self.next(tarinfo.name, hdr)
+        return self.next(hdr)
 
 
-    def done (self, tag):
+    def done (self, filename, tag):
+        aad = "%s" % filename
+        self.aes.authenticate_additional_data (aad)
         return self.aes.finalize_with_tag (tag)