#!/usr/bin/env python
# pem2der -- convert PEM format certificate files to DER (.crt)
import argparse
import base64
import os
import re
import subprocess

def scan_certs(buf):
    buf = buf.replace(b"\r\n", b"\n")
    certs = re.findall(rb"^-----BEGIN CERTIFICATE-----\n"
                       rb".+?\n"
                       rb"-----END CERTIFICATE-----$",
                       buf, re.MULTILINE | re.DOTALL)
    return certs

def decode_pem(buf):
    res = re.search(rb"^-----BEGIN [^\n]+-----\n"
                    rb"(.+?)\n"
                    rb"-----END [^\n]+-----$",
                    buf, re.MULTILINE | re.DOTALL)
    return base64.b64decode(res[1])

parser = argparse.ArgumentParser()
parser.add_argument("-x", "--trash",
                        action="store_true",
                        help="remove inputs after successful conversion")
parser.add_argument("file",
                        nargs="+",
                        help="input .pem file")
args = parser.parse_args()

for inarg in args.file:
    with open(inarg, "rb") as fh:
        buf = fh.read(16*1024*1024)
    certs = scan_certs(buf)
    print(f"pem2der: found {len(certs)} certificates in {inarg!r}")
    basename, ext = os.path.splitext(inarg)
    for i, cert in enumerate(certs):
        if len(certs) == 1 and ext == ".pem":
            outarg = f"{basename}.crt"
        else:
            outarg = f"{basename}_{i}.crt"
        if outarg == inarg:
            raise Exception(f"Bug: {outarg=} is the same as {inarg=}")
        buf = decode_pem(cert)
        with open(outarg, "wb") as fh:
            fh.write(buf)
            print(f"pem2der: wrote {outarg!r}")
    if len(certs) and args.trash:
        subprocess.run(["trash", inarg])
