Add pfx_extract.py
This commit is contained in:
119
pfx_extract.py
Normal file
119
pfx_extract.py
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user