Merge branch 'crypto-review'
[python-delta-tar] / deltatar / tarfile.py
index 325feb8..8fc47d6 100644 (file)
@@ -526,6 +526,9 @@ class _Stream:
         self.encryption = encryption
         self.lasthdr    = None
 
+        if encryption is not None:
+            encryption.reset_last_iv ()
+
         try:
             if comptype == "gz":
                 try:
@@ -937,8 +940,13 @@ class _Stream:
         """Set the stream's file pointer to pos. Negative seeking
            is forbidden.
         """
-        if pos - self.pos >= 0:
+        if pos == self.pos:
+            pass # nothing to do
+        elif pos - self.pos >= 0:
             blocks, remainder = divmod(pos - self.pos, self.bufsize)
+            if self.encryption is not None:
+                # IV succession is only preserved between successive objects.
+                self.encryption.reset_last_iv ()
             for i in range(blocks):
                 self.read(self.bufsize)
             self.read(remainder)
@@ -3720,17 +3728,26 @@ def reconstruct_offsets_tar (fname):
         os.close (ifd)
 
 
-def read_tarobj_at_offset (fileobj, offset, mode, secret=None):
+def read_tarobj_at_offset (fileobj, offset, mode, secret=None,
+                           strict_validation=True):
+    """
+    :type  strict_validation:   bool
+    :param strict_validation:   Enable strict IV checking in the crypto
+                                layer. Should be disabled when dealing with
+                                potentially corrupted data.
+    """
     decr = None
 
     if secret is not None:
         ks   = secret [0]
 
         if ks == crypto.PDTCRYPT_SECRET_PW:
-            decr = crypto.Decrypt (password=secret [1])
+            decr = crypto.Decrypt (password=secret [1],
+                                   strict_ivs=strict_validation)
         elif ks == crypto.PDTCRYPT_SECRET_KEY:
             key = binascii.unhexlify (secret [1])
-            decr = crypto.Decrypt (key=key)
+            decr = crypto.Decrypt (key=key,
+                                   strict_ivs=strict_validation)
         else:
             raise RuntimeError
 
@@ -3816,7 +3833,8 @@ def gen_rescue_index (gen_volume_name, mode, maxvol=None, password=None, key=Non
         fileobj = bltn_open (vpath, "rb")
 
         def aux (acc, off):
-            obj = read_tarobj_at_offset (fileobj, off, mode, secret=secret)
+            obj = read_tarobj_at_offset (fileobj, off, mode, secret=secret,
+                                         strict_validation=False)
             if obj is not None:
                 acc.append ((off, nvol, obj))
             return acc