graciously handle GCM data length limit
[python-delta-tar] / testing / test_crypto.py
index aad35f7..8e5d210 100644 (file)
@@ -64,6 +64,13 @@ class CryptoLayerTest (unittest.TestCase):
 
 class AESGCMTest (CryptoLayerTest):
 
+    def tearDown (self):
+        """Reset globals altered for testing."""
+        _ = crypto._testing_set_AES_GCM_IV_CNT_MAX \
+                  ("I am fully aware that this will void my warranty.")
+        _ = crypto._testing_set_PDTCRYPT_MAX_OBJ_SIZE \
+                  ("I am fully aware that this will void my warranty.")
+
     def test_crypto_aes_gcm_enc_ctor (self):
         password   = str (os.urandom (42))
         encryptor  = crypto.Encrypt (TEST_VERSION,
@@ -128,7 +135,7 @@ class AESGCMTest (CryptoLayerTest):
 
         header_dummy   = encryptor.next (TEST_DUMMY_FILENAME)
         assert len (header_dummy) == crypto.PDTCRYPT_HDR_SIZE
-        _              = encryptor.process (TEST_PLAINTEXT)
+        _, _           = encryptor.process (TEST_PLAINTEXT)
         _, header, _   = encryptor.done (header_dummy)
         assert len (header) == crypto.PDTCRYPT_HDR_SIZE
 
@@ -141,7 +148,7 @@ class AESGCMTest (CryptoLayerTest):
                                          nacl=TEST_STATIC_NACL)
 
         header_dummy   = encryptor.next (TEST_DUMMY_FILENAME)
-        ciphertext     = encryptor.process (TEST_PLAINTEXT)
+        _, ciphertext  = encryptor.process (TEST_PLAINTEXT)
         assert len (ciphertext) == len (TEST_PLAINTEXT)
         rest, header, fixed = encryptor.done (header_dummy)
         assert len (rest) == 0
@@ -181,7 +188,7 @@ class AESGCMTest (CryptoLayerTest):
                                          nacl=TEST_STATIC_NACL)
 
         header_dummy   = encryptor.next (TEST_DUMMY_FILENAME)
-        ciphertext     = encryptor.process (TEST_PLAINTEXT)
+        _, ciphertext  = encryptor.process (TEST_PLAINTEXT)
         rest, header, fixed = encryptor.done (header_dummy)
         ciphertext    += rest
 
@@ -202,7 +209,7 @@ class AESGCMTest (CryptoLayerTest):
                                          nacl=TEST_STATIC_NACL)
 
         header_dummy   = encryptor.next (TEST_DUMMY_FILENAME)
-        ciphertext     = encryptor.process (TEST_PLAINTEXT)
+        _, ciphertext  = encryptor.process (TEST_PLAINTEXT)
         ciphertext2, header, fixed = encryptor.done (header_dummy)
 
         mut_header     = bytearray (header)
@@ -235,7 +242,7 @@ class AESGCMTest (CryptoLayerTest):
         ct = b""
         while off < len (pt):
             upto = min (off + cnksiz, len (pt))
-            cnk = encryptor.process (pt [off:upto])
+            _, cnk = encryptor.process (pt [off:upto])
             ct += cnk
             off += cnksiz
         cnk, header, fixed = encryptor.done (header_dummy)
@@ -259,7 +266,7 @@ class AESGCMTest (CryptoLayerTest):
         ct = b""
         while off < len (pt):
             upto = min (off + cnksiz, len (pt))
-            cnk = encryptor.process (pt [off:upto])
+            _, cnk = encryptor.process (pt [off:upto])
             ct += cnk
             off += cnksiz
         cnk, header, fixed = encryptor.done (header_dummy)
@@ -285,7 +292,7 @@ class AESGCMTest (CryptoLayerTest):
             ct = b""
             while off < len (pt):
                 upto = min (off + cnksiz, len (pt))
-                cnk = encryptor.process (pt [off:upto])
+                _, cnk = encryptor.process (pt [off:upto])
                 ct += cnk
                 off += cnksiz
             cnk, header, fixed = encryptor.done (header_dummy)
@@ -313,7 +320,7 @@ class AESGCMTest (CryptoLayerTest):
             ct = b""
             while off < len (pt):
                 upto = min (off + cnksiz, len (pt))
-                cnk = encryptor.process (pt [off:upto])
+                _, cnk = encryptor.process (pt [off:upto])
                 ct += cnk
                 off += cnksiz
             cnk, header, fixed = encryptor.done (header_dummy)
@@ -329,15 +336,14 @@ class AESGCMTest (CryptoLayerTest):
         Test behavior when the file counter tops out.
 
         Artificially lower the maximum possible file counter. Considering
-        invalid (0) and reserved (1, 2) values, the least possible file counter
+        invalid (0) and reserved (1, 2) values, the smallest possible file counter
         for normal objects is 3. Starting from that, the header of the (max -
         3)rd object must have both a different IV fixed part and a counter.
         """
         minimum = 3
         new_max = 8
-        old_max = crypto._testing_set_AES_GCM_IV_CNT_MAX \
-                        ("I am fully aware that this will void my warranty.",
-                         new_max)
+        crypto._testing_set_AES_GCM_IV_CNT_MAX \
+                ("I am fully aware that this will void my warranty.", new_max)
         cnksiz    = 1 << 10
         password  = str (os.urandom (42))
         encryptor = crypto.Encrypt (TEST_VERSION,
@@ -359,7 +365,7 @@ class AESGCMTest (CryptoLayerTest):
             ct = b""
             while off < len (pt):
                 upto = min (off + cnksiz, len (pt))
-                cnk = encryptor.process (pt [off:upto])
+                _, cnk = encryptor.process (pt [off:upto])
                 ct += cnk
                 off += cnksiz
             cnk, header, fixed = encryptor.done (header_dummy)
@@ -384,9 +390,37 @@ class AESGCMTest (CryptoLayerTest):
         for j in range (i + 2, i + new_max - 1): addobj (j) # counter range: [4, 8]
         addobj (j + 1, True) # counter wraps to 3 again
 
-        _ = crypto._testing_set_AES_GCM_IV_CNT_MAX \
-                  ("I am fully aware that this will void my warranty.",
-                   old_max)
+
+    def test_crypto_aes_gcm_enc_length_cap (self):
+        """
+        Artificially lower the maximum allowable data length and attempt to
+        encrypt a larger object. Verify that the crypto handler aborts with and
+        exception.
+        """
+        new_max = 2187
+        crypto._testing_set_PDTCRYPT_MAX_OBJ_SIZE \
+                ("I am fully aware that this will void my warranty.", new_max)
+        cnksiz    = 1 << 10
+        password  = str (os.urandom (42))
+        encryptor = crypto.Encrypt (TEST_VERSION,
+                                    TEST_PARAMVERSION,
+                                    password=password,
+                                    nacl=TEST_STATIC_NACL)
+
+        def encobj (s):
+            pt, ct       = fill_mod (s), None
+            header_dummy = encryptor.next ("%s_%d" % (TEST_DUMMY_FILENAME, s))
+
+            n, ct = encryptor.process (pt)
+            rest, _, _ = encryptor.done (header_dummy)
+            ct += rest
+
+            if len (pt) > new_max:
+                assert n < len (pt)
+            else:
+                assert n == len (pt) == len (ct)
+
+        for i in range (16): encobj (1 << i)
 
 
     def test_crypto_aes_gcm_dec_multicnk (self):
@@ -403,7 +437,7 @@ class AESGCMTest (CryptoLayerTest):
         ct = b""
         while off < len (orig_pt):
             upto = min (off + cnksiz, len (orig_pt))
-            cnk = encryptor.process (orig_pt [off:upto])
+            _n, cnk = encryptor.process (orig_pt [off:upto])
             ct += cnk
             off += cnksiz
         cnk, header, fixed = encryptor.done (header_dummy)
@@ -416,7 +450,7 @@ class AESGCMTest (CryptoLayerTest):
         pt  = b""
         while off < len (orig_pt):
             upto = min (off + cnksiz, len (orig_pt))
-            cnk = decryptor.process (ct [off:upto])
+            cnk  = decryptor.process (ct [off:upto])
             pt += cnk
             off += cnksiz
 
@@ -439,7 +473,7 @@ class AESGCMTest (CryptoLayerTest):
         ct = b""
         while off < len (orig_pt):
             upto = min (off + cnksiz, len (orig_pt))
-            cnk = encryptor.process (orig_pt [off:upto])
+            _n, cnk = encryptor.process (orig_pt [off:upto])
             ct += cnk
             off += cnksiz
         cnk, header, fixed = encryptor.done (header_dummy)
@@ -491,7 +525,7 @@ class AESGCMTest (CryptoLayerTest):
             ct = b""
             while off < len (pt):
                 upto = min (off + cnksiz, len (pt))
-                cnk = encryptor.process (pt [off:upto])
+                _n, cnk = encryptor.process (pt [off:upto])
                 ct += cnk
                 off += cnksiz
             cnk, header, fixed = encryptor.done (header_dummy)