99 lines
3.9 KiB
Python
99 lines
3.9 KiB
Python
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
|