def download(data_hash, sender, signature, decryption_key): """ Check if data_hash is valid SHA-256 hash matched with existing file. Download stored file from the Node. :param data_hash: SHA-256 hash for needed file :param sender: file sender's BitCoin address :param signature: data signature :param decryption_key: key for decrypt stored file :return: file data generator """ node = app.config['NODE'] checker = Checker(data_hash, sender, signature) if not (signature and sender): checks_result_unauthenticated = checker.check_all('hash', 'blacklist', 'file') if checks_result_unauthenticated: return checks_result_unauthenticated if checker.file.role not in ('001', '101'): return ERR_TRANSFER['INVALID_SIGNATURE'] else: checks_result_authenticated = checker.check_all('hash', 'blacklist', 'file', 'signature') if checks_result_authenticated: return checks_result_authenticated file = checker.file if node.limits['outgoing'] is not None and ( file.size > node.limits['outgoing'] - node.current['outgoing'] ): return ERR_TRANSFER['LIMIT_REACHED'] file_path = os.path.join(app.config['UPLOAD_FOLDER'], data_hash) if not os.path.exists(file_path): return ERR_TRANSFER['LOST_FILE'] if decryption_key: if file.role[2] == '1': try: decryption_key = binascii.unhexlify(decryption_key) # test on decryption_key validness test_decrypt_data_generator = convergence.decrypt_generator( file_path, decryption_key) next(test_decrypt_data_generator) decrypt_data_generator = convergence.decrypt_generator( file_path, decryption_key) return decrypt_data_generator except (binascii.Error, ValueError): return ERR_TRANSFER['INVALID_DECRYPTION_KEY'] else: return ERR_TRANSFER['NOT_FOUND'] with open(os.path.join(app.config['UPLOAD_FOLDER'], data_hash), 'rb') as f: returned_data = f.read() return returned_data
def test_streaming_decryption(self): plaintext = self.contents(self.sample1) key = convergence.encrypt_file_inline(self.sample1, "super secret") decrypted = "".encode() for chunk in convergence.decrypt_generator(self.sample1, key): decrypted += chunk self.assertEqual(plaintext, decrypted)
def test_streaming_authenticated_decryption(self): plaintext = self.contents(self.sample1) k,h = convergence.encrypt_file_inline(self.sample1, "test secret", True) decrypted = b"" for chunk in convergence.decrypt_generator(self.sample1, k, h): decrypted += chunk self.assertEqual(plaintext,decrypted)
def test_streaming_authenticated_decryption_failed(self): k,h = convergence.encrypt_file_inline(self.sample1, "test secret", True) # modify file with open(self.sample1, "ab") as f: f.write("data added!\n".encode()) decrypted = b"" with self.assertRaises(AuthenticationError) as ex: for chunk in convergence.decrypt_generator(self.sample1, k, h): decrypted += chunk self.assertEqual(str(ex.exception),"Hash Message Authentication Code invalid.")