49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
# dlitz 2026
|
|
import base64
|
|
import re
|
|
|
|
CERT_REGEXP = re.compile(
|
|
r"""
|
|
(?P<cert>
|
|
^-----BEGIN\ CERTIFICATE-----\n
|
|
(?P<b64data>
|
|
[0-9A-Za-z/+\n]+? # base64 characters and newlines
|
|
={0,2}\n # base64 padding
|
|
)
|
|
^-----END\ CERTIFICATE-----(?:\n|\Z)
|
|
)
|
|
""",
|
|
re.S | re.M | re.X,
|
|
)
|
|
|
|
|
|
def split_certs(pem_data: str, *, strict: bool = True) -> list[str]:
|
|
r = CERT_REGEXP
|
|
if not strict:
|
|
return [m["cert"] for m in r.finditer(pem_data)]
|
|
certs = []
|
|
pos = 0
|
|
for m in r.finditer(pem_data):
|
|
if strict and m.start() != pos:
|
|
raise ValueError(
|
|
f"certificate data contains extra junk at (position {pos})"
|
|
)
|
|
cert = m["cert"]
|
|
if strict:
|
|
# Try decoding the base64 data
|
|
base64.b64decode(m["b64data"])
|
|
certs.append(cert)
|
|
pos = m.end()
|
|
if strict and pos != len(pem_data):
|
|
raise ValueError(f"extra junk after certificate data (at position {pos})")
|
|
return certs
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from pathlib import Path
|
|
|
|
# print(split_certs(Path("threecerts.pem").read_text(), strict=False))
|
|
# print(split_certs(Path("threecerts.pem").read_text(), strict=True))
|
|
print(split_certs("-----BEGIN CERTIFICATE-----\nAAA=\n-----END CERTIFICATE-----\n"))
|