From 5018f796c0c32ff24f29502318f0d4c465a50b25 Mon Sep 17 00:00:00 2001 From: Benjamin Collet Date: Mon, 20 Jan 2025 20:30:47 +0100 Subject: [PATCH] Improve Subject/SAN display and parsing --- models/x509_cert.py | 29 ++++++++++++++++++++++++++++- step-ca-inspector.py | 20 +++++++++++++++----- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/models/x509_cert.py b/models/x509_cert.py index 958c441..8d0c10d 100644 --- a/models/x509_cert.py +++ b/models/x509_cert.py @@ -80,7 +80,7 @@ class cert: san_data = cert.extensions.get_extension_for_class( x509.SubjectAlternativeName ) - self.san_names = san_data.value.get_values_for_type(x509.GeneralName) + self.san_names = self.get_sans(san_data) except x509.extensions.ExtensionNotFound: self.san_names = [] @@ -125,6 +125,33 @@ class cert: cur.close() return cert + def get_sans(self, san_data): + sans = [] + + for san_value in san_data.value: + san = {} + if isinstance(san_value, x509.general_name.DNSName): + san["type"] = "DNS" + elif isinstance(san_value, x509.general_name.UniformResourceIdentifier): + san["type"] = "URI" + elif isinstance(san_value, x509.general_name.RFC822Name): + san["type"] = "Email" + elif isinstance(san_value, x509.general_name.IPAddress): + san["type"] = "IP" + elif isinstance(san_value, x509.general_name.DirectoryName): + san["type"] = "DirectoryName" + elif isinstance(san_value, x509.general_name.RegisteredID): + san["type"] = "RegisteredID" + elif isinstance(san_value, x509.general_name.OtherName): + san["type"] = "Other ({san_value.type_id})" + else: + continue + + san["value"] = san_value.value + sans.append(san) + + return sans + class status: REVOKED = 1 diff --git a/step-ca-inspector.py b/step-ca-inspector.py index 904d141..2f04b6f 100755 --- a/step-ca-inspector.py +++ b/step-ca-inspector.py @@ -89,9 +89,12 @@ def list_x509_certs(sort_key, revoked=False, expired=False): cert_row = {} cert_row["Serial"] = cert.serial - cert_row["Subject"] = "%.30s" % cert.subject - cert_row["Subject Alt Names (SAN)"] = "\n".join( - ["%.30s" % x for x in cert.san_names] + cert_row["Subject/Subject Alt Names (SAN)"] = "\n".join( + [ + "%.33s" % x + for x in [cert.subject] + + [f"{x['type']}: {x['value']}" for x in cert.san_names] + ] ) cert_row["Provisioner"] = ( f"{cert.provisioner['name']} ({cert.provisioner['type']})" @@ -119,7 +122,12 @@ def get_x509_cert(serial, show_cert=False, show_pubkey=False): cert_tbl.append(["Serial", cert.serial]) cert_tbl.append(["Subject", cert.subject]) - cert_tbl.append(["Subject Alt Names (SAN)", "\n".join(cert.san_names)]) + cert_tbl.append( + [ + "Subject Alt Names (SAN)", + "\n".join([f"{x['type']}: {x['value']}" for x in cert.san_names]), + ] + ) cert_tbl.append(["Issuer", cert.issuer]) cert_tbl.append(["Not valid before", cert.not_before]) cert_tbl.append(["Not valid after", cert.not_after]) @@ -261,7 +269,9 @@ if args.object == "x509": revoked=args.show_revoked, expired=args.show_expired, sort_key=args.sort_by ) elif args.action == "details": - get_x509_cert(serial=args.serial, show_cert=args.show_cert, show_pubkey=args.show_pubkey) + get_x509_cert( + serial=args.serial, show_cert=args.show_cert, show_pubkey=args.show_pubkey + ) elif args.action == "dump": dump_x509_cert(serial=args.serial) elif args.object == "ssh":