120 lines
3.7 KiB
Python
120 lines
3.7 KiB
Python
#!/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()
|