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

Avatar for Christian Heimes

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