Skip to content

Instantly share code, notes, and snippets.

@zed
Last active April 23, 2021 06:30
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zed/7901011 to your computer and use it in GitHub Desktop.
Save zed/7901011 to your computer and use it in GitHub Desktop.
Show server's ssl certificate as json.
#!/usr/bin/env python3
"""Show server's certificate as json.
Usage:
$ %(prog)s HOST [PORT]
"""
import json
import socket
import ssl
import sys
def getcert(addr, timeout=None):
"""Retrieve server's certificate at the specified address (host, port)."""
# it is similar to ssl.get_server_certificate() but it returns a dict
# and it verifies ssl unconditionally, assuming create_default_context does
with socket.create_connection(addr, timeout=timeout) as sock:
context = ssl.create_default_context()
with context.wrap_socket(sock, server_hostname=addr[0]) as sslsock:
return sslsock.getpeercert()
def main(argv):
host = argv[1]
port = int(argv[2]) if len(argv) > 2 else 443
print(json.dumps(getcert((host, port)), indent=2, sort_keys=True))
if __name__ == "__main__":
main(sys.argv)
@phantomOPBro
Copy link

Nice! Very helpful thank you.

@def-fun
Copy link

def-fun commented Mar 29, 2020

go wrong when provide a domain which certificate is invlid.
For example,

$ ./getcert.py self-signed.badssl.com 443
Traceback (most recent call last):
  File "./getcert.py", line 26, in <module>
    main(sys.argv)
  File "./getcert.py", line 23, in main
    print(json.dumps(getcert((host, port)), indent=2, sort_keys=True))
  File "./getcert.py", line 17, in getcert
    with context.wrap_socket(sock, server_hostname=addr[0]) as sslsock:
  File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
    _context=self)
  File "/usr/lib/python3.5/ssl.py", line 752, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)

@zed
Copy link
Author

zed commented Mar 29, 2020

provide a domain
It is the first arg to the script e.g., for the getcert example.com command, it would be example.com.
It is a quick and dirty dev's tool, otherwise a traceback wouldn't be the best error message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment