commit 1971b210d605e38f2529ebb2f404cfa3fdd2d6e1 Author: gru Date: Wed Nov 26 08:29:12 2025 +0100 Add pfx_extract.py diff --git a/pfx_extract.py b/pfx_extract.py new file mode 100644 index 0000000..aecbbd7 --- /dev/null +++ b/pfx_extract.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +import argparse +import os +import subprocess +import tarfile +import tempfile +import shutil +import sys + +def run_cmd(cmd, password): + env = os.environ.copy() + # hasło przekazujemy przez zmienną środowiskową, żeby nie wisiało w ps + env["PFXPASSWORD"] = password + # używamy -passin env:PFXPASSWORD w openssl + result = subprocess.run( + cmd, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + if result.returncode != 0: + print("Błąd wykonania:", " ".join(cmd), file=sys.stderr) + print(result.stderr, file=sys.stderr) + sys.exit(result.returncode) + return result.stdout + +def extract_from_pfx(pfx_path, password, out_dir, base_name): + key_path = os.path.join(out_dir, f"{base_name}.key.pem") + cert_path = os.path.join(out_dir, f"{base_name}.cert.pem") + chain_path = os.path.join(out_dir, f"{base_name}.chain.pem") + + # klucz prywatny + run_cmd([ + "openssl", "pkcs12", + "-in", pfx_path, + "-passin", "env:PFXPASSWORD", + "-nodes", + "-nocerts", + "-out", key_path + ], password) + + # cert końcowy + run_cmd([ + "openssl", "pkcs12", + "-in", pfx_path, + "-passin", "env:PFXPASSWORD", + "-clcerts", + "-nokeys", + "-out", cert_path + ], password) + + # certy pośrednie (CA chain) – może być puste, wtedy plik zostanie, ale bez zawartości + run_cmd([ + "openssl", "pkcs12", + "-in", pfx_path, + "-passin", "env:PFXPASSWORD", + "-nokeys", + "-cacerts", + "-out", chain_path + ], password) + + return key_path, cert_path, chain_path + +def create_tar_gz(archive_name, files): + with tarfile.open(archive_name, "w:gz") as tar: + for f in files: + if os.path.isfile(f): + tar.add(f, arcname=os.path.basename(f)) + +def main(): + parser = argparse.ArgumentParser( + description="Rozszyfruj PFX i spakuj key/cert/chain do tar.gz" + ) + parser.add_argument("pfx", help="Ścieżka do pliku .pfx/.p12") + parser.add_argument("password", help="Hasło do pliku PFX") + parser.add_argument( + "-o", "--output-dir", + default=".", + help="Katalog wyjściowy (domyślnie bieżący)" + ) + + args = parser.parse_args() + + pfx_path = os.path.abspath(args.pfx) + if not os.path.isfile(pfx_path): + print(f"Nie znaleziono pliku: {pfx_path}", file=sys.stderr) + sys.exit(1) + + os.makedirs(args.output_dir, exist_ok=True) + base_name = os.path.splitext(os.path.basename(pfx_path))[0] + archive_name = os.path.join(args.output_dir, f"{base_name}.tar.gz") + + # pracujemy w katalogu tymczasowym, potem wyniki kopiujemy + tmpdir = tempfile.mkdtemp(prefix="pfx_extract_") + try: + key_path, cert_path, chain_path = extract_from_pfx( + pfx_path, args.password, tmpdir, base_name + ) + + # kopiujemy pliki PEM do katalogu wyjściowego (opcjonalne, ale zwykle przydatne) + final_key = shutil.copy(key_path, os.path.join(args.output_dir, os.path.basename(key_path))) + final_cert = shutil.copy(cert_path, os.path.join(args.output_dir, os.path.basename(cert_path))) + final_chain = shutil.copy(chain_path, os.path.join(args.output_dir, os.path.basename(chain_path))) + + # tworzymy tar.gz z tych 3 plików + create_tar_gz(archive_name, [final_key, final_cert, final_chain]) + + print("Utworzono pliki:") + print(" Klucz: ", final_key) + print(" Certyfikat: ", final_cert) + print(" Chain: ", final_chain) + print("Archiwum tar.gz:", archive_name) + + finally: + shutil.rmtree(tmpdir, ignore_errors=True) + +if __name__ == "__main__": + main()