Browse Source

Improved error handling

Jonas Borgström 14 years ago
parent
commit
bf08c09dcc
2 changed files with 10 additions and 7 deletions
  1. 5 4
      darc/archive.py
  2. 5 3
      darc/key.py

+ 5 - 4
darc/archive.py

@@ -221,7 +221,7 @@ class Archive(object):
             os.utime(path, (item['mtime'], item['mtime']))
             os.utime(path, (item['mtime'], item['mtime']))
 
 
     def verify_file(self, item, start, result):
     def verify_file(self, item, start, result):
-        def verify_chunk(chunk, error, (id, i, last)):
+        def verify_chunk(chunk, error, (id, i)):
             if error:
             if error:
                 raise error
                 raise error
             if i == 0:
             if i == 0:
@@ -229,7 +229,7 @@ class Archive(object):
             data, hash = self.key.decrypt(chunk)
             data, hash = self.key.decrypt(chunk)
             if self.key.id_hash(data) != id:
             if self.key.id_hash(data) != id:
                 result(item, False)
                 result(item, False)
-            elif last:
+            elif i == n - 1:
                 result(item, True)
                 result(item, True)
         n = len(item['chunks'])
         n = len(item['chunks'])
         if n == 0:
         if n == 0:
@@ -237,13 +237,14 @@ class Archive(object):
             result(item, True)
             result(item, True)
         else:
         else:
             for i, (id, size, csize) in enumerate(item['chunks']):
             for i, (id, size, csize) in enumerate(item['chunks']):
-                self.store.get(NS_CHUNK, id, callback=verify_chunk, callback_data=(id, i, i==n-1))
+                self.store.get(NS_CHUNK, id, callback=verify_chunk, callback_data=(id, i))
 
 
     def delete(self, cache):
     def delete(self, cache):
         def callback(chunk, error, id):
         def callback(chunk, error, id):
             assert not error
             assert not error
             data, items_hash = self.key.decrypt(chunk)
             data, items_hash = self.key.decrypt(chunk)
-            assert self.key.id_hash(data) == id
+            if self.key.id_hash(data) != id:
+                raise IntegrityError('Chunk checksum mismatch')
             unpacker.feed(data)
             unpacker.feed(data)
             for item in unpacker:
             for item in unpacker:
                 try:
                 try:

+ 5 - 3
darc/key.py

@@ -50,7 +50,8 @@ class Key(object):
             if not data:
             if not data:
                 print 'Incorrect password'
                 print 'Incorrect password'
         key = msgpack.unpackb(data)
         key = msgpack.unpackb(data)
-        assert key['version'] == 1
+        if key['version'] != 1:
+            raise IntegrityError('Invalid key file header')
         self.store_id = key['store_id']
         self.store_id = key['store_id']
         self.enc_key = key['enc_key']
         self.enc_key = key['enc_key']
         self.enc_hmac_key = key['enc_hmac_key']
         self.enc_hmac_key = key['enc_hmac_key']
@@ -161,10 +162,11 @@ class Key(object):
         return ''.join(('\0', hash, data)), hash
         return ''.join(('\0', hash, data)), hash
 
 
     def decrypt(self, data):
     def decrypt(self, data):
-        assert data[0] == '\0'
+        if data[0] != '\0':
+            raise IntegrityError('Invalid encryption envelope')
         hash = data[1:33]
         hash = data[1:33]
         if HMAC.new(self.enc_hmac_key, data[33:], SHA256).digest() != hash:
         if HMAC.new(self.enc_hmac_key, data[33:], SHA256).digest() != hash:
-            raise IntegrityError('Encryption integrity error')
+            raise IntegrityError('Encryption envelope checksum mismatch')
         nonce = bytes_to_long(data[33:49])
         nonce = bytes_to_long(data[33:49])
         counter = Counter.new(128, initial_value=nonce, allow_wraparound=True)
         counter = Counter.new(128, initial_value=nonce, allow_wraparound=True)
         data = AES.new(self.enc_key, AES.MODE_CTR, counter=counter).decrypt(data[49:])
         data = AES.new(self.enc_key, AES.MODE_CTR, counter=counter).decrypt(data[49:])