Add CA chain and fingerprints
This commit is contained in:
parent
e1f7fa0989
commit
575bceec25
|
@ -6,9 +6,11 @@ import argparse
|
|||
import socket
|
||||
import ssl
|
||||
import sys
|
||||
import urllib.error
|
||||
from typing import Any
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from cert_chain_resolver.api import CertificateChain, resolve
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
|
@ -17,6 +19,21 @@ from tabulate import tabulate
|
|||
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(
|
||||
site: str,
|
||||
error: Any = None,
|
||||
|
@ -53,6 +70,10 @@ if __name__ == "__main__":
|
|||
"""
|
||||
args = parseargs()
|
||||
|
||||
url = args.site
|
||||
if "://" not in url:
|
||||
url = f"https://{url}"
|
||||
|
||||
parts = urlparse(args.site, scheme="https")
|
||||
|
||||
if not parts.netloc:
|
||||
|
@ -70,7 +91,15 @@ if __name__ == "__main__":
|
|||
try:
|
||||
pem_data = ssl.get_server_certificate(
|
||||
(parts.hostname, parts.port),
|
||||
timeout=10,
|
||||
).encode("utf-8")
|
||||
|
||||
cert_chain = CertificateChain()
|
||||
try:
|
||||
cert_chain = resolve(pem_data)
|
||||
except urllib.error.URLError:
|
||||
pass
|
||||
|
||||
except (
|
||||
ConnectionRefusedError,
|
||||
ssl.CertificateError,
|
||||
|
@ -113,11 +142,28 @@ if __name__ == "__main__":
|
|||
["Valid to", cert.not_valid_after_utc],
|
||||
["Issuer", cert.issuer.rfc4514_string()],
|
||||
[
|
||||
"SHA1 fingerprint",
|
||||
":".join([format(i, "02x") for i in cert.fingerprint(hashes.SHA1())]),
|
||||
"Fingerprint",
|
||||
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"))
|
||||
|
||||
return 0
|
||||
|
|
|
@ -10,7 +10,7 @@ description = "Show TLS certificate details for a given endpoint"
|
|||
keywords = ["tls", "certificate", "python"]
|
||||
classifiers = ["Programming Language :: Python :: 3"]
|
||||
readme = "README.md"
|
||||
dependencies = ["cryptography", "tabulate"]
|
||||
dependencies = ["cert-chain-resolver", "cryptography", "tabulate"]
|
||||
requires-python = ">=3.11"
|
||||
|
||||
[project.urls]
|
||||
|
|
Loading…
Reference in a new issue