use exception to communicate tag mismatch
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Mon, 10 Apr 2017 08:27:47 +0000 (10:27 +0200)
committerPhilipp Gesang <philipp.gesang@intra2net.com>
Mon, 7 Aug 2017 12:02:46 +0000 (14:02 +0200)
deltatar/crypto.py
deltatar/tarfile.py

index 17aa074..f40270a 100755 (executable)
@@ -67,30 +67,45 @@ class EndOfFile (Exception):
     """Reached EOF."""
     pass
 
+
 class InvalidParameter (Exception):
     """Inputs not valid for PDT encryption."""
     pass
 
+
 class InvalidHeader (Exception):
     """Header not valid."""
     pass
 
+
+class InvalidGCMTag (Exception):
+    """
+    The GCM tag calculated during decryption differs from that in the object
+    header.
+    """
+    pass
+
+
 class InvalidIVFixedPart (Exception):
     """IV fixed part not in supplied list."""
     pass
 
+
 class FormatError (Exception):
     """Unusable parameters in header."""
     pass
 
+
 class DecryptionError (Exception):
     """Error during decryption."""
     pass
 
+
 class Unreachable (Exception):
     """Makeshift __builtin_unreachable()."""
     pass
 
+
 class InternalError (Exception):
     """Errors not ascribable to bad user inputs or cryptography."""
     pass
@@ -564,18 +579,19 @@ class Decrypt (Crypto):
 
 
     def done (self, tag=None):
-        ret  = True
         data = b""
         try:
             if tag is None:
                 data = self.enc.finalize ()
             else:
                 data = self.enc.finalize_with_tag (self.tag)
-        except cryptography.exceptions.InvalidTag as exn:
-            return False, repr (exn)
+        except cryptography.exceptions.InvalidTag:
+            return InvalidGCMTag ("done: tag mismatch of object %d: %r "
+                                  "rejected by finalize ()"
+                                  % (self.cnt, self.tag))
         self.ctsize += len (data)
         self.stats ["out"] += len (data)
-        return ret, data
+        return data
 
 
     def process (self, buf):
index 65513c5..23968fc 100644 (file)
@@ -783,19 +783,11 @@ class _Stream:
             and self.lasthdr    is not None :
             assert self.remainder >= 0
             if self.remainder > 0:
-                # should only be happening with the last item in the archive
-                #zeroes = self.fileobj.read (self.remainder)
-                #pred_all_zero = lambda c: c == 0
-                #if all (pred_all_zero (c) for c in zeroes) is False:
-                #    # this isn’t the last two blocks; something is messed up
-                #    raise DecryptionError ("trailing blocks of %d B contain "
-                #                           "non-zero bytes" % self.remainder)
-                #assert len (zeroes) == self.remainder
                 self.remainder = 0
-            ok, data = self.encryption.done ()
-            if ok is False: # XXX handle error
-                print(">> !!!!!!! %s" % data)
-                print(">> bad tag %s" % self.encryption.tag)
+            try:
+                data = self.encryption.done ()
+            except crypto.InvalidGCMTag as exn:
+                raise DecryptionError ("decryption failed: %s" % exn)
             return data