Skip to content

Instantly share code, notes, and snippets.

@tiran
Created November 2, 2017 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tiran/6e7a5b00483376e164c951730db7d4e5 to your computer and use it in GitHub Desktop.
Save tiran/6e7a5b00483376e164c951730db7d4e5 to your computer and use it in GitHub Desktop.
ssl.get_server_certificate with cert type
#!/usr/bin/env python3
# see https://bugs.python.org/issue31892
from socket import create_connection
from ssl import (
_create_stdlib_context, DER_cert_to_PEM_cert, PROTOCOL_TLS,
CERT_REQUIRED, CERT_NONE
)
CERT_TYPE = {
'RSA': 'aRSA:!NULL',
'ECDSA': 'aECDSA:!NULL',
}
def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None,
*, certtype=None):
"""Retrieve the certificate from the server at the specified address,
and return it as a PEM-encoded string.
If 'ca_certs' is specified, validate the server cert against it.
If 'ssl_version' is specified, use it in the connection attempt."""
host, port = addr
if ca_certs is not None:
cert_reqs = CERT_REQUIRED
else:
cert_reqs = CERT_NONE
context = _create_stdlib_context(ssl_version,
cert_reqs=cert_reqs,
cafile=ca_certs)
if certtype is not None:
context.set_ciphers(CERT_TYPE[certtype])
with create_connection(addr) as sock:
with context.wrap_socket(sock) as sslsock:
dercert = sslsock.getpeercert(True)
return DER_cert_to_PEM_cert(dercert)
if __name__ == '__main__':
ADDR = ('www.facebook.com', 443)
for certtype in (None, 'RSA', 'ECDSA'):
print(certtype)
print(get_server_certificate(ADDR, certtype=certtype))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment