Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hamburg Python Pizza 2019: ssl module 10

Hamburg Python Pizza 2019: ssl module 10

Christian Heimes

November 09, 2019
Tweet

More Decks by Christian Heimes

Other Decks in Programming

Transcript

  1. 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
  2. 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.
  3. 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
  4. 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)
  5. 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 <ssl.SSLContext object at 0x7f4286ab0360> >>> ctx.verify_mode, ctx.check_hostname (<VerifyMode.CERT_REQUIRED: 2>, True) >>> ctx = ssl.create_default_context() >>> ctx <ssl.SSLContext object at 0x7f4286ab0360> >>> ctx.verify_mode, ctx.check_hostname (<VerifyMode.CERT_REQUIRED: 2>, True) >>> sock = socket.create_connection(('hamburg.python.pizza', 443)) >>> sock <socket.socket fd=4, family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, ...> >>> sock = socket.create_connection(('hamburg.python.pizza', 443)) >>> sock <socket.socket fd=4, family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, ...> >>> ssock = ctx.wrap_socket(sock, server_hostname='hamburg.python.pizza') >>> ssock <ssl.SSLSocket fd=4, family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, ...> >>> ssock = ctx.wrap_socket(sock, server_hostname='hamburg.python.pizza') >>> ssock <ssl.SSLSocket fd=4, family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, ...>
  6. 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}
  7. 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
  8. 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
  9. 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
  10. 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}
  11. 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