On 15 Apr 2020, at 19:56, Ander Juaristi <a@juaristi.eus> wrote:

Hi list,

I haven't seen this being discussed, but TL;DR I just want to propose to extend the ssl module so that TLS session state can be serialized to disk.

You might want to read this analysis of TLS session tickets in TLS 1.2.

https://blog.filippo.io/we-need-to-talk-about-session-tickets/

Tl;dr its not considered secure.

Barry


I see a similar issue was being discussed here [0], but cannot tell why it (apparently) didn't get into. The link to the patch is broken.

TLS session resumption is currently supported, but only within the same process. To the best of my knowledge, there is no way to save the TLS session to a file to resume the TLS session later on. Please tell me how this is done if I'm wrong.

   #
   # open a TLS connection
   #
   with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
       with context.wrap_socket(sock, server_hostname=hostname) \
               as ssock:
           ssock.connect((hostname, 443))
           ssl_session = ssock.session  # get TLS session

   #
   # later on, open a new connection resuming session
   #
   with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
       with context.wrap_socket(sock,
                                server_hostname=hostname,
                                session=ssl_session) as ssock:
           ssock.connect((hostname, 443))
           print("-- TLS session %s resumed --"
                 % ("WAS" if ssock.session_reused else "WAS NOT")


However TLS sessions live for
hours, if not days, and hence it may make sense to persist them
to disk for later retrieval. I think this is a real world use case though I have not any numbers to back this up.

The values currently exposed by SSLSession (id, time, timeout) are not enough to resume a TLS session. There are a number of parameters that need to be stored to resume a TLS session at a later time, some of which are not currently retrievable from python's ssl module. For instance, the master secret.

I'm not a fan of exposing the master secret directly with a getter as that could be and will definitely be misused by someone in spite of the bright red warnings, leading to disaster.

What OpenSSL currently does, as do other implementations, is to allow the SSL_SESSION object to be serialized, with i2d_SSL_SESSION(). This function will return a DER-encoded ASN.1 object containing all the needed state to resume the TLS session. I do believe exposing this object from the ssl module (as an opaque bytes object) would be a useful compromise with very little chance of misuse.

One possible incarnation of this idea would be add two new methods to SSLSession, to_der(), and from_der():

   class SSLSession:
       def to_der():
           """ Returns OpenSSL's DER-encoded SSL_SESSION object """

       @staticmethod
       def from_der(der_bytes):
           """
           Creates a new SSLSession object from the given
           DER-encoded SSL_SESSION object
           """

If this has already been discussed (likely), what are the reasons it was rejected?

Thanks!

[0] https://bugs.python.org/issue19500
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/55RZJODLVNVP72FNE42GUZEO57RDE5W4/
Code of Conduct: http://python.org/psf/codeofconduct/