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