unify common operations between encryption and decryption
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Fri, 24 Mar 2017 10:27:45 +0000 (11:27 +0100)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 2 Apr 2018 11:34:08 +0000 (13:34 +0200)
deltatar/crypto.py

index 77ce90e..984bcab 100755 (executable)
@@ -305,8 +305,9 @@ def kdf_by_version (paramversion):
     return partial (fn, params)
 
 
-STATE_DEAD = 0
-STATE_LIVE = 1
+STATE_FRESH = 0
+STATE_DEAD  = 1
+STATE_LIVE  = 2
 
 class Crypto (object):
     """
@@ -322,7 +323,10 @@ class Crypto (object):
     stats = { "in"  : 0
             , "out" : 0
             , "obj" : 0 }
-    state = STATE_DEAD
+
+    state   = STATE_FRESH
+    ctsize  = -1
+    ptsize  = -1
 
     def __init__ (self, *al, **akv):
         self.set_parameters (*al, **akv)
@@ -336,9 +340,7 @@ class Crypto (object):
         if paramversion is None and nacl is None:
             # postpone until first header is available
             return
-        self.nacl         = nacl
-        self.paramversion = paramversion
-        kdf               = kdf_by_version (paramversion)
+        kdf       = kdf_by_version (paramversion)
         if kdf is not None:
             self.key, self.nacl = kdf (password, nacl)
 
@@ -347,6 +349,9 @@ class Crypto (object):
         if self.pfx is None:
             self.pfx = os.urandom(8)
 
+        self.nacl         = nacl
+        self.paramversion = paramversion
+
 
     def process (self, buf):
         if self.aes is not None:
@@ -357,6 +362,13 @@ class Crypto (object):
         return b""
 
 
+    def next (self):
+        self.ctsize = 0
+        self.ptsize = 0
+        self.stats ["obj"] += 1
+        self.state = STATE_LIVE
+
+
     def counters (self):
         return self.stats ["obj"], self.stats ["in"], self.stats ["out"]
 
@@ -368,7 +380,6 @@ class Encrypt (Crypto):
 
     curobj = None
     hdrdum = None
-    ctsize = -1     # per object from .next() → .done()
 
     def __init__ (self, password, paramversion, nacl=None,
                   counter=AES_GCM_IV_CNT_DATA):
@@ -383,7 +394,6 @@ class Encrypt (Crypto):
         self.iv = self.iv_make()
         self.curobj = (filename, version, paramversion, nacl or self.nacl)
         self.cnt += 1
-        self.ctsize = 0
         self.aes = Cipher \
                         ( algorithms.AES (self.key)
                         , modes.GCM (self.iv)
@@ -395,8 +405,7 @@ class Encrypt (Crypto):
         #self.aes.authenticate_additional_data (str.encode (aad))
 
         self.hdrdum = hdr_make_dummy (filename)
-        self.stats ["obj"] += 1
-        self.state = STATE_LIVE
+        super().next ()
         return self.hdrdum
 
 
@@ -416,6 +425,7 @@ class Encrypt (Crypto):
 
 
     def process (self, buf):
+        self.ptsize += len (buf)
         data = super().process (buf)
         self.ctsize += len (data)
         return data
@@ -425,8 +435,6 @@ class Decrypt (Crypto):
 
     pfx          = None
     tag          = None # GCM tag, part of header
-    ctsize       = -1
-    ptsize       = -1
 
     def __init__ (self, password, paramversion=None, nacl=None, counter=None):
         super().__init__ (password, paramversion, nacl, counter=counter)
@@ -446,11 +454,6 @@ class Decrypt (Crypto):
         # XXX figure out what we want for AAD. Filename (not known to stream)?
         #     Size?
         #self.aes.authenticate_additional_data (str.encode (aad))
-        ctsize = 0
-        ptsize = 0
-        self.stats ["obj"] += 1
-        self.state = STATE_LIVE
-
 
     def next_in_source (self, tarinfo, source):
         ok, hdr = hdr_read_stream (source)