Slide 1

Slide 1 text

ssl module 101 Python Pizza 2019 / Hamburg Christian Heimes Principal Software Engineer christian@python.org / cheimes@redhat.com @ChristianHeimes

Slide 2

Slide 2 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 2 Who am I? ● Python core developer since 2008 ● maintainer of ssl and hashlib module ● Python security team ● Red Hat Security Engineering ● FreeIPA Identity Management ● Dogtag PKI ● from Hamburg

Slide 3

Slide 3 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 3

Slide 4

Slide 4 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 4 Wikipedia definition Transport Layer Security (TLS) – and its predecessor, Secure Sockets Layer (SSL) – are cryptographic protocols that provide communications security over a computer network. The TLS protocol aims primarily to provide privacy and data integrity between two communicating computer applications.

Slide 5

Slide 5 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 5 SSL TLS

Slide 6

Slide 6 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 6 TLS core features ● encrypted transport stream ● application protocol agnostic ● integrity check ● replay attack protection ● strong authentication of server ● strong authentication of client (optional) ● extensible protocol

Slide 7

Slide 7 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 7

Slide 8

Slide 8 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 8 ssl module content ● SSLContext (configuration) ● CERT_* ● VERIFY_* ● PROTOCOL_* ● OP_* ● TLSVersion.* ● create_default_context() SSLContext → ● SSLSocket (socket wrapper) ● SSLObject (asyncio wrapper)

Slide 9

Slide 9 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 9 Connecting to a server >>> import socket, ssl >>> import socket, ssl >>> ctx = ssl.create_default_context() >>> ctx >>> ctx.verify_mode, ctx.check_hostname (, True) >>> ctx = ssl.create_default_context() >>> ctx >>> ctx.verify_mode, ctx.check_hostname (, True) >>> sock = socket.create_connection(('hamburg.python.pizza', 443)) >>> sock >>> sock = socket.create_connection(('hamburg.python.pizza', 443)) >>> sock >>> ssock = ctx.wrap_socket(sock, server_hostname='hamburg.python.pizza') >>> ssock >>> ssock = ctx.wrap_socket(sock, server_hostname='hamburg.python.pizza') >>> ssock

Slide 10

Slide 10 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 10 Connecting to a server (2) >>> ssock.sendall(b"GET / HTTP/1.1\r\nHost:hamburg.python.pizza\r\n\r\n") 45 >>> ssock.recv(17) b'HTTP/1.1 200 OK\r\n' >>> ssock.sendall(b"GET / HTTP/1.1\r\nHost:hamburg.python.pizza\r\n\r\n") 45 >>> ssock.recv(17) b'HTTP/1.1 200 OK\r\n' >>> ssock.cipher() ('TLS_AES_256_GCM_SHA384', 'TLSv1.3', 256) ('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1.2', 128) >>> ssock.cipher() ('TLS_AES_256_GCM_SHA384', 'TLSv1.3', 256) ('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1.2', 128) >>> pprint(ssock.getpeercert()) {'issuer': ((('countryName', 'US'),), (('organizationName', "Let's Encrypt"),), (('commonName', "Let's Encrypt Authority X3"),)), 'notAfter': 'Jan 23 15:13:59 2020 GMT', 'notBefore': 'Oct 25 15:13:59 2019 GMT', 'serialNumber': '04475BA2081686AAEE9701B751A5F6597107', 'subject': ((('commonName', '*.naples.python.pizza'),),), 'subjectAltName': (('DNS', '*.naples.python.pizza'), ('DNS', '*.python.pizza'), ('DNS', 'python.pizza')), 'version': 3} >>> pprint(ssock.getpeercert()) {'issuer': ((('countryName', 'US'),), (('organizationName', "Let's Encrypt"),), (('commonName', "Let's Encrypt Authority X3"),)), 'notAfter': 'Jan 23 15:13:59 2020 GMT', 'notBefore': 'Oct 25 15:13:59 2019 GMT', 'serialNumber': '04475BA2081686AAEE9701B751A5F6597107', 'subject': ((('commonName', '*.naples.python.pizza'),),), 'subjectAltName': (('DNS', '*.naples.python.pizza'), ('DNS', '*.python.pizza'), ('DNS', 'python.pizza')), 'version': 3}

Slide 11

Slide 11 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 11 wrap_socket() ● agree on connection parameters ● TLS version ● ciphers ● virtual host (server_hostname) ● server proofs its identity ● X.509 certificate, private key ● client verifies server ● root CA certs, server_hostname ● agree on common master secret ● Diffie-Hellman

Slide 12

Slide 12 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 12 TLS 1.2 handshake ClientHello Supported cipher suites max version, client random, ... Finish MAC of handshake message ChangeCipherSpec ClientKeyChange Diffie-Hellman server params Finish MAC of handshake message ChangeCipherSpec HTTP GET (verify mac) ServerHello select cipher suite version, server random, ... Certificate Chain ServerHelloDone ServerKeyExchange Diffie-Hellman server params Signature

Slide 13

Slide 13 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 13 Certificate types ● trust anchors (root CA certs) ● intermediate CA certs ● end-entity certs ● server ● client ● code signing ● email ● CRL/OCSP signing ● ... root CA self-signs intermediate CA 1 intermediate CA 2 signs end-entity cert signs signs

Slide 14

Slide 14 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 14 Hostname verification >>> pprint(ssock.getpeercert()) {'issuer': ((('countryName', 'US'),), (('organizationName', "Let's Encrypt"),), (('commonName', "Let's Encrypt Authority X3"),)), 'notAfter': 'Jan 23 15:13:59 2020 GMT', 'notBefore': 'Oct 25 15:13:59 2019 GMT', 'serialNumber': '04475BA2081686AAEE9701B751A5F6597107', 'subject': ((('commonName', '*.naples.python.pizza'),),), 'subjectAltName': ( ('DNS', '*.naples.python.pizza'), ('DNS', '*.python.pizza'), ('DNS', 'python.pizza') ), 'version': 3} >>> pprint(ssock.getpeercert()) {'issuer': ((('countryName', 'US'),), (('organizationName', "Let's Encrypt"),), (('commonName', "Let's Encrypt Authority X3"),)), 'notAfter': 'Jan 23 15:13:59 2020 GMT', 'notBefore': 'Oct 25 15:13:59 2019 GMT', 'serialNumber': '04475BA2081686AAEE9701B751A5F6597107', 'subject': ((('commonName', '*.naples.python.pizza'),),), 'subjectAltName': ( ('DNS', '*.naples.python.pizza'), ('DNS', '*.python.pizza'), ('DNS', 'python.pizza') ), 'version': 3}

Slide 15

Slide 15 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 15 Don't roll your own verification ● CN/SAN ● wildcards ● internationalized domain names (IDNA) ● > 6 bugs in Python's hostname verification code ● CVE-2013-2099, #12000, #17997, #17305, #30141 ● Python 3.7 uses X509_VERIFY_PARAM_set1_host() OpenSSL 1.0.2+ / LibreSSL 2.7.0

Slide 16

Slide 16 text

ssl module 101, Python Pizza Hamburg 2019, @ChristianHeimes, CC BY-SA 4.0 17 Books

Slide 17

Slide 17 text

THANK YOU plus.google.com/+RedHat youtube.com/user/RedHatVideos facebook.com/redhatinc twitter.com/RedHat linkedin.com/company/red-hat