Add CA chain and fingerprints

This commit is contained in:
Scott Wallace 2024-02-27 15:43:51 +00:00
parent e1f7fa0989
commit 575bceec25
Signed by: scott
GPG key ID: AA742FDC5AFE2A72
2 changed files with 49 additions and 3 deletions

View file

@ -6,9 +6,11 @@ import argparse
import socket import socket
import ssl import ssl
import sys import sys
import urllib.error
from typing import Any from typing import Any
from urllib.parse import urlparse from urllib.parse import urlparse
from cert_chain_resolver.api import CertificateChain, resolve
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
@ -17,6 +19,21 @@ from tabulate import tabulate
SAN_GROUPING = 4 SAN_GROUPING = 4
def format_fingerprint(fingerprint: bytes | str) -> str:
"""
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( def display_error(
site: str, site: str,
error: Any = None, error: Any = None,
@ -53,6 +70,10 @@ if __name__ == "__main__":
""" """
args = parseargs() args = parseargs()
url = args.site
if "://" not in url:
url = f"https://{url}"
parts = urlparse(args.site, scheme="https") parts = urlparse(args.site, scheme="https")
if not parts.netloc: if not parts.netloc:
@ -70,7 +91,15 @@ if __name__ == "__main__":
try: try:
pem_data = ssl.get_server_certificate( pem_data = ssl.get_server_certificate(
(parts.hostname, parts.port), (parts.hostname, parts.port),
timeout=10,
).encode("utf-8") ).encode("utf-8")
cert_chain = CertificateChain()
try:
cert_chain = resolve(pem_data)
except urllib.error.URLError:
pass
except ( except (
ConnectionRefusedError, ConnectionRefusedError,
ssl.CertificateError, ssl.CertificateError,
@ -113,11 +142,28 @@ if __name__ == "__main__":
["Valid to", cert.not_valid_after_utc], ["Valid to", cert.not_valid_after_utc],
["Issuer", cert.issuer.rfc4514_string()], ["Issuer", cert.issuer.rfc4514_string()],
[ [
"SHA1 fingerprint", "Fingerprint",
":".join([format(i, "02x") for i in cert.fingerprint(hashes.SHA1())]), f"{format_fingerprint(cert.fingerprint(hashes.SHA1()))} (SHA1)",
], ],
] ]
if cert_chain:
table.append(
[
"CA chain",
"\n".join(
[
f"{cert.common_name} "
f"(Issuer: {cert.issuer})\n"
"Fingerprint: "
f"{format_fingerprint(cert.get_fingerprint(hashes.SHA1))} (SHA1)"
for cert in list(cert_chain.intermediates)
+ [cert_chain.root]
]
),
]
)
print(tabulate(table, tablefmt="plain")) print(tabulate(table, tablefmt="plain"))
return 0 return 0

View file

@ -10,7 +10,7 @@ description = "Show TLS certificate details for a given endpoint"
keywords = ["tls", "certificate", "python"] keywords = ["tls", "certificate", "python"]
classifiers = ["Programming Language :: Python :: 3"] classifiers = ["Programming Language :: Python :: 3"]
readme = "README.md" readme = "README.md"
dependencies = ["cryptography", "tabulate"] dependencies = ["cert-chain-resolver", "cryptography", "tabulate"]
requires-python = ">=3.11" requires-python = ">=3.11"
[project.urls] [project.urls]