[Python-Dev] Let's make the SSL module sane (original) (raw)
Christian Heimes christian at python.org
Sat Sep 10 10:22:57 EDT 2016
- Previous message (by thread): [Python-Dev] sys.path file feature
- Next message (by thread): [Python-Dev] Let's make the SSL module sane
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi,
(CC TLS gurus)
For 3.6 I like to make the SSL more sane and more secure by default. Yes, I'm a bit late but all my proposals are implemented, documented, partly tested and existing tests are passing. I'm going to write more tests and documentation after beta1.
First I like to deprecated some old APIs and favor of SSLCotext. We have multiple ways to create a SSL socket or to configure libraries like urllib. The general idea is to make SSLContext the central object for TLS/SSL configuration. My patch deprecates ssl.wrap_socket() and SSLSocket constructor in favor of SSLContext.wrap_socket(). The patch also deprecates certfile, keyfile an similar arguments in network protocol libraries.
I also considered to make cert validation enabled by default for all protocol in 3.6, Victor has rising some concerns. How about we change the behavior in 3.7 and just add a warning to 3.6?
http://bugs.python.org/issue28022 https://github.com/tiran/cpython/commits/feature/feature/ssl_deprecation
Next up SSLContext default configuration. A bare SSLContext comes with insecure default settings. I'd like to make SSLContext(PROTOCOL_SSLv23) secure bu default. Changelog: The context is created with more secure default values. The options OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE, OP_NO_SSLv2 (except for PROTOCOL_SSLv2), and OP_NO_SSLv3 (except for PROTOCOL_SSLv3) are set by default. The initial cipher suite list contains only HIGH ciphers, no NULL ciphers and MD5 ciphers (except for PROTOCOL_SSLv2).
http://bugs.python.org/issue28043 https://github.com/tiran/cpython/commits/feature/ssl_sane_defaults
Finally (and this is the biggest) I like to change how the protocols work. OpenSSL 1.1.0 has deprecated all version specific protocols. Soon OpenSSL will only support auto-negotiation (formerly known as PROTOCOL_SSLv23). My patch #26470 added PROTOCOL_TLS as alias for PROTOCOL_SSLv23. If the last idea is accepted I will remove PROTOCOL_TLS again. It hasn't been released yet. Instead I'm going to add PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER (see https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_new.html TLS_server_method(), TLS_client_method()). PROTOCOL_TLS_CLIENT is like PROTOCOL_SSLv23 but only supports client-side sockets and PROTOCOL_TLS_SERVER just server-side sockets. In my experience we can't have a SSLContext with sensible and secure settings for client and server at the same time. Hostname checking and cert validation is only sensible for client-side sockets.
Starting in 3.8 (or 3.7?) there will be only PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER.
I haven't created a ticket yet, code is at https://github.com/tiran/cpython/commits/feature/openssl_client_server
How will my proposals change TLS/SSL code?
Application must create a SSLContext object. Applications are recommended to keep the context around to benefit from session reusage and reduce overload of cert parsing.
Client side, ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT):
- works with TLSv1.0, TLSv1.1, TLSv1.2 and new protocols
- Options OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION are set
- Only HIGH cipher suites are enabled, MD5 and NULL are disabled
- all other ciphers are still enabled, MD5 for SSLv2
- cert_required = CERT_REQUIRED
- check_hostname = True
- ctx.wrap_socket() creates a client-side socket
- ctx.wrap_socket(server_side=True) will not work
- root certs are not loaded
I don't load any certs because it is not possible to remove a cert or X509 lookup once it is loaded. create_default_context() just have to load the certs and set more secure ciper suites.
Server side, ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_PROTOCOL):
- works with TLSv1.0, TLSv1.1, TLSv1.2 and new protocols
- Options OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION are set
- OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE are set
- Only HIGH cipher suites are enabled, MD5 and NULL are disabled
- all other ciphers are still enabled, MD5 for SSLv2
- cert_required = CERT_NONE (no client cert validation)
- check_hostname = False
- no root CA certs are loaded
- only ctx.wrap_socket(server_side=True) works
I hope this mail makes sense. Christian
- Previous message (by thread): [Python-Dev] sys.path file feature
- Next message (by thread): [Python-Dev] Let's make the SSL module sane
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]