[Python-Dev] TLS 1.3 support

Christian Heimes christian at python.org
Thu Aug 16 09:27:52 EDT 2018


Hi,

I have some exciting news. RFC 8446 [1] for TLS 1.3 was finalized a
couple of days ago. The new TLS standard comes with several major
improvements, but also with major changes.

First some good news:
Python's ssl module not compiles with OpenSSL 1.1.1-pre. It's also able
to negotiate and establish TLS 1.3 connections successfully. Almost all
unit tests are passing, too. Yesterday I pushed some patches to fix 2.7,
3.6, 3.7, and master.

Of course, there is a catch. While TLS 1.0 to 1.2 were just gradual
improvements over SSLv3, TLS 1.3 behaves differently on several levels.
The article [2] from Nick Sullivan explains the biggest changes well.
Most improvements like 1-RTT handshake, enforced perfect forward secrecy
and improved cryptography are not visible to applications. However some
changes and new features are going to need additional work and new APIs.

I'm open to discuss the matter at the core dev sprints in Seattle next
month.

I'm still in the process of reviewing and assessing changes. OpenSSL
1.1.1's APIs are not finalized yet, too. I'm working closely with Red
Hat's crypto team and OpenSSL devs on the topic. I'll walk you through
some changes and possibly new APIs that I have identified so far.


New cipher suites
=================

Old ciphers suites in TLS 1.2 and earlier looked like

   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

The parameters are key agreement/key exchange (ECDHE), authentication
(RSA), bulk encryption (AES-256) with block and/or authenticated
encryption mode (GCM) and finally a pseudo random function for MAC.

In TLS 1.3, the cipher suites only specify bulk encryption and PRF. The
parameters for key agreement and authentication are configured
differently. TLS 1.3 uses dedicated TLS extensions for that, too. This
allows more fine grained control to specific supported EC curves,
signature algorithms (RSA PKCS#1.5, RSASSA-PSS) and so on. Some settings
also apply to TLS 1.2 already.

Further more, OpenSSL has introduced new APIs to configure TLS 1.3
cipher suites. SSLContext.set_ciphers() cannot be used to disable TLS
1.3 suites. For now, that is fine. All default algorithms are secure and
state-of-the-art.

For 3.8, I'm planning to make some of the settings configurable. I might
need to backport the new APIs to 3.7 and 3.6, though.


post handshake authentication
=============================

TLS 1.3 introduced the concept of post handshake authentication (PHA). A
server can either request a client to provide client cert authentication
during the handshake, directly after the handshake, or at any later
point. It makes optional authentication for HTTP much more sane. For
example a server may only require authentication for POST requests and
GET requests to /secure/* path. In TLS 1.2, optional client cert auth
requires a complete renegotiation of the handshake.

OpenSSL 1.1.1-pre9 will most likely disable PHA by default [3], because
PHA breaks some assumptions of TLS 1.2 clients and servers. But PHA
might be required for path specific authentication. I need to wait and
see how mod_ssl implements the feature.

I might have to add SSL_VERIFY_POST_HANDSHAKE,
SSL_verify_client_post_handshake(), and
SSL_CTX_set_post_handshake_auth() from [3][4] to Python 2.7, 3.6, 3.7
and master.


session handling
================

TLS 1.3 uses a different approach to handle sessions. Simple speaking,
session data is exchanged after the handshake, there can be more than
one ticket, tickets must not be reused, and session resumption involved
DHE. ssl.SSLSession [5] feature only applies to TLS 1.2 and earlier. I
need to come up with a different approach here. For the time being, TLS
1.3 won't be compatible with manual session control. It's not a big deal
since it is an advanced feature any way.

The new session system also seems to break FTP over TLS. FTP uses two
different TCP connections (control channel, data channel). For FTP over
TLS, the data channel must reuse a session of the control channel. For
now, I'm plannung to restrict FTP to TLSv1.2.


0-RTT resumption
=================

0 round trip time handshake on session resumption is an optional and
advanced feature. I might expose the feature in Python 3.8.

Regards,
Christian


[1] https://tools.ietf.org/html/rfc8446
[2] https://blog.cloudflare.com/rfc-8446-aka-tls-1-3/
[3] https://github.com/openssl/openssl/issues/6933
[4] https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_verify.html
[5] https://docs.python.org/3/library/ssl.html#ssl-session

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180816/ea4c9bec/attachment.sig>


More information about the Python-Dev mailing list