Initial commit

This commit is contained in:
2025-07-08 23:00:02 -06:00
commit 5922d2bb08
5 changed files with 418 additions and 0 deletions

71
pkcs12_export_proc.py Normal file
View File

@@ -0,0 +1,71 @@
#!python3
# dlitz 2025
from contextlib import ExitStack, contextmanager
import multiprocessing
import subprocess
import os
import re
class PKCS12Exporter:
openssl_prog = "openssl"
def export_pkcs12(self, privkey_data, cert_data, chain_data, passphrase):
assert re.search(r"^-----BEGIN (.*) PRIVATE KEY-----\n", privkey_data, re.M)
assert re.search(r"^-----BEGIN CERTIFICATE-----\n", cert_data, re.M)
assert "PRIVATE KEY" not in cert_data
assert chain_data is None or "PRIVATE KEY" not in chain_data
fullchain_data = cert_data + "\n" + (chain_data or "") + "\n"
all_data = privkey_data + "\n" + fullchain_data
with ExitStack() as stack:
passphrase_r, passphrase_w = stack.enter_context(self.open_pipes(text=True))
cmd = [
self.openssl_prog,
"pkcs12",
"-export",
"-passout", f"fd:{passphrase_r.fileno():d}",
"-macalg", "SHA256",
"-keypbe", "AES-256-CBC",
"-certpbe", "NONE",
]
passphrase_proc = multiprocessing.Process(target=self.data_writer, args=(passphrase_w, passphrase))
passphrase_proc.start()
passphrase_w.close()
print(cmd)
#subprocess.run(["bash", "-x", "-c", "ls -l /dev/fd/; cat /dev/fd/5; cat /dev/fd/3"], pass_fds=(passphrase_r.fileno(), privkey_r.fileno()))
#subprocess.run(cmd, pass_fds=(passphrase_r.fileno(), privkey_r.fileno()), input=fullchain_data.encode())
subprocess.run(cmd, pass_fds=(passphrase_r.fileno(), privkey_r.fileno()), input=all_data.encode())
passphrase_proc.terminate()
passphrase_proc.
@contextmanager
def open_pipes(self, *, text=False):
rfd, wfd = os.pipe()
rfile = wfile = None
try:
rfile = open(rfd, "r" if text else "rb")
wfile = open(wfd, "w" if text else "wb")
except:
if rfile is not None:
rfile.close()
else:
os.close(rfd)
if wfile is not None:
wfile.close()
else:
os.close(wfd)
with rfile as r, wfile as w:
yield r, w
@classmethod
def data_writer(cls, file, data):
file.write(data)
file.close()