From d207312a2e05346f95cc5a825cbfab78d55e89b9 Mon Sep 17 00:00:00 2001 From: Scott Wallace Date: Wed, 5 Mar 2025 17:29:06 +0000 Subject: [PATCH] Code tidy up --- cert_deets.py | 71 +++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/cert_deets.py b/cert_deets.py index 8a0947d..5a4fc6b 100644 --- a/cert_deets.py +++ b/cert_deets.py @@ -1,12 +1,13 @@ -#!python3 -""" -Return the Akamai property and version for a given site -""" +"""Display TLS certificate details for an HTTP endpoint.""" + +from __future__ import annotations + import argparse import socket import ssl import sys import urllib.error +from contextlib import suppress from typing import Any from urllib.parse import urlparse @@ -20,8 +21,7 @@ SAN_GROUPING = 4 def get_cert_with_servername(addr: tuple[str, int], servername: str = "") -> bytes: - """ - Get TLS certificate from an address with an explicit servername override + """Get TLS certificate from an address with an explicit servername override. Args: addr (tuple[str, int]): adress in tuple form (address, port) @@ -29,51 +29,49 @@ def get_cert_with_servername(addr: tuple[str, int], servername: str = "") -> byt Returns: bytes: PEM bytes + """ context = ssl.create_default_context() context.check_hostname = False - with socket.create_connection((addr[0], addr[1]), timeout=10) as sock: - with context.wrap_socket(sock, server_hostname=servername) as sslsock: - if der_cert := sslsock.getpeercert(True): - return ssl.DER_cert_to_PEM_cert(der_cert).encode("utf=8") + with socket.create_connection((addr[0], addr[1]), timeout=10) as sock, context.wrap_socket( + sock, + server_hostname=servername, + ) as sslsock: + if der_cert := sslsock.getpeercert(binary_form=True): + return ssl.DER_cert_to_PEM_cert(der_cert).encode("utf=8") - return bytes() + return b"" def format_fingerprint(fingerprint: bytes | str) -> str: - """ - Print a fingerprint as a colon-separated hex string + """Print a fingerprint as a colon-separated hex string. Args: fingerprint (bytes | str): fingerprint to format Returns: str: formatted fingerprint + """ if isinstance(fingerprint, str): fingerprint = bytearray.fromhex(fingerprint) return ":".join([format(i, "02x") for i in fingerprint]) -def display_error( - site: str, - error: Any = None, -) -> None: - """ - Print a generic error - """ +def display_error(site: str, error: Any = None) -> None: + """Print a generic error.""" print(f"ERROR: Could not find a certificate for {site}") if error: print(str(error)) def parseargs() -> argparse.Namespace: - """ - Parse the CLI + """Parse the CLI. Returns: argparse.Namespace: parsed arguments + """ parser = argparse.ArgumentParser() @@ -84,11 +82,11 @@ def parseargs() -> argparse.Namespace: def main() -> int: - """ - Main entrypoint + """Run the code. Returns: int: return value + """ args = parseargs() @@ -123,10 +121,8 @@ def main() -> int: ).encode("utf-8") cert_chain = CertificateChain() - try: + with suppress(urllib.error.URLError): cert_chain = resolve(pem_data) - except urllib.error.URLError: - pass except ( ConnectionRefusedError, ConnectionResetError, @@ -146,23 +142,20 @@ def main() -> int: sans = [ f"DNS:{dns}" - for dns in cert.extensions.get_extension_for_class( - x509.SubjectAlternativeName - ).value.get_values_for_type(x509.DNSName) + for dns in cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value.get_values_for_type( + x509.DNSName, + ) ] sans.extend( [ f"IP:{ip}" - for ip in cert.extensions.get_extension_for_class( - x509.SubjectAlternativeName - ).value.get_values_for_type(x509.IPAddress) - ] + for ip in cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value.get_values_for_type( + x509.IPAddress, + ) + ], ) - sangroups = [ - sans[group : group + SAN_GROUPING] - for group in range(0, len(sans), SAN_GROUPING) - ] + sangroups = [sans[group : group + SAN_GROUPING] for group in range(0, len(sans), SAN_GROUPING)] table = [ ["Common name", cert.subject.rfc4514_string()], @@ -192,7 +185,7 @@ def main() -> int: if cert ], ), - ] + ], ) print(tabulate(table, tablefmt="plain"))