import os import zipfile import hashlib from io import BytesIO from PyQt6.QtWidgets import QFileDialog, QMessageBox from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding public_key_path = os.path.join(".config_app","data","public_key.pem") with open(public_key_path, "rb") as key_file: public_key = serialization.load_pem_public_key(key_file.read()) def calcular_hash_zip_sin_firma(zip_data): hash_sha256 = hashlib.sha256() with zipfile.ZipFile(zip_data, 'r') as zipf: for name in sorted(zipf.namelist()): if name == "signature.sig": continue data = zipf.read(name) hash_sha256.update(data) return hash_sha256.digest() def extraer_zip(zip_data, destino): os.makedirs(destino, exist_ok=True) with zipfile.ZipFile(zip_data) as zip_file: for member in zip_file.namelist(): if member == "signature.sig": continue zip_file.extract(member, destino) print(f"Files extracted to: {destino}") def open_zip(): file_dialog = QFileDialog() file_dialog.setFileMode(QFileDialog.FileMode.ExistingFiles) file_dialog.setNameFilter("ZIP files (*.zip)") file_dialog.setViewMode(QFileDialog.ViewMode.List) if file_dialog.exec(): selected_files = file_dialog.selectedFiles() if selected_files: zip_file_path = selected_files[0] if not zip_file_path.lower().endswith(".zip"): QMessageBox.warning(None, "Invalid File", "Please select a valid ZIP file.") return False try: with open(zip_file_path, 'rb') as f: zip_data = BytesIO(f.read()) with zipfile.ZipFile(zip_data) as zip_file: file_list = zip_file.namelist() warning = False if "signature.sig" not in file_list: print("Warning: 'signature.sig' not found in the ZIP.") warning = True else: signature = zip_file.read("signature.sig") file_hash = calcular_hash_zip_sin_firma(zip_data) try: public_key.verify( signature, file_hash, padding.PKCS1v15(), hashes.SHA256() ) print("ZIP is valid and correctly signed.") destination = os.path.expanduser(".config_app/templates") extraer_zip(zip_data, destination) return True except Exception as e: print("ZIP is altered or invalid:", e) warning = True if warning: reply = QMessageBox.question( None, "Signature Warning", "This file may be tampered or unofficial.\nDo you want to continue at your own risk?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.Yes: destination = os.path.expanduser(".config_app/templates") extraer_zip(zip_data, destination) return True else: return False except Exception as e: print(f"Error processing the ZIP file → {e}") QMessageBox.critical(None, "Error", "An error occurred while processing the ZIP file.") return False else: return False else: return False