Skip to content

Instantly share code, notes, and snippets.

@ernix
Created December 18, 2019 05:54
Show Gist options
  • Save ernix/146e875de661f51e8fb7e64a694dc9e8 to your computer and use it in GitHub Desktop.
Save ernix/146e875de661f51e8fb7e64a694dc9e8 to your computer and use it in GitHub Desktop.
cert-domains.py
#!/usr/bin/env python3
import socket
import ssl
import sys
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.x509.oid import NameOID
def cert_domains(host):
# https://stackoverflow.com/a/52464142/482519
context = ssl.create_default_context()
with socket.create_connection((host, 443)) as sock:
with context.wrap_socket(sock, server_hostname=host) as sslsock:
der = sslsock.getpeercert(True)
pem = ssl.DER_cert_to_PEM_cert(der)
cert = x509.load_pem_x509_certificate(pem.encode('ascii'),
default_backend())
#
# http://wiki.cacert.org/FAQ/subjectAltName
# > subjectAltName must always be used (RFC 3280 4.2.1.7, 1. paragraph).
# > CN is only evaluated if subjectAltName is not present and only for
# > compatibility with old, non-compliant software. So if you set
# > subjectAltName, you have to use it for all host names, email addresses,
# > etc., not just the "additional" ones.
#
ext = cert.extensions
san = ext.get_extension_for_class(x509.SubjectAlternativeName)
if san:
return san.value.get_values_for_type(x509.DNSName)
else:
attrs = cert.subject.get_attributes_for_type(NameOID.COMMON_NAME)
return [cn.value for cn in attrs]
if __name__ == '__main__':
print(*cert_domains(sys.argv[1]), sep="\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment