Skip to content

Instantly share code, notes, and snippets.

@rswift
Last active October 10, 2023 13:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rswift/2b40bda6955bb2a5aabc8f73b82fb5af to your computer and use it in GitHub Desktop.
Save rswift/2b40bda6955bb2a5aabc8f73b82fb5af to your computer and use it in GitHub Desktop.
Trivial script to explore only using built-in Python 3 modules to establish a connection to a host that issues certs signed by a CA that isn't well known...
#
# Trivial script to explore only using built-in Python 3 modules to establish a connection to
# a host that issues certs signed by a CA that isn't well known...
#
# It does require that the root cert is available, so primarily an enterprise that has an
# internal or private CA and signs server certs with that...
#
import urllib.request
import ssl
import socket
#
# Google kindly provide a handy site for such testing
#
hostname = "untrusted-root.badssl.com"
port = 443
method = "GET"
data = None
##headers = {"Content-Type": "text/html; charset=UTF-8"}
cert_on_filesystem = False
#
# Using the untrusted-root test host, grab the cert using openssl and then simply copy it in
# or use your favourite utility to make the string from the openssl output. to get the cert, use:
#
# openssl s_client -showcerts -servername untrusted-root.badssl.com -connect untrusted-root.badssl.com:443
#
# and obviously make sure you take the correct cert in the chain, in this case the CN to use was
#
# CN=BadSSL Untrusted Root Certificate Authority
#
# also note that this cert may change (although it is valid until 2036), so check in case of errors
#
CA_ROOT_PEM = "-----BEGIN CERTIFICATE-----\n" \
"MIIGfjCCBGagAwIBAgIJAJeg/PrX5Sj9MA0GCSqGSIb3DQEBCwUAMIGBMQswCQYD" \
"VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j" \
"aXNjbzEPMA0GA1UECgwGQmFkU1NMMTQwMgYDVQQDDCtCYWRTU0wgVW50cnVzdGVk" \
"IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE2MDcwNzA2MzEzNVoXDTM2" \
"MDcwMjA2MzEzNVowgYExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh" \
"MRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wxNDAyBgNV" \
"BAMMK0JhZFNTTCBVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw" \
"ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKQtPMhEH073gis/HISWAi" \
"bOEpCtOsatA3JmeVbaWal8O/5ZO5GAn9dFVsGn0CXAHR6eUKYDAFJLa/3AhjBvWa" \
"tnQLoXaYlCvBjodjLEaFi8ckcJHrAYG9qZqioRQ16Yr8wUTkbgZf+er/Z55zi1yn" \
"CnhWth7kekvrwVDGP1rApeLqbhYCSLeZf5W/zsjLlvJni9OrU7U3a9msvz8mcCOX" \
"fJX9e3VbkD/uonIbK2SvmAGMaOj/1k0dASkZtMws0Bk7m1pTQL+qXDM/h3BQZJa5" \
"DwTcATaa/Qnk6YHbj/MaS5nzCSmR0Xmvs/3CulQYiZJ3kypns1KdqlGuwkfiCCgD" \
"yWJy7NE9qdj6xxLdqzne2DCyuPrjFPS0mmYimpykgbPnirEPBF1LW3GJc9yfhVXE" \
"Cc8OY8lWzxazDNNbeSRDpAGbBeGSQXGjAbliFJxwLyGzZ+cG+G8lc+zSvWjQu4Xp" \
"GJ+dOREhQhl+9U8oyPX34gfKo63muSgo539hGylqgQyzj+SX8OgK1FXXb2LS1gxt" \
"VIR5Qc4MmiEG2LKwPwfU8Yi+t5TYjGh8gaFv6NnksoX4hU42gP5KvjYggDpR+NSN" \
"CGQSWHfZASAYDpxjrOo+rk4xnO+sbuuMk7gORsrl+jgRT8F2VqoR9Z3CEdQxcCjR" \
"5FsfTymZCk3GfIbWKkaeLQIDAQABo4H2MIHzMB0GA1UdDgQWBBRvx4NzSbWnY/91" \
"3m1u/u37l6MsADCBtgYDVR0jBIGuMIGrgBRvx4NzSbWnY/913m1u/u37l6MsAKGB" \
"h6SBhDCBgTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV" \
"BAcMDVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDE0MDIGA1UEAwwrQmFk" \
"U1NMIFVudHJ1c3RlZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eYIJAJeg/PrX" \
"5Sj9MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IC" \
"AQBQU9U8+jTRT6H9AIFm6y50tXTg/ySxRNmeP1Ey9Zf4jUE6yr3Q8xBv9gTFLiY1" \
"qW2qfkDSmXVdBkl/OU3+xb5QOG5hW7wVolWQyKREV5EvUZXZxoH7LVEMdkCsRJDK" \
"wYEKnEErFls5WPXY3bOglBOQqAIiuLQ0f77a2HXULDdQTn5SueW/vrA4RJEKuWxU" \
"iD9XPnVZ9tPtky2Du7wcL9qhgTddpS/NgAuLO4PXh2TQ0EMCll5reZ5AEr0NSLDF" \
"c/koDv/EZqB7VYhcPzr1bhQgbv1dl9NZU0dWKIMkRE/T7vZ97I3aPZqIapC2ulrf" \
"KrlqjXidwrGFg8xbiGYQHPx3tHPZxoM5WG2voI6G3s1/iD+B4V6lUEvivd3f6tq7" \
"d1V/3q1sL5DNv7TvaKGsq8g5un0TAkqaewJQ5fXLigF/yYu5a24/GUD783MdAPFv" \
"gWz8F81evOyRfpf9CAqIswMF+T6Dwv3aw5L9hSniMrblkg+ai0K22JfoBcGOzMtB" \
"Ke/Ps2Za56dTRoY/a4r62hrcGxufXd0mTdPaJLw3sJeHYjLxVAYWQq4QKJQWDgTS" \
"dAEWyN2WXaBFPx5c8KIW95Eu8ShWE00VVC3oA4emoZ2nrzBXLrUScifY6VaYYkkR" \
"2O2tSqU8Ri3XRdgpNPDWp8ZL49KhYGYo3R/k98gnMHiY5g==\n" \
"-----END CERTIFICATE-----"
try:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = ssl.CERT_REQUIRED
# https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_verify_locations
if cert_on_filesystem:
ssl_context.load_verify_locations(cafile="/tmp/pca.pem")
else:
ssl_context.load_verify_locations(cadata=CA_ROOT_PEM)
# https://docs.python.org/3/library/ssl.html#ssl.SSLContext.cert_store_stats
ca_stats = ssl_context.cert_store_stats()
if 'x509_ca' in ca_stats:
print("{} CA entr{} in use".format(ca_stats['x509_ca'], 'y' if ca_stats['x509_ca'] == 1 else 'ies'))
except Exception as ssl_error:
print(ssl_error)
import sys
sys.exit()
with socket.create_connection((hostname, port)) as sock:
try:
# https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket
with ssl_context.wrap_socket(sock, server_hostname=hostname) as secure_socket:
print("Secure connection to {} using {}".format(secure_socket.server_hostname, secure_socket.version()))
# https://docs.python.org/3/library/ssl.html#ssl.SSLSocket.getpeercert
peer_cert = secure_socket.getpeercert()
# not pretty, but i'm on a train, it's late and i can't be arsed putting much effort in - knock yourself out though...
common_name = "***UNKNOWN***"
for x in peer_cert['subject']:
if x[0][0] == "commonName":
common_name = x[0][1]
issuer = "***UNKNOWN***"
for x in peer_cert['issuer']:
if x[0][0] == "commonName":
issuer = x[0][1]
not_before = "***UNKNOWN***"
if 'notBefore' in peer_cert:
not_before = peer_cert['notBefore']
not_after = "***UNKNOWN***"
if 'notAfter' in peer_cert:
not_after = peer_cert['notAfter']
print("Their certificate was issued to \"{}\", is valid from {} till {} and was signed by \"{}\"".format(common_name, not_before, not_after, issuer))
except ssl.SSLCertVerificationError as cert_error:
print("Got a cert error: {}".format(cert_error.verify_message))
except Exception as ssl_error:
print(ssl_error)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment