Initial commit
This commit is contained in:
71
pkcs12_export_proc.py
Normal file
71
pkcs12_export_proc.py
Normal 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()
|
||||
Reference in New Issue
Block a user