pass
+class InvalidFileCounter (Exception):
+ """IV fixed part not in supplied list."""
+ pass
+
+
class DuplicateIV (Exception):
"""IV reused."""
pass
% (cnt, AES_GCM_IV_CNT_MAX))
if cnt == AES_GCM_IV_CNT_INFOFILE:
if self.info_counter_used is True:
- raise InvalidParameter ("attempted to reuse info file counter "
- "%d: must be unique" % cnt)
+ raise InvalidFileCounter ("attempted to reuse info file "
+ "counter %d: must be unique" % cnt)
self.info_counter_used = True
elif cnt == AES_GCM_IV_CNT_INDEX:
if self.index_counter_used is True:
- raise InvalidParameter ("attempted to reuse index file counter "
- "%d: must be unique" % cnt)
+ raise InvalidFileCounter ("attempted to reuse index file "
+ " counter %d: must be unique" % cnt)
self.index_counter_used = True
if cnt <= AES_GCM_IV_CNT_MAX:
self.cnt = cnt
if self.enc is None:
raise RuntimeError ("process: context not initialized")
self.stats ["in"] += len (buf)
- out = self.enc.update (buf)
+ try:
+ out = self.enc.update (buf)
+ except cryptography.exceptions.AlreadyFinalized as exn:
+ raise InternalError (exn)
self.stats ["out"] += len (out)
return out
"invalid type %s; please pass an "
"integer instead" % type (counter))
self.set_object_counter (counter)
+
self.iv = self.iv_make ()
if self.paramenc == "aes-gcm":
self.enc = Cipher \
def __del__(self):
if hasattr(self, "closed") and not self.closed:
- self.close()
+ try:
+ self.close()
+ except crypto.InternalError:
+ # context already finalized due to abort but close() tried
+ # to use it
+ pass
def next (self, name):
assert value == self.md5sum(key)
+ def test_create_backup_index_max_file_length (self):
+ """
+ Creates a full backup including one file that exceeds the (purposely
+ lowered) upper bound on GCM encrypted objects. This will yield two
+ encrypted objects for one plaintext file.
+
+ Success is verified by splitting the archive at object boundaries and
+ counting the parts.
+ """
+ if self.MODE_COMPRESSES is True:
+ raise SkipTest ("GCM file length test not meaningful with compression.")
+ if self.ENCRYPTION is None:
+ raise SkipTest ("GCM file length applies only to encrypted backups.")
+
+ new_max = 5000
+ crypto._testing_set_PDTCRYPT_MAX_OBJ_SIZE \
+ ("I am fully aware that this will void my warranty.",
+ new_max)
+
+ password, paramversion = self.ENCRYPTION
+ deltatar = DeltaTar (mode=self.MODE, password=password,
+ crypto_paramversion=paramversion,
+ logger=self.consoleLogger)
+
+ self.hash = dict ()
+ os.makedirs ("source_dir2")
+ for i in range (42):
+ f = "source_dir2/dummy_%rd" % i
+ self.hash [f] = self.create_file (f, i)
+
+ try:
+ deltatar.create_full_backup \
+ (source_path="source_dir2", backup_path="backup_dir")
+ except crypto.InvalidFileCounter:
+ pass
+ shutil.rmtree ("source_dir2")
+
+
def test_check_index_checksum(self):
'''
Creates a full backup and checks the index' checksum of files